[
  {
    "path": ".coveragerc",
    "content": "# .coveragerc to control coverage.py\n[run]\n\n[report]\ninclude = */site-packages/google/datalab/*\n"
  },
  {
    "path": ".gitignore",
    "content": "*.pyc\n*.pyi\n*.map\n*.egg-info\n*.iml\n.idea\n.DS_Store\nMANIFEST\nbuild\n.coverage\ndist\ndatalab.magics.rst\ndatalab/notebook/static/*.js\ngoogle/datalab/notebook/static/*.js\n\n# Test files\n.tox/\n.cache/\n"
  },
  {
    "path": ".travis.yml",
    "content": "language: python\ndist: trusty\nsudo: false\n\nmatrix:\n  include:\n  - python: 2.7\n    env: TOX_ENV=py27\n  - python: 3.5\n    env: TOX_ENV=py35\n  - python: 2.7\n    env: TOX_ENV=flake8\n  - python: 2.7\n    env: TOX_ENV=coveralls\n\nbefore_install:\n  - npm install -g typescript@3.0.3\n  - tsc --module amd --noImplicitAny --outdir datalab/notebook/static datalab/notebook/static/*.ts\n  # We use tox for actually running tests.\n  - pip install --upgrade pip tox\n  \nscript:\n  # tox reads its configuration from tox.ini.\n  - tox -e $TOX_ENV\n\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "Want to contribute? Great! First, read this page (including the small print at the end).\n\n### Before you contribute\nBefore we can use your code, you must sign the\n[Google Individual Contributor License Agreement]\n(https://cla.developers.google.com/about/google-individual)\n(CLA), which you can do online. The CLA is necessary mainly because you own the\ncopyright to your changes, even after your contribution becomes part of our\ncodebase, so we need your permission to use and distribute your code. We also\nneed to be sure of various other things—for instance that you'll tell us if you\nknow that your code infringes on other people's patents. You don't have to sign\nthe CLA until after you've submitted your code for review and a member has\napproved it, but you must do it before we can put your code into our codebase.\nBefore you start working on a larger contribution, you should get in touch with\nus first through the issue tracker with your idea so that we can help out and\npossibly guide you. Coordinating up front makes it much easier to avoid\nfrustration later on.\n\n### Code reviews\nAll submissions, including submissions by project members, require review. We\nuse Github pull requests for this purpose.\n\n### Running tests\nWe use [`tox`](https://tox.readthedocs.io/) for running our tests. To run tests\nbefore sending out a pull request, just\n[install tox](https://tox.readthedocs.io/en/latest/install.html) and run\n\n```shell\n$ tox\n```\n\nto run tests under all supported environments. (This will skip any environments\nfor which no interpreter is available.) `tox -l` will provide a list of all\nsupported environments.\n\n`tox` will run all tests referenced by `tests/main.py` and\n`legacy_tests/main.py`.\n\n### The small print\nContributions made by corporations are covered by a different agreement than\nthe one above, the\n[Software Grant and Corporate Contributor License Agreement]\n(https://cla.developers.google.com/about/google-corporate).\n"
  },
  {
    "path": "LICENSE.txt",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n\n"
  },
  {
    "path": "README.md",
    "content": "# Google Cloud DataLab\n\nDatalab is deprecated. [Vertex AI Workbench](https://cloud.google.com/vertex-ai/docs/workbench) provides a notebook-based environment that offers capabilities beyond Datalab. We recommend that you use Vertex AI Workbench for new projects and [migrate your Datalab notebooks to Vertex AI Workbench](https://cloud.google.com/datalab/docs/resources/troubleshooting#migrate). For more information, see [Deprecation information](https://cloud.google.com/datalab/docs/resources/deprecation). To get help migrating Datalab projects to Vertex AI Workbench see [Get help](https://cloud.google.com/datalab/docs/resources/support#get-help).\n"
  },
  {
    "path": "datalab/README",
    "content": "Everything under datalab namespace is actively maintained but no new features are being added. Please use corresponding libraries under google.datalab namespace (source code under google/datalab directory).\n\nTo migrate existing code that relies on datalab namespace, since most API interfaces are the same between google.datalab and datalab, usually you just need to change the import namespace. The magic interface is different for bigquery though (%%sql --> %%bq).\n\nFor more details please see https://github.com/googledatalab/pydatalab/wiki/%60datalab%60-to-%60google.datalab%60-Migration-Guide.\n"
  },
  {
    "path": "datalab/__init__.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n"
  },
  {
    "path": "datalab/bigquery/__init__.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Google Cloud Platform library - BigQuery Functionality.\"\"\"\nfrom __future__ import absolute_import\n\nfrom ._csv_options import CSVOptions\nfrom ._dataset import Dataset, Datasets\nfrom ._dialect import Dialect\nfrom ._federated_table import FederatedTable\nfrom ._job import Job\nfrom ._query import Query\nfrom ._query_job import QueryJob\nfrom ._query_results_table import QueryResultsTable\nfrom ._query_stats import QueryStats\nfrom ._sampling import Sampling\nfrom ._schema import Schema\nfrom ._table import Table, TableMetadata\nfrom ._udf import UDF\nfrom ._utils import TableName, DatasetName\nfrom ._view import View\n\n__all__ = ['CSVOptions', 'Dataset', 'Datasets', 'Dialect', 'FederatedTable', 'Query', 'QueryJob',\n           'QueryResultsTable', 'QueryStats', 'Sampling', 'Schema', 'Table', 'TableMetadata',\n           'UDF', 'TableName', 'DatasetName', 'View']\n\n\ndef wait_any(jobs, timeout=None):\n  \"\"\" Return when at least one of the specified jobs has completed or timeout expires.\n\n  Args:\n    jobs: a list of Jobs to wait on.\n    timeout: a timeout in seconds to wait for. None (the default) means no timeout.\n  Returns:\n    Once at least one job completes, a list of all completed jobs.\n    If the call times out then an empty list will be returned.\n\n  \"\"\"\n  return Job.wait_any(jobs, timeout)\n\n\ndef wait_all(jobs, timeout=None):\n  \"\"\" Return when all of the specified jobs have completed or timeout expires.\n\n  Args:\n    jobs: a single Job or list of Jobs to wait on.\n    timeout: a timeout in seconds to wait for. None (the default) means no timeout.\n  Returns:\n    A list of completed Jobs. If the call timed out this will be shorter than the\n    list of jobs supplied as a parameter.\n  \"\"\"\n  return Job.wait_all(jobs, timeout)\n"
  },
  {
    "path": "datalab/bigquery/_api.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Implements BigQuery HTTP API wrapper.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom past.builtins import basestring\nfrom builtins import object\n\nimport datalab.utils\nimport datalab.bigquery\n\n\nclass Api(object):\n  \"\"\"A helper class to issue BigQuery HTTP requests.\"\"\"\n\n  # TODO(nikhilko): Use named placeholders in these string templates.\n  _ENDPOINT = 'https://www.googleapis.com/bigquery/v2'\n  _JOBS_PATH = '/projects/%s/jobs/%s'\n  _QUERIES_PATH = '/projects/%s/queries/%s'\n  _DATASETS_PATH = '/projects/%s/datasets/%s'\n  _TABLES_PATH = '/projects/%s/datasets/%s/tables/%s%s'\n  _TABLEDATA_PATH = '/projects/%s/datasets/%s/tables/%s%s/data'\n\n  _DEFAULT_TIMEOUT = 60000\n\n  def __init__(self, context):\n    \"\"\"Initializes the BigQuery helper with context information.\n\n    Args:\n      context: a Context object providing project_id and credentials.\n    \"\"\"\n    self._credentials = context.credentials\n    self._project_id = context.project_id\n\n  @property\n  def project_id(self):\n    \"\"\"The project_id associated with this API client.\"\"\"\n    return self._project_id\n\n  def jobs_insert_load(self, source, table_name, append=False, overwrite=False, create=False,\n                       source_format='CSV', field_delimiter=',', allow_jagged_rows=False,\n                       allow_quoted_newlines=False, encoding='UTF-8', ignore_unknown_values=False,\n                       max_bad_records=0, quote='\"', skip_leading_rows=0):\n    \"\"\" Issues a request to load data from GCS to a BQ table\n\n    Args:\n      source: the URL of the source bucket(s). Can include wildcards, and can be a single\n          string argument or a list.\n      table_name: a tuple representing the full name of the destination table.\n      append: if True append onto existing table contents.\n      overwrite: if True overwrite existing table contents.\n      create: if True, create the table if it doesn't exist\n      source_format: the format of the data; default 'CSV'. Other options are DATASTORE_BACKUP\n          or NEWLINE_DELIMITED_JSON.\n      field_delimiter: The separator for fields in a CSV file. BigQuery converts the string to\n          ISO-8859-1 encoding, and then uses the first byte of the encoded string to split the data\n          as raw binary (default ',').\n      allow_jagged_rows: If True, accept rows in CSV files that are missing trailing optional\n          columns; the missing values are treated as nulls (default False).\n      allow_quoted_newlines: If True, allow quoted data sections in CSV files that contain newline\n          characters (default False).\n      encoding: The character encoding of the data, either 'UTF-8' (the default) or 'ISO-8859-1'.\n      ignore_unknown_values: If True, accept rows that contain values that do not match the schema;\n          the unknown values are ignored (default False).\n      max_bad_records: The maximum number of bad records that are allowed (and ignored) before\n          returning an 'invalid' error in the Job result (default 0).\n      quote: The value used to quote data sections in a CSV file; default '\"'. If your data does\n          not contain quoted sections, set the property value to an empty string. If your data\n          contains quoted newline characters, you must also enable allow_quoted_newlines.\n      skip_leading_rows: A number of rows at the top of a CSV file to skip (default 0).\n    Returns:\n      A parsed result object.\n    Raises:\n      Exception if there is an error performing the operation.\n    \"\"\"\n    url = Api._ENDPOINT + (Api._JOBS_PATH % (table_name.project_id, ''))\n    if isinstance(source, basestring):\n      source = [source]\n    write_disposition = 'WRITE_EMPTY'\n    if overwrite:\n      write_disposition = 'WRITE_TRUNCATE'\n    if append:\n      write_disposition = 'WRITE_APPEND'\n    data = {\n        'kind': 'bigquery#job',\n        'configuration': {\n            'load': {\n                'sourceUris': source,\n                'destinationTable': {\n                    'projectId': table_name.project_id,\n                    'datasetId': table_name.dataset_id,\n                    'tableId': table_name.table_id\n                },\n                'createDisposition': 'CREATE_IF_NEEDED' if create else 'CREATE_NEVER',\n                'writeDisposition': write_disposition,\n                'sourceFormat': source_format,\n                'ignoreUnknownValues': ignore_unknown_values,\n                'maxBadRecords': max_bad_records,\n            }\n        }\n    }\n    if source_format == 'CSV':\n      load_config = data['configuration']['load']\n      load_config.update({\n          'fieldDelimiter': field_delimiter,\n          'allowJaggedRows': allow_jagged_rows,\n          'allowQuotedNewlines': allow_quoted_newlines,\n          'quote': quote,\n          'encoding': encoding,\n          'skipLeadingRows': skip_leading_rows\n      })\n\n    return datalab.utils.Http.request(url, data=data, credentials=self._credentials)\n\n  def jobs_insert_query(self, sql, code=None, imports=None, table_name=None, append=False,\n                        overwrite=False, dry_run=False, use_cache=True, batch=True,\n                        allow_large_results=False, table_definitions=None, dialect=None,\n                        billing_tier=None):\n    \"\"\"Issues a request to insert a query job.\n\n    Args:\n      sql: the SQL string representing the query to execute.\n      code: code for Javascript UDFs, if any.\n      imports: a list of GCS URLs containing additional Javascript UDF support code, if any.\n      table_name: None for an anonymous table, or a name parts tuple for a long-lived table.\n      append: if True, append to the table if it is non-empty; else the request will fail if table\n          is non-empty unless overwrite is True.\n      overwrite: if the table already exists, truncate it instead of appending or raising an\n          Exception.\n      dry_run: whether to actually execute the query or just dry run it.\n      use_cache: whether to use past query results or ignore cache. Has no effect if destination is\n          specified.\n      batch: whether to run this as a batch job (lower priority) or as an interactive job (high\n          priority, more expensive).\n      allow_large_results: whether to allow large results (slower with some restrictions but\n          can handle big jobs).\n      table_definitions: a list of JSON external table definitions for any external tables\n          referenced in the query.\n      dialect : {'legacy', 'standard'}, default 'legacy'\n          'legacy' : Use BigQuery's legacy SQL dialect.\n          'standard' : Use BigQuery's standard SQL (beta), which is\n          compliant with the SQL 2011 standard.\n      billing_tier: Limits the billing tier for this job. Queries that have resource\n          usage beyond this tier will fail (without incurring a charge). If unspecified, this\n          will be set to your project default. This can also be used to override your\n          project-wide default billing tier on a per-query basis.\n    Returns:\n      A parsed result object.\n    Raises:\n      Exception if there is an error performing the operation.\n    \"\"\"\n    url = Api._ENDPOINT + (Api._JOBS_PATH % (self._project_id, ''))\n\n    if dialect is None:\n        dialect = datalab.bigquery.Dialect.default().bq_dialect\n\n    data = {\n        'kind': 'bigquery#job',\n        'configuration': {\n            'query': {\n                'query': sql,\n                'useQueryCache': use_cache,\n                'allowLargeResults': allow_large_results,\n                'useLegacySql': dialect == 'legacy'\n            },\n            'dryRun': dry_run,\n            'priority': 'BATCH' if batch else 'INTERACTIVE',\n        },\n    }\n\n    query_config = data['configuration']['query']\n\n    resources = []\n    if code:\n      resources.extend([{'inlineCode': fragment} for fragment in code])\n\n    if imports:\n      resources.extend([{'resourceUri': uri} for uri in imports])\n\n    query_config['userDefinedFunctionResources'] = resources\n\n    if table_definitions:\n      query_config['tableDefinitions'] = table_definitions\n\n    if table_name:\n      query_config['destinationTable'] = {\n          'projectId': table_name.project_id,\n          'datasetId': table_name.dataset_id,\n          'tableId': table_name.table_id\n      }\n      if append:\n        query_config['writeDisposition'] = \"WRITE_APPEND\"\n      elif overwrite:\n        query_config['writeDisposition'] = \"WRITE_TRUNCATE\"\n\n    if billing_tier:\n        query_config['maximumBillingTier'] = billing_tier\n\n    return datalab.utils.Http.request(url, data=data, credentials=self._credentials)\n\n  def jobs_query_results(self, job_id, project_id, page_size, timeout, start_index=0):\n    \"\"\"Issues a request to the jobs/getQueryResults method.\n\n    Args:\n      job_id: the id of job from a previously executed query.\n      project_id: the project id to use to fetch the results; use None for the default project.\n      page_size: limit to the number of rows to fetch.\n      timeout: duration (in milliseconds) to wait for the query to complete.\n      start_index: the index of the row (0-based) at which to start retrieving the page of result\n          rows.\n    Returns:\n      A parsed result object.\n    Raises:\n      Exception if there is an error performing the operation.\n    \"\"\"\n    if timeout is None:\n      timeout = Api._DEFAULT_TIMEOUT\n    if project_id is None:\n      project_id = self._project_id\n\n    args = {\n        'maxResults': page_size,\n        'timeoutMs': timeout,\n        'startIndex': start_index\n    }\n    url = Api._ENDPOINT + (Api._QUERIES_PATH % (project_id, job_id))\n    return datalab.utils.Http.request(url, args=args, credentials=self._credentials)\n\n  def jobs_get(self, job_id, project_id=None):\n    \"\"\"Issues a request to retrieve information about a job.\n\n    Args:\n      job_id: the id of the job\n      project_id: the project id to use to fetch the results; use None for the default project.\n    Returns:\n      A parsed result object.\n    Raises:\n      Exception if there is an error performing the operation.\n    \"\"\"\n    if project_id is None:\n      project_id = self._project_id\n    url = Api._ENDPOINT + (Api._JOBS_PATH % (project_id, job_id))\n    return datalab.utils.Http.request(url, credentials=self._credentials)\n\n  def datasets_insert(self, dataset_name, friendly_name=None, description=None):\n    \"\"\"Issues a request to create a dataset.\n\n    Args:\n      dataset_name: the name of the dataset to create.\n      friendly_name: (optional) the friendly name for the dataset\n      description: (optional) a description for the dataset\n    Returns:\n      A parsed result object.\n    Raises:\n      Exception if there is an error performing the operation.\n    \"\"\"\n    url = Api._ENDPOINT + (Api._DATASETS_PATH % (dataset_name.project_id, ''))\n    data = {\n        'kind': 'bigquery#dataset',\n        'datasetReference': {\n            'projectId': dataset_name.project_id,\n            'datasetId': dataset_name.dataset_id\n        },\n    }\n    if friendly_name:\n      data['friendlyName'] = friendly_name\n    if description:\n      data['description'] = description\n    return datalab.utils.Http.request(url, data=data, credentials=self._credentials)\n\n  def datasets_delete(self, dataset_name, delete_contents):\n    \"\"\"Issues a request to delete a dataset.\n\n    Args:\n      dataset_name: the name of the dataset to delete.\n      delete_contents: if True, any tables in the dataset will be deleted. If False and the\n          dataset is non-empty an exception will be raised.\n    Returns:\n      A parsed result object.\n    Raises:\n      Exception if there is an error performing the operation.\n    \"\"\"\n    url = Api._ENDPOINT + (Api._DATASETS_PATH % dataset_name)\n    args = {}\n    if delete_contents:\n      args['deleteContents'] = True\n    return datalab.utils.Http.request(url, method='DELETE', args=args,\n                                      credentials=self._credentials, raw_response=True)\n\n  def datasets_update(self, dataset_name, dataset_info):\n    \"\"\"Updates the Dataset info.\n\n    Args:\n      dataset_name: the name of the dataset to update as a tuple of components.\n      dataset_info: the Dataset resource with updated fields.\n    \"\"\"\n    url = Api._ENDPOINT + (Api._DATASETS_PATH % dataset_name)\n    return datalab.utils.Http.request(url, method='PUT', data=dataset_info,\n                                      credentials=self._credentials)\n\n  def datasets_get(self, dataset_name):\n    \"\"\"Issues a request to retrieve information about a dataset.\n\n    Args:\n      dataset_name: the name of the dataset\n    Returns:\n      A parsed result object.\n    Raises:\n      Exception if there is an error performing the operation.\n    \"\"\"\n    url = Api._ENDPOINT + (Api._DATASETS_PATH % dataset_name)\n    return datalab.utils.Http.request(url, credentials=self._credentials)\n\n  def datasets_list(self, project_id=None, max_results=0, page_token=None):\n    \"\"\"Issues a request to list the datasets in the project.\n\n    Args:\n      project_id: the project id to use to fetch the results; use None for the default project.\n      max_results: an optional maximum number of tables to retrieve.\n      page_token: an optional token to continue the retrieval.\n    Returns:\n      A parsed result object.\n    Raises:\n      Exception if there is an error performing the operation.\n    \"\"\"\n    if project_id is None:\n      project_id = self._project_id\n    url = Api._ENDPOINT + (Api._DATASETS_PATH % (project_id, ''))\n\n    args = {}\n    if max_results != 0:\n      args['maxResults'] = max_results\n    if page_token is not None:\n      args['pageToken'] = page_token\n\n    return datalab.utils.Http.request(url, args=args, credentials=self._credentials)\n\n  def tables_get(self, table_name):\n    \"\"\"Issues a request to retrieve information about a table.\n\n    Args:\n      table_name: a tuple representing the full name of the table.\n    Returns:\n      A parsed result object.\n    Raises:\n      Exception if there is an error performing the operation.\n    \"\"\"\n    url = Api._ENDPOINT + (Api._TABLES_PATH % table_name)\n    return datalab.utils.Http.request(url, credentials=self._credentials)\n\n  def tables_list(self, dataset_name, max_results=0, page_token=None):\n    \"\"\"Issues a request to retrieve a list of tables.\n\n    Args:\n      dataset_name: the name of the dataset to enumerate.\n      max_results: an optional maximum number of tables to retrieve.\n      page_token: an optional token to continue the retrieval.\n    Returns:\n      A parsed result object.\n    Raises:\n      Exception if there is an error performing the operation.\n    \"\"\"\n    url = Api._ENDPOINT +\\\n        (Api._TABLES_PATH % (dataset_name.project_id, dataset_name.dataset_id, '', ''))\n\n    args = {}\n    if max_results != 0:\n      args['maxResults'] = max_results\n    if page_token is not None:\n      args['pageToken'] = page_token\n\n    return datalab.utils.Http.request(url, args=args, credentials=self._credentials)\n\n  def tables_insert(self, table_name, schema=None, query=None, friendly_name=None,\n                    description=None):\n    \"\"\"Issues a request to create a table or view in the specified dataset with the specified id.\n       A schema must be provided to create a Table, or a query must be provided to create a View.\n\n    Args:\n      table_name: the name of the table as a tuple of components.\n      schema: the schema, if this is a Table creation.\n      query: the query, if this is a View creation.\n      friendly_name: an optional friendly name.\n      description: an optional description.\n    Returns:\n      A parsed result object.\n    Raises:\n      Exception if there is an error performing the operation.\n    \"\"\"\n    url = Api._ENDPOINT + \\\n        (Api._TABLES_PATH % (table_name.project_id, table_name.dataset_id, '', ''))\n\n    data = {\n        'kind': 'bigquery#table',\n        'tableReference': {\n            'projectId': table_name.project_id,\n            'datasetId': table_name.dataset_id,\n            'tableId': table_name.table_id\n        }\n    }\n    if schema:\n      data['schema'] = {'fields': schema}\n    if query:\n      data['view'] = {'query': query}\n    if friendly_name:\n      data['friendlyName'] = friendly_name\n    if description:\n      data['description'] = description\n\n    return datalab.utils.Http.request(url, data=data, credentials=self._credentials)\n\n  def tabledata_insert_all(self, table_name, rows):\n    \"\"\"Issues a request to insert data into a table.\n\n    Args:\n      table_name: the name of the table as a tuple of components.\n      rows: the data to populate the table, as a list of dictionaries.\n    Returns:\n      A parsed result object.\n    Raises:\n      Exception if there is an error performing the operation.\n    \"\"\"\n    url = Api._ENDPOINT + (Api._TABLES_PATH % table_name) + \"/insertAll\"\n\n    data = {\n        'kind': 'bigquery#tableDataInsertAllRequest',\n        'rows': rows\n    }\n\n    return datalab.utils.Http.request(url, data=data, credentials=self._credentials)\n\n  def tabledata_list(self, table_name, start_index=None, max_results=None, page_token=None):\n    \"\"\" Retrieves the contents of a table.\n\n    Args:\n      table_name: the name of the table as a tuple of components.\n      start_index: the index of the row at which to start retrieval.\n      max_results: an optional maximum number of rows to retrieve.\n      page_token: an optional token to continue the retrieval.\n    Returns:\n      A parsed result object.\n    Raises:\n      Exception if there is an error performing the operation.\n    \"\"\"\n    url = Api._ENDPOINT + (Api._TABLEDATA_PATH % table_name)\n    args = {}\n    if start_index:\n      args['startIndex'] = start_index\n    if max_results:\n      args['maxResults'] = max_results\n    if page_token is not None:\n      args['pageToken'] = page_token\n    return datalab.utils.Http.request(url, args=args, credentials=self._credentials)\n\n  def table_delete(self, table_name):\n    \"\"\"Issues a request to delete a table.\n\n    Args:\n      table_name: the name of the table as a tuple of components.\n    Returns:\n      A parsed result object.\n    Raises:\n      Exception if there is an error performing the operation.\n    \"\"\"\n    url = Api._ENDPOINT + (Api._TABLES_PATH % table_name)\n    return datalab.utils.Http.request(url, method='DELETE', credentials=self._credentials,\n                                      raw_response=True)\n\n  def table_extract(self, table_name, destination, format='CSV', compress=True,\n                    field_delimiter=',', print_header=True):\n    \"\"\"Exports the table to GCS.\n\n    Args:\n      table_name: the name of the table as a tuple of components.\n      destination: the destination URI(s). Can be a single URI or a list.\n      format: the format to use for the exported data; one of CSV, NEWLINE_DELIMITED_JSON or AVRO.\n          Defaults to CSV.\n      compress: whether to compress the data on export. Compression is not supported for\n          AVRO format. Defaults to False.\n      field_delimiter: for CSV exports, the field delimiter to use. Defaults to ','\n      print_header: for CSV exports, whether to include an initial header line. Default true.\n    Returns:\n      A parsed result object.\n    Raises:\n      Exception if there is an error performing the operation.\n    \"\"\"\n    url = Api._ENDPOINT + (Api._JOBS_PATH % (table_name.project_id, ''))\n    if isinstance(destination, basestring):\n      destination = [destination]\n    data = {\n        # 'projectId': table_name.project_id, # Code sample shows this but it is not in job\n        # reference spec. Filed as b/19235843\n        'kind': 'bigquery#job',\n        'configuration': {\n            'extract': {\n                'sourceTable': {\n                    'projectId': table_name.project_id,\n                    'datasetId': table_name.dataset_id,\n                    'tableId': table_name.table_id,\n                },\n                'compression': 'GZIP' if compress else 'NONE',\n                'fieldDelimiter': field_delimiter,\n                'printHeader': print_header,\n                'destinationUris': destination,\n                'destinationFormat': format,\n            }\n        }\n    }\n    return datalab.utils.Http.request(url, data=data, credentials=self._credentials)\n\n  def table_update(self, table_name, table_info):\n    \"\"\"Updates the Table info.\n\n    Args:\n      table_name: the name of the table to update as a tuple of components.\n      table_info: the Table resource with updated fields.\n    \"\"\"\n    url = Api._ENDPOINT + (Api._TABLES_PATH % table_name)\n    return datalab.utils.Http.request(url, method='PUT', data=table_info,\n                                      credentials=self._credentials)\n"
  },
  {
    "path": "datalab/bigquery/_csv_options.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Implements CSV options for External Tables and Table loads from GCS.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom builtins import object\n\n\nclass CSVOptions(object):\n\n  def __init__(self, delimiter=',', skip_leading_rows=0, encoding='utf-8', quote='\"',\n               allow_quoted_newlines=False, allow_jagged_rows=False):\n\n    \"\"\" Initialize an instance of CSV options.\n\n    Args:\n      delimiter: The separator for fields in a CSV file. BigQuery converts the string to\n          ISO-8859-1 encoding, and then uses the first byte of the encoded string to split the data\n          as raw binary (default ',').\n      skip_leading_rows: A number of rows at the top of a CSV file to skip (default 0).\n      encoding: The character encoding of the data, either 'utf-8' (the default) or 'iso-8859-1'.\n      quote: The value used to quote data sections in a CSV file; default '\"'. If your data does\n          not contain quoted sections, set the property value to an empty string. If your data\n          contains quoted newline characters, you must also enable allow_quoted_newlines.\n      allow_quoted_newlines: If True, allow quoted data sections in CSV files that contain newline\n          characters (default False).\n      allow_jagged_rows: If True, accept rows in CSV files that are missing trailing optional\n          columns; the missing values are treated as nulls (default False).\n    \"\"\"\n    encoding_upper = encoding.upper()\n    if encoding_upper != 'UTF-8' and encoding_upper != 'ISO-8859-1':\n      raise Exception(\"Invalid source encoding %s\" % encoding)\n\n    self._delimiter = delimiter\n    self._skip_leading_rows = skip_leading_rows\n    self._encoding = encoding\n    self._quote = quote\n    self._allow_quoted_newlines = allow_quoted_newlines\n    self._allow_jagged_rows = allow_jagged_rows\n\n  @property\n  def delimiter(self):\n    return self._delimiter\n\n  @property\n  def skip_leading_rows(self):\n    return self._skip_leading_rows\n\n  @property\n  def encoding(self):\n    return self._encoding\n\n  @property\n  def quote(self):\n      return self._quote\n\n  @property\n  def allow_quoted_newlines(self):\n    return self._allow_quoted_newlines\n\n  @property\n  def allow_jagged_rows(self):\n    return self._allow_jagged_rows\n\n  def _to_query_json(self):\n    \"\"\" Return the options as a dictionary to be used as JSON in a query job. \"\"\"\n    return {\n      'quote': self._quote,\n      'fieldDelimiter': self._delimiter,\n      'encoding': self._encoding.upper(),\n      'skipLeadingRows': self._skip_leading_rows,\n      'allowQuotedNewlines': self._allow_quoted_newlines,\n      'allowJaggedRows': self._allow_jagged_rows\n    }\n"
  },
  {
    "path": "datalab/bigquery/_dataset.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Implements Dataset, and related Dataset BigQuery APIs.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom builtins import object\n\nimport datalab.context\nimport datalab.utils\n\nfrom . import _api\nfrom . import _table\nfrom . import _utils\nfrom . import _view\n\n\nclass Dataset(object):\n  \"\"\"Represents a list of BigQuery tables in a dataset.\"\"\"\n\n  def __init__(self, name, context=None):\n    \"\"\"Initializes an instance of a Dataset.\n\n    Args:\n      name: the name of the dataset, as a string or (project_id, dataset_id) tuple.\n      context: an optional Context object providing project_id and credentials. If a specific\n          project id or credentials are unspecified, the default ones configured at the global\n          level are used.\n    Raises:\n      Exception if the name is invalid.\n      \"\"\"\n    if context is None:\n      context = datalab.context.Context.default()\n    self._context = context\n    self._api = _api.Api(context)\n    self._name_parts = _utils.parse_dataset_name(name, self._api.project_id)\n    self._full_name = '%s:%s' % self._name_parts\n    self._info = None\n    try:\n      self._info = self._get_info()\n    except datalab.utils.RequestException:\n      pass\n\n  @property\n  def name(self):\n    \"\"\"The DatasetName named tuple (project_id, dataset_id) for the dataset.\"\"\"\n    return self._name_parts\n\n  @property\n  def description(self):\n    \"\"\"The description of the dataset, if any.\n\n    Raises:\n      Exception if the dataset exists but the metadata for the dataset could not be retrieved.\n    \"\"\"\n    self._get_info()\n    return self._info['description'] if self._info else None\n\n  @property\n  def friendly_name(self):\n    \"\"\"The friendly name of the dataset, if any.\n\n    Raises:\n      Exception if the dataset exists but the metadata for the dataset could not be retrieved.\n    \"\"\"\n    self._get_info()\n    return self._info['friendlyName'] if self._info else None\n\n  def _get_info(self):\n    try:\n      if self._info is None:\n        self._info = self._api.datasets_get(self._name_parts)\n      return self._info\n    except datalab.utils.RequestException as e:\n      if e.status == 404:\n        return None\n      raise e\n    except Exception as e:\n      raise e\n\n  def exists(self):\n    \"\"\" Checks if the dataset exists.\n\n    Returns:\n      True if the dataset exists; False otherwise.\n    Raises:\n      Exception if the dataset exists but the metadata for the dataset could not be retrieved.\n    \"\"\"\n    self._get_info()\n    return self._info is not None\n\n  def delete(self, delete_contents=False):\n    \"\"\"Issues a request to delete the dataset.\n\n    Args:\n      delete_contents: if True, any tables and views in the dataset will be deleted. If False\n          and the dataset is non-empty an exception will be raised.\n    Returns:\n      None on success.\n    Raises:\n      Exception if the delete fails (including if table was nonexistent).\n    \"\"\"\n    if not self.exists():\n      raise Exception('Cannot delete non-existent dataset %s' % self._full_name)\n    try:\n      self._api.datasets_delete(self._name_parts, delete_contents=delete_contents)\n    except Exception as e:\n      raise e\n    self._info = None\n    return None\n\n  def create(self, friendly_name=None, description=None):\n    \"\"\"Creates the Dataset with the specified friendly name and description.\n\n    Args:\n      friendly_name: (optional) the friendly name for the dataset if it is being created.\n      description: (optional) a description for the dataset if it is being created.\n    Returns:\n      The Dataset.\n    Raises:\n      Exception if the Dataset could not be created.\n    \"\"\"\n    if not self.exists():\n      try:\n        response = self._api.datasets_insert(self._name_parts,\n                                             friendly_name=friendly_name,\n                                             description=description)\n      except Exception as e:\n        raise e\n      if 'selfLink' not in response:\n        raise Exception(\"Could not create dataset %s\" % self._full_name)\n    return self\n\n  def update(self, friendly_name=None, description=None):\n    \"\"\" Selectively updates Dataset information.\n\n    Args:\n      friendly_name: if not None, the new friendly name.\n      description: if not None, the new description.\n\n    Returns:\n    \"\"\"\n    self._get_info()\n\n    if self._info:\n      if friendly_name:\n        self._info['friendlyName'] = friendly_name\n      if description:\n        self._info['description'] = description\n      try:\n        self._api.datasets_update(self._name_parts, self._info)\n      except Exception as e:\n        raise e\n      finally:\n        self._info = None  # need a refresh\n\n  def _retrieve_items(self, page_token, item_type):\n    try:\n      list_info = self._api.tables_list(self._name_parts, page_token=page_token)\n    except Exception as e:\n      raise e\n\n    tables = list_info.get('tables', [])\n    contents = []\n    if len(tables):\n      try:\n        for info in tables:\n          if info['type'] != item_type:\n            continue\n          if info['type'] == 'TABLE':\n            item = _table.Table((info['tableReference']['projectId'],\n                                 info['tableReference']['datasetId'],\n                                 info['tableReference']['tableId']), self._context)\n          else:\n            item = _view.View((info['tableReference']['projectId'],\n                               info['tableReference']['datasetId'],\n                               info['tableReference']['tableId']), self._context)\n          contents.append(item)\n      except KeyError:\n        raise Exception('Unexpected item list response')\n\n    page_token = list_info.get('nextPageToken', None)\n    return contents, page_token\n\n  def _retrieve_tables(self, page_token, _):\n    return self._retrieve_items(page_token=page_token, item_type='TABLE')\n\n  def _retrieve_views(self, page_token, _):\n    return self._retrieve_items(page_token=page_token, item_type='VIEW')\n\n  def tables(self):\n    \"\"\" Returns an iterator for iterating through the Tables in the dataset. \"\"\"\n    return iter(datalab.utils.Iterator(self._retrieve_tables))\n\n  def views(self):\n    \"\"\" Returns an iterator for iterating through the Views in the dataset. \"\"\"\n    return iter(datalab.utils.Iterator(self._retrieve_views))\n\n  def __iter__(self):\n    \"\"\" Returns an iterator for iterating through the Tables in the dataset. \"\"\"\n    return self.tables()\n\n  def __str__(self):\n    \"\"\"Returns a string representation of the dataset using its specified name.\n\n    Returns:\n      The string representation of this object.\n    \"\"\"\n    return self._full_name\n\n  def __repr__(self):\n    \"\"\"Returns a representation for the dataset for showing in the notebook.\n    \"\"\"\n    return 'Dataset %s' % self._full_name\n\n\nclass Datasets(object):\n  \"\"\" Iterator class for enumerating the datasets in a project. \"\"\"\n\n  def __init__(self, project_id=None, context=None):\n    \"\"\" Initialize the Datasets object.\n\n    Args:\n      project_id: the ID of the project whose datasets you want to list. If None defaults\n          to the project in the context.\n      context: an optional Context object providing project_id and credentials. If a specific\n          project id or credentials are unspecified, the default ones configured at the global\n          level are used.\n    \"\"\"\n    if context is None:\n      context = datalab.context.Context.default()\n    self._context = context\n    self._api = _api.Api(context)\n    self._project_id = project_id if project_id else self._api.project_id\n\n  def _retrieve_datasets(self, page_token, count):\n    try:\n      list_info = self._api.datasets_list(self._project_id, max_results=count,\n                                          page_token=page_token)\n    except Exception as e:\n      raise e\n\n    datasets = list_info.get('datasets', [])\n    if len(datasets):\n      try:\n        datasets = [Dataset((info['datasetReference']['projectId'],\n                             info['datasetReference']['datasetId']), self._context)\n                    for info in datasets]\n      except KeyError:\n        raise Exception('Unexpected response from server.')\n\n    page_token = list_info.get('nextPageToken', None)\n    return datasets, page_token\n\n  def __iter__(self):\n    \"\"\" Returns an iterator for iterating through the Datasets in the project.\n    \"\"\"\n    return iter(datalab.utils.Iterator(self._retrieve_datasets))\n"
  },
  {
    "path": "datalab/bigquery/_dialect.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Google Cloud Platform library - BigQuery SQL Dialect\"\"\"\nfrom __future__ import absolute_import\n\n\nclass Dialect(object):\n  \"\"\"\n  Represents the default BigQuery SQL dialect\n  \"\"\"\n  _global_dialect = None\n\n  def __init__(self, bq_dialect):\n    self._global_dialect = bq_dialect\n\n  @property\n  def bq_dialect(self):\n    \"\"\"Retrieves the value of the bq_dialect property.\n\n    Returns:\n      The default BigQuery SQL dialect\n    \"\"\"\n    return self._global_dialect\n\n  def set_bq_dialect(self, bq_dialect):\n    \"\"\" Set the default BigQuery SQL dialect\"\"\"\n    if bq_dialect in ['legacy', 'standard']:\n      self._global_dialect = bq_dialect\n\n  @staticmethod\n  def default():\n    \"\"\"Retrieves the default BigQuery SQL dialect, creating it if necessary.\n\n    Returns:\n      An initialized and shared instance of a Dialect object.\n    \"\"\"\n    if Dialect._global_dialect is None:\n      Dialect._global_dialect = Dialect('legacy')\n    return Dialect._global_dialect\n"
  },
  {
    "path": "datalab/bigquery/_federated_table.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Implements External Table functionality.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom builtins import object\n\nfrom . import _csv_options\n\n\nclass FederatedTable(object):\n\n  @staticmethod\n  def from_storage(source, source_format='csv', csv_options=None, ignore_unknown_values=False,\n                   max_bad_records=0, compressed=False, schema=None):\n\n    \"\"\" Create an external table for a GCS object.\n\n    Args:\n      source: the URL of the source objects(s). Can include a wildcard '*' at the end of the item\n         name. Can be a single source or a list.\n      source_format: the format of the data, 'csv' or 'json'; default 'csv'.\n      csv_options: For CSV files, the options such as quote character and delimiter.\n      ignore_unknown_values: If True, accept rows that contain values that do not match the schema;\n          the unknown values are ignored (default False).\n      max_bad_records: The maximum number of bad records that are allowed (and ignored) before\n          returning an 'invalid' error in the Job result (default 0).\n      compressed: whether the data is GZ compressed or not (default False). Note that compressed\n          data can be used as a federated table but cannot be loaded into a BQ Table.\n      schema: the schema of the data. This is required for this table to be used as a federated\n          table or to be loaded using a Table object that itself has no schema (default None).\n\n  \"\"\"\n    result = FederatedTable()\n    # Do some sanity checking and concert some params from friendly form to form used by BQ.\n    if source_format == 'csv':\n      result._bq_source_format = 'CSV'\n      if csv_options is None:\n        csv_options = _csv_options.CSVOptions()  # use defaults\n    elif source_format == 'json':\n      if csv_options:\n        raise Exception('CSV options are not support for JSON tables')\n      result._bq_source_format = 'NEWLINE_DELIMITED_JSON'\n    else:\n      raise Exception(\"Invalid source format %s\" % source_format)\n\n    result._source = source if isinstance(source, list) else [source]\n    result._source_format = source_format\n    result._csv_options = csv_options\n    result._ignore_unknown_values = ignore_unknown_values\n    result._max_bad_records = max_bad_records\n    result._compressed = compressed\n    result._schema = schema\n    return result\n\n  def __init__(self):\n\n    \"\"\" Create an external table reference. Do not call this directly; use factory method(s). \"\"\"\n    # Do some sanity checking and concert some params from friendly form to form used by BQ.\n    self._bq_source_format = None\n    self._source = None\n    self._source_format = None\n    self._csv_options = None\n    self._ignore_unknown_values = None\n    self._max_bad_records = None\n    self._compressed = None\n    self._schema = None\n\n  @property\n  def schema(self):\n    return self._schema\n\n  def _to_query_json(self):\n    \"\"\" Return the table as a dictionary to be used as JSON in a query job. \"\"\"\n    json = {\n      'compression': 'GZIP' if self._compressed else 'NONE',\n      'ignoreUnknownValues': self._ignore_unknown_values,\n      'maxBadRecords': self._max_bad_records,\n      'sourceFormat': self._bq_source_format,\n      'sourceUris': self._source,\n    }\n    if self._source_format == 'csv' and self._csv_options:\n      json['csvOptions'] = {}\n      json['csvOptions'].update(self._csv_options._to_query_json())\n    if self._schema:\n      json['schema'] = {'fields': self._schema._bq_schema}\n    return json\n"
  },
  {
    "path": "datalab/bigquery/_job.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Implements BigQuery Job functionality.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom __future__ import division\n\nimport datetime\n\nimport datalab.utils\n\nfrom . import _api\n\n\nclass Job(datalab.utils.GCPJob):\n  \"\"\"Represents a BigQuery Job.\n  \"\"\"\n\n  def __init__(self, job_id, context):\n    \"\"\"Initializes an instance of a Job.\n\n    Args:\n      job_id: the BigQuery job ID corresponding to this job.\n      context: a Context object providing project_id and credentials.\n    \"\"\"\n    super(Job, self).__init__(job_id, context)\n\n  def _create_api(self, context):\n    return _api.Api(context)\n\n  def _refresh_state(self):\n    \"\"\" Get the state of a job. If the job is complete this does nothing;\n        otherwise it gets a refreshed copy of the job resource.\n    \"\"\"\n    # TODO(gram): should we put a choke on refreshes? E.g. if the last call was less than\n    # a second ago should we return the cached value?\n    if self._is_complete:\n      return\n\n    try:\n      response = self._api.jobs_get(self._job_id)\n    except Exception as e:\n      raise e\n\n    if 'status' in response:\n      status = response['status']\n      if 'state' in status and status['state'] == 'DONE':\n        self._end_time = datetime.datetime.utcnow()\n        self._is_complete = True\n        self._process_job_status(status)\n\n    if 'statistics' in response:\n      statistics = response['statistics']\n      start_time = statistics.get('creationTime', None)\n      end_time = statistics.get('endTime', None)\n      if start_time and end_time and end_time >= start_time:\n        self._start_time = datetime.datetime.fromtimestamp(float(start_time) / 1000.0)\n        self._end_time = datetime.datetime.fromtimestamp(float(end_time) / 1000.0)\n\n  def _process_job_status(self, status):\n    if 'errorResult' in status:\n      error_result = status['errorResult']\n      location = error_result.get('location', None)\n      message = error_result.get('message', None)\n      reason = error_result.get('reason', None)\n      self._fatal_error = datalab.utils.JobError(location, message, reason)\n    if 'errors' in status:\n      self._errors = []\n      for error in status['errors']:\n        location = error.get('location', None)\n        message = error.get('message', None)\n        reason = error.get('reason', None)\n        self._errors.append(datalab.utils.JobError(location, message, reason))\n"
  },
  {
    "path": "datalab/bigquery/_parser.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Implements BigQuery related data parsing helpers.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import unicode_literals\nfrom builtins import zip\nfrom builtins import str\nfrom builtins import object\n\nimport datetime\n\n\nclass Parser(object):\n  \"\"\"A set of helper functions to parse data in BigQuery responses.\"\"\"\n\n  def __init__(self):\n    pass\n\n  @staticmethod\n  def parse_row(schema, data):\n    \"\"\"Parses a row from query results into an equivalent object.\n\n    Args:\n      schema: the array of fields defining the schema of the data.\n      data: the JSON row from a query result.\n    Returns:\n      The parsed row object.\n    \"\"\"\n    def parse_value(data_type, value):\n      \"\"\"Parses a value returned from a BigQuery response.\n\n      Args:\n        data_type: the type of the value as specified by the schema.\n        value: the raw value to return (before casting to data_type).\n\n      Returns:\n        The value cast to the data_type.\n      \"\"\"\n      if value is not None:\n        if value == 'null':\n          value = None\n        elif data_type == 'INTEGER':\n          value = int(value)\n        elif data_type == 'FLOAT':\n          value = float(value)\n        elif data_type == 'TIMESTAMP':\n          value = datetime.datetime.utcfromtimestamp(float(value))\n        elif data_type == 'BOOLEAN':\n          value = value == 'true'\n        elif (type(value) != str):\n          # TODO(gram): Handle nested JSON records\n          value = str(value)\n      return value\n\n    row = {}\n    if data is None:\n      return row\n\n    for i, (field, schema_field) in enumerate(zip(data['f'], schema)):\n      val = field['v']\n      name = schema_field['name']\n      data_type = schema_field['type']\n      repeated = True if 'mode' in schema_field and schema_field['mode'] == 'REPEATED' else False\n\n      if repeated and val is None:\n        row[name] = []\n      elif data_type == 'RECORD':\n        sub_schema = schema_field['fields']\n        if repeated:\n          row[name] = [Parser.parse_row(sub_schema, v['v']) for v in val]\n        else:\n          row[name] = Parser.parse_row(sub_schema, val)\n      elif repeated:\n        row[name] = [parse_value(data_type, v['v']) for v in val]\n      else:\n        row[name] = parse_value(data_type, val)\n\n    return row\n\n  @staticmethod\n  def parse_timestamp(value):\n    \"\"\"Parses a timestamp.\n\n    Args:\n      value: the number of milliseconds since epoch.\n    \"\"\"\n    return datetime.datetime.utcfromtimestamp(float(value) / 1000.0)\n"
  },
  {
    "path": "datalab/bigquery/_query.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Implements Query BigQuery API.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom builtins import object\n\nimport datalab.context\nimport datalab.data\nimport datalab.utils\n\nfrom . import _api\nfrom . import _federated_table\nfrom . import _query_job\nfrom . import _sampling\nfrom . import _udf\nfrom . import _utils\n\n\nclass Query(object):\n  \"\"\"Represents a Query object that encapsulates a BigQuery SQL query.\n\n  This object can be used to execute SQL queries and retrieve results.\n  \"\"\"\n\n  @staticmethod\n  def sampling_query(sql, context, fields=None, count=5, sampling=None, udfs=None,\n                     data_sources=None):\n    \"\"\"Returns a sampling Query for the SQL object.\n\n    Args:\n      sql: the SQL statement (string) or Query object to sample.\n      context: a Context object providing project_id and credentials.\n      fields: an optional list of field names to retrieve.\n      count: an optional count of rows to retrieve which is used if a specific\n          sampling is not specified.\n      sampling: an optional sampling strategy to apply to the table.\n      udfs: array of UDFs referenced in the SQL.\n      data_sources: dictionary of federated (external) tables referenced in the SQL.\n    Returns:\n      A Query object for sampling the table.\n    \"\"\"\n    return Query(_sampling.Sampling.sampling_query(sql, fields, count, sampling), context=context,\n                 udfs=udfs, data_sources=data_sources)\n\n  def __init__(self, sql, context=None, values=None, udfs=None, data_sources=None, **kwargs):\n    \"\"\"Initializes an instance of a Query object.\n       Note that either values or kwargs may be used, but not both.\n\n    Args:\n      sql: the BigQuery SQL query string to execute, or a SqlStatement object. The latter will\n          have any variable references replaced before being associated with the Query (i.e.\n          once constructed the SQL associated with a Query is static).\n\n          It is possible to have variable references in a query string too provided the variables\n          are passed as keyword arguments to this constructor.\n\n      context: an optional Context object providing project_id and credentials. If a specific\n          project id or credentials are unspecified, the default ones configured at the global\n          level are used.\n      values: a dictionary used to expand variables if passed a SqlStatement or a string with\n          variable references.\n      udfs: array of UDFs referenced in the SQL.\n      data_sources: dictionary of federated (external) tables referenced in the SQL.\n      kwargs: arguments to use when expanding the variables if passed a SqlStatement\n          or a string with variable references.\n\n    Raises:\n      Exception if expansion of any variables failed.\n      \"\"\"\n    if context is None:\n      context = datalab.context.Context.default()\n    self._context = context\n    self._api = _api.Api(context)\n    self._data_sources = data_sources\n    self._udfs = udfs\n\n    if data_sources is None:\n      data_sources = {}\n\n    self._results = None\n    self._code = None\n    self._imports = []\n    if values is None:\n      values = kwargs\n\n    self._sql = datalab.data.SqlModule.expand(sql, values)\n\n    # We need to take care not to include the same UDF code twice so we use sets.\n    udfs = set(udfs if udfs else [])\n    for value in list(values.values()):\n      if isinstance(value, _udf.UDF):\n        udfs.add(value)\n    included_udfs = set([])\n\n    tokens = datalab.data.tokenize(self._sql)\n    udf_dict = {udf.name: udf for udf in udfs}\n\n    for i, token in enumerate(tokens):\n      # Find the preceding and following non-whitespace tokens\n      prior = i - 1\n      while prior >= 0 and tokens[prior].isspace():\n        prior -= 1\n      if prior < 0:\n        continue\n      next = i + 1\n      while next < len(tokens) and tokens[next].isspace():\n        next += 1\n      if next >= len(tokens):\n        continue\n\n      uprior = tokens[prior].upper()\n      if uprior != 'FROM' and uprior != 'JOIN':\n        continue\n\n      # Check for external tables.\n      if tokens[next] not in \"[('\\\"\":\n        if token not in data_sources:\n          if values and token in values:\n            if isinstance(values[token], _federated_table.FederatedTable):\n              data_sources[token] = values[token]\n\n      # Now check for UDF calls.\n      if uprior != 'FROM' or tokens[next] != '(':\n        continue\n\n      # We have a 'FROM token (' sequence.\n\n      if token in udf_dict:\n        udf = udf_dict[token]\n        if token not in included_udfs:\n          included_udfs.add(token)\n          if self._code is None:\n            self._code = []\n          self._code.append(udf.code)\n          if udf.imports:\n            self._imports.extend(udf.imports)\n\n        fields = ', '.join([f[0] for f in udf._outputs])\n        tokens[i] = '(SELECT %s FROM %s' % (fields, token)\n\n        # Find the closing parenthesis and add the additional one now needed.\n        num_paren = 0\n        j = i + 1\n        while j < len(tokens):\n          if tokens[j] == '(':\n            num_paren += 1\n          elif tokens[j] == ')':\n            num_paren -= 1\n            if num_paren == 0:\n              tokens[j] = '))'\n              break\n          j += 1\n\n    self._external_tables = None\n    if len(data_sources):\n      self._external_tables = {}\n      for name, table in list(data_sources.items()):\n        if table.schema is None:\n          raise Exception('Referenced external table %s has no known schema' % name)\n        self._external_tables[name] = table._to_query_json()\n\n    self._sql = ''.join(tokens)\n\n  def _repr_sql_(self):\n    \"\"\"Creates a SQL representation of this object.\n\n    Returns:\n      The SQL representation to use when embedding this object into other SQL.\n    \"\"\"\n    return '(%s)' % self._sql\n\n  def __str__(self):\n    \"\"\"Creates a string representation of this object.\n\n    Returns:\n      The string representation of this object (the unmodified SQL).\n    \"\"\"\n    return self._sql\n\n  def __repr__(self):\n    \"\"\"Creates a friendly representation of this object.\n\n    Returns:\n      The friendly representation of this object (the unmodified SQL).\n    \"\"\"\n    return self._sql\n\n  @property\n  def sql(self):\n    \"\"\" Get the SQL for the query. \"\"\"\n    return self._sql\n\n  @property\n  def scripts(self):\n    \"\"\" Get the code for any Javascript UDFs used in the query. \"\"\"\n    return self._code\n\n  def results(self, use_cache=True, dialect=None, billing_tier=None):\n    \"\"\"Retrieves table of results for the query. May block if the query must be executed first.\n\n    Args:\n      use_cache: whether to use cached results or not. Ignored if append is specified.\n      dialect : {'legacy', 'standard'}, default 'legacy'\n          'legacy' : Use BigQuery's legacy SQL dialect.\n          'standard' : Use BigQuery's standard SQL (beta), which is\n          compliant with the SQL 2011 standard.\n      billing_tier: Limits the billing tier for this job. Queries that have resource\n          usage beyond this tier will fail (without incurring a charge). If unspecified, this\n          will be set to your project default. This can also be used to override your\n          project-wide default billing tier on a per-query basis.\n    Returns:\n      A QueryResultsTable containing the result set.\n    Raises:\n      Exception if the query could not be executed or query response was malformed.\n    \"\"\"\n    if not use_cache or (self._results is None):\n      self.execute(use_cache=use_cache, dialect=dialect, billing_tier=billing_tier)\n    return self._results.results\n\n  def extract(self, storage_uris, format='csv', csv_delimiter=',', csv_header=True,\n              compress=False, use_cache=True, dialect=None, billing_tier=None):\n    \"\"\"Exports the query results to GCS.\n\n    Args:\n      storage_uris: the destination URI(s). Can be a single URI or a list.\n      format: the format to use for the exported data; one of 'csv', 'json', or 'avro'\n          (default 'csv').\n      csv_delimiter: for csv exports, the field delimiter to use (default ',').\n      csv_header: for csv exports, whether to include an initial header line (default True).\n      compress: whether to compress the data on export. Compression is not supported for\n          AVRO format (default False).\n      use_cache: whether to use cached results or not (default True).\n      dialect : {'legacy', 'standard'}, default 'legacy'\n          'legacy' : Use BigQuery's legacy SQL dialect.\n          'standard' : Use BigQuery's standard SQL (beta), which is\n          compliant with the SQL 2011 standard.\n      billing_tier: Limits the billing tier for this job. Queries that have resource\n          usage beyond this tier will fail (without incurring a charge). If unspecified, this\n          will be set to your project default. This can also be used to override your\n          project-wide default billing tier on a per-query basis.\n    Returns:\n      A Job object for the export Job if it was completed successfully; else None.\n    Raises:\n      An Exception if the query or extract failed.\n    \"\"\"\n    return self.results(use_cache=use_cache, dialect=dialect,\n                        billing_tier=billing_tier).extract(storage_uris, format=format,\n                                                           csv_delimiter=csv_delimiter,\n                                                           csv_header=csv_header,\n                                                           compress=compress)\n\n  @datalab.utils.async_method\n  def extract_async(self, storage_uris, format='csv', csv_delimiter=',', csv_header=True,\n                    compress=False, use_cache=True, dialect=None, billing_tier=None):\n    \"\"\"Exports the query results to GCS. Returns a Job immediately.\n\n    Note that there are two jobs that may need to be run sequentially, one to run the query,\n    and the second to extract the resulting table. These are wrapped by a single outer Job.\n\n    If the query has already been executed and you would prefer to get a Job just for the\n    extract, you can can call extract_async on the QueryResultsTable instead; i.e.:\n\n        query.results().extract_async(...)\n\n    Args:\n      storage_uris: the destination URI(s). Can be a single URI or a list.\n      format: the format to use for the exported data; one of 'csv', 'json', or 'avro'\n          (default 'csv').\n      csv_delimiter: for CSV exports, the field delimiter to use (default ',').\n      csv_header: for CSV exports, whether to include an initial header line (default True).\n      compress: whether to compress the data on export. Compression is not supported for\n          AVRO format (default False).\n      use_cache: whether to use cached results or not (default True).\n      dialect : {'legacy', 'standard'}, default 'legacy'\n          'legacy' : Use BigQuery's legacy SQL dialect.\n          'standard' : Use BigQuery's standard SQL (beta), which is\n          compliant with the SQL 2011 standard.\n      billing_tier: Limits the billing tier for this job. Queries that have resource\n          usage beyond this tier will fail (without incurring a charge). If unspecified, this\n          will be set to your project default. This can also be used to override your\n          project-wide default billing tier on a per-query basis.\n    Returns:\n      A Job for the combined (execute, extract) task that will in turn return the Job object for\n      the completed extract task when done; else None.\n    Raises:\n      An Exception if the query failed.\n    \"\"\"\n    return self.extract(storage_uris, format=format, csv_delimiter=csv_delimiter,\n                        csv_header=csv_header, use_cache=use_cache, compress=compress,\n                        dialect=dialect, billing_tier=billing_tier)\n\n  def to_dataframe(self, start_row=0, max_rows=None, use_cache=True, dialect=None,\n                   billing_tier=None):\n    \"\"\" Exports the query results to a Pandas dataframe.\n\n    Args:\n      start_row: the row of the table at which to start the export (default 0).\n      max_rows: an upper limit on the number of rows to export (default None).\n      use_cache: whether to use cached results or not (default True).\n      dialect : {'legacy', 'standard'}, default 'legacy'\n          'legacy' : Use BigQuery's legacy SQL dialect.\n          'standard' : Use BigQuery's standard SQL (beta), which is\n          compliant with the SQL 2011 standard.\n      billing_tier: Limits the billing tier for this job. Queries that have resource\n          usage beyond this tier will fail (without incurring a charge). If unspecified, this\n          will be set to your project default. This can also be used to override your\n          project-wide default billing tier on a per-query basis.\n    Returns:\n      A Pandas dataframe containing the table data.\n    \"\"\"\n    return self.results(use_cache=use_cache, dialect=dialect, billing_tier=billing_tier) \\\n        .to_dataframe(start_row=start_row, max_rows=max_rows)\n\n  def to_file(self, path, format='csv', csv_delimiter=',', csv_header=True, use_cache=True,\n              dialect=None, billing_tier=None):\n    \"\"\"Save the results to a local file in CSV format.\n\n    Args:\n      path: path on the local filesystem for the saved results.\n      format: the format to use for the exported data; currently only 'csv' is supported.\n      csv_delimiter: for CSV exports, the field delimiter to use. Defaults to ','\n      csv_header: for CSV exports, whether to include an initial header line. Default true.\n      use_cache: whether to use cached results or not.\n      dialect : {'legacy', 'standard'}, default 'legacy'\n          'legacy' : Use BigQuery's legacy SQL dialect.\n          'standard' : Use BigQuery's standard SQL (beta), which is\n          compliant with the SQL 2011 standard.\n      billing_tier: Limits the billing tier for this job. Queries that have resource\n          usage beyond this tier will fail (without incurring a charge). If unspecified, this\n          will be set to your project default. This can also be used to override your\n          project-wide default billing tier on a per-query basis.\n    Returns:\n      The path to the local file.\n    Raises:\n      An Exception if the operation failed.\n    \"\"\"\n    self.results(use_cache=use_cache, dialect=dialect, billing_tier=billing_tier) \\\n        .to_file(path, format=format, csv_delimiter=csv_delimiter, csv_header=csv_header)\n    return path\n\n  @datalab.utils.async_method\n  def to_file_async(self, path, format='csv', csv_delimiter=',', csv_header=True, use_cache=True,\n                    dialect=None, billing_tier=None):\n    \"\"\"Save the results to a local file in CSV format. Returns a Job immediately.\n\n    Args:\n      path: path on the local filesystem for the saved results.\n      format: the format to use for the exported data; currently only 'csv' is supported.\n      csv_delimiter: for CSV exports, the field delimiter to use. Defaults to ','\n      csv_header: for CSV exports, whether to include an initial header line. Default true.\n      use_cache: whether to use cached results or not.\n      dialect : {'legacy', 'standard'}, default 'legacy'\n          'legacy' : Use BigQuery's legacy SQL dialect.\n          'standard' : Use BigQuery's standard SQL (beta), which is\n          compliant with the SQL 2011 standard.\n      billing_tier: Limits the billing tier for this job. Queries that have resource\n          usage beyond this tier will fail (without incurring a charge). If unspecified, this\n          will be set to your project default. This can also be used to override your\n          project-wide default billing tier on a per-query basis.\n    Returns:\n      A Job for the save that returns the path to the local file on completion.\n    Raises:\n      An Exception if the operation failed.\n    \"\"\"\n    return self.to_file(path, format=format, csv_delimiter=csv_delimiter, csv_header=csv_header,\n                        use_cache=use_cache, dialect=dialect, billing_tier=billing_tier)\n\n  def sample(self, count=5, fields=None, sampling=None, use_cache=True, dialect=None,\n             billing_tier=None):\n    \"\"\"Retrieves a sampling of rows for the query.\n\n    Args:\n      count: an optional count of rows to retrieve which is used if a specific\n          sampling is not specified (default 5).\n      fields: the list of fields to sample (default None implies all).\n      sampling: an optional sampling strategy to apply to the table.\n      use_cache: whether to use cached results or not (default True).\n      dialect : {'legacy', 'standard'}, default 'legacy'\n          'legacy' : Use BigQuery's legacy SQL dialect.\n          'standard' : Use BigQuery's standard SQL (beta), which is\n          compliant with the SQL 2011 standard.\n      billing_tier: Limits the billing tier for this job. Queries that have resource\n          usage beyond this tier will fail (without incurring a charge). If unspecified, this\n          will be set to your project default. This can also be used to override your\n          project-wide default billing tier on a per-query basis.\n    Returns:\n      A QueryResultsTable containing a sampling of the result set.\n    Raises:\n      Exception if the query could not be executed or query response was malformed.\n    \"\"\"\n    return Query.sampling_query(self._sql, self._context, count=count, fields=fields,\n                                sampling=sampling, udfs=self._udfs,\n                                data_sources=self._data_sources).results(use_cache=use_cache,\n                                                                         dialect=dialect,\n                                                                         billing_tier=billing_tier)\n\n  def execute_dry_run(self, dialect=None, billing_tier=None):\n    \"\"\"Dry run a query, to check the validity of the query and return some useful statistics.\n\n    Args:\n      dialect : {'legacy', 'standard'}, default 'legacy'\n          'legacy' : Use BigQuery's legacy SQL dialect.\n          'standard' : Use BigQuery's standard SQL (beta), which is\n          compliant with the SQL 2011 standard.\n      billing_tier: Limits the billing tier for this job. Queries that have resource\n          usage beyond this tier will fail (without incurring a charge). If unspecified, this\n          will be set to your project default. This can also be used to override your\n          project-wide default billing tier on a per-query basis.\n    Returns:\n      A dict with 'cacheHit' and 'totalBytesProcessed' fields.\n    Raises:\n      An exception if the query was malformed.\n    \"\"\"\n    try:\n      query_result = self._api.jobs_insert_query(self._sql, self._code, self._imports,\n                                                 dry_run=True,\n                                                 table_definitions=self._external_tables,\n                                                 dialect=dialect, billing_tier=billing_tier)\n    except Exception as e:\n      raise e\n    return query_result['statistics']['query']\n\n  def execute_async(self, table_name=None, table_mode='create', use_cache=True,\n                    priority='interactive', allow_large_results=False, dialect=None,\n                    billing_tier=None):\n    \"\"\" Initiate the query and return a QueryJob.\n\n    Args:\n      table_name: the result table name as a string or TableName; if None (the default), then a\n          temporary table will be used.\n      table_mode: one of 'create', 'overwrite' or 'append'. If 'create' (the default), the request\n          will fail if the table exists.\n      use_cache: whether to use past query results or ignore cache. Has no effect if destination is\n          specified (default True).\n      priority:one of 'batch' or 'interactive' (default). 'interactive' jobs should be scheduled\n          to run quickly but are subject to rate limits; 'batch' jobs could be delayed by as much\n          as three hours but are not rate-limited.\n      allow_large_results: whether to allow large results; i.e. compressed data over 100MB. This is\n          slower and requires a table_name to be specified) (default False).\n      dialect : {'legacy', 'standard'}, default 'legacy'\n          'legacy' : Use BigQuery's legacy SQL dialect.\n          'standard' : Use BigQuery's standard SQL (beta), which is\n          compliant with the SQL 2011 standard.\n      billing_tier: Limits the billing tier for this job. Queries that have resource\n          usage beyond this tier will fail (without incurring a charge). If unspecified, this\n          will be set to your project default. This can also be used to override your\n          project-wide default billing tier on a per-query basis.\n    Returns:\n      A QueryJob.\n    Raises:\n      Exception if query could not be executed.\n    \"\"\"\n    batch = priority == 'low'\n    append = table_mode == 'append'\n    overwrite = table_mode == 'overwrite'\n    if table_name is not None:\n      table_name = _utils.parse_table_name(table_name, self._api.project_id)\n\n    try:\n      query_result = self._api.jobs_insert_query(self._sql, self._code, self._imports,\n                                                 table_name=table_name,\n                                                 append=append,\n                                                 overwrite=overwrite,\n                                                 use_cache=use_cache,\n                                                 batch=batch,\n                                                 allow_large_results=allow_large_results,\n                                                 table_definitions=self._external_tables,\n                                                 dialect=dialect,\n                                                 billing_tier=billing_tier)\n    except Exception as e:\n      raise e\n    if 'jobReference' not in query_result:\n      raise Exception('Unexpected response from server')\n\n    job_id = query_result['jobReference']['jobId']\n    if not table_name:\n      try:\n        destination = query_result['configuration']['query']['destinationTable']\n        table_name = (destination['projectId'], destination['datasetId'], destination['tableId'])\n      except KeyError:\n        # The query was in error\n        raise Exception(_utils.format_query_errors(query_result['status']['errors']))\n    return _query_job.QueryJob(job_id, table_name, self._sql, context=self._context)\n\n  def execute(self, table_name=None, table_mode='create', use_cache=True, priority='interactive',\n              allow_large_results=False, dialect=None, billing_tier=None):\n    \"\"\" Initiate the query, blocking until complete and then return the results.\n\n    Args:\n      table_name: the result table name as a string or TableName; if None (the default), then a\n          temporary table will be used.\n      table_mode: one of 'create', 'overwrite' or 'append'. If 'create' (the default), the request\n          will fail if the table exists.\n      use_cache: whether to use past query results or ignore cache. Has no effect if destination is\n          specified (default True).\n      priority:one of 'batch' or 'interactive' (default). 'interactive' jobs should be scheduled\n          to run quickly but are subject to rate limits; 'batch' jobs could be delayed by as much\n          as three hours but are not rate-limited.\n      allow_large_results: whether to allow large results; i.e. compressed data over 100MB. This is\n          slower and requires a table_name to be specified) (default False).\n      dialect : {'legacy', 'standard'}, default 'legacy'\n          'legacy' : Use BigQuery's legacy SQL dialect.\n          'standard' : Use BigQuery's standard SQL (beta), which is\n          compliant with the SQL 2011 standard.\n      billing_tier: Limits the billing tier for this job. Queries that have resource\n          usage beyond this tier will fail (without incurring a charge). If unspecified, this\n          will be set to your project default. This can also be used to override your\n          project-wide default billing tier on a per-query basis.\n    Returns:\n      The QueryResultsTable for the query.\n    Raises:\n      Exception if query could not be executed.\n    \"\"\"\n    job = self.execute_async(table_name=table_name, table_mode=table_mode, use_cache=use_cache,\n                             priority=priority, allow_large_results=allow_large_results,\n                             dialect=dialect, billing_tier=billing_tier)\n    self._results = job.wait()\n    return self._results\n\n  def to_view(self, view_name):\n    \"\"\" Create a View from this Query.\n\n    Args:\n      view_name: the name of the View either as a string or a 3-part tuple\n          (projectid, datasetid, name).\n\n    Returns:\n      A View for the Query.\n    \"\"\"\n    # Do the import here to avoid circular dependencies at top-level.\n    from . import _view\n    return _view.View(view_name, self._context).create(self._sql)\n"
  },
  {
    "path": "datalab/bigquery/_query_job.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Implements BigQuery query job functionality.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom builtins import str\n\nfrom . import _job\nfrom . import _query_results_table\n\n\nclass QueryJob(_job.Job):\n  \"\"\" Represents a BigQuery Query Job. \"\"\"\n\n  def __init__(self, job_id, table_name, sql, context):\n    \"\"\"  Initializes a QueryJob object.\n\n    Args:\n      job_id: the ID of the query job.\n      table_name: the name of the table where the query results will be stored.\n      sql: the SQL statement that was executed for the query.\n      context: the Context object providing project_id and credentials that was used\n          when executing the query.\n    \"\"\"\n    super(QueryJob, self).__init__(job_id, context)\n    self._sql = sql\n    self._table = _query_results_table.QueryResultsTable(table_name, context, self,\n                                                         is_temporary=True)\n    self._bytes_processed = None\n    self._cache_hit = None\n    self._total_rows = None\n\n  @property\n  def bytes_processed(self):\n    \"\"\" The number of bytes processed, or None if the job is not complete. \"\"\"\n    return self._bytes_processed\n\n  @property\n  def total_rows(self):\n    \"\"\" The total number of rows in the result, or None if not complete. \"\"\"\n    return self._total_rows\n\n  @property\n  def cache_hit(self):\n    \"\"\" Whether the query results were obtained from the cache or not, or None if not complete. \"\"\"\n    return self._cache_hit\n\n  @property\n  def sql(self):\n    \"\"\" The SQL statement that was executed for the query. \"\"\"\n    return self._sql\n\n  def wait(self, timeout=None):\n    \"\"\" Wait for the job to complete, or a timeout to happen.\n\n      This is more efficient than the version in the base Job class, in that we can\n      use a call that blocks for the poll duration rather than a sleep. That means we\n      shouldn't block unnecessarily long and can also poll less.\n\n    Args:\n      timeout: how long to wait (in seconds) before giving up; default None which means no timeout.\n\n    Returns:\n      The QueryJob\n    \"\"\"\n    poll = 30\n    while not self._is_complete:\n      try:\n        query_result = self._api.jobs_query_results(self._job_id,\n                                                    project_id=self._context.project_id,\n                                                    page_size=0,\n                                                    timeout=poll * 1000)\n      except Exception as e:\n        raise e\n      if query_result['jobComplete']:\n        if 'totalBytesProcessed' in query_result:\n          self._bytes_processed = int(query_result['totalBytesProcessed'])\n        self._cache_hit = query_result.get('cacheHit', None)\n        if 'totalRows' in query_result:\n          self._total_rows = int(query_result['totalRows'])\n        break\n\n      if timeout is not None:\n        timeout -= poll\n        if timeout <= 0:\n          break\n\n    self._refresh_state()\n    return self\n\n  @property\n  def results(self):\n    \"\"\" Get the table used for the results of the query. If the query is incomplete, this blocks.\n\n    Raises:\n      Exception if we timed out waiting for results or the query failed.\n    \"\"\"\n    self.wait()\n    if self.failed:\n      raise Exception('Query failed: %s' % str(self.errors))\n    return self._table\n"
  },
  {
    "path": "datalab/bigquery/_query_results_table.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Implements BigQuery query job results table functionality.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\n\nfrom . import _table\n\n\nclass QueryResultsTable(_table.Table):\n  \"\"\" A subclass of Table specifically for Query results.\n\n  The primary differences are the additional properties job_id and sql.\n  \"\"\"\n\n  def __init__(self, name, context, job, is_temporary=False):\n    \"\"\"Initializes an instance of a Table object.\n\n    Args:\n      name: the name of the table either as a string or a 3-part tuple (projectid, datasetid, name).\n      context: an optional Context object providing project_id and credentials. If a specific\n        project id or credentials are unspecified, the default ones configured at the global\n        level are used.\n      job: the QueryJob associated with these results.\n      is_temporary: if True, this is a short-lived table for intermediate results (default False).\n    \"\"\"\n    super(QueryResultsTable, self).__init__(name, context)\n    self._job = job\n    self._is_temporary = is_temporary\n\n  def __repr__(self):\n    \"\"\"Returns a representation for the dataset for showing in the notebook.\n    \"\"\"\n    if self._is_temporary:\n      return 'QueryResultsTable %s' % self.job_id\n    else:\n      return super(QueryResultsTable, self).__repr__()\n\n  @property\n  def job(self):\n    \"\"\" The QueryJob object that caused the table to be populated. \"\"\"\n    return self._job\n\n  @property\n  def job_id(self):\n    \"\"\" The ID of the query job that caused the table to be populated. \"\"\"\n    return self._job.id\n\n  @property\n  def sql(self):\n    \"\"\" The SQL statement for the query that populated the table. \"\"\"\n    return self._job.sql\n\n  @property\n  def is_temporary(self):\n    \"\"\" Whether this is a short-lived table or not. \"\"\"\n    return self._is_temporary\n"
  },
  {
    "path": "datalab/bigquery/_query_stats.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\n\"\"\"Implements representation of BigQuery query job dry run results.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom builtins import object\n\n\nclass QueryStats(object):\n  \"\"\"A wrapper for statistics returned by a dry run query. Useful so we can get an HTML\n  representation in a notebook.\n  \"\"\"\n\n  def __init__(self, total_bytes, is_cached):\n    self.total_bytes = float(total_bytes)\n    self.is_cached = is_cached\n\n  def _repr_html_(self):\n    self.total_bytes = QueryStats._size_formatter(self.total_bytes)\n    return \"\"\"\n    <p>Dry run information: %s to process, results %s</p>\n    \"\"\" % (self.total_bytes, \"cached\" if self.is_cached else \"not cached\")\n\n  @staticmethod\n  def _size_formatter(byte_num, suf='B'):\n    for mag in ['', 'K', 'M', 'G', 'T']:\n      if byte_num < 1000.0:\n        if suf == 'B':  # Don't do fractional bytes\n          return \"%5d%s%s\" % (int(byte_num), mag, suf)\n        return \"%3.1f%s%s\" % (byte_num, mag, suf)\n      byte_num /= 1000.0\n    return \"%.1f%s%s\".format(byte_num, 'P', suf)\n"
  },
  {
    "path": "datalab/bigquery/_sampling.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Sampling for BigQuery.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import unicode_literals\nfrom builtins import object\n\n\nclass Sampling(object):\n  \"\"\"Provides common sampling strategies.\n\n  Sampling strategies can be used for sampling tables or queries.\n\n  They are implemented as functions that take in a SQL statement representing the table or query\n  that should be sampled, and return a new SQL statement that limits the result set in some manner.\n  \"\"\"\n\n  def __init__(self):\n    pass\n\n  @staticmethod\n  def _create_projection(fields):\n    \"\"\"Creates a projection for use in a SELECT statement.\n\n    Args:\n      fields: the list of fields to be specified.\n    \"\"\"\n    if (fields is None) or (len(fields) == 0):\n      return '*'\n    return ','.join(fields)\n\n  @staticmethod\n  def default(fields=None, count=5):\n    \"\"\"Provides a simple default sampling strategy which limits the result set by a count.\n\n    Args:\n      fields: an optional list of field names to retrieve.\n      count: optional number of rows to limit the sampled results to.\n    Returns:\n      A sampling function that can be applied to get a random sampling.\n    \"\"\"\n    projection = Sampling._create_projection(fields)\n    return lambda sql: 'SELECT %s FROM (%s) LIMIT %d' % (projection, sql, count)\n\n  @staticmethod\n  def sorted(field_name, ascending=True, fields=None, count=5):\n    \"\"\"Provides a sampling strategy that picks from an ordered set of rows.\n\n    Args:\n      field_name: the name of the field to sort the rows by.\n      ascending: whether to sort in ascending direction or not.\n      fields: an optional list of field names to retrieve.\n      count: optional number of rows to limit the sampled results to.\n    Returns:\n      A sampling function that can be applied to get the initial few rows.\n    \"\"\"\n    direction = '' if ascending else ' DESC'\n    projection = Sampling._create_projection(fields)\n    return lambda sql: 'SELECT %s FROM (%s) ORDER BY %s%s LIMIT %d' % (projection, sql, field_name,\n                                                                       direction, count)\n\n  @staticmethod\n  def sampling_query(sql, fields=None, count=5, sampling=None):\n    \"\"\"Returns a sampling query for the SQL object.\n\n    Args:\n      sql: the SQL object to sample\n      fields: an optional list of field names to retrieve.\n      count: an optional count of rows to retrieve which is used if a specific\n          sampling is not specified.\n      sampling: an optional sampling strategy to apply to the table.\n    Returns:\n      A SQL query string for sampling the input sql.\n    \"\"\"\n    if sampling is None:\n      sampling = Sampling.default(count=count, fields=fields)\n    return sampling(sql)\n\n  @staticmethod\n  def hashed(field_name, percent, fields=None, count=0):\n    \"\"\"Provides a sampling strategy based on hashing and selecting a percentage of data.\n\n    Args:\n      field_name: the name of the field to hash.\n      percent: the percentage of the resulting hashes to select.\n      fields: an optional list of field names to retrieve.\n      count: optional maximum count of rows to pick.\n    Returns:\n      A sampling function that can be applied to get a hash-based sampling.\n    \"\"\"\n    def _hashed_sampling(sql):\n      projection = Sampling._create_projection(fields)\n      sql = 'SELECT %s FROM (%s) WHERE ABS(HASH(%s)) %% 100 < %d' % \\\n            (projection, sql, field_name, percent)\n      if count != 0:\n        sql = '%s LIMIT %d' % (sql, count)\n      return sql\n    return _hashed_sampling\n\n  @staticmethod\n  def random(percent, fields=None, count=0):\n    \"\"\"Provides a sampling strategy that picks a semi-random set of rows.\n\n    Args:\n      percent: the percentage of the resulting hashes to select.\n      fields: an optional list of field names to retrieve.\n      count: maximum number of rows to limit the sampled results to (default 5).\n    Returns:\n      A sampling function that can be applied to get some random rows. In order for this to\n      provide a good random sample percent should be chosen to be ~count/#rows where #rows\n      is the number of rows in the object (query, view or table) being sampled.\n      The rows will be returned in order; i.e. the order itself is not randomized.\n    \"\"\"\n    def _random_sampling(sql):\n      projection = Sampling._create_projection(fields)\n      sql = 'SELECT %s FROM (%s) WHERE rand() < %f' % (projection, sql, (float(percent) / 100.0))\n      if count != 0:\n        sql = '%s LIMIT %d' % (sql, count)\n      return sql\n    return _random_sampling\n"
  },
  {
    "path": "datalab/bigquery/_schema.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Implements Table and View Schema APIs.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom builtins import str\nfrom builtins import range\nfrom past.builtins import basestring\nfrom builtins import object\n\nimport datetime\nimport pandas\n\n\nclass Schema(list):\n  \"\"\"Represents the schema of a BigQuery table as a flattened list of objects representing fields.\n\n   Each field object has name, data_type, mode and description properties. Nested fields\n   get flattened with their full-qualified names. So a Schema that has an object A with nested\n   field B will be represented as [(name: 'A', ...), (name: 'A.b', ...)].\n  \"\"\"\n\n  class Field(object):\n    \"\"\" Represents a single field in a Table schema.\n\n    This has the properties:\n\n    - name: the flattened, full-qualified name of the field.\n    - data_type: the type of the field as a string ('INTEGER', 'BOOLEAN', 'FLOAT', 'STRING'\n       or 'TIMESTAMP').\n    - mode: the mode of the field; 'NULLABLE' by default.\n    - description: a description of the field, if known; empty string by default.\n\n     \"\"\"\n\n    # TODO(gram): consider renaming data_type member to type. Yes, it shadows top-level\n    # name but that is what we are using in __str__ and __getitem__ and is what is used in BQ.\n    # The shadowing is unlikely to cause problems.\n    def __init__(self, name, data_type, mode='NULLABLE', description=''):\n      self.name = name\n      self.data_type = data_type\n      self.mode = mode\n      self.description = description\n\n    def _repr_sql_(self):\n      \"\"\"Returns a representation of the field for embedding into a SQL statement.\n\n      Returns:\n        A formatted field name for use within SQL statements.\n      \"\"\"\n      return self.name\n\n    def __eq__(self, other):\n      \"\"\" Compare two schema field objects for equality (ignoring description). \"\"\"\n      return self.name == other.name and self.data_type == other.data_type\\\n          and self.mode == other.mode\n\n    def __str__(self):\n      \"\"\" Returns the schema field as a string form of a dictionary. \"\"\"\n      return \"{ 'name': '%s', 'type': '%s', 'mode':'%s', 'description': '%s' }\" % \\\n             (self.name, self.data_type, self.mode, self.description)\n\n    def __repr__(self):\n      \"\"\" Returns the schema field as a string form of a dictionary. \"\"\"\n      return str(self)\n\n    def __getitem__(self, item):\n      # TODO(gram): Currently we need this for a Schema object to work with the Parser object.\n      # Eventually if we change Parser to only work with Schema (and not also with the\n      # schema dictionaries in query results) we can remove this.\n\n      if item == 'name':\n        return self.name\n      if item == 'type':\n        return self.data_type\n      if item == 'mode':\n        return self.mode\n      if item == 'description':\n        return self.description\n\n  @staticmethod\n  def _from_dataframe(dataframe, default_type='STRING'):\n    \"\"\"\n      Infer a BigQuery table schema from a Pandas dataframe. Note that if you don't explicitly set\n      the types of the columns in the dataframe, they may be of a type that forces coercion to\n      STRING, so even though the fields in the dataframe themselves may be numeric, the type in the\n      derived schema may not be. Hence it is prudent to make sure the Pandas dataframe is typed\n      correctly.\n\n    Args:\n      dataframe: The DataFrame.\n      default_type : The default big query type in case the type of the column does not exist in\n          the schema. Defaults to 'STRING'.\n    Returns:\n      A list of dictionaries containing field 'name' and 'type' entries, suitable for use in a\n          BigQuery Tables resource schema.\n    \"\"\"\n\n    type_mapping = {\n      'i': 'INTEGER',\n      'b': 'BOOLEAN',\n      'f': 'FLOAT',\n      'O': 'STRING',\n      'S': 'STRING',\n      'U': 'STRING',\n      'M': 'TIMESTAMP'\n    }\n\n    fields = []\n    for column_name, dtype in dataframe.dtypes.iteritems():\n      fields.append({'name': column_name,\n                     'type': type_mapping.get(dtype.kind, default_type)})\n\n    return fields\n\n  @staticmethod\n  def from_dataframe(dataframe, default_type='STRING'):\n    \"\"\"\n      Infer a BigQuery table schema from a Pandas dataframe. Note that if you don't explicitly set\n      the types of the columns in the dataframe, they may be of a type that forces coercion to\n      STRING, so even though the fields in the dataframe themselves may be numeric, the type in the\n      derived schema may not be. Hence it is prudent to make sure the Pandas dataframe is typed\n      correctly.\n\n    Args:\n      dataframe: The DataFrame.\n      default_type : The default big query type in case the type of the column does not exist in\n          the schema. Defaults to 'STRING'.\n    Returns:\n      A Schema.\n    \"\"\"\n    return Schema(Schema._from_dataframe(dataframe, default_type=default_type))\n\n  @staticmethod\n  def _get_field_entry(name, value):\n    entry = {'name': name}\n    if isinstance(value, datetime.datetime):\n      _type = 'TIMESTAMP'\n    elif isinstance(value, bool):\n      _type = 'BOOLEAN'\n    elif isinstance(value, float):\n      _type = 'FLOAT'\n    elif isinstance(value, int):\n      _type = 'INTEGER'\n    elif isinstance(value, dict) or isinstance(value, list):\n      _type = 'RECORD'\n      entry['fields'] = Schema._from_record(value)\n    else:\n      _type = 'STRING'\n    entry['type'] = _type\n    return entry\n\n  @staticmethod\n  def _from_dict_record(data):\n    \"\"\"\n    Infer a BigQuery table schema from a dictionary. If the dictionary has entries that\n    are in turn OrderedDicts these will be turned into RECORD types. Ideally this will\n    be an OrderedDict but it is not required.\n\n    Args:\n      data: The dict to infer a schema from.\n    Returns:\n      A list of dictionaries containing field 'name' and 'type' entries, suitable for use in a\n          BigQuery Tables resource schema.\n    \"\"\"\n    return [Schema._get_field_entry(name, value) for name, value in list(data.items())]\n\n  @staticmethod\n  def _from_list_record(data):\n    \"\"\"\n    Infer a BigQuery table schema from a list of values.\n\n    Args:\n      data: The list of values.\n    Returns:\n      A list of dictionaries containing field 'name' and 'type' entries, suitable for use in a\n          BigQuery Tables resource schema.\n    \"\"\"\n    return [Schema._get_field_entry('Column%d' % (i + 1), value) for i, value in enumerate(data)]\n\n  @staticmethod\n  def _from_record(data):\n    \"\"\"\n    Infer a BigQuery table schema from a list of fields or a dictionary. The typeof the elements\n    is used. For a list, the field names are simply 'Column1', 'Column2', etc.\n\n    Args:\n      data: The list of fields or dictionary.\n    Returns:\n      A list of dictionaries containing field 'name' and 'type' entries, suitable for use in a\n          BigQuery Tables resource schema.\n    \"\"\"\n    if isinstance(data, dict):\n      return Schema._from_dict_record(data)\n    elif isinstance(data, list):\n      return Schema._from_list_record(data)\n    else:\n      raise Exception('Cannot create a schema from record %s' % str(data))\n\n  @staticmethod\n  def from_record(source):\n    \"\"\"\n    Infers a table/view schema from a single record that can contain a list of fields or a\n    dictionary of fields. The type of the elements is used for the types in the schema. For a\n    dict, key names are used for column names while for a list, the field names are simply named\n    'Column1', 'Column2', etc. Note that if using a dict you may want to use an OrderedDict\n    to ensure column ordering is deterministic.\n\n    Args:\n      source: The list of field values or dictionary of key/values.\n\n    Returns:\n      A Schema for the data.\n    \"\"\"\n    # TODO(gram): may want to allow an optional second argument which is a list of field\n    # names; could be useful for the record-containing-list case.\n    return Schema(Schema._from_record(source))\n\n  @staticmethod\n  def from_data(source):\n    \"\"\"Infers a table/view schema from its JSON representation, a list of records, or a Pandas\n       dataframe.\n\n    Args:\n      source: the Pandas Dataframe, a dictionary representing a record, a list of heterogeneous\n          data (record) or homogeneous data (list of records) from which to infer the schema, or\n          a definition of the schema as a list of dictionaries with 'name' and 'type' entries\n          and possibly 'mode' and 'description' entries. Only used if no data argument was provided.\n          'mode' can be 'NULLABLE', 'REQUIRED' or 'REPEATED'. For the allowed types, see:\n          https://cloud.google.com/bigquery/preparing-data-for-bigquery#datatypes\n\n          Note that there is potential ambiguity when passing a list of lists or a list of\n          dicts between whether that should be treated as a list of records or a single record\n          that is a list. The heuristic used is to check the length of the entries in the\n          list; if they are equal then a list of records is assumed. To avoid this ambiguity\n          you can instead use the Schema.from_record method which assumes a single record,\n          in either list of values or dictionary of key-values form.\n\n    Returns:\n      A Schema for the data.\n    \"\"\"\n    if isinstance(source, pandas.DataFrame):\n      bq_schema = Schema._from_dataframe(source)\n    elif isinstance(source, list):\n      if len(source) == 0:\n        bq_schema = source\n      elif all(isinstance(d, dict) for d in source):\n        if all('name' in d and 'type' in d for d in source):\n          # It looks like a bq_schema; use it as-is.\n          bq_schema = source\n        elif all(len(d) == len(source[0]) for d in source):\n          bq_schema = Schema._from_dict_record(source[0])\n        else:\n          raise Exception(('Cannot create a schema from heterogeneous list %s; perhaps you meant ' +\n                          'to use Schema.from_record?') % str(source))\n      elif isinstance(source[0], list) and \\\n              all([isinstance(l, list) and len(l) == len(source[0]) for l in source]):\n        # A list of lists all of the same length; treat first entry as a list record.\n        bq_schema = Schema._from_record(source[0])\n      else:\n        # A heterogeneous list; treat as a record.\n        raise Exception(('Cannot create a schema from heterogeneous list %s; perhaps you meant ' +\n                        'to use Schema.from_record?') % str(source))\n    elif isinstance(source, dict):\n      raise Exception(('Cannot create a schema from dict %s; perhaps you meant to use ' +\n                      'Schema.from_record?') % str(source))\n    else:\n      raise Exception('Cannot create a schema from %s' % str(source))\n    return Schema(bq_schema)\n\n  def __init__(self, definition=None):\n    \"\"\"Initializes a Schema from its raw JSON representation, a Pandas Dataframe, or a list.\n\n    Args:\n      definition: a definition of the schema as a list of dictionaries with 'name' and 'type'\n          entries and possibly 'mode' and 'description' entries. Only used if no data argument was\n          provided. 'mode' can be 'NULLABLE', 'REQUIRED' or 'REPEATED'. For the allowed types, see:\n          https://cloud.google.com/bigquery/preparing-data-for-bigquery#datatypes\n    \"\"\"\n    super(Schema, self).__init__()\n    self._map = {}\n    self._bq_schema = definition\n    self._populate_fields(definition)\n\n  def __getitem__(self, key):\n    \"\"\"Provides ability to lookup a schema field by position or by name.\n    \"\"\"\n    if isinstance(key, basestring):\n      return self._map.get(key, None)\n    # noinspection PyCallByClass\n    return list.__getitem__(self, key)\n\n  def _add_field(self, name, data_type, mode='NULLABLE', description=''):\n    field = Schema.Field(name, data_type, mode, description)\n    self.append(field)\n    self._map[name] = field\n\n  def find(self, name):\n    \"\"\" Get the index of a field in the flattened list given its (fully-qualified) name.\n\n    Args:\n      name: the fully-qualified name of the field.\n    Returns:\n      The index of the field, if found; else -1.\n    \"\"\"\n    for i in range(0, len(self)):\n      if self[i].name == name:\n        return i\n    return -1\n\n  def _populate_fields(self, data, prefix=''):\n    for field_data in data:\n      name = prefix + field_data['name']\n      data_type = field_data['type']\n      self._add_field(name, data_type, field_data.get('mode', None),\n                      field_data.get('description', None))\n\n      if data_type == 'RECORD':\n        # Recurse into the nested fields, using this field's name as a prefix.\n        self._populate_fields(field_data.get('fields'), name + '.')\n\n  def __str__(self):\n    \"\"\" Returns a string representation of the non-flattened form of the schema. \"\"\"\n    # TODO(gram): We should probably return the flattened form. There was a reason why this is\n    # not but I don't remember what it was. Figure that out and fix this.\n    return str(self._bq_schema)\n\n  def __eq__(self, other):\n    \"\"\" Compares two schema for equality. \"\"\"\n    other_map = other._map\n    if len(self._map) != len(other_map):\n      return False\n    for name in self._map.keys():\n      if name not in other_map:\n        return False\n      if not self._map[name] == other_map[name]:\n        return False\n    return True\n\n  def __ne__(self, other):\n    \"\"\" Compares two schema for inequality. \"\"\"\n    return not(self.__eq__(other))\n"
  },
  {
    "path": "datalab/bigquery/_table.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Implements Table, and related Table BigQuery APIs.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import unicode_literals\nfrom builtins import str\nfrom past.utils import old_div\nfrom builtins import object\n\nimport calendar\nimport codecs\nimport csv\nimport datetime\nimport pandas\nimport time\nimport traceback\nimport uuid\nimport sys\n\nimport datalab.context\nimport datalab.utils\n\nfrom . import _api\nfrom . import _csv_options\nfrom . import _job\nfrom . import _parser\nfrom . import _schema\nfrom . import _utils\n\n\n# import of Query is at end of module as we have a circular dependency of\n# Query.execute().results -> Table and Table.sample() -> Query\n\nclass TableMetadata(object):\n  \"\"\"Represents metadata about a BigQuery table.\"\"\"\n\n  def __init__(self, table, info):\n    \"\"\"Initializes a TableMetadata instance.\n\n    Args:\n      table: the Table object this belongs to.\n      info: The BigQuery information about this table as a Python dictionary.\n    \"\"\"\n    self._table = table\n    self._info = info\n\n  @property\n  def created_on(self):\n    \"\"\"The creation timestamp.\"\"\"\n    timestamp = self._info.get('creationTime')\n    return _parser.Parser.parse_timestamp(timestamp)\n\n  @property\n  def description(self):\n    \"\"\"The description of the table if it exists.\"\"\"\n    return self._info.get('description', '')\n\n  @property\n  def expires_on(self):\n    \"\"\"The timestamp for when the table will expire, or None if unknown.\"\"\"\n    timestamp = self._info.get('expirationTime', None)\n    if timestamp is None:\n      return None\n    return _parser.Parser.parse_timestamp(timestamp)\n\n  @property\n  def friendly_name(self):\n    \"\"\"The friendly name of the table if it exists.\"\"\"\n    return self._info.get('friendlyName', '')\n\n  @property\n  def modified_on(self):\n    \"\"\"The timestamp for when the table was last modified.\"\"\"\n    timestamp = self._info.get('lastModifiedTime')\n    return _parser.Parser.parse_timestamp(timestamp)\n\n  @property\n  def rows(self):\n    \"\"\"The number of rows within the table, or -1 if unknown. \"\"\"\n    return int(self._info['numRows']) if 'numRows' in self._info else -1\n\n  @property\n  def size(self):\n    \"\"\"The size of the table in bytes, or -1 if unknown. \"\"\"\n    return int(self._info['numBytes']) if 'numBytes' in self._info else -1\n\n  def refresh(self):\n    \"\"\" Refresh the metadata. \"\"\"\n    self._info = self._table._load_info()\n\n\nclass Table(object):\n  \"\"\"Represents a Table object referencing a BigQuery table. \"\"\"\n\n  # Allowed characters in a BigQuery table column name\n  _VALID_COLUMN_NAME_CHARACTERS = '_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'\n\n  # When fetching table contents, the max number of rows to fetch per HTTP request\n  _DEFAULT_PAGE_SIZE = 1024\n\n  # Milliseconds per week\n  _MSEC_PER_WEEK = 7 * 24 * 3600 * 1000\n\n  def __init__(self, name, context=None):\n    \"\"\"Initializes an instance of a Table object. The Table need not exist yet.\n\n    Args:\n      name: the name of the table either as a string or a 3-part tuple (projectid, datasetid, name).\n        If a string, it must have the form '<project>:<dataset>.<table>' or '<dataset>.<table>'.\n      context: an optional Context object providing project_id and credentials. If a specific\n        project id or credentials are unspecified, the default ones configured at the global\n        level are used.\n    Raises:\n      Exception if the name is invalid.\n    \"\"\"\n    if context is None:\n      context = datalab.context.Context.default()\n    self._context = context\n    self._api = _api.Api(context)\n    self._name_parts = _utils.parse_table_name(name, self._api.project_id)\n    self._full_name = '%s:%s.%s%s' % self._name_parts\n    self._info = None\n    self._cached_page = None\n    self._cached_page_index = 0\n    self._schema = None\n\n  @property\n  def name(self):\n    \"\"\"The TableName named tuple (project_id, dataset_id, table_id, decorator) for the table.\"\"\"\n    return self._name_parts\n\n  @property\n  def job(self):\n    \"\"\" For tables resulting from executing queries, the job that created the table.\n\n    Default is None for a Table object; this is overridden by QueryResultsTable.\n    \"\"\"\n    return None\n\n  @property\n  def is_temporary(self):\n    \"\"\" Whether this is a short-lived table or not. Always False for non-QueryResultsTables. \"\"\"\n    return False\n\n  def _load_info(self):\n    \"\"\"Loads metadata about this table.\"\"\"\n    if self._info is None:\n      try:\n        self._info = self._api.tables_get(self._name_parts)\n      except Exception as e:\n        raise e\n\n  @property\n  def metadata(self):\n    \"\"\"Retrieves metadata about the table.\n\n    Returns:\n      A TableMetadata object.\n    Raises\n      Exception if the request could not be executed or the response was malformed.\n    \"\"\"\n    self._load_info()\n    return TableMetadata(self, self._info)\n\n  def exists(self):\n    \"\"\"Checks if the table exists.\n\n    Returns:\n      True if the table exists; False otherwise.\n    Raises:\n      Exception if there was an error requesting information about the table.\n    \"\"\"\n    try:\n      info = self._api.tables_get(self._name_parts)\n    except datalab.utils.RequestException as e:\n      if e.status == 404:\n        return False\n      raise e\n    except Exception as e:\n      raise e\n    self._info = info\n    return True\n\n  def is_listable(self):\n    \"\"\" Determine if the table can be listed.\n\n    Returns:\n      True is the Table can be listed; False otherwise.\n    \"\"\"\n    self._load_info()\n    return 'type' not in self._info or 'MODEL' != self._info['type']\n\n  def delete(self):\n    \"\"\" Delete the table.\n\n    Returns:\n      True if the Table no longer exists; False otherwise.\n    \"\"\"\n    try:\n      self._api.table_delete(self._name_parts)\n    except datalab.utils.RequestException:\n      # TODO(gram): May want to check the error reasons here and if it is not\n      # because the file didn't exist, return an error.\n      pass\n    except Exception as e:\n      raise e\n    return not self.exists()\n\n  def create(self, schema, overwrite=False):\n    \"\"\" Create the table with the specified schema.\n\n    Args:\n      schema: the schema to use to create the table. Should be a list of dictionaries, each\n          containing at least a pair of entries, 'name' and 'type'.\n          See https://cloud.google.com/bigquery/docs/reference/v2/tables#resource\n      overwrite: if True, delete the table first if it exists. If False and the table exists,\n          creation will fail and raise an Exception.\n    Returns:\n      The Table instance.\n    Raises:\n      Exception if the table couldn't be created or already exists and truncate was False.\n    \"\"\"\n    if overwrite and self.exists():\n      self.delete()\n    if not isinstance(schema, _schema.Schema):\n      # Convert to a Schema object\n      schema = _schema.Schema(schema)\n    try:\n      response = self._api.tables_insert(self._name_parts, schema=schema._bq_schema)\n    except Exception as e:\n      raise e\n    if 'selfLink' in response:\n      self._schema = schema\n      return self\n    raise Exception(\"Table %s could not be created as it already exists\" % self._full_name)\n\n  def sample(self, fields=None, count=5, sampling=None, use_cache=True, dialect=None,\n             billing_tier=None):\n    \"\"\"Retrieves a sampling of data from the table.\n\n    Args:\n      fields: an optional list of field names to retrieve.\n      count: an optional count of rows to retrieve which is used if a specific\n          sampling is not specified.\n      sampling: an optional sampling strategy to apply to the table.\n      use_cache: whether to use cached results or not.\n      dialect : {'legacy', 'standard'}, default 'legacy'\n          'legacy' : Use BigQuery's legacy SQL dialect.\n          'standard' : Use BigQuery's standard SQL (beta), which is\n          compliant with the SQL 2011 standard.\n      billing_tier: Limits the billing tier for this job. Queries that have resource\n          usage beyond this tier will fail (without incurring a charge). If unspecified, this\n          will be set to your project default. This can also be used to override your\n          project-wide default billing tier on a per-query basis.\n    Returns:\n      A QueryResultsTable object containing the resulting data.\n    Raises:\n      Exception if the sample query could not be executed or query response was malformed.\n    \"\"\"\n    # Do import here to avoid top-level circular dependencies.\n    from . import _query\n    sql = self._repr_sql_()\n    return _query.Query.sampling_query(sql, context=self._context, count=count, fields=fields,\n                                       sampling=sampling).results(use_cache=use_cache,\n                                                                  dialect=dialect,\n                                                                  billing_tier=billing_tier)\n\n  @staticmethod\n  def _encode_dict_as_row(record, column_name_map):\n    \"\"\" Encode a dictionary representing a table row in a form suitable for streaming to BQ.\n\n      This includes encoding timestamps as ISO-compatible strings and removing invalid\n      characters from column names.\n\n    Args:\n      record: a Python dictionary representing the table row.\n      column_name_map: a dictionary mapping dictionary keys to column names. This is initially\n        empty and built up by this method when it first encounters each column, then used as a\n        cache subsequently.\n    Returns:\n      The sanitized dictionary.\n    \"\"\"\n    for k in list(record.keys()):\n      v = record[k]\n      # If the column is a date, convert to ISO string.\n      if isinstance(v, pandas.Timestamp) or isinstance(v, datetime.datetime):\n        v = record[k] = record[k].isoformat()\n\n      # If k has invalid characters clean it up\n      if k not in column_name_map:\n        column_name_map[k] = ''.join(c for c in k if c in Table._VALID_COLUMN_NAME_CHARACTERS)\n      new_k = column_name_map[k]\n      if k != new_k:\n        record[new_k] = v\n        del record[k]\n    return record\n\n  def insert_data(self, data, include_index=False, index_name=None):\n    \"\"\" Insert the contents of a Pandas DataFrame or a list of dictionaries into the table.\n\n    The insertion will be performed using at most 500 rows per POST, and at most 10 POSTs per\n    second, as BigQuery has some limits on streaming rates.\n\n    Args:\n      data: the DataFrame or list to insert.\n      include_index: whether to include the DataFrame or list index as a column in the BQ table.\n      index_name: for a list, if include_index is True, this should be the name for the index.\n          If not specified, 'Index' will be used.\n    Returns:\n      The table.\n    Raises:\n      Exception if the table doesn't exist, the table's schema differs from the data's schema,\n      or the insert failed.\n    \"\"\"\n    # TODO(gram): we could create the Table here is it doesn't exist using a schema derived\n    # from the data. IIRC we decided not to but doing so seems less unwieldy that having to\n    # create it first and then validate the schema against it itself.\n\n    # There are BigQuery limits on the streaming API:\n    #\n    # max_rows_per_post = 500\n    # max_bytes_per_row = 20000\n    # max_rows_per_second = 10000\n    # max_bytes_per_post = 1000000\n    # max_bytes_per_second = 10000000\n    #\n    # It is non-trivial to enforce these here, and the max bytes per row is not something we\n    # can really control. As an approximation we enforce the 500 row limit\n    # with a 0.05 sec POST interval (to enforce the 10,000 rows per sec limit).\n    max_rows_per_post = 500\n    post_interval = 0.05\n\n    # TODO(gram): add different exception types for each failure case.\n    if not self.exists():\n      raise Exception('Table %s does not exist.' % self._full_name)\n\n    data_schema = _schema.Schema.from_data(data)\n    if isinstance(data, list):\n      if include_index:\n        if not index_name:\n          index_name = 'Index'\n        data_schema._add_field(index_name, 'INTEGER')\n\n    table_schema = self.schema\n\n    # Do some validation of the two schema to make sure they are compatible.\n    for data_field in data_schema:\n      name = data_field.name\n      table_field = table_schema[name]\n      if table_field is None:\n        raise Exception('Table does not contain field %s' % name)\n      data_type = data_field.data_type\n      table_type = table_field.data_type\n      if table_type != data_type:\n        raise Exception('Field %s in data has type %s but in table has type %s' %\n                        (name, data_type, table_type))\n\n    total_rows = len(data)\n    total_pushed = 0\n\n    job_id = uuid.uuid4().hex\n    rows = []\n    column_name_map = {}\n\n    is_dataframe = isinstance(data, pandas.DataFrame)\n    if is_dataframe:\n      # reset_index creates a new dataframe so we don't affect the original. reset_index(drop=True)\n      # drops the original index and uses an integer range.\n      gen = data.reset_index(drop=not include_index).iterrows()\n    else:\n      gen = enumerate(data)\n\n    for index, row in gen:\n      if is_dataframe:\n        row = row.to_dict()\n      elif include_index:\n        row[index_name] = index\n\n      rows.append({\n        'json': self._encode_dict_as_row(row, column_name_map),\n        'insertId': job_id + str(index)\n      })\n\n      total_pushed += 1\n\n      if (total_pushed == total_rows) or (len(rows) == max_rows_per_post):\n        try:\n          response = self._api.tabledata_insert_all(self._name_parts, rows)\n        except Exception as e:\n          raise e\n        if 'insertErrors' in response:\n          raise Exception('insertAll failed: %s' % response['insertErrors'])\n\n        time.sleep(post_interval)  # Streaming API is rate-limited\n        rows = []\n\n    # Block until data is ready\n    while True:\n      self._info = self._api.tables_get(self._name_parts)\n      if 'streamingBuffer' not in self._info or \\\n              'estimatedRows' not in self._info['streamingBuffer'] or \\\n              int(self._info['streamingBuffer']['estimatedRows']) > 0:\n        break\n      time.sleep(2)\n\n    return self\n\n  def _init_job_from_response(self, response):\n    \"\"\" Helper function to create a Job instance from a response. \"\"\"\n    job = None\n    if response and 'jobReference' in response:\n      job = _job.Job(job_id=response['jobReference']['jobId'], context=self._context)\n    return job\n\n  def extract_async(self, destination, format='csv', csv_delimiter=',', csv_header=True,\n                    compress=False):\n    \"\"\"Starts a job to export the table to GCS.\n\n    Args:\n      destination: the destination URI(s). Can be a single URI or a list.\n      format: the format to use for the exported data; one of 'csv', 'json', or 'avro'\n          (default 'csv').\n      csv_delimiter: for CSV exports, the field delimiter to use. Defaults to ','\n      csv_header: for CSV exports, whether to include an initial header line. Default true.\n      compress: whether to compress the data on export. Compression is not supported for\n          AVRO format. Defaults to False.\n    Returns:\n      A Job object for the export Job if it was started successfully; else None.\n    \"\"\"\n    format = format.upper()\n    if format == 'JSON':\n      format = 'NEWLINE_DELIMITED_JSON'\n    try:\n      response = self._api.table_extract(self._name_parts, destination, format, compress,\n                                         csv_delimiter, csv_header)\n      return self._init_job_from_response(response)\n    except Exception as e:\n      raise datalab.utils.JobError(location=traceback.format_exc(), message=str(e),\n                                   reason=str(type(e)))\n\n  def extract(self, destination, format='csv', csv_delimiter=',', csv_header=True, compress=False):\n    \"\"\"Exports the table to GCS; blocks until complete.\n\n    Args:\n      destination: the destination URI(s). Can be a single URI or a list.\n      format: the format to use for the exported data; one of 'csv', 'json', or 'avro'\n          (default 'csv').\n      csv_delimiter: for CSV exports, the field delimiter to use. Defaults to ','\n      csv_header: for CSV exports, whether to include an initial header line. Default true.\n      compress: whether to compress the data on export. Compression is not supported for\n          AVRO format. Defaults to False.\n    Returns:\n      A Job object for the completed export Job if it was started successfully; else None.\n    \"\"\"\n    job = self.extract_async(destination, format=format, csv_delimiter=csv_delimiter,\n                             csv_header=csv_header, compress=compress)\n    if job is not None:\n      job.wait()\n    return job\n\n  def load_async(self, source, mode='create', source_format='csv', csv_options=None,\n                 ignore_unknown_values=False, max_bad_records=0):\n    \"\"\" Starts importing a table from GCS and return a Future.\n\n    Args:\n      source: the URL of the source objects(s). Can include a wildcard '*' at the end of the item\n         name. Can be a single source or a list.\n      mode: one of 'create', 'append', or 'overwrite'. 'append' or 'overwrite' will fail if the\n          table does not already exist, while 'create' will fail if it does. The default is\n          'create'. If 'create' the schema will be inferred if necessary.\n      source_format: the format of the data, 'csv' or 'json'; default 'csv'.\n      csv_options: if source format is 'csv', additional options as a CSVOptions object.\n      ignore_unknown_values: If True, accept rows that contain values that do not match the schema;\n          the unknown values are ignored (default False).\n      max_bad_records: the maximum number of bad records that are allowed (and ignored) before\n          returning an 'invalid' error in the Job result (default 0).\n\n    Returns:\n      A Job object for the import if it was started successfully or None if not.\n    Raises:\n      Exception if the load job failed to be started or invalid arguments were supplied.\n    \"\"\"\n    if source_format == 'csv':\n      source_format = 'CSV'\n    elif source_format == 'json':\n      source_format = 'NEWLINE_DELIMITED_JSON'\n    else:\n      raise Exception(\"Invalid source format %s\" % source_format)\n\n    if not(mode == 'create' or mode == 'append' or mode == 'overwrite'):\n      raise Exception(\"Invalid mode %s\" % mode)\n\n    if csv_options is None:\n      csv_options = _csv_options.CSVOptions()\n\n    try:\n      response = self._api.jobs_insert_load(source, self._name_parts,\n                                            append=(mode == 'append'),\n                                            overwrite=(mode == 'overwrite'),\n                                            create=(mode == 'create'),\n                                            source_format=source_format,\n                                            field_delimiter=csv_options.delimiter,\n                                            allow_jagged_rows=csv_options.allow_jagged_rows,\n                                            allow_quoted_newlines=csv_options.allow_quoted_newlines,\n                                            encoding=csv_options.encoding.upper(),\n                                            ignore_unknown_values=ignore_unknown_values,\n                                            max_bad_records=max_bad_records,\n                                            quote=csv_options.quote,\n                                            skip_leading_rows=csv_options.skip_leading_rows)\n    except Exception as e:\n      raise e\n    return self._init_job_from_response(response)\n\n  def load(self, source, mode='create', source_format='csv', csv_options=None,\n           ignore_unknown_values=False, max_bad_records=0):\n    \"\"\" Load the table from GCS.\n\n    Args:\n      source: the URL of the source objects(s). Can include a wildcard '*' at the end of the item\n         name. Can be a single source or a list.\n      mode: one of 'create', 'append', or 'overwrite'. 'append' or 'overwrite' will fail if the\n          table does not already exist, while 'create' will fail if it does. The default is\n          'create'. If 'create' the schema will be inferred if necessary.\n      source_format: the format of the data, 'csv' or 'json'; default 'csv'.\n      csv_options: if source format is 'csv', additional options as a CSVOptions object.\n      ignore_unknown_values: if True, accept rows that contain values that do not match the schema;\n          the unknown values are ignored (default False).\n      max_bad_records: the maximum number of bad records that are allowed (and ignored) before\n          returning an 'invalid' error in the Job result (default 0).\n\n    Returns:\n      A Job object for the completed load Job if it was started successfully; else None.\n    \"\"\"\n    job = self.load_async(source,\n                          mode=mode,\n                          source_format=source_format,\n                          csv_options=csv_options,\n                          ignore_unknown_values=ignore_unknown_values,\n                          max_bad_records=max_bad_records)\n    if job is not None:\n      job.wait()\n    return job\n\n  def _get_row_fetcher(self, start_row=0, max_rows=None, page_size=_DEFAULT_PAGE_SIZE):\n    \"\"\" Get a function that can retrieve a page of rows.\n\n    The function returned is a closure so that it can have a signature suitable for use\n    by Iterator.\n\n    Args:\n      start_row: the row to start fetching from; default 0.\n      max_rows: the maximum number of rows to fetch (across all calls, not per-call). Default\n          is None which means no limit.\n      page_size: the maximum number of results to fetch per page; default 1024.\n    Returns:\n      A function that can be called repeatedly with a page token and running count, and that\n      will return an array of rows and a next page token; when the returned page token is None\n      the fetch is complete.\n    \"\"\"\n    if not start_row:\n      start_row = 0\n    elif start_row < 0:  # We are measuring from the table end\n      if self.length >= 0:\n        start_row += self.length\n      else:\n        raise Exception('Cannot use negative indices for table of unknown length')\n\n    schema = self.schema._bq_schema\n    name_parts = self._name_parts\n\n    def _retrieve_rows(page_token, count):\n\n      page_rows = []\n      if max_rows and count >= max_rows:\n        page_token = None\n      else:\n        if max_rows and page_size > (max_rows - count):\n          max_results = max_rows - count\n        else:\n          max_results = page_size\n\n        try:\n          if page_token:\n            response = self._api.tabledata_list(name_parts, page_token=page_token,\n                                                max_results=max_results)\n          else:\n            response = self._api.tabledata_list(name_parts, start_index=start_row,\n                                                max_results=max_results)\n        except Exception as e:\n          raise e\n        page_token = response['pageToken'] if 'pageToken' in response else None\n        if 'rows' in response:\n          page_rows = response['rows']\n\n      rows = []\n      for row_dict in page_rows:\n        rows.append(_parser.Parser.parse_row(schema, row_dict))\n\n      return rows, page_token\n\n    return _retrieve_rows\n\n  def range(self, start_row=0, max_rows=None):\n    \"\"\" Get an iterator to iterate through a set of table rows.\n\n    Args:\n      start_row: the row of the table at which to start the iteration (default 0)\n      max_rows: an upper limit on the number of rows to iterate through (default None)\n\n    Returns:\n      A row iterator.\n    \"\"\"\n    fetcher = self._get_row_fetcher(start_row=start_row, max_rows=max_rows)\n    return iter(datalab.utils.Iterator(fetcher))\n\n  def to_dataframe(self, start_row=0, max_rows=None):\n    \"\"\" Exports the table to a Pandas dataframe.\n\n    Args:\n      start_row: the row of the table at which to start the export (default 0)\n      max_rows: an upper limit on the number of rows to export (default None)\n    Returns:\n      A Pandas dataframe containing the table data.\n    \"\"\"\n    fetcher = self._get_row_fetcher(start_row=start_row, max_rows=max_rows)\n    count = 0\n    page_token = None\n    df = None\n    while True:\n      page_rows, page_token = fetcher(page_token, count)\n      if len(page_rows):\n        count += len(page_rows)\n        if df is None:\n          df = pandas.DataFrame.from_records(page_rows)\n        else:\n          df = df.append(page_rows, ignore_index=True)\n      if not page_token:\n        break\n\n    # Need to reorder the dataframe to preserve column ordering\n    ordered_fields = [field.name for field in self.schema]\n    return df[ordered_fields] if df is not None else pandas.DataFrame()\n\n  def to_file(self, destination, format='csv', csv_delimiter=',', csv_header=True):\n    \"\"\"Save the results to a local file in CSV format.\n\n    Args:\n      destination: path on the local filesystem for the saved results.\n      format: the format to use for the exported data; currently only 'csv' is supported.\n      csv_delimiter: for CSV exports, the field delimiter to use. Defaults to ','\n      csv_header: for CSV exports, whether to include an initial header line. Default true.\n    Raises:\n      An Exception if the operation failed.\n    \"\"\"\n    f = codecs.open(destination, 'w', 'utf-8')\n    fieldnames = []\n    for column in self.schema:\n      fieldnames.append(column.name)\n    if sys.version_info[0] == 2:\n      csv_delimiter = csv_delimiter.encode('unicode_escape')\n    writer = csv.DictWriter(f, fieldnames=fieldnames, delimiter=csv_delimiter)\n    if csv_header:\n      writer.writeheader()\n    for row in self:\n      writer.writerow(row)\n    f.close()\n\n  @datalab.utils.async_method\n  def to_file_async(self, destination, format='csv', csv_delimiter=',', csv_header=True):\n    \"\"\"Start saving the results to a local file in CSV format and return a Job for completion.\n\n    Args:\n      destination: path on the local filesystem for the saved results.\n      format: the format to use for the exported data; currently only 'csv' is supported.\n      csv_delimiter: for CSV exports, the field delimiter to use. Defaults to ','\n      csv_header: for CSV exports, whether to include an initial header line. Default true.\n    Returns:\n      A Job for the async save operation.\n    Raises:\n      An Exception if the operation failed.\n    \"\"\"\n    self.to_file(destination, format=format, csv_delimiter=csv_delimiter, csv_header=csv_header)\n\n  @property\n  def schema(self):\n    \"\"\"Retrieves the schema of the table.\n\n    Returns:\n      A Schema object containing a list of schema fields and associated metadata.\n    Raises\n      Exception if the request could not be executed or the response was malformed.\n    \"\"\"\n    if not self._schema:\n      try:\n        self._load_info()\n        self._schema = _schema.Schema(self._info['schema']['fields'])\n      except KeyError:\n        raise Exception('Unexpected table response: missing schema')\n    return self._schema\n\n  def update(self, friendly_name=None, description=None, expiry=None, schema=None):\n    \"\"\" Selectively updates Table information.\n\n    Any parameters that are omitted or None are not updated.\n\n    Args:\n      friendly_name: if not None, the new friendly name.\n      description: if not None, the new description.\n      expiry: if not None, the new expiry time, either as a DateTime or milliseconds since epoch.\n      schema: if not None, the new schema: either a list of dictionaries or a Schema.\n    \"\"\"\n    self._load_info()\n    if friendly_name is not None:\n      self._info['friendlyName'] = friendly_name\n    if description is not None:\n      self._info['description'] = description\n    if expiry is not None:\n      if isinstance(expiry, datetime.datetime):\n        expiry = calendar.timegm(expiry.utctimetuple()) * 1000\n      self._info['expirationTime'] = expiry\n    if schema is not None:\n      if isinstance(schema, _schema.Schema):\n        schema = schema._bq_schema\n      self._info['schema'] = {'fields': schema}\n    try:\n      self._api.table_update(self._name_parts, self._info)\n    except datalab.utils.RequestException:\n      # The cached metadata is out of sync now; abandon it.\n      self._info = None\n    except Exception as e:\n      raise e\n\n  def _repr_sql_(self):\n    \"\"\"Returns a representation of the table for embedding into a SQL statement.\n\n    Returns:\n      A formatted table name for use within SQL statements.\n    \"\"\"\n    return '[' + self._full_name + ']'\n\n  def __repr__(self):\n    \"\"\"Returns a representation for the table for showing in the notebook.\n    \"\"\"\n    return 'Table %s' % self._full_name\n\n  def __str__(self):\n    \"\"\"Returns a string representation of the table using its specified name.\n\n    Returns:\n      The string representation of this object.\n    \"\"\"\n    return self._full_name\n\n  @property\n  def length(self):\n    \"\"\" Get the length of the table (number of rows). We don't use __len__ as this may\n        return -1 for 'unknown'.\n    \"\"\"\n    return self.metadata.rows\n\n  def __iter__(self):\n    \"\"\" Get an iterator for the table.\n    \"\"\"\n    return self.range(start_row=0)\n\n  def __getitem__(self, item):\n    \"\"\" Get an item or a slice of items from the table. This uses a small cache\n        to reduce the number of calls to tabledata.list.\n\n        Note: this is a useful function to have, and supports some current usage like\n        query.results()[0], but should be used with care.\n    \"\"\"\n    if isinstance(item, slice):\n      # Just treat this as a set of calls to __getitem__(int)\n      result = []\n      i = item.start\n      step = item.step if item.step else 1\n      while i < item.stop:\n        result.append(self[i])\n        i += step\n      return result\n\n    # Handle the integer index case.\n    if item < 0:\n      if self.length >= 0:\n        item += self.length\n      else:\n        raise Exception('Cannot use negative indices for table of unknown length')\n\n    if not self._cached_page \\\n        or self._cached_page_index > item \\\n            or self._cached_page_index + len(self._cached_page) <= item:\n      # cache a new page. To get the start row we round to the nearest multiple of the page\n      # size.\n      first = old_div(item, self._DEFAULT_PAGE_SIZE) * self._DEFAULT_PAGE_SIZE\n      count = self._DEFAULT_PAGE_SIZE\n\n      if self.length >= 0:\n        remaining = self.length - first\n        if count > remaining:\n          count = remaining\n\n      fetcher = self._get_row_fetcher(start_row=first, max_rows=count, page_size=count)\n      self._cached_page_index = first\n      self._cached_page, _ = fetcher(None, 0)\n\n    return self._cached_page[item - self._cached_page_index]\n\n  @staticmethod\n  def _convert_decorator_time(when):\n    if isinstance(when, datetime.datetime):\n      value = 1000 * (when - datetime.datetime.utcfromtimestamp(0)).total_seconds()\n    elif isinstance(when, datetime.timedelta):\n      value = when.total_seconds() * 1000\n      if value > 0:\n        raise Exception(\"Invalid snapshot relative when argument: %s\" % str(when))\n    else:\n      raise Exception(\"Invalid snapshot when argument type: %s\" % str(when))\n\n    if value < -Table._MSEC_PER_WEEK:\n      raise Exception(\"Invalid snapshot relative when argument: must be within 7 days: %s\"\n                      % str(when))\n\n    if value > 0:\n      now = 1000 * (datetime.datetime.utcnow() -\n                    datetime.datetime.utcfromtimestamp(0)).total_seconds()\n      # Check that an abs value is not more than 7 days in the past and is\n      # not in the future\n      if not ((now - Table._MSEC_PER_WEEK) < value < now):\n        raise Exception(\"Invalid snapshot absolute when argument: %s\" % str(when))\n\n    return int(value)\n\n  def snapshot(self, at):\n    \"\"\" Return a new Table which is a snapshot of this table at the specified time.\n\n    Args:\n      at: the time of the snapshot. This can be a Python datetime (absolute) or timedelta\n          (relative to current time). The result must be after the table was created and no more\n          than seven days in the past. Passing None will get a reference the oldest snapshot.\n\n          Note that using a datetime will get a snapshot at an absolute point in time, while\n          a timedelta will provide a varying snapshot; any queries issued against such a Table\n          will be done against a snapshot that has an age relative to the execution time of the\n          query.\n\n    Returns:\n      A new Table object referencing the snapshot.\n\n    Raises:\n      An exception if this Table is already decorated, or if the time specified is invalid.\n    \"\"\"\n    if self._name_parts.decorator != '':\n      raise Exception(\"Cannot use snapshot() on an already decorated table\")\n\n    value = Table._convert_decorator_time(at)\n    return Table(\"%s@%s\" % (self._full_name, str(value)), context=self._context)\n\n  def window(self, begin, end=None):\n    \"\"\" Return a new Table limited to the rows added to this Table during the specified time range.\n\n    Args:\n      begin: the start time of the window. This can be a Python datetime (absolute) or timedelta\n          (relative to current time). The result must be after the table was created and no more\n          than seven days in the past.\n\n          Note that using a relative value will provide a varying snapshot, not a fixed\n          snapshot; any queries issued against such a Table will be done against a snapshot\n          that has an age relative to the execution time of the query.\n\n      end: the end time of the snapshot; if None, then the current time is used. The types and\n          interpretation of values is as for start.\n\n    Returns:\n      A new Table object referencing the window.\n\n    Raises:\n      An exception if this Table is already decorated, or if the time specified is invalid.\n    \"\"\"\n    if self._name_parts.decorator != '':\n      raise Exception(\"Cannot use window() on an already decorated table\")\n\n    start = Table._convert_decorator_time(begin)\n    if end is None:\n      if isinstance(begin, datetime.timedelta):\n        end = datetime.timedelta(0)\n      else:\n        end = datetime.datetime.utcnow()\n    stop = Table._convert_decorator_time(end)\n\n    # Both values must have the same sign\n    if (start > 0 >= stop) or (stop > 0 >= start):\n      raise Exception(\"window: Between arguments must both be absolute or relative: %s, %s\" %\n                      (str(begin), str(end)))\n\n    # start must be less than stop\n    if start > stop:\n      raise Exception(\"window: Between arguments: begin must be before end: %s, %s\" %\n                      (str(begin), str(end)))\n\n    return Table(\"%s@%s-%s\" % (self._full_name, str(start), str(stop)), context=self._context)\n\n  def to_query(self, fields=None):\n    \"\"\" Return a Query for this Table.\n\n    Args:\n      fields: the fields to return. If None, all fields will be returned. This can be a string\n          which will be injected into the Query after SELECT, or a list of field names.\n\n    Returns:\n      A Query object that will return the specified fields from the records in the Table.\n    \"\"\"\n    # Do import here to avoid top-level circular dependencies.\n    from . import _query\n    if fields is None:\n      fields = '*'\n    elif isinstance(fields, list):\n      fields = ','.join(fields)\n    return _query.Query('SELECT %s FROM %s' % (fields, self._repr_sql_()), context=self._context)\n"
  },
  {
    "path": "datalab/bigquery/_udf.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Google Cloud Platform library - BigQuery UDF Functionality.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom builtins import str\nfrom builtins import object\n\nimport json\n\n\nclass UDF(object):\n  \"\"\"Represents a BigQuery UDF declaration.\n  \"\"\"\n\n  @property\n  def name(self):\n    return self._name\n\n  @property\n  def imports(self):\n    return self._imports\n\n  @property\n  def code(self):\n    return self._code\n\n  def __init__(self, inputs, outputs, name, implementation, support_code=None, imports=None):\n    \"\"\"Initializes a Function object from its pieces.\n\n    Args:\n      inputs: a list of string field names representing the schema of input.\n      outputs: a list of name/type tuples representing the schema of the output.\n      name: the name of the javascript function\n      implementation: a javascript function implementing the logic.\n      support_code: additional javascript code that the function can use.\n      imports: a list of GCS URLs or files containing further support code.\n    Raises:\n      Exception if the name is invalid.\n      \"\"\"\n    self._outputs = outputs\n    self._name = name\n    self._implementation = implementation\n    self._support_code = support_code\n    self._imports = imports\n    self._code = UDF._build_js(inputs, outputs, name, implementation, support_code)\n\n  @staticmethod\n  def _build_js(inputs, outputs, name, implementation, support_code):\n    \"\"\"Creates a BigQuery SQL UDF javascript object.\n\n    Args:\n      inputs: a list of (name, type) tuples representing the schema of input.\n      outputs: a list of (name, type) tuples representing the schema of the output.\n      name: the name of the function\n      implementation: a javascript function defining the UDF logic.\n      support_code: additional javascript code that the function can use.\n    \"\"\"\n    # Construct a comma-separated list of input field names\n    # For example, field1,field2,...\n    input_fields = json.dumps([f[0] for f in inputs])\n\n    # Construct a json representation of the output schema\n    # For example, [{'name':'field1','type':'string'},...]\n    output_fields = [{'name': f[0], 'type': f[1]} for f in outputs]\n    output_fields = json.dumps(output_fields, sort_keys=True)\n\n    # Build the JS from the individual bits with proper escaping of the implementation\n    if support_code is None:\n      support_code = ''\n    return ('{code}\\n{name}={implementation};\\nbigquery.defineFunction(\\'{name}\\', {inputs}, '\n            '{outputs}, {name});').format(code=support_code, name=name,\n                                          implementation=implementation, inputs=str(input_fields),\n                                          outputs=str(output_fields))\n"
  },
  {
    "path": "datalab/bigquery/_utils.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Useful common utility functions.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom builtins import str\nfrom past.builtins import basestring\n\nimport collections\nimport re\n\n\nDatasetName = collections.namedtuple('DatasetName', ['project_id', 'dataset_id'])\n\"\"\" A namedtuple for Dataset names.\n\n  Args:\n    project_id: the project id for the dataset.\n    dataset_id: the dataset id for the dataset.\n\"\"\"\n\nTableName = collections.namedtuple('TableName',\n                                   ['project_id', 'dataset_id', 'table_id', 'decorator'])\n\"\"\" A namedtuple for Table names.\n\n  Args:\n    project_id: the project id for the table.\n    dataset_id: the dataset id for the table.\n    table_id: the table id for the table.\n    decorator: the optional decorator for the table (for windowing/snapshot-ing).\n\"\"\"\n\n# Absolute project-qualified name pattern: <project>:<dataset>\n_ABS_DATASET_NAME_PATTERN = r'^([a-z\\d\\-_\\.:]+)\\:(\\w+)$'\n\n# Relative name pattern: <dataset>\n_REL_DATASET_NAME_PATTERN = r'^(\\w+)$'\n\n# Absolute project-qualified name pattern: <project>:<dataset>.<table>\n_ABS_TABLE_NAME_PATTERN = r'^([a-z\\d\\-_\\.:]+)\\:(\\w+)\\.(\\w+)(@[\\d\\-]+)?$'\n\n# Relative name pattern: <dataset>.<table>\n_REL_TABLE_NAME_PATTERN = r'^(\\w+)\\.(\\w+)(@[\\d\\-]+)?$'\n\n# Table-only name pattern: <table>. Includes an optional decorator.\n_TABLE_NAME_PATTERN = r'^(\\w+)(@[\\d\\-]+)$'\n\n\ndef parse_dataset_name(name, project_id=None):\n  \"\"\"Parses a dataset name into its individual parts.\n\n  Args:\n    name: the name to parse, or a tuple, dictionary or array containing the parts.\n    project_id: the expected project ID. If the name does not contain a project ID,\n        this will be used; if the name does contain a project ID and it does not match\n        this, an exception will be thrown.\n  Returns:\n    A DatasetName named tuple for the dataset.\n  Raises:\n    Exception: raised if the name doesn't match the expected formats or a project_id was\n        specified that does not match that in the name.\n  \"\"\"\n  _project_id = _dataset_id = None\n  if isinstance(name, basestring):\n    # Try to parse as absolute name first.\n    m = re.match(_ABS_DATASET_NAME_PATTERN, name, re.IGNORECASE)\n    if m is not None:\n      _project_id, _dataset_id = m.groups()\n    else:\n      # Next try to match as a relative name implicitly scoped within current project.\n      m = re.match(_REL_DATASET_NAME_PATTERN, name)\n      if m is not None:\n        groups = m.groups()\n        _dataset_id = groups[0]\n  elif isinstance(name, dict):\n    try:\n      _dataset_id = name['dataset_id']\n      _project_id = name['project_id']\n    except KeyError:\n      pass\n  else:\n    # Try treat as an array or tuple\n    if len(name) == 2:\n      # Treat as a tuple or array.\n      _project_id, _dataset_id = name\n    elif len(name) == 1:\n      _dataset_id = name[0]\n  if not _dataset_id:\n    raise Exception('Invalid dataset name: ' + str(name))\n  if not _project_id:\n    _project_id = project_id\n\n  return DatasetName(_project_id, _dataset_id)\n\n\ndef parse_table_name(name, project_id=None, dataset_id=None):\n  \"\"\"Parses a table name into its individual parts.\n\n  Args:\n    name: the name to parse, or a tuple, dictionary or array containing the parts.\n    project_id: the expected project ID. If the name does not contain a project ID,\n        this will be used; if the name does contain a project ID and it does not match\n        this, an exception will be thrown.\n    dataset_id: the expected dataset ID. If the name does not contain a dataset ID,\n        this will be used; if the name does contain a dataset ID and it does not match\n        this, an exception will be thrown.\n  Returns:\n    A TableName named tuple consisting of the full name and individual name parts.\n  Raises:\n    Exception: raised if the name doesn't match the expected formats, or a project_id and/or\n        dataset_id was provided that does not match that in the name.\n  \"\"\"\n  _project_id = _dataset_id = _table_id = _decorator = None\n  if isinstance(name, basestring):\n    # Try to parse as absolute name first.\n    m = re.match(_ABS_TABLE_NAME_PATTERN, name, re.IGNORECASE)\n    if m is not None:\n      _project_id, _dataset_id, _table_id, _decorator = m.groups()\n    else:\n      # Next try to match as a relative name implicitly scoped within current project.\n      m = re.match(_REL_TABLE_NAME_PATTERN, name)\n      if m is not None:\n        groups = m.groups()\n        _project_id, _dataset_id, _table_id, _decorator =\\\n            project_id, groups[0], groups[1], groups[2]\n      else:\n        # Finally try to match as a table name only.\n        m = re.match(_TABLE_NAME_PATTERN, name)\n        if m is not None:\n          groups = m.groups()\n          _project_id, _dataset_id, _table_id, _decorator =\\\n              project_id, dataset_id, groups[0], groups[1]\n  elif isinstance(name, dict):\n    try:\n      _table_id = name['table_id']\n      _dataset_id = name['dataset_id']\n      _project_id = name['project_id']\n    except KeyError:\n      pass\n  else:\n    # Try treat as an array or tuple\n    if len(name) == 4:\n      _project_id, _dataset_id, _table_id, _decorator = name\n    elif len(name) == 3:\n      _project_id, _dataset_id, _table_id = name\n    elif len(name) == 2:\n      _dataset_id, _table_id = name\n  if not _table_id:\n    raise Exception('Invalid table name: ' + str(name))\n  if not _project_id:\n    _project_id = project_id\n  if not _dataset_id:\n    _dataset_id = dataset_id\n  if not _decorator:\n    _decorator = ''\n\n  return TableName(_project_id, _dataset_id, _table_id, _decorator)\n\n\ndef format_query_errors(errors):\n  return '\\n'.join(['%s: %s' % (error['reason'], error['message']) for error in errors])\n"
  },
  {
    "path": "datalab/bigquery/_view.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Implements BigQuery Views.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom builtins import str\nfrom builtins import object\n\nimport datalab.context\n\nfrom . import _query\nfrom . import _table\n\n# Query import is at end to avoid issues with circular dependencies.\n\n\nclass View(object):\n  \"\"\" An implementation of a BigQuery View. \"\"\"\n\n  # Views in BigQuery are virtual tables, but it is useful to have a mixture of both Table and\n  # Query semantics; our version thus internally has a BaseTable and a Query (for materialization;\n  # not the same as the view query), and exposes a number of the same APIs as Table and Query\n  # through wrapper functions around these.\n\n  def __init__(self, name, context=None):\n    \"\"\"Initializes an instance of a View object.\n\n    Args:\n      name: the name of the view either as a string or a 3-part tuple\n          (projectid, datasetid, name). If a string, it must have the form\n          '<project>:<dataset>.<view>' or '<dataset>.<view>'.\n      context: an optional Context object providing project_id and credentials. If a specific\n          project id or credentials are unspecified, the default ones configured at the global\n          level are used.\n    Raises:\n      Exception if the name is invalid.\n      \"\"\"\n    if context is None:\n      context = datalab.context.Context.default()\n    self._context = context\n    self._table = _table.Table(name, context=context)\n    self._materialization = _query.Query('SELECT * FROM %s' % self._repr_sql_(), context=context)\n\n  def __str__(self):\n    \"\"\"The full name for the view as a string.\"\"\"\n    return str(self._table)\n\n  @property\n  def name(self):\n    \"\"\"The name for the view as a named tuple.\"\"\"\n    return self._table.name\n\n  @property\n  def description(self):\n    \"\"\"The description of the view if it exists.\"\"\"\n    return self._table.metadata.description\n\n  @property\n  def friendly_name(self):\n    \"\"\"The friendly name of the view if it exists.\"\"\"\n    return self._table.metadata.friendly_name\n\n  @property\n  def query(self):\n    \"\"\"The Query that defines the view.\"\"\"\n    if not self.exists():\n      return None\n    self._table._load_info()\n    if 'view' in self._table._info and 'query' in self._table._info['view']:\n      return _query.Query(self._table._info['view']['query'], context=self._context)\n    return None\n\n  def exists(self):\n    \"\"\"Whether the view's Query has been executed and the view is available or not.\"\"\"\n    return self._table.exists()\n\n  def delete(self):\n    \"\"\"Removes the view if it exists.\"\"\"\n    self._table.delete()\n\n  def create(self, query):\n    \"\"\" Creates the view with the specified query.\n\n    Args:\n      query: the query to use to for the View; either a string containing a SQL query or\n          a Query object.\n    Returns:\n      The View instance.\n    Raises:\n      Exception if the view couldn't be created or already exists and overwrite was False.\n    \"\"\"\n    if isinstance(query, _query.Query):\n      query = query.sql\n    try:\n      response = self._table._api.tables_insert(self._table.name, query=query)\n    except Exception as e:\n      raise e\n    if 'selfLink' in response:\n      return self\n    raise Exception(\"View %s could not be created as it already exists\" % str(self))\n\n  def sample(self, fields=None, count=5, sampling=None, use_cache=True, dialect=None,\n             billing_tier=None):\n    \"\"\"Retrieves a sampling of data from the view.\n\n    Args:\n      fields: an optional list of field names to retrieve.\n      count: an optional count of rows to retrieve which is used if a specific\n          sampling is not specified.\n      sampling: an optional sampling strategy to apply to the view.\n      use_cache: whether to use cached results or not.\n      dialect : {'legacy', 'standard'}, default 'legacy'\n          'legacy' : Use BigQuery's legacy SQL dialect.\n          'standard' : Use BigQuery's standard SQL (beta), which is\n          compliant with the SQL 2011 standard.\n      billing_tier: Limits the billing tier for this job. Queries that have resource\n          usage beyond this tier will fail (without incurring a charge). If unspecified, this\n          will be set to your project default. This can also be used to override your\n          project-wide default billing tier on a per-query basis.\n    Returns:\n      A QueryResultsTable object containing the resulting data.\n    Raises:\n      Exception if the sample query could not be executed or the query response was malformed.\n    \"\"\"\n    return self._table.sample(fields=fields, count=count, sampling=sampling, use_cache=use_cache,\n                              dialect=dialect, billing_tier=billing_tier)\n\n  @property\n  def schema(self):\n    \"\"\"Retrieves the schema of the table.\n\n    Returns:\n      A Schema object containing a list of schema fields and associated metadata.\n    Raises\n      Exception if the request could not be executed or the response was malformed.\n    \"\"\"\n    return self._table.schema\n\n  def update(self, friendly_name=None, description=None, query=None):\n    \"\"\" Selectively updates View information.\n\n    Any parameters that are None (the default) are not applied in the update.\n\n    Args:\n      friendly_name: if not None, the new friendly name.\n      description: if not None, the new description.\n      query: if not None, a new query string for the View.\n    \"\"\"\n    self._table._load_info()\n    if query is not None:\n      if isinstance(query, _query.Query):\n        query = query.sql\n      self._table._info['view'] = {'query': query}\n    self._table.update(friendly_name=friendly_name, description=description)\n\n  def results(self, use_cache=True, dialect=None, billing_tier=None):\n    \"\"\"Materialize the view synchronously.\n\n    If you require more control over the execution, use execute() or execute_async().\n\n    Args:\n      use_cache: whether to use cached results or not.\n      dialect : {'legacy', 'standard'}, default 'legacy'\n          'legacy' : Use BigQuery's legacy SQL dialect.\n          'standard' : Use BigQuery's standard SQL (beta), which is\n          compliant with the SQL 2011 standard.\n      billing_tier: Limits the billing tier for this job. Queries that have resource\n          usage beyond this tier will fail (without incurring a charge). If unspecified, this\n          will be set to your project default. This can also be used to override your\n          project-wide default billing tier on a per-query basis.\n    Returns:\n      A QueryResultsTable containing the result set.\n    Raises:\n      Exception if the query could not be executed or query response was malformed.\n    \"\"\"\n    return self._materialization.results(use_cache=use_cache, dialect=dialect,\n                                         billing_tier=billing_tier)\n\n  def execute_async(self, table_name=None, table_mode='create', use_cache=True, priority='high',\n                    allow_large_results=False, dialect=None, billing_tier=None):\n    \"\"\"Materialize the View asynchronously.\n\n    Args:\n      table_name: the result table name; if None, then a temporary table will be used.\n      table_mode: one of 'create', 'overwrite' or 'append'. If 'create' (the default), the request\n          will fail if the table exists.\n      use_cache: whether to use past query results or ignore cache. Has no effect if destination is\n          specified (default True).\n      priority:one of 'low' or 'high' (default). Note that 'high' is more expensive, but is\n          better suited to exploratory analysis.\n      allow_large_results: whether to allow large results; i.e. compressed data over 100MB. This is\n          slower and requires a table_name to be specified) (default False).\n      dialect : {'legacy', 'standard'}, default 'legacy'\n          'legacy' : Use BigQuery's legacy SQL dialect.\n          'standard' : Use BigQuery's standard SQL (beta), which is\n          compliant with the SQL 2011 standard.\n      billing_tier: Limits the billing tier for this job. Queries that have resource\n          usage beyond this tier will fail (without incurring a charge). If unspecified, this\n          will be set to your project default. This can also be used to override your\n          project-wide default billing tier on a per-query basis.\n    Returns:\n      A QueryJob for the materialization\n    Raises:\n      Exception (KeyError) if View could not be materialized.\n    \"\"\"\n    return self._materialization.execute_async(table_name=table_name, table_mode=table_mode,\n                                               use_cache=use_cache, priority=priority,\n                                               allow_large_results=allow_large_results,\n                                               dialect=dialect, billing_tier=billing_tier)\n\n  def execute(self, table_name=None, table_mode='create', use_cache=True, priority='high',\n              allow_large_results=False, dialect=None, billing_tier=None):\n    \"\"\"Materialize the View synchronously.\n\n    Args:\n      table_name: the result table name; if None, then a temporary table will be used.\n      table_mode: one of 'create', 'overwrite' or 'append'. If 'create' (the default), the request\n          will fail if the table exists.\n      use_cache: whether to use past query results or ignore cache. Has no effect if destination is\n          specified (default True).\n      priority:one of 'low' or 'high' (default). Note that 'high' is more expensive, but is\n          better suited to exploratory analysis.\n      allow_large_results: whether to allow large results; i.e. compressed data over 100MB. This is\n          slower and requires a table_name to be specified) (default False).\n      dialect : {'legacy', 'standard'}, default 'legacy'\n          'legacy' : Use BigQuery's legacy SQL dialect.\n          'standard' : Use BigQuery's standard SQL (beta), which is\n          compliant with the SQL 2011 standard.\n      billing_tier: Limits the billing tier for this job. Queries that have resource\n          usage beyond this tier will fail (without incurring a charge). If unspecified, this\n          will be set to your project default. This can also be used to override your\n          project-wide default billing tier on a per-query basis.\n    Returns:\n      A QueryJob for the materialization\n    Raises:\n      Exception (KeyError) if View could not be materialized.\n    \"\"\"\n    return self._materialization.execute(table_name=table_name, table_mode=table_mode,\n                                         use_cache=use_cache, priority=priority,\n                                         allow_large_results=allow_large_results,\n                                         dialect=dialect, billing_tier=billing_tier)\n\n  def _repr_sql_(self):\n    \"\"\"Returns a representation of the view for embedding into a SQL statement.\n\n    Returns:\n      A formatted table name for use within SQL statements.\n    \"\"\"\n    return '[' + str(self) + ']'\n\n  def __repr__(self):\n    \"\"\"Returns a representation for the view for showing in the notebook.\n    \"\"\"\n    return 'View %s\\n%s' % (self._table, self.query)\n"
  },
  {
    "path": "datalab/bigquery/commands/__init__.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\nfrom __future__ import absolute_import\n\nfrom . import _bigquery\n\n__all__ = ['_bigquery']\n"
  },
  {
    "path": "datalab/bigquery/commands/_bigquery.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Google Cloud Platform library - BigQuery IPython Functionality.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import print_function\nfrom __future__ import unicode_literals\nfrom builtins import zip\nfrom builtins import str\nfrom past.builtins import basestring\n\ntry:\n  import IPython\n  import IPython.core.display\n  import IPython.core.magic\nexcept ImportError:\n  raise Exception('This module can only be loaded in ipython.')\n\nimport fnmatch\nimport json\nimport re\n\nimport datalab.bigquery\nimport datalab.data\nimport datalab.utils\nimport datalab.utils.commands\n\n\ndef _create_create_subparser(parser):\n  create_parser = parser.subcommand('create', 'Create a dataset or table.')\n  sub_commands = create_parser.add_subparsers(dest='command')\n\n  create_dataset_parser = sub_commands.add_parser('dataset', help='Create a dataset.')\n  create_dataset_parser.add_argument('-n', '--name', help='The name of the dataset to create.',\n                                     required=True)\n  create_dataset_parser.add_argument('-f', '--friendly', help='The friendly name of the dataset.')\n\n  create_table_parser = sub_commands.add_parser('table', help='Create a table.')\n  create_table_parser.add_argument('-n', '--name', help='The name of the table to create.',\n                                   required=True)\n  create_table_parser.add_argument('-o', '--overwrite', help='Overwrite table if it exists.',\n                                   action='store_true')\n  return create_parser\n\n\ndef _create_delete_subparser(parser):\n  delete_parser = parser.subcommand('delete', 'Delete a dataset or table.')\n  sub_commands = delete_parser.add_subparsers(dest='command')\n\n  delete_dataset_parser = sub_commands.add_parser('dataset', help='Delete a dataset.')\n  delete_dataset_parser.add_argument('-n', '--name', help='The name of the dataset to delete.',\n                                     required=True)\n\n  delete_table_parser = sub_commands.add_parser('table', help='Delete a table.')\n  delete_table_parser.add_argument('-n', '--name', help='The name of the table to delete.',\n                                   required=True)\n  return delete_parser\n\n\ndef _create_sample_subparser(parser):\n  sample_parser = parser.subcommand('sample',\n                                    'Display a sample of the results of a BigQuery SQL query.\\nThe '\n                                    'cell can optionally contain arguments for expanding variables '\n                                    'in the query,\\nif -q/--query was used, or it can contain SQL '\n                                    'for a query.')\n  group = sample_parser.add_mutually_exclusive_group()\n  group.add_argument('-q', '--query', help='the name of the query to sample')\n  group.add_argument('-t', '--table', help='the name of the table to sample')\n  group.add_argument('-v', '--view', help='the name of the view to sample')\n  sample_parser.add_argument('-d', '--dialect', help='BigQuery SQL dialect',\n                             choices=['legacy', 'standard'])\n  sample_parser.add_argument('-b', '--billing', type=int, help='BigQuery billing tier')\n  sample_parser.add_argument('-c', '--count', type=int, default=10,\n                             help='The number of rows to limit to, if sampling')\n  sample_parser.add_argument('-m', '--method', help='The type of sampling to use',\n                             choices=['limit', 'random', 'hashed', 'sorted'], default='limit')\n  sample_parser.add_argument('-p', '--percent', type=int, default=1,\n                             help='For random or hashed sampling, what percentage to sample from')\n  sample_parser.add_argument('-f', '--field',\n                             help='The field to use for sorted or hashed sampling')\n  sample_parser.add_argument('-o', '--order', choices=['ascending', 'descending'],\n                             default='ascending', help='The sort order to use for sorted sampling')\n  sample_parser.add_argument('-P', '--profile', action='store_true',\n                             default=False, help='Generate an interactive profile of the data')\n  sample_parser.add_argument('--verbose',\n                             help='Show the expanded SQL that is being executed',\n                             action='store_true')\n  return sample_parser\n\n\ndef _create_udf_subparser(parser):\n  udf_parser = parser.subcommand('udf', 'Create a named Javascript BigQuery UDF')\n  udf_parser.add_argument('-m', '--module', help='The name for this UDF')\n  return udf_parser\n\n\ndef _create_dry_run_subparser(parser):\n  dry_run_parser = parser.subcommand('dryrun',\n                                     'Execute a dry run of a BigQuery query and display '\n                                     'approximate usage statistics')\n  dry_run_parser.add_argument('-q', '--query',\n                              help='The name of the query to be dry run')\n  dry_run_parser.add_argument('-d', '--dialect', help='BigQuery SQL dialect',\n                              choices=['legacy', 'standard'])\n  dry_run_parser.add_argument('-b', '--billing', type=int, help='BigQuery billing tier')\n  dry_run_parser.add_argument('-v', '--verbose',\n                              help='Show the expanded SQL that is being executed',\n                              action='store_true')\n  return dry_run_parser\n\n\ndef _create_execute_subparser(parser):\n  execute_parser = parser.subcommand('execute',\n                                     'Execute a BigQuery SQL query and optionally send the results '\n                                     'to a named table.\\nThe cell can optionally contain arguments '\n                                     'for expanding variables in the query.')\n  execute_parser.add_argument('-nc', '--nocache', help='Don\\'t use previously cached results',\n                              action='store_true')\n  execute_parser.add_argument('-d', '--dialect', help='BigQuery SQL dialect',\n                              choices=['legacy', 'standard'])\n  execute_parser.add_argument('-b', '--billing', type=int, help='BigQuery billing tier')\n  execute_parser.add_argument('-m', '--mode', help='The table creation mode', default='create',\n                              choices=['create', 'append', 'overwrite'])\n  execute_parser.add_argument('-l', '--large', help='Whether to allow large results',\n                              action='store_true')\n  execute_parser.add_argument('-q', '--query', help='The name of query to run')\n  execute_parser.add_argument('-t', '--target', help='target table name')\n  execute_parser.add_argument('-v', '--verbose',\n                              help='Show the expanded SQL that is being executed',\n                              action='store_true')\n  return execute_parser\n\n\ndef _create_pipeline_subparser(parser):\n  pipeline_parser = parser.subcommand('pipeline',\n                                      'Define a deployable pipeline based on a BigQuery query.\\n'\n                                      'The cell can optionally contain arguments for expanding '\n                                      'variables in the query.')\n  pipeline_parser.add_argument('-n', '--name', help='The pipeline name')\n  pipeline_parser.add_argument('-nc', '--nocache', help='Don\\'t use previously cached results',\n                               action='store_true')\n  pipeline_parser.add_argument('-d', '--dialect', help='BigQuery SQL dialect',\n                               choices=['legacy', 'standard'])\n  pipeline_parser.add_argument('-b', '--billing', type=int, help='BigQuery billing tier')\n  pipeline_parser.add_argument('-m', '--mode', help='The table creation mode', default='create',\n                               choices=['create', 'append', 'overwrite'])\n  pipeline_parser.add_argument('-l', '--large', help='Allow large results', action='store_true')\n  pipeline_parser.add_argument('-q', '--query', help='The name of query to run', required=True)\n  pipeline_parser.add_argument('-t', '--target', help='The target table name', nargs='?')\n  pipeline_parser.add_argument('-v', '--verbose',\n                               help='Show the expanded SQL that is being executed',\n                               action='store_true')\n  pipeline_parser.add_argument('action', nargs='?', choices=('deploy', 'run', 'dryrun'),\n                               default='dryrun',\n                               help='Whether to deploy the pipeline, execute it immediately in ' +\n                                    'the notebook, or validate it with a dry run')\n  # TODO(gram): we may want to move some command line arguments to the cell body config spec\n  # eventually.\n  return pipeline_parser\n\n\ndef _create_table_subparser(parser):\n  table_parser = parser.subcommand('table', 'View a BigQuery table.')\n  table_parser.add_argument('-r', '--rows', type=int, default=25,\n                            help='Rows to display per page')\n  table_parser.add_argument('-c', '--cols',\n                            help='Comma-separated list of column names to restrict to')\n  table_parser.add_argument('table', help='The name of, or a reference to, the table or view')\n  return table_parser\n\n\ndef _create_schema_subparser(parser):\n  schema_parser = parser.subcommand('schema', 'View a BigQuery table or view schema.')\n  group = schema_parser.add_mutually_exclusive_group()\n  group.add_argument('-v', '--view', help='the name of the view whose schema should be displayed')\n  group.add_argument('-t', '--table', help='the name of the table whose schema should be displayed')\n  return schema_parser\n\n\ndef _create_datasets_subparser(parser):\n  datasets_parser = parser.subcommand('datasets', 'List the datasets in a BigQuery project.')\n  datasets_parser.add_argument('-p', '--project',\n                               help='The project whose datasets should be listed')\n  datasets_parser.add_argument('-f', '--filter',\n                               help='Optional wildcard filter string used to limit the results')\n  return datasets_parser\n\n\ndef _create_tables_subparser(parser):\n  tables_parser = parser.subcommand('tables', 'List the tables in a BigQuery project or dataset.')\n  tables_parser.add_argument('-p', '--project',\n                             help='The project whose tables should be listed')\n  tables_parser.add_argument('-d', '--dataset',\n                             help='The dataset to restrict to')\n  tables_parser.add_argument('-f', '--filter',\n                             help='Optional wildcard filter string used to limit the results')\n  return tables_parser\n\n\ndef _create_extract_subparser(parser):\n  extract_parser = parser.subcommand('extract', 'Extract BigQuery query results or table to GCS.')\n  extract_parser.add_argument('-f', '--format', choices=['csv', 'json'], default='csv',\n                              help='The format to use for the export')\n  extract_parser.add_argument('-c', '--compress', action='store_true',\n                              help='Whether to compress the data')\n  extract_parser.add_argument('-H', '--header', action='store_true',\n                              help='Whether to include a header line (CSV only)')\n  extract_parser.add_argument('-d', '--delimiter', default=',',\n                              help='The field delimiter to use (CSV only)')\n  extract_parser.add_argument('-S', '--source', help='The name of the query or table to extract')\n  extract_parser.add_argument('-D', '--destination', help='The URL of the destination')\n  return extract_parser\n\n\ndef _create_load_subparser(parser):\n  load_parser = parser.subcommand('load', 'Load data from GCS into a BigQuery table.')\n  load_parser.add_argument('-m', '--mode', help='One of create (default), append or overwrite',\n                           choices=['create', 'append', 'overwrite'], default='create')\n  load_parser.add_argument('-f', '--format', help='The source format', choices=['json', 'csv'],\n                           default='csv')\n  load_parser.add_argument('-n', '--skip',\n                           help='The number of initial lines to skip; useful for CSV headers',\n                           type=int, default=0)\n  load_parser.add_argument('-s', '--strict', help='Whether to reject bad values and jagged lines',\n                           action='store_true')\n  load_parser.add_argument('-d', '--delimiter', default=',',\n                           help='The inter-field delimiter for CVS (default ,)')\n  load_parser.add_argument('-q', '--quote', default='\"',\n                           help='The quoted field delimiter for CVS (default \")')\n  load_parser.add_argument('-i', '--infer',\n                           help='Whether to attempt to infer the schema from source; '\n                                'if false the table must already exist',\n                           action='store_true')\n  load_parser.add_argument('-S', '--source', help='The URL of the GCS source(s)')\n  load_parser.add_argument('-D', '--destination', help='The destination table name')\n  return load_parser\n\n\ndef _get_query_argument(args, cell, env):\n  \"\"\" Get a query argument to a cell magic.\n\n  The query is specified with args['query']. We look that up and if it is a BQ query\n  just return it. If it is instead a SqlModule or SqlStatement it may have variable\n  references. We resolve those using the arg parser for the SqlModule, then override\n  the resulting defaults with either the Python code in cell, or the dictionary in\n  overrides. The latter is for if the overrides are specified with YAML or JSON and\n  eventually we should eliminate code in favor of this.\n\n  Args:\n    args: the dictionary of magic arguments.\n    cell: the cell contents which can be variable value overrides (if args has a 'query'\n        value) or inline SQL otherwise.\n    env: a dictionary that is used for looking up variable values.\n  Returns:\n    A Query object.\n  \"\"\"\n  sql_arg = args.get('query', None)\n  if sql_arg is None:\n    # Assume we have inline SQL in the cell\n    if not isinstance(cell, basestring):\n      raise Exception('Expected a --query argument or inline SQL')\n    return datalab.bigquery.Query(cell, values=env)\n\n  item = datalab.utils.commands.get_notebook_item(sql_arg)\n  if isinstance(item, datalab.bigquery.Query):  # Queries are already expanded.\n    return item\n\n  # Create an expanded BQ Query.\n  config = datalab.utils.commands.parse_config(cell, env)\n  item, env = datalab.data.SqlModule.get_sql_statement_with_environment(item, config)\n  if cell:\n    env.update(config)  # config is both a fallback and an override.\n  return datalab.bigquery.Query(item, values=env)\n\n\ndef _sample_cell(args, cell_body):\n  \"\"\"Implements the bigquery sample cell magic for ipython notebooks.\n\n  Args:\n    args: the optional arguments following '%%bigquery sample'.\n    cell_body: optional contents of the cell interpreted as SQL, YAML or JSON.\n  Returns:\n    The results of executing the sampling query, or a profile of the sample data.\n  \"\"\"\n\n  env = datalab.utils.commands.notebook_environment()\n  query = None\n  table = None\n  view = None\n\n  if args['query']:\n    query = _get_query_argument(args, cell_body, env)\n  elif args['table']:\n    table = _get_table(args['table'])\n  elif args['view']:\n    view = datalab.utils.commands.get_notebook_item(args['view'])\n    if not isinstance(view, datalab.bigquery.View):\n      raise Exception('%s is not a view' % args['view'])\n  else:\n    query = datalab.bigquery.Query(cell_body, values=env)\n\n  count = args['count']\n  method = args['method']\n  if method == 'random':\n    sampling = datalab.bigquery.Sampling.random(percent=args['percent'], count=count)\n  elif method == 'hashed':\n    sampling = datalab.bigquery.Sampling.hashed(field_name=args['field'], percent=args['percent'],\n                                                count=count)\n  elif method == 'sorted':\n    ascending = args['order'] == 'ascending'\n    sampling = datalab.bigquery.Sampling.sorted(args['field'],\n                                                ascending=ascending,\n                                                count=count)\n  elif method == 'limit':\n    sampling = datalab.bigquery.Sampling.default(count=count)\n  else:\n    sampling = datalab.bigquery.Sampling.default(count=count)\n\n  if query:\n    results = query.sample(sampling=sampling, dialect=args['dialect'], billing_tier=args['billing'])\n  elif view:\n    results = view.sample(sampling=sampling)\n  else:\n    results = table.sample(sampling=sampling)\n  if args['verbose']:\n    print(results.sql)\n  if args['profile']:\n    return datalab.utils.commands.profile_df(results.to_dataframe())\n  else:\n    return results\n\n\ndef _create_cell(args, cell_body):\n  \"\"\"Implements the BigQuery cell magic used to create datasets and tables.\n\n   The supported syntax is:\n\n     %%bigquery create dataset -n|--name <name> [-f|--friendly <friendlyname>]\n     [<description>]\n\n   or:\n\n     %%bigquery create table -n|--name <tablename> [--overwrite]\n     [<YAML or JSON cell_body defining schema to use for tables>]\n\n  Args:\n    args: the argument following '%bigquery create <command>'.\n  \"\"\"\n  if args['command'] == 'dataset':\n    try:\n      datalab.bigquery.Dataset(args['name']).create(friendly_name=args['friendly'],\n                                                    description=cell_body)\n    except Exception as e:\n      print('Failed to create dataset %s: %s' % (args['name'], e))\n  else:\n    if cell_body is None:\n      print('Failed to create %s: no schema specified' % args['name'])\n    else:\n      try:\n        record = datalab.utils.commands.parse_config(cell_body,\n                                                     datalab.utils.commands.notebook_environment(),\n                                                     as_dict=False)\n        schema = datalab.bigquery.Schema(record)\n        datalab.bigquery.Table(args['name']).create(schema=schema, overwrite=args['overwrite'])\n      except Exception as e:\n        print('Failed to create table %s: %s' % (args['name'], e))\n\n\ndef _delete_cell(args, _):\n  \"\"\"Implements the BigQuery cell magic used to delete datasets and tables.\n\n   The supported syntax is:\n\n     %%bigquery delete dataset -n|--name <name>\n\n   or:\n\n     %%bigquery delete table -n|--name <name>\n\n  Args:\n    args: the argument following '%bigquery delete <command>'.\n  \"\"\"\n  # TODO(gram): add support for wildchars and multiple arguments at some point. The latter is\n  # easy, the former a bit more tricky if non-default projects are involved.\n  if args['command'] == 'dataset':\n    try:\n      datalab.bigquery.Dataset(args['name']).delete()\n    except Exception as e:\n      print('Failed to delete dataset %s: %s' % (args['name'], e))\n  else:\n    try:\n      datalab.bigquery.Table(args['name']).delete()\n    except Exception as e:\n      print('Failed to delete table %s: %s' % (args['name'], e))\n\n\ndef _dryrun_cell(args, cell_body):\n  \"\"\"Implements the BigQuery cell magic used to dry run BQ queries.\n\n   The supported syntax is:\n   %%bigquery dryrun [-q|--sql <query identifier>]\n   [<YAML or JSON cell_body or inline SQL>]\n\n  Args:\n    args: the argument following '%bigquery dryrun'.\n    cell_body: optional contents of the cell interpreted as YAML or JSON.\n  Returns:\n    The response wrapped in a DryRunStats object\n  \"\"\"\n  query = _get_query_argument(args, cell_body, datalab.utils.commands.notebook_environment())\n\n  if args['verbose']:\n    print(query.sql)\n  result = query.execute_dry_run(dialect=args['dialect'], billing_tier=args['billing'])\n  return datalab.bigquery._query_stats.QueryStats(total_bytes=result['totalBytesProcessed'],\n                                                  is_cached=result['cacheHit'])\n\n\ndef _udf_cell(args, js):\n  \"\"\"Implements the bigquery_udf cell magic for ipython notebooks.\n\n  The supported syntax is:\n  %%bigquery udf --module <var>\n  <js function>\n\n  Args:\n    args: the optional arguments following '%%bigquery udf'.\n    js: the UDF declaration (inputs and outputs) and implementation in javascript.\n  Returns:\n    The results of executing the UDF converted to a dataframe if no variable\n    was specified. None otherwise.\n  \"\"\"\n  variable_name = args['module']\n  if not variable_name:\n    raise Exception('Declaration must be of the form %%bigquery udf --module <variable name>')\n\n  # Parse out the input and output specification\n  spec_pattern = r'\\{\\{([^}]+)\\}\\}'\n  spec_part_pattern = r'[a-z_][a-z0-9_]*'\n\n  specs = re.findall(spec_pattern, js)\n  if len(specs) < 2:\n    raise Exception('The JavaScript must declare the input row and output emitter parameters '\n                    'using valid jsdoc format comments.\\n'\n                    'The input row param declaration must be typed as {{field:type, field2:type}} '\n                    'and the output emitter param declaration must be typed as '\n                    'function({{field:type, field2:type}}.')\n\n  inputs = []\n  input_spec_parts = re.findall(spec_part_pattern, specs[0], flags=re.IGNORECASE)\n  if len(input_spec_parts) % 2 != 0:\n    raise Exception('Invalid input row param declaration. The jsdoc type expression must '\n                    'define an object with field and type pairs.')\n  for n, t in zip(input_spec_parts[0::2], input_spec_parts[1::2]):\n    inputs.append((n, t))\n\n  outputs = []\n  output_spec_parts = re.findall(spec_part_pattern, specs[1], flags=re.IGNORECASE)\n  if len(output_spec_parts) % 2 != 0:\n    raise Exception('Invalid output emitter param declaration. The jsdoc type expression must '\n                    'define a function accepting an an object with field and type pairs.')\n  for n, t in zip(output_spec_parts[0::2], output_spec_parts[1::2]):\n    outputs.append((n, t))\n\n  # Look for imports. We use a non-standard @import keyword; we could alternatively use @requires.\n  # Object names can contain any characters except \\r and \\n.\n  import_pattern = r'@import[\\s]+(gs://[a-z\\d][a-z\\d_\\.\\-]*[a-z\\d]/[^\\n\\r]+)'\n  imports = re.findall(import_pattern, js)\n\n  # Split the cell if necessary. We look for a 'function(' with no name and a header comment\n  # block with @param and assume this is the primary function, up to a closing '}' at the start\n  # of the line. The remaining cell content is used as support code.\n  split_pattern = r'(.*)(/\\*.*?@param.*?@param.*?\\*/\\w*\\n\\w*function\\w*\\(.*?^}\\n?)(.*)'\n  parts = re.match(split_pattern, js, re.MULTILINE | re.DOTALL)\n  support_code = ''\n  if parts:\n    support_code = (parts.group(1) + parts.group(3)).strip()\n    if len(support_code):\n      js = parts.group(2)\n\n  # Finally build the UDF object\n  udf = datalab.bigquery.UDF(inputs, outputs, variable_name, js, support_code, imports)\n  datalab.utils.commands.notebook_environment()[variable_name] = udf\n\n\ndef _execute_cell(args, cell_body):\n  \"\"\"Implements the BigQuery cell magic used to execute BQ queries.\n\n   The supported syntax is:\n   %%bigquery execute [-q|--sql <query identifier>] <other args>\n   [<YAML or JSON cell_body or inline SQL>]\n\n  Args:\n    args: the arguments following '%bigquery execute'.\n    cell_body: optional contents of the cell interpreted as YAML or JSON.\n  Returns:\n    The QueryResultsTable\n  \"\"\"\n  query = _get_query_argument(args, cell_body, datalab.utils.commands.notebook_environment())\n  if args['verbose']:\n    print(query.sql)\n  return query.execute(args['target'], table_mode=args['mode'], use_cache=not args['nocache'],\n                       allow_large_results=args['large'], dialect=args['dialect'],\n                       billing_tier=args['billing']).results\n\n\ndef _pipeline_cell(args, cell_body):\n  \"\"\"Implements the BigQuery cell magic used to validate, execute or deploy BQ pipelines.\n\n   The supported syntax is:\n   %%bigquery pipeline [-q|--sql <query identifier>] <other args> <action>\n   [<YAML or JSON cell_body or inline SQL>]\n\n  Args:\n    args: the arguments following '%bigquery pipeline'.\n    cell_body: optional contents of the cell interpreted as YAML or JSON.\n  Returns:\n    The QueryResultsTable\n  \"\"\"\n  if args['action'] == 'deploy':\n    raise Exception('Deploying a pipeline is not yet supported')\n\n  env = {}\n  for key, value in datalab.utils.commands.notebook_environment().items():\n    if isinstance(value, datalab.bigquery._udf.UDF):\n      env[key] = value\n\n  query = _get_query_argument(args, cell_body, env)\n  if args['verbose']:\n    print(query.sql)\n  if args['action'] == 'dryrun':\n    print(query.sql)\n    result = query.execute_dry_run()\n    return datalab.bigquery._query_stats.QueryStats(total_bytes=result['totalBytesProcessed'],\n                                                    is_cached=result['cacheHit'])\n  if args['action'] == 'run':\n    return query.execute(args['target'], table_mode=args['mode'], use_cache=not args['nocache'],\n                         allow_large_results=args['large'], dialect=args['dialect'],\n                         billing_tier=args['billing']).results\n\n\ndef _table_line(args):\n  \"\"\"Implements the BigQuery table magic used to display tables.\n\n   The supported syntax is:\n   %bigquery table -t|--table <name> <other args>\n\n  Args:\n    args: the arguments following '%bigquery table'.\n  Returns:\n    The HTML rendering for the table.\n  \"\"\"\n  # TODO(gram): It would be good to turn _table_viewer into a class that has a registered\n  # renderer. That would allow this to return a table viewer object which is easier to test.\n  name = args['table']\n  table = _get_table(name)\n  if table and table.exists():\n    fields = args['cols'].split(',') if args['cols'] else None\n    html = _table_viewer(table, rows_per_page=args['rows'], fields=fields)\n    return IPython.core.display.HTML(html)\n  else:\n    raise Exception('Table %s does not exist; cannot display' % name)\n\n\ndef _get_schema(name):\n  \"\"\" Given a variable or table name, get the Schema if it exists. \"\"\"\n  item = datalab.utils.commands.get_notebook_item(name)\n  if not item:\n    item = _get_table(name)\n\n  if isinstance(item, datalab.bigquery.Schema):\n    return item\n  if hasattr(item, 'schema') and isinstance(item.schema, datalab.bigquery._schema.Schema):\n    return item.schema\n  return None\n\n\n# An LRU cache for Tables. This is mostly useful so that when we cross page boundaries\n# when paging through a table we don't have to re-fetch the schema.\n_table_cache = datalab.utils.LRUCache(10)\n\n\ndef _get_table(name):\n  \"\"\" Given a variable or table name, get a Table if it exists.\n\n  Args:\n    name: the name of the Table or a variable referencing the Table.\n  Returns:\n    The Table, if found.\n  \"\"\"\n  # If name is a variable referencing a table, use that.\n  item = datalab.utils.commands.get_notebook_item(name)\n  if isinstance(item, datalab.bigquery.Table):\n    return item\n  # Else treat this as a BQ table name and return the (cached) table if it exists.\n  try:\n    return _table_cache[name]\n  except KeyError:\n    table = datalab.bigquery.Table(name)\n    if table.exists():\n      _table_cache[name] = table\n      return table\n  return None\n\n\ndef _schema_line(args):\n  \"\"\"Implements the BigQuery schema magic used to display table/view schemas.\n\n  Args:\n    args: the arguments following '%bigquery schema'.\n  Returns:\n    The HTML rendering for the schema.\n  \"\"\"\n  # TODO(gram): surely we could just return the schema itself?\n  name = args['table'] if args['table'] else args['view']\n  if name is None:\n    raise Exception('No table or view specified; cannot show schema')\n\n  schema = _get_schema(name)\n  if schema:\n    html = _repr_html_table_schema(schema)\n    return IPython.core.display.HTML(html)\n  else:\n    raise Exception('%s is not a schema and does not appear to have a schema member' % name)\n\n\ndef _render_table(data, fields=None):\n  \"\"\" Helper to render a list of dictionaries as an HTML display object. \"\"\"\n  return IPython.core.display.HTML(datalab.utils.commands.HtmlBuilder.render_table(data, fields))\n\n\ndef _render_list(data):\n  \"\"\" Helper to render a list of objects as an HTML list object. \"\"\"\n  return IPython.core.display.HTML(datalab.utils.commands.HtmlBuilder.render_list(data))\n\n\ndef _datasets_line(args):\n  \"\"\"Implements the BigQuery datasets magic used to display datasets in a project.\n\n   The supported syntax is:\n\n       %bigquery datasets [-f <filter>] [-p|--project <project_id>]\n\n  Args:\n    args: the arguments following '%bigquery datasets'.\n  Returns:\n    The HTML rendering for the table of datasets.\n  \"\"\"\n  filter_ = args['filter'] if args['filter'] else '*'\n  return _render_list([str(dataset) for dataset in datalab.bigquery.Datasets(args['project'])\n                       if fnmatch.fnmatch(str(dataset), filter_)])\n\n\ndef _tables_line(args):\n  \"\"\"Implements the BigQuery tables magic used to display tables in a dataset.\n\n   The supported syntax is:\n\n       %bigquery tables -p|--project <project_id>  -d|--dataset <dataset_id>\n\n  Args:\n    args: the arguments following '%bigquery tables'.\n  Returns:\n    The HTML rendering for the list of tables.\n  \"\"\"\n  filter_ = args['filter'] if args['filter'] else '*'\n  if args['dataset']:\n    if args['project'] is None:\n      datasets = [datalab.bigquery.Dataset(args['dataset'])]\n    else:\n      datasets = [datalab.bigquery.Dataset((args['project'], args['dataset']))]\n  else:\n    datasets = datalab.bigquery.Datasets(args['project'])\n\n  tables = []\n  for dataset in datasets:\n    tables.extend([str(table) for table in dataset if fnmatch.fnmatch(str(table), filter_)])\n\n  return _render_list(tables)\n\n\ndef _extract_line(args):\n  \"\"\"Implements the BigQuery extract magic used to extract table data to GCS.\n\n   The supported syntax is:\n\n       %bigquery extract -S|--source <table> -D|--destination <url> <other_args>\n\n  Args:\n    args: the arguments following '%bigquery extract'.\n  Returns:\n    A message about whether the extract succeeded or failed.\n  \"\"\"\n  name = args['source']\n  source = datalab.utils.commands.get_notebook_item(name)\n  if not source:\n    source = _get_table(name)\n\n  if not source:\n    raise Exception('No source named %s found' % name)\n  elif isinstance(source, datalab.bigquery.Table) and not source.exists():\n    raise Exception('Table %s does not exist' % name)\n  else:\n\n    job = source.extract(args['destination'],\n                         format='CSV' if args['format'] == 'csv' else 'NEWLINE_DELIMITED_JSON',\n                         compress=args['compress'],\n                         csv_delimiter=args['delimiter'],\n                         csv_header=args['header'])\n    if job.failed:\n      raise Exception('Extract failed: %s' % str(job.fatal_error))\n    elif job.errors:\n      raise Exception('Extract completed with errors: %s' % str(job.errors))\n\n\ndef _load_cell(args, schema):\n  \"\"\"Implements the BigQuery load magic used to load data from GCS to a table.\n\n   The supported syntax is:\n\n       %bigquery load -S|--source <source> -D|--destination <table>  <other_args>\n\n  Args:\n    args: the arguments following '%bigquery load'.\n    schema: a JSON schema for the destination table.\n  Returns:\n    A message about whether the load succeeded or failed.\n  \"\"\"\n  name = args['destination']\n  table = _get_table(name)\n  if not table:\n    table = datalab.bigquery.Table(name)\n\n  if table.exists():\n    if args['mode'] == 'create':\n      raise Exception('%s already exists; use --append or --overwrite' % name)\n  elif schema:\n    table.create(json.loads(schema))\n  elif not args['infer']:\n    raise Exception(\n        'Table does not exist, no schema specified in cell and no --infer flag; cannot load')\n\n  # TODO(gram): we should probably try do the schema infer ourselves as BQ doesn't really seem\n  # to be able to do it. Alternatively we can drop the --infer argument and force the user\n  # to use a pre-existing table or supply a JSON schema.\n  csv_options = datalab.bigquery.CSVOptions(delimiter=args['delimiter'],\n                                            skip_leading_rows=args['skip'],\n                                            allow_jagged_rows=not args['strict'],\n                                            quote=args['quote'])\n  job = table.load(args['source'],\n                   mode=args['mode'],\n                   source_format=('CSV' if args['format'] == 'csv' else 'NEWLINE_DELIMITED_JSON'),\n                   csv_options=csv_options,\n                   ignore_unknown_values=not args['strict'])\n  if job.failed:\n    raise Exception('Load failed: %s' % str(job.fatal_error))\n  elif job.errors:\n    raise Exception('Load completed with errors: %s' % str(job.errors))\n\n\ndef _add_command(parser, subparser_fn, handler, cell_required=False, cell_prohibited=False):\n  \"\"\" Create and initialize a bigquery subcommand handler. \"\"\"\n  sub_parser = subparser_fn(parser)\n  sub_parser.set_defaults(func=lambda args, cell: _dispatch_handler(args, cell, sub_parser, handler,\n                          cell_required=cell_required, cell_prohibited=cell_prohibited))\n\n\ndef _create_bigquery_parser():\n  \"\"\" Create the parser for the %bigquery magics.\n\n  Note that because we use the func default handler dispatch mechanism of argparse,\n  our handlers can take only one argument which is the parsed args. So we must create closures\n  for the handlers that bind the cell contents and thus must recreate this parser for each\n  cell upon execution.\n  \"\"\"\n  parser = datalab.utils.commands.CommandParser(prog='bigquery', description=\"\"\"\nExecute various BigQuery-related operations. Use \"%bigquery <command> -h\"\nfor help on a specific command.\n  \"\"\")\n\n  # This is a bit kludgy because we want to handle some line magics and some cell magics\n  # with the bigquery command.\n\n  # %%bigquery sample\n  _add_command(parser, _create_sample_subparser, _sample_cell)\n\n  # %%bigquery create\n  _add_command(parser, _create_create_subparser, _create_cell)\n\n  # %%bigquery delete\n  _add_command(parser, _create_delete_subparser, _delete_cell)\n\n  # %%bigquery dryrun\n  _add_command(parser, _create_dry_run_subparser, _dryrun_cell)\n\n  # %%bigquery udf\n  _add_command(parser, _create_udf_subparser, _udf_cell, cell_required=True)\n\n  # %%bigquery execute\n  _add_command(parser, _create_execute_subparser, _execute_cell)\n\n  # %%bigquery pipeline\n  _add_command(parser, _create_pipeline_subparser, _pipeline_cell)\n\n  # %bigquery table\n  _add_command(parser, _create_table_subparser, _table_line, cell_prohibited=True)\n\n  # %bigquery schema\n  _add_command(parser, _create_schema_subparser, _schema_line, cell_prohibited=True)\n\n  # %bigquery datasets\n  _add_command(parser, _create_datasets_subparser, _datasets_line, cell_prohibited=True)\n\n  # %bigquery tables\n  _add_command(parser, _create_tables_subparser, _tables_line, cell_prohibited=True)\n\n  # % bigquery extract\n  _add_command(parser, _create_extract_subparser, _extract_line, cell_prohibited=True)\n\n  # %bigquery load\n  # TODO(gram): need some additional help, esp. around the option of specifying schema in\n  # cell body and how schema infer may fail.\n  _add_command(parser, _create_load_subparser, _load_cell)\n  return parser\n\n\n_bigquery_parser = _create_bigquery_parser()\n\n\n@IPython.core.magic.register_line_cell_magic\ndef bigquery(line, cell=None):\n  \"\"\"Implements the bigquery cell magic for ipython notebooks.\n\n  The supported syntax is:\n\n    %%bigquery <command> [<args>]\n    <cell>\n\n  or:\n\n    %bigquery <command> [<args>]\n\n  Use %bigquery --help for a list of commands, or %bigquery <command> --help for help\n  on a specific command.\n  \"\"\"\n  namespace = {}\n  if line.find('$') >= 0:\n    # We likely have variables to expand; get the appropriate context.\n    namespace = datalab.utils.commands.notebook_environment()\n\n  return datalab.utils.commands.handle_magic_line(line, cell, _bigquery_parser, namespace=namespace)\n\n\ndef _dispatch_handler(args, cell, parser, handler, cell_required=False, cell_prohibited=False):\n  \"\"\" Makes sure cell magics include cell and line magics don't, before dispatching to handler.\n\n  Args:\n    args: the parsed arguments from the magic line.\n    cell: the contents of the cell, if any.\n    parser: the argument parser for <cmd>; used for error message.\n    handler: the handler to call if the cell present/absent check passes.\n    cell_required: True for cell magics, False for line magics that can't be cell magics.\n    cell_prohibited: True for line magics, False for cell magics that can't be line magics.\n  Returns:\n    The result of calling the handler.\n  Raises:\n    Exception if the invocation is not valid.\n  \"\"\"\n  if cell_prohibited:\n    if cell and len(cell.strip()):\n      parser.print_help()\n      raise Exception('Additional data is not supported with the %s command.' % parser.prog)\n    return handler(args)\n\n  if cell_required and not cell:\n    parser.print_help()\n    raise Exception('The %s command requires additional data' % parser.prog)\n\n  return handler(args, cell)\n\n\ndef _table_viewer(table, rows_per_page=25, fields=None):\n  \"\"\"  Return a table viewer.\n\n    This includes a static rendering of the first page of the table, that gets replaced\n    by the charting code in environments where Javascript is executable and BQ is available.\n\n  Args:\n    table: the table to view.\n    rows_per_page: how many rows to display at one time.\n    fields: an array of field names to display; default is None which uses the full schema.\n  Returns:\n    A string containing the HTML for the table viewer.\n  \"\"\"\n\n  # TODO(gram): rework this to use datalab.utils.commands.chart_html\n\n  if not table.exists():\n    raise Exception('Table %s does not exist' % str(table))\n\n  if not table.is_listable():\n    return \"Done\"\n\n  _HTML_TEMPLATE = u\"\"\"\n    <div class=\"bqtv\" id=\"{div_id}\">{static_table}</div>\n    <br />{meta_data}<br />\n    <script src=\"/static/components/requirejs/require.js\"></script>\n    <script>\n\n      require.config({{\n        paths: {{\n          base: '/static/base',\n          d3: '//cdnjs.cloudflare.com/ajax/libs/d3/3.4.13/d3',\n          plotly: 'https://cdn.plot.ly/plotly-1.5.1.min.js?noext',\n          jquery: '//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min'\n        }},\n        map: {{\n          '*': {{\n            datalab: 'nbextensions/gcpdatalab'\n          }}\n        }},\n        shim: {{\n          plotly: {{\n            deps: ['d3', 'jquery'],\n            exports: 'plotly'\n          }}\n        }}\n      }});\n\n      require(['datalab/charting', 'datalab/element!{div_id}', 'base/js/events',\n          'datalab/style!/nbextensions/gcpdatalab/charting.css'],\n        function(charts, dom, events) {{\n          charts.render('gcharts', dom, events, '{chart_style}', [], {data},\n            {{\n              pageSize: {rows_per_page},\n              cssClassNames:  {{\n                tableRow: 'gchart-table-row',\n                headerRow: 'gchart-table-headerrow',\n                oddTableRow: 'gchart-table-oddrow',\n                selectedTableRow: 'gchart-table-selectedrow',\n                hoverTableRow: 'gchart-table-hoverrow',\n                tableCell: 'gchart-table-cell',\n                headerCell: 'gchart-table-headercell',\n                rowNumberCell: 'gchart-table-rownumcell'\n              }}\n            }},\n            {{source_index: {source_index}, fields: '{fields}', legacy: 'true'}},\n            0,\n            {total_rows});\n        }}\n      );\n    </script>\n  \"\"\"\n\n  if fields is None:\n    fields = datalab.utils.commands.get_field_list(fields, table.schema)\n  div_id = datalab.utils.commands.Html.next_id()\n  meta_count = ('rows: %d' % table.length) if table.length >= 0 else ''\n  meta_name = str(table) if table.job is None else ('job: %s' % table.job.id)\n  if table.job:\n    if table.job.cache_hit:\n      meta_cost = 'cached'\n    else:\n      bytes = datalab.bigquery._query_stats.QueryStats._size_formatter(table.job.bytes_processed)\n      meta_cost = '%s processed' % bytes\n    meta_time = 'time: %.1fs' % table.job.total_time\n  else:\n    meta_cost = ''\n    meta_time = ''\n\n  data, total_count = datalab.utils.commands.get_data(table, fields, first_row=0,\n                                                      count=rows_per_page)\n\n  if total_count < 0:\n    # The table doesn't have a length metadata property but may still be small if we fetched less\n    # rows than we asked for.\n    fetched_count = len(data['rows'])\n    if fetched_count < rows_per_page:\n      total_count = fetched_count\n\n  chart = 'table' if 0 <= total_count <= rows_per_page else 'paged_table'\n  meta_entries = [meta_count, meta_time, meta_cost, meta_name]\n  meta_data = '(%s)' % (', '.join([entry for entry in meta_entries if len(entry)]))\n\n  return _HTML_TEMPLATE.format(div_id=div_id,\n                               static_table=datalab.utils.commands.HtmlBuilder\n                               .render_chart_data(data),\n                               meta_data=meta_data,\n                               chart_style=chart,\n                               source_index=datalab.utils.commands\n                               .get_data_source_index(str(table)),\n                               fields=','.join(fields),\n                               total_rows=total_count,\n                               rows_per_page=rows_per_page,\n                               data=json.dumps(data, cls=datalab.utils.JSONEncoder))\n\n\ndef _repr_html_query(query):\n  # TODO(nikhilko): Pretty print the SQL\n  return datalab.utils.commands.HtmlBuilder.render_text(query.sql, preformatted=True)\n\n\ndef _repr_html_query_results_table(results):\n  return _table_viewer(results)\n\n\ndef _repr_html_table(results):\n  return _table_viewer(results)\n\n\ndef _repr_html_table_schema(schema):\n  _HTML_TEMPLATE = \"\"\"\n    <div class=\"bqsv\" id=\"%s\"></div>\n\n    <script src=\"/static/components/requirejs/require.js\"></script>\n    <script>\n      require.config({\n        paths: {\n          base: '/static/base',\n        },\n        map: {\n          '*': {\n            datalab: 'nbextensions/gcpdatalab'\n          }\n        },\n      });\n\n      require(['datalab/bigquery', 'datalab/element!%s',\n          'datalab/style!/nbextensions/gcpdatalab/bigquery.css'],\n        function(bq, dom) {\n          bq.renderSchema(dom, %s);\n        }\n      );\n    </script>\n    \"\"\"\n  id = datalab.utils.commands.Html.next_id()\n  return _HTML_TEMPLATE % (id, id, json.dumps(schema._bq_schema))\n\n\ndef _register_html_formatters():\n  try:\n    ipy = IPython.get_ipython()\n    html_formatter = ipy.display_formatter.formatters['text/html']\n\n    html_formatter.for_type_by_name('datalab.bigquery._query', 'Query', _repr_html_query)\n    html_formatter.for_type_by_name('datalab.bigquery._query_results_table', 'QueryResultsTable',\n                                    _repr_html_query_results_table)\n    html_formatter.for_type_by_name('datalab.bigquery._table', 'Table', _repr_html_table)\n    html_formatter.for_type_by_name('datalab.bigquery._schema', 'Schema', _repr_html_table_schema)\n  except TypeError:\n    # For when running unit tests\n    pass\n\n\n_register_html_formatters()\n"
  },
  {
    "path": "datalab/context/__init__.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Google Cloud Platform library - authorization Context for Cloud services.\"\"\"\n\nfrom ._context import Context\nfrom ._project import Project, Projects\n\n__all__ = ['Context', 'Project', 'Projects']\n"
  },
  {
    "path": "datalab/context/_api.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Implements HTTP API wrapper.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom builtins import object\n\nimport datalab.utils\n\n\nclass Api(object):\n  \"\"\"A helper class to issue API HTTP requests to resource manager API.\"\"\"\n\n  _ENDPOINT = 'https://cloudresourcemanager.googleapis.com/v1'\n  _PROJECT_PATH = '/projects/%s'\n  _PROJECTS_PATH = '/projects'\n\n  def __init__(self, credentials):\n    self._credentials = credentials\n\n  def projects_list(self, max_results=0, page_token=None):\n    url = Api._ENDPOINT + Api._PROJECTS_PATH\n    args = {}\n    if max_results != 0:\n      args['pageSize'] = max_results\n    if page_token is not None:\n      args['pageToken'] = page_token\n\n    return datalab.utils.Http.request(url, args=args, credentials=self._credentials)\n\n  def project_get(self, projectId):\n    url = Api._ENDPOINT + (Api._PROJECT_PATH % projectId)\n    return datalab.utils.Http.request(url, credentials=self._credentials)\n"
  },
  {
    "path": "datalab/context/_context.py",
    "content": "# Copyright 2014 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#  http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\"\"\"Implements Context functionality.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom builtins import object\n\nfrom . import _project\nfrom . import _utils\n\n\nclass Context(object):\n  \"\"\"Maintains contextual state for connecting to Cloud APIs.\n  \"\"\"\n\n  _global_context = None\n\n  def __init__(self, project_id, credentials):\n    \"\"\"Initializes an instance of a Context object.\n\n    Args:\n      project_id: the current cloud project.\n      credentials: the credentials to use to authorize requests.\n    \"\"\"\n    self._project_id = project_id\n    self._credentials = credentials\n\n  @property\n  def credentials(self):\n    \"\"\"Retrieves the value of the credentials property.\n\n    Returns:\n      The current credentials used in authorizing API requests.\n    \"\"\"\n    return self._credentials\n\n  def set_credentials(self, credentials):\n    \"\"\" Set the credentials for the context. \"\"\"\n    self._credentials = credentials\n\n  @property\n  def project_id(self):\n    \"\"\"Retrieves the value of the project_id property.\n\n    Returns:\n      The current project id to associate with API requests.\n    \"\"\"\n    if not self._project_id:\n      raise Exception('No project ID found. Perhaps you should set one by running '\n                      '\"%projects set <project-id>\" in a code cell.')\n    return self._project_id\n\n  def set_project_id(self, project_id):\n    \"\"\" Set the project_id for the context. \"\"\"\n    self._project_id = project_id\n    if self == Context._global_context:\n      try:\n        from google.datalab import Context as new_context\n        new_context.default().set_project_id(project_id)\n      except ImportError:\n        # If the new library is not loaded, then we have nothing to do.\n        pass\n\n  @staticmethod\n  def is_signed_in():\n    \"\"\" If the user has signed in or it is on GCE VM with default credential.\"\"\"\n    try:\n      _utils.get_credentials()\n      return True\n    except Exception:\n      return False\n\n  @staticmethod\n  def default():\n    \"\"\"Retrieves a default Context object, creating it if necessary.\n\n      The default Context is a global shared instance used every time the default context is\n      retrieved.\n\n      Attempting to use a Context with no project_id will raise an exception, so on first use\n      set_project_id must be called.\n\n    Returns:\n      An initialized and shared instance of a Context object.\n    \"\"\"\n    credentials = _utils.get_credentials()\n    if Context._global_context is None:\n      project = _project.Projects.get_default_id(credentials)\n      Context._global_context = Context(project, credentials)\n    else:\n      # Always update the credentials in case the access token is revoked or expired\n      Context._global_context.set_credentials(credentials)\n    return Context._global_context\n"
  },
  {
    "path": "datalab/context/_project.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Implements Projects functionality.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom builtins import object\n\nimport datalab.utils\n\nfrom . import _api\nfrom . import _utils\n\n\n# We could do this with the gcloud SDK. However, installing that while locked on oauth2.5\n# introduces some ugliness; in particular we are stuck with v0.9 and need to work around:\n#\n#   https://github.com/GoogleCloudPlatform/gcloud-python/issues/1412\n#\n# and would have to put up with:\n#\n#    https://github.com/GoogleCloudPlatform/gcloud-python/issues/1570\n#\n# So we use the REST API instead.\n\nclass Project(object):\n  \"\"\" Simple wrapper class for Cloud projects. \"\"\"\n\n  def __init__(self, api, id, number, name):\n    self._api = api\n    self._id = id\n    self._number = number\n    self._name = name\n\n  @property\n  def id(self):\n    return self._id\n\n  @property\n  def name(self):\n    return self._name\n\n  @property\n  def number(self):\n    return self._number\n\n  def __str__(self):\n    return self._id\n\n\nclass Projects(object):\n  \"\"\" Iterator class for enumerating the active projects accessible to the account. \"\"\"\n\n  def __init__(self, credentials=None):\n    \"\"\" Initialize the Projects object.\n\n    Args:\n      credentials: the credentials for the account.\n    \"\"\"\n    if credentials is None:\n      credentials = _utils.get_credentials()\n    self._api = _api.Api(credentials)\n\n  def _retrieve_projects(self, page_token, count):\n    try:\n      list_info = self._api.projects_list(max_results=count,\n                                          page_token=page_token)\n    except Exception as e:\n      raise e\n\n    projects = list_info.get('projects', [])\n    if len(projects):\n      try:\n        projects = [Project(self._api, info['projectId'], info['projectNumber'], info['name'])\n                    for info in projects if info['lifecycleState'] == 'ACTIVE']\n      except KeyError:\n        raise Exception('Unexpected response from server.')\n\n    page_token = list_info.get('nextPageToken', None)\n    return projects, page_token\n\n  def __iter__(self):\n    \"\"\" Returns an iterator for iterating through the Datasets in the project.\n    \"\"\"\n    return iter(datalab.utils.Iterator(self._retrieve_projects))\n\n  @staticmethod\n  def get_default_id(credentials=None):\n    \"\"\" Get default project id.\n\n    Returns: the default project id if there is one, or None.\n    \"\"\"\n    project_id = _utils.get_project_id()\n    if project_id is None:\n      projects, _ = Projects(credentials)._retrieve_projects(None, 2)\n      if len(projects) == 1:\n        project_id = projects[0].id\n    return project_id\n\n  @staticmethod\n  def save_default_id(project_id):\n    \"\"\" Save default project id to config so it will persist across kernels and Datalab runs.\n\n    Args:\n      project_id: the project_id to save.\n    \"\"\"\n    _utils.save_project_id(project_id)\n"
  },
  {
    "path": "datalab/context/_utils.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#  http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\"\"\" Support for getting gcloud credentials. \"\"\"\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nimport json\nimport os\nimport subprocess\n\nimport oauth2client.client\nimport google.auth\nimport google.auth.exceptions\nimport google.auth.credentials\nimport google.auth._oauth2client\n\n\n# TODO(ojarjur): This limits the APIs against which Datalab can be called\n# (when using a service account with a credentials file) to only being those\n# that are part of the Google Cloud Platform. We should either extend this\n# to all of the API scopes that Google supports, or make it extensible so\n# that the user can define for themselves which scopes they want to use.\nCREDENTIAL_SCOPES = [\n  'https://www.googleapis.com/auth/cloud-platform',\n]\n\n\ndef _in_datalab_docker():\n  return os.path.exists('/datalab') and os.getenv('DATALAB_ENV')\n\n\ndef get_config_dir():\n  config_dir = os.getenv('CLOUDSDK_CONFIG')\n  if config_dir is None:\n    if os.name == 'nt':\n      try:\n        config_dir = os.path.join(os.environ['APPDATA'], 'gcloud')\n      except KeyError:\n        # This should never happen unless someone is really messing with things.\n        drive = os.environ.get('SystemDrive', 'C:')\n        config_dir = os.path.join(drive, '\\\\gcloud')\n    else:\n      config_dir = os.path.join(os.path.expanduser('~'), '.config/gcloud')\n  return config_dir\n\n\ndef _convert_oauth2client_creds(credentials):\n  new_credentials = google.oauth2.credentials.Credentials(\n    token=credentials.access_token,\n    refresh_token=credentials.refresh_token,\n    token_uri=credentials.token_uri,\n    client_id=credentials.client_id,\n    client_secret=credentials.client_secret,\n    scopes=credentials.scopes)\n\n  new_credentials._expires = credentials.token_expiry\n  return new_credentials\n\n\ndef get_credentials():\n  \"\"\" Get the credentials to use. We try application credentials first, followed by\n      user credentials. The path to the application credentials can be overridden\n      by pointing the GOOGLE_APPLICATION_CREDENTIALS environment variable to some file;\n      the path to the user credentials can be overridden by pointing the CLOUDSDK_CONFIG\n      environment variable to some directory (after which we will look for the file\n      $CLOUDSDK_CONFIG/gcloud/credentials). Unless you have specific reasons for\n      overriding these the defaults should suffice.\n  \"\"\"\n  try:\n    credentials, _ = google.auth.default()\n    credentials = google.auth.credentials.with_scopes_if_required(credentials, CREDENTIAL_SCOPES)\n    return credentials\n  except Exception as e:\n\n    # Try load user creds from file\n    cred_file = get_config_dir() + '/credentials'\n    if os.path.exists(cred_file):\n      with open(cred_file) as f:\n        creds = json.loads(f.read())\n      # Use the first gcloud one we find\n      for entry in creds['data']:\n        if entry['key']['type'] == 'google-cloud-sdk':\n          creds = oauth2client.client.OAuth2Credentials.from_json(json.dumps(entry['credential']))\n          return _convert_oauth2client_creds(creds)\n\n    if type(e) == google.auth.exceptions.DefaultCredentialsError:\n      # If we are in Datalab container, change the message to be about signing in.\n      if _in_datalab_docker():\n        raise Exception('No application credentials found. Perhaps you should sign in.')\n\n    raise e\n\n\ndef save_project_id(project_id):\n  \"\"\" Save project id to config file.\n\n  Args:\n    project_id: the project_id to save.\n  \"\"\"\n  # Try gcloud first. If gcloud fails (probably because it does not exist), then\n  # write to a config file.\n  try:\n    subprocess.call(['gcloud', 'config', 'set', 'project', project_id])\n  except:\n    config_file = os.path.join(get_config_dir(), 'config.json')\n    config = {}\n    if os.path.exists(config_file):\n      with open(config_file) as f:\n        config = json.loads(f.read())\n    config['project_id'] = project_id\n    with open(config_file, 'w') as f:\n      f.write(json.dumps(config))\n\n\ndef get_project_id():\n  \"\"\" Get default project id from config or environment var.\n\n  Returns: the project id if available, or None.\n  \"\"\"\n  # Try getting default project id from gcloud. If it fails try config.json.\n  try:\n    proc = subprocess.Popen(['gcloud', 'config', 'list', '--format', 'value(core.project)'],\n                            stdout=subprocess.PIPE)\n    stdout, _ = proc.communicate()\n    value = stdout.decode().strip()\n    if proc.poll() == 0 and value:\n      return value\n  except:\n    pass\n\n  config_file = os.path.join(get_config_dir(), 'config.json')\n  if os.path.exists(config_file):\n    with open(config_file) as f:\n      config = json.loads(f.read())\n      if 'project_id' in config and config['project_id']:\n        return str(config['project_id'])\n\n  if os.getenv('PROJECT_ID') is not None:\n    return os.getenv('PROJECT_ID')\n  return None\n"
  },
  {
    "path": "datalab/context/commands/__init__.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\nfrom __future__ import absolute_import\n\nfrom . import _projects\n\n__all__ = ['_projects']\n"
  },
  {
    "path": "datalab/context/commands/_projects.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Implements listing projects and setting default project.\"\"\"\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\ntry:\n  import IPython\n  import IPython.core.magic\n  import IPython.core.display\nexcept ImportError:\n  raise Exception('This module can only be loaded in ipython.')\n\nimport fnmatch\n\nimport datalab.utils.commands\nimport datalab.context\n\n\n@IPython.core.magic.register_line_cell_magic\ndef projects(line, cell=None):\n  parser = datalab.utils.commands.CommandParser.create('projects')\n\n  list_parser = parser.subcommand('list', 'List available projects.')\n  list_parser.add_argument('-f', '--filter',\n                           help='Optional wildcard id filter string used to limit the results')\n  list_parser.set_defaults(func=_list_line, cell_prohibited=True)\n\n  set_parser = parser.subcommand('set', 'Set the default project.')\n  set_parser.add_argument('id', help='The ID of the project to use')\n  set_parser.set_defaults(func=_set_line, cell_prohibited=True)\n\n  return datalab.utils.commands.handle_magic_line(line, cell, parser)\n\n\ndef _list_line(args, _):\n  # TODO(gram): should we use a paginated table?\n  filter_ = args['filter'] if args['filter'] else '*'\n  data = [{'id': project.id, 'name': project.name}\n          for project in datalab.context.Projects() if fnmatch.fnmatch(project.id, filter_)]\n  return IPython.core.display.HTML(datalab.utils.commands.HtmlBuilder.render_table(data, ['id',\n                                                                                          'name']))\n\n\ndef _set_line(args, _):\n  id_ = args['id'] if args['id'] else ''\n  context = datalab.context.Context.default()\n  context.set_project_id(id_)\n  datalab.context.Projects.save_default_id(id_)\n"
  },
  {
    "path": "datalab/data/__init__.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Google Cloud Platform library - Generic SQL Helpers.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\n\nfrom ._csv import Csv\nfrom ._sql_module import SqlModule\nfrom ._sql_statement import SqlStatement\nfrom ._utils import tokenize\n\n__all__ = ['Csv', 'SqlModule', 'SqlStatement', 'tokenize']\n"
  },
  {
    "path": "datalab/data/_csv.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Implements usefule CSV utilities.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom builtins import next\nfrom builtins import str as newstr\nfrom builtins import range\nfrom builtins import object\n\n\nimport csv\nimport os\nimport pandas as pd\nimport random\nimport sys\n\ntry:\n    from StringIO import StringIO\nexcept ImportError:\n    from io import StringIO\nimport tempfile\nimport datalab.storage\nimport datalab.utils\n\n\n_MAX_CSV_BYTES = 10000000\n\n\nclass Csv(object):\n  \"\"\"Represents a CSV file in GCS or locally with same schema.\n  \"\"\"\n  def __init__(self, path, delimiter=b','):\n    \"\"\"Initializes an instance of a Csv instance.\n    Args:\n      path: path of the Csv file.\n      delimiter: the separator used to parse a Csv line.\n    \"\"\"\n    self._path = path\n    self._delimiter = delimiter\n\n  @property\n  def path(self):\n    return self._path\n\n  @staticmethod\n  def _read_gcs_lines(path, max_lines=None):\n    return datalab.storage.Item.from_url(path).read_lines(max_lines)\n\n  @staticmethod\n  def _read_local_lines(path, max_lines=None):\n    lines = []\n    for line in open(path):\n      if max_lines is not None and len(lines) >= max_lines:\n        break\n      lines.append(line)\n    return lines\n\n  def _is_probably_categorical(self, column):\n    if newstr(column.dtype) != 'object':\n      # only string types (represented in DataFrame as object) can potentially be categorical\n      return False\n    if len(max(column, key=lambda p: len(newstr(p)))) > 100:\n      return False  # value too long to be a category\n    if len(set(column)) > 100:\n      return False  # too many unique values to be a category\n    return True\n\n  def browse(self, max_lines=None, headers=None):\n    \"\"\"Try reading specified number of lines from the CSV object.\n    Args:\n      max_lines: max number of lines to read. If None, the whole file is read\n      headers: a list of strings as column names. If None, it will use \"col0, col1...\"\n    Returns:\n      A pandas DataFrame with the schema inferred from the data.\n    Raises:\n      Exception if the csv object cannot be read or not enough lines to read, or the\n      headers size does not match columns size.\n    \"\"\"\n    if self.path.startswith('gs://'):\n      lines = Csv._read_gcs_lines(self.path, max_lines)\n    else:\n      lines = Csv._read_local_lines(self.path, max_lines)\n    if len(lines) == 0:\n      return pd.DataFrame(columns=headers)\n    columns_size = len(next(csv.reader([lines[0]], delimiter=self._delimiter)))\n    if headers is None:\n      headers = ['col' + newstr(e) for e in range(columns_size)]\n    if len(headers) != columns_size:\n      raise Exception('Number of columns in CSV do not match number of headers')\n    buf = StringIO()\n    for line in lines:\n      buf.write(line)\n      buf.write('\\n')\n    buf.seek(0)\n    df = pd.read_csv(buf, names=headers, delimiter=self._delimiter)\n    for key, col in df.iteritems():\n      if self._is_probably_categorical(col):\n        df[key] = df[key].astype('category')\n    return df\n\n  def _create_federated_table(self, skip_header_rows):\n    import datalab.bigquery as bq\n    df = self.browse(1, None)\n    # read each column as STRING because we only want to sample rows.\n    schema_train = bq.Schema([{'name': name, 'type': 'STRING'} for name in df.keys()])\n    options = bq.CSVOptions(skip_leading_rows=(1 if skip_header_rows is True else 0))\n    return bq.FederatedTable.from_storage(self.path,\n                                          csv_options=options,\n                                          schema=schema_train,\n                                          max_bad_records=0)\n\n  def _get_gcs_csv_row_count(self, federated_table):\n    import datalab.bigquery as bq\n    results = bq.Query('SELECT count(*) from data',\n                       data_sources={'data': federated_table}).results()\n    return results[0].values()[0]\n\n  def sample_to(self, count, skip_header_rows, strategy, target):\n    \"\"\"Sample rows from GCS or local file and save results to target file.\n\n    Args:\n      count: number of rows to sample. If strategy is \"BIGQUERY\", it is used as approximate number.\n      skip_header_rows: whether to skip first row when reading from source.\n      strategy: can be \"LOCAL\" or \"BIGQUERY\". If local, the sampling happens in local memory,\n          and number of resulting rows matches count. If BigQuery, sampling is done\n          with BigQuery in cloud, and the number of resulting rows will be approximated to\n          count.\n      target: The target file path, can be GCS or local path.\n    Raises:\n      Exception if strategy is \"BIGQUERY\" but source is not a GCS path.\n    \"\"\"\n    # TODO(qimingj) Add unit test\n    # Read data from source into DataFrame.\n\n    if sys.version_info.major > 2:\n      xrange = range  # for python 3 compatibility\n\n    if strategy == 'BIGQUERY':\n      import datalab.bigquery as bq\n      if not self.path.startswith('gs://'):\n        raise Exception('Cannot use BIGQUERY if data is not in GCS')\n      federated_table = self._create_federated_table(skip_header_rows)\n      row_count = self._get_gcs_csv_row_count(federated_table)\n      query = bq.Query('SELECT * from data', data_sources={'data': federated_table})\n      sampling = bq.Sampling.random(count * 100 / float(row_count))\n      sample = query.sample(sampling=sampling)\n      df = sample.to_dataframe()\n    elif strategy == 'LOCAL':\n      local_file = self.path\n      if self.path.startswith('gs://'):\n        local_file = tempfile.mktemp()\n        datalab.utils.gcs_copy_file(self.path, local_file)\n      with open(local_file) as f:\n        row_count = sum(1 for line in f)\n      start_row = 1 if skip_header_rows is True else 0\n      skip_count = row_count - count - 1 if skip_header_rows is True else row_count - count\n      skip = sorted(random.sample(xrange(start_row, row_count), skip_count))\n      header_row = 0 if skip_header_rows is True else None\n      df = pd.read_csv(local_file, skiprows=skip, header=header_row, delimiter=self._delimiter)\n      if self.path.startswith('gs://'):\n        os.remove(local_file)\n    else:\n      raise Exception('strategy must be BIGQUERY or LOCAL')\n    # Write to target.\n    if target.startswith('gs://'):\n      with tempfile.NamedTemporaryFile() as f:\n        df.to_csv(f, header=False, index=False)\n        f.flush()\n        datalab.utils.gcs_copy_file(f.name, target)\n    else:\n      with open(target, 'w') as f:\n        df.to_csv(f, header=False, index=False, sep=str(self._delimiter))\n"
  },
  {
    "path": "datalab/data/_sql_module.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Helper functions for %%sql modules.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom builtins import str\nfrom past.builtins import basestring\nfrom builtins import object\n\nimport shlex\n\nfrom . import _sql_statement\nfrom . import _utils\n\n\n# It would be nice to be able to inherit from Python module but AFAICT that is not possible.\n# So this just wraps a bunch of static helpers.\n\nclass SqlModule(object):\n  \"\"\" A container for SqlStatements defined together and able to reference each other. \"\"\"\n\n  @staticmethod\n  def _get_sql_args(parser, args=None):\n    \"\"\" Parse a set of %%sql arguments or get the default value of the arguments.\n\n    Args:\n      parser: the argument parser to use.\n      args: the argument flags. May be a string or a list. If omitted the empty string is used so\n          we can get the default values for the arguments. These are all used to override the\n          arg parser. Alternatively args may be a dictionary, in which case it overrides the\n          default values from the arg parser.\n    Returns:\n      A dictionary of argument names and values.\n    \"\"\"\n    overrides = None\n    if args is None:\n      tokens = []\n    elif isinstance(args, basestring):\n      command_line = ' '.join(args.split('\\n'))\n      tokens = shlex.split(command_line)\n    elif isinstance(args, dict):\n      overrides = args\n      tokens = []\n    else:\n      tokens = args\n\n    args = {} if parser is None else vars(parser.parse_args(tokens))\n    if overrides:\n      args.update(overrides)\n\n    # Don't return any args that are None as we don't want to expand to 'None'\n    return {arg: value for arg, value in args.items() if value is not None}\n\n  @staticmethod\n  def get_default_query_from_module(module):\n    \"\"\" Given a %%sql module return the default (last) query for the module.\n\n    Args:\n      module: the %%sql module.\n\n    Returns:\n      The default query associated with this module.\n    \"\"\"\n    return _utils.get_default_query_from_module(module)\n\n  @staticmethod\n  def get_sql_statement_with_environment(item, args=None):\n    \"\"\" Given a SQLStatement, string or module plus command line args or a dictionary,\n     return a SqlStatement and final dictionary for variable resolution.\n\n    Args:\n      item: a SqlStatement, %%sql module, or string containing a query.\n      args: a string of command line arguments or a dictionary of values.\n\n    Returns:\n      A SqlStatement for the query or module, plus a dictionary of variable values to use.\n    \"\"\"\n    if isinstance(item, basestring):\n      item = _sql_statement.SqlStatement(item)\n    elif not isinstance(item, _sql_statement.SqlStatement):\n      item = SqlModule.get_default_query_from_module(item)\n      if not item:\n        raise Exception('Expected a SQL statement or module but got %s' % str(item))\n\n    env = {}\n    if item.module:\n      env.update(item.module.__dict__)\n      parser = env.get(_utils._SQL_MODULE_ARGPARSE, None)\n      if parser:\n        args = SqlModule._get_sql_args(parser, args=args)\n      else:\n        args = None\n\n    if isinstance(args, dict):\n      env.update(args)\n\n    return item, env\n\n  @staticmethod\n  def expand(sql, args=None):\n    \"\"\" Expand a SqlStatement, query string or SqlModule with a set of arguments.\n\n    Args:\n      sql: a SqlStatement, %%sql module, or string containing a query.\n      args: a string of command line arguments or a dictionary of values. If a string, it is\n          passed to the argument parser for the SqlModule associated with the SqlStatement or\n          SqlModule. If a dictionary, it is used to override any default arguments from the\n          argument parser. If the sql argument is a string then args must be None or a dictionary\n          as in this case there is no associated argument parser.\n    Returns:\n      The expanded SQL, list of referenced scripts, and list of referenced external tables.\n    \"\"\"\n    sql, args = SqlModule.get_sql_statement_with_environment(sql, args)\n    return _sql_statement.SqlStatement.format(sql._sql, args)\n"
  },
  {
    "path": "datalab/data/_sql_statement.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Implements SQL statement helper functionality.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom builtins import str\nfrom builtins import object\nfrom past.builtins import basestring\n\nimport re\nimport types\n\nimport datalab.utils\n\nfrom . import _utils\n\n\nclass SqlStatement(object):\n  \"\"\"A helper class for wrapping and manipulating SQL statements.\n  \"\"\"\n\n  def __init__(self, sql, module=None):\n    \"\"\" Initializes the SqlStatement.\n\n    Args:\n      sql: a string containing a SQL query with optional variable references.\n      module: if defined in a %%sql cell, the parent SqlModule object for the SqlStatement.\n    \"\"\"\n    self._sql = sql\n    self._module = module\n\n  def __str__(self):\n    \"\"\"Creates a string representation of this object.\n\n    Returns:\n      The string representation of this object.\n    \"\"\"\n    return self._sql\n\n  def __repr__(self):\n    \"\"\"Creates a friendly representation of this object.\n\n    Returns:\n      The friendly representation of this object.\n    \"\"\"\n    return self._sql\n\n  @property\n  def sql(self):\n    \"\"\" The (unexpanded) SQL for the SqlStatement. \"\"\"\n    return self._sql\n\n  @property\n  def module(self):\n    \"\"\" The parent SqlModule for the SqlStatement, if any. \"\"\"\n    return self._module\n\n  @staticmethod\n  def _find_recursive_dependencies(sql, values, code, resolved_vars, resolving_vars=None):\n    \"\"\" Recursive helper method for expanding variables including transitive dependencies.\n\n    Placeholders in SQL are represented as $<name>. If '$' must appear within\n    the SQL statement literally, then it can be escaped as '$$'.\n\n    Args:\n      sql: the raw SQL statement with named placeholders.\n      values: the user-supplied dictionary of name/value pairs to use for placeholder values.\n      code: an array of referenced UDFs found during expansion.\n      resolved_vars: a ref parameter for the variable references completely resolved so far.\n      resolving_vars: a ref parameter for the variable(s) we are currently resolving; if we see\n          a dependency again that is in this set we know we have a circular reference.\n    Returns:\n      The formatted SQL statement with placeholders replaced with their values.\n    Raises:\n      Exception if a placeholder was found in the SQL statement, but did not\n      have a corresponding argument value.\n    \"\"\"\n\n    # Get the set of $var references in this SQL.\n    dependencies = SqlStatement._get_dependencies(sql)\n    for dependency in dependencies:\n      # Now we check each dependency. If it is in complete - i.e., we have an expansion\n      # for it already - we just continue.\n      if dependency in resolved_vars:\n        continue\n      # Look it up in our resolution namespace dictionary.\n      dep = datalab.utils.get_item(values, dependency)\n      # If it is a SQL module, get the main/last query from the module, so users can refer\n      # to $module. Useful especially if final query in module has no DEFINE QUERY <name> part.\n      if isinstance(dep, types.ModuleType):\n        dep = _utils.get_default_query_from_module(dep)\n      # If we can't resolve the $name, give up.\n      if dep is None:\n        raise Exception(\"Unsatisfied dependency $%s\" % dependency)\n      # If it is a SqlStatement, it may have its own $ references in turn; check to make\n      # sure we don't have circular references, and if not, recursively expand it and add\n      # it to the set of complete dependencies.\n      if isinstance(dep, SqlStatement):\n        if resolving_vars is None:\n          resolving_vars = []\n        elif dependency in resolving_vars:\n          # Circular dependency\n          raise Exception(\"Circular dependency in $%s\" % dependency)\n        resolving_vars.append(dependency)\n        SqlStatement._find_recursive_dependencies(dep._sql, values, code, resolved_vars,\n                                                  resolving_vars)\n        resolving_vars.pop()\n        resolved_vars[dependency] = SqlStatement(dep._sql)\n      else:\n        resolved_vars[dependency] = dep\n\n  @staticmethod\n  def _escape_string(s):\n    return '\"' + s.replace('\"', '\\\\\"') + '\"'\n\n  @staticmethod\n  def format(sql, args=None):\n    \"\"\" Resolve variable references in a query within an environment.\n\n    This computes and resolves the transitive dependencies in the query and raises an\n    exception if that fails due to either undefined or circular references.\n\n    Args:\n      sql: query to format.\n      args: a dictionary of values to use in variable expansion.\n\n    Returns:\n      The resolved SQL text with variables expanded.\n\n    Raises:\n      Exception on failure.\n    \"\"\"\n    resolved_vars = {}\n    code = []\n    SqlStatement._find_recursive_dependencies(sql, args, code=code,\n                                              resolved_vars=resolved_vars)\n\n    # Rebuild the SQL string, substituting just '$' for escaped $ occurrences,\n    # variable references substituted with their values, or literal text copied\n    # over as-is.\n    parts = []\n    for (escape, placeholder, _, literal) in SqlStatement._get_tokens(sql):\n      if escape:\n        parts.append('$')\n      elif placeholder:\n        variable = placeholder[1:]\n        try:\n          value = resolved_vars[variable]\n        except KeyError as e:\n          raise Exception('Invalid sql. Unable to substitute $%s.' % e.args[0])\n\n        if isinstance(value, types.ModuleType):\n          value = _utils.get_default_query_from_module(value)\n\n        if isinstance(value, SqlStatement):\n          sql = value.format(value._sql, resolved_vars)\n          value = '(%s)' % sql\n        elif '_repr_sql_' in dir(value):\n          # pylint: disable=protected-access\n          value = value._repr_sql_()\n        elif isinstance(value, basestring):\n          value = SqlStatement._escape_string(value)\n        elif isinstance(value, list) or isinstance(value, tuple):\n          if isinstance(value, tuple):\n            value = list(value)\n          expansion = '('\n          for v in value:\n            if len(expansion) > 1:\n              expansion += ', '\n            if isinstance(v, basestring):\n              expansion += SqlStatement._escape_string(v)\n            else:\n              expansion += str(v)\n          expansion += ')'\n          value = expansion\n        else:\n          value = str(value)\n        parts.append(value)\n      elif literal:\n        parts.append(literal)\n\n    expanded = ''.join(parts)\n    return expanded\n\n  @staticmethod\n  def _get_tokens(sql):\n    # Find escaped '$' characters ($$), \"$<name>\" variable references, lone '$' characters, or\n    # literal sequences of character without any '$' in them (in that order).\n    return re.findall(r'(\\$\\$)|(\\$[a-zA-Z_][a-zA-Z0-9_\\.]*)|(\\$)|([^\\$]*)', sql)\n\n  @staticmethod\n  def _get_dependencies(sql):\n    \"\"\" Return the list of variables referenced in this SQL. \"\"\"\n    dependencies = []\n    for (_, placeholder, dollar, _) in SqlStatement._get_tokens(sql):\n      if placeholder:\n        variable = placeholder[1:]\n        if variable not in dependencies:\n          dependencies.append(variable)\n      elif dollar:\n        raise Exception('Invalid sql; $ with no following $ or identifier: %s.' % sql)\n    return dependencies\n"
  },
  {
    "path": "datalab/data/_utils.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Google Cloud Platform library - Generic SQL Helpers.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nimport types\n\n\n# Names used for the arg parser, unnamed (main) query and last query in the module.\n# Note that every module has a last query, but not every module has a main query.\n\n_SQL_MODULE_ARGPARSE = '_sql_module_arg_parser'\n_SQL_MODULE_MAIN = '_sql_module_main'\n_SQL_MODULE_LAST = '_sql_module_last'\n\n\ndef get_default_query_from_module(module):\n  \"\"\" Given a %%sql module return the default (last) query for the module.\n\n  Args:\n    module: the %%sql module.\n\n  Returns:\n    The default query associated with this module.\n  \"\"\"\n  if isinstance(module, types.ModuleType):\n    return module.__dict__.get(_SQL_MODULE_LAST, None)\n  return None\n\n\ndef _next_token(sql):\n  \"\"\" This is a basic tokenizer for our limited purposes.\n  It splits a SQL statement up into a series of segments, where a segment is one of:\n  - identifiers\n  - left or right parentheses\n  - multi-line comments\n  - single line comments\n  - white-space sequences\n  - string literals\n  - consecutive strings of characters that are not one of the items above\n\n  The aim is for us to be able to find function calls (identifiers followed by '('), and the\n  associated closing ')') so we can augment these if needed.\n\n  Args:\n    sql: a SQL statement as a (possibly multi-line) string.\n\n  Returns:\n    For each call, the next token in the initial input.\n  \"\"\"\n  i = 0\n\n  # We use def statements here to make the logic more clear. The start_* functions return\n  # true if i is the index of the start of that construct, while the end_* functions\n  # return true if i point to the first character beyond that construct or the end of the\n  # content.\n  #\n  # We don't currently need numbers so the tokenizer here just does sequences of\n  # digits as a convenience to shrink the total number of tokens. If we needed numbers\n  # later we would need a special handler for these much like strings.\n\n  def start_multi_line_comment(s, i):\n    return s[i] == '/' and i < len(s) - 1 and s[i + 1] == '*'\n\n  def end_multi_line_comment(s, i):\n    return s[i - 2] == '*' and s[i - 1] == '/'\n\n  def start_single_line_comment(s, i):\n    return s[i] == '-' and i < len(s) - 1 and s[i + 1] == '-'\n\n  def end_single_line_comment(s, i):\n    return s[i - 1] == '\\n'\n\n  def start_whitespace(s, i):\n    return s[i].isspace()\n\n  def end_whitespace(s, i):\n    return not s[i].isspace()\n\n  def start_number(s, i):\n    return s[i].isdigit()\n\n  def end_number(s, i):\n    return not s[i].isdigit()\n\n  def start_identifier(s, i):\n    return s[i].isalpha() or s[i] == '_' or s[i] == '$'\n\n  def end_identifier(s, i):\n    return not(s[i].isalnum() or s[i] == '_')\n\n  def start_string(s, i):\n    return s[i] == '\"' or s[i] == \"'\"\n\n  def always_true(s, i):\n    return True\n\n  while i < len(sql):\n    start = i\n    if start_multi_line_comment(sql, i):\n      i += 1\n      end_checker = end_multi_line_comment\n    elif start_single_line_comment(sql, i):\n      i += 1\n      end_checker = end_single_line_comment\n    elif start_whitespace(sql, i):\n      end_checker = end_whitespace\n    elif start_identifier(sql, i):\n      end_checker = end_identifier\n    elif start_number(sql, i):\n      end_checker = end_number\n    elif start_string(sql, i):\n      # Special handling here as we need to check for escaped closing quotes.\n      quote = sql[i]\n      end_checker = always_true\n      i += 1\n      while i < len(sql) and sql[i] != quote:\n        i += 2 if sql[i] == '\\\\' else 1\n    else:\n      # We return single characters for everything else\n      end_checker = always_true\n\n    i += 1\n    while i < len(sql) and not end_checker(sql, i):\n      i += 1\n\n    (yield sql[start:i])\n\n\ndef tokenize(sql):\n  \"\"\" This is a basic tokenizer for our limited purposes.\n  It splits a SQL statement up into a series of segments, where a segment is one of:\n  - identifiers\n  - left or right parentheses\n  - multi-line comments\n  - single line comments\n  - white-space sequences\n  - string literals\n  - consecutive strings of characters that are not one of the items above\n\n  The aim is for us to be able to find function calls (identifiers followed by '('), and the\n  associated closing ')') so we can augment these if needed.\n\n  Args:\n    sql: a SQL statement as a (possibly multi-line) string.\n\n  Returns:\n    A list of strings corresponding to the groups above.\n  \"\"\"\n  return list(_next_token(sql))\n"
  },
  {
    "path": "datalab/data/commands/__init__.py",
    "content": "from __future__ import absolute_import\n# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\nfrom . import _sql\n\n__all__ = ['_sql']\n"
  },
  {
    "path": "datalab/data/commands/_sql.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Google Cloud Platform library - %%arguments IPython Cell Magic Functionality.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import print_function\nfrom __future__ import unicode_literals\nfrom builtins import str\nfrom past.builtins import basestring\n\ntry:\n  import IPython\n  import IPython.core.magic\nexcept ImportError:\n  raise Exception('This module can only be loaded in ipython.')\n\nimport argparse\nimport datetime\nimport imp\nimport re\nimport sys\nimport time\n\nimport datalab.bigquery\nimport datalab.data\nfrom datalab.utils.commands import CommandParser, handle_magic_line\n\n\ndef _create_sql_parser():\n  sql_parser = CommandParser(prog=\"%%sql\",\n                             formatter_class=argparse.RawDescriptionHelpFormatter,\n                             description=\"\"\"\nCreate a named SQL module with one or more queries.\n\nThe cell body should contain an optional initial part defining the default\nvalues for the variables, if any, using Python code, followed by one or more\nqueries.\n\nQueries should start with 'DEFINE QUERY <name>' in order to bind them to\n<module name>.<query name> in the notebook (as datalab.data.SqlStament instances).\nThe final query can optionally omit 'DEFINE QUERY <name>', as using the module\nname in places where a SqlStatement is expected will resolve to the final query\nin the module.\n\nQueries can refer to variables with '$<name>', as well as refer to other queries\nwithin the same module, making it easy to compose nested queries and test their\nparts.\n\nThe Python code defining the variable default values can assign scalar or list/tuple values to\nvariables, or one of the special functions 'datestring' and 'source'.\n\nWhen a variable with a 'datestring' default is expanded it will expand to a formatted\nstring based on the current date, while a 'source' default will expand to a table whose\nname is based on the current date.\n\ndatestring() takes two named arguments, 'format' and 'offset'. The former is a\nformat string that is the same as for Python's time.strftime function. The latter\nis a string containing a comma-separated list of expressions such as -1y, +2m,\netc; these are offsets from the time of expansion that are applied in order. The\nsuffix (y, m, d, h, M) correspond to units of years, months, days, hours and\nminutes, while the +n or -n prefix is the number of units to add or subtract from\nthe time of expansion. Three special values 'now', 'today' and 'yesterday' are\nalso supported; 'today' and 'yesterday' will be midnight UTC on the current date\nor previous days date.\n\nsource() can take a 'name' argument for a fixed table name, or 'format' and 'offset'\narguments similar to datestring(), but unlike datestring() will resolve to a Table\nwith the specified name.\n\"\"\")\n  sql_parser.add_argument('-m', '--module', help='The name for this SQL module')\n  sql_parser.add_argument('-d', '--dialect', help='BigQuery SQL dialect',\n                          choices=['legacy', 'standard'])\n  sql_parser.add_argument('-b', '--billing', type=int, help='BigQuery billing tier')\n  sql_parser.set_defaults(func=lambda args, cell: sql_cell(args, cell))\n  return sql_parser\n\n\n_sql_parser = _create_sql_parser()\n\n\n# Register the line magic as well as the cell magic so we can at least give people help\n# without requiring them to enter cell content first.\n@IPython.core.magic.register_line_cell_magic\ndef sql(line, cell=None):\n  \"\"\" Create a SQL module with one or more queries. Use %sql --help for more details.\n\n  The supported syntax is:\n\n  %%sql [--module <modulename>]\n  [<optional Python code for default argument values>]\n  [<optional named queries>]\n  [<optional unnamed query>]\n\n  At least one query should be present. Named queries should start with:\n\n    DEFINE QUERY <name>\n\n  on a line by itself.\n\n  Args:\n  args: the optional arguments following '%%sql'.\n  cell: the contents of the cell; Python code for arguments followed by SQL queries.\n   \"\"\"\n  if cell is None:\n    _sql_parser.print_help()\n  else:\n    return handle_magic_line(line, cell, _sql_parser)\n\n\ndef _date(val, offset=None):\n  \"\"\" A special pseudo-type for pipeline arguments.\n\n  This allows us to parse dates as Python datetimes, including special values like 'now'\n  and 'today', as well as apply offsets to the datetime.\n\n  Args:\n    val: a string containing the value for the datetime. This can be 'now', 'today' (midnight at\n        start of day), 'yesterday' (midnight at start of yesterday), or a formatted date that\n        will be passed to the datetime constructor. Note that 'now' etc are assumed to\n        be in UTC.\n    offset: for date arguments a string containing a comma-separated list of\n      relative offsets to apply of the form <n><u> where <n> is an integer and\n      <u> is a single character unit (d=day, m=month, y=year, h=hour, m=minute).\n\n  Returns:\n    A Python datetime resulting from starting at <val> and applying the sequence of deltas\n    specified in <offset>.\n  \"\"\"\n  if val is None:\n    return val\n  if val == '' or val == 'now':\n    when = datetime.datetime.utcnow()\n  elif val == 'today':\n    dt = datetime.datetime.utcnow()\n    when = datetime.datetime(dt.year, dt.month, dt.day)\n  elif val == 'yesterday':\n    dt = datetime.datetime.utcnow() - datetime.timedelta(1)\n    when = datetime.datetime(dt.year, dt.month, dt.day)\n  else:\n    when = datetime.datetime.strptime(val, \"%Y%m%d\")\n  if offset is not None:\n    for part in offset.split(','):\n      unit = part[-1]\n      quantity = int(part[:-1])\n      # We can use timedelta for days and under, but not for years and months\n      if unit == 'y':\n        when = datetime.datetime(year=when.year + quantity, month=when.month, day=when.day,\n                                 hour=when.hour, minute=when.minute)\n      elif unit == 'm':\n        new_year = when.year\n        new_month = when.month + quantity\n        if new_month < 1:\n          new_month = -new_month\n          new_year += 1 + (new_month // 12)\n          new_month = 12 - new_month % 12\n        elif new_month > 12:\n          new_year += (new_month - 1) // 12\n          new_month = 1 + (new_month - 1) % 12\n        when = datetime.datetime(year=new_year, month=new_month, day=when.day,\n                                 hour=when.hour, minute=when.minute)\n      elif unit == 'd':\n        when += datetime.timedelta(days=quantity)\n      elif unit == 'h':\n        when += datetime.timedelta(hours=quantity)\n      elif unit == 'M':\n        when += datetime.timedelta(minutes=quantity)\n\n  return when\n\n\ndef _resolve_table(v, format, delta):\n  try:\n    when = _date(v, delta)\n    v = time.strftime(format, when.timetuple())\n  except Exception:\n    pass\n  return datalab.bigquery.Table(v)\n\n\ndef _make_string_formatter(f, offset=None):\n  \"\"\" A closure-izer for string arguments that include a format and possibly an offset. \"\"\"\n  format = f\n  delta = offset\n  return lambda v: time.strftime(format, (_date(v, delta)).timetuple())\n\n\ndef _make_table_formatter(f, offset=None):\n  \"\"\" A closure-izer for table arguments that include a format and possibly an offset. \"\"\"\n  format = f\n  delta = offset\n  return lambda v: _resolve_table(v, format, delta)\n\n\ndef _make_table(v):\n  return datalab.bigquery.Table(v)\n\n\ndef _datestring(format, offset=''):\n  return {'type': 'datestring', 'format': format, 'offset': offset}\n\n\ndef _table(name=None, format=None, offset=''):\n  return {'type': 'table', 'name': name, 'format': format, 'offset': offset}\n\n\ndef _arguments(code, module):\n  \"\"\"Define pipeline arguments.\n\n  Args:\n    code: the Python code to execute that defines the arguments.\n\n  \"\"\"\n  arg_parser = CommandParser.create('')\n  try:\n    # Define our special argument 'types' and add them to the environment.\n    builtins = {'source': _table, 'datestring': _datestring}\n    env = {}\n    env.update(builtins)\n\n    # Execute the cell which should be one or more calls to arg().\n    exec(code, env)\n\n    # Iterate through the module dictionary. For any newly defined objects,\n    # add args to the parser.\n    for key in env:\n\n      # Skip internal/private stuff.\n      if key in builtins or key[0] == '_':\n        continue\n      # If we want to support importing query modules into other query modules, uncomment next 4\n      # Skip imports but add them to the module\n      # if isinstance(env[key], types.ModuleType):\n      #   module.__dict__[key] = env[key]\n      #   continue\n\n      val = env[key]\n      key = '--%s' % key\n\n      if isinstance(val, bool):\n        if val:\n          arg_parser.add_argument(key, default=val, action='store_true')\n        else:\n          arg_parser.add_argument(key, default=val, action='store_false')\n      elif isinstance(val, basestring) or isinstance(val, int) or isinstance(val, float) \\\n              or isinstance(val, int):\n        arg_parser.add_argument(key, default=val)\n      elif isinstance(val, list):\n        arg_parser.add_argument(key, default=val, nargs='+')\n      elif isinstance(val, tuple):\n        arg_parser.add_argument(key, default=list(val), nargs='+')\n\n      # Is this one of our pseudo-types for dates/tables?\n      elif isinstance(val, dict) and 'type' in val:\n        if val['type'] == 'datestring':\n          arg_parser.add_argument(key, default='',\n                                  type=_make_string_formatter(val['format'],\n                                                              offset=val['offset']))\n        elif val['type'] == 'table':\n          if val['format'] is not None:\n            arg_parser.add_argument(key, default='',\n                                    type=_make_table_formatter(val['format'],\n                                                               offset=val['offset']))\n          else:\n            arg_parser.add_argument(key, default=val['name'], type=_make_table)\n        else:\n          raise Exception('Cannot generate argument for %s of type %s' % (key, type(val)))\n      else:\n        raise Exception('Cannot generate argument for %s of type %s' % (key, type(val)))\n\n  except Exception as e:\n    print(\"%%sql arguments: %s from code '%s'\" % (str(e), str(code)))\n  return arg_parser\n\n\ndef _split_cell(cell, module):\n  \"\"\" Split a hybrid %%sql cell into the Python code and the queries.\n\n    Populates a module with the queries.\n\n  Args:\n    cell: the contents of the %%sql cell.\n    module: the module that the contents will populate.\n\n  Returns:\n    The default (last) query for the module.\n\n  \"\"\"\n  lines = cell.split('\\n')\n  code = None\n  last_def = -1\n  name = None\n  define_wild_re = re.compile('^DEFINE\\s+.*$', re.IGNORECASE)\n  define_re = re.compile('^DEFINE\\s+QUERY\\s+([A-Z]\\w*)\\s*?(.*)$', re.IGNORECASE)\n  select_re = re.compile('^SELECT\\s*.*$', re.IGNORECASE)\n  standard_sql_re = re.compile('^(CREATE|WITH|INSERT|DELETE|UPDATE)\\s*.*$', re.IGNORECASE)\n  # TODO(gram): a potential issue with this code is if we have leading Python code followed\n  # by a SQL-style comment before we see SELECT/DEFINE. When switching to the tokenizer see\n  # if we can address this.\n  for i, line in enumerate(lines):\n    define_match = define_re.match(line)\n    select_match = select_re.match(line)\n    standard_sql_match = standard_sql_re.match(line)\n\n    if i:\n      prior_content = ''.join(lines[:i]).strip()\n      if select_match:\n        # Avoid matching if previous token was '(' or if Standard SQL is found\n        # TODO: handle the possibility of comments immediately preceding SELECT\n        select_match = len(prior_content) == 0 or \\\n            (prior_content[-1] != '(' and not standard_sql_re.match(prior_content))\n      if standard_sql_match:\n        standard_sql_match = len(prior_content) == 0 or not standard_sql_re.match(prior_content)\n\n    if define_match or select_match or standard_sql_match:\n      # If this is the first query, get the preceding Python code.\n      if code is None:\n        code = ('\\n'.join(lines[:i])).strip()\n        if len(code):\n          code += '\\n'\n      elif last_def >= 0:\n\n        # This is not the first query, so gather the previous query text.\n        query = '\\n'.join([line for line in lines[last_def:i] if len(line)]).strip()\n        if select_match and name != datalab.data._utils._SQL_MODULE_MAIN and len(query) == 0:\n          # Avoid DEFINE query name\\nSELECT ... being seen as an empty DEFINE followed by SELECT\n          continue\n\n        # Save the query\n        statement = datalab.data.SqlStatement(query, module)\n        module.__dict__[name] = statement\n        # And set the 'last' query to be this too\n        module.__dict__[datalab.data._utils._SQL_MODULE_LAST] = statement\n\n      # Get the query name and strip off our syntactic sugar if appropriate.\n      if define_match:\n        name = define_match.group(1)\n        lines[i] = define_match.group(2)\n      else:\n        name = datalab.data._utils._SQL_MODULE_MAIN\n\n      # Save the starting line index of the new query\n      last_def = i\n    else:\n      define_wild_match = define_wild_re.match(line)\n      if define_wild_match:\n        raise Exception('Expected \"DEFINE QUERY <name>\"')\n\n  if last_def >= 0:\n    # We were in a query so save this tail query.\n    query = '\\n'.join([line for line in lines[last_def:] if len(line)]).strip()\n    statement = datalab.data.SqlStatement(query, module)\n    module.__dict__[name] = statement\n    module.__dict__[datalab.data._utils._SQL_MODULE_LAST] = statement\n\n  if code is None:\n    code = ''\n  module.__dict__[datalab.data._utils._SQL_MODULE_ARGPARSE] = _arguments(code, module)\n  return module.__dict__.get(datalab.data._utils._SQL_MODULE_LAST, None)\n\n\ndef sql_cell(args, cell):\n  \"\"\"Implements the SQL cell magic for ipython notebooks.\n\n  The supported syntax is:\n\n      %%sql [--module <modulename>]\n      [<optional Python code for default argument values>]\n      [<optional named queries>]\n      [<optional unnamed query>]\n\n  At least one query should be present. Named queries should start with:\n\n      DEFINE QUERY <name>\n\n  on a line by itself.\n\n  Args:\n    args: the optional arguments following '%%sql'.\n    cell: the contents of the cell; Python code for arguments followed by SQL queries.\n  \"\"\"\n  name = args['module'] if args['module'] else '_sql_cell'\n  module = imp.new_module(name)\n  query = _split_cell(cell, module)\n  ipy = IPython.get_ipython()\n  if not args['module']:\n      # Execute now\n      if query:\n        return datalab.bigquery.Query(query, values=ipy.user_ns) \\\n          .execute(dialect=args['dialect'], billing_tier=args['billing']).results\n  else:\n    # Add it as a module\n    sys.modules[name] = module\n    exec('import %s' % name, ipy.user_ns)\n"
  },
  {
    "path": "datalab/kernel/__init__.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Google Cloud Datalab - notebook functionality.\"\"\"\n\n\nimport httplib2 as _httplib2\nimport requests as _requests\n\n\ntry:\n  import IPython as _IPython\n  import IPython.core.magic as _magic # noqa\n  import IPython.core.interactiveshell as _shell\n  from IPython import get_ipython # noqa\nexcept ImportError:\n  raise Exception('This package requires an IPython notebook installation')\n\nimport datalab.context as _context\n\n# Import the modules that do cell magics.\nimport datalab.bigquery.commands\nimport datalab.context.commands\nimport datalab.data.commands\nimport datalab.stackdriver.commands\nimport datalab.storage.commands\nimport datalab.utils.commands\n\n# mlalpha modules require TensorFlow, CloudML SDK, and DataFlow (installed with CloudML SDK).\n# These are big dependencies and users who want to use Bigquery/Storage features may not\n# want to install them.\n# This __init__.py file is called when Jupyter/Datalab loads magics on startup. We don't want\n# Jupyter+pydatalab fail to start because of missing TensorFlow/DataFlow. So we ignore import\n# errors on mlalpha commands.\ntry:\n  import datalab.mlalpha.commands\nexcept:\n  print('TensorFlow and CloudML SDK are required.')\n\n\n_orig_request = _httplib2.Http.request\n_orig_init = _requests.Session.__init__\n_orig_run_cell_magic = _shell.InteractiveShell.run_cell_magic\n_orig_run_line_magic = _shell.InteractiveShell.run_line_magic\n\n\ndef load_ipython_extension(shell):\n  \"\"\"\n  Called when the extension is loaded.\n\n  Args:\n      shell - (NotebookWebApplication): handle to the Notebook interactive shell instance.\n  \"\"\"\n\n  # Inject our user agent on all requests by monkey-patching a wrapper around httplib2.Http.request.\n\n  def _request(self, uri, method=\"GET\", body=None, headers=None,\n               redirections=_httplib2.DEFAULT_MAX_REDIRECTS, connection_type=None):\n    if headers is None:\n      headers = {}\n    headers['user-agent'] = 'GoogleCloudDataLab/1.0'\n    return _orig_request(self, uri, method=method, body=body, headers=headers,\n                         redirections=redirections, connection_type=connection_type)\n\n  _httplib2.Http.request = _request\n\n  # Similarly for the requests library.\n\n  def _init_session(self):\n    _orig_init(self)\n    self.headers['User-Agent'] = 'GoogleCloudDataLab/1.0'\n\n  _requests.Session.__init__ = _init_session\n\n  # Be more tolerant with magics. If the user specified a cell magic that doesn't\n  # exist and an empty cell body but a line magic with that name exists, run that\n  # instead. Conversely, if the user specified a line magic that doesn't exist but\n  # a cell magic exists with that name, run the cell magic with an empty body.\n\n  def _run_line_magic(self, magic_name, line):\n    fn = self.find_line_magic(magic_name)\n    if fn is None:\n      cm = self.find_cell_magic(magic_name)\n      if cm:\n        return _run_cell_magic(self, magic_name, line, None)\n    return _orig_run_line_magic(self, magic_name, line)\n\n  def _run_cell_magic(self, magic_name, line, cell):\n    if len(cell) == 0 or cell.isspace():\n      fn = self.find_line_magic(magic_name)\n      if fn:\n        return _orig_run_line_magic(self, magic_name, line)\n      # IPython will complain if cell is empty string but not if it is None\n      cell = None\n    return _orig_run_cell_magic(self, magic_name, line, cell)\n\n  _shell.InteractiveShell.run_cell_magic = _run_cell_magic\n  _shell.InteractiveShell.run_line_magic = _run_line_magic\n\n  # Define global 'project_id' and 'set_project_id' functions to manage the default project ID. We\n  # do this conditionally in a try/catch # to avoid the call to Context.default() when running tests\n  # which mock IPython.get_ipython().\n\n  def _get_project_id():\n    try:\n      return _context.Context.default().project_id\n    except Exception:\n      return None\n\n  def _set_project_id(project_id):\n    context = _context.Context.default()\n    context.set_project_id(project_id)\n\n  def _get_bq_dialect():\n    return datalab.bigquery.Dialect.default().bq_dialect\n\n  def _set_bq_dialect(bq_dialect):\n    datalab.bigquery.Dialect.default().set_bq_dialect(bq_dialect)\n\n  try:\n    if 'datalab_project_id' not in _IPython.get_ipython().user_ns:\n      _IPython.get_ipython().user_ns['datalab_project_id'] = _get_project_id\n      _IPython.get_ipython().user_ns['set_datalab_project_id'] = _set_project_id\n    if 'datalab_bq_dialect' not in _IPython.get_ipython().user_ns:\n      _IPython.get_ipython().user_ns['datalab_bq_dialect'] = _get_bq_dialect\n      _IPython.get_ipython().user_ns['set_datalab_bq_dialect'] = _set_bq_dialect\n  except TypeError:\n    pass\n\n\ndef unload_ipython_extension(shell):\n  _shell.InteractiveShell.run_cell_magic = _orig_run_cell_magic\n  _shell.InteractiveShell.run_line_magic = _orig_run_line_magic\n  _requests.Session.__init__ = _orig_init\n  _httplib2.Http.request = _orig_request\n  try:\n    del _IPython.get_ipython().user_ns['project_id']\n    del _IPython.get_ipython().user_ns['set_project_id']\n  except Exception:\n    pass  # We mock IPython for tests so we need this.\n  # TODO(gram): unregister imports/magics/etc.\n"
  },
  {
    "path": "datalab/notebook/__init__.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Google Cloud Datalab - notebook extension functionality.\"\"\"\n\ntry:\n  import IPython as _\nexcept ImportError:\n  raise Exception('This package requires an IPython notebook installation')\n\n__all__ = ['_']\n\n\ndef _jupyter_nbextension_paths():\n  return [dict(section=\"notebook\", src=\"static\", dest=\"gcpdatalab\")]\n"
  },
  {
    "path": "datalab/notebook/static/bigquery.css",
    "content": "/*\n * Copyright 2015 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License. You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under the License\n * is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n * or implied. See the License for the specific language governing permissions and limitations under\n * the License.\n */\n\ntable.bqsv {\n  font-family: inherit;\n  font-size: smaller;\n}\ntable.bqsv th, table.bqsv td {\n  border: solid 1px #cfcfcf;\n}\nth.bqsv_expanded, th.bqsv_collapsed {\n  background-color: #f7f7f7;\n}\nth.bqsv_colheader {\n  font-weight: bold;\n  background-color: #e7e7e7;\n}\ntbody.bqsv_hidden {\n  display: none;\n}\nth.bqsv_expanded:before {\n  content: '\\25be  '\n}\nth.bqsv_collapsed:before {\n  content: '\\25b8  '\n}\n"
  },
  {
    "path": "datalab/notebook/static/bigquery.ts",
    "content": "/*\n * Copyright 2015 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License. You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under the License\n * is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n * or implied. See the License for the specific language governing permissions and limitations under\n * the License.\n */\n\n/// <reference path=\"../../../externs/ts/require/require.d.ts\" />\n\nmodule BigQuery {\n\n  // Event handler to toggle visibility of a nested schema table.\n  function _toggleNode(e: any): void {\n    var node = e.target;\n    var expand = node.className == 'bqsv_collapsed';\n    node.className = expand ? 'bqsv_expanded' : 'bqsv_collapsed';\n    var tgroup = node.parentNode.nextSibling;\n    tgroup.className = expand ? 'bqsv_visible' : 'bqsv_hidden';\n  }\n\n  // Helper function to recursively render a table schema.\n  function _renderSchema(table: any, schema: any, title: string,\n     includeColumnHeaders: boolean, columns: any): void {\n\n    // Create a tbody element to hold the entities for this level. We group them so\n    // we can easily collapse/expand the level.\n    var tbody = document.createElement('tbody');\n\n    for (var i = 0; i < schema.length; i++) {\n      if (i == 0) {\n        if (title.length > 0) {\n          // title.length > 0 implies we are in a nested table. Create a title header row\n          // for this nested table with a click handler and hide the tbody.\n\n          tbody.className = 'bqsv_hidden';\n\n          var th = document.createElement('th');\n          th.colSpan = columns.length;\n          th.className = 'bqsv_collapsed';\n          th.textContent = title.substring(1);  // skip the leading '.'\n          th.addEventListener('click', _toggleNode);\n\n          var tr = document.createElement('tr');\n          tr.appendChild(th);\n          table.appendChild(tr);\n        } else {\n          // We are in the top-level table; add a header row with the column labels.\n          tbody.className = 'bqsv_visible';\n          if (includeColumnHeaders) {\n            // First line; show column headers.\n            var tr = document.createElement('tr');\n            for (var j = 0; j < columns.length; j++) {\n              var th = document.createElement('th');\n              th.textContent = columns[j];\n              th.className = 'bqsv_colheader';\n              tr.appendChild(th);\n            }\n            table.appendChild(tr);\n          }\n        }\n      }\n\n      // Add the details for the current row to the tbody.\n      var field = schema[i];\n      var tr = document.createElement('tr');\n      for (var j = 0; j < columns.length; j++) {\n        var td = document.createElement('td');\n        var v = field[columns[j]];\n        td.textContent = v == undefined ? '' : v;\n        tr.appendChild(td);\n      }\n      tbody.appendChild(tr);\n    }\n\n    // Add the tbody with all the rows to the table.\n    table.appendChild(tbody);\n\n    // Recurse into any nested tables.\n    for (var i = 0; i < schema.length; i++) {\n      var field = schema[i];\n      if (field.type == 'RECORD') {\n        _renderSchema(table, field.fields, title + '.' + field.name, false, columns);\n      }\n    }\n  }\n\n  // Top-level public function for schema rendering.\n  export function renderSchema(dom: any, schema: any) {\n    var columns = ['name', 'type', 'mode', 'description'];\n    var table = document.createElement('table');\n    table.className = 'bqsv';\n    _renderSchema(table, schema, '', /*includeColumnHeaders*/ true, columns);\n    dom.appendChild(table);\n  }\n}\n\nexport = BigQuery;\n"
  },
  {
    "path": "datalab/notebook/static/charting.css",
    "content": "/*\n * Copyright 2015 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License. You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under the License\n * is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n * or implied. See the License for the specific language governing permissions and limitations under\n * the License.\n */\n\ntable.google-visualization-table-table, table.dataframe {\n  font-family: inherit;\n  font-size: smaller;\n}\ntr.gchart-table-row {\n}\ntr.gchart-table-headerrow, table.dataframe thead th {\n  font-weight: bold;\n  background-color: #e7e7e7;\n}\ntr.gchart-table-oddrow, table.dataframe tr:nth-child(odd) {\n  background-color: #f7f7f7;\n}\ntr.gchart-table-selectedTableRow {\n  background-color: #e3f2fd;\n}\ntr.gchart-table-hoverrow, table.dataframe tr:hover {\n  background-color: #bbdefb;\n}\ntd.gchart-table-cell, table.dataframe td {\n  border: solid 1px #cfcfcf;\n}\ntd.gchart-table-rownumcell, table.dataframe tr th {\n  border: solid 1px #cfcfcf;\n  color: #999;\n}\nth.gchart-table-headercell, table.dataframe th {\n  border: solid 1px #cfcfcf;\n}\ndiv.bqgc {\n  display: flex;\n  justify-content: center;\n}\ndiv.bqgc img {\n  max-width: none; // Fix the conflict with maps and Bootstrap that messes up zoom controls.\n}\n.gchart-slider {\n  width: 80%;\n  float: left;\n}\n.gchart-slider-value {\n  text-align: center;\n  float: left;\n  width: 20%;\n}\n.gchart-control {\n  padding-top: 10px;\n  padding-bottom: 10px;\n}\n.gchart-controls {\n  font-size: 14px;\n  color: #333333;\t \n  background: #f4f4f4;\n  padding: 10px;\n  width: 180px;\n  float: left;\n}\n.bqgc {\n  padding: 0;\n  max-width: 100%;\n}\n.bqgc-controlled {\n  display: flex;\n  flex-direction: row;\n  justify-content:space-between;\n}\n.bqgc-container {\n  display: block;\n}\n.bqgc-ml-metrics {\n  display: flex;\n  flex-direction: row;\n  justify-content:left;\n}\n"
  },
  {
    "path": "datalab/notebook/static/charting.ts",
    "content": "/*\n * Copyright 2015 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License. You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under the License\n * is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n * or implied. See the License for the specific language governing permissions and limitations under\n * the License.\n */\n\n/// <reference path=\"../../../externs/ts/require/require.d.ts\" />\n\nmodule Charting {\n  declare var IPython:any;\n  declare var datalab:any;\n\n// Wrappers for Plotly.js and Google Charts\n\n  abstract class ChartLibraryDriver {\n\n    chartModule:any;\n\n    constructor(protected dom:HTMLElement, protected chartStyle:string) {\n    }\n\n    abstract requires(url: string, chartStyle:string):Array<string>;\n\n    init(chartModule:any):void {\n      this.chartModule = chartModule;\n    }\n\n    abstract draw(data:any, options:any):void;\n\n    abstract getStaticImage(callback:Function):void;\n\n    abstract addChartReadyHandler(handler:Function):void;\n\n    addPageChangedHandler(handler:Function):void {\n    }\n\n    error(message:string):void {\n    }\n  }\n\n  class PlotlyDriver extends ChartLibraryDriver {\n    readyHandler:any;\n\n    constructor(dom:HTMLElement, chartStyle:string) {\n      super(dom, chartStyle)\n    }\n\n    requires(url: string, chartStyle:string):Array<string> {\n      return ['d3', 'plotly'];\n    }\n\n    public draw(data:any, options:any):void {\n      /*\n       * TODO(gram): if we start moving more chart types over to Plotly.js we should change the\n       * shape of the data we pass to render so we don't need to reshape it here. Also, a fair\n       * amount of the computation done here could be moved to Python code. We should just be\n       * passing in the mostly complete layout object in JSON, for example.\n       */\n      var xlabels: Array<string> = [];\n      var points: Array<any> = [];\n      var layout: any = {\n        xaxis: {},\n        yaxis: {},\n        height: 300,\n        margin: {\n          b: 60,\n          t: 60,\n          l: 60,\n          r: 60\n        }\n      };\n      if (options.title) {\n        layout.title = options.title;\n      }\n      var minX: number = undefined;\n      var maxX: number = undefined;\n      if ('hAxis' in options) {\n        if ('minValue' in options.hAxis) {\n          minX = options.hAxis.minValue;\n        }\n        if ('maxValue' in options.hAxis) {\n          maxX = options.hAxis.maxValue;\n        }\n        if (minX != undefined || maxX != undefined) {\n          layout.xaxis.range = [minX, maxX];\n        }\n      }\n      var minY: number = undefined;\n      var maxY: number = undefined;\n      if ('vAxis' in options) {\n        if ('minValue' in options.vAxis) {\n          minY = options.vAxis.minValue;\n        } else if ('minValues' in options.vAxis) {\n          minY = options.vAxis.minValues[0];\n        }\n        if ('maxValue' in options.vAxis) {\n          maxY = options.vAxis.maxValue;\n        } else if ('maxValues' in options.vAxis) {\n          maxY = options.vAxis.maxValues[0];\n        }\n        if (minY != undefined || maxY != undefined) {\n          layout.yaxis.range = [minY, maxY];\n        }\n        if ('minValues' in options.vAxis) {\n          minY = options.vAxis.minValues[1]; // for second axis below\n        }\n        if ('maxValues' in options.vAxis) {\n          maxY = options.vAxis.maxValues[1]; // for second axis below\n        }\n      }\n      if (options.xAxisTitle) {\n        layout.xaxis.title = options.xAxisTitle;\n      }\n      if (options.xAxisSide) {\n        layout.xaxis.side = options.xAxisSide;\n      }\n      if (options.yAxisTitle) {\n        layout.yaxis.title = options.yAxisTitle;\n      }\n      if (options.yAxesTitles) {\n        layout.yaxis.title = options.yAxesTitles[0];\n        layout.yaxis2 = {\n          title: options.yAxesTitles[1],\n          side: 'right',\n          overlaying: 'y'\n        };\n        if (minY != undefined || maxY != undefined) {\n          layout.yaxis2.range = [minY, maxY];\n        }\n      }\n      if ('width' in options) {\n        layout.width = options.width;\n      }\n      if ('height' in options) {\n        layout.height = options.height;\n        if ('width' in options) {\n          layout.autosize = false;\n        }\n      }\n      var pdata: Array<any> = [];\n\n      if (this.chartStyle == 'line' || this.chartStyle == 'scatter') {\n        var hoverCol: number = 0;\n        var x: Array<any> = [];\n        // First col is X, other cols are Y's and optional hover text only column\n        var y: Array<any> = [];\n        var hover: Array<any> = [];\n        for (var c = 1; c < data.cols.length; c++) {\n          x[c - 1] = [];\n          y[c - 1] = [];\n          var line:any = {\n            x: x[c - 1],\n            y: y[c - 1],\n            name: data.cols[c].label,\n            type: 'scatter',\n            mode: this.chartStyle == 'scatter' ? 'markers' : 'lines'\n          };\n          if (options.hoverOnly) {\n            hover[c - 1] = [];\n            line.text = hover[c - 1];\n            line.hoverinfo = 'text';\n          }\n          if (options.yAxesTitles && (c % 2) == 0) {\n            line.yaxis = 'y2';\n          }\n          pdata.push(line);\n        }\n        for (var c = 1; c < data.cols.length; c++) {\n          if (c == hoverCol) {\n            continue;\n          }\n          for (var r = 0; r < data.rows.length; r++) {\n            var entry:Array<any> = data.rows[r].c;\n            if ('v' in entry[c]) {\n              var xVal = entry[0].v;\n              var yVal = entry[c].v;\n              if (options.hoverOnly) {\n                // Each column is a dict with two values, one for y and one for\n                // hover. Extract these.\n                var hoverVal:any;\n                var yDict:any  = yVal;\n                for (var prop in yDict) {\n                  var val = yDict[prop];\n                  if (prop == options.hoverOnly) {\n                    hoverVal = val;\n                  } else {\n                    yVal = val;\n                  }\n                }\n                // TODO(gram): we may want to add explicit hover text this even without hoverOnly.\n                var xlabel:any = options.xAxisTitle || data.cols[0].label;\n                var ylabel:any  = options.yAxisTitle || data.cols[c].label;\n                var prefix = '';\n                if (options.yAxisTitle) {\n                  prefix += data.cols[c].label + ': ';\n                }\n                hover[c - 1].push(prefix +\n                    options.hoverOnly + '=' + hoverVal + ', ' +\n                    xlabel + '=' + xVal + ', ' +\n                    ylabel + '=' + yVal);\n              }\n              x[c - 1].push(xVal);\n              y[c - 1].push(yVal);\n            }\n          }\n        }\n      } else if (this.chartStyle == 'heatmap') {\n        var size:number = 200 + data.cols.length * 50;\n        if (size > 800) size = 800;\n        layout.height = size;\n        layout.width = size;\n        layout.autosize = false;\n\n        for (var i = 0; i < data.cols.length; i++) {\n          xlabels[i] = data.cols[i].label;\n        }\n        var ylabels = [].concat(xlabels);\n\n        // Plotly draws the first row at the bottom, not the top, so we need\n        // to reverse the y and z array ordering.\n        // We will need to tweak this a bit if we later support non-square maps.\n        ylabels.reverse();\n\n        var hovertext: Array<Array<string>> = [];\n        var hoverx:string = options.xAxisTitle || 'x';\n        var hovery = options.yAxisTitle || 'y';\n\n        for (var i = 0; i < data.rows.length; i++) {\n          var entry:Array<any> = data.rows[i].c;\n          var row:Array<number> = [];\n          var hoverrow:Array<string> = [];\n          for (var j = 0; j < data.cols.length; j++) {\n            row[j] = entry[j].v;\n            hoverrow[j] = hoverx + '= ' + xlabels[j] + ', ' + hovery + '= ' +\n                ylabels[i] + ': ' + row[j];\n          }\n          points[i] = row;\n          hovertext[i] = hoverrow;\n        }\n        points.reverse();\n        layout.hovermode = 'closest';\n\n        pdata = [{\n          x: xlabels,\n          y: ylabels,\n          z: points,\n          type: 'heatmap',\n          text: hovertext,\n          hoverinfo: 'text'\n        }];\n        if (options.colorScale) {\n          pdata[0].colorscale = [\n            [0, options.colorScale.min],\n            [1, options.colorScale.max]\n          ];\n        } else {\n          pdata[0].colorscale = [\n            [0, 'red'],\n            [0.5, 'gray'],\n            [1, 'blue']\n          ];\n        }\n        if (options.hideScale) {\n          pdata[0].showscale = false;\n        }\n        if (options.annotate) {\n          layout.annotations = [];\n          for (var i = 0; i < pdata[0].y.length; i++) {\n            for (var j = 0; j < pdata[0].x.length; j++) {\n              var currentValue = pdata[0].z[i][j];\n              var textColor = (currentValue == 0.0) ? 'black' : 'white';\n              var result = {\n                xref: 'x1',\n                yref: 'y1',\n                x: pdata[0].x[j],\n                y: pdata[0].y[i],\n                text: pdata[0].z[i][j].toPrecision(3),\n                showarrow: false,\n                font: {\n                  color: textColor\n                }\n              };\n              layout.annotations.push(result);\n            }\n          }\n        }\n      }\n      this.chartModule.newPlot(this.dom.id, pdata, layout, {displayModeBar: false});\n      if (this.readyHandler) {\n        this.readyHandler();\n      }\n    }\n\n    getStaticImage(callback:Function):void {\n      this.chartModule.Snapshot.toImage(document.getElementById(this.dom.id),\n          {format: 'png'}).once('success', function (url:string) {\n        callback(this.model, url);\n      });\n    }\n\n    addChartReadyHandler(handler:Function):void {\n      this.readyHandler = handler;\n    }\n  }\n\n  interface IStringMap {\n    [key: string]: string;\n  }\n\n  class GChartsDriver extends ChartLibraryDriver {\n\n    chart:any;\n\n    nameMap: IStringMap = {\n      annotation: 'AnnotationChart',\n      area: 'AreaChart',\n      columns: 'ColumnChart',\n      bars: 'BarChart',\n      bubbles: 'BubbleChart',\n      calendar: 'Calendar',\n      candlestick: 'CandlestickChart',\n      combo: 'ComboChart',\n      gauge: 'Gauge',\n      geo: 'GeoChart',\n      histogram: 'Histogram',\n      line: 'LineChart',\n      map: 'Map',\n      org: 'OrgChart',\n      paged_table: 'Table',\n      pie: 'PieChart',\n      sankey: 'Sankey',\n      scatter: 'ScatterChart',\n      stepped_area: 'SteppedAreaChart',\n      table: 'Table',\n      timeline: 'Timeline',\n      treemap: 'TreeMap',\n    };\n\n    scriptMap: IStringMap = {\n      annotation: 'annotationchart',\n      calendar: 'calendar',\n      gauge: 'gauge',\n      geo: 'geochart',\n      map: 'map',\n      org: 'orgchart',\n      paged_table: 'table',\n      sankey: 'sankey',\n      table: 'table',\n      timeline: 'timeline',\n      treemap: 'treemap'\n    };\n\n    constructor(dom:HTMLElement, chartStyle:string) {\n      super(dom, chartStyle);\n    }\n\n    requires(url: string, chartStyle:string):Array<string> {\n      var chartScript:string = 'corechart';\n      if (chartStyle in this.scriptMap) {\n        chartScript = this.scriptMap[chartStyle];\n      }\n      return [url + 'visualization!' + chartScript];\n    }\n\n    init(chartModule:any):void {\n      super.init(chartModule);\n      var constructor:Function = this.chartModule[this.nameMap[this.chartStyle]];\n      this.chart = new (<any>constructor)(this.dom);\n    }\n\n    error(message:string):void {\n      this.chartModule.errors.addError(this.dom, 'Unable to render the chart', message,\n          {showInTooltip: false});\n    }\n\n    draw(data:any, options:any):void {\n      console.log('Drawing with options ' + JSON.stringify(options));\n      this.chart.draw(new this.chartModule.DataTable(data), options);\n    }\n\n    getStaticImage(callback:Function):void {\n      if (this.chart.getImageURI) {\n        callback(this.chart.getImageURI());\n      }\n    }\n\n    addChartReadyHandler(handler:Function) {\n      this.chartModule.events.addListener(this.chart, 'ready', handler);\n    }\n\n    addPageChangedHandler(handler:Function) {\n      this.chartModule.events.addListener(this.chart, 'page', function (e:any) {\n        handler(e.page);\n      });\n    }\n  }\n\n  class Chart {\n    dataCache:any;  // TODO: add interface types for the caches.\n    optionsCache:any;\n    hasIPython:boolean;\n    cellElement:HTMLElement;\n    totalRows:number;\n\n    constructor(protected driver:ChartLibraryDriver,\n                protected dom:Element,\n                protected controlIds:Array<string>,\n                protected base_options:any,\n                protected refreshData:any,\n                protected refreshInterval:number,\n                totalRows:number) {\n      this.totalRows = totalRows || -1; // Total rows in all (server-side) data.\n      this.dataCache = {};\n      this.optionsCache = {};\n      this.hasIPython = false;\n      try {\n        if (IPython) {\n          this.hasIPython = true;\n        }\n      } catch (e) {\n      }\n      (<HTMLElement>this.dom).innerHTML = '';\n      this.removeStaticChart();\n      this.addControls();\n      // Generate and add a new static chart once chart is ready.\n      var _this = this;\n      this.driver.addChartReadyHandler(function () {\n        _this.addStaticChart();\n      });\n    }\n\n    // Convert any string fields that are date type to JS Dates.\n    public static convertDates(data:any):void {\n      for (var i = 0; i < data.cols.length; i++) {\n        if (data.cols[i].type == 'date' || data.cols[i].type == 'datetime') {\n          var rows = data.rows;\n          for (var j = 0; j < rows.length; j++) {\n            rows[j].c[i].v = new Date(rows[j].c[i].v);\n          }\n        } else if (data.cols[i].type == 'timeofday') {\n          var rows = data.rows;\n          for (var j = 0; j < rows.length; j++) {\n            var timeInSeconds = rows[j].c[i].v.split('.')[0];\n            rows[j].c[i].v = timeInSeconds.split(':').map(\n              function(n:string) {\n                return parseInt(n, 10);\n              });\n          }\n        }\n      }\n    }\n\n    // Extend the properties in a 'base' object with the changes in an 'update' object.\n    // We can add properties or override properties but not delete yet.\n    private static extend(base:any, update:any):void {\n      for (var p in update) {\n        if (typeof base[p] !== 'object' || !base.hasOwnProperty(p)) {\n          base[p] = update[p];\n        } else {\n          this.extend(base[p], update[p]);\n        }\n      }\n    }\n\n    // Get the IPython cell associated with this chart.\n    private getCell() {\n      if (!this.hasIPython) {\n        return undefined;\n      }\n      var cells = IPython.notebook.get_cells();\n      for (var cellIndex in cells) {\n        var cell = cells[cellIndex];\n        if (cell.element && cell.element.length) {\n          var element = cell.element[0];\n          var chartDivs = element.getElementsByClassName('bqgc');\n          if (chartDivs && chartDivs.length) {\n            for (var i = 0; i < chartDivs.length; i++) {\n              if (chartDivs[i].id == this.dom.id) {\n                return cell;\n              }\n            }\n          }\n        }\n      }\n      return undefined;\n    }\n\n    protected getRefreshHandler(useCache:boolean):Function {\n      var _this = this;\n      return function () {\n        _this.refresh(useCache);\n      };\n    }\n\n    // Bind event handlers to the chart controls, if any.\n    private addControls():void {\n      if (!this.controlIds) {\n        return;\n      }\n      var controlHandler = this.getRefreshHandler(true);\n      for (var i = 0; i < this.controlIds.length; i++) {\n        var id = this.controlIds[i];\n        var split = id.indexOf(':');\n        var control:HTMLInputElement;\n        if (split >= 0) {\n          // Checkbox group.\n          var count = parseInt(id.substring(split + 1));\n          var base = id.substring(0, split + 1);\n          for (var j = 0; j < count; j++) {\n            control = <HTMLInputElement>document.getElementById(base + j);\n            control.disabled = !this.hasIPython;\n            control.addEventListener('change', function() {\n              controlHandler();\n            });\n          }\n          continue;\n        }\n        // See if we have an associated control that needs dual binding.\n        control = <HTMLInputElement>document.getElementById(id);\n        if (!control) {\n          // Kernel restart?\n          return;\n        }\n        control.disabled = !this.hasIPython;\n        var textControl = <HTMLInputElement>document.getElementById(id + '_value');\n        if (textControl) {\n          textControl.disabled = !this.hasIPython;\n          textControl.addEventListener('change', function () {\n            if (control.value != textControl.value) {\n              control.value = textControl.value;\n              controlHandler();\n            }\n          });\n          control.addEventListener('change', function () {\n            textControl.value = control.value;\n            controlHandler();\n          });\n        } else {\n          control.addEventListener('change', function() {\n            controlHandler();\n          });\n        }\n      }\n    }\n\n    // Iterate through any widget controls and build up a JSON representation\n    // of their values that can be passed to the Python kernel as part of the\n    // magic to fetch data (also used as part of the cache key).\n    protected getControlSettings():any {\n      var env:any = {};\n      if (this.controlIds) {\n        for (var i = 0; i < this.controlIds.length; i++) {\n          var id = this.controlIds[i];\n          var parts = id.split('__');\n          var varName = parts[1];\n          var splitPoint = varName.indexOf(':');\n          if (splitPoint >= 0) { // this is a checkbox group\n            var count = parseInt(varName.substring(splitPoint + 1));\n            varName = varName.substring(0, splitPoint);\n            var cbBaseId = parts[0] + '__' + varName + ':';\n            var list:Array<string> = [];\n            env[varName] = list;\n            for (var j = 0; j < count; j++) {\n              var cb = <HTMLInputElement>document.getElementById(cbBaseId + j);\n              if (!cb) {\n                // Stale refresh; user re-executed cell.\n                return undefined;\n              }\n              if (cb.checked) {\n                list.push(cb.value);\n              }\n            }\n          } else {\n            var e = <HTMLInputElement>document.getElementById(id);\n            if (!e) {\n              // Stale refresh; user re-executed cell.\n              return undefined;\n            }\n            if (e && e.type == 'checkbox') {\n              // boolean\n              env[varName] = e.checked;\n            } else {\n              // picker/slider/text\n              env[varName] = e.value;\n            }\n          }\n        }\n      }\n      return env;\n    }\n\n    // Get a string representation of the current environment - i.e. control settings and\n    // refresh data. This is used as a cache key.\n    private getEnvironment():string {\n      var controls:any = this.getControlSettings();\n      if (controls == undefined) {\n        // This means the user has re-executed the cell and our controls are gone.\n        return undefined;\n      }\n      var env:any = {controls: controls};\n      Chart.extend(env, this.refreshData);\n      return JSON.stringify(env);\n    }\n\n    protected refresh(useCache:boolean):void {\n      // TODO(gram): remember last cache key and don't redraw chart if cache\n      // key is the same unless this is an ML key and the number of data points has changed.\n      this.removeStaticChart();\n      var env:string = this.getEnvironment();\n      if (env == undefined) {\n        // This means the user has re-executed the cell and our controls are gone.\n        console.log('No chart control environment; abandoning refresh');\n        return;\n      }\n      if (useCache && env in this.dataCache) {\n        this.draw(this.dataCache[env], this.optionsCache[env]);\n        return;\n      }\n      var code = '%_get_chart_data\\n' + env;\n\n      // TODO: hook into the notebook UI to enable/disable 'Running...' while we fetch more data.\n      if (!this.cellElement) {\n        var cell = this.getCell();\n        if (cell && cell.element && cell.element.length == 1) {\n          this.cellElement = cell.element[0];\n        }\n      }\n      // Start the cell spinner in the notebook UI.\n      if (this.cellElement) {\n        this.cellElement.classList.remove('completed');\n      }\n      var _this = this;\n      datalab.session.execute(code, function (error:string, response:any) {\n        _this.handleNewData(env, error, response);\n      });\n    }\n\n    private handleNewData(env: any, error:any, response: any) {\n      var data = response.data;\n\n      // Stop the cell spinner in the notebook UI.\n      if (this.cellElement) {\n        this.cellElement.classList.add('completed');\n      }\n\n      if (data == undefined || data.cols == undefined) {\n        error = 'No data';\n      }\n\n      if (error) {\n        this.driver.error(error);\n        return;\n      }\n\n      this.refreshInterval = response.refresh_interval;\n      if (this.refreshInterval == 0) {\n        console.log('No more refreshes for ' + this.refreshData.name);\n      }\n\n      Chart.convertDates(data);\n      var options = this.base_options;\n      if (response.options) {\n        // update any options. We need to make a copy so we don't break the base options.\n        options = JSON.parse(JSON.stringify(options));\n        Chart.extend(options, response.options);\n      }\n\n      // Don't update or keep refreshing this if control settings have changed.\n      var newEnv = this.getEnvironment();\n      if (env == newEnv) {\n        console.log('Got refresh for ' + this.refreshData.name + ', ' + env);\n        this.draw(data, options);\n      } else {\n        console.log('Stopping refresh for ' + env + ' as controls are now ' + newEnv)\n      }\n    }\n\n    // Remove a static chart (PNG) from the notebook and the DOM.\n    protected removeStaticChart():void {\n      var cell = this.getCell();\n      if (cell) {\n        var pngDivs = <NodeListOf<HTMLDivElement>>\n            cell.element[0].getElementsByClassName('output_png');\n        if (pngDivs) {\n          for (var i = 0; i < pngDivs.length; i++) {\n            pngDivs[i].innerHTML = '';\n          }\n        }\n        var cell_outputs = cell.output_area.outputs;\n        var changed = true;\n        while (changed) {\n          changed = false;\n          for (var outputIndex in cell_outputs) {\n            var output = cell_outputs[outputIndex];\n            if (output.output_type == 'display_data' && output.metadata.source_id == this.dom.id) {\n              cell_outputs.splice(outputIndex, 1);\n              changed = true;\n              break;\n            }\n          }\n        }\n      } else {\n        // Not running under IPython; use a different approach and just clear the DOM.\n        // Iterate through the IPython outputs...\n        var outputDivs = document.getElementsByClassName('output_wrapper');\n        if (outputDivs) {\n          for (var i = 0; i < outputDivs.length; i++) {\n            // ...and any chart outputs in each...\n            var outputDiv = <HTMLDivElement>outputDivs[i];\n            var chartDivs = outputDiv.getElementsByClassName('bqgc');\n            if (chartDivs) {\n              for (var j = 0; j < chartDivs.length; j++) {\n                // ...until we find the chart div ID we want...\n                if (chartDivs[j].id == this.dom.id) {\n                  // ...then get any PNG outputs in that same output group...\n                  var pngDivs = <NodeListOf<HTMLDivElement>>outputDiv.\n                      getElementsByClassName('output_png');\n                  if (pngDivs) {\n                    for (var k = 0; k < pngDivs.length; k++) {\n                      // ... and clear their contents.\n                      pngDivs[k].innerHTML = '';\n                    }\n                  }\n                  return;\n                }\n              }\n            }\n          }\n        }\n      }\n    }\n\n    // Add a static chart (PNG) to the notebook. The notebook will in turn add it to the DOM when\n    // the notebook is opened.\n    private addStaticChart():void {\n      var _this = this;\n      this.driver.getStaticImage(function (img:string) {\n        _this.handleStaticChart(img);\n      });\n    }\n\n    private handleStaticChart(img: string) {\n      if (img) {\n        var cell = this.getCell();\n        if (cell) {\n          var encoding = img.substr(img.indexOf(',') + 1);  // strip leading base64 etc.\n          var static_output = {\n            metadata: {\n              source_id: this.dom.id\n            },\n            data: {\n              'image/png': encoding\n            },\n            output_type: 'display_data'\n          };\n          cell.output_area.outputs.push(static_output);\n        }\n      }\n    }\n\n    // Set up a refresh callback if we have a non-zero interval and the DOM element still exists\n    // (i.e. output hasn't been cleared).\n    private configureRefresh(refreshInterval:number):void {\n      if (refreshInterval > 0 && document.getElementById(this.dom.id)) {\n        window.setTimeout(this.getRefreshHandler(false), 1000 * refreshInterval);\n      }\n    }\n\n    // Cache the current data and options and draw the chart.\n    public draw(data:any, options:any):void {\n      var env:string = this.getEnvironment();\n      this.dataCache[env] = data;\n      this.optionsCache[env] = options;\n      if ('cols' in data) {\n        this.driver.draw(data, options);\n      }\n      this.configureRefresh(this.refreshInterval);\n    }\n  }\n\n  //-----------------------------------------------------------\n  // A special version of Chart for supporting paginated data.\n\n  class PagedTable extends Chart {\n    firstRow:number;\n    pageSize:number;\n\n    constructor(driver:ChartLibraryDriver,\n                dom:HTMLElement,\n                controlIds:Array<string>,\n                base_options:any,\n                refreshData:any,\n                refreshInterval:number,\n                totalRows:number) {\n      super(driver, dom, controlIds, base_options, refreshData, refreshInterval, totalRows);\n      this.firstRow = 0;  // Index of first row being displayed in page.\n      this.pageSize = base_options.pageSize || 25;\n      if (this.base_options.showRowNumber == undefined) {\n        this.base_options.showRowNumber = true;\n      }\n      this.base_options.sort = 'disable';\n      var __this = this;\n      this.driver.addPageChangedHandler(function (page:number) {\n        __this.handlePageEvent(page);\n      });\n    }\n\n    // Get control settings for cache key. For paged table we add the first row offset of the table.\n    protected getControlSettings():any {\n      var env = super.getControlSettings();\n      if (env) {\n        env.first = this.firstRow;\n      }\n      return env;\n    }\n\n    public draw(data:any, options:any):void {\n      var count = this.pageSize;\n      options.firstRowNumber = this.firstRow + 1;\n      options.page = 'event';\n      if (this.totalRows < 0) {\n        // We don't know where the end is, so we should have 'next' button.\n        options.pagingButtonsConfiguration = this.firstRow > 0 ? 'both' : 'next';\n      } else {\n        count = this.totalRows - this.firstRow;\n        if (count > this.pageSize) {\n          count = this.pageSize;\n        }\n        if (this.firstRow + count < this.totalRows) {\n          // We are not on last page, so we should have 'next' button.\n          options.pagingButtonsConfiguration = this.firstRow > 0 ? 'both' : 'next';\n        } else {\n          // We are on last page\n          if (this.firstRow == 0) {\n            options.pagingButtonsConfiguration = 'none';\n            options.page = 'disable';\n          } else {\n            options.pagingButtonsConfiguration = 'prev';\n          }\n        }\n      }\n      super.draw(data, options);\n    }\n\n    // Handle page forward/back events. Page will only be 0 or 1.\n    handlePageEvent(page:number):void {\n      var offset = (page == 0) ? -1 : 1;\n      this.firstRow += offset * this.pageSize;\n      this.refreshData.first = this.firstRow;\n      this.refreshData.count = this.pageSize;\n      this.refresh(true);\n    }\n  }\n\n  function convertListToDataTable(data:any):any {\n    if (!data || !data.length) {\n      return {cols: [], rows: []};\n    }\n\n    var firstItem = data[0];\n    var names = Object.keys(firstItem);\n\n    var columns = names.map(function (name) {\n      return {id: name, label: name, type: typeof firstItem[name]}\n    });\n\n    var rows = data.map(function (item:any) {\n      var cells = names.map(function (name) {\n        return {v: item[name]};\n      });\n      return {c: cells};\n    });\n\n    return {cols: columns, rows: rows};\n  }\n\n  // The main render method, called from render() wrapper below. dom is the DOM element\n  // for the chart, model is a set of parameters from Python, and options is a JSON\n  // set of options provided by the user in the cell magic body, which takes precedence over\n  // model. An initial set of data can be passed in as a final optional parameter.\n\n  function _render(driver:ChartLibraryDriver,\n                   dom:HTMLElement,\n                   chartStyle:string,\n                   controlIds:Array<string>,\n                   data:any,\n                   options:any,\n                   refreshData:any,\n                   refreshInterval:number,\n                   totalRows:number):void {\n    require([\"base/js/namespace\"], function(Jupyter: any) {\n      var url = \"datalab/\";\n      require(driver.requires(url, chartStyle), function (/* ... */) {\n        // chart module should be last dependency in require() call...\n        var chartModule = arguments[arguments.length - 1];  // See if it needs to be a member.\n        driver.init(chartModule);\n        options = options || {};\n\n        var chart:Chart;\n        if (chartStyle == 'paged_table') {\n          chart = new PagedTable(driver, dom, controlIds, options, refreshData, refreshInterval, totalRows);\n        } else {\n          chart = new Chart(driver, dom, controlIds, options, refreshData, refreshInterval, totalRows);\n        }\n        Chart.convertDates(data);\n        chart.draw(data, options);\n        // Do we need to do anything to prevent it getting GCed?\n      });\n    });\n  }\n\n  export function render(driverName:string,\n                         dom:HTMLElement,\n                         events:any,\n                         chartStyle:string,\n                         controlIds:Array<string>,\n                         data:any,\n                         options:any,\n                         refreshData:any,\n                         refreshInterval:number,\n                         totalRows:number):void {\n\n    // If this is HTML from nbconvert we can't support paging so add some text making this clear.\n    if (chartStyle == 'paged_table' && document.hasOwnProperty('_in_nbconverted')) {\n      chartStyle = 'table';\n      var p = document.createElement(\"div\");\n      p.innerHTML = '<br>(Truncated to first page of results)';\n      dom.parentNode.insertBefore(p, dom.nextSibling);\n    }\n\n    // Allocate an appropriate driver.\n    var driver:ChartLibraryDriver;\n    if (driverName == 'plotly') {\n      driver = new PlotlyDriver(dom, chartStyle);\n    } else if (driverName == 'gcharts') {\n      driver = new GChartsDriver(dom, chartStyle);\n    } else {\n      throw new Error('Unsupported chart driver ' + driverName);\n    }\n\n    // Get data in form needed for GCharts.\n    // We shouldn't need this; should be handled by caller.\n    if (!data.cols && !data.rows) {\n      data = this.convertListToDataTable(data);\n    }\n\n    // If we have a datalab session, we can go ahead and draw the chart; if not, add code to do the\n    // drawing to an event handler for when the kernel is ready.\n    if (IPython.notebook.kernel.is_connected()) {\n      _render(driver, dom, chartStyle, controlIds, data, options, refreshData, refreshInterval,\n          totalRows)\n    } else {\n      // If the kernel is not connected, wait for the event.\n      events.on('kernel_ready.Kernel', function (e:any) {\n        _render(driver, dom, chartStyle, controlIds, data, options, refreshData, refreshInterval,\n            totalRows)\n      });\n    }\n  }\n}\n\nexport = Charting;\n\n\n"
  },
  {
    "path": "datalab/notebook/static/element.ts",
    "content": "/*\n * Copyright 2015 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License. You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under the License\n * is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n * or implied. See the License for the specific language governing permissions and limitations under\n * the License.\n */\n\n/// <reference path=\"../../../externs/ts/require/require.d.ts\" />\n\nmodule Element {\n\n// RequireJS plugin to resolve DOM elements.\n\n  'use strict';\n\n  var pendingCallbacks: any = null;\n\n  function resolve(cbInfo: any): void {\n    cbInfo.cb(document.getElementById(cbInfo.name));\n  }\n  \n  function domReadyCallback(): void {\n    if (pendingCallbacks) {\n      // Clear out pendingCallbacks, so any future requests are immediately resolved.\n      var callbacks = pendingCallbacks;\n      pendingCallbacks = null;\n\n      callbacks.forEach(resolve);\n    }\n  }\n\n  export function load(name: any, req: any, loadCallback: any, config: any): void {\n    if (config.isBuild) {\n      loadCallback(null);\n    }\n    else {\n      var cbInfo = { name: name, cb: loadCallback };\n\n      if (document.readyState == 'loading') {\n        if (!pendingCallbacks) {\n          pendingCallbacks = [];\n          document.addEventListener('DOMContentLoaded', domReadyCallback, false);\n        }\n\n        pendingCallbacks.push(cbInfo);\n      }\n      else {\n        resolve(cbInfo);\n      }\n    }\n  }\n}\n\nexport = Element;\n\n"
  },
  {
    "path": "datalab/notebook/static/extern/d3.parcoords.css",
    "content": ".parcoords > svg, .parcoords > canvas {\n  /*font: 14px sans-serif;*/\n  position: absolute;\n}\n.parcoords > canvas {\n  pointer-events: none;\n}\n.parcoords rect.background {\n  fill: transparent;\n}\n.parcoords rect.background:hover {\n  fill: rgba(120,120,120,0.2);\n}\n.parcoords .resize rect {\n  fill: rgba(0,0,0,0.1);\n}\n.parcoords rect.extent {\n  fill: rgba(255,255,255,0.25);\n  stroke: rgba(0,0,0,0.6);\n}\n.parcoords .axis line, .parcoords .axis path {\n  fill: none;\n  stroke: #222;\n  shape-rendering: crispEdges;\n}\n.parcoords canvas {\n  opacity: 1;\n  -moz-transition: opacity 0.3s;\n  -webkit-transition: opacity 0.3s;\n  -o-transition: opacity 0.3s;\n}\n.parcoords canvas.faded {\n  opacity: 0.25;\n}\n.parcoords_grid { text-align: center; }\n.parcoords_grid .row, .header { clear: left; font-size: 16px; line-height: 18px; height: 18px; }\n.parcoords_grid .row:nth-child(odd) { background: rgba(0,0,0,0.05); }\n.parcoords_grid .row:hover { background: green; }\n.parcoords_grid .header { font-weight: bold; }\n.parcoords_grid .cell { float: left; overflow: hidden; white-space: nowrap; width: 120px; height: 18px; }\n.parcoords_grid .col-0 { width: 110px; }\n"
  },
  {
    "path": "datalab/notebook/static/extern/d3.parcoords.js",
    "content": "d3.parcoords = function(config) {\n  var __ = {\n    data: [],\n    highlighted: [],\n    dimensions: [],\n    dimensionTitles: {},\n    dimensionTitleRotation: 0,\n    types: {},\n    brushed: false,\n    mode: \"default\",\n    rate: 20,\n    width: 600,\n    height: 300,\n    margin: { top: 30, right: 0, bottom: 12, left: 0 },\n    color: \"#069\",\n    composite: \"source-over\",\n    alpha: 0.7,\n    bundlingStrength: 0.5,\n    bundleDimension: null,\n    smoothness: 0.25,\n    showControlPoints: false,\n    hideAxis : []\n  };\n\n  extend(__, config);\nvar pc = function(selection) {\n  selection = pc.selection = d3.select(selection);\n\n  __.width = selection[0][0].clientWidth;\n  __.height = selection[0][0].clientHeight;\n\n  // canvas data layers\n  [\"shadows\", \"marks\", \"foreground\", \"highlight\"].forEach(function(layer) {\n    canvas[layer] = selection\n      .append(\"canvas\")\n      .attr(\"class\", layer)[0][0];\n    ctx[layer] = canvas[layer].getContext(\"2d\");\n  });\n\n  // svg tick and brush layers\n  pc.svg = selection\n    .append(\"svg\")\n      .attr(\"width\", __.width)\n      .attr(\"height\", __.height)\n    .append(\"svg:g\")\n      .attr(\"transform\", \"translate(\" + __.margin.left + \",\" + __.margin.top + \")\");\n\n  return pc;\n};\nvar events = d3.dispatch.apply(this,[\"render\", \"resize\", \"highlight\", \"brush\", \"brushend\", \"axesreorder\"].concat(d3.keys(__))),\n    w = function() { return __.width - __.margin.right - __.margin.left; },\n    h = function() { return __.height - __.margin.top - __.margin.bottom; },\n    flags = {\n      brushable: false,\n      reorderable: false,\n      axes: false,\n      interactive: false,\n      shadows: false,\n      debug: false\n    },\n    xscale = d3.scale.ordinal(),\n    yscale = {},\n    dragging = {},\n    line = d3.svg.line(),\n    axis = d3.svg.axis().orient(\"left\").ticks(5),\n    g, // groups for axes, brushes\n    ctx = {},\n    canvas = {},\n    clusterCentroids = [];\n\n// side effects for setters\nvar side_effects = d3.dispatch.apply(this,d3.keys(__))\n  .on(\"composite\", function(d) { ctx.foreground.globalCompositeOperation = d.value; })\n  .on(\"alpha\", function(d) { ctx.foreground.globalAlpha = d.value; })\n  .on(\"width\", function(d) { pc.resize(); })\n  .on(\"height\", function(d) { pc.resize(); })\n  .on(\"margin\", function(d) { pc.resize(); })\n  .on(\"rate\", function(d) { rqueue.rate(d.value); })\n  .on(\"data\", function(d) {\n    if (flags.shadows){paths(__.data, ctx.shadows);}\n  })\n  .on(\"dimensions\", function(d) {\n    xscale.domain(__.dimensions);\n    if (flags.interactive){pc.render().updateAxes();}\n  })\n  .on(\"bundleDimension\", function(d) {\n\t  if (!__.dimensions.length) pc.detectDimensions();\n\t  if (!(__.dimensions[0] in yscale)) pc.autoscale();\n\t  if (typeof d.value === \"number\") {\n\t\t  if (d.value < __.dimensions.length) {\n\t\t\t  __.bundleDimension = __.dimensions[d.value];\n\t\t  } else if (d.value < __.hideAxis.length) {\n\t\t\t  __.bundleDimension = __.hideAxis[d.value];\n\t\t  }\n\t  } else {\n\t\t  __.bundleDimension = d.value;\n\t  }\n\n\t  __.clusterCentroids = compute_cluster_centroids(__.bundleDimension);\n  })\n  .on(\"hideAxis\", function(d) {\n\t  if (!__.dimensions.length) pc.detectDimensions();\n\t  pc.dimensions(without(__.dimensions, d.value));\n  });\n\n// expose the state of the chart\npc.state = __;\npc.flags = flags;\n\n// create getter/setters\ngetset(pc, __, events);\n\n// expose events\nd3.rebind(pc, events, \"on\");\n\n// tick formatting\nd3.rebind(pc, axis, \"ticks\", \"orient\", \"tickValues\", \"tickSubdivide\", \"tickSize\", \"tickPadding\", \"tickFormat\");\n\n// getter/setter with event firing\nfunction getset(obj,state,events)  {\n  d3.keys(state).forEach(function(key) {\n    obj[key] = function(x) {\n      if (!arguments.length) {\n\t\treturn state[key];\n\t}\n      var old = state[key];\n      state[key] = x;\n      side_effects[key].call(pc,{\"value\": x, \"previous\": old});\n      events[key].call(pc,{\"value\": x, \"previous\": old});\n      return obj;\n    };\n  });\n};\n\nfunction extend(target, source) {\n  for (key in source) {\n    target[key] = source[key];\n  }\n  return target;\n};\n\nfunction without(arr, item) {\n  return arr.filter(function(elem) { return item.indexOf(elem) === -1; })\n};\npc.autoscale = function() {\n  // yscale\n  var defaultScales = {\n    \"date\": function(k) {\n      return d3.time.scale()\n        .domain(d3.extent(__.data, function(d) {\n          return d[k] ? d[k].getTime() : null;\n        }))\n        .range([h()+1, 1]);\n    },\n    \"number\": function(k) {\n      return d3.scale.linear()\n        .domain(d3.extent(__.data, function(d) { return +d[k]; }))\n        .range([h()+1, 1]);\n    },\n    \"string\": function(k) {\n      var counts = {},\n          domain = [];\n\n      // Let's get the count for each value so that we can sort the domain based\n      // on the number of items for each value.\n      __.data.map(function(p) {\n        if (counts[p[k]] === undefined) {\n          counts[p[k]] = 1;\n        } else {\n          counts[p[k]] = counts[p[k]] + 1;\n        }\n      });\n\n      domain = Object.getOwnPropertyNames(counts).sort(function(a, b) {\n        return counts[a] - counts[b];\n      });\n\n      return d3.scale.ordinal()\n        .domain(domain)\n        .rangePoints([h()+1, 1]);\n    }\n  };\n\n  __.dimensions.forEach(function(k) {\n    yscale[k] = defaultScales[__.types[k]](k);\n  });\n\n  __.hideAxis.forEach(function(k) {\n    yscale[k] = defaultScales[__.types[k]](k);\n  });\n\n  // hack to remove ordinal dimensions with many values\n  pc.dimensions(pc.dimensions().filter(function(p,i) {\n    var uniques = yscale[p].domain().length;\n    if (__.types[p] == \"string\" && (uniques > 60 || uniques < 2)) {\n      return false;\n    }\n    return true;\n  }));\n\n  // xscale\n  xscale.rangePoints([0, w()], 1);\n\n  // canvas sizes\n  pc.selection.selectAll(\"canvas\")\n      .style(\"margin-top\", __.margin.top + \"px\")\n      .style(\"margin-left\", __.margin.left + \"px\")\n      .attr(\"width\", w()+2)\n      .attr(\"height\", h()+2);\n\n  // default styles, needs to be set when canvas width changes\n  ctx.foreground.strokeStyle = __.color;\n  ctx.foreground.lineWidth = 1.4;\n  ctx.foreground.globalCompositeOperation = __.composite;\n  ctx.foreground.globalAlpha = __.alpha;\n  ctx.highlight.lineWidth = 3;\n  ctx.shadows.strokeStyle = \"#dadada\";\n\n  return this;\n};\n\npc.scale = function(d, domain) {\n\tyscale[d].domain(domain);\n\n\treturn this;\n};\n\npc.flip = function(d) {\n\t//yscale[d].domain().reverse();\t\t\t\t\t// does not work\n\tyscale[d].domain(yscale[d].domain().reverse()); // works\n\n\treturn this;\n};\n\npc.commonScale = function(global, type) {\n\tvar t = type || \"number\";\n\tif (typeof global === 'undefined') {\n\t\tglobal = true;\n\t}\n\n\t// scales of the same type\n\tvar scales = __.dimensions.concat(__.hideAxis).filter(function(p) {\n\t\treturn __.types[p] == t;\n\t});\n\n\tif (global) {\n\t\tvar extent = d3.extent(scales.map(function(p,i) {\n\t\t\t\treturn yscale[p].domain();\n\t\t\t}).reduce(function(a,b) {\n\t\t\t\treturn a.concat(b);\n\t\t\t}));\n\n\t\tscales.forEach(function(d) {\n\t\t\tyscale[d].domain(extent);\n\t\t});\n\n\t} else {\n\t\tscales.forEach(function(k) {\n\t\t\tyscale[k].domain(d3.extent(__.data, function(d) { return +d[k]; }));\n\t\t});\n\t}\n\n\t// update centroids\n\tif (__.bundleDimension !== null) {\n\t\tpc.bundleDimension(__.bundleDimension);\n\t}\n\n\treturn this;\n};pc.detectDimensions = function() {\n  pc.types(pc.detectDimensionTypes(__.data));\n  pc.dimensions(d3.keys(pc.types()));\n  return this;\n};\n\n// a better \"typeof\" from this post: http://stackoverflow.com/questions/7390426/better-way-to-get-type-of-a-javascript-variable\npc.toType = function(v) {\n  return ({}).toString.call(v).match(/\\s([a-zA-Z]+)/)[1].toLowerCase();\n};\n\n// try to coerce to number before returning type\npc.toTypeCoerceNumbers = function(v) {\n  if ((parseFloat(v) == v) && (v != null)) {\n\treturn \"number\";\n}\n  return pc.toType(v);\n};\n\n// attempt to determine types of each dimension based on first row of data\npc.detectDimensionTypes = function(data) {\n  var types = {};\n  d3.keys(data[0])\n    .forEach(function(col) {\n      types[col] = pc.toTypeCoerceNumbers(data[0][col]);\n    });\n  return types;\n};\npc.render = function() {\n  // try to autodetect dimensions and create scales\n  if (!__.dimensions.length) pc.detectDimensions();\n  if (!(__.dimensions[0] in yscale)) pc.autoscale();\n\n  pc.render[__.mode]();\n\n  events.render.call(this);\n  return this;\n};\n\npc.render['default'] = function() {\n  pc.clear('foreground');\n  if (__.brushed) {\n    __.brushed.forEach(path_foreground);\n    __.highlighted.forEach(path_highlight);\n  } else {\n    __.data.forEach(path_foreground);\n    __.highlighted.forEach(path_highlight);\n  }\n};\n\nvar rqueue = d3.renderQueue(path_foreground)\n  .rate(50)\n  .clear(function() {\n    pc.clear('foreground');\n    pc.clear('highlight');\n  });\n\npc.render.queue = function() {\n  if (__.brushed) {\n    rqueue(__.brushed);\n    __.highlighted.forEach(path_highlight);\n  } else {\n    rqueue(__.data);\n    __.highlighted.forEach(path_highlight);\n  }\n};\nfunction compute_cluster_centroids(d) {\n\n\tvar clusterCentroids = d3.map();\n\tvar clusterCounts = d3.map();\n\t// determine clusterCounts\n\t__.data.forEach(function(row) {\n\t\tvar scaled = yscale[d](row[d]);\n\t\tif (!clusterCounts.has(scaled)) {\n\t\t\tclusterCounts.set(scaled, 0);\n\t\t}\n\t\tvar count = clusterCounts.get(scaled);\n\t\tclusterCounts.set(scaled, count + 1);\n\t});\n\n\t__.data.forEach(function(row) {\n\t\t__.dimensions.map(function(p, i) {\n\t\t\tvar scaled = yscale[d](row[d]);\n\t\t\tif (!clusterCentroids.has(scaled)) {\n\t\t\t\tvar map = d3.map();\n\t\t\t\tclusterCentroids.set(scaled, map);\n\t\t\t}\n\t\t\tif (!clusterCentroids.get(scaled).has(p)) {\n\t\t\t\tclusterCentroids.get(scaled).set(p, 0);\n\t\t\t}\n\t\t\tvar value = clusterCentroids.get(scaled).get(p);\n\t\t\tvalue += yscale[p](row[p]) / clusterCounts.get(scaled);\n\t\t\tclusterCentroids.get(scaled).set(p, value);\n\t\t});\n\t});\n\n\treturn clusterCentroids;\n\n}\n\nfunction compute_centroids(row) {\n\tvar centroids = [];\n\n\tvar p = __.dimensions;\n\tvar cols = p.length;\n\tvar a = 0.5;\t\t\t// center between axes\n\tfor (var i = 0; i < cols; ++i) {\n\t\t// centroids on 'real' axes\n\t\tvar x = position(p[i]);\n\t\tvar y = yscale[p[i]](row[p[i]]);\n    centroids.push([x, y]);\n\t\t//centroids.push($V([x, y]));\n\n\t\t// centroids on 'virtual' axes\n\t\tif (i < cols - 1) {\n\t\t\tvar cx = x + a * (position(p[i+1]) - x);\n\t\t\tvar cy = y + a * (yscale[p[i+1]](row[p[i+1]]) - y);\n\t\t\tif (__.bundleDimension !== null) {\n\t\t\t\tvar leftCentroid = __.clusterCentroids.get(yscale[__.bundleDimension](row[__.bundleDimension])).get(p[i]);\n\t\t\t\tvar rightCentroid = __.clusterCentroids.get(yscale[__.bundleDimension](row[__.bundleDimension])).get(p[i+1]);\n\t\t\t\tvar centroid = 0.5 * (leftCentroid + rightCentroid);\n\t\t\t\tcy = centroid + (1 - __.bundlingStrength) * (cy - centroid);\n\t\t\t}\n      centroids.push([cx, cy]);\n\t\t\t//centroids.push($V([cx, cy]));\n\t\t}\n\t}\n\n\treturn centroids;\n}\n\npc.compute_centroids = compute_centroids;\n\nfunction compute_control_points(centroids) {\n\n\tvar cols = centroids.length;\n\tvar a = __.smoothness;\n\tvar cps = [];\n\n\tcps.push(centroids[0]);\n\tcps.push($V([centroids[0].e(1) + a*2*(centroids[1].e(1)-centroids[0].e(1)), centroids[0].e(2)]));\n\tfor (var col = 1; col < cols - 1; ++col) {\n\t\tvar mid = centroids[col];\n\t\tvar left = centroids[col - 1];\n\t\tvar right = centroids[col + 1];\n\n\t\tvar diff = left.subtract(right);\n\t\tcps.push(mid.add(diff.x(a)));\n\t\tcps.push(mid);\n\t\tcps.push(mid.subtract(diff.x(a)));\n\t}\n\tcps.push($V([centroids[cols-1].e(1) + a*2*(centroids[cols-2].e(1)-centroids[cols-1].e(1)), centroids[cols-1].e(2)]));\n\tcps.push(centroids[cols - 1]);\n\n\treturn cps;\n\n};pc.shadows = function() {\n\tflags.shadows = true;\n\tif (__.data.length > 0) {\n\t\tpaths(__.data, ctx.shadows);\n\t}\n\treturn this;\n};\n\n// draw little dots on the axis line where data intersects\npc.axisDots = function() {\n\tvar ctx = pc.ctx.marks;\n\tctx.globalAlpha = d3.min([ 1 / Math.pow(data.length, 1 / 2), 1 ]);\n\t__.data.forEach(function(d) {\n\t\t__.dimensions.map(function(p, i) {\n\t\t\tctx.fillRect(position(p) - 0.75, yscale[p](d[p]) - 0.75, 1.5, 1.5);\n\t\t});\n\t});\n\treturn this;\n};\n\n// draw single cubic bezier curve\nfunction single_curve(d, ctx) {\n\n\tvar centroids = compute_centroids(d);\n\tvar cps = compute_control_points(centroids);\n\n\tctx.moveTo(cps[0].e(1), cps[0].e(2));\n\tfor (var i = 1; i < cps.length; i += 3) {\n\t\tif (__.showControlPoints) {\n\t\t\tfor (var j = 0; j < 3; j++) {\n\t\t\t\tctx.fillRect(cps[i+j].e(1), cps[i+j].e(2), 2, 2);\n\t\t\t}\n\t\t}\n\t\tctx.bezierCurveTo(cps[i].e(1), cps[i].e(2), cps[i+1].e(1), cps[i+1].e(2), cps[i+2].e(1), cps[i+2].e(2));\n\t}\n};\n\n// draw single polyline\nfunction color_path(d, i, ctx) {\n\tctx.strokeStyle = d3.functor(__.color)(d, i);\n\tctx.beginPath();\n\tif (__.bundleDimension === null || (__.bundlingStrength === 0 && __.smoothness == 0)) {\n\t\tsingle_path(d, ctx);\n\t} else {\n\t\tsingle_curve(d, ctx);\n\t}\n\tctx.stroke();\n};\n\n// draw many polylines of the same color\nfunction paths(data, ctx) {\n\tctx.clearRect(-1, -1, w() + 2, h() + 2);\n\tctx.beginPath();\n\tdata.forEach(function(d) {\n\t\tif (__.bundleDimension === null || (__.bundlingStrength === 0 && __.smoothness == 0)) {\n\t\t\tsingle_path(d, ctx);\n\t\t} else {\n\t\t\tsingle_curve(d, ctx);\n\t\t}\n\t});\n\tctx.stroke();\n};\n\nfunction single_path(d, ctx) {\n\t__.dimensions.map(function(p, i) {\n\t\tif (i == 0) {\n\t\t\tctx.moveTo(position(p), yscale[p](d[p]));\n\t\t} else {\n\t\t\tctx.lineTo(position(p), yscale[p](d[p]));\n\t\t}\n\t});\n}\n\nfunction path_foreground(d, i) {\n\treturn color_path(d, i, ctx.foreground);\n};\n\nfunction path_highlight(d, i) {\n\treturn color_path(d, i, ctx.highlight);\n};\npc.clear = function(layer) {\n  ctx[layer].clearRect(0,0,w()+2,h()+2);\n  return this;\n};\nfunction flipAxisAndUpdatePCP(dimension, i) {\n  var g = pc.svg.selectAll(\".dimension\");\n\n  pc.flip(dimension);\n  d3.select(g[0][i])\n    .transition()\n      .duration(1100)\n      .call(axis.scale(yscale[dimension]));\n\n  pc.render();\n  if (flags.shadows) paths(__.data, ctx.shadows);\n}\n\nfunction rotateLabels() {\n  var delta = d3.event.deltaY;\n  delta = delta < 0 ? -5 : delta;\n  delta = delta > 0 ? 5 : delta;\n\n  __.dimensionTitleRotation += delta;\n  pc.svg.selectAll(\"text.label\")\n    .attr(\"transform\", \"translate(0,-5) rotate(\" + __.dimensionTitleRotation + \")\");\n  d3.event.preventDefault();\n}\n\npc.createAxes = function() {\n  if (g) pc.removeAxes();\n\n  // Add a group element for each dimension.\n  g = pc.svg.selectAll(\".dimension\")\n      .data(__.dimensions, function(d) { return d; })\n    .enter().append(\"svg:g\")\n      .attr(\"class\", \"dimension\")\n      .attr(\"transform\", function(d) { return \"translate(\" + xscale(d) + \")\"; });\n\n  // Add an axis and title.\n  g.append(\"svg:g\")\n      .attr(\"class\", \"axis\")\n      .attr(\"transform\", \"translate(0,0)\")\n      .each(function(d) { d3.select(this).call(axis.scale(yscale[d])); })\n    .append(\"svg:text\")\n      .attr({\n        \"text-anchor\": \"middle\",\n        \"y\": 0,\n        \"transform\": \"translate(0,-5) rotate(\" + __.dimensionTitleRotation + \")\",\n        \"x\": 0,\n        \"class\": \"label\"\n      })\n      .text(function(d) {\n        return d in __.dimensionTitles ? __.dimensionTitles[d] : d;  // dimension display names\n      })\n      .on(\"dblclick\", flipAxisAndUpdatePCP)\n      .on(\"wheel\", rotateLabels);\n\n  flags.axes= true;\n  return this;\n};\n\npc.removeAxes = function() {\n  g.remove();\n  return this;\n};\n\npc.updateAxes = function() {\n  var g_data = pc.svg.selectAll(\".dimension\").data(__.dimensions);\n\n  // Enter\n  g_data.enter().append(\"svg:g\")\n      .attr(\"class\", \"dimension\")\n      .attr(\"transform\", function(p) { return \"translate(\" + position(p) + \")\"; })\n      .style(\"opacity\", 0)\n    .append(\"svg:g\")\n      .attr(\"class\", \"axis\")\n      .attr(\"transform\", \"translate(0,0)\")\n      .each(function(d) { d3.select(this).call(axis.scale(yscale[d])); })\n    .append(\"svg:text\")\n      .attr({\n        \"text-anchor\": \"middle\",\n        \"y\": 0,\n        \"transform\": \"translate(0,-5) rotate(\" + __.dimensionTitleRotation + \")\",\n        \"x\": 0,\n        \"class\": \"label\"\n      })\n      .text(String)\n      .on(\"dblclick\", flipAxisAndUpdatePCP)\n      .on(\"wheel\", rotateLabels);\n\n  // Update\n  g_data.attr(\"opacity\", 0);\n  g_data.select(\".axis\")\n    .transition()\n      .duration(1100)\n      .each(function(d) {\n        d3.select(this).call(axis.scale(yscale[d]));\n      });\n  g_data.select(\".label\")\n    .transition()\n      .duration(1100)\n      .text(String)\n      .attr(\"transform\", \"translate(0,-5) rotate(\" + __.dimensionTitleRotation + \")\");\n\n  // Exit\n  g_data.exit().remove();\n\n  g = pc.svg.selectAll(\".dimension\");\n  g.transition().duration(1100)\n    .attr(\"transform\", function(p) { return \"translate(\" + position(p) + \")\"; })\n    .style(\"opacity\", 1);\n\n  pc.svg.selectAll(\".axis\")\n    .transition()\n      .duration(1100)\n      .each(function(d) { d3.select(this).call(axis.scale(yscale[d])); });\n\n  if (flags.shadows) paths(__.data, ctx.shadows);\n  if (flags.brushable) pc.brushable();\n  if (flags.reorderable) pc.reorderable();\n  if (pc.brushMode() !== \"None\") {\n    var mode = pc.brushMode();\n    pc.brushMode(\"None\");\n    pc.brushMode(mode);\n  }\n  return this;\n};\n\n// Jason Davies, http://bl.ocks.org/1341281\npc.reorderable = function() {\n  if (!g) pc.createAxes();\n\n  // Keep track of the order of the axes to verify if the order has actually\n  // changed after a drag ends. Changed order might have consequence (e.g.\n  // strums that need to be reset).\n  var dimsAtDragstart;\n\n  g.style(\"cursor\", \"move\")\n    .call(d3.behavior.drag()\n      .on(\"dragstart\", function(d) {\n        dragging[d] = this.__origin__ = xscale(d);\n        dimsAtDragstart = __.dimensions.slice();\n      })\n      .on(\"drag\", function(d) {\n        dragging[d] = Math.min(w(), Math.max(0, this.__origin__ += d3.event.dx));\n        __.dimensions.sort(function(a, b) { return position(a) - position(b); });\n        xscale.domain(__.dimensions);\n        pc.render();\n        g.attr(\"transform\", function(d) { return \"translate(\" + position(d) + \")\"; });\n      })\n      .on(\"dragend\", function(d, i) {\n        // Let's see if the order has changed and send out an event if so.\n        var j = __.dimensions.indexOf(d),\n            parent = this.parentElement;\n\n        if (i !== j) {\n          events.axesreorder.call(pc, __.dimensions);\n          // We now also want to reorder the actual dom elements that represent\n          // the axes. That is, the g.dimension elements. If we don't do this,\n          // we get a weird and confusing transition when updateAxes is called.\n          // This is due to the fact that, initially the nth g.dimension element\n          // represents the nth axis. However, after a manual reordering,\n          // without reordering the dom elements, the nth dom elements no longer\n          // necessarily represents the nth axis.\n          //\n          // i is the original index of the dom element\n          // j is the new index of the dom element\n          parent.insertBefore(this, parent.children[j + 1])\n        }\n\n        delete this.__origin__;\n        delete dragging[d];\n        d3.select(this).transition().attr(\"transform\", \"translate(\" + xscale(d) + \")\");\n        pc.render();\n        if (flags.shadows) paths(__.data, ctx.shadows);\n      }));\n  flags.reorderable = true;\n  return this;\n};\n\n// pairs of adjacent dimensions\npc.adjacent_pairs = function(arr) {\n  var ret = [];\n  for (var i = 0; i < arr.length-1; i++) {\n    ret.push([arr[i],arr[i+1]]);\n  };\n  return ret;\n};\n\nvar brush = {\n  modes: {\n    \"None\": {\n      install: function(pc) {},           // Nothing to be done.\n      uninstall: function(pc) {},         // Nothing to be done.\n      selected: function() { return []; } // Nothing to return\n    }\n  },\n  mode: \"None\",\n  predicate: \"AND\",\n  currentMode: function() {\n    return this.modes[this.mode];\n  }\n};\n\n// This function can be used for 'live' updates of brushes. That is, during the\n// specification of a brush, this method can be called to update the view.\n//\n// @param newSelection - The new set of data items that is currently contained\n//                       by the brushes\nfunction brushUpdated(newSelection) {\n  __.brushed = newSelection;\n  events.brush.call(pc,__.brushed);\n  pc.render();\n}\n\nfunction brushPredicate(predicate) {\n  if (!arguments.length) { return brush.predicate; }\n\n  predicate = String(predicate).toUpperCase();\n  if (predicate !== \"AND\" && predicate !== \"OR\") {\n    throw \"Invalid predicate \" + predicate;\n  }\n\n  brush.predicate = predicate;\n  __.brushed = brush.currentMode().selected();\n  pc.render();\n  return pc;\n}\n\npc.brushModes = function() {\n  return Object.getOwnPropertyNames(brush.modes);\n};\n\npc.brushMode = function(mode) {\n  if (arguments.length === 0) {\n    return brush.mode;\n  }\n\n  if (pc.brushModes().indexOf(mode) === -1) {\n    throw \"pc.brushmode: Unsupported brush mode: \" + mode;\n  }\n\n  // Make sure that we don't trigger unnecessary events by checking if the mode\n  // actually changes.\n  if (mode !== brush.mode) {\n    // When changing brush modes, the first thing we need to do is clearing any\n    // brushes from the current mode, if any.\n    if (brush.mode !== \"None\") {\n      pc.brushReset();\n    }\n\n    // Next, we need to 'uninstall' the current brushMode.\n    brush.modes[brush.mode].uninstall(pc);\n    // Finally, we can install the requested one.\n    brush.mode = mode;\n    brush.modes[brush.mode].install();\n    if (mode === \"None\") {\n      delete pc.brushPredicate;\n    } else {\n      pc.brushPredicate = brushPredicate;\n    }\n  }\n\n  return pc;\n};\n\n// brush mode: 1D-Axes\n\n(function() {\n  var brushes = {};\n\n  function is_brushed(p) {\n    return !brushes[p].empty();\n  }\n\n  // data within extents\n  function selected() {\n    var actives = __.dimensions.filter(is_brushed),\n        extents = actives.map(function(p) { return brushes[p].extent(); });\n\n    // We don't want to return the full data set when there are no axes brushed.\n    // Actually, when there are no axes brushed, by definition, no items are\n    // selected. So, let's avoid the filtering and just return false.\n    //if (actives.length === 0) return false;\n\n    // Resolves broken examples for now. They expect to get the full dataset back from empty brushes\n    if (actives.length === 0) return __.data;\n\n    // test if within range\n    var within = {\n      \"date\": function(d,p,dimension) {\n        return extents[dimension][0] <= d[p] && d[p] <= extents[dimension][1]\n      },\n      \"number\": function(d,p,dimension) {\n        return extents[dimension][0] <= d[p] && d[p] <= extents[dimension][1]\n      },\n      \"string\": function(d,p,dimension) {\n        return extents[dimension][0] <= yscale[p](d[p]) && yscale[p](d[p]) <= extents[dimension][1]\n      }\n    };\n\n    return __.data\n      .filter(function(d) {\n        switch(brush.predicate) {\n        case \"AND\":\n          return actives.every(function(p, dimension) {\n            return within[__.types[p]](d,p,dimension);\n          });\n        case \"OR\":\n          return actives.some(function(p, dimension) {\n            return within[__.types[p]](d,p,dimension);\n          });\n        default:\n          throw \"Unknown brush predicate \" + __.brushPredicate;\n        }\n      });\n  };\n\n  function brushExtents() {\n    var extents = {};\n    __.dimensions.forEach(function(d) {\n      var brush = brushes[d];\n      if (!brush.empty()) {\n        var extent = brush.extent();\n        extent.sort(d3.ascending);\n        extents[d] = extent;\n      }\n    });\n    return extents;\n  }\n\n  function brushFor(axis) {\n    var brush = d3.svg.brush();\n\n    brush\n      .y(yscale[axis])\n      .on(\"brushstart\", function() { d3.event.sourceEvent.stopPropagation() })\n      .on(\"brush\", function() {\n        brushUpdated(selected());\n      })\n      .on(\"brushend\", function() {\n        events.brushend.call(pc, __.brushed);\n      });\n\n    brushes[axis] = brush;\n    return brush;\n  }\n\n  function brushReset(dimension) {\n    __.brushed = false;\n    if (g) {\n      g.selectAll('.brush')\n        .each(function(d) {\n          d3.select(this).call(\n            brushes[d].clear()\n          );\n        });\n      pc.render();\n    }\n    return this;\n  };\n\n  function install() {\n    if (!g) pc.createAxes();\n\n    // Add and store a brush for each axis.\n    g.append(\"svg:g\")\n      .attr(\"class\", \"brush\")\n      .each(function(d) {\n        d3.select(this).call(brushFor(d));\n      })\n      .selectAll(\"rect\")\n        .style(\"visibility\", null)\n        .attr(\"x\", -15)\n        .attr(\"width\", 30);\n\n    pc.brushExtents = brushExtents;\n    pc.brushReset = brushReset;\n    return pc;\n  }\n\n  brush.modes[\"1D-axes\"] = {\n    install: install,\n    uninstall: function() {\n      g.selectAll(\".brush\").remove();\n      brushes = {};\n      delete pc.brushExtents;\n      delete pc.brushReset;\n    },\n    selected: selected\n  }\n})();\n// brush mode: 2D-strums\n// bl.ocks.org/syntagmatic/5441022\n\n(function() {\n  var strums = {},\n      strumRect;\n\n  function drawStrum(strum, activePoint) {\n    var svg = pc.selection.select(\"svg\").select(\"g#strums\"),\n        id = strum.dims.i,\n        points = [strum.p1, strum.p2],\n        line = svg.selectAll(\"line#strum-\" + id).data([strum]),\n        circles = svg.selectAll(\"circle#strum-\" + id).data(points),\n        drag = d3.behavior.drag();\n\n    line.enter()\n      .append(\"line\")\n      .attr(\"id\", \"strum-\" + id)\n      .attr(\"class\", \"strum\");\n\n    line\n      .attr(\"x1\", function(d) { return d.p1[0]; })\n      .attr(\"y1\", function(d) { return d.p1[1]; })\n      .attr(\"x2\", function(d) { return d.p2[0]; })\n      .attr(\"y2\", function(d) { return d.p2[1]; })\n      .attr(\"stroke\", \"black\")\n      .attr(\"stroke-width\", 2);\n\n    drag\n      .on(\"drag\", function(d, i) { \n        var ev = d3.event;\n        i = i + 1;\n        strum[\"p\" + i][0] = Math.min(Math.max(strum.minX + 1, ev.x), strum.maxX);\n        strum[\"p\" + i][1] = Math.min(Math.max(strum.minY, ev.y), strum.maxY);\n        drawStrum(strum, i - 1);\n      })\n      .on(\"dragend\", onDragEnd());\n\n    circles.enter()\n      .append(\"circle\")\n      .attr(\"id\", \"strum-\" + id)\n      .attr(\"class\", \"strum\");\n\n    circles\n      .attr(\"cx\", function(d) { return d[0]; })\n      .attr(\"cy\", function(d) { return d[1]; })\n      .attr(\"r\", 5)\n      .style(\"opacity\", function(d, i) {\n        return (activePoint !== undefined && i === activePoint) ? 0.8 : 0;\n      })\n      .on(\"mouseover\", function() {\n        d3.select(this).style(\"opacity\", 0.8);\n      })\n      .on(\"mouseout\", function() {\n        d3.select(this).style(\"opacity\", 0);\n      })\n      .call(drag);\n  }\n\n  function dimensionsForPoint(p) {\n    var dims = { i: -1, left: undefined, right: undefined };\n    __.dimensions.some(function(dim, i) {\n      if (xscale(dim) < p[0]) {\n        var next = __.dimensions[i + 1];\n        dims.i = i;\n        dims.left = dim;\n        dims.right = next;\n        return false;\n      }\n      return true;\n    });\n\n    if (dims.left === undefined) {\n      // Event on the left side of the first axis.\n      dims.i = 0;\n      dims.left = __.dimensions[0];\n      dims.right = __.dimensions[1];\n    } else if (dims.right === undefined) {\n      // Event on the right side of the last axis\n      dims.i = __.dimensions.length - 1;\n      dims.right = dims.left;\n      dims.left = __.dimensions[__.dimensions.length - 2];\n    }\n\n    return dims;\n  }\n\n  function onDragStart() {\n    // First we need to determine between which two axes the sturm was started.\n    // This will determine the freedom of movement, because a strum can\n    // logically only happen between two axes, so no movement outside these axes\n    // should be allowed.\n    return function() {\n      var p = d3.mouse(strumRect[0][0]),\n          dims = dimensionsForPoint(p),\n          strum = {\n            p1: p,\n            dims: dims,\n            minX: xscale(dims.left),\n            maxX: xscale(dims.right),\n            minY: 0,\n            maxY: h()\n          };\n\n      strums[dims.i] = strum;\n      strums.active = dims.i;\n\n      // Make sure that the point is within the bounds\n      strum.p1[0] = Math.min(Math.max(strum.minX, p[0]), strum.maxX);\n      strum.p1[1] = p[1] - __.margin.top;\n      strum.p2 = strum.p1.slice();\n    };\n  }\n\n  function onDrag() {\n    return function() {\n      var ev = d3.event,\n          strum = strums[strums.active];\n\n      // Make sure that the point is within the bounds\n      strum.p2[0] = Math.min(Math.max(strum.minX + 1, ev.x), strum.maxX);\n      strum.p2[1] = Math.min(Math.max(strum.minY, ev.y - __.margin.top), strum.maxY);\n      drawStrum(strum, 1);\n    };\n  }\n\n  function containmentTest(strum, width) {\n    var p1 = [strum.p1[0] - strum.minX, strum.p1[1] - strum.minX],\n        p2 = [strum.p2[0] - strum.minX, strum.p2[1] - strum.minX],\n        m1 = 1 - width / p1[0],\n        b1 = p1[1] * (1 - m1),\n        m2 = 1 - width / p2[0],\n        b2 = p2[1] * (1 - m2);\n\n    // test if point falls between lines\n    return function(p) {\n      var x = p[0],\n          y = p[1],\n          y1 = m1 * x + b1,\n          y2 = m2 * x + b2;\n\n      if (y > Math.min(y1, y2) && y < Math.max(y1, y2)) {\n        return true;\n      }\n\n      return false;\n    };\n  }\n\n  function selected() {\n    var ids = Object.getOwnPropertyNames(strums),\n        brushed = __.data;\n\n    // Get the ids of the currently active strums.\n    ids = ids.filter(function(d) {\n      return !isNaN(d);\n    });\n\n    function crossesStrum(d, id) {\n      var strum = strums[id],\n          test = containmentTest(strum, strums.width(id)),\n          d1 = strum.dims.left,\n          d2 = strum.dims.right,\n          y1 = yscale[d1],\n          y2 = yscale[d2],\n          point = [y1(d[d1]) - strum.minX, y2(d[d2]) - strum.minX];\n      return test(point);\n    }\n\n    if (ids.length === 0) { return brushed; }\n\n    return brushed.filter(function(d) {\n      switch(brush.predicate) {\n      case \"AND\":\n        return ids.every(function(id) { return crossesStrum(d, id); });\n      case \"OR\":\n        return ids.some(function(id) { return crossesStrum(d, id); });\n      default:\n        throw \"Unknown brush predicate \" + __.brushPredicate;\n      }\n    });\n  }\n\n  function removeStrum() {\n    var strum = strums[strums.active],\n        svg = pc.selection.select(\"svg\").select(\"g#strums\");\n\n    delete strums[strums.active];\n    strums.active = undefined;\n    svg.selectAll(\"line#strum-\" + strum.dims.i).remove();\n    svg.selectAll(\"circle#strum-\" + strum.dims.i).remove();\n  }\n\n  function onDragEnd() {\n    return function() {\n      var brushed = __.data,\n          strum = strums[strums.active];\n\n      // Okay, somewhat unexpected, but not totally unsurprising, a mousclick is\n      // considered a drag without move. So we have to deal with that case\n      if (strum && strum.p1[0] === strum.p2[0] && strum.p1[1] === strum.p2[1]) {\n        removeStrum(strums);\n      }\n\n      brushed = selected(strums);\n      strums.active = undefined;\n      __.brushed = brushed;\n      pc.render();\n      events.brushend.call(pc, __.brushed);\n    };\n  }\n\n  function brushReset(strums) {\n    return function() {\n      var ids = Object.getOwnPropertyNames(strums).filter(function(d) {\n        return !isNaN(d);\n      });\n\n      ids.forEach(function(d) {\n        strums.active = d;\n        removeStrum(strums);\n      });\n      onDragEnd(strums)();\n    };\n  }\n\n  function install() {\n    var drag = d3.behavior.drag();\n\n    // Map of current strums. Strums are stored per segment of the PC. A segment,\n    // being the area between two axes. The left most area is indexed at 0.\n    strums.active = undefined;\n    // Returns the width of the PC segment where currently a strum is being\n    // placed. NOTE: even though they are evenly spaced in our current\n    // implementation, we keep for when non-even spaced segments are supported as\n    // well.\n    strums.width = function(id) {\n      var strum = strums[id];\n\n      if (strum === undefined) {\n        return undefined;\n      }\n\n      return strum.maxX - strum.minX;\n    };\n\n    pc.on(\"axesreorder.strums\", function() {\n      var ids = Object.getOwnPropertyNames(strums).filter(function(d) {\n        return !isNaN(d);\n      });\n\n      // Checks if the first dimension is directly left of the second dimension.\n      function consecutive(first, second) {\n        var length = __.dimensions.length;\n        return __.dimensions.some(function(d, i) {\n          return (d === first)\n            ? i + i < length && __.dimensions[i + 1] === second\n            : false;\n        });\n      }\n\n      if (ids.length > 0) { // We have some strums, which might need to be removed.\n        ids.forEach(function(d) {\n          var dims = strums[d].dims;\n          strums.active = d;\n          // If the two dimensions of the current strum are not next to each other\n          // any more, than we'll need to remove the strum. Otherwise we keep it.\n          if (!consecutive(dims.left, dims.right)) {\n            removeStrum(strums);\n          }\n        });\n        onDragEnd(strums)();\n      }\n    });\n\n    // Add a new svg group in which we draw the strums.\n    pc.selection.select(\"svg\").append(\"g\")\n      .attr(\"id\", \"strums\")\n      .attr(\"transform\", \"translate(\" + __.margin.left + \",\" + __.margin.top + \")\");\n\n    // Install the required brushReset function\n    pc.brushReset = brushReset(strums);\n\n    drag\n      .on(\"dragstart\", onDragStart(strums))\n      .on(\"drag\", onDrag(strums))\n      .on(\"dragend\", onDragEnd(strums));\n\n    // NOTE: The styling needs to be done here and not in the css. This is because\n    //       for 1D brushing, the canvas layers should not listen to\n    //       pointer-events.\n    strumRect = pc.selection.select(\"svg\").insert(\"rect\", \"g#strums\")\n      .attr(\"id\", \"strum-events\")\n      .attr(\"x\", __.margin.left)\n      .attr(\"y\", __.margin.top)\n      .attr(\"width\", w())\n      .attr(\"height\", h() + 2)\n      .style(\"opacity\", 0)\n      .call(drag);\n  }\n\n  brush.modes[\"2D-strums\"] = {\n    install: install,\n    uninstall: function() {\n      pc.selection.select(\"svg\").select(\"g#strums\").remove();\n      pc.selection.select(\"svg\").select(\"rect#strum-events\").remove();\n      pc.on(\"axesreorder.strums\", undefined);\n      delete pc.brushReset;\n\n      strumRect = undefined;\n    },\n    selected: selected\n  };\n\n}());\n\npc.interactive = function() {\n  flags.interactive = true;\n  return this;\n};\n\n// expose a few objects\npc.xscale = xscale;\npc.yscale = yscale;\npc.ctx = ctx;\npc.canvas = canvas;\npc.g = function() { return g; };\n\n// rescale for height, width and margins\n// TODO currently assumes chart is brushable, and destroys old brushes\npc.resize = function() {\n  // selection size\n  pc.selection.select(\"svg\")\n    .attr(\"width\", __.width)\n    .attr(\"height\", __.height)\n  pc.svg.attr(\"transform\", \"translate(\" + __.margin.left + \",\" + __.margin.top + \")\");\n\n  // FIXME: the current brush state should pass through\n  if (flags.brushable) pc.brushReset();\n\n  // scales\n  pc.autoscale();\n\n  // axes, destroys old brushes.\n  if (g) pc.createAxes();\n  if (flags.shadows) paths(__.data, ctx.shadows);\n  if (flags.brushable) pc.brushable();\n  if (flags.reorderable) pc.reorderable();\n\n  events.resize.call(this, {width: __.width, height: __.height, margin: __.margin});\n  return this;\n};\n\n// highlight an array of data\npc.highlight = function(data) {\n  if (arguments.length === 0) {\n    return __.highlighted;\n  }\n\n  __.highlighted = data;\n  pc.clear(\"highlight\");\n  d3.select(canvas.foreground).classed(\"faded\", true);\n  data.forEach(path_highlight);\n  events.highlight.call(this, data);\n  return this;\n};\n\n// clear highlighting\npc.unhighlight = function() {\n  __.highlighted = [];\n  pc.clear(\"highlight\");\n  d3.select(canvas.foreground).classed(\"faded\", false);\n  return this;\n};\n\n// calculate 2d intersection of line a->b with line c->d\n// points are objects with x and y properties\npc.intersection =  function(a, b, c, d) {\n  return {\n    x: ((a.x * b.y - a.y * b.x) * (c.x - d.x) - (a.x - b.x) * (c.x * d.y - c.y * d.x)) / ((a.x - b.x) * (c.y - d.y) - (a.y - b.y) * (c.x - d.x)),\n    y: ((a.x * b.y - a.y * b.x) * (c.y - d.y) - (a.y - b.y) * (c.x * d.y - c.y * d.x)) / ((a.x - b.x) * (c.y - d.y) - (a.y - b.y) * (c.x - d.x))\n  };\n};\n\nfunction position(d) {\n  var v = dragging[d];\n  return v == null ? xscale(d) : v;\n}\npc.version = \"0.5.0\";\n  // this descriptive text should live with other introspective methods\n  pc.toString = function() { return \"Parallel Coordinates: \" + __.dimensions.length + \" dimensions (\" + d3.keys(__.data[0]).length + \" total) , \" + __.data.length + \" rows\"; };\n\n  return pc;\n};\n\nd3.renderQueue = (function(func) {\n  var _queue = [],                  // data to be rendered\n      _rate = 10,                   // number of calls per frame\n      _clear = function() {},       // clearing function\n      _i = 0;                       // current iteration\n\n  var rq = function(data) {\n    if (data) rq.data(data);\n    rq.invalidate();\n    _clear();\n    rq.render();\n  };\n\n  rq.render = function() {\n    _i = 0;\n    var valid = true;\n    rq.invalidate = function() { valid = false; };\n\n    function doFrame() {\n      if (!valid) return true;\n      if (_i > _queue.length) return true;\n\n      // Typical d3 behavior is to pass a data item *and* its index. As the\n      // render queue splits the original data set, we'll have to be slightly\n      // more carefull about passing the correct index with the data item.\n      var end = Math.min(_i + _rate, _queue.length);\n      for (var i = _i; i < end; i++) {\n        func(_queue[i], i);\n      }\n      _i += _rate;\n    }\n\n    d3.timer(doFrame);\n  };\n\n  rq.data = function(data) {\n    rq.invalidate();\n    _queue = data.slice(0);\n    return rq;\n  };\n\n  rq.rate = function(value) {\n    if (!arguments.length) return _rate;\n    _rate = value;\n    return rq;\n  };\n\n  rq.remaining = function() {\n    return _queue.length - _i;\n  };\n\n  // clear the canvas\n  rq.clear = function(func) {\n    if (!arguments.length) {\n      _clear();\n      return rq;\n    }\n    _clear = func;\n    return rq;\n  };\n\n  rq.invalidate = function() {};\n\n  return rq;\n});\n\nd3.divgrid = function(config) {\n  var columns = [];\n\n  var dg = function(selection) {\n    if (columns.length == 0) {\n      columns = d3.keys(selection.data()[0][0]);\n      columns = columns.filter( function(item) {\n        return (item.substr(item.length - 5) != \"(log)\");\n      });\n    }\n\n    // header\n    selection.selectAll(\".header\")\n        .data([true])\n      .enter().append(\"div\")\n        .attr(\"class\", \"header\")\n\n    var header = selection.select(\".header\")\n      .selectAll(\".cell\")\n      .data(columns);\n\n    header.enter().append(\"div\")\n      .attr(\"class\", function(d,i) { return \"col-\" + i; })\n      .classed(\"cell\", true)\n\n    selection.selectAll(\".header .cell\")\n      .text(function(d) { return d; });\n\n    header.exit().remove();\n\n    // rows\n    var rows = selection.selectAll(\".row\")\n        .data(function(d) { return d; })\n\n    rows.enter().append(\"div\")\n        .attr(\"class\", \"row\")\n\n    rows.exit().remove();\n\n    var cells = selection.selectAll(\".row\").selectAll(\".cell\")\n        .data(function(d) { return columns.map(function(col){return d[col];}) })\n\n    // cells\n    cells.enter().append(\"div\")\n      .attr(\"class\", function(d,i) { return \"col-\" + i; })\n      .classed(\"cell\", true)\n\n    cells.exit().remove();\n\n    selection.selectAll(\".cell\")\n      .text(function(d) { return d; });\n\n    return dg;\n  };\n\n  dg.columns = function(_) {\n    if (!arguments.length) return columns;\n    columns = _;\n    return this;\n  };\n\n  return dg;\n};\n"
  },
  {
    "path": "datalab/notebook/static/extern/lantern-browser.html",
    "content": "<html><head><!--\n@license\nCopyright (c) 2016 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n--><!--\n@license\nCopyright (c) 2014 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n--><!--\n@license\nCopyright (c) 2015 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n--><meta charset=\"UTF-8\">\n    </head>\n  <body><div hidden by-vulcanize=\"\">\n\n<dom-module id=\"iron-pages\" assetpath=\"/iron-pages/\">\n\n  <template>\n    <style>\n      :host {\n        display: block;\n      }\n\n      :host > ::content > :not(.iron-selected) {\n        display: none !important;\n      }\n    </style>\n\n    <content></content>\n  </template>\n\n  </dom-module>\n\n\n<dom-module id=\"iron-a11y-announcer\" assetpath=\"/iron-a11y-announcer/\">\n  <template>\n    <style>\n      :host {\n        display: inline-block;\n        position: fixed;\n        clip: rect(0px,0px,0px,0px);\n      }\n    </style>\n    <div aria-live$=\"[[mode]]\">[[_text]]</div>\n  </template>\n\n  </dom-module>\n\n\n<link rel=\"stylesheet\" href=\"https://fonts.googleapis.com/css?family=Roboto:400,300,300italic,400italic,500,500italic,700,700italic\">\n<link rel=\"stylesheet\" href=\"https://fonts.googleapis.com/css?family=Roboto+Mono:400,700\">\n<style is=\"custom-style\">\n\n  :root {\n\n    /* Shared Styles */\n    --paper-font-common-base: {\n      font-family: 'Roboto', 'Noto', sans-serif;\n      -webkit-font-smoothing: antialiased;\n    };\n\n    --paper-font-common-code: {\n      font-family: 'Roboto Mono', 'Consolas', 'Menlo', monospace;\n      -webkit-font-smoothing: antialiased;\n    };\n\n    --paper-font-common-expensive-kerning: {\n      text-rendering: optimizeLegibility;\n    };\n\n    --paper-font-common-nowrap: {\n      white-space: nowrap;\n      overflow: hidden;\n      text-overflow: ellipsis;\n    };\n\n    /* Material Font Styles */\n\n    --paper-font-display4: {\n      @apply(--paper-font-common-base);\n      @apply(--paper-font-common-nowrap);\n\n      font-size: 112px;\n      font-weight: 300;\n      letter-spacing: -.044em;\n      line-height: 120px;\n    };\n\n    --paper-font-display3: {\n      @apply(--paper-font-common-base);\n      @apply(--paper-font-common-nowrap);\n\n      font-size: 56px;\n      font-weight: 400;\n      letter-spacing: -.026em;\n      line-height: 60px;\n    };\n\n    --paper-font-display2: {\n      @apply(--paper-font-common-base);\n\n      font-size: 45px;\n      font-weight: 400;\n      letter-spacing: -.018em;\n      line-height: 48px;\n    };\n\n    --paper-font-display1: {\n      @apply(--paper-font-common-base);\n\n      font-size: 34px;\n      font-weight: 400;\n      letter-spacing: -.01em;\n      line-height: 40px;\n    };\n\n    --paper-font-headline: {\n      @apply(--paper-font-common-base);\n\n      font-size: 24px;\n      font-weight: 400;\n      letter-spacing: -.012em;\n      line-height: 32px;\n    };\n\n    --paper-font-title: {\n      @apply(--paper-font-common-base);\n      @apply(--paper-font-common-nowrap);\n\n      font-size: 20px;\n      font-weight: 500;\n      line-height: 28px;\n    };\n\n    --paper-font-subhead: {\n      @apply(--paper-font-common-base);\n\n      font-size: 16px;\n      font-weight: 400;\n      line-height: 24px;\n    };\n\n    --paper-font-body2: {\n      @apply(--paper-font-common-base);\n\n      font-size: 14px;\n      font-weight: 500;\n      line-height: 24px;\n    };\n\n    --paper-font-body1: {\n      @apply(--paper-font-common-base);\n\n      font-size: 14px;\n      font-weight: 400;\n      line-height: 20px;\n    };\n\n    --paper-font-caption: {\n      @apply(--paper-font-common-base);\n      @apply(--paper-font-common-nowrap);\n\n      font-size: 12px;\n      font-weight: 400;\n      letter-spacing: 0.011em;\n      line-height: 20px;\n    };\n\n    --paper-font-menu: {\n      @apply(--paper-font-common-base);\n      @apply(--paper-font-common-nowrap);\n\n      font-size: 13px;\n      font-weight: 500;\n      line-height: 24px;\n    };\n\n    --paper-font-button: {\n      @apply(--paper-font-common-base);\n      @apply(--paper-font-common-nowrap);\n\n      font-size: 14px;\n      font-weight: 500;\n      letter-spacing: 0.018em;\n      line-height: 24px;\n      text-transform: uppercase;\n    };\n\n    --paper-font-code2: {\n      @apply(--paper-font-common-code);\n\n      font-size: 14px;\n      font-weight: 700;\n      line-height: 20px;\n    };\n\n    --paper-font-code1: {\n      @apply(--paper-font-common-code);\n\n      font-size: 14px;\n      font-weight: 500;\n      line-height: 20px;\n    };\n\n  }\n\n</style><dom-module id=\"paper-input-char-counter\" assetpath=\"/paper-input/\">\n  <template>\n    <style>\n      :host {\n        display: inline-block;\n        float: right;\n\n        @apply(--paper-font-caption);\n        @apply(--paper-input-char-counter);\n      }\n\n      :host([hidden]) {\n        display: none !important;\n      }\n\n      :host-context([dir=\"rtl\"]) {\n        float: left;\n      }\n    </style>\n\n    <span>[[_charCounterStr]]</span>\n  </template>\n</dom-module>\n\n<style>\n  /* IE 10 support for HTML5 hidden attr */\n  [hidden] {\n    display: none !important;\n  }\n</style><style is=\"custom-style\">\n  :root {\n\n    --layout: {\n      display: -ms-flexbox;\n      display: -webkit-flex;\n      display: flex;\n    };\n\n    --layout-inline: {\n      display: -ms-inline-flexbox;\n      display: -webkit-inline-flex;\n      display: inline-flex;\n    };\n\n    --layout-horizontal: {\n      @apply(--layout);\n\n      -ms-flex-direction: row;\n      -webkit-flex-direction: row;\n      flex-direction: row;\n    };\n\n    --layout-horizontal-reverse: {\n      @apply(--layout);\n\n      -ms-flex-direction: row-reverse;\n      -webkit-flex-direction: row-reverse;\n      flex-direction: row-reverse;\n    };\n\n    --layout-vertical: {\n      @apply(--layout);\n\n      -ms-flex-direction: column;\n      -webkit-flex-direction: column;\n      flex-direction: column;\n    };\n\n    --layout-vertical-reverse: {\n      @apply(--layout);\n\n      -ms-flex-direction: column-reverse;\n      -webkit-flex-direction: column-reverse;\n      flex-direction: column-reverse;\n    };\n\n    --layout-wrap: {\n      -ms-flex-wrap: wrap;\n      -webkit-flex-wrap: wrap;\n      flex-wrap: wrap;\n    };\n\n    --layout-wrap-reverse: {\n      -ms-flex-wrap: wrap-reverse;\n      -webkit-flex-wrap: wrap-reverse;\n      flex-wrap: wrap-reverse;\n    };\n\n    --layout-flex-auto: {\n      -ms-flex: 1 1 auto;\n      -webkit-flex: 1 1 auto;\n      flex: 1 1 auto;\n    };\n\n    --layout-flex-none: {\n      -ms-flex: none;\n      -webkit-flex: none;\n      flex: none;\n    };\n\n    --layout-flex: {\n      -ms-flex: 1 1 0.000000001px;\n      -webkit-flex: 1;\n      flex: 1;\n      -webkit-flex-basis: 0.000000001px;\n      flex-basis: 0.000000001px;\n    };\n\n    --layout-flex-2: {\n      -ms-flex: 2;\n      -webkit-flex: 2;\n      flex: 2;\n    };\n\n    --layout-flex-3: {\n      -ms-flex: 3;\n      -webkit-flex: 3;\n      flex: 3;\n    };\n\n    --layout-flex-4: {\n      -ms-flex: 4;\n      -webkit-flex: 4;\n      flex: 4;\n    };\n\n    --layout-flex-5: {\n      -ms-flex: 5;\n      -webkit-flex: 5;\n      flex: 5;\n    };\n\n    --layout-flex-6: {\n      -ms-flex: 6;\n      -webkit-flex: 6;\n      flex: 6;\n    };\n\n    --layout-flex-7: {\n      -ms-flex: 7;\n      -webkit-flex: 7;\n      flex: 7;\n    };\n\n    --layout-flex-8: {\n      -ms-flex: 8;\n      -webkit-flex: 8;\n      flex: 8;\n    };\n\n    --layout-flex-9: {\n      -ms-flex: 9;\n      -webkit-flex: 9;\n      flex: 9;\n    };\n\n    --layout-flex-10: {\n      -ms-flex: 10;\n      -webkit-flex: 10;\n      flex: 10;\n    };\n\n    --layout-flex-11: {\n      -ms-flex: 11;\n      -webkit-flex: 11;\n      flex: 11;\n    };\n\n    --layout-flex-12: {\n      -ms-flex: 12;\n      -webkit-flex: 12;\n      flex: 12;\n    };\n\n    /* alignment in cross axis */\n\n    --layout-start: {\n      -ms-flex-align: start;\n      -webkit-align-items: flex-start;\n      align-items: flex-start;\n    };\n\n    --layout-center: {\n      -ms-flex-align: center;\n      -webkit-align-items: center;\n      align-items: center;\n    };\n\n    --layout-end: {\n      -ms-flex-align: end;\n      -webkit-align-items: flex-end;\n      align-items: flex-end;\n    };\n\n    /* alignment in main axis */\n\n    --layout-start-justified: {\n      -ms-flex-pack: start;\n      -webkit-justify-content: flex-start;\n      justify-content: flex-start;\n    };\n\n    --layout-center-justified: {\n      -ms-flex-pack: center;\n      -webkit-justify-content: center;\n      justify-content: center;\n    };\n\n    --layout-end-justified: {\n      -ms-flex-pack: end;\n      -webkit-justify-content: flex-end;\n      justify-content: flex-end;\n    };\n\n    --layout-around-justified: {\n      -ms-flex-pack: distribute;\n      -webkit-justify-content: space-around;\n      justify-content: space-around;\n    };\n\n    --layout-justified: {\n      -ms-flex-pack: justify;\n      -webkit-justify-content: space-between;\n      justify-content: space-between;\n    };\n\n    --layout-center-center: {\n      @apply(--layout-center);\n      @apply(--layout-center-justified);\n    };\n\n    /* self alignment */\n\n    --layout-self-start: {\n      -ms-align-self: flex-start;\n      -webkit-align-self: flex-start;\n      align-self: flex-start;\n    };\n\n    --layout-self-center: {\n      -ms-align-self: center;\n      -webkit-align-self: center;\n      align-self: center;\n    };\n\n    --layout-self-end: {\n      -ms-align-self: flex-end;\n      -webkit-align-self: flex-end;\n      align-self: flex-end;\n    };\n\n    --layout-self-stretch: {\n      -ms-align-self: stretch;\n      -webkit-align-self: stretch;\n      align-self: stretch;\n    };\n\n    /*******************************\n              Other Layout\n    *******************************/\n\n    --layout-block: {\n      display: block;\n    };\n\n    --layout-invisible: {\n      visibility: hidden !important;\n    };\n\n    --layout-relative: {\n      position: relative;\n    };\n\n    --layout-fit: {\n      position: absolute;\n      top: 0;\n      right: 0;\n      bottom: 0;\n      left: 0;\n    };\n\n    --layout-scroll: {\n      -webkit-overflow-scrolling: touch;\n      overflow: auto;\n    };\n\n    --layout-fullbleed: {\n      margin: 0;\n      height: 100vh;\n    };\n\n    /* fixed position */\n\n    --layout-fixed-top: {\n      position: fixed;\n      top: 0;\n      left: 0;\n      right: 0;\n    };\n\n    --layout-fixed-right: {\n      position: fixed;\n      top: 0;\n      right: 0;\n      bottom: 0;\n    };\n\n    --layout-fixed-bottom: {\n      position: fixed;\n      right: 0;\n      bottom: 0;\n      left: 0;\n    };\n\n    --layout-fixed-left: {\n      position: fixed;\n      top: 0;\n      bottom: 0;\n      left: 0;\n    };\n\n  }\n\n</style>\n\n<style is=\"custom-style\">\n\n  :root {\n\n    /* Material Design color palette for Google products */\n\n    --google-red-100: #f4c7c3;\n    --google-red-300: #e67c73;\n    --google-red-500: #db4437;\n    --google-red-700: #c53929;\n\n    --google-blue-100: #c6dafc;\n    --google-blue-300: #7baaf7;\n    --google-blue-500: #4285f4;\n    --google-blue-700: #3367d6;\n\n    --google-green-100: #b7e1cd;\n    --google-green-300: #57bb8a;\n    --google-green-500: #0f9d58;\n    --google-green-700: #0b8043;\n\n    --google-yellow-100: #fce8b2;\n    --google-yellow-300: #f7cb4d;\n    --google-yellow-500: #f4b400;\n    --google-yellow-700: #f09300;\n\n    --google-grey-100: #f5f5f5;\n    --google-grey-300: #e0e0e0;\n    --google-grey-500: #9e9e9e;\n    --google-grey-700: #616161;\n    \n    /* Material Design color palette from online spec document */\n\n    --paper-red-50: #ffebee;\n    --paper-red-100: #ffcdd2;\n    --paper-red-200: #ef9a9a;\n    --paper-red-300: #e57373;\n    --paper-red-400: #ef5350;\n    --paper-red-500: #f44336;\n    --paper-red-600: #e53935;\n    --paper-red-700: #d32f2f;\n    --paper-red-800: #c62828;\n    --paper-red-900: #b71c1c;\n    --paper-red-a100: #ff8a80;\n    --paper-red-a200: #ff5252;\n    --paper-red-a400: #ff1744;\n    --paper-red-a700: #d50000;\n \n    --paper-pink-50: #fce4ec;\n    --paper-pink-100: #f8bbd0;\n    --paper-pink-200: #f48fb1;\n    --paper-pink-300: #f06292;\n    --paper-pink-400: #ec407a;\n    --paper-pink-500: #e91e63;\n    --paper-pink-600: #d81b60;\n    --paper-pink-700: #c2185b;\n    --paper-pink-800: #ad1457;\n    --paper-pink-900: #880e4f;\n    --paper-pink-a100: #ff80ab;\n    --paper-pink-a200: #ff4081;\n    --paper-pink-a400: #f50057;\n    --paper-pink-a700: #c51162;\n \n    --paper-purple-50: #f3e5f5;\n    --paper-purple-100: #e1bee7;\n    --paper-purple-200: #ce93d8;\n    --paper-purple-300: #ba68c8;\n    --paper-purple-400: #ab47bc;\n    --paper-purple-500: #9c27b0;\n    --paper-purple-600: #8e24aa;\n    --paper-purple-700: #7b1fa2;\n    --paper-purple-800: #6a1b9a;\n    --paper-purple-900: #4a148c;\n    --paper-purple-a100: #ea80fc;\n    --paper-purple-a200: #e040fb;\n    --paper-purple-a400: #d500f9;\n    --paper-purple-a700: #aa00ff;\n \n    --paper-deep-purple-50: #ede7f6;\n    --paper-deep-purple-100: #d1c4e9;\n    --paper-deep-purple-200: #b39ddb;\n    --paper-deep-purple-300: #9575cd;\n    --paper-deep-purple-400: #7e57c2;\n    --paper-deep-purple-500: #673ab7;\n    --paper-deep-purple-600: #5e35b1;\n    --paper-deep-purple-700: #512da8;\n    --paper-deep-purple-800: #4527a0;\n    --paper-deep-purple-900: #311b92;\n    --paper-deep-purple-a100: #b388ff;\n    --paper-deep-purple-a200: #7c4dff;\n    --paper-deep-purple-a400: #651fff;\n    --paper-deep-purple-a700: #6200ea;\n \n    --paper-indigo-50: #e8eaf6;\n    --paper-indigo-100: #c5cae9;\n    --paper-indigo-200: #9fa8da;\n    --paper-indigo-300: #7986cb;\n    --paper-indigo-400: #5c6bc0;\n    --paper-indigo-500: #3f51b5;\n    --paper-indigo-600: #3949ab;\n    --paper-indigo-700: #303f9f;\n    --paper-indigo-800: #283593;\n    --paper-indigo-900: #1a237e;\n    --paper-indigo-a100: #8c9eff;\n    --paper-indigo-a200: #536dfe;\n    --paper-indigo-a400: #3d5afe;\n    --paper-indigo-a700: #304ffe;\n \n    --paper-blue-50: #e3f2fd;\n    --paper-blue-100: #bbdefb;\n    --paper-blue-200: #90caf9;\n    --paper-blue-300: #64b5f6;\n    --paper-blue-400: #42a5f5;\n    --paper-blue-500: #2196f3;\n    --paper-blue-600: #1e88e5;\n    --paper-blue-700: #1976d2;\n    --paper-blue-800: #1565c0;\n    --paper-blue-900: #0d47a1;\n    --paper-blue-a100: #82b1ff;\n    --paper-blue-a200: #448aff;\n    --paper-blue-a400: #2979ff;\n    --paper-blue-a700: #2962ff;\n \n    --paper-light-blue-50: #e1f5fe;\n    --paper-light-blue-100: #b3e5fc;\n    --paper-light-blue-200: #81d4fa;\n    --paper-light-blue-300: #4fc3f7;\n    --paper-light-blue-400: #29b6f6;\n    --paper-light-blue-500: #03a9f4;\n    --paper-light-blue-600: #039be5;\n    --paper-light-blue-700: #0288d1;\n    --paper-light-blue-800: #0277bd;\n    --paper-light-blue-900: #01579b;\n    --paper-light-blue-a100: #80d8ff;\n    --paper-light-blue-a200: #40c4ff;\n    --paper-light-blue-a400: #00b0ff;\n    --paper-light-blue-a700: #0091ea;\n \n    --paper-cyan-50: #e0f7fa;\n    --paper-cyan-100: #b2ebf2;\n    --paper-cyan-200: #80deea;\n    --paper-cyan-300: #4dd0e1;\n    --paper-cyan-400: #26c6da;\n    --paper-cyan-500: #00bcd4;\n    --paper-cyan-600: #00acc1;\n    --paper-cyan-700: #0097a7;\n    --paper-cyan-800: #00838f;\n    --paper-cyan-900: #006064;\n    --paper-cyan-a100: #84ffff;\n    --paper-cyan-a200: #18ffff;\n    --paper-cyan-a400: #00e5ff;\n    --paper-cyan-a700: #00b8d4;\n \n    --paper-teal-50: #e0f2f1;\n    --paper-teal-100: #b2dfdb;\n    --paper-teal-200: #80cbc4;\n    --paper-teal-300: #4db6ac;\n    --paper-teal-400: #26a69a;\n    --paper-teal-500: #009688;\n    --paper-teal-600: #00897b;\n    --paper-teal-700: #00796b;\n    --paper-teal-800: #00695c;\n    --paper-teal-900: #004d40;\n    --paper-teal-a100: #a7ffeb;\n    --paper-teal-a200: #64ffda;\n    --paper-teal-a400: #1de9b6;\n    --paper-teal-a700: #00bfa5;\n \n    --paper-green-50: #e8f5e9;\n    --paper-green-100: #c8e6c9;\n    --paper-green-200: #a5d6a7;\n    --paper-green-300: #81c784;\n    --paper-green-400: #66bb6a;\n    --paper-green-500: #4caf50;\n    --paper-green-600: #43a047;\n    --paper-green-700: #388e3c;\n    --paper-green-800: #2e7d32;\n    --paper-green-900: #1b5e20;\n    --paper-green-a100: #b9f6ca;\n    --paper-green-a200: #69f0ae;\n    --paper-green-a400: #00e676;\n    --paper-green-a700: #00c853;\n \n    --paper-light-green-50: #f1f8e9;\n    --paper-light-green-100: #dcedc8;\n    --paper-light-green-200: #c5e1a5;\n    --paper-light-green-300: #aed581;\n    --paper-light-green-400: #9ccc65;\n    --paper-light-green-500: #8bc34a;\n    --paper-light-green-600: #7cb342;\n    --paper-light-green-700: #689f38;\n    --paper-light-green-800: #558b2f;\n    --paper-light-green-900: #33691e;\n    --paper-light-green-a100: #ccff90;\n    --paper-light-green-a200: #b2ff59;\n    --paper-light-green-a400: #76ff03;\n    --paper-light-green-a700: #64dd17;\n \n    --paper-lime-50: #f9fbe7;\n    --paper-lime-100: #f0f4c3;\n    --paper-lime-200: #e6ee9c;\n    --paper-lime-300: #dce775;\n    --paper-lime-400: #d4e157;\n    --paper-lime-500: #cddc39;\n    --paper-lime-600: #c0ca33;\n    --paper-lime-700: #afb42b;\n    --paper-lime-800: #9e9d24;\n    --paper-lime-900: #827717;\n    --paper-lime-a100: #f4ff81;\n    --paper-lime-a200: #eeff41;\n    --paper-lime-a400: #c6ff00;\n    --paper-lime-a700: #aeea00;\n \n    --paper-yellow-50: #fffde7;\n    --paper-yellow-100: #fff9c4;\n    --paper-yellow-200: #fff59d;\n    --paper-yellow-300: #fff176;\n    --paper-yellow-400: #ffee58;\n    --paper-yellow-500: #ffeb3b;\n    --paper-yellow-600: #fdd835;\n    --paper-yellow-700: #fbc02d;\n    --paper-yellow-800: #f9a825;\n    --paper-yellow-900: #f57f17;\n    --paper-yellow-a100: #ffff8d;\n    --paper-yellow-a200: #ffff00;\n    --paper-yellow-a400: #ffea00;\n    --paper-yellow-a700: #ffd600;\n \n    --paper-amber-50: #fff8e1;\n    --paper-amber-100: #ffecb3;\n    --paper-amber-200: #ffe082;\n    --paper-amber-300: #ffd54f;\n    --paper-amber-400: #ffca28;\n    --paper-amber-500: #ffc107;\n    --paper-amber-600: #ffb300;\n    --paper-amber-700: #ffa000;\n    --paper-amber-800: #ff8f00;\n    --paper-amber-900: #ff6f00;\n    --paper-amber-a100: #ffe57f;\n    --paper-amber-a200: #ffd740;\n    --paper-amber-a400: #ffc400;\n    --paper-amber-a700: #ffab00;\n \n    --paper-orange-50: #fff3e0;\n    --paper-orange-100: #ffe0b2;\n    --paper-orange-200: #ffcc80;\n    --paper-orange-300: #ffb74d;\n    --paper-orange-400: #ffa726;\n    --paper-orange-500: #ff9800;\n    --paper-orange-600: #fb8c00;\n    --paper-orange-700: #f57c00;\n    --paper-orange-800: #ef6c00;\n    --paper-orange-900: #e65100;\n    --paper-orange-a100: #ffd180;\n    --paper-orange-a200: #ffab40;\n    --paper-orange-a400: #ff9100;\n    --paper-orange-a700: #ff6500;\n \n    --paper-deep-orange-50: #fbe9e7;\n    --paper-deep-orange-100: #ffccbc;\n    --paper-deep-orange-200: #ffab91;\n    --paper-deep-orange-300: #ff8a65;\n    --paper-deep-orange-400: #ff7043;\n    --paper-deep-orange-500: #ff5722;\n    --paper-deep-orange-600: #f4511e;\n    --paper-deep-orange-700: #e64a19;\n    --paper-deep-orange-800: #d84315;\n    --paper-deep-orange-900: #bf360c;\n    --paper-deep-orange-a100: #ff9e80;\n    --paper-deep-orange-a200: #ff6e40;\n    --paper-deep-orange-a400: #ff3d00;\n    --paper-deep-orange-a700: #dd2c00;\n \n    --paper-brown-50: #efebe9;\n    --paper-brown-100: #d7ccc8;\n    --paper-brown-200: #bcaaa4;\n    --paper-brown-300: #a1887f;\n    --paper-brown-400: #8d6e63;\n    --paper-brown-500: #795548;\n    --paper-brown-600: #6d4c41;\n    --paper-brown-700: #5d4037;\n    --paper-brown-800: #4e342e;\n    --paper-brown-900: #3e2723;\n \n    --paper-grey-50: #fafafa;\n    --paper-grey-100: #f5f5f5;\n    --paper-grey-200: #eeeeee;\n    --paper-grey-300: #e0e0e0;\n    --paper-grey-400: #bdbdbd;\n    --paper-grey-500: #9e9e9e;\n    --paper-grey-600: #757575;\n    --paper-grey-700: #616161;\n    --paper-grey-800: #424242;\n    --paper-grey-900: #212121;\n \n    --paper-blue-grey-50: #eceff1;\n    --paper-blue-grey-100: #cfd8dc;\n    --paper-blue-grey-200: #b0bec5;\n    --paper-blue-grey-300: #90a4ae;\n    --paper-blue-grey-400: #78909c;\n    --paper-blue-grey-500: #607d8b;\n    --paper-blue-grey-600: #546e7a;\n    --paper-blue-grey-700: #455a64;\n    --paper-blue-grey-800: #37474f;\n    --paper-blue-grey-900: #263238;\n\n    /* opacity for dark text on a light background */\n    --dark-divider-opacity: 0.12;\n    --dark-disabled-opacity: 0.38; /* or hint text or icon */\n    --dark-secondary-opacity: 0.54;\n    --dark-primary-opacity: 0.87;\n\n    /* opacity for light text on a dark background */\n    --light-divider-opacity: 0.12;\n    --light-disabled-opacity: 0.3; /* or hint text or icon */\n    --light-secondary-opacity: 0.7;\n    --light-primary-opacity: 1.0;\n\n  }\n\n</style><style is=\"custom-style\">\n\n  :root {\n    /*\n     * You can use these generic variables in your elements for easy theming.\n     * For example, if all your elements use `--primary-text-color` as its main\n     * color, then switching from a light to a dark theme is just a matter of\n     * changing the value of `--primary-text-color` in your application.\n     */\n    --primary-text-color: var(--light-theme-text-color);\n    --primary-background-color: var(--light-theme-background-color);\n    --secondary-text-color: var(--light-theme-secondary-color);\n    --disabled-text-color: var(--light-theme-disabled-color);\n    --divider-color: var(--light-theme-divider-color);\n    --error-color: var(--paper-deep-orange-a700);\n\n    /*\n     * Primary and accent colors. Also see color.html for more colors.\n     */\n    --primary-color: var(--paper-indigo-500);\n    --light-primary-color: var(--paper-indigo-100);\n    --dark-primary-color: var(--paper-indigo-700);\n\n    --accent-color: var(--paper-pink-a200);\n    --light-accent-color: var(--paper-pink-a100);\n    --dark-accent-color: var(--paper-pink-a400);\n\n\n    /*\n     * Material Design Light background theme\n     */\n    --light-theme-background-color: #ffffff;\n    --light-theme-base-color: #000000;\n    --light-theme-text-color: var(--paper-grey-900);\n    --light-theme-secondary-color: #737373;  /* for secondary text and icons */\n    --light-theme-disabled-color: #9b9b9b;  /* disabled/hint text */\n    --light-theme-divider-color: #dbdbdb;\n\n    /*\n     * Material Design Dark background theme\n     */\n    --dark-theme-background-color: var(--paper-grey-900);\n    --dark-theme-base-color: #ffffff;\n    --dark-theme-text-color: #ffffff;\n    --dark-theme-secondary-color: #bcbcbc;  /* for secondary text and icons */\n    --dark-theme-disabled-color: #646464;  /* disabled/hint text */\n    --dark-theme-divider-color: #3c3c3c;\n\n    /*\n     * Deprecated values because of their confusing names.\n     */\n    --text-primary-color: var(--dark-theme-text-color);\n    --default-primary-color: var(--primary-color);\n\n  }\n\n</style><dom-module id=\"paper-input-container\" assetpath=\"/paper-input/\">\n  <template>\n    <style>\n      :host {\n        display: block;\n        padding: 8px 0;\n\n        @apply(--paper-input-container);\n      }\n\n      :host([inline]) {\n        display: inline-block;\n      }\n\n      :host([disabled]) {\n        pointer-events: none;\n        opacity: 0.33;\n\n        @apply(--paper-input-container-disabled);\n      }\n\n      :host([hidden]) {\n        display: none !important;\n      }\n\n      .floated-label-placeholder {\n        @apply(--paper-font-caption);\n      }\n\n      .underline {\n        position: relative;\n      }\n\n      .focused-line {\n        @apply(--layout-fit);\n\n        background: var(--paper-input-container-focus-color, --primary-color);\n        height: 2px;\n\n        -webkit-transform-origin: center center;\n        transform-origin: center center;\n        -webkit-transform: scale3d(0,1,1);\n        transform: scale3d(0,1,1);\n\n        @apply(--paper-input-container-underline-focus);\n      }\n\n      .underline.is-highlighted .focused-line {\n        -webkit-transform: none;\n        transform: none;\n        -webkit-transition: -webkit-transform 0.25s;\n        transition: transform 0.25s;\n\n        @apply(--paper-transition-easing);\n      }\n\n      .underline.is-invalid .focused-line {\n        background: var(--paper-input-container-invalid-color, --error-color);\n        -webkit-transform: none;\n        transform: none;\n        -webkit-transition: -webkit-transform 0.25s;\n        transition: transform 0.25s;\n\n        @apply(--paper-transition-easing);\n      }\n\n      .unfocused-line {\n        @apply(--layout-fit);\n\n        background: var(--paper-input-container-color, --secondary-text-color);\n        height: 1px;\n\n        @apply(--paper-input-container-underline);\n      }\n\n      :host([disabled]) .unfocused-line {\n        border-bottom: 1px dashed;\n        border-color: var(--paper-input-container-color, --secondary-text-color);\n        background: transparent;\n\n        @apply(--paper-input-container-underline-disabled);\n      }\n\n      .label-and-input-container {\n        @apply(--layout-flex-auto);\n        @apply(--layout-relative);\n\n        width: 100%;\n        max-width: 100%;\n      }\n\n      .input-content {\n        @apply(--layout-horizontal);\n        @apply(--layout-center);\n\n        position: relative;\n      }\n\n      .input-content ::content label,\n      .input-content ::content .paper-input-label {\n        position: absolute;\n        top: 0;\n        right: 0;\n        left: 0;\n        width: 100%;\n        font: inherit;\n        color: var(--paper-input-container-color, --secondary-text-color);\n        -webkit-transition: -webkit-transform 0.25s, width 0.25s;\n        transition: transform 0.25s, width 0.25s;\n        -webkit-transform-origin: left top;\n        transform-origin: left top;\n\n        @apply(--paper-font-common-nowrap);\n        @apply(--paper-font-subhead);\n        @apply(--paper-input-container-label);\n        @apply(--paper-transition-easing);\n      }\n\n      .input-content.label-is-floating ::content label,\n      .input-content.label-is-floating ::content .paper-input-label {\n        -webkit-transform: translateY(-75%) scale(0.75);\n        transform: translateY(-75%) scale(0.75);\n\n        /* Since we scale to 75/100 of the size, we actually have 100/75 of the\n        original space now available */\n        width: 133%;\n\n        @apply(--paper-input-container-label-floating);\n      }\n\n      :host-context([dir=\"rtl\"]) .input-content.label-is-floating ::content label,\n      :host-context([dir=\"rtl\"]) .input-content.label-is-floating ::content .paper-input-label {\n        /* TODO(noms): Figure out why leaving the width at 133% before the animation\n         * actually makes\n         * it wider on the right side, not left side, as you would expect in RTL */\n        width: 100%;\n        -webkit-transform-origin: right top;\n        transform-origin: right top;\n      }\n\n      .input-content.label-is-highlighted ::content label,\n      .input-content.label-is-highlighted ::content .paper-input-label {\n        color: var(--paper-input-container-focus-color, --primary-color);\n\n        @apply(--paper-input-container-label-focus);\n      }\n\n      .input-content.is-invalid ::content label,\n      .input-content.is-invalid ::content .paper-input-label {\n        color: var(--paper-input-container-invalid-color, --error-color);\n      }\n\n      .input-content.label-is-hidden ::content label,\n      .input-content.label-is-hidden ::content .paper-input-label {\n        visibility: hidden;\n      }\n\n      .input-content ::content input,\n      .input-content ::content textarea,\n      .input-content ::content iron-autogrow-textarea,\n      .input-content ::content .paper-input-input {\n        position: relative; /* to make a stacking context */\n        outline: none;\n        box-shadow: none;\n        padding: 0;\n        width: 100%;\n        max-width: 100%;\n        background: transparent;\n        border: none;\n        color: var(--paper-input-container-input-color, --primary-text-color);\n        -webkit-appearance: none;\n        text-align: inherit;\n\n        @apply(--paper-font-subhead);\n        @apply(--paper-input-container-input);\n      }\n\n      ::content [prefix] {\n        @apply(--paper-font-subhead);\n\n        @apply(--paper-input-prefix);\n        @apply(--layout-flex-none);\n      }\n\n      ::content [suffix] {\n        @apply(--paper-font-subhead);\n\n        @apply(--paper-input-suffix);\n        @apply(--layout-flex-none);\n      }\n\n      /* Firefox sets a min-width on the input, which can cause layout issues */\n      .input-content ::content input {\n        min-width: 0;\n      }\n\n      .input-content ::content textarea {\n        resize: none;\n      }\n\n      .add-on-content {\n        position: relative;\n      }\n\n      .add-on-content.is-invalid ::content * {\n        color: var(--paper-input-container-invalid-color, --error-color);\n      }\n\n      .add-on-content.is-highlighted ::content * {\n        color: var(--paper-input-container-focus-color, --primary-color);\n      }\n    </style>\n\n    <template is=\"dom-if\" if=\"[[!noLabelFloat]]\">\n      <div class=\"floated-label-placeholder\" aria-hidden=\"true\">&nbsp;</div>\n    </template>\n\n    <div class$=\"[[X_(noLabelFloat,alwaysFloatLabel,focused,invalid,_inputHasContent)]]\">\n      <content select=\"[prefix]\" id=\"prefix\"></content>\n\n      <div class=\"label-and-input-container\" id=\"labelAndInputContainer\">\n        <content select=\":not([add-on]):not([prefix]):not([suffix])\"></content>\n      </div>\n\n      <content select=\"[suffix]\"></content>\n    </div>\n\n    <div class$=\"[[b0(focused,invalid)]]\">\n      <div class=\"unfocused-line\"></div>\n      <div class=\"focused-line\"></div>\n    </div>\n\n    <div class$=\"[[P_(focused,invalid)]]\">\n      <content id=\"addOnContent\" select=\"[add-on]\"></content>\n    </div>\n  </template>\n</dom-module>\n\n<dom-module id=\"paper-input-error\" assetpath=\"/paper-input/\">\n  <template>\n    <style>\n      :host {\n        display: inline-block;\n        visibility: hidden;\n\n        color: var(--paper-input-container-invalid-color, --error-color);\n\n        @apply(--paper-font-caption);\n        @apply(--paper-input-error);\n        position: absolute;\n        left:0;\n        right:0;\n      }\n\n      :host([invalid]) {\n        visibility: visible;\n      };\n    </style>\n\n    <content></content>\n  </template>\n</dom-module>\n\n<dom-module id=\"paper-input\" assetpath=\"/paper-input/\">\n  <template>\n    <style>\n      :host {\n        display: block;\n      }\n\n      :host([focused]) {\n        outline: none;\n      }\n\n      :host([hidden]) {\n        display: none !important;\n      }\n\n      input::-webkit-input-placeholder {\n        color: var(--paper-input-container-color, --secondary-text-color);\n      }\n\n      input:-moz-placeholder {\n        color: var(--paper-input-container-color, --secondary-text-color);\n      }\n\n      input::-moz-placeholder {\n        color: var(--paper-input-container-color, --secondary-text-color);\n      }\n\n      input:-ms-input-placeholder {\n        color: var(--paper-input-container-color, --secondary-text-color);\n      }\n\n      label {\n        pointer-events: none;\n      }\n    </style>\n\n    <paper-input-container no-label-float=\"[[noLabelFloat]]\" always-float-label=\"[[Q_(alwaysFloatLabel,placeholder)]]\" auto-validate$=\"[[autoValidate]]\" disabled$=\"[[disabled]]\" invalid=\"[[invalid]]\">\n\n      <content select=\"[prefix]\"></content>\n\n      <label hidden$=\"[[!label]]\" aria-hidden=\"true\" for=\"input\">[[label]]</label>\n\n      <input is=\"iron-input\" id=\"input\" aria-labelledby$=\"[[_ariaLabelledBy]]\" aria-describedby$=\"[[_ariaDescribedBy]]\" disabled$=\"[[disabled]]\" title$=\"[[title]]\" bind-value=\"{{value}}\" invalid=\"{{invalid}}\" prevent-invalid-input=\"[[preventInvalidInput]]\" allowed-pattern=\"[[allowedPattern]]\" validator=\"[[validator]]\" type$=\"[[type]]\" pattern$=\"[[pattern]]\" required$=\"[[required]]\" autocomplete$=\"[[autocomplete]]\" autofocus$=\"[[autofocus]]\" inputmode$=\"[[inputmode]]\" minlength$=\"[[minlength]]\" maxlength$=\"[[maxlength]]\" min$=\"[[min]]\" max$=\"[[max]]\" step$=\"[[step]]\" name$=\"[[name]]\" placeholder$=\"[[placeholder]]\" readonly$=\"[[readonly]]\" list$=\"[[list]]\" size$=\"[[size]]\" autocapitalize$=\"[[autocapitalize]]\" autocorrect$=\"[[autocorrect]]\" on-change=\"J0\" tabindex$=\"[[tabindex]]\" autosave$=\"[[autosave]]\" results$=\"[[results]]\" accept$=\"[[accept]]\" multiple$=\"[[multiple]]\">\n\n      <content select=\"[suffix]\"></content>\n\n      <template is=\"dom-if\" if=\"[[errorMessage]]\">\n        <paper-input-error aria-live=\"assertive\">[[errorMessage]]</paper-input-error>\n      </template>\n\n      <template is=\"dom-if\" if=\"[[charCounter]]\">\n        <paper-input-char-counter></paper-input-char-counter>\n      </template>\n\n    </paper-input-container>\n  </template>\n</dom-module>\n\n<dom-module id=\"iron-icon\" assetpath=\"/iron-icon/\">\n  <template>\n    <style>\n      :host {\n        @apply(--layout-inline);\n        @apply(--layout-center-center);\n        position: relative;\n\n        vertical-align: middle;\n\n        fill: var(--iron-icon-fill-color, currentcolor);\n        stroke: var(--iron-icon-stroke-color, none);\n\n        width: var(--iron-icon-width, 24px);\n        height: var(--iron-icon-height, 24px);\n        @apply(--iron-icon);\n      }\n    </style>\n  </template>\n\n  </dom-module>\n\n\n\n\n<dom-module id=\"iron-overlay-backdrop\" assetpath=\"/iron-overlay-behavior/\">\n\n  <template>\n    <style>\n      :host {\n        position: fixed;\n        top: 0;\n        left: 0;\n        width: 100%;\n        height: 100%;\n        background-color: var(--iron-overlay-backdrop-background-color, #000);\n        opacity: 0;\n        transition: opacity 0.2s;\n        pointer-events: none;\n        @apply(--iron-overlay-backdrop);\n      }\n\n      :host(.opened) {\n        opacity: var(--iron-overlay-backdrop-opacity, 0.6);\n        pointer-events: auto;\n        @apply(--iron-overlay-backdrop-opened);\n      }\n    </style>\n\n    <content></content>\n  </template>\n\n</dom-module>\n\n<dom-module id=\"iron-dropdown\" assetpath=\"/iron-dropdown/\">\n  <template>\n    <style>\n      :host {\n        position: fixed;\n      }\n\n      #contentWrapper ::content > * {\n        overflow: auto;\n      }\n\n      #contentWrapper.animating ::content > * {\n        overflow: hidden;\n      }\n    </style>\n\n    <div id=\"contentWrapper\">\n      <content id=\"content\" select=\".dropdown-content\"></content>\n    </div>\n  </template>\n\n  </dom-module>\n\n\n<style is=\"custom-style\">\n\n  :root {\n\n    --shadow-transition: {\n      transition: box-shadow 0.28s cubic-bezier(0.4, 0, 0.2, 1);\n    };\n\n    --shadow-none: {\n      box-shadow: none;\n    };\n\n    /* from http://codepen.io/shyndman/pen/c5394ddf2e8b2a5c9185904b57421cdb */\n\n    --shadow-elevation-2dp: {\n      box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14),\n                  0 1px 5px 0 rgba(0, 0, 0, 0.12),\n                  0 3px 1px -2px rgba(0, 0, 0, 0.2);\n    };\n\n    --shadow-elevation-3dp: {\n      box-shadow: 0 3px 4px 0 rgba(0, 0, 0, 0.14),\n                  0 1px 8px 0 rgba(0, 0, 0, 0.12),\n                  0 3px 3px -2px rgba(0, 0, 0, 0.4);\n    };\n\n    --shadow-elevation-4dp: {\n      box-shadow: 0 4px 5px 0 rgba(0, 0, 0, 0.14),\n                  0 1px 10px 0 rgba(0, 0, 0, 0.12),\n                  0 2px 4px -1px rgba(0, 0, 0, 0.4);\n    };\n\n    --shadow-elevation-6dp: {\n      box-shadow: 0 6px 10px 0 rgba(0, 0, 0, 0.14),\n                  0 1px 18px 0 rgba(0, 0, 0, 0.12),\n                  0 3px 5px -1px rgba(0, 0, 0, 0.4);\n    };\n\n    --shadow-elevation-8dp: {\n      box-shadow: 0 8px 10px 1px rgba(0, 0, 0, 0.14),\n                  0 3px 14px 2px rgba(0, 0, 0, 0.12),\n                  0 5px 5px -3px rgba(0, 0, 0, 0.4);\n    };\n\n    --shadow-elevation-12dp: {\n      box-shadow: 0 12px 16px 1px rgba(0, 0, 0, 0.14),\n                  0 4px 22px 3px rgba(0, 0, 0, 0.12),\n                  0 6px 7px -4px rgba(0, 0, 0, 0.4);\n    };\n\n    --shadow-elevation-16dp: {\n      box-shadow: 0 16px 24px 2px rgba(0, 0, 0, 0.14),\n                  0  6px 30px 5px rgba(0, 0, 0, 0.12),\n                  0  8px 10px -5px rgba(0, 0, 0, 0.4);\n    };\n\n  }\n\n</style><dom-module id=\"paper-menu-button\" assetpath=\"/paper-menu-button/\">\n  <template>\n    <style>\n      :host {\n        display: inline-block;\n        position: relative;\n        padding: 8px;\n        outline: none;\n\n        @apply(--paper-menu-button);\n      }\n\n      :host([disabled]) {\n        cursor: auto;\n        color: var(--disabled-text-color);\n\n        @apply(--paper-menu-button-disabled);\n      }\n\n      iron-dropdown {\n        @apply(--paper-menu-button-dropdown);\n      }\n\n      .dropdown-content {\n        @apply(--shadow-elevation-2dp);\n\n        position: relative;\n        border-radius: 2px;\n        background-color: var(--paper-menu-button-dropdown-background, --primary-background-color);\n\n        @apply(--paper-menu-button-content);\n      }\n\n      :host([vertical-align=\"top\"]) .dropdown-content {\n        margin-bottom: 20px;\n        margin-top: -10px;\n        top: 10px;\n      }\n\n      :host([vertical-align=\"bottom\"]) .dropdown-content {\n        bottom: 10px;\n        margin-bottom: -10px;\n        margin-top: 20px;\n      }\n    </style>\n\n    <div id=\"trigger\" on-tap=\"toggle\">\n      <content select=\".dropdown-trigger\"></content>\n    </div>\n\n    <iron-dropdown id=\"dropdown\" opened=\"{{opened}}\" horizontal-align=\"[[horizontalAlign]]\" vertical-align=\"[[verticalAlign]]\" dynamic-align=\"[[dynamicAlign]]\" horizontal-offset=\"[[horizontalOffset]]\" vertical-offset=\"[[verticalOffset]]\" no-overlap=\"[[noOverlap]]\" open-animation-config=\"[[openAnimationConfig]]\" close-animation-config=\"[[closeAnimationConfig]]\" no-animations=\"[[noAnimations]]\" focus-target=\"[[_dropdownContent]]\" allow-outside-scroll=\"[[allowOutsideScroll]]\" restore-focus-on-close=\"[[restoreFocusOnClose]]\" on-iron-overlay-canceled=\"B_\">\n      <div class=\"dropdown-content\">\n        <content id=\"content\" select=\".dropdown-content\"></content>\n      </div>\n    </iron-dropdown>\n  </template>\n\n  </dom-module>\n\n\n<dom-module id=\"paper-ripple\" assetpath=\"/paper-ripple/\">\n\n  \n\n  <template>\n    <style>\n      :host {\n        display: block;\n        position: absolute;\n        border-radius: inherit;\n        overflow: hidden;\n        top: 0;\n        left: 0;\n        right: 0;\n        bottom: 0;\n\n        /* See PolymerElements/paper-behaviors/issues/34. On non-Chrome browsers,\n         * creating a node (with a position:absolute) in the middle of an event\n         * handler \"interrupts\" that event handler (which happens when the\n         * ripple is created on demand) */\n        pointer-events: none;\n      }\n\n      :host([animating]) {\n        /* This resolves a rendering issue in Chrome (as of 40) where the\n           ripple is not properly clipped by its parent (which may have\n           rounded corners). See: http://jsbin.com/temexa/4\n\n           Note: We only apply this style conditionally. Otherwise, the browser\n           will create a new compositing layer for every ripple element on the\n           page, and that would be bad. */\n        -webkit-transform: translate(0, 0);\n        transform: translate3d(0, 0, 0);\n      }\n\n      #background,\n      #waves,\n      .wave-container,\n      .wave {\n        pointer-events: none;\n        position: absolute;\n        top: 0;\n        left: 0;\n        width: 100%;\n        height: 100%;\n      }\n\n      #background,\n      .wave {\n        opacity: 0;\n      }\n\n      #waves,\n      .wave {\n        overflow: hidden;\n      }\n\n      .wave-container,\n      .wave {\n        border-radius: 50%;\n      }\n\n      :host(.circle) #background,\n      :host(.circle) #waves {\n        border-radius: 50%;\n      }\n\n      :host(.circle) .wave-container {\n        overflow: hidden;\n      }\n    </style>\n\n    <div id=\"background\"></div>\n    <div id=\"waves\"></div>\n  </template>\n</dom-module>\n<iron-iconset-svg name=\"paper-dropdown-menu\" size=\"24\">\n<svg><defs>\n<g id=\"arrow-drop-down\"><path d=\"M7 10l5 5 5-5z\"></path></g>\n</defs></svg>\n</iron-iconset-svg>\n<dom-module id=\"paper-dropdown-menu-shared-styles\" assetpath=\"/paper-dropdown-menu/\">\n  <template>\n    <style>\n      :host {\n        display: inline-block;\n        position: relative;\n        text-align: left;\n\n        /* NOTE(cdata): Both values are needed, since some phones require the\n         * value to be `transparent`.\n         */\n        -webkit-tap-highlight-color: rgba(0,0,0,0);\n        -webkit-tap-highlight-color: transparent;\n\n        --paper-input-container-input: {\n          overflow: hidden;\n          white-space: nowrap;\n          text-overflow: ellipsis;\n          max-width: 100%;\n          box-sizing: border-box;\n          cursor: pointer;\n        };\n\n        @apply(--paper-dropdown-menu);\n      }\n\n      :host([disabled]) {\n        @apply(--paper-dropdown-menu-disabled);\n      }\n\n      :host([noink]) paper-ripple {\n        display: none;\n      }\n\n      :host([no-label-float]) paper-ripple {\n        top: 8px;\n      }\n\n      paper-ripple {\n        top: 12px;\n        left: 0px;\n        bottom: 8px;\n        right: 0px;\n\n        @apply(--paper-dropdown-menu-ripple);\n      }\n\n      paper-menu-button {\n        display: block;\n        padding: 0;\n\n        @apply(--paper-dropdown-menu-button);\n      }\n\n      paper-input {\n        @apply(--paper-dropdown-menu-input);\n      }\n\n      iron-icon {\n        color: var(--disabled-text-color);\n\n        @apply(--paper-dropdown-menu-icon);\n      }\n    </style>\n  </template>\n</dom-module>\n<dom-module id=\"paper-dropdown-menu\" assetpath=\"/paper-dropdown-menu/\">\n  <template>\n    <style include=\"paper-dropdown-menu-shared-styles\"></style>\n\n    \n    <span role=\"button\"></span>\n    <paper-menu-button id=\"menuButton\" vertical-align=\"[[verticalAlign]]\" horizontal-align=\"[[horizontalAlign]]\" dynamic-align=\"[[dynamicAlign]]\" vertical-offset=\"[[qF(noLabelFloat)]]\" disabled=\"[[disabled]]\" no-animations=\"[[noAnimations]]\" on-iron-select=\"Zv\" on-iron-deselect=\"xG\" opened=\"{{opened}}\" close-on-activate=\"\" allow-outside-scroll=\"[[allowOutsideScroll]]\" restore-focus-on-close=\"[[restoreFocusOnClose]]\">\n      <div class=\"dropdown-trigger\">\n        <paper-ripple></paper-ripple>\n        \n        <paper-input type=\"text\" invalid=\"[[invalid]]\" readonly disabled=\"[[disabled]]\" value=\"[[selectedItemLabel]]\" placeholder=\"[[placeholder]]\" error-message=\"[[errorMessage]]\" always-float-label=\"[[alwaysFloatLabel]]\" no-label-float=\"[[noLabelFloat]]\" label=\"[[label]]\">\n          <iron-icon icon=\"paper-dropdown-menu:arrow-drop-down\" suffix=\"\"></iron-icon>\n        </paper-input>\n      </div>\n      <content id=\"content\" select=\".dropdown-content\"></content>\n    </paper-menu-button>\n  </template>\n\n  </dom-module>\n\n\n\n\n<dom-module id=\"paper-item-shared-styles\" assetpath=\"/paper-item/\">\n  <template>\n    <style>\n      :host {\n        display: block;\n        position: relative;\n        min-height: var(--paper-item-min-height, 48px);\n        padding: 0px 16px;\n      }\n\n      :host([hidden]) {\n        display: none !important;\n      }\n\n      :host(.iron-selected) {\n        font-weight: var(--paper-item-selected-weight, bold);\n\n        @apply(--paper-item-selected);\n      }\n\n      :host([disabled]) {\n        color: var(--paper-item-disabled-color, --disabled-text-color);\n\n        @apply(--paper-item-disabled);\n      }\n\n      :host(:focus) {\n        position: relative;\n        outline: 0;\n\n        @apply(--paper-item-focused);\n      }\n\n      :host(:focus):before {\n        @apply(--layout-fit);\n\n        background: currentColor;\n        content: '';\n        opacity: var(--dark-divider-opacity);\n        pointer-events: none;\n\n        @apply(--paper-item-focused-before);\n      }\n    </style>\n  </template>\n</dom-module>\n<dom-module id=\"paper-item\" assetpath=\"/paper-item/\">\n  <template>\n    <style include=\"paper-item-shared-styles\"></style>\n    <style>\n      :host {\n        @apply(--layout-horizontal);\n        @apply(--layout-center);\n        @apply(--paper-font-subhead);\n\n        @apply(--paper-item);\n      }\n    </style>\n\n    <content></content>\n  </template>\n\n  </dom-module>\n\n\n<dom-module id=\"paper-listbox\" assetpath=\"/paper-listbox/\">\n  <template>\n    <style>\n      :host {\n        display: block;\n        padding: 8px 0;\n\n        background: var(--paper-listbox-background-color, --primary-background-color);\n        color: var(--paper-listbox-color, --primary-text-color);\n\n        @apply(--paper-listbox);\n      }\n    </style>\n\n    <content></content>\n  </template>\n\n  </dom-module>\n\n\n<dom-module id=\"paper-progress\" assetpath=\"/paper-progress/\">\n  <template>\n    <style>\n      :host {\n        display: block;\n        width: 200px;\n        position: relative;\n        overflow: hidden;\n      }\n\n      #progressContainer {\n        position: relative;\n      }\n\n      #progressContainer,\n      /* the stripe for the indeterminate animation*/\n      .indeterminate::after {\n        height: var(--paper-progress-height, 4px);\n      }\n\n      #primaryProgress,\n      #secondaryProgress,\n      .indeterminate::after {\n        @apply(--layout-fit);\n      }\n\n      #progressContainer,\n      .indeterminate::after {\n        background: var(--paper-progress-container-color, --google-grey-300);\n      }\n\n      :host(.transiting) #primaryProgress,\n      :host(.transiting) #secondaryProgress {\n        -webkit-transition-property: -webkit-transform;\n        transition-property: transform;\n\n        /* Duration */\n        -webkit-transition-duration: var(--paper-progress-transition-duration, 0.08s);\n        transition-duration: var(--paper-progress-transition-duration, 0.08s);\n\n        /* Timing function */\n        -webkit-transition-timing-function: var(--paper-progress-transition-timing-function, ease);\n        transition-timing-function: var(--paper-progress-transition-timing-function, ease);\n\n        /* Delay */\n        -webkit-transition-delay: var(--paper-progress-transition-delay, 0s);\n        transition-delay: var(--paper-progress-transition-delay, 0s);\n      }\n\n      #primaryProgress,\n      #secondaryProgress {\n        @apply(--layout-fit);\n        -webkit-transform-origin: left center;\n        transform-origin: left center;\n        -webkit-transform: scaleX(0);\n        transform: scaleX(0);\n        will-change: transform;\n      }\n\n      #primaryProgress {\n        background: var(--paper-progress-active-color, --google-green-500);\n      }\n\n      #secondaryProgress {\n        background: var(--paper-progress-secondary-color, --google-green-100);\n      }\n\n      :host([disabled]) #primaryProgress {\n        background: var(--paper-progress-disabled-active-color, --google-grey-500);\n      }\n\n      :host([disabled]) #secondaryProgress {\n        background: var(--paper-progress-disabled-secondary-color, --google-grey-300);\n      }\n\n      :host(:not([disabled])) #primaryProgress.indeterminate {\n        -webkit-transform-origin: right center;\n        transform-origin: right center;\n        -webkit-animation: indeterminate-bar 2s linear infinite;\n        animation: indeterminate-bar 2s linear infinite;\n      }\n\n      :host(:not([disabled])) #primaryProgress.indeterminate::after {\n        content: \"\";\n        -webkit-transform-origin: center center;\n        transform-origin: center center;\n\n        -webkit-animation: indeterminate-splitter 2s linear infinite;\n        animation: indeterminate-splitter 2s linear infinite;\n      }\n\n      @-webkit-keyframes indeterminate-bar {\n        0% {\n          -webkit-transform: scaleX(1) translateX(-100%);\n        }\n        50% {\n          -webkit-transform: scaleX(1) translateX(0%);\n        }\n        75% {\n          -webkit-transform: scaleX(1) translateX(0%);\n          -webkit-animation-timing-function: cubic-bezier(.28,.62,.37,.91);\n        }\n        100% {\n          -webkit-transform: scaleX(0) translateX(0%);\n        }\n      }\n\n      @-webkit-keyframes indeterminate-splitter {\n        0% {\n          -webkit-transform: scaleX(.75) translateX(-125%);\n        }\n        30% {\n          -webkit-transform: scaleX(.75) translateX(-125%);\n          -webkit-animation-timing-function: cubic-bezier(.42,0,.6,.8);\n        }\n        90% {\n          -webkit-transform: scaleX(.75) translateX(125%);\n        }\n        100% {\n          -webkit-transform: scaleX(.75) translateX(125%);\n        }\n      }\n\n      @keyframes indeterminate-bar {\n        0% {\n          transform: scaleX(1) translateX(-100%);\n        }\n        50% {\n          transform: scaleX(1) translateX(0%);\n        }\n        75% {\n          transform: scaleX(1) translateX(0%);\n          animation-timing-function: cubic-bezier(.28,.62,.37,.91);\n        }\n        100% {\n          transform: scaleX(0) translateX(0%);\n        }\n      }\n\n      @keyframes indeterminate-splitter {\n        0% {\n          transform: scaleX(.75) translateX(-125%);\n        }\n        30% {\n          transform: scaleX(.75) translateX(-125%);\n          animation-timing-function: cubic-bezier(.42,0,.6,.8);\n        }\n        90% {\n          transform: scaleX(.75) translateX(125%);\n        }\n        100% {\n          transform: scaleX(.75) translateX(125%);\n        }\n      }\n    </style>\n\n    <div id=\"progressContainer\">\n      <div id=\"secondaryProgress\" hidden$=\"[[s0(secondaryRatio)]]\"></div>\n      <div id=\"primaryProgress\"></div>\n    </div>\n  </template>\n</dom-module>\n\n<dom-module id=\"paper-slider\" assetpath=\"/paper-slider/\">\n  <template strip-whitespace=\"\">\n    <style>\n      :host {\n        @apply(--layout);\n        @apply(--layout-justified);\n        @apply(--layout-center);\n        width: 200px;\n        cursor: default;\n        -webkit-user-select: none;\n        -moz-user-select: none;\n        -ms-user-select: none;\n        user-select: none;\n        -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n        --paper-progress-active-color: var(--paper-slider-active-color, --google-blue-700);\n        --paper-progress-secondary-color: var(--paper-slider-secondary-color, --google-blue-300);\n        --paper-progress-disabled-active-color: var(--paper-slider-disabled-active-color, --paper-grey-400);\n        --paper-progress-disabled-secondary-color: var(--paper-slider-disabled-secondary-color, --paper-grey-400);\n      }\n\n      /* focus shows the ripple */\n      :host(:focus) {\n        outline: none;\n      }\n\n      #sliderContainer {\n        position: relative;\n        width: 100%;\n        height: calc(30px + var(--paper-slider-height, 2px));\n        margin-left: calc(15px + var(--paper-slider-height, 2px)/2);\n        margin-right: calc(15px + var(--paper-slider-height, 2px)/2);\n      }\n\n      #sliderContainer:focus {\n        outline: 0;\n      }\n\n      #sliderContainer.editable {\n        margin-top: 12px;\n        margin-bottom: 12px;\n      }\n\n      .bar-container {\n        position: absolute;\n        top: 0;\n        bottom: 0;\n        left: 0;\n        right: 0;\n        overflow: hidden;\n      }\n\n      .ring > .bar-container {\n        left: calc(5px + var(--paper-slider-height, 2px)/2);\n        transition: left 0.18s ease;\n      }\n\n      .ring.expand.dragging > .bar-container {\n        transition: none;\n      }\n\n      .ring.expand:not(.pin) > .bar-container {\n        left: calc(8px + var(--paper-slider-height, 2px)/2);\n      }\n\n      #sliderBar {\n        padding: 15px 0;\n        width: 100%;\n        background-color: var(--paper-slider-bar-color, transparent);\n        --paper-progress-container-color: var(--paper-grey-400);\n        --paper-progress-height: var(--paper-slider-height, 2px);\n      }\n\n      .slider-markers {\n        position: absolute;\n        top: calc(14px + var(--paper-slider-height,2px)/2);\n        height: var(--paper-slider-height, 2px);\n        left: 0;\n        right: -1px;\n        box-sizing: border-box;\n        pointer-events: none;\n        @apply(--layout-horizontal);\n      }\n\n      .slider-marker {\n        @apply(--layout-flex);\n      }\n      .slider-markers::after,\n      .slider-marker::after {\n        content: \"\";\n        display: block;\n        margin-left: -1px;\n        width: 2px;\n        height: 2px;\n        border-radius: 50%;\n        background-color: black;\n      }\n\n      #sliderKnob {\n        position: absolute;\n        left: 0;\n        top: 0;\n        margin-left: calc(-15px - var(--paper-slider-height, 2px)/2);\n        width: calc(30px + var(--paper-slider-height, 2px));\n        height: calc(30px + var(--paper-slider-height, 2px));\n      }\n\n      .transiting > #sliderKnob {\n        transition: left 0.08s ease;\n      }\n\n      #sliderKnob:focus {\n        outline: none;\n      }\n\n      #sliderKnob.dragging {\n        transition: none;\n      }\n\n      .snaps > #sliderKnob.dragging {\n        transition: -webkit-transform 0.08s ease;\n        transition: transform 0.08s ease;\n      }\n\n      #sliderKnobInner {\n        margin: 10px;\n        width: calc(100% - 20px);\n        height: calc(100% - 20px);\n        background-color: var(--paper-slider-knob-color, --google-blue-700);\n        border: 2px solid var(--paper-slider-knob-color, --google-blue-700);\n        border-radius: 50%;\n\n        -moz-box-sizing: border-box;\n        box-sizing: border-box;\n\n        transition-property: -webkit-transform, background-color, border;\n        transition-property: transform, background-color, border;\n        transition-duration: 0.18s;\n        transition-timing-function: ease;\n      }\n\n      .expand:not(.pin) > #sliderKnob > #sliderKnobInner {\n        -webkit-transform: scale(1.5);\n        transform: scale(1.5);\n      }\n\n      .ring > #sliderKnob > #sliderKnobInner {\n        background-color: var(--paper-slider-knob-start-color, transparent);\n        border: 2px solid var(--paper-slider-knob-start-border-color, --paper-grey-400);\n      }\n\n      #sliderKnobInner::before {\n        background-color: var(--paper-slider-pin-color, --google-blue-700);\n      }\n\n      .pin > #sliderKnob > #sliderKnobInner::before {\n        content: \"\";\n        position: absolute;\n        top: 0;\n        left: 50%;\n        margin-left: -13px;\n        width: 26px;\n        height: 26px;\n        border-radius: 50% 50% 50% 0;\n\n        -webkit-transform: rotate(-45deg) scale(0) translate(0);\n        transform: rotate(-45deg) scale(0) translate(0);\n      }\n\n      #sliderKnobInner::before,\n      #sliderKnobInner::after {\n        transition: -webkit-transform .18s ease, background-color .18s ease;\n        transition: transform .18s ease, background-color .18s ease;\n      }\n\n      .pin.ring > #sliderKnob > #sliderKnobInner::before {\n        background-color: var(--paper-slider-pin-start-color, --paper-grey-400);\n      }\n\n      .pin.expand > #sliderKnob > #sliderKnobInner::before {\n        -webkit-transform: rotate(-45deg) scale(1) translate(17px, -17px);\n        transform: rotate(-45deg) scale(1) translate(17px, -17px);\n      }\n\n      .pin > #sliderKnob > #sliderKnobInner::after {\n        content: attr(value);\n        position: absolute;\n        top: 0;\n        left: 50%;\n        margin-left: -16px;\n        width: 32px;\n        height: 26px;\n        text-align: center;\n        color: var(--paper-slider-font-color, #fff);\n        font-size: 10px;\n\n        -webkit-transform: scale(0) translate(0);\n        transform: scale(0) translate(0);\n      }\n\n      .pin.expand > #sliderKnob > #sliderKnobInner::after {\n        -webkit-transform: scale(1) translate(0, -17px);\n        transform: scale(1) translate(0, -17px);\n      }\n\n      /* paper-input */\n      .slider-input {\n        width: 50px;\n        overflow: hidden;\n        --paper-input-container-input: {\n          text-align: center;\n        };\n        @apply(--paper-slider-input);\n      }\n\n      /* disabled state */\n      #sliderContainer.disabled {\n        pointer-events: none;\n      }\n\n      .disabled > #sliderKnob > #sliderKnobInner {\n        background-color: var(--paper-slider-disabled-knob-color, --paper-grey-400);\n        border: 2px solid var(--paper-slider-disabled-knob-color, --paper-grey-400);\n        -webkit-transform: scale3d(0.75, 0.75, 1);\n        transform: scale3d(0.75, 0.75, 1);\n      }\n\n      .disabled.ring > #sliderKnob > #sliderKnobInner {\n        background-color: var(--paper-slider-knob-start-color, transparent);\n        border: 2px solid var(--paper-slider-knob-start-border-color, --paper-grey-400);\n      }\n\n      paper-ripple {\n        color: var(--paper-slider-knob-color, --google-blue-700);\n      }\n    </style>\n\n    <div id=\"sliderContainer\" class$=\"[[n0(disabled,pin,snaps,immediateValue,min,expand,dragging,transiting,editable)]]\">\n\n      <div class=\"bar-container\">\n        <paper-progress disabled$=\"[[disabled]]\" id=\"sliderBar\" aria-hidden=\"true\" min=\"[[min]]\" max=\"[[max]]\" step=\"[[step]]\" value=\"[[immediateValue]]\" secondary-progress=\"[[secondaryProgress]]\" on-down=\"K_\" on-up=\"LG\" on-track=\"Z0\">\n        </paper-progress>\n      </div>\n\n      <template is=\"dom-if\" if=\"[[snaps]]\">\n        <div class=\"slider-markers\">\n          <template is=\"dom-repeat\" items=\"[[markers]]\">\n            <div class=\"slider-marker\"></div>\n          </template>\n        </div>\n      </template>\n\n      <div id=\"sliderKnob\" on-down=\"C0\" on-up=\"LG\" on-track=\"Z0\" on-transitionend=\"B0\">\n          <div id=\"sliderKnobInner\" value$=\"[[immediateValue]]\"></div>\n      </div>\n    </div>\n\n    <template is=\"dom-if\" if=\"[[editable]]\">\n      <paper-input id=\"input\" type=\"number\" step=\"[[step]]\" min=\"[[min]]\" max=\"[[max]]\" class=\"slider-input\" disabled$=\"[[disabled]]\" value=\"[[immediateValue]]\" on-change=\"M_\" on-keydown=\"z0\" no-label-float=\"\">\n      </paper-input>\n    </template>\n  </template>\n\n  </dom-module>\n<iron-iconset-svg name=\"icons\" size=\"24\">\n<svg><defs>\n<g id=\"3d-rotation\"><path d=\"M7.52 21.48C4.25 19.94 1.91 16.76 1.55 13H.05C.56 19.16 5.71 24 12 24l.66-.03-3.81-3.81-1.33 1.32zm.89-6.52c-.19 0-.37-.03-.52-.08-.16-.06-.29-.13-.4-.24-.11-.1-.2-.22-.26-.37-.06-.14-.09-.3-.09-.47h-1.3c0 .36.07.68.21.95.14.27.33.5.56.69.24.18.51.32.82.41.3.1.62.15.96.15.37 0 .72-.05 1.03-.15.32-.1.6-.25.83-.44s.42-.43.55-.72c.13-.29.2-.61.2-.97 0-.19-.02-.38-.07-.56-.05-.18-.12-.35-.23-.51-.1-.16-.24-.3-.4-.43-.17-.13-.37-.23-.61-.31.2-.09.37-.2.52-.33.15-.13.27-.27.37-.42.1-.15.17-.3.22-.46.05-.16.07-.32.07-.48 0-.36-.06-.68-.18-.96-.12-.28-.29-.51-.51-.69-.2-.19-.47-.33-.77-.43C9.1 8.05 8.76 8 8.39 8c-.36 0-.69.05-1 .16-.3.11-.57.26-.79.45-.21.19-.38.41-.51.67-.12.26-.18.54-.18.85h1.3c0-.17.03-.32.09-.45s.14-.25.25-.34c.11-.09.23-.17.38-.22.15-.05.3-.08.48-.08.4 0 .7.1.89.31.19.2.29.49.29.86 0 .18-.03.34-.08.49-.05.15-.14.27-.25.37-.11.1-.25.18-.41.24-.16.06-.36.09-.58.09H7.5v1.03h.77c.22 0 .42.02.6.07s.33.13.45.23c.12.11.22.24.29.4.07.16.1.35.1.57 0 .41-.12.72-.35.93-.23.23-.55.33-.95.33zm8.55-5.92c-.32-.33-.7-.59-1.14-.77-.43-.18-.92-.27-1.46-.27H12v8h2.3c.55 0 1.06-.09 1.51-.27.45-.18.84-.43 1.16-.76.32-.33.57-.73.74-1.19.17-.47.26-.99.26-1.57v-.4c0-.58-.09-1.1-.26-1.57-.18-.47-.43-.87-.75-1.2zm-.39 3.16c0 .42-.05.79-.14 1.13-.1.33-.24.62-.43.85-.19.23-.43.41-.71.53-.29.12-.62.18-.99.18h-.91V9.12h.97c.72 0 1.27.23 1.64.69.38.46.57 1.12.57 1.99v.4zM12 0l-.66.03 3.81 3.81 1.33-1.33c3.27 1.55 5.61 4.72 5.96 8.48h1.5C23.44 4.84 18.29 0 12 0z\"></path></g>\n<g id=\"accessibility\"><path d=\"M12 2c1.1 0 2 .9 2 2s-.9 2-2 2-2-.9-2-2 .9-2 2-2zm9 7h-6v13h-2v-6h-2v6H9V9H3V7h18v2z\"></path></g>\n<g id=\"accessible\"><circle cx=\"12\" cy=\"4\" r=\"2\"></circle><path d=\"M19 13v-2c-1.54.02-3.09-.75-4.07-1.83l-1.29-1.43c-.17-.19-.38-.34-.61-.45-.01 0-.01-.01-.02-.01H13c-.35-.2-.75-.3-1.19-.26C10.76 7.11 10 8.04 10 9.09V15c0 1.1.9 2 2 2h5v5h2v-5.5c0-1.1-.9-2-2-2h-3v-3.45c1.29 1.07 3.25 1.94 5 1.95zm-6.17 5c-.41 1.16-1.52 2-2.83 2-1.66 0-3-1.34-3-3 0-1.31.84-2.41 2-2.83V12.1c-2.28.46-4 2.48-4 4.9 0 2.76 2.24 5 5 5 2.42 0 4.44-1.72 4.9-4h-2.07z\"></path></g>\n<g id=\"account-balance\"><path d=\"M4 10v7h3v-7H4zm6 0v7h3v-7h-3zM2 22h19v-3H2v3zm14-12v7h3v-7h-3zm-4.5-9L2 6v2h19V6l-9.5-5z\"></path></g>\n<g id=\"account-balance-wallet\"><path d=\"M21 18v1c0 1.1-.9 2-2 2H5c-1.11 0-2-.9-2-2V5c0-1.1.89-2 2-2h14c1.1 0 2 .9 2 2v1h-9c-1.11 0-2 .9-2 2v8c0 1.1.89 2 2 2h9zm-9-2h10V8H12v8zm4-2.5c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5z\"></path></g>\n<g id=\"account-box\"><path d=\"M3 5v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2H5c-1.11 0-2 .9-2 2zm12 4c0 1.66-1.34 3-3 3s-3-1.34-3-3 1.34-3 3-3 3 1.34 3 3zm-9 8c0-2 4-3.1 6-3.1s6 1.1 6 3.1v1H6v-1z\"></path></g>\n<g id=\"account-circle\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 3c1.66 0 3 1.34 3 3s-1.34 3-3 3-3-1.34-3-3 1.34-3 3-3zm0 14.2c-2.5 0-4.71-1.28-6-3.22.03-1.99 4-3.08 6-3.08 1.99 0 5.97 1.09 6 3.08-1.29 1.94-3.5 3.22-6 3.22z\"></path></g>\n<g id=\"add\"><path d=\"M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z\"></path></g>\n<g id=\"add-alert\"><path d=\"M10.01 21.01c0 1.1.89 1.99 1.99 1.99s1.99-.89 1.99-1.99h-3.98zm8.87-4.19V11c0-3.25-2.25-5.97-5.29-6.69v-.72C13.59 2.71 12.88 2 12 2s-1.59.71-1.59 1.59v.72C7.37 5.03 5.12 7.75 5.12 11v5.82L3 18.94V20h18v-1.06l-2.12-2.12zM16 13.01h-3v3h-2v-3H8V11h3V8h2v3h3v2.01z\"></path></g>\n<g id=\"add-box\"><path d=\"M19 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-2 10h-4v4h-2v-4H7v-2h4V7h2v4h4v2z\"></path></g>\n<g id=\"add-circle\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm5 11h-4v4h-2v-4H7v-2h4V7h2v4h4v2z\"></path></g>\n<g id=\"add-circle-outline\"><path d=\"M13 7h-2v4H7v2h4v4h2v-4h4v-2h-4V7zm-1-5C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z\"></path></g>\n<g id=\"add-shopping-cart\"><path d=\"M11 9h2V6h3V4h-3V1h-2v3H8v2h3v3zm-4 9c-1.1 0-1.99.9-1.99 2S5.9 22 7 22s2-.9 2-2-.9-2-2-2zm10 0c-1.1 0-1.99.9-1.99 2s.89 2 1.99 2 2-.9 2-2-.9-2-2-2zm-9.83-3.25l.03-.12.9-1.63h7.45c.75 0 1.41-.41 1.75-1.03l3.86-7.01L19.42 4h-.01l-1.1 2-2.76 5H8.53l-.13-.27L6.16 6l-.95-2-.94-2H1v2h2l3.6 7.59-1.35 2.45c-.16.28-.25.61-.25.96 0 1.1.9 2 2 2h12v-2H7.42c-.13 0-.25-.11-.25-.25z\"></path></g>\n<g id=\"alarm\"><path d=\"M22 5.72l-4.6-3.86-1.29 1.53 4.6 3.86L22 5.72zM7.88 3.39L6.6 1.86 2 5.71l1.29 1.53 4.59-3.85zM12.5 8H11v6l4.75 2.85.75-1.23-4-2.37V8zM12 4c-4.97 0-9 4.03-9 9s4.02 9 9 9c4.97 0 9-4.03 9-9s-4.03-9-9-9zm0 16c-3.87 0-7-3.13-7-7s3.13-7 7-7 7 3.13 7 7-3.13 7-7 7z\"></path></g>\n<g id=\"alarm-add\"><path d=\"M7.88 3.39L6.6 1.86 2 5.71l1.29 1.53 4.59-3.85zM22 5.72l-4.6-3.86-1.29 1.53 4.6 3.86L22 5.72zM12 4c-4.97 0-9 4.03-9 9s4.02 9 9 9c4.97 0 9-4.03 9-9s-4.03-9-9-9zm0 16c-3.87 0-7-3.13-7-7s3.13-7 7-7 7 3.13 7 7-3.13 7-7 7zm1-11h-2v3H8v2h3v3h2v-3h3v-2h-3V9z\"></path></g>\n<g id=\"alarm-off\"><path d=\"M12 6c3.87 0 7 3.13 7 7 0 .84-.16 1.65-.43 2.4l1.52 1.52c.58-1.19.91-2.51.91-3.92 0-4.97-4.03-9-9-9-1.41 0-2.73.33-3.92.91L9.6 6.43C10.35 6.16 11.16 6 12 6zm10-.28l-4.6-3.86-1.29 1.53 4.6 3.86L22 5.72zM2.92 2.29L1.65 3.57 2.98 4.9l-1.11.93 1.42 1.42 1.11-.94.8.8C3.83 8.69 3 10.75 3 13c0 4.97 4.02 9 9 9 2.25 0 4.31-.83 5.89-2.2l2.2 2.2 1.27-1.27L3.89 3.27l-.97-.98zm13.55 16.1C15.26 19.39 13.7 20 12 20c-3.87 0-7-3.13-7-7 0-1.7.61-3.26 1.61-4.47l9.86 9.86zM8.02 3.28L6.6 1.86l-.86.71 1.42 1.42.86-.71z\"></path></g>\n<g id=\"alarm-on\"><path d=\"M22 5.72l-4.6-3.86-1.29 1.53 4.6 3.86L22 5.72zM7.88 3.39L6.6 1.86 2 5.71l1.29 1.53 4.59-3.85zM12 4c-4.97 0-9 4.03-9 9s4.02 9 9 9c4.97 0 9-4.03 9-9s-4.03-9-9-9zm0 16c-3.87 0-7-3.13-7-7s3.13-7 7-7 7 3.13 7 7-3.13 7-7 7zm-1.46-5.47L8.41 12.4l-1.06 1.06 3.18 3.18 6-6-1.06-1.06-4.93 4.95z\"></path></g>\n<g id=\"all-out\"><path d=\"M16.21 4.16l4 4v-4zm4 12l-4 4h4zm-12 4l-4-4v4zm-4-12l4-4h-4zm12.95-.95c-2.73-2.73-7.17-2.73-9.9 0s-2.73 7.17 0 9.9 7.17 2.73 9.9 0 2.73-7.16 0-9.9zm-1.1 8.8c-2.13 2.13-5.57 2.13-7.7 0s-2.13-5.57 0-7.7 5.57-2.13 7.7 0 2.13 5.57 0 7.7z\"></path></g>\n<g id=\"android\"><path d=\"M6 18c0 .55.45 1 1 1h1v3.5c0 .83.67 1.5 1.5 1.5s1.5-.67 1.5-1.5V19h2v3.5c0 .83.67 1.5 1.5 1.5s1.5-.67 1.5-1.5V19h1c.55 0 1-.45 1-1V8H6v10zM3.5 8C2.67 8 2 8.67 2 9.5v7c0 .83.67 1.5 1.5 1.5S5 17.33 5 16.5v-7C5 8.67 4.33 8 3.5 8zm17 0c-.83 0-1.5.67-1.5 1.5v7c0 .83.67 1.5 1.5 1.5s1.5-.67 1.5-1.5v-7c0-.83-.67-1.5-1.5-1.5zm-4.97-5.84l1.3-1.3c.2-.2.2-.51 0-.71-.2-.2-.51-.2-.71 0l-1.48 1.48C13.85 1.23 12.95 1 12 1c-.96 0-1.86.23-2.66.63L7.85.15c-.2-.2-.51-.2-.71 0-.2.2-.2.51 0 .71l1.31 1.31C6.97 3.26 6 5.01 6 7h12c0-1.99-.97-3.75-2.47-4.84zM10 5H9V4h1v1zm5 0h-1V4h1v1z\"></path></g>\n<g id=\"announcement\"><path d=\"M20 2H4c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-7 9h-2V5h2v6zm0 4h-2v-2h2v2z\"></path></g>\n<g id=\"apps\"><path d=\"M4 8h4V4H4v4zm6 12h4v-4h-4v4zm-6 0h4v-4H4v4zm0-6h4v-4H4v4zm6 0h4v-4h-4v4zm6-10v4h4V4h-4zm-6 4h4V4h-4v4zm6 6h4v-4h-4v4zm0 6h4v-4h-4v4z\"></path></g>\n<g id=\"archive\"><path d=\"M20.54 5.23l-1.39-1.68C18.88 3.21 18.47 3 18 3H6c-.47 0-.88.21-1.16.55L3.46 5.23C3.17 5.57 3 6.02 3 6.5V19c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V6.5c0-.48-.17-.93-.46-1.27zM12 17.5L6.5 12H10v-2h4v2h3.5L12 17.5zM5.12 5l.81-1h12l.94 1H5.12z\"></path></g>\n<g id=\"arrow-back\"><path d=\"M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2z\"></path></g>\n<g id=\"arrow-downward\"><path d=\"M20 12l-1.41-1.41L13 16.17V4h-2v12.17l-5.58-5.59L4 12l8 8 8-8z\"></path></g>\n<g id=\"arrow-drop-down\"><path d=\"M7 10l5 5 5-5z\"></path></g>\n<g id=\"arrow-drop-down-circle\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 12l-4-4h8l-4 4z\"></path></g>\n<g id=\"arrow-drop-up\"><path d=\"M7 14l5-5 5 5z\"></path></g>\n<g id=\"arrow-forward\"><path d=\"M12 4l-1.41 1.41L16.17 11H4v2h12.17l-5.58 5.59L12 20l8-8z\"></path></g>\n<g id=\"arrow-upward\"><path d=\"M4 12l1.41 1.41L11 7.83V20h2V7.83l5.58 5.59L20 12l-8-8-8 8z\"></path></g>\n<g id=\"aspect-ratio\"><path d=\"M19 12h-2v3h-3v2h5v-5zM7 9h3V7H5v5h2V9zm14-6H3c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16.01H3V4.99h18v14.02z\"></path></g>\n<g id=\"assessment\"><path d=\"M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM9 17H7v-7h2v7zm4 0h-2V7h2v10zm4 0h-2v-4h2v4z\"></path></g>\n<g id=\"assignment\"><path d=\"M19 3h-4.18C14.4 1.84 13.3 1 12 1c-1.3 0-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-7 0c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm2 14H7v-2h7v2zm3-4H7v-2h10v2zm0-4H7V7h10v2z\"></path></g>\n<g id=\"assignment-ind\"><path d=\"M19 3h-4.18C14.4 1.84 13.3 1 12 1c-1.3 0-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-7 0c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm0 4c1.66 0 3 1.34 3 3s-1.34 3-3 3-3-1.34-3-3 1.34-3 3-3zm6 12H6v-1.4c0-2 4-3.1 6-3.1s6 1.1 6 3.1V19z\"></path></g>\n<g id=\"assignment-late\"><path d=\"M19 3h-4.18C14.4 1.84 13.3 1 12 1c-1.3 0-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-6 15h-2v-2h2v2zm0-4h-2V8h2v6zm-1-9c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1z\"></path></g>\n<g id=\"assignment-return\"><path d=\"M19 3h-4.18C14.4 1.84 13.3 1 12 1c-1.3 0-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-7 0c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm4 12h-4v3l-5-5 5-5v3h4v4z\"></path></g>\n<g id=\"assignment-returned\"><path d=\"M19 3h-4.18C14.4 1.84 13.3 1 12 1c-1.3 0-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-7 0c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm0 15l-5-5h3V9h4v4h3l-5 5z\"></path></g>\n<g id=\"assignment-turned-in\"><path d=\"M19 3h-4.18C14.4 1.84 13.3 1 12 1c-1.3 0-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-7 0c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm-2 14l-4-4 1.41-1.41L10 14.17l6.59-6.59L18 9l-8 8z\"></path></g>\n<g id=\"attachment\"><path d=\"M2 12.5C2 9.46 4.46 7 7.5 7H18c2.21 0 4 1.79 4 4s-1.79 4-4 4H9.5C8.12 15 7 13.88 7 12.5S8.12 10 9.5 10H17v2H9.41c-.55 0-.55 1 0 1H18c1.1 0 2-.9 2-2s-.9-2-2-2H7.5C5.57 9 4 10.57 4 12.5S5.57 16 7.5 16H17v2H7.5C4.46 18 2 15.54 2 12.5z\"></path></g>\n<g id=\"autorenew\"><path d=\"M12 6v3l4-4-4-4v3c-4.42 0-8 3.58-8 8 0 1.57.46 3.03 1.24 4.26L6.7 14.8c-.45-.83-.7-1.79-.7-2.8 0-3.31 2.69-6 6-6zm6.76 1.74L17.3 9.2c.44.84.7 1.79.7 2.8 0 3.31-2.69 6-6 6v-3l-4 4 4 4v-3c4.42 0 8-3.58 8-8 0-1.57-.46-3.03-1.24-4.26z\"></path></g>\n<g id=\"backspace\"><path d=\"M22 3H7c-.69 0-1.23.35-1.59.88L0 12l5.41 8.11c.36.53.9.89 1.59.89h15c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-3 12.59L17.59 17 14 13.41 10.41 17 9 15.59 12.59 12 9 8.41 10.41 7 14 10.59 17.59 7 19 8.41 15.41 12 19 15.59z\"></path></g>\n<g id=\"backup\"><path d=\"M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM14 13v4h-4v-4H7l5-5 5 5h-3z\"></path></g>\n<g id=\"block\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zM4 12c0-4.42 3.58-8 8-8 1.85 0 3.55.63 4.9 1.69L5.69 16.9C4.63 15.55 4 13.85 4 12zm8 8c-1.85 0-3.55-.63-4.9-1.69L18.31 7.1C19.37 8.45 20 10.15 20 12c0 4.42-3.58 8-8 8z\"></path></g>\n<g id=\"book\"><path d=\"M18 2H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zM6 4h5v8l-2.5-1.5L6 12V4z\"></path></g>\n<g id=\"bookmark\"><path d=\"M17 3H7c-1.1 0-1.99.9-1.99 2L5 21l7-3 7 3V5c0-1.1-.9-2-2-2z\"></path></g>\n<g id=\"bookmark-border\"><path d=\"M17 3H7c-1.1 0-1.99.9-1.99 2L5 21l7-3 7 3V5c0-1.1-.9-2-2-2zm0 15l-5-2.18L7 18V5h10v13z\"></path></g>\n<g id=\"bug-report\"><path d=\"M20 8h-2.81c-.45-.78-1.07-1.45-1.82-1.96L17 4.41 15.59 3l-2.17 2.17C12.96 5.06 12.49 5 12 5c-.49 0-.96.06-1.41.17L8.41 3 7 4.41l1.62 1.63C7.88 6.55 7.26 7.22 6.81 8H4v2h2.09c-.05.33-.09.66-.09 1v1H4v2h2v1c0 .34.04.67.09 1H4v2h2.81c1.04 1.79 2.97 3 5.19 3s4.15-1.21 5.19-3H20v-2h-2.09c.05-.33.09-.66.09-1v-1h2v-2h-2v-1c0-.34-.04-.67-.09-1H20V8zm-6 8h-4v-2h4v2zm0-4h-4v-2h4v2z\"></path></g>\n<g id=\"build\"><path d=\"M22.7 19l-9.1-9.1c.9-2.3.4-5-1.5-6.9-2-2-5-2.4-7.4-1.3L9 6 6 9 1.6 4.7C.4 7.1.9 10.1 2.9 12.1c1.9 1.9 4.6 2.4 6.9 1.5l9.1 9.1c.4.4 1 .4 1.4 0l2.3-2.3c.5-.4.5-1.1.1-1.4z\"></path></g>\n<g id=\"cached\"><path d=\"M19 8l-4 4h3c0 3.31-2.69 6-6 6-1.01 0-1.97-.25-2.8-.7l-1.46 1.46C8.97 19.54 10.43 20 12 20c4.42 0 8-3.58 8-8h3l-4-4zM6 12c0-3.31 2.69-6 6-6 1.01 0 1.97.25 2.8.7l1.46-1.46C15.03 4.46 13.57 4 12 4c-4.42 0-8 3.58-8 8H1l4 4 4-4H6z\"></path></g>\n<g id=\"camera-enhance\"><path d=\"M9 3L7.17 5H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2h-3.17L15 3H9zm3 15c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-1l1.25-2.75L16 13l-2.75-1.25L12 9l-1.25 2.75L8 13l2.75 1.25z\"></path></g>\n<g id=\"cancel\"><path d=\"M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm5 13.59L15.59 17 12 13.41 8.41 17 7 15.59 10.59 12 7 8.41 8.41 7 12 10.59 15.59 7 17 8.41 13.41 12 17 15.59z\"></path></g>\n<g id=\"card-giftcard\"><path d=\"M20 6h-2.18c.11-.31.18-.65.18-1 0-1.66-1.34-3-3-3-1.05 0-1.96.54-2.5 1.35l-.5.67-.5-.68C10.96 2.54 10.05 2 9 2 7.34 2 6 3.34 6 5c0 .35.07.69.18 1H4c-1.11 0-1.99.89-1.99 2L2 19c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V8c0-1.11-.89-2-2-2zm-5-2c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zM9 4c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm11 15H4v-2h16v2zm0-5H4V8h5.08L7 10.83 8.62 12 11 8.76l1-1.36 1 1.36L15.38 12 17 10.83 14.92 8H20v6z\"></path></g>\n<g id=\"card-membership\"><path d=\"M20 2H4c-1.11 0-2 .89-2 2v11c0 1.11.89 2 2 2h4v5l4-2 4 2v-5h4c1.11 0 2-.89 2-2V4c0-1.11-.89-2-2-2zm0 13H4v-2h16v2zm0-5H4V4h16v6z\"></path></g>\n<g id=\"card-travel\"><path d=\"M20 6h-3V4c0-1.11-.89-2-2-2H9c-1.11 0-2 .89-2 2v2H4c-1.11 0-2 .89-2 2v11c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V8c0-1.11-.89-2-2-2zM9 4h6v2H9V4zm11 15H4v-2h16v2zm0-5H4V8h3v2h2V8h6v2h2V8h3v6z\"></path></g>\n<g id=\"change-history\"><path d=\"M12 7.77L18.39 18H5.61L12 7.77M12 4L2 20h20L12 4z\"></path></g>\n<g id=\"check\"><path d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\"></path></g>\n<g id=\"check-box\"><path d=\"M19 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.11 0 2-.9 2-2V5c0-1.1-.89-2-2-2zm-9 14l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z\"></path></g>\n<g id=\"check-box-outline-blank\"><path d=\"M19 5v14H5V5h14m0-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z\"></path></g>\n<g id=\"check-circle\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z\"></path></g>\n<g id=\"chevron-left\"><path d=\"M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z\"></path></g>\n<g id=\"chevron-right\"><path d=\"M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z\"></path></g>\n<g id=\"chrome-reader-mode\"><path d=\"M13 12h7v1.5h-7zm0-2.5h7V11h-7zm0 5h7V16h-7zM21 4H3c-1.1 0-2 .9-2 2v13c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 15h-9V6h9v13z\"></path></g>\n<g id=\"class\"><path d=\"M18 2H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zM6 4h5v8l-2.5-1.5L6 12V4z\"></path></g>\n<g id=\"clear\"><path d=\"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"></path></g>\n<g id=\"close\"><path d=\"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"></path></g>\n<g id=\"cloud\"><path d=\"M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96z\"></path></g>\n<g id=\"cloud-circle\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm4.5 14H8c-1.66 0-3-1.34-3-3s1.34-3 3-3l.14.01C8.58 8.28 10.13 7 12 7c2.21 0 4 1.79 4 4h.5c1.38 0 2.5 1.12 2.5 2.5S17.88 16 16.5 16z\"></path></g>\n<g id=\"cloud-done\"><path d=\"M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM10 17l-3.5-3.5 1.41-1.41L10 14.17 15.18 9l1.41 1.41L10 17z\"></path></g>\n<g id=\"cloud-download\"><path d=\"M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM17 13l-5 5-5-5h3V9h4v4h3z\"></path></g>\n<g id=\"cloud-off\"><path d=\"M19.35 10.04C18.67 6.59 15.64 4 12 4c-1.48 0-2.85.43-4.01 1.17l1.46 1.46C10.21 6.23 11.08 6 12 6c3.04 0 5.5 2.46 5.5 5.5v.5H19c1.66 0 3 1.34 3 3 0 1.13-.64 2.11-1.56 2.62l1.45 1.45C23.16 18.16 24 16.68 24 15c0-2.64-2.05-4.78-4.65-4.96zM3 5.27l2.75 2.74C2.56 8.15 0 10.77 0 14c0 3.31 2.69 6 6 6h11.73l2 2L21 20.73 4.27 4 3 5.27zM7.73 10l8 8H6c-2.21 0-4-1.79-4-4s1.79-4 4-4h1.73z\"></path></g>\n<g id=\"cloud-queue\"><path d=\"M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM19 18H6c-2.21 0-4-1.79-4-4s1.79-4 4-4h.71C7.37 7.69 9.48 6 12 6c3.04 0 5.5 2.46 5.5 5.5v.5H19c1.66 0 3 1.34 3 3s-1.34 3-3 3z\"></path></g>\n<g id=\"cloud-upload\"><path d=\"M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM14 13v4h-4v-4H7l5-5 5 5h-3z\"></path></g>\n<g id=\"code\"><path d=\"M9.4 16.6L4.8 12l4.6-4.6L8 6l-6 6 6 6 1.4-1.4zm5.2 0l4.6-4.6-4.6-4.6L16 6l6 6-6 6-1.4-1.4z\"></path></g>\n<g id=\"compare-arrows\"><path d=\"M9.01 14H2v2h7.01v3L13 15l-3.99-4v3zm5.98-1v-3H22V8h-7.01V5L11 9l3.99 4z\"></path></g>\n<g id=\"content-copy\"><path d=\"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z\"></path></g>\n<g id=\"content-cut\"><path d=\"M9.64 7.64c.23-.5.36-1.05.36-1.64 0-2.21-1.79-4-4-4S2 3.79 2 6s1.79 4 4 4c.59 0 1.14-.13 1.64-.36L10 12l-2.36 2.36C7.14 14.13 6.59 14 6 14c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4c0-.59-.13-1.14-.36-1.64L12 14l7 7h3v-1L9.64 7.64zM6 8c-1.1 0-2-.89-2-2s.9-2 2-2 2 .89 2 2-.9 2-2 2zm0 12c-1.1 0-2-.89-2-2s.9-2 2-2 2 .89 2 2-.9 2-2 2zm6-7.5c-.28 0-.5-.22-.5-.5s.22-.5.5-.5.5.22.5.5-.22.5-.5.5zM19 3l-6 6 2 2 7-7V3z\"></path></g>\n<g id=\"content-paste\"><path d=\"M19 2h-4.18C14.4.84 13.3 0 12 0c-1.3 0-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-7 0c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm7 18H5V4h2v3h10V4h2v16z\"></path></g>\n<g id=\"copyright\"><path d=\"M10.08 10.86c.05-.33.16-.62.3-.87s.34-.46.59-.62c.24-.15.54-.22.91-.23.23.01.44.05.63.13.2.09.38.21.52.36s.25.33.34.53.13.42.14.64h1.79c-.02-.47-.11-.9-.28-1.29s-.4-.73-.7-1.01-.66-.5-1.08-.66-.88-.23-1.39-.23c-.65 0-1.22.11-1.7.34s-.88.53-1.2.92-.56.84-.71 1.36S8 11.29 8 11.87v.27c0 .58.08 1.12.23 1.64s.39.97.71 1.35.72.69 1.2.91 1.05.34 1.7.34c.47 0 .91-.08 1.32-.23s.77-.36 1.08-.63.56-.58.74-.94.29-.74.3-1.15h-1.79c-.01.21-.06.4-.15.58s-.21.33-.36.46-.32.23-.52.3c-.19.07-.39.09-.6.1-.36-.01-.66-.08-.89-.23-.25-.16-.45-.37-.59-.62s-.25-.55-.3-.88-.08-.67-.08-1v-.27c0-.35.03-.68.08-1.01zM12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z\"></path></g>\n<g id=\"create\"><path d=\"M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z\"></path></g>\n<g id=\"create-new-folder\"><path d=\"M20 6h-8l-2-2H4c-1.11 0-1.99.89-1.99 2L2 18c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V8c0-1.11-.89-2-2-2zm-1 8h-3v3h-2v-3h-3v-2h3V9h2v3h3v2z\"></path></g>\n<g id=\"credit-card\"><path d=\"M20 4H4c-1.11 0-1.99.89-1.99 2L2 18c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V6c0-1.11-.89-2-2-2zm0 14H4v-6h16v6zm0-10H4V6h16v2z\"></path></g>\n<g id=\"dashboard\"><path d=\"M3 13h8V3H3v10zm0 8h8v-6H3v6zm10 0h8V11h-8v10zm0-18v6h8V3h-8z\"></path></g>\n<g id=\"date-range\"><path d=\"M9 11H7v2h2v-2zm4 0h-2v2h2v-2zm4 0h-2v2h2v-2zm2-7h-1V2h-2v2H8V2H6v2H5c-1.11 0-1.99.9-1.99 2L3 20c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 16H5V9h14v11z\"></path></g>\n<g id=\"delete\"><path d=\"M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z\"></path></g>\n<g id=\"description\"><path d=\"M14 2H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6zm2 16H8v-2h8v2zm0-4H8v-2h8v2zm-3-5V3.5L18.5 9H13z\"></path></g>\n<g id=\"dns\"><path d=\"M20 13H4c-.55 0-1 .45-1 1v6c0 .55.45 1 1 1h16c.55 0 1-.45 1-1v-6c0-.55-.45-1-1-1zM7 19c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zM20 3H4c-.55 0-1 .45-1 1v6c0 .55.45 1 1 1h16c.55 0 1-.45 1-1V4c0-.55-.45-1-1-1zM7 9c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2z\"></path></g>\n<g id=\"done\"><path d=\"M9 16.2L4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4L9 16.2z\"></path></g>\n<g id=\"done-all\"><path d=\"M18 7l-1.41-1.41-6.34 6.34 1.41 1.41L18 7zm4.24-1.41L11.66 16.17 7.48 12l-1.41 1.41L11.66 19l12-12-1.42-1.41zM.41 13.41L6 19l1.41-1.41L1.83 12 .41 13.41z\"></path></g>\n<g id=\"donut-large\"><path d=\"M11 5.08V2c-5 .5-9 4.81-9 10s4 9.5 9 10v-3.08c-3-.48-6-3.4-6-6.92s3-6.44 6-6.92zM18.97 11H22c-.47-5-4-8.53-9-9v3.08C16 5.51 18.54 8 18.97 11zM13 18.92V22c5-.47 8.53-4 9-9h-3.03c-.43 3-2.97 5.49-5.97 5.92z\"></path></g>\n<g id=\"donut-small\"><path d=\"M11 9.16V2c-5 .5-9 4.79-9 10s4 9.5 9 10v-7.16c-1-.41-2-1.52-2-2.84s1-2.43 2-2.84zM14.86 11H22c-.48-4.75-4-8.53-9-9v7.16c1 .3 1.52.98 1.86 1.84zM13 14.84V22c5-.47 8.52-4.25 9-9h-7.14c-.34.86-.86 1.54-1.86 1.84z\"></path></g>\n<g id=\"drafts\"><path d=\"M21.99 8c0-.72-.37-1.35-.94-1.7L12 1 2.95 6.3C2.38 6.65 2 7.28 2 8v10c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2l-.01-10zM12 13L3.74 7.84 12 3l8.26 4.84L12 13z\"></path></g>\n<g id=\"eject\"><path d=\"M5 17h14v2H5zm7-12L5.33 15h13.34z\"></path></g>\n<g id=\"error\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z\"></path></g>\n<g id=\"error-outline\"><path d=\"M11 15h2v2h-2zm0-8h2v6h-2zm.99-5C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z\"></path></g>\n<g id=\"event\"><path d=\"M17 12h-5v5h5v-5zM16 1v2H8V1H6v2H5c-1.11 0-1.99.9-1.99 2L3 19c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2h-1V1h-2zm3 18H5V8h14v11z\"></path></g>\n<g id=\"event-seat\"><path d=\"M4 18v3h3v-3h10v3h3v-6H4zm15-8h3v3h-3zM2 10h3v3H2zm15 3H7V5c0-1.1.9-2 2-2h6c1.1 0 2 .9 2 2v8z\"></path></g>\n<g id=\"exit-to-app\"><path d=\"M10.09 15.59L11.5 17l5-5-5-5-1.41 1.41L12.67 11H3v2h9.67l-2.58 2.59zM19 3H5c-1.11 0-2 .9-2 2v4h2V5h14v14H5v-4H3v4c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z\"></path></g>\n<g id=\"expand-less\"><path d=\"M12 8l-6 6 1.41 1.41L12 10.83l4.59 4.58L18 14z\"></path></g>\n<g id=\"expand-more\"><path d=\"M16.59 8.59L12 13.17 7.41 8.59 6 10l6 6 6-6z\"></path></g>\n<g id=\"explore\"><path d=\"M12 10.9c-.61 0-1.1.49-1.1 1.1s.49 1.1 1.1 1.1c.61 0 1.1-.49 1.1-1.1s-.49-1.1-1.1-1.1zM12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm2.19 12.19L6 18l3.81-8.19L18 6l-3.81 8.19z\"></path></g>\n<g id=\"extension\"><path d=\"M20.5 11H19V7c0-1.1-.9-2-2-2h-4V3.5C13 2.12 11.88 1 10.5 1S8 2.12 8 3.5V5H4c-1.1 0-1.99.9-1.99 2v3.8H3.5c1.49 0 2.7 1.21 2.7 2.7s-1.21 2.7-2.7 2.7H2V20c0 1.1.9 2 2 2h3.8v-1.5c0-1.49 1.21-2.7 2.7-2.7 1.49 0 2.7 1.21 2.7 2.7V22H17c1.1 0 2-.9 2-2v-4h1.5c1.38 0 2.5-1.12 2.5-2.5S21.88 11 20.5 11z\"></path></g>\n<g id=\"face\"><path d=\"M9 11.75c-.69 0-1.25.56-1.25 1.25s.56 1.25 1.25 1.25 1.25-.56 1.25-1.25-.56-1.25-1.25-1.25zm6 0c-.69 0-1.25.56-1.25 1.25s.56 1.25 1.25 1.25 1.25-.56 1.25-1.25-.56-1.25-1.25-1.25zM12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8 0-.29.02-.58.05-.86 2.36-1.05 4.23-2.98 5.21-5.37C11.07 8.33 14.05 10 17.42 10c.78 0 1.53-.09 2.25-.26.21.71.33 1.47.33 2.26 0 4.41-3.59 8-8 8z\"></path></g>\n<g id=\"favorite\"><path d=\"M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z\"></path></g>\n<g id=\"favorite-border\"><path d=\"M16.5 3c-1.74 0-3.41.81-4.5 2.09C10.91 3.81 9.24 3 7.5 3 4.42 3 2 5.42 2 8.5c0 3.78 3.4 6.86 8.55 11.54L12 21.35l1.45-1.32C18.6 15.36 22 12.28 22 8.5 22 5.42 19.58 3 16.5 3zm-4.4 15.55l-.1.1-.1-.1C7.14 14.24 4 11.39 4 8.5 4 6.5 5.5 5 7.5 5c1.54 0 3.04.99 3.57 2.36h1.87C13.46 5.99 14.96 5 16.5 5c2 0 3.5 1.5 3.5 3.5 0 2.89-3.14 5.74-7.9 10.05z\"></path></g>\n<g id=\"feedback\"><path d=\"M20 2H4c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-7 12h-2v-2h2v2zm0-4h-2V6h2v4z\"></path></g>\n<g id=\"file-download\"><path d=\"M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z\"></path></g>\n<g id=\"file-upload\"><path d=\"M9 16h6v-6h4l-7-7-7 7h4zm-4 2h14v2H5z\"></path></g>\n<g id=\"filter-list\"><path d=\"M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z\"></path></g>\n<g id=\"find-in-page\"><path d=\"M20 19.59V8l-6-6H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c.45 0 .85-.15 1.19-.4l-4.43-4.43c-.8.52-1.74.83-2.76.83-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5c0 1.02-.31 1.96-.83 2.75L20 19.59zM9 13c0 1.66 1.34 3 3 3s3-1.34 3-3-1.34-3-3-3-3 1.34-3 3z\"></path></g>\n<g id=\"find-replace\"><path d=\"M11 6c1.38 0 2.63.56 3.54 1.46L12 10h6V4l-2.05 2.05C14.68 4.78 12.93 4 11 4c-3.53 0-6.43 2.61-6.92 6H6.1c.46-2.28 2.48-4 4.9-4zm5.64 9.14c.66-.9 1.12-1.97 1.28-3.14H15.9c-.46 2.28-2.48 4-4.9 4-1.38 0-2.63-.56-3.54-1.46L10 12H4v6l2.05-2.05C7.32 17.22 9.07 18 11 18c1.55 0 2.98-.51 4.14-1.36L20 21.49 21.49 20l-4.85-4.86z\"></path></g>\n<g id=\"fingerprint\"><path d=\"M17.81 4.47c-.08 0-.16-.02-.23-.06C15.66 3.42 14 3 12.01 3c-1.98 0-3.86.47-5.57 1.41-.24.13-.54.04-.68-.2-.13-.24-.04-.55.2-.68C7.82 2.52 9.86 2 12.01 2c2.13 0 3.99.47 6.03 1.52.25.13.34.43.21.67-.09.18-.26.28-.44.28zM3.5 9.72c-.1 0-.2-.03-.29-.09-.23-.16-.28-.47-.12-.7.99-1.4 2.25-2.5 3.75-3.27C9.98 4.04 14 4.03 17.15 5.65c1.5.77 2.76 1.86 3.75 3.25.16.22.11.54-.12.7-.23.16-.54.11-.7-.12-.9-1.26-2.04-2.25-3.39-2.94-2.87-1.47-6.54-1.47-9.4.01-1.36.7-2.5 1.7-3.4 2.96-.08.14-.23.21-.39.21zm6.25 12.07c-.13 0-.26-.05-.35-.15-.87-.87-1.34-1.43-2.01-2.64-.69-1.23-1.05-2.73-1.05-4.34 0-2.97 2.54-5.39 5.66-5.39s5.66 2.42 5.66 5.39c0 .28-.22.5-.5.5s-.5-.22-.5-.5c0-2.42-2.09-4.39-4.66-4.39-2.57 0-4.66 1.97-4.66 4.39 0 1.44.32 2.77.93 3.85.64 1.15 1.08 1.64 1.85 2.42.19.2.19.51 0 .71-.11.1-.24.15-.37.15zm7.17-1.85c-1.19 0-2.24-.3-3.1-.89-1.49-1.01-2.38-2.65-2.38-4.39 0-.28.22-.5.5-.5s.5.22.5.5c0 1.41.72 2.74 1.94 3.56.71.48 1.54.71 2.54.71.24 0 .64-.03 1.04-.1.27-.05.53.13.58.41.05.27-.13.53-.41.58-.57.11-1.07.12-1.21.12zM14.91 22c-.04 0-.09-.01-.13-.02-1.59-.44-2.63-1.03-3.72-2.1-1.4-1.39-2.17-3.24-2.17-5.22 0-1.62 1.38-2.94 3.08-2.94 1.7 0 3.08 1.32 3.08 2.94 0 1.07.93 1.94 2.08 1.94s2.08-.87 2.08-1.94c0-3.77-3.25-6.83-7.25-6.83-2.84 0-5.44 1.58-6.61 4.03-.39.81-.59 1.76-.59 2.8 0 .78.07 2.01.67 3.61.1.26-.03.55-.29.64-.26.1-.55-.04-.64-.29-.49-1.31-.73-2.61-.73-3.96 0-1.2.23-2.29.68-3.24 1.33-2.79 4.28-4.6 7.51-4.6 4.55 0 8.25 3.51 8.25 7.83 0 1.62-1.38 2.94-3.08 2.94s-3.08-1.32-3.08-2.94c0-1.07-.93-1.94-2.08-1.94s-2.08.87-2.08 1.94c0 1.71.66 3.31 1.87 4.51.95.94 1.86 1.46 3.27 1.85.27.07.42.35.35.61-.05.23-.26.38-.47.38z\"></path></g>\n<g id=\"flag\"><path d=\"M14.4 6L14 4H5v17h2v-7h5.6l.4 2h7V6z\"></path></g>\n<g id=\"flight-land\"><path d=\"M2.5 19h19v2h-19zm7.18-5.73l4.35 1.16 5.31 1.42c.8.21 1.62-.26 1.84-1.06.21-.8-.26-1.62-1.06-1.84l-5.31-1.42-2.76-9.02L10.12 2v8.28L5.15 8.95l-.93-2.32-1.45-.39v5.17l1.6.43 5.31 1.43z\"></path></g>\n<g id=\"flight-takeoff\"><path d=\"M2.5 19h19v2h-19zm19.57-9.36c-.21-.8-1.04-1.28-1.84-1.06L14.92 10l-6.9-6.43-1.93.51 4.14 7.17-4.97 1.33-1.97-1.54-1.45.39 1.82 3.16.77 1.33 1.6-.43 5.31-1.42 4.35-1.16L21 11.49c.81-.23 1.28-1.05 1.07-1.85z\"></path></g>\n<g id=\"flip-to-back\"><path d=\"M9 7H7v2h2V7zm0 4H7v2h2v-2zm0-8c-1.11 0-2 .9-2 2h2V3zm4 12h-2v2h2v-2zm6-12v2h2c0-1.1-.9-2-2-2zm-6 0h-2v2h2V3zM9 17v-2H7c0 1.1.89 2 2 2zm10-4h2v-2h-2v2zm0-4h2V7h-2v2zm0 8c1.1 0 2-.9 2-2h-2v2zM5 7H3v12c0 1.1.89 2 2 2h12v-2H5V7zm10-2h2V3h-2v2zm0 12h2v-2h-2v2z\"></path></g>\n<g id=\"flip-to-front\"><path d=\"M3 13h2v-2H3v2zm0 4h2v-2H3v2zm2 4v-2H3c0 1.1.89 2 2 2zM3 9h2V7H3v2zm12 12h2v-2h-2v2zm4-18H9c-1.11 0-2 .9-2 2v10c0 1.1.89 2 2 2h10c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 12H9V5h10v10zm-8 6h2v-2h-2v2zm-4 0h2v-2H7v2z\"></path></g>\n<g id=\"folder\"><path d=\"M10 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2h-8l-2-2z\"></path></g>\n<g id=\"folder-open\"><path d=\"M20 6h-8l-2-2H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2zm0 12H4V8h16v10z\"></path></g>\n<g id=\"folder-shared\"><path d=\"M20 6h-8l-2-2H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2zm-5 3c1.1 0 2 .9 2 2s-.9 2-2 2-2-.9-2-2 .9-2 2-2zm4 8h-8v-1c0-1.33 2.67-2 4-2s4 .67 4 2v1z\"></path></g>\n<g id=\"font-download\"><path d=\"M9.93 13.5h4.14L12 7.98zM20 2H4c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-4.05 16.5l-1.14-3H9.17l-1.12 3H5.96l5.11-13h1.86l5.11 13h-2.09z\"></path></g>\n<g id=\"forward\"><path d=\"M12 8V4l8 8-8 8v-4H4V8z\"></path></g>\n<g id=\"fullscreen\"><path d=\"M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z\"></path></g>\n<g id=\"fullscreen-exit\"><path d=\"M5 16h3v3h2v-5H5v2zm3-8H5v2h5V5H8v3zm6 11h2v-3h3v-2h-5v5zm2-11V5h-2v5h5V8h-3z\"></path></g>\n<g id=\"gavel\"><path d=\"M1 21h12v2H1zM5.245 8.07l2.83-2.827 14.14 14.142-2.828 2.828zM12.317 1l5.657 5.656-2.83 2.83-5.654-5.66zM3.825 9.485l5.657 5.657-2.828 2.828-5.657-5.657z\"></path></g>\n<g id=\"gesture\"><path d=\"M4.59 6.89c.7-.71 1.4-1.35 1.71-1.22.5.2 0 1.03-.3 1.52-.25.42-2.86 3.89-2.86 6.31 0 1.28.48 2.34 1.34 2.98.75.56 1.74.73 2.64.46 1.07-.31 1.95-1.4 3.06-2.77 1.21-1.49 2.83-3.44 4.08-3.44 1.63 0 1.65 1.01 1.76 1.79-3.78.64-5.38 3.67-5.38 5.37 0 1.7 1.44 3.09 3.21 3.09 1.63 0 4.29-1.33 4.69-6.1H21v-2.5h-2.47c-.15-1.65-1.09-4.2-4.03-4.2-2.25 0-4.18 1.91-4.94 2.84-.58.73-2.06 2.48-2.29 2.72-.25.3-.68.84-1.11.84-.45 0-.72-.83-.36-1.92.35-1.09 1.4-2.86 1.85-3.52.78-1.14 1.3-1.92 1.3-3.28C8.95 3.69 7.31 3 6.44 3 5.12 3 3.97 4 3.72 4.25c-.36.36-.66.66-.88.93l1.75 1.71zm9.29 11.66c-.31 0-.74-.26-.74-.72 0-.6.73-2.2 2.87-2.76-.3 2.69-1.43 3.48-2.13 3.48z\"></path></g>\n<g id=\"get-app\"><path d=\"M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z\"></path></g>\n<g id=\"gif\"><path d=\"M11.5 9H13v6h-1.5zM9 9H6c-.6 0-1 .5-1 1v4c0 .5.4 1 1 1h3c.6 0 1-.5 1-1v-2H8.5v1.5h-2v-3H10V10c0-.5-.4-1-1-1zm10 1.5V9h-4.5v6H16v-2h2v-1.5h-2v-1z\"></path></g>\n<g id=\"grade\"><path d=\"M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z\"></path></g>\n<g id=\"group-work\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zM8 17.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5zM9.5 8c0-1.38 1.12-2.5 2.5-2.5s2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5S9.5 9.38 9.5 8zm6.5 9.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z\"></path></g>\n<g id=\"help\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 17h-2v-2h2v2zm2.07-7.75l-.9.92C13.45 12.9 13 13.5 13 15h-2v-.5c0-1.1.45-2.1 1.17-2.83l1.24-1.26c.37-.36.59-.86.59-1.41 0-1.1-.9-2-2-2s-2 .9-2 2H8c0-2.21 1.79-4 4-4s4 1.79 4 4c0 .88-.36 1.68-.93 2.25z\"></path></g>\n<g id=\"help-outline\"><path d=\"M11 18h2v-2h-2v2zm1-16C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm0-14c-2.21 0-4 1.79-4 4h2c0-1.1.9-2 2-2s2 .9 2 2c0 2-3 1.75-3 5h2c0-2.25 3-2.5 3-5 0-2.21-1.79-4-4-4z\"></path></g>\n<g id=\"highlight-off\"><path d=\"M14.59 8L12 10.59 9.41 8 8 9.41 10.59 12 8 14.59 9.41 16 12 13.41 14.59 16 16 14.59 13.41 12 16 9.41 14.59 8zM12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z\"></path></g>\n<g id=\"history\"><path d=\"M13 3c-4.97 0-9 4.03-9 9H1l3.89 3.89.07.14L9 12H6c0-3.87 3.13-7 7-7s7 3.13 7 7-3.13 7-7 7c-1.93 0-3.68-.79-4.94-2.06l-1.42 1.42C8.27 19.99 10.51 21 13 21c4.97 0 9-4.03 9-9s-4.03-9-9-9zm-1 5v5l4.28 2.54.72-1.21-3.5-2.08V8H12z\"></path></g>\n<g id=\"home\"><path d=\"M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z\"></path></g>\n<g id=\"hourglass-empty\"><path d=\"M6 2v6h.01L6 8.01 10 12l-4 4 .01.01H6V22h12v-5.99h-.01L18 16l-4-4 4-3.99-.01-.01H18V2H6zm10 14.5V20H8v-3.5l4-4 4 4zm-4-5l-4-4V4h8v3.5l-4 4z\"></path></g>\n<g id=\"hourglass-full\"><path d=\"M6 2v6h.01L6 8.01 10 12l-4 4 .01.01H6V22h12v-5.99h-.01L18 16l-4-4 4-3.99-.01-.01H18V2H6z\"></path></g>\n<g id=\"http\"><path d=\"M4.5 11h-2V9H1v6h1.5v-2.5h2V15H6V9H4.5v2zm2.5-.5h1.5V15H10v-4.5h1.5V9H7v1.5zm5.5 0H14V15h1.5v-4.5H17V9h-4.5v1.5zm9-1.5H18v6h1.5v-2h2c.8 0 1.5-.7 1.5-1.5v-1c0-.8-.7-1.5-1.5-1.5zm0 2.5h-2v-1h2v1z\"></path></g>\n<g id=\"https\"><path d=\"M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zm-6 9c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zm3.1-9H8.9V6c0-1.71 1.39-3.1 3.1-3.1 1.71 0 3.1 1.39 3.1 3.1v2z\"></path></g>\n<g id=\"important-devices\"><path d=\"M23 11.01L18 11c-.55 0-1 .45-1 1v9c0 .55.45 1 1 1h5c.55 0 1-.45 1-1v-9c0-.55-.45-.99-1-.99zM23 20h-5v-7h5v7zM20 2H2C.89 2 0 2.89 0 4v12c0 1.1.89 2 2 2h7v2H7v2h8v-2h-2v-2h2v-2H2V4h18v5h2V4c0-1.11-.9-2-2-2zm-8.03 7L11 6l-.97 3H7l2.47 1.76-.94 2.91 2.47-1.8 2.47 1.8-.94-2.91L15 9h-3.03z\"></path></g>\n<g id=\"inbox\"><path d=\"M19 3H4.99c-1.11 0-1.98.89-1.98 2L3 19c0 1.1.88 2 1.99 2H19c1.1 0 2-.9 2-2V5c0-1.11-.9-2-2-2zm0 12h-4c0 1.66-1.35 3-3 3s-3-1.34-3-3H4.99V5H19v10z\"></path></g>\n<g id=\"indeterminate-check-box\"><path d=\"M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-2 10H7v-2h10v2z\"></path></g>\n<g id=\"info\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z\"></path></g>\n<g id=\"info-outline\"><path d=\"M11 17h2v-6h-2v6zm1-15C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zM11 9h2V7h-2v2z\"></path></g>\n<g id=\"input\"><path d=\"M21 3.01H3c-1.1 0-2 .9-2 2V9h2V4.99h18v14.03H3V15H1v4.01c0 1.1.9 1.98 2 1.98h18c1.1 0 2-.88 2-1.98v-14c0-1.11-.9-2-2-2zM11 16l4-4-4-4v3H1v2h10v3z\"></path></g>\n<g id=\"invert-colors\"><path d=\"M17.66 7.93L12 2.27 6.34 7.93c-3.12 3.12-3.12 8.19 0 11.31C7.9 20.8 9.95 21.58 12 21.58c2.05 0 4.1-.78 5.66-2.34 3.12-3.12 3.12-8.19 0-11.31zM12 19.59c-1.6 0-3.11-.62-4.24-1.76C6.62 16.69 6 15.19 6 13.59s.62-3.11 1.76-4.24L12 5.1v14.49z\"></path></g>\n<g id=\"label\"><path d=\"M17.63 5.84C17.27 5.33 16.67 5 16 5L5 5.01C3.9 5.01 3 5.9 3 7v10c0 1.1.9 1.99 2 1.99L16 19c.67 0 1.27-.33 1.63-.84L22 12l-4.37-6.16z\"></path></g>\n<g id=\"label-outline\"><path d=\"M17.63 5.84C17.27 5.33 16.67 5 16 5L5 5.01C3.9 5.01 3 5.9 3 7v10c0 1.1.9 1.99 2 1.99L16 19c.67 0 1.27-.33 1.63-.84L22 12l-4.37-6.16zM16 17H5V7h11l3.55 5L16 17z\"></path></g>\n<g id=\"language\"><path d=\"M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zm6.93 6h-2.95c-.32-1.25-.78-2.45-1.38-3.56 1.84.63 3.37 1.91 4.33 3.56zM12 4.04c.83 1.2 1.48 2.53 1.91 3.96h-3.82c.43-1.43 1.08-2.76 1.91-3.96zM4.26 14C4.1 13.36 4 12.69 4 12s.1-1.36.26-2h3.38c-.08.66-.14 1.32-.14 2 0 .68.06 1.34.14 2H4.26zm.82 2h2.95c.32 1.25.78 2.45 1.38 3.56-1.84-.63-3.37-1.9-4.33-3.56zm2.95-8H5.08c.96-1.66 2.49-2.93 4.33-3.56C8.81 5.55 8.35 6.75 8.03 8zM12 19.96c-.83-1.2-1.48-2.53-1.91-3.96h3.82c-.43 1.43-1.08 2.76-1.91 3.96zM14.34 14H9.66c-.09-.66-.16-1.32-.16-2 0-.68.07-1.35.16-2h4.68c.09.65.16 1.32.16 2 0 .68-.07 1.34-.16 2zm.25 5.56c.6-1.11 1.06-2.31 1.38-3.56h2.95c-.96 1.65-2.49 2.93-4.33 3.56zM16.36 14c.08-.66.14-1.32.14-2 0-.68-.06-1.34-.14-2h3.38c.16.64.26 1.31.26 2s-.1 1.36-.26 2h-3.38z\"></path></g>\n<g id=\"launch\"><path d=\"M19 19H5V5h7V3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2v-7h-2v7zM14 3v2h3.59l-9.83 9.83 1.41 1.41L19 6.41V10h2V3h-7z\"></path></g>\n<g id=\"lightbulb-outline\"><path d=\"M9 21c0 .55.45 1 1 1h4c.55 0 1-.45 1-1v-1H9v1zm3-19C8.14 2 5 5.14 5 9c0 2.38 1.19 4.47 3 5.74V17c0 .55.45 1 1 1h6c.55 0 1-.45 1-1v-2.26c1.81-1.27 3-3.36 3-5.74 0-3.86-3.14-7-7-7zm2.85 11.1l-.85.6V16h-4v-2.3l-.85-.6C7.8 12.16 7 10.63 7 9c0-2.76 2.24-5 5-5s5 2.24 5 5c0 1.63-.8 3.16-2.15 4.1z\"></path></g>\n<g id=\"line-style\"><path d=\"M3 16h5v-2H3v2zm6.5 0h5v-2h-5v2zm6.5 0h5v-2h-5v2zM3 20h2v-2H3v2zm4 0h2v-2H7v2zm4 0h2v-2h-2v2zm4 0h2v-2h-2v2zm4 0h2v-2h-2v2zM3 12h8v-2H3v2zm10 0h8v-2h-8v2zM3 4v4h18V4H3z\"></path></g>\n<g id=\"line-weight\"><path d=\"M3 17h18v-2H3v2zm0 3h18v-1H3v1zm0-7h18v-3H3v3zm0-9v4h18V4H3z\"></path></g>\n<g id=\"link\"><path d=\"M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z\"></path></g>\n<g id=\"list\"><path d=\"M3 13h2v-2H3v2zm0 4h2v-2H3v2zm0-8h2V7H3v2zm4 4h14v-2H7v2zm0 4h14v-2H7v2zM7 7v2h14V7H7z\"></path></g>\n<g id=\"lock\"><path d=\"M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zm-6 9c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zm3.1-9H8.9V6c0-1.71 1.39-3.1 3.1-3.1 1.71 0 3.1 1.39 3.1 3.1v2z\"></path></g>\n<g id=\"lock-open\"><path d=\"M12 17c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm6-9h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6h1.9c0-1.71 1.39-3.1 3.1-3.1 1.71 0 3.1 1.39 3.1 3.1v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zm0 12H6V10h12v10z\"></path></g>\n<g id=\"lock-outline\"><path d=\"M12 17c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm6-9h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zM8.9 6c0-1.71 1.39-3.1 3.1-3.1s3.1 1.39 3.1 3.1v2H8.9V6zM18 20H6V10h12v10z\"></path></g>\n<g id=\"loyalty\"><path d=\"M21.41 11.58l-9-9C12.05 2.22 11.55 2 11 2H4c-1.1 0-2 .9-2 2v7c0 .55.22 1.05.59 1.42l9 9c.36.36.86.58 1.41.58.55 0 1.05-.22 1.41-.59l7-7c.37-.36.59-.86.59-1.41 0-.55-.23-1.06-.59-1.42zM5.5 7C4.67 7 4 6.33 4 5.5S4.67 4 5.5 4 7 4.67 7 5.5 6.33 7 5.5 7zm11.77 8.27L13 19.54l-4.27-4.27C8.28 14.81 8 14.19 8 13.5c0-1.38 1.12-2.5 2.5-2.5.69 0 1.32.28 1.77.74l.73.72.73-.73c.45-.45 1.08-.73 1.77-.73 1.38 0 2.5 1.12 2.5 2.5 0 .69-.28 1.32-.73 1.77z\"></path></g>\n<g id=\"mail\"><path d=\"M20 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 4l-8 5-8-5V6l8 5 8-5v2z\"></path></g>\n<g id=\"markunread\"><path d=\"M20 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 4l-8 5-8-5V6l8 5 8-5v2z\"></path></g>\n<g id=\"markunread-mailbox\"><path d=\"M20 6H10v6H8V4h6V0H6v6H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2z\"></path></g>\n<g id=\"menu\"><path d=\"M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z\"></path></g>\n<g id=\"more-horiz\"><path d=\"M6 10c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm12 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm-6 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z\"></path></g>\n<g id=\"more-vert\"><path d=\"M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z\"></path></g>\n<g id=\"motorcycle\"><path d=\"M19.44 9.03L15.41 5H11v2h3.59l2 2H5c-2.8 0-5 2.2-5 5s2.2 5 5 5c2.46 0 4.45-1.69 4.9-4h1.65l2.77-2.77c-.21.54-.32 1.14-.32 1.77 0 2.8 2.2 5 5 5s5-2.2 5-5c0-2.65-1.97-4.77-4.56-4.97zM7.82 15C7.4 16.15 6.28 17 5 17c-1.63 0-3-1.37-3-3s1.37-3 3-3c1.28 0 2.4.85 2.82 2H5v2h2.82zM19 17c-1.66 0-3-1.34-3-3s1.34-3 3-3 3 1.34 3 3-1.34 3-3 3z\"></path></g>\n<g id=\"move-to-inbox\"><path d=\"M19 3H4.99c-1.11 0-1.98.9-1.98 2L3 19c0 1.1.88 2 1.99 2H19c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 12h-4c0 1.66-1.35 3-3 3s-3-1.34-3-3H4.99V5H19v10zm-3-5h-2V7h-4v3H8l4 4 4-4z\"></path></g>\n<g id=\"next-week\"><path d=\"M20 7h-4V5c0-.55-.22-1.05-.59-1.41C15.05 3.22 14.55 3 14 3h-4c-1.1 0-2 .9-2 2v2H4c-1.1 0-2 .9-2 2v11c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V9c0-1.1-.9-2-2-2zM10 5h4v2h-4V5zm1 13.5l-1-1 3-3-3-3 1-1 4 4-4 4z\"></path></g>\n<g id=\"note-add\"><path d=\"M14 2H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6zm2 14h-3v3h-2v-3H8v-2h3v-3h2v3h3v2zm-3-7V3.5L18.5 9H13z\"></path></g>\n<g id=\"offline-pin\"><path d=\"M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10 10-4.5 10-10S17.5 2 12 2zm5 16H7v-2h10v2zm-6.7-4L7 10.7l1.4-1.4 1.9 1.9 5.3-5.3L17 7.3 10.3 14z\"></path></g>\n<g id=\"opacity\"><path d=\"M17.66 8L12 2.35 6.34 8C4.78 9.56 4 11.64 4 13.64s.78 4.11 2.34 5.67 3.61 2.35 5.66 2.35 4.1-.79 5.66-2.35S20 15.64 20 13.64 19.22 9.56 17.66 8zM6 14c.01-2 .62-3.27 1.76-4.4L12 5.27l4.24 4.38C17.38 10.77 17.99 12 18 14H6z\"></path></g>\n<g id=\"open-in-browser\"><path d=\"M19 4H5c-1.11 0-2 .9-2 2v12c0 1.1.89 2 2 2h4v-2H5V8h14v10h-4v2h4c1.1 0 2-.9 2-2V6c0-1.1-.89-2-2-2zm-7 6l-4 4h3v6h2v-6h3l-4-4z\"></path></g>\n<g id=\"open-in-new\"><path d=\"M19 19H5V5h7V3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2v-7h-2v7zM14 3v2h3.59l-9.83 9.83 1.41 1.41L19 6.41V10h2V3h-7z\"></path></g>\n<g id=\"open-with\"><path d=\"M10 9h4V6h3l-5-5-5 5h3v3zm-1 1H6V7l-5 5 5 5v-3h3v-4zm14 2l-5-5v3h-3v4h3v3l5-5zm-9 3h-4v3H7l5 5 5-5h-3v-3z\"></path></g>\n<g id=\"pageview\"><path d=\"M11.5 9C10.12 9 9 10.12 9 11.5s1.12 2.5 2.5 2.5 2.5-1.12 2.5-2.5S12.88 9 11.5 9zM20 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm-3.21 14.21l-2.91-2.91c-.69.44-1.51.7-2.39.7C9.01 16 7 13.99 7 11.5S9.01 7 11.5 7 16 9.01 16 11.5c0 .88-.26 1.69-.7 2.39l2.91 2.9-1.42 1.42z\"></path></g>\n<g id=\"pan-tool\"><path d=\"M23 5.5V20c0 2.2-1.8 4-4 4h-7.3c-1.08 0-2.1-.43-2.85-1.19L1 14.83s1.26-1.23 1.3-1.25c.22-.19.49-.29.79-.29.22 0 .42.06.6.16.04.01 4.31 2.46 4.31 2.46V4c0-.83.67-1.5 1.5-1.5S11 3.17 11 4v7h1V1.5c0-.83.67-1.5 1.5-1.5S15 .67 15 1.5V11h1V2.5c0-.83.67-1.5 1.5-1.5s1.5.67 1.5 1.5V11h1V5.5c0-.83.67-1.5 1.5-1.5s1.5.67 1.5 1.5z\"></path></g>\n<g id=\"payment\"><path d=\"M20 4H4c-1.11 0-1.99.89-1.99 2L2 18c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V6c0-1.11-.89-2-2-2zm0 14H4v-6h16v6zm0-10H4V6h16v2z\"></path></g>\n<g id=\"perm-camera-mic\"><path d=\"M20 5h-3.17L15 3H9L7.17 5H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h7v-2.09c-2.83-.48-5-2.94-5-5.91h2c0 2.21 1.79 4 4 4s4-1.79 4-4h2c0 2.97-2.17 5.43-5 5.91V21h7c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm-6 8c0 1.1-.9 2-2 2s-2-.9-2-2V9c0-1.1.9-2 2-2s2 .9 2 2v4z\"></path></g>\n<g id=\"perm-contact-calendar\"><path d=\"M19 3h-1V1h-2v2H8V1H6v2H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-7 3c1.66 0 3 1.34 3 3s-1.34 3-3 3-3-1.34-3-3 1.34-3 3-3zm6 12H6v-1c0-2 4-3.1 6-3.1s6 1.1 6 3.1v1z\"></path></g>\n<g id=\"perm-data-setting\"><path d=\"M18.99 11.5c.34 0 .67.03 1 .07L20 0 0 20h11.56c-.04-.33-.07-.66-.07-1 0-4.14 3.36-7.5 7.5-7.5zm3.71 7.99c.02-.16.04-.32.04-.49 0-.17-.01-.33-.04-.49l1.06-.83c.09-.08.12-.21.06-.32l-1-1.73c-.06-.11-.19-.15-.31-.11l-1.24.5c-.26-.2-.54-.37-.85-.49l-.19-1.32c-.01-.12-.12-.21-.24-.21h-2c-.12 0-.23.09-.25.21l-.19 1.32c-.3.13-.59.29-.85.49l-1.24-.5c-.11-.04-.24 0-.31.11l-1 1.73c-.06.11-.04.24.06.32l1.06.83c-.02.16-.03.32-.03.49 0 .17.01.33.03.49l-1.06.83c-.09.08-.12.21-.06.32l1 1.73c.06.11.19.15.31.11l1.24-.5c.26.2.54.37.85.49l.19 1.32c.02.12.12.21.25.21h2c.12 0 .23-.09.25-.21l.19-1.32c.3-.13.59-.29.84-.49l1.25.5c.11.04.24 0 .31-.11l1-1.73c.06-.11.03-.24-.06-.32l-1.07-.83zm-3.71 1.01c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5z\"></path></g>\n<g id=\"perm-device-information\"><path d=\"M13 7h-2v2h2V7zm0 4h-2v6h2v-6zm4-9.99L7 1c-1.1 0-2 .9-2 2v18c0 1.1.9 2 2 2h10c1.1 0 2-.9 2-2V3c0-1.1-.9-1.99-2-1.99zM17 19H7V5h10v14z\"></path></g>\n<g id=\"perm-identity\"><path d=\"M12 5.9c1.16 0 2.1.94 2.1 2.1s-.94 2.1-2.1 2.1S9.9 9.16 9.9 8s.94-2.1 2.1-2.1m0 9c2.97 0 6.1 1.46 6.1 2.1v1.1H5.9V17c0-.64 3.13-2.1 6.1-2.1M12 4C9.79 4 8 5.79 8 8s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4zm0 9c-2.67 0-8 1.34-8 4v3h16v-3c0-2.66-5.33-4-8-4z\"></path></g>\n<g id=\"perm-media\"><path d=\"M2 6H0v5h.01L0 20c0 1.1.9 2 2 2h18v-2H2V6zm20-2h-8l-2-2H6c-1.1 0-1.99.9-1.99 2L4 16c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zM7 15l4.5-6 3.5 4.51 2.5-3.01L21 15H7z\"></path></g>\n<g id=\"perm-phone-msg\"><path d=\"M20 15.5c-1.25 0-2.45-.2-3.57-.57-.35-.11-.74-.03-1.02.24l-2.2 2.2c-2.83-1.44-5.15-3.75-6.59-6.58l2.2-2.21c.28-.27.36-.66.25-1.01C8.7 6.45 8.5 5.25 8.5 4c0-.55-.45-1-1-1H4c-.55 0-1 .45-1 1 0 9.39 7.61 17 17 17 .55 0 1-.45 1-1v-3.5c0-.55-.45-1-1-1zM12 3v10l3-3h6V3h-9z\"></path></g>\n<g id=\"perm-scan-wifi\"><path d=\"M12 3C6.95 3 3.15 4.85 0 7.23L12 22 24 7.25C20.85 4.87 17.05 3 12 3zm1 13h-2v-6h2v6zm-2-8V6h2v2h-2z\"></path></g>\n<g id=\"pets\"><circle cx=\"4.5\" cy=\"9.5\" r=\"2.5\"></circle><circle cx=\"9\" cy=\"5.5\" r=\"2.5\"></circle><circle cx=\"15\" cy=\"5.5\" r=\"2.5\"></circle><circle cx=\"19.5\" cy=\"9.5\" r=\"2.5\"></circle><path d=\"M17.34 14.86c-.87-1.02-1.6-1.89-2.48-2.91-.46-.54-1.05-1.08-1.75-1.32-.11-.04-.22-.07-.33-.09-.25-.04-.52-.04-.78-.04s-.53 0-.79.05c-.11.02-.22.05-.33.09-.7.24-1.28.78-1.75 1.32-.87 1.02-1.6 1.89-2.48 2.91-1.31 1.31-2.92 2.76-2.62 4.79.29 1.02 1.02 2.03 2.33 2.32.73.15 3.06-.44 5.54-.44h.18c2.48 0 4.81.58 5.54.44 1.31-.29 2.04-1.31 2.33-2.32.31-2.04-1.3-3.49-2.61-4.8z\"></path></g>\n<g id=\"picture-in-picture\"><path d=\"M19 7h-8v6h8V7zm2-4H3c-1.1 0-2 .9-2 2v14c0 1.1.9 1.98 2 1.98h18c1.1 0 2-.88 2-1.98V5c0-1.1-.9-2-2-2zm0 16.01H3V4.98h18v14.03z\"></path></g>\n<g id=\"picture-in-picture-alt\"><path d=\"M19 11h-8v6h8v-6zm4 8V4.98C23 3.88 22.1 3 21 3H3c-1.1 0-2 .88-2 1.98V19c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2zm-2 .02H3V4.97h18v14.05z\"></path></g>\n<g id=\"play-for-work\"><path d=\"M11 5v5.59H7.5l4.5 4.5 4.5-4.5H13V5h-2zm-5 9c0 3.31 2.69 6 6 6s6-2.69 6-6h-2c0 2.21-1.79 4-4 4s-4-1.79-4-4H6z\"></path></g>\n<g id=\"polymer\"><path d=\"M19 4h-4L7.11 16.63 4.5 12 9 4H5L.5 12 5 20h4l7.89-12.63L19.5 12 15 20h4l4.5-8z\"></path></g>\n<g id=\"power-settings-new\"><path d=\"M13 3h-2v10h2V3zm4.83 2.17l-1.42 1.42C17.99 7.86 19 9.81 19 12c0 3.87-3.13 7-7 7s-7-3.13-7-7c0-2.19 1.01-4.14 2.58-5.42L6.17 5.17C4.23 6.82 3 9.26 3 12c0 4.97 4.03 9 9 9s9-4.03 9-9c0-2.74-1.23-5.18-3.17-6.83z\"></path></g>\n<g id=\"pregnant-woman\"><path d=\"M9 4c0-1.11.89-2 2-2s2 .89 2 2-.89 2-2 2-2-.89-2-2zm7 9c-.01-1.34-.83-2.51-2-3 0-1.66-1.34-3-3-3s-3 1.34-3 3v7h2v5h3v-5h3v-4z\"></path></g>\n<g id=\"print\"><path d=\"M19 8H5c-1.66 0-3 1.34-3 3v6h4v4h12v-4h4v-6c0-1.66-1.34-3-3-3zm-3 11H8v-5h8v5zm3-7c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm-1-9H6v4h12V3z\"></path></g>\n<g id=\"query-builder\"><path d=\"M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zm.5-13H11v6l5.25 3.15.75-1.23-4.5-2.67z\"></path></g>\n<g id=\"question-answer\"><path d=\"M21 6h-2v9H6v2c0 .55.45 1 1 1h11l4 4V7c0-.55-.45-1-1-1zm-4 6V3c0-.55-.45-1-1-1H3c-.55 0-1 .45-1 1v14l4-4h10c.55 0 1-.45 1-1z\"></path></g>\n<g id=\"radio-button-checked\"><path d=\"M12 7c-2.76 0-5 2.24-5 5s2.24 5 5 5 5-2.24 5-5-2.24-5-5-5zm0-5C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z\"></path></g>\n<g id=\"radio-button-unchecked\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z\"></path></g>\n<g id=\"receipt\"><path d=\"M18 17H6v-2h12v2zm0-4H6v-2h12v2zm0-4H6V7h12v2zM3 22l1.5-1.5L6 22l1.5-1.5L9 22l1.5-1.5L12 22l1.5-1.5L15 22l1.5-1.5L18 22l1.5-1.5L21 22V2l-1.5 1.5L18 2l-1.5 1.5L15 2l-1.5 1.5L12 2l-1.5 1.5L9 2 7.5 3.5 6 2 4.5 3.5 3 2v20z\"></path></g>\n<g id=\"record-voice-over\"><circle cx=\"9\" cy=\"9\" r=\"4\"></circle><path d=\"M9 15c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4zm7.76-9.64l-1.68 1.69c.84 1.18.84 2.71 0 3.89l1.68 1.69c2.02-2.02 2.02-5.07 0-7.27zM20.07 2l-1.63 1.63c2.77 3.02 2.77 7.56 0 10.74L20.07 16c3.9-3.89 3.91-9.95 0-14z\"></path></g>\n<g id=\"redeem\"><path d=\"M20 6h-2.18c.11-.31.18-.65.18-1 0-1.66-1.34-3-3-3-1.05 0-1.96.54-2.5 1.35l-.5.67-.5-.68C10.96 2.54 10.05 2 9 2 7.34 2 6 3.34 6 5c0 .35.07.69.18 1H4c-1.11 0-1.99.89-1.99 2L2 19c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V8c0-1.11-.89-2-2-2zm-5-2c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zM9 4c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm11 15H4v-2h16v2zm0-5H4V8h5.08L7 10.83 8.62 12 11 8.76l1-1.36 1 1.36L15.38 12 17 10.83 14.92 8H20v6z\"></path></g>\n<g id=\"redo\"><path d=\"M18.4 10.6C16.55 8.99 14.15 8 11.5 8c-4.65 0-8.58 3.03-9.96 7.22L3.9 16c1.05-3.19 4.05-5.5 7.6-5.5 1.95 0 3.73.72 5.12 1.88L13 16h9V7l-3.6 3.6z\"></path></g>\n<g id=\"refresh\"><path d=\"M17.65 6.35C16.2 4.9 14.21 4 12 4c-4.42 0-7.99 3.58-7.99 8s3.57 8 7.99 8c3.73 0 6.84-2.55 7.73-6h-2.08c-.82 2.33-3.04 4-5.65 4-3.31 0-6-2.69-6-6s2.69-6 6-6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z\"></path></g>\n<g id=\"remove\"><path d=\"M19 13H5v-2h14v2z\"></path></g>\n<g id=\"remove-circle\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm5 11H7v-2h10v2z\"></path></g>\n<g id=\"remove-circle-outline\"><path d=\"M7 11v2h10v-2H7zm5-9C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z\"></path></g>\n<g id=\"reorder\"><path d=\"M3 15h18v-2H3v2zm0 4h18v-2H3v2zm0-8h18V9H3v2zm0-6v2h18V5H3z\"></path></g>\n<g id=\"reply\"><path d=\"M10 9V5l-7 7 7 7v-4.1c5 0 8.5 1.6 11 5.1-1-5-4-10-11-11z\"></path></g>\n<g id=\"reply-all\"><path d=\"M7 8V5l-7 7 7 7v-3l-4-4 4-4zm6 1V5l-7 7 7 7v-4.1c5 0 8.5 1.6 11 5.1-1-5-4-10-11-11z\"></path></g>\n<g id=\"report\"><path d=\"M15.73 3H8.27L3 8.27v7.46L8.27 21h7.46L21 15.73V8.27L15.73 3zM12 17.3c-.72 0-1.3-.58-1.3-1.3 0-.72.58-1.3 1.3-1.3.72 0 1.3.58 1.3 1.3 0 .72-.58 1.3-1.3 1.3zm1-4.3h-2V7h2v6z\"></path></g>\n<g id=\"report-problem\"><path d=\"M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z\"></path></g>\n<g id=\"restore\"><path d=\"M13 3c-4.97 0-9 4.03-9 9H1l3.89 3.89.07.14L9 12H6c0-3.87 3.13-7 7-7s7 3.13 7 7-3.13 7-7 7c-1.93 0-3.68-.79-4.94-2.06l-1.42 1.42C8.27 19.99 10.51 21 13 21c4.97 0 9-4.03 9-9s-4.03-9-9-9zm-1 5v5l4.28 2.54.72-1.21-3.5-2.08V8H12z\"></path></g>\n<g id=\"room\"><path d=\"M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z\"></path></g>\n<g id=\"rounded-corner\"><path d=\"M19 19h2v2h-2v-2zm0-2h2v-2h-2v2zM3 13h2v-2H3v2zm0 4h2v-2H3v2zm0-8h2V7H3v2zm0-4h2V3H3v2zm4 0h2V3H7v2zm8 16h2v-2h-2v2zm-4 0h2v-2h-2v2zm4 0h2v-2h-2v2zm-8 0h2v-2H7v2zm-4 0h2v-2H3v2zM21 8c0-2.76-2.24-5-5-5h-5v2h5c1.65 0 3 1.35 3 3v5h2V8z\"></path></g>\n<g id=\"rowing\"><path d=\"M8.5 14.5L4 19l1.5 1.5L9 17h2l-2.5-2.5zM15 1c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm6 20.01L18 24l-2.99-3.01V19.5l-7.1-7.09c-.31.05-.61.07-.91.07v-2.16c1.66.03 3.61-.87 4.67-2.04l1.4-1.55c.19-.21.43-.38.69-.5.29-.14.62-.23.96-.23h.03C15.99 6.01 17 7.02 17 8.26v5.75c0 .84-.35 1.61-.92 2.16l-3.58-3.58v-2.27c-.63.52-1.43 1.02-2.29 1.39L16.5 18H18l3 3.01z\"></path></g>\n<g id=\"save\"><path d=\"M17 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V7l-4-4zm-5 16c-1.66 0-3-1.34-3-3s1.34-3 3-3 3 1.34 3 3-1.34 3-3 3zm3-10H5V5h10v4z\"></path></g>\n<g id=\"schedule\"><path d=\"M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zm.5-13H11v6l5.25 3.15.75-1.23-4.5-2.67z\"></path></g>\n<g id=\"search\"><path d=\"M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z\"></path></g>\n<g id=\"select-all\"><path d=\"M3 5h2V3c-1.1 0-2 .9-2 2zm0 8h2v-2H3v2zm4 8h2v-2H7v2zM3 9h2V7H3v2zm10-6h-2v2h2V3zm6 0v2h2c0-1.1-.9-2-2-2zM5 21v-2H3c0 1.1.9 2 2 2zm-2-4h2v-2H3v2zM9 3H7v2h2V3zm2 18h2v-2h-2v2zm8-8h2v-2h-2v2zm0 8c1.1 0 2-.9 2-2h-2v2zm0-12h2V7h-2v2zm0 8h2v-2h-2v2zm-4 4h2v-2h-2v2zm0-16h2V3h-2v2zM7 17h10V7H7v10zm2-8h6v6H9V9z\"></path></g>\n<g id=\"send\"><path d=\"M2.01 21L23 12 2.01 3 2 10l15 2-15 2z\"></path></g>\n<g id=\"settings\"><path d=\"M19.43 12.98c.04-.32.07-.64.07-.98s-.03-.66-.07-.98l2.11-1.65c.19-.15.24-.42.12-.64l-2-3.46c-.12-.22-.39-.3-.61-.22l-2.49 1c-.52-.4-1.08-.73-1.69-.98l-.38-2.65C14.46 2.18 14.25 2 14 2h-4c-.25 0-.46.18-.49.42l-.38 2.65c-.61.25-1.17.59-1.69.98l-2.49-1c-.23-.09-.49 0-.61.22l-2 3.46c-.13.22-.07.49.12.64l2.11 1.65c-.04.32-.07.65-.07.98s.03.66.07.98l-2.11 1.65c-.19.15-.24.42-.12.64l2 3.46c.12.22.39.3.61.22l2.49-1c.52.4 1.08.73 1.69.98l.38 2.65c.03.24.24.42.49.42h4c.25 0 .46-.18.49-.42l.38-2.65c.61-.25 1.17-.59 1.69-.98l2.49 1c.23.09.49 0 .61-.22l2-3.46c.12-.22.07-.49-.12-.64l-2.11-1.65zM12 15.5c-1.93 0-3.5-1.57-3.5-3.5s1.57-3.5 3.5-3.5 3.5 1.57 3.5 3.5-1.57 3.5-3.5 3.5z\"></path></g>\n<g id=\"settings-applications\"><path d=\"M12 10c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm7-7H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.11 0 2-.9 2-2V5c0-1.1-.89-2-2-2zm-1.75 9c0 .23-.02.46-.05.68l1.48 1.16c.13.11.17.3.08.45l-1.4 2.42c-.09.15-.27.21-.43.15l-1.74-.7c-.36.28-.76.51-1.18.69l-.26 1.85c-.03.17-.18.3-.35.3h-2.8c-.17 0-.32-.13-.35-.29l-.26-1.85c-.43-.18-.82-.41-1.18-.69l-1.74.7c-.16.06-.34 0-.43-.15l-1.4-2.42c-.09-.15-.05-.34.08-.45l1.48-1.16c-.03-.23-.05-.46-.05-.69 0-.23.02-.46.05-.68l-1.48-1.16c-.13-.11-.17-.3-.08-.45l1.4-2.42c.09-.15.27-.21.43-.15l1.74.7c.36-.28.76-.51 1.18-.69l.26-1.85c.03-.17.18-.3.35-.3h2.8c.17 0 .32.13.35.29l.26 1.85c.43.18.82.41 1.18.69l1.74-.7c.16-.06.34 0 .43.15l1.4 2.42c.09.15.05.34-.08.45l-1.48 1.16c.03.23.05.46.05.69z\"></path></g>\n<g id=\"settings-backup-restore\"><path d=\"M14 12c0-1.1-.9-2-2-2s-2 .9-2 2 .9 2 2 2 2-.9 2-2zm-2-9c-4.97 0-9 4.03-9 9H0l4 4 4-4H5c0-3.87 3.13-7 7-7s7 3.13 7 7-3.13 7-7 7c-1.51 0-2.91-.49-4.06-1.3l-1.42 1.44C8.04 20.3 9.94 21 12 21c4.97 0 9-4.03 9-9s-4.03-9-9-9z\"></path></g>\n<g id=\"settings-bluetooth\"><path d=\"M11 24h2v-2h-2v2zm-4 0h2v-2H7v2zm8 0h2v-2h-2v2zm2.71-18.29L12 0h-1v7.59L6.41 3 5 4.41 10.59 10 5 15.59 6.41 17 11 12.41V20h1l5.71-5.71-4.3-4.29 4.3-4.29zM13 3.83l1.88 1.88L13 7.59V3.83zm1.88 10.46L13 16.17v-3.76l1.88 1.88z\"></path></g>\n<g id=\"settings-brightness\"><path d=\"M21 3H3c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16.01H3V4.99h18v14.02zM8 16h2.5l1.5 1.5 1.5-1.5H16v-2.5l1.5-1.5-1.5-1.5V8h-2.5L12 6.5 10.5 8H8v2.5L6.5 12 8 13.5V16zm4-7c1.66 0 3 1.34 3 3s-1.34 3-3 3V9z\"></path></g>\n<g id=\"settings-cell\"><path d=\"M7 24h2v-2H7v2zm4 0h2v-2h-2v2zm4 0h2v-2h-2v2zM16 .01L8 0C6.9 0 6 .9 6 2v16c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V2c0-1.1-.9-1.99-2-1.99zM16 16H8V4h8v12z\"></path></g>\n<g id=\"settings-ethernet\"><path d=\"M7.77 6.76L6.23 5.48.82 12l5.41 6.52 1.54-1.28L3.42 12l4.35-5.24zM7 13h2v-2H7v2zm10-2h-2v2h2v-2zm-6 2h2v-2h-2v2zm6.77-7.52l-1.54 1.28L20.58 12l-4.35 5.24 1.54 1.28L23.18 12l-5.41-6.52z\"></path></g>\n<g id=\"settings-input-antenna\"><path d=\"M12 5c-3.87 0-7 3.13-7 7h2c0-2.76 2.24-5 5-5s5 2.24 5 5h2c0-3.87-3.13-7-7-7zm1 9.29c.88-.39 1.5-1.26 1.5-2.29 0-1.38-1.12-2.5-2.5-2.5S9.5 10.62 9.5 12c0 1.02.62 1.9 1.5 2.29v3.3L7.59 21 9 22.41l3-3 3 3L16.41 21 13 17.59v-3.3zM12 1C5.93 1 1 5.93 1 12h2c0-4.97 4.03-9 9-9s9 4.03 9 9h2c0-6.07-4.93-11-11-11z\"></path></g>\n<g id=\"settings-input-component\"><path d=\"M5 2c0-.55-.45-1-1-1s-1 .45-1 1v4H1v6h6V6H5V2zm4 14c0 1.3.84 2.4 2 2.82V23h2v-4.18c1.16-.41 2-1.51 2-2.82v-2H9v2zm-8 0c0 1.3.84 2.4 2 2.82V23h2v-4.18C6.16 18.4 7 17.3 7 16v-2H1v2zM21 6V2c0-.55-.45-1-1-1s-1 .45-1 1v4h-2v6h6V6h-2zm-8-4c0-.55-.45-1-1-1s-1 .45-1 1v4H9v6h6V6h-2V2zm4 14c0 1.3.84 2.4 2 2.82V23h2v-4.18c1.16-.41 2-1.51 2-2.82v-2h-6v2z\"></path></g>\n<g id=\"settings-input-composite\"><path d=\"M5 2c0-.55-.45-1-1-1s-1 .45-1 1v4H1v6h6V6H5V2zm4 14c0 1.3.84 2.4 2 2.82V23h2v-4.18c1.16-.41 2-1.51 2-2.82v-2H9v2zm-8 0c0 1.3.84 2.4 2 2.82V23h2v-4.18C6.16 18.4 7 17.3 7 16v-2H1v2zM21 6V2c0-.55-.45-1-1-1s-1 .45-1 1v4h-2v6h6V6h-2zm-8-4c0-.55-.45-1-1-1s-1 .45-1 1v4H9v6h6V6h-2V2zm4 14c0 1.3.84 2.4 2 2.82V23h2v-4.18c1.16-.41 2-1.51 2-2.82v-2h-6v2z\"></path></g>\n<g id=\"settings-input-hdmi\"><path d=\"M18 7V4c0-1.1-.9-2-2-2H8c-1.1 0-2 .9-2 2v3H5v6l3 6v3h8v-3l3-6V7h-1zM8 4h8v3h-2V5h-1v2h-2V5h-1v2H8V4z\"></path></g>\n<g id=\"settings-input-svideo\"><path d=\"M8 11.5c0-.83-.67-1.5-1.5-1.5S5 10.67 5 11.5 5.67 13 6.5 13 8 12.33 8 11.5zm7-5c0-.83-.67-1.5-1.5-1.5h-3C9.67 5 9 5.67 9 6.5S9.67 8 10.5 8h3c.83 0 1.5-.67 1.5-1.5zM8.5 15c-.83 0-1.5.67-1.5 1.5S7.67 18 8.5 18s1.5-.67 1.5-1.5S9.33 15 8.5 15zM12 1C5.93 1 1 5.93 1 12s4.93 11 11 11 11-4.93 11-11S18.07 1 12 1zm0 20c-4.96 0-9-4.04-9-9s4.04-9 9-9 9 4.04 9 9-4.04 9-9 9zm5.5-11c-.83 0-1.5.67-1.5 1.5s.67 1.5 1.5 1.5 1.5-.67 1.5-1.5-.67-1.5-1.5-1.5zm-2 5c-.83 0-1.5.67-1.5 1.5s.67 1.5 1.5 1.5 1.5-.67 1.5-1.5-.67-1.5-1.5-1.5z\"></path></g>\n<g id=\"settings-overscan\"><path d=\"M12.01 5.5L10 8h4l-1.99-2.5zM18 10v4l2.5-1.99L18 10zM6 10l-2.5 2.01L6 14v-4zm8 6h-4l2.01 2.5L14 16zm7-13H3c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16.01H3V4.99h18v14.02z\"></path></g>\n<g id=\"settings-phone\"><path d=\"M13 9h-2v2h2V9zm4 0h-2v2h2V9zm3 6.5c-1.25 0-2.45-.2-3.57-.57-.35-.11-.74-.03-1.02.24l-2.2 2.2c-2.83-1.44-5.15-3.75-6.59-6.58l2.2-2.21c.28-.27.36-.66.25-1.01C8.7 6.45 8.5 5.25 8.5 4c0-.55-.45-1-1-1H4c-.55 0-1 .45-1 1 0 9.39 7.61 17 17 17 .55 0 1-.45 1-1v-3.5c0-.55-.45-1-1-1zM19 9v2h2V9h-2z\"></path></g>\n<g id=\"settings-power\"><path d=\"M7 24h2v-2H7v2zm4 0h2v-2h-2v2zm2-22h-2v10h2V2zm3.56 2.44l-1.45 1.45C16.84 6.94 18 8.83 18 11c0 3.31-2.69 6-6 6s-6-2.69-6-6c0-2.17 1.16-4.06 2.88-5.12L7.44 4.44C5.36 5.88 4 8.28 4 11c0 4.42 3.58 8 8 8s8-3.58 8-8c0-2.72-1.36-5.12-3.44-6.56zM15 24h2v-2h-2v2z\"></path></g>\n<g id=\"settings-remote\"><path d=\"M15 9H9c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h6c.55 0 1-.45 1-1V10c0-.55-.45-1-1-1zm-3 6c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zM7.05 6.05l1.41 1.41C9.37 6.56 10.62 6 12 6s2.63.56 3.54 1.46l1.41-1.41C15.68 4.78 13.93 4 12 4s-3.68.78-4.95 2.05zM12 0C8.96 0 6.21 1.23 4.22 3.22l1.41 1.41C7.26 3.01 9.51 2 12 2s4.74 1.01 6.36 2.64l1.41-1.41C17.79 1.23 15.04 0 12 0z\"></path></g>\n<g id=\"settings-voice\"><path d=\"M7 24h2v-2H7v2zm5-11c1.66 0 2.99-1.34 2.99-3L15 4c0-1.66-1.34-3-3-3S9 2.34 9 4v6c0 1.66 1.34 3 3 3zm-1 11h2v-2h-2v2zm4 0h2v-2h-2v2zm4-14h-1.7c0 3-2.54 5.1-5.3 5.1S6.7 13 6.7 10H5c0 3.41 2.72 6.23 6 6.72V20h2v-3.28c3.28-.49 6-3.31 6-6.72z\"></path></g>\n<g id=\"shop\"><path d=\"M16 6V4c0-1.11-.89-2-2-2h-4c-1.11 0-2 .89-2 2v2H2v13c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V6h-6zm-6-2h4v2h-4V4zM9 18V9l7.5 4L9 18z\"></path></g>\n<g id=\"shop-two\"><path d=\"M3 9H1v11c0 1.11.89 2 2 2h14c1.11 0 2-.89 2-2H3V9zm15-4V3c0-1.11-.89-2-2-2h-4c-1.11 0-2 .89-2 2v2H5v11c0 1.11.89 2 2 2h14c1.11 0 2-.89 2-2V5h-5zm-6-2h4v2h-4V3zm0 12V8l5.5 3-5.5 4z\"></path></g>\n<g id=\"shopping-basket\"><path d=\"M17.21 9l-4.38-6.56c-.19-.28-.51-.42-.83-.42-.32 0-.64.14-.83.43L6.79 9H2c-.55 0-1 .45-1 1 0 .09.01.18.04.27l2.54 9.27c.23.84 1 1.46 1.92 1.46h13c.92 0 1.69-.62 1.93-1.46l2.54-9.27L23 10c0-.55-.45-1-1-1h-4.79zM9 9l3-4.4L15 9H9zm3 8c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2z\"></path></g>\n<g id=\"shopping-cart\"><path d=\"M7 18c-1.1 0-1.99.9-1.99 2S5.9 22 7 22s2-.9 2-2-.9-2-2-2zM1 2v2h2l3.6 7.59-1.35 2.45c-.16.28-.25.61-.25.96 0 1.1.9 2 2 2h12v-2H7.42c-.14 0-.25-.11-.25-.25l.03-.12.9-1.63h7.45c.75 0 1.41-.41 1.75-1.03l3.58-6.49c.08-.14.12-.31.12-.48 0-.55-.45-1-1-1H5.21l-.94-2H1zm16 16c-1.1 0-1.99.9-1.99 2s.89 2 1.99 2 2-.9 2-2-.9-2-2-2z\"></path></g>\n<g id=\"sort\"><path d=\"M3 18h6v-2H3v2zM3 6v2h18V6H3zm0 7h12v-2H3v2z\"></path></g>\n<g id=\"speaker-notes\"><path d=\"M20 2H4c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zM8 14H6v-2h2v2zm0-3H6V9h2v2zm0-3H6V6h2v2zm7 6h-5v-2h5v2zm3-3h-8V9h8v2zm0-3h-8V6h8v2z\"></path></g>\n<g id=\"spellcheck\"><path d=\"M12.45 16h2.09L9.43 3H7.57L2.46 16h2.09l1.12-3h5.64l1.14 3zm-6.02-5L8.5 5.48 10.57 11H6.43zm15.16.59l-8.09 8.09L9.83 16l-1.41 1.41 5.09 5.09L23 13l-1.41-1.41z\"></path></g>\n<g id=\"star\"><path d=\"M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z\"></path></g>\n<g id=\"star-border\"><path d=\"M22 9.24l-7.19-.62L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21 12 17.27 18.18 21l-1.63-7.03L22 9.24zM12 15.4l-3.76 2.27 1-4.28-3.32-2.88 4.38-.38L12 6.1l1.71 4.04 4.38.38-3.32 2.88 1 4.28L12 15.4z\"></path></g>\n<g id=\"star-half\"><path d=\"M22 9.24l-7.19-.62L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21 12 17.27 18.18 21l-1.63-7.03L22 9.24zM12 15.4V6.1l1.71 4.04 4.38.38-3.32 2.88 1 4.28L12 15.4z\"></path></g>\n<g id=\"stars\"><path d=\"M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zm4.24 16L12 15.45 7.77 18l1.12-4.81-3.73-3.23 4.92-.42L12 5l1.92 4.53 4.92.42-3.73 3.23L16.23 18z\"></path></g>\n<g id=\"store\"><path d=\"M20 4H4v2h16V4zm1 10v-2l-1-5H4l-1 5v2h1v6h10v-6h4v6h2v-6h1zm-9 4H6v-4h6v4z\"></path></g>\n<g id=\"subdirectory-arrow-left\"><path d=\"M11 9l1.42 1.42L8.83 14H18V4h2v12H8.83l3.59 3.58L11 21l-6-6 6-6z\"></path></g>\n<g id=\"subdirectory-arrow-right\"><path d=\"M19 15l-6 6-1.42-1.42L15.17 16H4V4h2v10h9.17l-3.59-3.58L13 9l6 6z\"></path></g>\n<g id=\"subject\"><path d=\"M14 17H4v2h10v-2zm6-8H4v2h16V9zM4 15h16v-2H4v2zM4 5v2h16V5H4z\"></path></g>\n<g id=\"supervisor-account\"><path d=\"M16.5 12c1.38 0 2.49-1.12 2.49-2.5S17.88 7 16.5 7C15.12 7 14 8.12 14 9.5s1.12 2.5 2.5 2.5zM9 11c1.66 0 2.99-1.34 2.99-3S10.66 5 9 5C7.34 5 6 6.34 6 8s1.34 3 3 3zm7.5 3c-1.83 0-5.5.92-5.5 2.75V19h11v-2.25c0-1.83-3.67-2.75-5.5-2.75zM9 13c-2.33 0-7 1.17-7 3.5V19h7v-2.25c0-.85.33-2.34 2.37-3.47C10.5 13.1 9.66 13 9 13z\"></path></g>\n<g id=\"swap-horiz\"><path d=\"M6.99 11L3 15l3.99 4v-3H14v-2H6.99v-3zM21 9l-3.99-4v3H10v2h7.01v3L21 9z\"></path></g>\n<g id=\"swap-vert\"><path d=\"M16 17.01V10h-2v7.01h-3L15 21l4-3.99h-3zM9 3L5 6.99h3V14h2V6.99h3L9 3z\"></path></g>\n<g id=\"swap-vertical-circle\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zM6.5 9L10 5.5 13.5 9H11v4H9V9H6.5zm11 6L14 18.5 10.5 15H13v-4h2v4h2.5z\"></path></g>\n<g id=\"system-update-alt\"><path d=\"M12 16.5l4-4h-3v-9h-2v9H8l4 4zm9-13h-6v1.99h6v14.03H3V5.49h6V3.5H3c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2v-14c0-1.1-.9-2-2-2z\"></path></g>\n<g id=\"tab\"><path d=\"M21 3H3c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H3V5h10v4h8v10z\"></path></g>\n<g id=\"tab-unselected\"><path d=\"M1 9h2V7H1v2zm0 4h2v-2H1v2zm0-8h2V3c-1.1 0-2 .9-2 2zm8 16h2v-2H9v2zm-8-4h2v-2H1v2zm2 4v-2H1c0 1.1.9 2 2 2zM21 3h-8v6h10V5c0-1.1-.9-2-2-2zm0 14h2v-2h-2v2zM9 5h2V3H9v2zM5 21h2v-2H5v2zM5 5h2V3H5v2zm16 16c1.1 0 2-.9 2-2h-2v2zm0-8h2v-2h-2v2zm-8 8h2v-2h-2v2zm4 0h2v-2h-2v2z\"></path></g>\n<g id=\"text-format\"><path d=\"M5 17v2h14v-2H5zm4.5-4.2h5l.9 2.2h2.1L12.75 4h-1.5L6.5 15h2.1l.9-2.2zM12 5.98L13.87 11h-3.74L12 5.98z\"></path></g>\n<g id=\"theaters\"><path d=\"M18 3v2h-2V3H8v2H6V3H4v18h2v-2h2v2h8v-2h2v2h2V3h-2zM8 17H6v-2h2v2zm0-4H6v-2h2v2zm0-4H6V7h2v2zm10 8h-2v-2h2v2zm0-4h-2v-2h2v2zm0-4h-2V7h2v2z\"></path></g>\n<g id=\"thumb-down\"><path d=\"M15 3H6c-.83 0-1.54.5-1.84 1.22l-3.02 7.05c-.09.23-.14.47-.14.73v1.91l.01.01L1 14c0 1.1.9 2 2 2h6.31l-.95 4.57-.03.32c0 .41.17.79.44 1.06L9.83 23l6.59-6.59c.36-.36.58-.86.58-1.41V5c0-1.1-.9-2-2-2zm4 0v12h4V3h-4z\"></path></g>\n<g id=\"thumb-up\"><path d=\"M1 21h4V9H1v12zm22-11c0-1.1-.9-2-2-2h-6.31l.95-4.57.03-.32c0-.41-.17-.79-.44-1.06L14.17 1 7.59 7.59C7.22 7.95 7 8.45 7 9v10c0 1.1.9 2 2 2h9c.83 0 1.54-.5 1.84-1.22l3.02-7.05c.09-.23.14-.47.14-.73v-1.91l-.01-.01L23 10z\"></path></g>\n<g id=\"thumbs-up-down\"><path d=\"M12 6c0-.55-.45-1-1-1H5.82l.66-3.18.02-.23c0-.31-.13-.59-.33-.8L5.38 0 .44 4.94C.17 5.21 0 5.59 0 6v6.5c0 .83.67 1.5 1.5 1.5h6.75c.62 0 1.15-.38 1.38-.91l2.26-5.29c.07-.17.11-.36.11-.55V6zm10.5 4h-6.75c-.62 0-1.15.38-1.38.91l-2.26 5.29c-.07.17-.11.36-.11.55V18c0 .55.45 1 1 1h5.18l-.66 3.18-.02.24c0 .31.13.59.33.8l.79.78 4.94-4.94c.27-.27.44-.65.44-1.06v-6.5c0-.83-.67-1.5-1.5-1.5z\"></path></g>\n<g id=\"timeline\"><path d=\"M23 8c0 1.1-.9 2-2 2-.18 0-.35-.02-.51-.07l-3.56 3.55c.05.16.07.34.07.52 0 1.1-.9 2-2 2s-2-.9-2-2c0-.18.02-.36.07-.52l-2.55-2.55c-.16.05-.34.07-.52.07s-.36-.02-.52-.07l-4.55 4.56c.05.16.07.33.07.51 0 1.1-.9 2-2 2s-2-.9-2-2 .9-2 2-2c.18 0 .35.02.51.07l4.56-4.55C8.02 9.36 8 9.18 8 9c0-1.1.9-2 2-2s2 .9 2 2c0 .18-.02.36-.07.52l2.55 2.55c.16-.05.34-.07.52-.07s.36.02.52.07l3.55-3.56C19.02 8.35 19 8.18 19 8c0-1.1.9-2 2-2s2 .9 2 2z\"></path></g>\n<g id=\"toc\"><path d=\"M3 9h14V7H3v2zm0 4h14v-2H3v2zm0 4h14v-2H3v2zm16 0h2v-2h-2v2zm0-10v2h2V7h-2zm0 6h2v-2h-2v2z\"></path></g>\n<g id=\"today\"><path d=\"M19 3h-1V1h-2v2H8V1H6v2H5c-1.11 0-1.99.9-1.99 2L3 19c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V8h14v11zM7 10h5v5H7z\"></path></g>\n<g id=\"toll\"><path d=\"M15 4c-4.42 0-8 3.58-8 8s3.58 8 8 8 8-3.58 8-8-3.58-8-8-8zm0 14c-3.31 0-6-2.69-6-6s2.69-6 6-6 6 2.69 6 6-2.69 6-6 6zM3 12c0-2.61 1.67-4.83 4-5.65V4.26C3.55 5.15 1 8.27 1 12s2.55 6.85 6 7.74v-2.09c-2.33-.82-4-3.04-4-5.65z\"></path></g>\n<g id=\"touch-app\"><path d=\"M9 11.24V7.5C9 6.12 10.12 5 11.5 5S14 6.12 14 7.5v3.74c1.21-.81 2-2.18 2-3.74C16 5.01 13.99 3 11.5 3S7 5.01 7 7.5c0 1.56.79 2.93 2 3.74zm9.84 4.63l-4.54-2.26c-.17-.07-.35-.11-.54-.11H13v-6c0-.83-.67-1.5-1.5-1.5S10 6.67 10 7.5v10.74l-3.43-.72c-.08-.01-.15-.03-.24-.03-.31 0-.59.13-.79.33l-.79.8 4.94 4.94c.27.27.65.44 1.06.44h6.79c.75 0 1.33-.55 1.44-1.28l.75-5.27c.01-.07.02-.14.02-.2 0-.62-.38-1.16-.91-1.38z\"></path></g>\n<g id=\"track-changes\"><path d=\"M19.07 4.93l-1.41 1.41C19.1 7.79 20 9.79 20 12c0 4.42-3.58 8-8 8s-8-3.58-8-8c0-4.08 3.05-7.44 7-7.93v2.02C8.16 6.57 6 9.03 6 12c0 3.31 2.69 6 6 6s6-2.69 6-6c0-1.66-.67-3.16-1.76-4.24l-1.41 1.41C15.55 9.9 16 10.9 16 12c0 2.21-1.79 4-4 4s-4-1.79-4-4c0-1.86 1.28-3.41 3-3.86v2.14c-.6.35-1 .98-1 1.72 0 1.1.9 2 2 2s2-.9 2-2c0-.74-.4-1.38-1-1.72V2h-1C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10c0-2.76-1.12-5.26-2.93-7.07z\"></path></g>\n<g id=\"translate\"><path d=\"M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z\"></path></g>\n<g id=\"trending-down\"><path d=\"M16 18l2.29-2.29-4.88-4.88-4 4L2 7.41 3.41 6l6 6 4-4 6.3 6.29L22 12v6z\"></path></g>\n<g id=\"trending-flat\"><path d=\"M22 12l-4-4v3H3v2h15v3z\"></path></g>\n<g id=\"trending-up\"><path d=\"M16 6l2.29 2.29-4.88 4.88-4-4L2 16.59 3.41 18l6-6 4 4 6.3-6.29L22 12V6z\"></path></g>\n<g id=\"turned-in\"><path d=\"M17 3H7c-1.1 0-1.99.9-1.99 2L5 21l7-3 7 3V5c0-1.1-.9-2-2-2z\"></path></g>\n<g id=\"turned-in-not\"><path d=\"M17 3H7c-1.1 0-1.99.9-1.99 2L5 21l7-3 7 3V5c0-1.1-.9-2-2-2zm0 15l-5-2.18L7 18V5h10v13z\"></path></g>\n<g id=\"unarchive\"><path d=\"M20.55 5.22l-1.39-1.68C18.88 3.21 18.47 3 18 3H6c-.47 0-.88.21-1.15.55L3.46 5.22C3.17 5.57 3 6.01 3 6.5V19c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V6.5c0-.49-.17-.93-.45-1.28zM12 9.5l5.5 5.5H14v2h-4v-2H6.5L12 9.5zM5.12 5l.82-1h12l.93 1H5.12z\"></path></g>\n<g id=\"undo\"><path d=\"M12.5 8c-2.65 0-5.05.99-6.9 2.6L2 7v9h9l-3.62-3.62c1.39-1.16 3.16-1.88 5.12-1.88 3.54 0 6.55 2.31 7.6 5.5l2.37-.78C21.08 11.03 17.15 8 12.5 8z\"></path></g>\n<g id=\"unfold-less\"><path d=\"M7.41 18.59L8.83 20 12 16.83 15.17 20l1.41-1.41L12 14l-4.59 4.59zm9.18-13.18L15.17 4 12 7.17 8.83 4 7.41 5.41 12 10l4.59-4.59z\"></path></g>\n<g id=\"unfold-more\"><path d=\"M12 5.83L15.17 9l1.41-1.41L12 3 7.41 7.59 8.83 9 12 5.83zm0 12.34L8.83 15l-1.41 1.41L12 21l4.59-4.59L15.17 15 12 18.17z\"></path></g>\n<g id=\"update\"><path d=\"M21 10.12h-6.78l2.74-2.82c-2.73-2.7-7.15-2.8-9.88-.1-2.73 2.71-2.73 7.08 0 9.79 2.73 2.71 7.15 2.71 9.88 0C18.32 15.65 19 14.08 19 12.1h2c0 1.98-.88 4.55-2.64 6.29-3.51 3.48-9.21 3.48-12.72 0-3.5-3.47-3.53-9.11-.02-12.58 3.51-3.47 9.14-3.47 12.65 0L21 3v7.12zM12.5 8v4.25l3.5 2.08-.72 1.21L11 13V8h1.5z\"></path></g>\n<g id=\"verified-user\"><path d=\"M12 1L3 5v6c0 5.55 3.84 10.74 9 12 5.16-1.26 9-6.45 9-12V5l-9-4zm-2 16l-4-4 1.41-1.41L10 14.17l6.59-6.59L18 9l-8 8z\"></path></g>\n<g id=\"view-agenda\"><path d=\"M20 13H3c-.55 0-1 .45-1 1v6c0 .55.45 1 1 1h17c.55 0 1-.45 1-1v-6c0-.55-.45-1-1-1zm0-10H3c-.55 0-1 .45-1 1v6c0 .55.45 1 1 1h17c.55 0 1-.45 1-1V4c0-.55-.45-1-1-1z\"></path></g>\n<g id=\"view-array\"><path d=\"M4 18h3V5H4v13zM18 5v13h3V5h-3zM8 18h9V5H8v13z\"></path></g>\n<g id=\"view-carousel\"><path d=\"M7 19h10V4H7v15zm-5-2h4V6H2v11zM18 6v11h4V6h-4z\"></path></g>\n<g id=\"view-column\"><path d=\"M10 18h5V5h-5v13zm-6 0h5V5H4v13zM16 5v13h5V5h-5z\"></path></g>\n<g id=\"view-day\"><path d=\"M2 21h19v-3H2v3zM20 8H3c-.55 0-1 .45-1 1v6c0 .55.45 1 1 1h17c.55 0 1-.45 1-1V9c0-.55-.45-1-1-1zM2 3v3h19V3H2z\"></path></g>\n<g id=\"view-headline\"><path d=\"M4 15h16v-2H4v2zm0 4h16v-2H4v2zm0-8h16V9H4v2zm0-6v2h16V5H4z\"></path></g>\n<g id=\"view-list\"><path d=\"M4 14h4v-4H4v4zm0 5h4v-4H4v4zM4 9h4V5H4v4zm5 5h12v-4H9v4zm0 5h12v-4H9v4zM9 5v4h12V5H9z\"></path></g>\n<g id=\"view-module\"><path d=\"M4 11h5V5H4v6zm0 7h5v-6H4v6zm6 0h5v-6h-5v6zm6 0h5v-6h-5v6zm-6-7h5V5h-5v6zm6-6v6h5V5h-5z\"></path></g>\n<g id=\"view-quilt\"><path d=\"M10 18h5v-6h-5v6zm-6 0h5V5H4v13zm12 0h5v-6h-5v6zM10 5v6h11V5H10z\"></path></g>\n<g id=\"view-stream\"><path d=\"M4 18h17v-6H4v6zM4 5v6h17V5H4z\"></path></g>\n<g id=\"view-week\"><path d=\"M6 5H3c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h3c.55 0 1-.45 1-1V6c0-.55-.45-1-1-1zm14 0h-3c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h3c.55 0 1-.45 1-1V6c0-.55-.45-1-1-1zm-7 0h-3c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h3c.55 0 1-.45 1-1V6c0-.55-.45-1-1-1z\"></path></g>\n<g id=\"visibility\"><path d=\"M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z\"></path></g>\n<g id=\"visibility-off\"><path d=\"M12 7c2.76 0 5 2.24 5 5 0 .65-.13 1.26-.36 1.83l2.92 2.92c1.51-1.26 2.7-2.89 3.43-4.75-1.73-4.39-6-7.5-11-7.5-1.4 0-2.74.25-3.98.7l2.16 2.16C10.74 7.13 11.35 7 12 7zM2 4.27l2.28 2.28.46.46C3.08 8.3 1.78 10.02 1 12c1.73 4.39 6 7.5 11 7.5 1.55 0 3.03-.3 4.38-.84l.42.42L19.73 22 21 20.73 3.27 3 2 4.27zM7.53 9.8l1.55 1.55c-.05.21-.08.43-.08.65 0 1.66 1.34 3 3 3 .22 0 .44-.03.65-.08l1.55 1.55c-.67.33-1.41.53-2.2.53-2.76 0-5-2.24-5-5 0-.79.2-1.53.53-2.2zm4.31-.78l3.15 3.15.02-.16c0-1.66-1.34-3-3-3l-.17.01z\"></path></g>\n<g id=\"warning\"><path d=\"M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z\"></path></g>\n<g id=\"watch-later\"><path d=\"M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10 10-4.5 10-10S17.5 2 12 2zm4.2 14.2L11 13V7h1.5v5.2l4.5 2.7-.8 1.3z\"></path></g>\n<g id=\"weekend\"><path d=\"M21 10c-1.1 0-2 .9-2 2v3H5v-3c0-1.1-.9-2-2-2s-2 .9-2 2v5c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2v-5c0-1.1-.9-2-2-2zm-3-5H6c-1.1 0-2 .9-2 2v2.15c1.16.41 2 1.51 2 2.82V14h12v-2.03c0-1.3.84-2.4 2-2.82V7c0-1.1-.9-2-2-2z\"></path></g>\n<g id=\"work\"><path d=\"M20 6h-4V4c0-1.11-.89-2-2-2h-4c-1.11 0-2 .89-2 2v2H4c-1.11 0-1.99.89-1.99 2L2 19c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V8c0-1.11-.89-2-2-2zm-6 0h-4V4h4v2z\"></path></g>\n<g id=\"youtube-searched-for\"><path d=\"M17.01 14h-.8l-.27-.27c.98-1.14 1.57-2.61 1.57-4.23 0-3.59-2.91-6.5-6.5-6.5s-6.5 3-6.5 6.5H2l3.84 4 4.16-4H6.51C6.51 7 8.53 5 11.01 5s4.5 2.01 4.5 4.5c0 2.48-2.02 4.5-4.5 4.5-.65 0-1.26-.14-1.82-.38L7.71 15.1c.97.57 2.09.9 3.3.9 1.61 0 3.08-.59 4.22-1.57l.27.27v.79l5.01 4.99L22 19l-4.99-5z\"></path></g>\n<g id=\"zoom-in\"><path d=\"M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14zm2.5-4h-2v2H9v-2H7V9h2V7h1v2h2v1z\"></path></g>\n<g id=\"zoom-out\"><path d=\"M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14zM7 9h5v1H7z\"></path></g>\n</defs></svg>\n</iron-iconset-svg>\n\n\n\n\n<dom-module id=\"paper-material-shared-styles\" assetpath=\"/paper-material/\">\n  <template>\n    <style>\n      :host {\n        display: block;\n        position: relative;\n      }\n\n      :host([elevation=\"1\"]) {\n        @apply(--shadow-elevation-2dp);\n      }\n\n      :host([elevation=\"2\"]) {\n        @apply(--shadow-elevation-4dp);\n      }\n\n      :host([elevation=\"3\"]) {\n        @apply(--shadow-elevation-6dp);\n      }\n\n      :host([elevation=\"4\"]) {\n        @apply(--shadow-elevation-8dp);\n      }\n\n      :host([elevation=\"5\"]) {\n        @apply(--shadow-elevation-16dp);\n      }\n    </style>\n  </template>\n</dom-module>\n<dom-module id=\"paper-material\" assetpath=\"/paper-material/\">\n  <template>\n    <style include=\"paper-material-shared-styles\"></style>\n    <style>\n      :host([animated]) {\n        @apply(--shadow-transition);\n      }\n    </style>\n\n    <content></content>\n  </template>\n</dom-module>\n<dom-module id=\"paper-button\" assetpath=\"/paper-button/\">\n  <template strip-whitespace=\"\">\n\n    <style include=\"paper-material\">\n      :host {\n        display: inline-block;\n        position: relative;\n        box-sizing: border-box;\n        min-width: 5.14em;\n        margin: 0 0.29em;\n        background: transparent;\n        text-align: center;\n        font: inherit;\n        text-transform: uppercase;\n        outline-width: 0;\n        border-radius: 3px;\n        -moz-user-select: none;\n        -ms-user-select: none;\n        -webkit-user-select: none;\n        user-select: none;\n        cursor: pointer;\n        z-index: 0;\n        padding: 0.7em 0.57em;\n\n        @apply(--paper-button);\n      }\n\n      :host([raised].keyboard-focus) {\n        font-weight: bold;\n        @apply(--paper-button-raised-keyboard-focus);\n      }\n\n      :host(:not([raised]).keyboard-focus) {\n        font-weight: bold;\n        @apply(--paper-button-flat-keyboard-focus);\n      }\n\n      :host([disabled]) {\n        background: #eaeaea;\n        color: #a8a8a8;\n        cursor: auto;\n        pointer-events: none;\n\n        @apply(--paper-button-disabled);\n      }\n\n      paper-ripple {\n        color: var(--paper-button-ink-color);\n      }\n\n      :host > ::content * {\n        text-transform: inherit;\n      }\n    </style>\n    <content></content>\n  </template>\n</dom-module>\n\n<dom-module id=\"iron-image\" assetpath=\"/iron-image/\">\n  <template>\n    <style>\n      :host {\n        display: inline-block;\n        overflow: hidden;\n        position: relative;\n      }\n\n      #sizedImgDiv {\n        @apply(--layout-fit);\n\n        display: none;\n      }\n\n      #img {\n        display: block;\n        width: var(--iron-image-width, auto);\n        height: var(--iron-image-height, auto);\n      }\n\n      :host([sizing]) #sizedImgDiv {\n        display: block;\n      }\n\n      :host([sizing]) #img {\n        display: none;\n      }\n\n      #placeholder {\n        @apply(--layout-fit);\n\n        background-color: inherit;\n        opacity: 1;\n\n        @apply(--iron-image-placeholder);\n      }\n\n      #placeholder.faded-out {\n        transition: opacity 0.5s linear;\n        opacity: 0;\n      }\n    </style>\n\n    <div id=\"sizedImgDiv\" role=\"img\" hidden$=\"[[V_(sizing)]]\" aria-hidden$=\"[[T_(alt)]]\" aria-label$=\"[[U_(alt,src)]]\"></div>\n    <img id=\"img\" alt$=\"[[alt]]\" hidden$=\"[[W_(sizing)]]\">\n    <div id=\"placeholder\" hidden$=\"[[a0(preload,fade,loading,loaded)]]\" class$=\"[[$_(preload,fade,loading,loaded)]]\"></div>\n  </template>\n\n  </dom-module>\n<dom-module id=\"paper-card\" assetpath=\"/paper-card/\">\n  <template>\n    <style include=\"paper-material\">\n      :host {\n        display: inline-block;\n        position: relative;\n        box-sizing: border-box;\n        background-color: var(--paper-card-background-color, --primary-background-color);\n        border-radius: 2px;\n\n        @apply(--paper-font-common-base);\n        @apply(--paper-card);\n      }\n\n      /* IE 10 support for HTML5 hidden attr */\n      [hidden] {\n        display: none !important;\n      }\n\n      .header {\n        position: relative;\n        border-top-left-radius: inherit;\n        border-top-right-radius: inherit;\n        overflow: hidden;\n\n        @apply(--paper-card-header);\n      }\n\n      .header iron-image {\n        display: block;\n        width: 100%;\n        --iron-image-width: 100%;\n        pointer-events: none;\n\n        @apply(--paper-card-header-image);\n      }\n\n      .header .title-text {\n        padding: 16px;\n        font-size: 24px;\n        font-weight: 400;\n        color: var(--paper-card-header-color, #000);\n\n        @apply(--paper-card-header-text);\n      }\n\n      .header .title-text.over-image {\n        position: absolute;\n        bottom: 0px;\n\n        @apply(--paper-card-header-image-text);\n      }\n\n      :host ::content .card-content {\n        padding: 16px;\n        position:relative;\n\n        @apply(--paper-card-content);\n      }\n\n      :host ::content .card-actions {\n        border-top: 1px solid #e8e8e8;\n        padding: 5px 16px;\n        position:relative;\n\n        @apply(--paper-card-actions);\n      }\n    </style>\n\n    <div class=\"header\">\n      <iron-image hidden$=\"[[!image]]\" aria-hidden$=\"[[A0(image)]]\" src=\"[[image]]\" alt=\"[[alt]]\" placeholder=\"[[placeholderImage]]\" preload=\"[[preloadImage]]\" fade=\"[[fadeImage]]\"></iron-image>\n      <div hidden$=\"[[!heading]]\" class$=\"title-text [[S_(image)]]\">[[heading]]</div>\n    </div>\n\n    <content></content>\n  </template>\n\n  </dom-module>\n\n\n<dom-module id=\"paper-dialog-shared-styles\" assetpath=\"/paper-dialog-behavior/\">\n  <template>\n    <style>\n      :host {\n        display: block;\n        margin: 24px 40px;\n\n        background: var(--paper-dialog-background-color, --primary-background-color);\n        color: var(--paper-dialog-color, --primary-text-color);\n\n        @apply(--paper-font-body1);\n        @apply(--shadow-elevation-16dp);\n        @apply(--paper-dialog);\n      }\n\n      :host > ::content > * {\n        margin-top: 20px;\n        padding: 0 24px;\n      }\n\n      :host > ::content > .no-padding {\n        padding: 0;\n      }\n\n      :host > ::content > *:first-child {\n        margin-top: 24px;\n      }\n\n      :host > ::content > *:last-child {\n        margin-bottom: 24px;\n      }\n\n      :host > ::content h2 {\n        position: relative;\n        margin: 0;\n        @apply(--paper-font-title);\n\n        @apply(--paper-dialog-title);\n      }\n\n      :host > ::content .buttons {\n        position: relative;\n        padding: 8px 8px 8px 24px;\n        margin: 0;\n\n        color: var(--paper-dialog-button-color, --primary-color);\n\n        @apply(--layout-horizontal);\n        @apply(--layout-end-justified);\n      }\n    </style>\n  </template>\n</dom-module>\n<dom-module id=\"paper-dialog\" assetpath=\"/paper-dialog/\">\n  <template>\n    <style include=\"paper-dialog-shared-styles\"></style>\n    <content></content>\n  </template>\n</dom-module>\n\n<dom-module id=\"paper-icon-button\" assetpath=\"/paper-icon-button/\">\n  <template strip-whitespace=\"\">\n    <style>\n      :host {\n        display: inline-block;\n        position: relative;\n        padding: 8px;\n        outline: none;\n        -webkit-user-select: none;\n        -moz-user-select: none;\n        -ms-user-select: none;\n        user-select: none;\n        cursor: pointer;\n        z-index: 0;\n        line-height: 1;\n\n        width: 40px;\n        height: 40px;\n\n        /* NOTE: Both values are needed, since some phones require the value to be `transparent`. */\n        -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n        -webkit-tap-highlight-color: transparent;\n\n        /* Because of polymer/2558, this style has lower specificity than * */\n        box-sizing: border-box !important;\n\n        @apply(--paper-icon-button);\n      }\n\n      :host #ink {\n        color: var(--paper-icon-button-ink-color, --primary-text-color);\n        opacity: 0.6;\n      }\n\n      :host([disabled]) {\n        color: var(--paper-icon-button-disabled-text, --disabled-text-color);\n        pointer-events: none;\n        cursor: auto;\n\n        @apply(--paper-icon-button-disabled);\n      }\n\n      :host(:hover) {\n        @apply(--paper-icon-button-hover);\n      }\n\n      iron-icon {\n        --iron-icon-width: 100%;\n        --iron-icon-height: 100%;\n      }\n    </style>\n\n    <iron-icon id=\"icon\" src=\"[[src]]\" icon=\"[[icon]]\" alt$=\"[[alt]]\"></iron-icon>\n  </template>\n\n  </dom-module>\n\n\n<dom-module id=\"paper-toggle-button\" assetpath=\"/paper-toggle-button/\">\n  <template strip-whitespace=\"\">\n\n    <style>\n      :host {\n        display: inline-block;\n        @apply(--layout-horizontal);\n        @apply(--layout-center);\n        @apply(--paper-font-common-base);\n      }\n\n      :host([disabled]) {\n        pointer-events: none;\n      }\n\n      :host(:focus) {\n        outline:none;\n      }\n\n      .toggle-bar {\n        position: absolute;\n        height: 100%;\n        width: 100%;\n        border-radius: 8px;\n        pointer-events: none;\n        opacity: 0.4;\n        transition: background-color linear .08s;\n        background-color: var(--paper-toggle-button-unchecked-bar-color, #000000);\n\n        @apply(--paper-toggle-button-unchecked-bar);\n      }\n\n      .toggle-button {\n        position: absolute;\n        top: -3px;\n        left: 0;\n        height: 20px;\n        width: 20px;\n        border-radius: 50%;\n        box-shadow: 0 1px 5px 0 rgba(0, 0, 0, 0.6);\n        transition: -webkit-transform linear .08s, background-color linear .08s;\n        transition: transform linear .08s, background-color linear .08s;\n        will-change: transform;\n        background-color: var(--paper-toggle-button-unchecked-button-color, --paper-grey-50);\n\n        @apply(--paper-toggle-button-unchecked-button);\n      }\n\n      .toggle-button.dragging {\n        -webkit-transition: none;\n        transition: none;\n      }\n\n      :host([checked]:not([disabled])) .toggle-bar {\n        opacity: 0.5;\n        background-color: var(--paper-toggle-button-checked-bar-color, --primary-color);\n\n        @apply(--paper-toggle-button-checked-bar);\n      }\n\n      :host([disabled]) .toggle-bar {\n        background-color: #000;\n        opacity: 0.12;\n      }\n\n      :host([checked]) .toggle-button {\n        -webkit-transform: translate(16px, 0);\n        transform: translate(16px, 0);\n      }\n\n      :host([checked]:not([disabled])) .toggle-button {\n        background-color: var(--paper-toggle-button-checked-button-color, --primary-color);\n\n        @apply(--paper-toggle-button-checked-button);\n      }\n\n      :host([disabled]) .toggle-button {\n        background-color: #bdbdbd;\n        opacity: 1;\n      }\n\n      .toggle-ink {\n        position: absolute;\n        top: -14px;\n        left: -14px;\n        right: auto;\n        bottom: auto;\n        width: 48px;\n        height: 48px;\n        opacity: 0.5;\n        pointer-events: none;\n        color: var(--paper-toggle-button-unchecked-ink-color, --primary-text-color);\n      }\n\n      :host([checked]) .toggle-ink {\n        color: var(--paper-toggle-button-checked-ink-color, --primary-color);\n      }\n\n      .toggle-container {\n        display: inline-block;\n        position: relative;\n        width: 36px;\n        height: 14px;\n        /* The toggle button has an absolute position of -3px; The extra 1px\n        /* accounts for the toggle button shadow box. */\n        margin: 4px 1px;\n      }\n\n      .toggle-label {\n        position: relative;\n        display: inline-block;\n        vertical-align: middle;\n        padding-left: var(--paper-toggle-button-label-spacing, 8px);\n        pointer-events: none;\n        color: var(--paper-toggle-button-label-color, --primary-text-color);\n      }\n\n      /* invalid state */\n      :host([invalid]) .toggle-bar {\n        background-color: var(--paper-toggle-button-invalid-bar-color, --error-color);\n      }\n\n      :host([invalid]) .toggle-button {\n        background-color: var(--paper-toggle-button-invalid-button-color, --error-color);\n      }\n\n      :host([invalid]) .toggle-ink {\n        color: var(--paper-toggle-button-invalid-ink-color, --error-color);\n      }\n    </style>\n\n    <div class=\"toggle-container\">\n      <div id=\"toggleBar\" class=\"toggle-bar\"></div>\n      <div id=\"toggleButton\" class=\"toggle-button\"></div>\n    </div>\n\n    <div class=\"toggle-label\"><content></content></div>\n\n  </template>\n\n  </dom-module>\n<dom-module id=\"gviz-loader\" assetpath=\"/gviz-loader/\">\n  <template>\n  </template>\n  </dom-module>\n<dom-module id=\"metrics-histogram\" assetpath=\"/metrics-histogram/\">\n  \n  <template><style>\n:host {\n  display: block;\n}\n\n.section {\n  margin: 5px 0;\n}\n\n.ui {\n  margin: auto;\n  width: 680px; /* Three ui-elements (210px each) + options toggle (50px) */\n}\n\n.ui-input {\n  width: 200px;\n}\n\n.ui-element {\n  display: inline-block;\n  margin-right: 2px;\n}\n\n.placeholder {\n  height: 32px;\n  display: flex;\n}\n\n#overview ::content path.blue {\n  fill: #3366cc;\n}\n\n#overview ::content path.red {\n  fill: #dc3912;\n}\n\n#overview ::content rect.overview {\n  fill: #ccc;\n  stroke: #000;\n  opacity: .1;\n}\n\n#overview ::content rect#focus {\n  fill: gray;\n  stroke: #000;\n  opacity: .2;\n}\n\n#details ::content rect.highlighted {\n  fill: #ffde5a;\n}\n\n#details ::content g.highlighted text {\n  fill: #212121;\n  font-weight: bold;\n}\n\n#empty {\n  margin: 20px auto 0;\n  width: calc(100% - 240px);\n  text-align: center;\n}\n\n</style>\n    <gviz-loader id=\"loader\" packages=\"[[chartPackages_]]\"></gviz-loader>\n    <div class=\"ui section\">\n      <span id=\"metric-select\" class=\"ui-element ui-input\">\n        <paper-dropdown-menu label=\"Select Metric\">\n          <paper-listbox class=\"dropdown-content\" selected=\"{{metric}}\" attr-for-selected=\"value\">\n            <template is=\"dom-repeat\" items=\"[[selectableMetrics_]]\">\n              <paper-item value=\"[[item]]\">[[item]]</paper-item>\n            </template>\n          </paper-listbox>\n        </paper-dropdown-menu>\n        <div class=\"placeholder\"></div>\n      </span>\n      <span id=\"type-select\" class=\"ui-element ui-input\">\n        <paper-dropdown-menu label=\"Histogram Type\">\n          <paper-listbox class=\"dropdown-content\" selected=\"{{type}}\" attr-for-selected=\"value\">\n            <paper-item value=\"unweighted\">Slice Counts</paper-item>\n            <paper-item value=\"weighted\">Example Counts</paper-item>\n            <paper-item value=\"both\">Both</paper-item>\n          </paper-listbox>\n        </paper-dropdown-menu>\n        <div class=\"placeholder\"></div>\n      </span>\n      <span id=\"num-buckets\" class=\"ui-element ui-input\">\n        <paper-input label=\"Number of Buckets\" always-float-label=\"\" value=\"{{numBuckets}}\" auto-validate=\"\" pattern=\"[1-9]|[1-4][0-9]|50\" error-message=\"must be between [1, 50]\"></paper-input>\n        <paper-slider class=\"slider\" min=\"1\" max=\"50\" value=\"{{numBuckets}}\" immediate-value=\"{{numBuckets}}\"></paper-slider>\n      </span>\n      <span class=\"ui-element\">\n        <paper-icon-button id=\"options-toggle\" icon=\"settings\" data-dialog=\"options\" on-tap=\"l$\">More Options</paper-icon-button>\n        <div class=\"placeholder\"></div>\n        <paper-dialog id=\"options\">\n          <h2>Options</h2>\n          <div>\n            <paper-toggle-button id=\"logarithm-scale\" type=\"checkbox\" checked=\"{{logarithmScale}}\">Logarithm Scale</paper-toggle-button>\n          </div>\n        </paper-dialog>\n      </span>\n    </div>\n    <svg id=\"overview\" class=\"section\">\n      <g class=\"unweighted\"></g>\n      <g class=\"weighted\"></g>\n    </svg>\n    <div id=\"details\"></div>\n    <paper-card id=\"empty\">\n      <div class=\"card-content\">\n        <paper-icon-button icon=\"block\"></paper-icon-button>\n        <div>Empty Histogram</div>\n      </div>\n    </paper-card>\n  </template>\n  </dom-module>\n<dom-module id=\"gviz-table\" assetpath=\"/gviz-table/\">\n  <template>\n    <gviz-loader id=\"loader\"></gviz-loader>\n    <div id=\"table\"></div>\n  </template>\n  </dom-module>\n<dom-module id=\"bounded-value\" assetpath=\"/bounded-value/\">\n  \n  <template><style>\n:host {\n  display: block;\n}\n\n</style>\n    [[value_]]±[[range_]]\n  </template>\n  </dom-module>\n<dom-module id=\"precision-at-k\" assetpath=\"/precision-at-k/\">\n  \n  <template><style>\n:host div.tr:nth-child(even) {\n  background: #e4e4e4;\n}\n\n/**\n * NOTE(paulyang): There is a bad interaction between dom-repeat element, table\n * tag and vulcanization. Use div and equivalent display: table* on class table,\n * tr and td as a work-around.\n *\n * See b/22376520 for more details.\n */\n:host div.table {\n  text-align: center;\n  display: table;\n}\n\n:host div.td {\n  min-width: 15px;\n  padding: 0 5px;\n  display: table-cell;\n}\n\n:host div.tr {\n  display: table-row;\n}\n\n/**\n * Hides the weighted count when comparinging precision at k inside\n * lantern-model-diff.\n */\n:host-context(lantern-model-diff) div.td:nth-child(3) {\n  display: none;\n}\n\n</style>\n    <div class=\"table\">\n        <template is=\"dom-repeat\" items=\"{{formattedData_}}\">\n          <div class=\"tr\">\n            <div class=\"td\">[[item.k]]</div>\n            <div class=\"td\">[[item.value]]</div>\n            <div class=\"td\">[[item.total]]</div>\n          </div>\n        </template>\n      \n    </div>\n  </template>\n  </dom-module>\n<dom-module id=\"metrics-table\" assetpath=\"/metrics-table/\">\n  \n  <template><style>\n:host {\n  display: block;\n  box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14),\n              0 1px 5px 0 rgba(0, 0, 0, 0.12),\n              0 3px 1px -2px rgba(0, 0, 0, 0.2)\n}\n\ngoogle-chart {\n  width: 100%;\n  height: 100%;\n}\n\ngoogle-chart ::content * {\n  font-family: 'Roboto','Noto','Helvetica Neue',Helvetica,Arial,sans-serif;\n  font-weight: 400;\n  font-size: 12px;\n  text-align: left;\n}\n\ngoogle-chart ::content .google-visualization-table-th {\n  font-weight: 500;\n  text-overflow: ellipsis;\n  color: rgba(0,0,0,0.54);\n  border-right: none;\n  padding: 0 24px 0 24px;\n  background-color: white;\n  text-align: left;\n  box-shadow: 0 1px 0 rgba(0, 0, 0, 0.09),\n              0 2px 0 rgba(0, 0, 0, 0.03),\n              0 3px 0 rgba(0, 0, 0, 0.01),\n              0 4px 0 rgba(0, 0, 0, 0.005);\n  -webkit-user-select: none;\n}\n\ngoogle-chart ::content .google-visualization-table-td {\n  font-size: 13px;\n  color: rgba(0,0,0,0.87);\n  border-bottom: 1px solid #e3e3e3;\n  border-right: none;\n  padding: 0 24px 0 24px;\n}\n\ngoogle-chart ::content thead > tr {\n  height: 56px;\n}\n\ngoogle-chart ::content tbody > tr {\n  line-height: 2.2;\n}\n\ngoogle-chart ::content .sort-descending > span.google-visualization-table-sortind::after {\n  content: \"➔\";\n  font-size: 13px;\n  display: inline-block;\n  transform: rotate(90deg);\n  color: rgba(0, 0, 0, 0.87);\n}\n\ngoogle-chart ::content .sort-ascending > span.google-visualization-table-sortind::after {\n  content: \"➔\";\n  font-size: 13px;\n  display: inline-block;\n  transform: rotate(-90deg);\n  color: rgba(0, 0, 0, 0.87);\n}\n\ngoogle-chart ::content .google-visualization-table-div-page {\n  background-color: white;\n  position: relative;\n  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.14);\n  border: none;\n}\n\ngoogle-chart ::content tr.google-visualization-table-tr-sel,\ngoogle-chart ::content tr.google-visualization-table-tr-sel.google-visualization-table-tr-over {\n  background-color: #eee;\n}\n\ngoogle-chart ::content tr.google-visualization-table-tr-over {\n  background-color: #e9e9e9;\n}\n\ngoogle-chart ::content .google-visualization-table-tr-odd {\n  background-color: white;\n}\n\ngoogle-chart ::content a.google-visualization-table-page-number:hover {\n  font-weight: bold;\n}\n\ngoogle-chart ::content a.google-visualization-table-page-number {\n  padding: 4px;\n  background-color: white;\n  border: 1px solid rgba(0,0,0,.2);\n  text-align: center;\n  font-size: 11px;\n  color: rgba(0,0,0,.87);\n}\n\ngoogle-chart ::content a.google-visualization-table-page-number.current {\n  font-size: 12px;\n}\n\n/*\n * For the following rules, we have two versions for the experiment browser and\n * the other environments. In the experiment browser, the chart styles are\n * prefixed with \"charts\" while in other places the prefixes are \"goog\".\n */\ngoogle-chart ::content .goog-custom-button-hover .goog-custom-button-inner-box,\ngoogle-chart ::content .goog-custom-button-hover .goog-custom-button-outer-box,\ngoogle-chart ::content .charts-custom-button-hover .charts-custom-button-inner-box,\ngoogle-chart ::content .charts-custom-button-hover .charts-custom-button-outer-box {\n  border-color: rgba(0,0,0,.3) !important; /* Overwrite google-chart important */\n}\n\ngoogle-chart ::content .goog-inline-block.goog-custom-button-outer-box,\ngoogle-chart ::content .charts-inline-block.charts-custom-button-outer-box {\n  background-color: white;\n  border-color: rgba(0,0,0,.2);\n}\n\ngoogle-chart ::content .goog-inline-block.goog-custom-button-inner-box,\ngoogle-chart ::content .charts-inline-block.charts-custom-button-inner-box {\n  padding: 4px;\n  color: rgba(0,0,0,.4);\n}\n\n\n</style>\n    <gviz-table type=\"table\" options=\"[[options]]\" data=\"[[plotData_]]\" selection=\"{{selection}}\" chart-ready=\"{{tableReady_}}\">\n    </gviz-table>\n  </template>\n  </dom-module>\n<dom-module id=\"slice-overview\" assetpath=\"/slice-overview/\">\n  <template>\n    <style>\n      #controls {\n        margin: 0 auto 20px;\n        width: 724px;\n      }\n      #controls paper-dropdown-menu {\n        width: 320px;\n        padding: 0 12px;\n      }\n    </style>\n    <div id=\"controls\">\n      <paper-dropdown-menu label=\"Show\">\n        <paper-listbox class=\"dropdown-content\" selected=\"{{metricToShow}}\" attr-for-selected=\"value\">\n          <template is=\"dom-repeat\" items=\"[[metrics_]]\">\n            <paper-item value=\"[[item.name]]\" disabled=\"[[item.disabled]]\">\n              [[item.name]]\n            </paper-item>\n          </template>\n        </paper-listbox>\n      </paper-dropdown-menu>\n      <paper-dropdown-menu label=\"Sort by\">\n        <paper-listbox class=\"dropdown-content\" selected=\"{{metricToSort_}}\" attr-for-selected=\"value\">\n          <template is=\"dom-repeat\" items=\"[[metricsForSorting_]]\">\n            <paper-item value=\"[[item.name]]\" disabled=\"[[item.disabled]]\">\n              [[item.name]]\n            </paper-item>\n          </template>\n        </paper-listbox>\n      </paper-dropdown-menu>\n    </div>\n    <gviz-loader id=\"loader\" packages=\"[[chartPackages_]]\"></gviz-loader>\n    <div id=\"chart\"></div>\n  </template>\n  </dom-module>\n<dom-module id=\"lantern-browser\" assetpath=\"/lantern-browser/\">\n  \n  <template><style>\n#table {\n  display: block;\n  width: calc(100% - 240px);\n  margin: 20px 120px 60px 120px;\n}\n\n.ui {\n  margin: 20px auto 0;\n  /* Two ui-inputs, each 260px (have 10px soft margin) */\n  width: calc(260px * 2);\n}\n\n.ui-input {\n  width: 250px;\n}\n\n.ui-element {\n  display: inline-block;\n  margin-right: 2px;\n}\n\n.placeholder {\n  height: 32px;\n  display: flex;\n}\n\n::content .links {\n  text-transform: none;\n  font-weight: normal;\n  text-decoration: underline;\n  font-size: 13px;\n  color: #337ab7;\n}\n\n</style>\n    <div class=\"section ui\">\n      <span id=\"chart-type\" class=\"ui-element ui-input\">\n        <paper-dropdown-menu label=\"Visualization\">\n          <paper-listbox class=\"dropdown-content\" selected=\"{{chartType}}\">\n            <paper-item>Slices Overview</paper-item>\n            <paper-item>Metrics Histogram</paper-item>\n          </paper-listbox>\n        </paper-dropdown-menu>\n        <div class=\"placeholder\"></div>\n      </span>\n      <span id=\"weighted-examples-threshold\" class=\"ui-element ui-input\">\n        <paper-input-container always-float-label=\"\">\n          <label>Examples (Weighted) Threshold\n            <paper-icon-button suffix=\"\" icon=\"help\" title=\"ignore slices with number of (weighted) examples less than this threshold\"></paper-icon-button>\n          </label>\n          <input value=\"0\" type=\"number\">\n        </paper-input-container>\n        <paper-slider class=\"slider\" min=\"0\" max=\"[[weightedExamplesInfo_.max]]\" step=\"[[weightedExamplesInfo_.step]]\"></paper-slider>\n      </span>\n    </div>\n    <iron-pages selected=\"[[chartType]]\">\n      <slice-overview slices=\"[[filteredData_]]\" metric-to-show=\"[[weightedExamplesColumn]]\">\n      </slice-overview>\n      <div>\n        <metrics-histogram id=\"histogram\" data=\"[[filteredData_]]\" details-data=\"{{focusedData_}}\" weighted-examples-column=\"[[weightedExamplesColumn]]\" selected-features=\"[[selectedFeatures]]\" class=\"vis\"></metrics-histogram>\n      </div>\n    </iron-pages>\n    <metrics-table id=\"table\" data=\"[[metricsTableData_]]\" metrics=\"[[metrics]]\" metric-formats=\"[[metricFormats_]]\" selected=\"[[selectedColumn]]\">\n    </metrics-table>\n  </template>\n  </dom-module>\n</div>\n    <lantern-browser></lantern-browser>\n  \n\n\n<script>\n(function(){function resolve(){document.body.removeAttribute(\"unresolved\")}if(window.WebComponents)addEventListener(\"WebComponentsReady\",resolve);else if(document.readyState===\"interactive\"||document.readyState===\"complete\")resolve();else addEventListener(\"DOMContentLoaded\",resolve)})();\nwindow.Polymer={Settings:function(){var settings=window.Polymer||{};if(!settings.noUrlSettings){var parts=location.search.slice(1).split(\"&\");for(var i=0,o;i<parts.length&&(o=parts[i]);i++){o=o.split(\"=\");o[0]&&(settings[o[0]]=o[1]||true)}}settings.wantShadow=settings.dom===\"shadow\";settings.hasShadow=Boolean(Element.prototype.createShadowRoot);settings.nativeShadow=settings.hasShadow&&!window.ShadowDOMPolyfill;settings.useShadow=settings.wantShadow&&settings.hasShadow;settings.hasNativeImports=Boolean(\"import\"in\ndocument.createElement(\"link\"));settings.useNativeImports=settings.hasNativeImports;settings.useNativeCustomElements=!window.CustomElements||window.CustomElements.useNative;settings.useNativeShadow=settings.useShadow&&settings.nativeShadow;settings.usePolyfillProto=!settings.useNativeCustomElements&&!Object.__proto__;settings.hasNativeCSSProperties=!navigator.userAgent.match(\"AppleWebKit/601\")&&window.CSS&&CSS.supports&&CSS.supports(\"box-shadow\",\"0 0 0 var(--foo)\");settings.useNativeCSSProperties=\nsettings.hasNativeCSSProperties&&settings.lazyRegister&&settings.useNativeCSSProperties;settings.isIE=navigator.userAgent.match(\"Trident\");return settings}()};\n(function(){var userPolymer=window.Polymer;window.Polymer=function(prototype){if(typeof prototype===\"function\")prototype=prototype.prototype;if(!prototype)prototype={};prototype=desugar(prototype);var customCtor=prototype===prototype.constructor.prototype?prototype.constructor:null;var options={prototype:prototype};if(prototype[\"extends\"])options[\"extends\"]=prototype[\"extends\"];Polymer.telemetry._registrate(prototype);var ctor=document.registerElement(prototype.is,options);return customCtor||ctor};\nvar desugar=function(prototype){var base=Polymer.Base;if(prototype[\"extends\"])base=Polymer.Base._getExtendedPrototype(prototype[\"extends\"]);prototype=Polymer.Base.chainObject(prototype,base);prototype.registerCallback();return prototype};if(userPolymer)for(var i in userPolymer)Polymer[i]=userPolymer[i];Polymer.Class=function(prototype){if(!prototype.factoryImpl)prototype.factoryImpl=function(){};return desugar(prototype).constructor}})();\nPolymer.telemetry={registrations:[],_regLog:function(prototype){console.log(\"[\"+prototype.is+\"]: registered\")},_registrate:function(prototype){this.registrations.push(prototype);Polymer.log&&this._regLog(prototype)},dumpRegistrations:function(){this.registrations.forEach(this._regLog)}};Object.defineProperty(window,\"currentImport\",{enumerable:true,configurable:true,get:function(){return(document._currentScript||document.currentScript||{}).ownerDocument}});\nPolymer.RenderStatus={_ready:false,_callbacks:[],whenReady:function(cb){if(this._ready)cb();else this._callbacks.push(cb)},_makeReady:function(){this._ready=true;for(var i=0;i<this._callbacks.length;i++)this._callbacks[i]();this._callbacks=[]},_catchFirstRender:function(){requestAnimationFrame(function(){Polymer.RenderStatus._makeReady()})},_afterNextRenderQueue:[],_waitingNextRender:false,afterNextRender:function(element,fn,args){this._watchNextRender();this._afterNextRenderQueue.push([element,fn,\nargs])},hasRendered:function(){return this._ready},_watchNextRender:function(){if(!this._waitingNextRender){this._waitingNextRender=true;var fn=function(){Polymer.RenderStatus._flushNextRender()};if(!this._ready)this.whenReady(fn);else requestAnimationFrame(fn)}},_flushNextRender:function(){var self=this;setTimeout(function(){self._flushRenderCallbacks(self._afterNextRenderQueue);self._afterNextRenderQueue=[];self._waitingNextRender=false})},_flushRenderCallbacks:function(callbacks){for(var i=0,h;i<\ncallbacks.length;i++){h=callbacks[i];h[1].apply(h[0],h[2]||Polymer.nar)}}};if(window.HTMLImports)HTMLImports.whenReady(function(){Polymer.RenderStatus._catchFirstRender()});else Polymer.RenderStatus._catchFirstRender();Polymer.ImportStatus=Polymer.RenderStatus;Polymer.ImportStatus.whenLoaded=Polymer.ImportStatus.whenReady;\n(function(){var settings=Polymer.Settings;Polymer.Base={__isPolymerInstance__:true,_addFeature:function(feature){this.mixin(this,feature)},registerCallback:function(){if(settings.lazyRegister===\"max\"){if(this.beforeRegister)this.beforeRegister()}else{this._desugarBehaviors();for(var i=0,b;i<this.behaviors.length;i++){b=this.behaviors[i];if(b.beforeRegister)b.beforeRegister.call(this)}if(this.beforeRegister)this.beforeRegister()}this._registerFeatures();if(!settings.lazyRegister)this.ensureRegisterFinished()},\ncreatedCallback:function(){if(settings.disableUpgradeEnabled)if(this.hasAttribute(\"disable-upgrade\")){this._propertySetter=disableUpgradePropertySetter;this.__data__={};return}else this.__hasInitialized=true;this.__initialize()},__initialize:function(){if(!this.__hasRegisterFinished)this._ensureRegisterFinished(this.__proto__);Polymer.telemetry.instanceCount++;this.root=this;for(var i=0,b;i<this.behaviors.length;i++){b=this.behaviors[i];if(b.created)b.created.call(this)}if(this.created)this.created();\nthis._initFeatures()},ensureRegisterFinished:function(){this._ensureRegisterFinished(this)},_ensureRegisterFinished:function(proto){if(proto.__hasRegisterFinished!==proto.is||!proto.is){if(settings.lazyRegister===\"max\"){proto._desugarBehaviors();for(var i=0,b;i<proto.behaviors.length;i++){b=proto.behaviors[i];if(b.beforeRegister)b.beforeRegister.call(proto)}}proto.__hasRegisterFinished=proto.is;if(proto._finishRegisterFeatures)proto._finishRegisterFeatures();for(var j=0,pb;j<proto.behaviors.length;j++){pb=\nproto.behaviors[j];if(pb.registered)pb.registered.call(proto)}if(proto.registered)proto.registered();if(settings.usePolyfillProto&&proto!==this)proto.extend(this,proto)}},attachedCallback:function(){var self=this;Polymer.RenderStatus.whenReady(function(){self.isAttached=true;for(var i=0,b;i<self.behaviors.length;i++){b=self.behaviors[i];if(b.attached)b.attached.call(self)}if(self.attached)self.attached()})},detachedCallback:function(){var self=this;Polymer.RenderStatus.whenReady(function(){self.isAttached=\nfalse;for(var i=0,b;i<self.behaviors.length;i++){b=self.behaviors[i];if(b.detached)b.detached.call(self)}if(self.detached)self.detached()})},attributeChangedCallback:function(name,oldValue,newValue){this._attributeChangedImpl(name);for(var i=0,b;i<this.behaviors.length;i++){b=this.behaviors[i];if(b.attributeChanged)b.attributeChanged.call(this,name,oldValue,newValue)}if(this.attributeChanged)this.attributeChanged(name,oldValue,newValue)},_attributeChangedImpl:function(name){this._setAttributeToProperty(this,\nname)},extend:function(target,source){if(target&&source){var n$=Object.getOwnPropertyNames(source);for(var i=0,n;i<n$.length&&(n=n$[i]);i++)this.copyOwnProperty(n,source,target)}return target||source},mixin:function(target,source){for(var i in source)target[i]=source[i];return target},copyOwnProperty:function(name,source,target){var pd=Object.getOwnPropertyDescriptor(source,name);if(pd)Object.defineProperty(target,name,pd)},_logger:function(level,args){if(args.length===1&&Array.isArray(args[0]))args=\nargs[0];switch(level){case \"log\":case \"warn\":case \"error\":console[level].apply(console,args);break}},_log:function(){var args=Array.prototype.slice.call(arguments,0);this._logger(\"log\",args)},_warn:function(){var args=Array.prototype.slice.call(arguments,0);this._logger(\"warn\",args)},_error:function(){var args=Array.prototype.slice.call(arguments,0);this._logger(\"error\",args)},_logf:function(){return this._logPrefix.concat(this.is).concat(Array.prototype.slice.call(arguments,0))}};Polymer.Base._logPrefix=\nfunction(){var color=window.chrome&&!/edge/i.test(navigator.userAgent)||/firefox/i.test(navigator.userAgent);return color?[\"%c[%s::%s]:\",\"font-weight: bold; background-color:#EEEE00;\"]:[\"[%s::%s]:\"]}();Polymer.Base.chainObject=function(object,inherited){if(object&&inherited&&object!==inherited){if(!Object.__proto__)object=Polymer.Base.extend(Object.create(inherited),object);object.__proto__=inherited}return object};Polymer.Base=Polymer.Base.chainObject(Polymer.Base,HTMLElement.prototype);Polymer.BaseDescriptors=\n{};var disableUpgradePropertySetter;if(settings.disableUpgradeEnabled){disableUpgradePropertySetter=function(property,value){this.__data__[property]=value};var origAttributeChangedCallback=Polymer.Base.attributeChangedCallback;Polymer.Base.attributeChangedCallback=function(name,oldValue,newValue){if(!this.__hasInitialized&&name===\"disable-upgrade\"){this.__hasInitialized=true;this._propertySetter=Polymer.Bind._modelApi._propertySetter;this.__initialize()}origAttributeChangedCallback.call(this,name,\noldValue,newValue)}}if(window.CustomElements)Polymer[\"instanceof\"]=CustomElements[\"instanceof\"];else Polymer[\"instanceof\"]=function(obj,ctor){return obj instanceof ctor};Polymer.isInstance=function(obj){return Boolean(obj&&obj.__isPolymerInstance__)};Polymer.telemetry.instanceCount=0})();\n(function(){var modules={};var lcModules={};var findModule=function(id){return modules[id]||lcModules[id.toLowerCase()]};var DomModule=function(){return document.createElement(\"dom-module\")};DomModule.prototype=Object.create(HTMLElement.prototype);Polymer.Base.mixin(DomModule.prototype,{createdCallback:function(){this.register()},register:function(id){id=id||this.id||this.getAttribute(\"name\")||this.getAttribute(\"is\");if(id){this.id=id;modules[id]=this;lcModules[id.toLowerCase()]=this}},\"import\":function(id,\nselector){if(id){var m=findModule(id);if(!m){forceDomModulesUpgrade();m=findModule(id)}if(m&&selector)m=m.querySelector(selector);return m}}});Object.defineProperty(DomModule.prototype,\"constructor\",{value:DomModule,configurable:true,writable:true});var cePolyfill=window.CustomElements&&!CustomElements.useNative;document.registerElement(\"dom-module\",DomModule);function forceDomModulesUpgrade(){if(cePolyfill){var script=document._currentScript||document.currentScript;var doc=script&&script.ownerDocument||\ndocument;var modules=doc.querySelectorAll(\"dom-module\");for(var i=modules.length-1,m;i>=0&&(m=modules[i]);i--)if(m.__upgraded__)return;else CustomElements.upgrade(m)}}})();Polymer.Base._addFeature({_prepIs:function(){if(!this.is){var module=(document._currentScript||document.currentScript).parentNode;if(module.localName===\"dom-module\"){var id=module.id||module.getAttribute(\"name\")||module.getAttribute(\"is\");this.is=id}}if(this.is)this.is=this.is.toLowerCase()}});\nPolymer.Base._addFeature({behaviors:[],_desugarBehaviors:function(){if(this.behaviors.length)this.behaviors=this._desugarSomeBehaviors(this.behaviors)},_desugarSomeBehaviors:function(behaviors){var behaviorSet=[];behaviors=this._flattenBehaviorsList(behaviors);for(var i=behaviors.length-1;i>=0;i--){var b=behaviors[i];if(behaviorSet.indexOf(b)===-1){this._mixinBehavior(b);behaviorSet.unshift(b)}}return behaviorSet},_flattenBehaviorsList:function(behaviors){var flat=[];for(var i=0;i<behaviors.length;i++){var b=\nbehaviors[i];if(b instanceof Array)flat=flat.concat(this._flattenBehaviorsList(b));else if(b)flat.push(b);else this._warn(this._logf(\"_flattenBehaviorsList\",\"behavior is null, check for missing or 404 import\"))}return flat},_mixinBehavior:function(b){var n$=Object.getOwnPropertyNames(b);var useAssignment=b._noAccessors;for(var i=0,n;i<n$.length&&(n=n$[i]);i++)if(!Polymer.Base._behaviorProperties[n]&&!this.hasOwnProperty(n))if(useAssignment)this[n]=b[n];else this.copyOwnProperty(n,b,this)},_prepBehaviors:function(){this._prepFlattenedBehaviors(this.behaviors)},\n_prepFlattenedBehaviors:function(behaviors){for(var i=0,l=behaviors.length;i<l;i++)this._prepBehavior(behaviors[i]);this._prepBehavior(this)},_marshalBehaviors:function(){for(var i=0;i<this.behaviors.length;i++)this._marshalBehavior(this.behaviors[i]);this._marshalBehavior(this)}});Polymer.Base._behaviorProperties={hostAttributes:true,beforeRegister:true,registered:true,properties:true,observers:true,listeners:true,created:true,attached:true,detached:true,attributeChanged:true,ready:true,_noAccessors:true};\nPolymer.Base._addFeature({_getExtendedPrototype:function(tag){return this._getExtendedNativePrototype(tag)},_nativePrototypes:{},_getExtendedNativePrototype:function(tag){var p=this._nativePrototypes[tag];if(!p){p=Object.create(this.getNativePrototype(tag));var p$=Object.getOwnPropertyNames(Polymer.Base);for(var i=0,n;i<p$.length&&(n=p$[i]);i++)if(!Polymer.BaseDescriptors[n])p[n]=Polymer.Base[n];Object.defineProperties(p,Polymer.BaseDescriptors);this._nativePrototypes[tag]=p}return p},getNativePrototype:function(tag){return Object.getPrototypeOf(document.createElement(tag))}});\nPolymer.Base._addFeature({_prepConstructor:function(){this._factoryArgs=this[\"extends\"]?[this[\"extends\"],this.is]:[this.is];var ctor=function(){return this._factory(arguments)};if(this.hasOwnProperty(\"extends\"))ctor[\"extends\"]=this[\"extends\"];Object.defineProperty(this,\"constructor\",{value:ctor,writable:true,configurable:true});ctor.prototype=this},_factory:function(args){var elt=document.createElement.apply(document,this._factoryArgs);if(this.factoryImpl)this.factoryImpl.apply(elt,args);return elt}});\nPolymer.nob=Object.create(null);\nPolymer.Base._addFeature({getPropertyInfo:function(property){var info=this._getPropertyInfo(property,this.properties);if(!info)for(var i=0;i<this.behaviors.length;i++){info=this._getPropertyInfo(property,this.behaviors[i].properties);if(info)return info}return info||Polymer.nob},_getPropertyInfo:function(property,properties){var p=properties&&properties[property];if(typeof p===\"function\")p=properties[property]={type:p};if(p)p.defined=true;return p},_prepPropertyInfo:function(){this._propertyInfo={};\nfor(var i=0;i<this.behaviors.length;i++)this._addPropertyInfo(this._propertyInfo,this.behaviors[i].properties);this._addPropertyInfo(this._propertyInfo,this.properties);this._addPropertyInfo(this._propertyInfo,this._propertyEffects)},_addPropertyInfo:function(target,source){if(source){var t,s;for(var i in source){t=target[i];s=source[i];if(i[0]===\"_\"&&!s.readOnly)continue;if(!target[i])target[i]={type:typeof s===\"function\"?s:s.type,readOnly:s.readOnly,attribute:Polymer.CaseMap.camelToDashCase(i)};\nelse{if(!t.type)t.type=s.type;if(!t.readOnly)t.readOnly=s.readOnly}}}}});(function(){var propertiesDesc={configurable:true,writable:true,enumerable:true,value:{}};Polymer.BaseDescriptors.properties=propertiesDesc;Object.defineProperty(Polymer.Base,\"properties\",propertiesDesc)})();\nPolymer.CaseMap={_caseMap:{},_rx:{dashToCamel:/-[a-z]/g,camelToDash:/([A-Z])/g},dashToCamelCase:function(dash){return this._caseMap[dash]||(this._caseMap[dash]=dash.indexOf(\"-\")<0?dash:dash.replace(this._rx.dashToCamel,function(m){return m[1].toUpperCase()}))},camelToDashCase:function(camel){return this._caseMap[camel]||(this._caseMap[camel]=camel.replace(this._rx.camelToDash,\"-$1\").toLowerCase())}};\nPolymer.Base._addFeature({_addHostAttributes:function(attributes){if(!this._aggregatedAttributes)this._aggregatedAttributes={};if(attributes)this.mixin(this._aggregatedAttributes,attributes)},_marshalHostAttributes:function(){if(this._aggregatedAttributes)this._applyAttributes(this,this._aggregatedAttributes)},_applyAttributes:function(node,attr$){for(var n in attr$)if(!this.hasAttribute(n)&&n!==\"class\"){var v=attr$[n];this.serializeValueToAttribute(v,n,this)}},_marshalAttributes:function(){this._takeAttributesToModel(this)},\n_takeAttributesToModel:function(model){if(this.hasAttributes())for(var i in this._propertyInfo){var info=this._propertyInfo[i];if(this.hasAttribute(info.attribute))this._setAttributeToProperty(model,info.attribute,i,info)}},_setAttributeToProperty:function(model,attribute,property,info){if(!this._serializing){property=property||Polymer.CaseMap.dashToCamelCase(attribute);info=info||this._propertyInfo&&this._propertyInfo[property];if(info&&!info.readOnly){var v=this.getAttribute(attribute);model[property]=\nthis.deserialize(v,info.type)}}},_serializing:false,reflectPropertyToAttribute:function(property,attribute,value){this._serializing=true;value=value===undefined?this[property]:value;this.serializeValueToAttribute(value,attribute||Polymer.CaseMap.camelToDashCase(property));this._serializing=false},serializeValueToAttribute:function(value,attribute,node){var str=this.serialize(value);node=node||this;if(str===undefined)node.removeAttribute(attribute);else node.setAttribute(attribute,str)},deserialize:function(value,\ntype){switch(type){case Number:value=Number(value);break;case Boolean:value=value!=null;break;case Object:try{value=JSON.parse(value)}catch(x){}break;case Array:try{value=JSON.parse(value)}catch(x$0){value=null;console.warn(\"Polymer::Attributes: couldn`t decode Array as JSON\")}break;case Date:value=new Date(value);break;case String:default:break}return value},serialize:function(value){switch(typeof value){case \"boolean\":return value?\"\":undefined;case \"object\":if(value instanceof Date)return value.toString();\nelse if(value)try{return JSON.stringify(value)}catch(x){return\"\"}default:return value!=null?value:undefined}}});Polymer.version=\"1.8.0\";Polymer.Base._addFeature({_registerFeatures:function(){this._prepIs();this._prepBehaviors();this._prepConstructor();this._prepPropertyInfo()},_prepBehavior:function(b){this._addHostAttributes(b.hostAttributes)},_marshalBehavior:function(b){},_initFeatures:function(){this._marshalHostAttributes();this._marshalBehaviors()}});Polymer.Base._addFeature({_prepTemplate:function(){if(this._template===undefined)this._template=Polymer.DomModule[\"import\"](this.is,\"template\");if(this._template&&this._template.hasAttribute(\"is\"))this._warn(this._logf(\"_prepTemplate\",\"top-level Polymer template \"+\"must not be a type-extension, found\",this._template,\"Move inside simple <template>.\"));if(this._template&&!this._template.content&&window.HTMLTemplateElement&&HTMLTemplateElement.decorate)HTMLTemplateElement.decorate(this._template)},_stampTemplate:function(){if(this._template)this.root=\nthis.instanceTemplate(this._template)},instanceTemplate:function(template){var dom=document.importNode(template._content||template.content,true);return dom}});\n(function(){var baseAttachedCallback=Polymer.Base.attachedCallback;Polymer.Base._addFeature({_hostStack:[],ready:function(){},_registerHost:function(host){this.dataHost=host=host||Polymer.Base._hostStack[Polymer.Base._hostStack.length-1];if(host&&host._clients)host._clients.push(this);this._clients=null;this._clientsReadied=false},_beginHosting:function(){Polymer.Base._hostStack.push(this);if(!this._clients)this._clients=[]},_endHosting:function(){Polymer.Base._hostStack.pop()},_tryReady:function(){this._readied=\nfalse;if(this._canReady())this._ready()},_canReady:function(){return!this.dataHost||this.dataHost._clientsReadied},_ready:function(){this._beforeClientsReady();if(this._template){this._setupRoot();this._readyClients()}this._clientsReadied=true;this._clients=null;this._afterClientsReady();this._readySelf()},_readyClients:function(){this._beginDistribute();var c$=this._clients;if(c$)for(var i=0,l=c$.length,c;i<l&&(c=c$[i]);i++)c._ready();this._finishDistribute()},_readySelf:function(){for(var i=0,b;i<\nthis.behaviors.length;i++){b=this.behaviors[i];if(b.ready)b.ready.call(this)}if(this.ready)this.ready();this._readied=true;if(this._attachedPending){this._attachedPending=false;this.attachedCallback()}},_beforeClientsReady:function(){},_afterClientsReady:function(){},_beforeAttached:function(){},attachedCallback:function(){if(this._readied){this._beforeAttached();baseAttachedCallback.call(this)}else this._attachedPending=true}})})();\nPolymer.ArraySplice=function(){function newSplice(index,removed,addedCount){return{index:index,removed:removed,addedCount:addedCount}}var EDIT_LEAVE=0;var EDIT_UPDATE=1;var EDIT_ADD=2;var EDIT_DELETE=3;function ArraySplice(){}ArraySplice.prototype={calcEditDistances:function(current,currentStart,currentEnd,old,oldStart,oldEnd){var rowCount=oldEnd-oldStart+1;var columnCount=currentEnd-currentStart+1;var distances=new Array(rowCount);for(var i=0;i<rowCount;i++){distances[i]=new Array(columnCount);distances[i][0]=\ni}for(var j=0;j<columnCount;j++)distances[0][j]=j;for(i=1;i<rowCount;i++)for(j=1;j<columnCount;j++)if(this.equals(current[currentStart+j-1],old[oldStart+i-1]))distances[i][j]=distances[i-1][j-1];else{var north=distances[i-1][j]+1;var west=distances[i][j-1]+1;distances[i][j]=north<west?north:west}return distances},spliceOperationsFromEditDistances:function(distances){var i=distances.length-1;var j=distances[0].length-1;var current=distances[i][j];var edits=[];while(i>0||j>0){if(i==0){edits.push(EDIT_ADD);\nj--;continue}if(j==0){edits.push(EDIT_DELETE);i--;continue}var northWest=distances[i-1][j-1];var west=distances[i-1][j];var north=distances[i][j-1];var min;if(west<north)min=west<northWest?west:northWest;else min=north<northWest?north:northWest;if(min==northWest){if(northWest==current)edits.push(EDIT_LEAVE);else{edits.push(EDIT_UPDATE);current=northWest}i--;j--}else if(min==west){edits.push(EDIT_DELETE);i--;current=west}else{edits.push(EDIT_ADD);j--;current=north}}edits.reverse();return edits},calcSplices:function(current,\ncurrentStart,currentEnd,old,oldStart,oldEnd){var prefixCount=0;var suffixCount=0;var minLength=Math.min(currentEnd-currentStart,oldEnd-oldStart);if(currentStart==0&&oldStart==0)prefixCount=this.sharedPrefix(current,old,minLength);if(currentEnd==current.length&&oldEnd==old.length)suffixCount=this.sharedSuffix(current,old,minLength-prefixCount);currentStart+=prefixCount;oldStart+=prefixCount;currentEnd-=suffixCount;oldEnd-=suffixCount;if(currentEnd-currentStart==0&&oldEnd-oldStart==0)return[];if(currentStart==\ncurrentEnd){var splice=newSplice(currentStart,[],0);while(oldStart<oldEnd)splice.removed.push(old[oldStart++]);return[splice]}else if(oldStart==oldEnd)return[newSplice(currentStart,[],currentEnd-currentStart)];var ops=this.spliceOperationsFromEditDistances(this.calcEditDistances(current,currentStart,currentEnd,old,oldStart,oldEnd));splice=undefined;var splices=[];var index=currentStart;var oldIndex=oldStart;for(var i=0;i<ops.length;i++)switch(ops[i]){case EDIT_LEAVE:if(splice){splices.push(splice);\nsplice=undefined}index++;oldIndex++;break;case EDIT_UPDATE:if(!splice)splice=newSplice(index,[],0);splice.addedCount++;index++;splice.removed.push(old[oldIndex]);oldIndex++;break;case EDIT_ADD:if(!splice)splice=newSplice(index,[],0);splice.addedCount++;index++;break;case EDIT_DELETE:if(!splice)splice=newSplice(index,[],0);splice.removed.push(old[oldIndex]);oldIndex++;break}if(splice)splices.push(splice);return splices},sharedPrefix:function(current,old,searchLength){for(var i=0;i<searchLength;i++)if(!this.equals(current[i],\nold[i]))return i;return searchLength},sharedSuffix:function(current,old,searchLength){var index1=current.length;var index2=old.length;var count=0;while(count<searchLength&&this.equals(current[--index1],old[--index2]))count++;return count},calculateSplices:function(current,previous){return this.calcSplices(current,0,current.length,previous,0,previous.length)},equals:function(currentValue,previousValue){return currentValue===previousValue}};return new ArraySplice}();\nPolymer.domInnerHTML=function(){var escapeAttrRegExp=/[&\\u00A0\"]/g;var escapeDataRegExp=/[&\\u00A0<>]/g;function escapeReplace(c){switch(c){case \"&\":return\"&amp;\";case \"<\":return\"&lt;\";case \">\":return\"&gt;\";case '\"':return\"&quot;\";case \"\\u00a0\":return\"&nbsp;\"}}function escapeAttr(s){return s.replace(escapeAttrRegExp,escapeReplace)}function escapeData(s){return s.replace(escapeDataRegExp,escapeReplace)}function makeSet(arr){var set={};for(var i=0;i<arr.length;i++)set[arr[i]]=true;return set}var voidElements=\nmakeSet([\"area\",\"base\",\"br\",\"col\",\"command\",\"embed\",\"hr\",\"img\",\"input\",\"keygen\",\"link\",\"meta\",\"param\",\"source\",\"track\",\"wbr\"]);var plaintextParents=makeSet([\"style\",\"script\",\"xmp\",\"iframe\",\"noembed\",\"noframes\",\"plaintext\",\"noscript\"]);function getOuterHTML(node,parentNode,composed){switch(node.nodeType){case Node.ELEMENT_NODE:var tagName=node.localName;var s=\"<\"+tagName;var attrs=node.attributes;for(var i=0,attr;attr=attrs[i];i++)s+=\" \"+attr.name+'=\"'+escapeAttr(attr.value)+'\"';s+=\">\";if(voidElements[tagName])return s;\nreturn s+getInnerHTML(node,composed)+\"</\"+tagName+\">\";case Node.TEXT_NODE:var data=node.data;if(parentNode&&plaintextParents[parentNode.localName])return data;return escapeData(data);case Node.COMMENT_NODE:return\"\\x3c!--\"+node.data+\"--\\x3e\";default:console.error(node);throw new Error(\"not implemented\");}}function getInnerHTML(node,composed){if(node instanceof HTMLTemplateElement)node=node.content;var s=\"\";var c$=Polymer.dom(node).childNodes;for(var i=0,l=c$.length,child;i<l&&(child=c$[i]);i++)s+=\ngetOuterHTML(child,node,composed);return s}return{getInnerHTML:getInnerHTML}}();\n(function(){var nativeInsertBefore=Element.prototype.insertBefore;var nativeAppendChild=Element.prototype.appendChild;var nativeRemoveChild=Element.prototype.removeChild;Polymer.TreeApi={arrayCopyChildNodes:function(parent){var copy=[],i=0;for(var n=parent.firstChild;n;n=n.nextSibling)copy[i++]=n;return copy},arrayCopyChildren:function(parent){var copy=[],i=0;for(var n=parent.firstElementChild;n;n=n.nextElementSibling)copy[i++]=n;return copy},arrayCopy:function(a$){var l=a$.length;var copy=new Array(l);\nfor(var i=0;i<l;i++)copy[i]=a$[i];return copy}};Polymer.TreeApi.Logical={hasParentNode:function(node){return Boolean(node.__dom&&node.__dom.parentNode)},hasChildNodes:function(node){return Boolean(node.__dom&&node.__dom.childNodes!==undefined)},getChildNodes:function(node){return this.hasChildNodes(node)?this._getChildNodes(node):node.childNodes},_getChildNodes:function(node){if(!node.__dom.childNodes){node.__dom.childNodes=[];for(var n=node.__dom.firstChild;n;n=n.__dom.nextSibling)node.__dom.childNodes.push(n)}return node.__dom.childNodes},\ngetParentNode:function(node){return node.__dom&&node.__dom.parentNode!==undefined?node.__dom.parentNode:node.parentNode},getFirstChild:function(node){return node.__dom&&node.__dom.firstChild!==undefined?node.__dom.firstChild:node.firstChild},getLastChild:function(node){return node.__dom&&node.__dom.lastChild!==undefined?node.__dom.lastChild:node.lastChild},getNextSibling:function(node){return node.__dom&&node.__dom.nextSibling!==undefined?node.__dom.nextSibling:node.nextSibling},getPreviousSibling:function(node){return node.__dom&&\nnode.__dom.previousSibling!==undefined?node.__dom.previousSibling:node.previousSibling},getFirstElementChild:function(node){return node.__dom&&node.__dom.firstChild!==undefined?this._getFirstElementChild(node):node.firstElementChild},_getFirstElementChild:function(node){var n=node.__dom.firstChild;while(n&&n.nodeType!==Node.ELEMENT_NODE)n=n.__dom.nextSibling;return n},getLastElementChild:function(node){return node.__dom&&node.__dom.lastChild!==undefined?this._getLastElementChild(node):node.lastElementChild},\n_getLastElementChild:function(node){var n=node.__dom.lastChild;while(n&&n.nodeType!==Node.ELEMENT_NODE)n=n.__dom.previousSibling;return n},getNextElementSibling:function(node){return node.__dom&&node.__dom.nextSibling!==undefined?this._getNextElementSibling(node):node.nextElementSibling},_getNextElementSibling:function(node){var n=node.__dom.nextSibling;while(n&&n.nodeType!==Node.ELEMENT_NODE)n=n.__dom.nextSibling;return n},getPreviousElementSibling:function(node){return node.__dom&&node.__dom.previousSibling!==\nundefined?this._getPreviousElementSibling(node):node.previousElementSibling},_getPreviousElementSibling:function(node){var n=node.__dom.previousSibling;while(n&&n.nodeType!==Node.ELEMENT_NODE)n=n.__dom.previousSibling;return n},saveChildNodes:function(node){if(!this.hasChildNodes(node)){node.__dom=node.__dom||{};node.__dom.firstChild=node.firstChild;node.__dom.lastChild=node.lastChild;node.__dom.childNodes=[];for(var n=node.firstChild;n;n=n.nextSibling){n.__dom=n.__dom||{};n.__dom.parentNode=node;\nnode.__dom.childNodes.push(n);n.__dom.nextSibling=n.nextSibling;n.__dom.previousSibling=n.previousSibling}}},recordInsertBefore:function(node,container,ref_node){container.__dom.childNodes=null;if(node.nodeType===Node.DOCUMENT_FRAGMENT_NODE)for(var n=node.firstChild;n;n=n.nextSibling)this._linkNode(n,container,ref_node);else this._linkNode(node,container,ref_node)},_linkNode:function(node,container,ref_node){node.__dom=node.__dom||{};container.__dom=container.__dom||{};if(ref_node)ref_node.__dom=\nref_node.__dom||{};node.__dom.previousSibling=ref_node?ref_node.__dom.previousSibling:container.__dom.lastChild;if(node.__dom.previousSibling)node.__dom.previousSibling.__dom.nextSibling=node;node.__dom.nextSibling=ref_node||null;if(node.__dom.nextSibling)node.__dom.nextSibling.__dom.previousSibling=node;node.__dom.parentNode=container;if(ref_node){if(ref_node===container.__dom.firstChild)container.__dom.firstChild=node}else{container.__dom.lastChild=node;if(!container.__dom.firstChild)container.__dom.firstChild=\nnode}container.__dom.childNodes=null},recordRemoveChild:function(node,container){node.__dom=node.__dom||{};container.__dom=container.__dom||{};if(node===container.__dom.firstChild)container.__dom.firstChild=node.__dom.nextSibling;if(node===container.__dom.lastChild)container.__dom.lastChild=node.__dom.previousSibling;var p=node.__dom.previousSibling;var n=node.__dom.nextSibling;if(p)p.__dom.nextSibling=n;if(n)n.__dom.previousSibling=p;node.__dom.parentNode=node.__dom.previousSibling=node.__dom.nextSibling=\nundefined;container.__dom.childNodes=null}};Polymer.TreeApi.Composed={getChildNodes:function(node){return Polymer.TreeApi.arrayCopyChildNodes(node)},getParentNode:function(node){return node.parentNode},clearChildNodes:function(node){node.textContent=\"\"},insertBefore:function(parentNode,newChild,refChild){return nativeInsertBefore.call(parentNode,newChild,refChild||null)},appendChild:function(parentNode,newChild){return nativeAppendChild.call(parentNode,newChild)},removeChild:function(parentNode,node){return nativeRemoveChild.call(parentNode,\nnode)}}})();\nPolymer.DomApi=function(){var Settings=Polymer.Settings;var TreeApi=Polymer.TreeApi;var DomApi=function(node){this.node=needsToWrap?DomApi.wrap(node):node};var needsToWrap=Settings.hasShadow&&!Settings.nativeShadow;DomApi.wrap=window.wrap?window.wrap:function(node){return node};DomApi.prototype={flush:function(){Polymer.dom.flush()},deepContains:function(node){if(this.node.contains(node))return true;var n=node;var doc=node.ownerDocument;while(n&&n!==doc&&n!==this.node)n=Polymer.dom(n).parentNode||n.host;\nreturn n===this.node},queryDistributedElements:function(selector){var c$=this.getEffectiveChildNodes();var list=[];for(var i=0,l=c$.length,c;i<l&&(c=c$[i]);i++)if(c.nodeType===Node.ELEMENT_NODE&&DomApi.matchesSelector.call(c,selector))list.push(c);return list},getEffectiveChildNodes:function(){var list=[];var c$=this.childNodes;for(var i=0,l=c$.length,c;i<l&&(c=c$[i]);i++)if(c.localName===CONTENT){var d$=dom(c).getDistributedNodes();for(var j=0;j<d$.length;j++)list.push(d$[j])}else list.push(c);return list},\nobserveNodes:function(callback){if(callback){if(!this.observer)this.observer=this.node.localName===CONTENT?new DomApi.DistributedNodesObserver(this):new DomApi.EffectiveNodesObserver(this);return this.observer.addListener(callback)}},unobserveNodes:function(handle){if(this.observer)this.observer.removeListener(handle)},notifyObserver:function(){if(this.observer)this.observer.notify()},_query:function(matcher,node,halter){node=node||this.node;var list=[];this._queryElements(TreeApi.Logical.getChildNodes(node),\nmatcher,halter,list);return list},_queryElements:function(elements,matcher,halter,list){for(var i=0,l=elements.length,c;i<l&&(c=elements[i]);i++)if(c.nodeType===Node.ELEMENT_NODE)if(this._queryElement(c,matcher,halter,list))return true},_queryElement:function(node,matcher,halter,list){var result=matcher(node);if(result)list.push(node);if(halter&&halter(result))return result;this._queryElements(TreeApi.Logical.getChildNodes(node),matcher,halter,list)}};var CONTENT=DomApi.CONTENT=\"content\";var dom=\nDomApi.factory=function(node){node=node||document;if(!node.__domApi)node.__domApi=new DomApi.ctor(node);return node.__domApi};DomApi.hasApi=function(node){return Boolean(node.__domApi)};DomApi.ctor=DomApi;Polymer.dom=function(obj,patch){if(obj instanceof Event)return Polymer.EventApi.factory(obj);else return DomApi.factory(obj,patch)};var p=Element.prototype;DomApi.matchesSelector=p.matches||p.matchesSelector||p.mozMatchesSelector||p.msMatchesSelector||p.oMatchesSelector||p.webkitMatchesSelector;\nreturn DomApi}();\n(function(){var Settings=Polymer.Settings;var DomApi=Polymer.DomApi;var dom=DomApi.factory;var TreeApi=Polymer.TreeApi;var getInnerHTML=Polymer.domInnerHTML.getInnerHTML;var CONTENT=DomApi.CONTENT;if(Settings.useShadow)return;var nativeCloneNode=Element.prototype.cloneNode;var nativeImportNode=Document.prototype.importNode;Polymer.Base.mixin(DomApi.prototype,{_lazyDistribute:function(host){if(host.shadyRoot&&host.shadyRoot._distributionClean){host.shadyRoot._distributionClean=false;Polymer.dom.addDebouncer(host.debounce(\"_distribute\",\nhost._distributeContent))}},appendChild:function(node){return this.insertBefore(node)},insertBefore:function(node,ref_node){if(ref_node&&TreeApi.Logical.getParentNode(ref_node)!==this.node)throw Error(\"The ref_node to be inserted before is not a child \"+\"of this node\");if(node.nodeType!==Node.DOCUMENT_FRAGMENT_NODE){var parent=TreeApi.Logical.getParentNode(node);if(parent){if(DomApi.hasApi(parent))dom(parent).notifyObserver();this._removeNode(node)}else this._removeOwnerShadyRoot(node)}if(!this._addNode(node,\nref_node)){if(ref_node)ref_node=ref_node.localName===CONTENT?this._firstComposedNode(ref_node):ref_node;var container=this.node._isShadyRoot?this.node.host:this.node;if(ref_node)TreeApi.Composed.insertBefore(container,node,ref_node);else TreeApi.Composed.appendChild(container,node)}this.notifyObserver();return node},_addNode:function(node,ref_node){var root=this.getOwnerRoot();if(root){var ipAdded=this._maybeAddInsertionPoint(node,this.node);if(!root._invalidInsertionPoints)root._invalidInsertionPoints=\nipAdded;this._addNodeToHost(root.host,node)}if(TreeApi.Logical.hasChildNodes(this.node))TreeApi.Logical.recordInsertBefore(node,this.node,ref_node);var handled=this._maybeDistribute(node)||this.node.shadyRoot;if(handled)if(node.nodeType===Node.DOCUMENT_FRAGMENT_NODE)while(node.firstChild)TreeApi.Composed.removeChild(node,node.firstChild);else{var parent=TreeApi.Composed.getParentNode(node);if(parent)TreeApi.Composed.removeChild(parent,node)}return handled},removeChild:function(node){if(TreeApi.Logical.getParentNode(node)!==\nthis.node)throw Error(\"The node to be removed is not a child of this node: \"+node);if(!this._removeNode(node)){var container=this.node._isShadyRoot?this.node.host:this.node;var parent=TreeApi.Composed.getParentNode(node);if(container===parent)TreeApi.Composed.removeChild(container,node)}this.notifyObserver();return node},_removeNode:function(node){var logicalParent=TreeApi.Logical.hasParentNode(node)&&TreeApi.Logical.getParentNode(node);var distributed;var root=this._ownerShadyRootForNode(node);if(logicalParent){distributed=\ndom(node)._maybeDistributeParent();TreeApi.Logical.recordRemoveChild(node,logicalParent);if(root&&this._removeDistributedChildren(root,node)){root._invalidInsertionPoints=true;this._lazyDistribute(root.host)}}this._removeOwnerShadyRoot(node);if(root)this._removeNodeFromHost(root.host,node);return distributed},replaceChild:function(node,ref_node){this.insertBefore(node,ref_node);this.removeChild(ref_node);return node},_hasCachedOwnerRoot:function(node){return Boolean(node._ownerShadyRoot!==undefined)},\ngetOwnerRoot:function(){return this._ownerShadyRootForNode(this.node)},_ownerShadyRootForNode:function(node){if(!node)return;var root=node._ownerShadyRoot;if(root===undefined){if(node._isShadyRoot)root=node;else{var parent=TreeApi.Logical.getParentNode(node);if(parent)root=parent._isShadyRoot?parent:this._ownerShadyRootForNode(parent);else root=null}if(root||document.documentElement.contains(node))node._ownerShadyRoot=root}return root},_maybeDistribute:function(node){var fragContent=node.nodeType===\nNode.DOCUMENT_FRAGMENT_NODE&&!node.__noContent&&dom(node).querySelector(CONTENT);var wrappedContent=fragContent&&TreeApi.Logical.getParentNode(fragContent).nodeType!==Node.DOCUMENT_FRAGMENT_NODE;var hasContent=fragContent||node.localName===CONTENT;if(hasContent){var root=this.getOwnerRoot();if(root)this._lazyDistribute(root.host)}var needsDist=this._nodeNeedsDistribution(this.node);if(needsDist)this._lazyDistribute(this.node);return needsDist||hasContent&&!wrappedContent},_maybeAddInsertionPoint:function(node,\nparent){var added;if(node.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&!node.__noContent){var c$=dom(node).querySelectorAll(CONTENT);for(var i=0,n,np,na;i<c$.length&&(n=c$[i]);i++){np=TreeApi.Logical.getParentNode(n);if(np===node)np=parent;na=this._maybeAddInsertionPoint(n,np);added=added||na}}else if(node.localName===CONTENT){TreeApi.Logical.saveChildNodes(parent);TreeApi.Logical.saveChildNodes(node);added=true}return added},_updateInsertionPoints:function(host){var i$=host.shadyRoot._insertionPoints=\ndom(host.shadyRoot).querySelectorAll(CONTENT);for(var i=0,c;i<i$.length;i++){c=i$[i];TreeApi.Logical.saveChildNodes(c);TreeApi.Logical.saveChildNodes(TreeApi.Logical.getParentNode(c))}},_nodeNeedsDistribution:function(node){return node&&node.shadyRoot&&DomApi.hasInsertionPoint(node.shadyRoot)},_addNodeToHost:function(host,node){if(host._elementAdd)host._elementAdd(node)},_removeNodeFromHost:function(host,node){if(host._elementRemove)host._elementRemove(node)},_removeDistributedChildren:function(root,\ncontainer){var hostNeedsDist;var ip$=root._insertionPoints;for(var i=0;i<ip$.length;i++){var content=ip$[i];if(this._contains(container,content)){var dc$=dom(content).getDistributedNodes();for(var j=0;j<dc$.length;j++){hostNeedsDist=true;var node=dc$[j];var parent=TreeApi.Composed.getParentNode(node);if(parent)TreeApi.Composed.removeChild(parent,node)}}}return hostNeedsDist},_contains:function(container,node){while(node){if(node==container)return true;node=TreeApi.Logical.getParentNode(node)}},_removeOwnerShadyRoot:function(node){if(this._hasCachedOwnerRoot(node)){var c$=\nTreeApi.Logical.getChildNodes(node);for(var i=0,l=c$.length,n;i<l&&(n=c$[i]);i++)this._removeOwnerShadyRoot(n)}node._ownerShadyRoot=undefined},_firstComposedNode:function(content){var n$=dom(content).getDistributedNodes();for(var i=0,l=n$.length,n,p$;i<l&&(n=n$[i]);i++){p$=dom(n).getDestinationInsertionPoints();if(p$[p$.length-1]===content)return n}},querySelector:function(selector){var result=this._query(function(n){return DomApi.matchesSelector.call(n,selector)},this.node,function(n){return Boolean(n)})[0];\nreturn result||null},querySelectorAll:function(selector){return this._query(function(n){return DomApi.matchesSelector.call(n,selector)},this.node)},getDestinationInsertionPoints:function(){return this.node._destinationInsertionPoints||[]},getDistributedNodes:function(){return this.node._distributedNodes||[]},_clear:function(){while(this.childNodes.length)this.removeChild(this.childNodes[0])},setAttribute:function(name,value){this.node.setAttribute(name,value);this._maybeDistributeParent()},removeAttribute:function(name){this.node.removeAttribute(name);\nthis._maybeDistributeParent()},_maybeDistributeParent:function(){if(this._nodeNeedsDistribution(this.parentNode)){this._lazyDistribute(this.parentNode);return true}},cloneNode:function(deep){var n=nativeCloneNode.call(this.node,false);if(deep){var c$=this.childNodes;var d=dom(n);for(var i=0,nc;i<c$.length;i++){nc=dom(c$[i]).cloneNode(true);d.appendChild(nc)}}return n},importNode:function(externalNode,deep){var doc=this.node instanceof Document?this.node:this.node.ownerDocument;var n=nativeImportNode.call(doc,\nexternalNode,false);if(deep){var c$=TreeApi.Logical.getChildNodes(externalNode);var d=dom(n);for(var i=0,nc;i<c$.length;i++){nc=dom(doc).importNode(c$[i],true);d.appendChild(nc)}}return n},_getComposedInnerHTML:function(){return getInnerHTML(this.node,true)}});Object.defineProperties(DomApi.prototype,{activeElement:{get:function(){var active=document.activeElement;if(!active)return null;var isShadyRoot=!!this.node._isShadyRoot;if(this.node!==document){if(!isShadyRoot)return null;if(this.node.host===\nactive||!this.node.host.contains(active))return null}var activeRoot=dom(active).getOwnerRoot();while(activeRoot&&activeRoot!==this.node){active=activeRoot.host;activeRoot=dom(active).getOwnerRoot()}if(this.node===document)return activeRoot?null:active;else return activeRoot===this.node?active:null},configurable:true},childNodes:{get:function(){var c$=TreeApi.Logical.getChildNodes(this.node);return Array.isArray(c$)?c$:TreeApi.arrayCopyChildNodes(this.node)},configurable:true},children:{get:function(){if(TreeApi.Logical.hasChildNodes(this.node))return Array.prototype.filter.call(this.childNodes,\nfunction(n){return n.nodeType===Node.ELEMENT_NODE});else return TreeApi.arrayCopyChildren(this.node)},configurable:true},parentNode:{get:function(){return TreeApi.Logical.getParentNode(this.node)},configurable:true},firstChild:{get:function(){return TreeApi.Logical.getFirstChild(this.node)},configurable:true},lastChild:{get:function(){return TreeApi.Logical.getLastChild(this.node)},configurable:true},nextSibling:{get:function(){return TreeApi.Logical.getNextSibling(this.node)},configurable:true},\npreviousSibling:{get:function(){return TreeApi.Logical.getPreviousSibling(this.node)},configurable:true},firstElementChild:{get:function(){return TreeApi.Logical.getFirstElementChild(this.node)},configurable:true},lastElementChild:{get:function(){return TreeApi.Logical.getLastElementChild(this.node)},configurable:true},nextElementSibling:{get:function(){return TreeApi.Logical.getNextElementSibling(this.node)},configurable:true},previousElementSibling:{get:function(){return TreeApi.Logical.getPreviousElementSibling(this.node)},\nconfigurable:true},textContent:{get:function(){var nt=this.node.nodeType;if(nt===Node.TEXT_NODE||nt===Node.COMMENT_NODE)return this.node.textContent;else{var tc=[];for(var i=0,cn=this.childNodes,c;c=cn[i];i++)if(c.nodeType!==Node.COMMENT_NODE)tc.push(c.textContent);return tc.join(\"\")}},set:function(text){var nt=this.node.nodeType;if(nt===Node.TEXT_NODE||nt===Node.COMMENT_NODE)this.node.textContent=text;else{this._clear();if(text)this.appendChild(document.createTextNode(text))}},configurable:true},\ninnerHTML:{get:function(){var nt=this.node.nodeType;if(nt===Node.TEXT_NODE||nt===Node.COMMENT_NODE)return null;else return getInnerHTML(this.node)},set:function(text){var nt=this.node.nodeType;if(nt!==Node.TEXT_NODE||nt!==Node.COMMENT_NODE){this._clear();var d=document.createElement(\"div\");d.innerHTML=text;var c$=TreeApi.arrayCopyChildNodes(d);for(var i=0;i<c$.length;i++)this.appendChild(c$[i])}},configurable:true}});DomApi.hasInsertionPoint=function(root){return Boolean(root&&root._insertionPoints.length)}})();\n(function(){var Settings=Polymer.Settings;var TreeApi=Polymer.TreeApi;var DomApi=Polymer.DomApi;if(!Settings.useShadow)return;Polymer.Base.mixin(DomApi.prototype,{querySelectorAll:function(selector){return TreeApi.arrayCopy(this.node.querySelectorAll(selector))},getOwnerRoot:function(){var n=this.node;while(n){if(n.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&n.host)return n;n=n.parentNode}},importNode:function(externalNode,deep){var doc=this.node instanceof Document?this.node:this.node.ownerDocument;\nreturn doc.importNode(externalNode,deep)},getDestinationInsertionPoints:function(){var n$=this.node.getDestinationInsertionPoints&&this.node.getDestinationInsertionPoints();return n$?TreeApi.arrayCopy(n$):[]},getDistributedNodes:function(){var n$=this.node.getDistributedNodes&&this.node.getDistributedNodes();return n$?TreeApi.arrayCopy(n$):[]}});Object.defineProperties(DomApi.prototype,{activeElement:{get:function(){var node=DomApi.wrap(this.node);var activeElement=node.activeElement;return node.contains(activeElement)?\nactiveElement:null},configurable:true},childNodes:{get:function(){return TreeApi.arrayCopyChildNodes(this.node)},configurable:true},children:{get:function(){return TreeApi.arrayCopyChildren(this.node)},configurable:true},textContent:{get:function(){return this.node.textContent},set:function(value){return this.node.textContent=value},configurable:true},innerHTML:{get:function(){return this.node.innerHTML},set:function(value){return this.node.innerHTML=value},configurable:true}});var forwardMethods=\nfunction(m$){for(var i=0;i<m$.length;i++)forwardMethod(m$[i])};var forwardMethod=function(method){DomApi.prototype[method]=function(){return this.node[method].apply(this.node,arguments)}};forwardMethods([\"cloneNode\",\"appendChild\",\"insertBefore\",\"removeChild\",\"replaceChild\",\"setAttribute\",\"removeAttribute\",\"querySelector\"]);var forwardProperties=function(f$){for(var i=0;i<f$.length;i++)forwardProperty(f$[i])};var forwardProperty=function(name){Object.defineProperty(DomApi.prototype,name,{get:function(){return this.node[name]},\nconfigurable:true})};forwardProperties([\"parentNode\",\"firstChild\",\"lastChild\",\"nextSibling\",\"previousSibling\",\"firstElementChild\",\"lastElementChild\",\"nextElementSibling\",\"previousElementSibling\"])})();\nPolymer.Base.mixin(Polymer.dom,{_flushGuard:0,_FLUSH_MAX:100,_needsTakeRecords:!Polymer.Settings.useNativeCustomElements,_debouncers:[],_staticFlushList:[],_finishDebouncer:null,flush:function(){this._flushGuard=0;this._prepareFlush();while(this._debouncers.length&&this._flushGuard<this._FLUSH_MAX){while(this._debouncers.length)this._debouncers.shift().complete();if(this._finishDebouncer)this._finishDebouncer.complete();this._prepareFlush();this._flushGuard++}if(this._flushGuard>=this._FLUSH_MAX)console.warn(\"Polymer.dom.flush aborted. Flush may not be complete.\")},\n_prepareFlush:function(){if(this._needsTakeRecords)CustomElements.takeRecords();for(var i=0;i<this._staticFlushList.length;i++)this._staticFlushList[i]()},addStaticFlush:function(fn){this._staticFlushList.push(fn)},removeStaticFlush:function(fn){var i=this._staticFlushList.indexOf(fn);if(i>=0)this._staticFlushList.splice(i,1)},addDebouncer:function(debouncer){this._debouncers.push(debouncer);this._finishDebouncer=Polymer.Debounce(this._finishDebouncer,this._finishFlush)},_finishFlush:function(){Polymer.dom._debouncers=\n[]}});\nPolymer.EventApi=function(){var DomApi=Polymer.DomApi.ctor;var Settings=Polymer.Settings;DomApi.Event=function(event){this.event=event};if(Settings.useShadow)DomApi.Event.prototype={get rootTarget(){return this.event.path[0]},get localTarget(){return this.event.target},get path(){var path=this.event.path;if(!Array.isArray(path))path=Array.prototype.slice.call(path);return path}};else DomApi.Event.prototype={get rootTarget(){return this.event.target},get localTarget(){var current=this.event.currentTarget;var currentRoot=\ncurrent&&Polymer.dom(current).getOwnerRoot();var p$=this.path;for(var i=0;i<p$.length;i++)if(Polymer.dom(p$[i]).getOwnerRoot()===currentRoot)return p$[i]},get path(){if(!this.event._path){var path=[];var current=this.rootTarget;while(current){path.push(current);var insertionPoints=Polymer.dom(current).getDestinationInsertionPoints();if(insertionPoints.length){for(var i=0;i<insertionPoints.length-1;i++)path.push(insertionPoints[i]);current=insertionPoints[insertionPoints.length-1]}else current=Polymer.dom(current).parentNode||\ncurrent.host}path.push(window);this.event._path=path}return this.event._path}};var factory=function(event){if(!event.__eventApi)event.__eventApi=new DomApi.Event(event);return event.__eventApi};return{factory:factory}}();\n(function(){var DomApi=Polymer.DomApi.ctor;var useShadow=Polymer.Settings.useShadow;Object.defineProperty(DomApi.prototype,\"classList\",{get:function(){if(!this._classList)this._classList=new DomApi.ClassList(this);return this._classList},configurable:true});DomApi.ClassList=function(host){this.domApi=host;this.node=host.node};DomApi.ClassList.prototype={add:function(){this.node.classList.add.apply(this.node.classList,arguments);this._distributeParent()},remove:function(){this.node.classList.remove.apply(this.node.classList,\narguments);this._distributeParent()},toggle:function(){this.node.classList.toggle.apply(this.node.classList,arguments);this._distributeParent()},_distributeParent:function(){if(!useShadow)this.domApi._maybeDistributeParent()},contains:function(){return this.node.classList.contains.apply(this.node.classList,arguments)}}})();\n(function(){var DomApi=Polymer.DomApi.ctor;var Settings=Polymer.Settings;DomApi.EffectiveNodesObserver=function(domApi){this.domApi=domApi;this.node=this.domApi.node;this._listeners=[]};DomApi.EffectiveNodesObserver.prototype={addListener:function(callback){if(!this._isSetup){this._setup();this._isSetup=true}var listener={fn:callback,_nodes:[]};this._listeners.push(listener);this._scheduleNotify();return listener},removeListener:function(handle){var i=this._listeners.indexOf(handle);if(i>=0){this._listeners.splice(i,\n1);handle._nodes=[]}if(!this._hasListeners()){this._cleanup();this._isSetup=false}},_setup:function(){this._observeContentElements(this.domApi.childNodes)},_cleanup:function(){this._unobserveContentElements(this.domApi.childNodes)},_hasListeners:function(){return Boolean(this._listeners.length)},_scheduleNotify:function(){if(this._debouncer)this._debouncer.stop();this._debouncer=Polymer.Debounce(this._debouncer,this._notify);this._debouncer.context=this;Polymer.dom.addDebouncer(this._debouncer)},\nnotify:function(){if(this._hasListeners())this._scheduleNotify()},_notify:function(){this._beforeCallListeners();this._callListeners()},_beforeCallListeners:function(){this._updateContentElements()},_updateContentElements:function(){this._observeContentElements(this.domApi.childNodes)},_observeContentElements:function(elements){for(var i=0,n;i<elements.length&&(n=elements[i]);i++)if(this._isContent(n)){n.__observeNodesMap=n.__observeNodesMap||new WeakMap;if(!n.__observeNodesMap.has(this))n.__observeNodesMap.set(this,\nthis._observeContent(n))}},_observeContent:function(content){var self=this;var h=Polymer.dom(content).observeNodes(function(){self._scheduleNotify()});h._avoidChangeCalculation=true;return h},_unobserveContentElements:function(elements){for(var i=0,n,h;i<elements.length&&(n=elements[i]);i++)if(this._isContent(n)){h=n.__observeNodesMap.get(this);if(h){Polymer.dom(n).unobserveNodes(h);n.__observeNodesMap[\"delete\"](this)}}},_isContent:function(node){return node.localName===\"content\"},_callListeners:function(){var o$=\nthis._listeners;var nodes=this._getEffectiveNodes();for(var i=0,o;i<o$.length&&(o=o$[i]);i++){var info=this._generateListenerInfo(o,nodes);if(info||o._alwaysNotify)this._callListener(o,info)}},_getEffectiveNodes:function(){return this.domApi.getEffectiveChildNodes()},_generateListenerInfo:function(listener,newNodes){if(listener._avoidChangeCalculation)return true;var oldNodes=listener._nodes;var info={target:this.node,addedNodes:[],removedNodes:[]};var splices=Polymer.ArraySplice.calculateSplices(newNodes,\noldNodes);for(var i=0,s;i<splices.length&&(s=splices[i]);i++)for(var j=0,n;j<s.removed.length&&(n=s.removed[j]);j++)info.removedNodes.push(n);for(i=0,s;i<splices.length&&(s=splices[i]);i++)for(j=s.index;j<s.index+s.addedCount;j++)info.addedNodes.push(newNodes[j]);listener._nodes=newNodes;if(info.addedNodes.length||info.removedNodes.length)return info},_callListener:function(listener,info){return listener.fn.call(this.node,info)},enableShadowAttributeTracking:function(){}};if(Settings.useShadow){var baseSetup=\nDomApi.EffectiveNodesObserver.prototype._setup;var baseCleanup=DomApi.EffectiveNodesObserver.prototype._cleanup;Polymer.Base.mixin(DomApi.EffectiveNodesObserver.prototype,{_setup:function(){if(!this._observer){var self=this;this._mutationHandler=function(mxns){if(mxns&&mxns.length)self._scheduleNotify()};this._observer=new MutationObserver(this._mutationHandler);this._boundFlush=function(){self._flush()};Polymer.dom.addStaticFlush(this._boundFlush);this._observer.observe(this.node,{childList:true})}baseSetup.call(this)},\n_cleanup:function(){this._observer.disconnect();this._observer=null;this._mutationHandler=null;Polymer.dom.removeStaticFlush(this._boundFlush);baseCleanup.call(this)},_flush:function(){if(this._observer)this._mutationHandler(this._observer.takeRecords())},enableShadowAttributeTracking:function(){if(this._observer){this._makeContentListenersAlwaysNotify();this._observer.disconnect();this._observer.observe(this.node,{childList:true,attributes:true,subtree:true});var root=this.domApi.getOwnerRoot();\nvar host=root&&root.host;if(host&&Polymer.dom(host).observer)Polymer.dom(host).observer.enableShadowAttributeTracking()}},_makeContentListenersAlwaysNotify:function(){for(var i=0,h;i<this._listeners.length;i++){h=this._listeners[i];h._alwaysNotify=h._isContentListener}}})}})();\n(function(){var DomApi=Polymer.DomApi.ctor;var Settings=Polymer.Settings;DomApi.DistributedNodesObserver=function(domApi){DomApi.EffectiveNodesObserver.call(this,domApi)};DomApi.DistributedNodesObserver.prototype=Object.create(DomApi.EffectiveNodesObserver.prototype);Polymer.Base.mixin(DomApi.DistributedNodesObserver.prototype,{_setup:function(){},_cleanup:function(){},_beforeCallListeners:function(){},_getEffectiveNodes:function(){return this.domApi.getDistributedNodes()}});if(Settings.useShadow)Polymer.Base.mixin(DomApi.DistributedNodesObserver.prototype,\n{_setup:function(){if(!this._observer){var root=this.domApi.getOwnerRoot();var host=root&&root.host;if(host){var self=this;this._observer=Polymer.dom(host).observeNodes(function(){self._scheduleNotify()});this._observer._isContentListener=true;if(this._hasAttrSelect())Polymer.dom(host).observer.enableShadowAttributeTracking()}}},_hasAttrSelect:function(){var select=this.node.getAttribute(\"select\");return select&&select.match(/[[.]+/)},_cleanup:function(){var root=this.domApi.getOwnerRoot();var host=\nroot&&root.host;if(host)Polymer.dom(host).unobserveNodes(this._observer);this._observer=null}})})();\n(function(){var DomApi=Polymer.DomApi;var TreeApi=Polymer.TreeApi;Polymer.Base._addFeature({_prepShady:function(){this._useContent=this._useContent||Boolean(this._template)},_setupShady:function(){this.shadyRoot=null;if(!this.__domApi)this.__domApi=null;if(!this.__dom)this.__dom=null;if(!this._ownerShadyRoot)this._ownerShadyRoot=undefined},_poolContent:function(){if(this._useContent)TreeApi.Logical.saveChildNodes(this)},_setupRoot:function(){if(this._useContent){this._createLocalRoot();if(!this.dataHost)upgradeLogicalChildren(TreeApi.Logical.getChildNodes(this))}},\n_createLocalRoot:function(){this.shadyRoot=this.root;this.shadyRoot._distributionClean=false;this.shadyRoot._hasDistributed=false;this.shadyRoot._isShadyRoot=true;this.shadyRoot._dirtyRoots=[];var i$=this.shadyRoot._insertionPoints=!this._notes||this._notes._hasContent?this.shadyRoot.querySelectorAll(\"content\"):[];TreeApi.Logical.saveChildNodes(this.shadyRoot);for(var i=0,c;i<i$.length;i++){c=i$[i];TreeApi.Logical.saveChildNodes(c);TreeApi.Logical.saveChildNodes(c.parentNode)}this.shadyRoot.host=\nthis},distributeContent:function(updateInsertionPoints){if(this.shadyRoot){this.shadyRoot._invalidInsertionPoints=this.shadyRoot._invalidInsertionPoints||updateInsertionPoints;var host=getTopDistributingHost(this);Polymer.dom(this)._lazyDistribute(host)}},_distributeContent:function(){if(this._useContent&&!this.shadyRoot._distributionClean){if(this.shadyRoot._invalidInsertionPoints){Polymer.dom(this)._updateInsertionPoints(this);this.shadyRoot._invalidInsertionPoints=false}this._beginDistribute();\nthis._distributeDirtyRoots();this._finishDistribute()}},_beginDistribute:function(){if(this._useContent&&DomApi.hasInsertionPoint(this.shadyRoot)){this._resetDistribution();this._distributePool(this.shadyRoot,this._collectPool())}},_distributeDirtyRoots:function(){var c$=this.shadyRoot._dirtyRoots;for(var i=0,l=c$.length,c;i<l&&(c=c$[i]);i++)c._distributeContent();this.shadyRoot._dirtyRoots=[]},_finishDistribute:function(){if(this._useContent){this.shadyRoot._distributionClean=true;if(DomApi.hasInsertionPoint(this.shadyRoot)){this._composeTree();\nnotifyContentObservers(this.shadyRoot)}else if(!this.shadyRoot._hasDistributed){TreeApi.Composed.clearChildNodes(this);this.appendChild(this.shadyRoot)}else{var children=this._composeNode(this);this._updateChildNodes(this,children)}if(!this.shadyRoot._hasDistributed)notifyInitialDistribution(this);this.shadyRoot._hasDistributed=true}},elementMatches:function(selector,node){node=node||this;return DomApi.matchesSelector.call(node,selector)},_resetDistribution:function(){var children=TreeApi.Logical.getChildNodes(this);\nfor(var i=0;i<children.length;i++){var child=children[i];if(child._destinationInsertionPoints)child._destinationInsertionPoints=undefined;if(isInsertionPoint(child))clearDistributedDestinationInsertionPoints(child)}var root=this.shadyRoot;var p$=root._insertionPoints;for(var j=0;j<p$.length;j++)p$[j]._distributedNodes=[]},_collectPool:function(){var pool=[];var children=TreeApi.Logical.getChildNodes(this);for(var i=0;i<children.length;i++){var child=children[i];if(isInsertionPoint(child))pool.push.apply(pool,\nchild._distributedNodes);else pool.push(child)}return pool},_distributePool:function(node,pool){var p$=node._insertionPoints;for(var i=0,l=p$.length,p;i<l&&(p=p$[i]);i++){this._distributeInsertionPoint(p,pool);maybeRedistributeParent(p,this)}},_distributeInsertionPoint:function(content,pool){var anyDistributed=false;for(var i=0,l=pool.length,node;i<l;i++){node=pool[i];if(!node)continue;if(this._matchesContentSelect(node,content)){distributeNodeInto(node,content);pool[i]=undefined;anyDistributed=true}}if(!anyDistributed){var children=\nTreeApi.Logical.getChildNodes(content);for(var j=0;j<children.length;j++)distributeNodeInto(children[j],content)}},_composeTree:function(){this._updateChildNodes(this,this._composeNode(this));var p$=this.shadyRoot._insertionPoints;for(var i=0,l=p$.length,p,parent;i<l&&(p=p$[i]);i++){parent=TreeApi.Logical.getParentNode(p);if(!parent._useContent&&parent!==this&&parent!==this.shadyRoot)this._updateChildNodes(parent,this._composeNode(parent))}},_composeNode:function(node){var children=[];var c$=TreeApi.Logical.getChildNodes(node.shadyRoot||\nnode);for(var i=0;i<c$.length;i++){var child=c$[i];if(isInsertionPoint(child)){var distributedNodes=child._distributedNodes;for(var j=0;j<distributedNodes.length;j++){var distributedNode=distributedNodes[j];if(isFinalDestination(child,distributedNode))children.push(distributedNode)}}else children.push(child)}return children},_updateChildNodes:function(container,children){var composed=TreeApi.Composed.getChildNodes(container);var splices=Polymer.ArraySplice.calculateSplices(children,composed);for(var i=\n0,d=0,s;i<splices.length&&(s=splices[i]);i++){for(var j=0,n;j<s.removed.length&&(n=s.removed[j]);j++){if(TreeApi.Composed.getParentNode(n)===container)TreeApi.Composed.removeChild(container,n);composed.splice(s.index+d,1)}d-=s.addedCount}for(var i=0,s,next;i<splices.length&&(s=splices[i]);i++){next=composed[s.index];for(j=s.index,n;j<s.index+s.addedCount;j++){n=children[j];TreeApi.Composed.insertBefore(container,n,next);composed.splice(j,0,n)}}},_matchesContentSelect:function(node,contentElement){var select=\ncontentElement.getAttribute(\"select\");if(!select)return true;select=select.trim();if(!select)return true;if(!(node instanceof Element))return false;var validSelectors=/^(:not\\()?[*.#[a-zA-Z_|]/;if(!validSelectors.test(select))return false;return this.elementMatches(select,node)},_elementAdd:function(){},_elementRemove:function(){}});var domHostDesc={get:function(){var root=Polymer.dom(this).getOwnerRoot();return root&&root.host},configurable:true};Object.defineProperty(Polymer.Base,\"domHost\",domHostDesc);\nPolymer.BaseDescriptors.domHost=domHostDesc;function distributeNodeInto(child,insertionPoint){insertionPoint._distributedNodes.push(child);var points=child._destinationInsertionPoints;if(!points)child._destinationInsertionPoints=[insertionPoint];else points.push(insertionPoint)}function clearDistributedDestinationInsertionPoints(content){var e$=content._distributedNodes;if(e$)for(var i=0;i<e$.length;i++){var d=e$[i]._destinationInsertionPoints;if(d)d.splice(d.indexOf(content)+1,d.length)}}function maybeRedistributeParent(content,\nhost){var parent=TreeApi.Logical.getParentNode(content);if(parent&&parent.shadyRoot&&DomApi.hasInsertionPoint(parent.shadyRoot)&&parent.shadyRoot._distributionClean){parent.shadyRoot._distributionClean=false;host.shadyRoot._dirtyRoots.push(parent)}}function isFinalDestination(insertionPoint,node){var points=node._destinationInsertionPoints;return points&&points[points.length-1]===insertionPoint}function isInsertionPoint(node){return node.localName==\"content\"}function getTopDistributingHost(host){while(host&&\nhostNeedsRedistribution(host))host=host.domHost;return host}function hostNeedsRedistribution(host){var c$=TreeApi.Logical.getChildNodes(host);for(var i=0,c;i<c$.length;i++){c=c$[i];if(c.localName&&c.localName===\"content\")return host.domHost}}function notifyContentObservers(root){for(var i=0,c;i<root._insertionPoints.length;i++){c=root._insertionPoints[i];if(DomApi.hasApi(c))Polymer.dom(c).notifyObserver()}}function notifyInitialDistribution(host){if(DomApi.hasApi(host))Polymer.dom(host).notifyObserver()}\nvar needsUpgrade=window.CustomElements&&!CustomElements.useNative;function upgradeLogicalChildren(children){if(needsUpgrade&&children)for(var i=0;i<children.length;i++)CustomElements.upgrade(children[i])}})();\nif(Polymer.Settings.useShadow)Polymer.Base._addFeature({_poolContent:function(){},_beginDistribute:function(){},distributeContent:function(){},_distributeContent:function(){},_finishDistribute:function(){},_createLocalRoot:function(){this.createShadowRoot();this.shadowRoot.appendChild(this.root);this.root=this.shadowRoot}});\nPolymer.Async={_currVal:0,_lastVal:0,_callbacks:[],_twiddleContent:0,_twiddle:document.createTextNode(\"\"),run:function(callback,waitTime){if(waitTime>0)return~setTimeout(callback,waitTime);else{this._twiddle.textContent=this._twiddleContent++;this._callbacks.push(callback);return this._currVal++}},cancel:function(handle){if(handle<0)clearTimeout(~handle);else{var idx=handle-this._lastVal;if(idx>=0){if(!this._callbacks[idx])throw\"invalid async handle: \"+handle;this._callbacks[idx]=null}}},_atEndOfMicrotask:function(){var len=\nthis._callbacks.length;for(var i=0;i<len;i++){var cb=this._callbacks[i];if(cb)try{cb()}catch(e){i++;this._callbacks.splice(0,i);this._lastVal+=i;this._twiddle.textContent=this._twiddleContent++;throw e;}}this._callbacks.splice(0,len);this._lastVal+=len}};(new window.MutationObserver(function(){Polymer.Async._atEndOfMicrotask()})).observe(Polymer.Async._twiddle,{characterData:true});\nPolymer.Debounce=function(){var Async=Polymer.Async;var Debouncer=function(context){this.context=context;var self=this;this.boundComplete=function(){self.complete()}};Debouncer.prototype={go:function(callback,wait){var h;this.finish=function(){Async.cancel(h)};h=Async.run(this.boundComplete,wait);this.callback=callback},stop:function(){if(this.finish){this.finish();this.finish=null;this.callback=null}},complete:function(){if(this.finish){var callback=this.callback;this.stop();callback.call(this.context)}}};\nfunction debounce(debouncer,callback,wait){if(debouncer)debouncer.stop();else debouncer=new Debouncer(this);debouncer.go(callback,wait);return debouncer}return debounce}();\nPolymer.Base._addFeature({_setupDebouncers:function(){this._debouncers={}},debounce:function(jobName,callback,wait){return this._debouncers[jobName]=Polymer.Debounce.call(this,this._debouncers[jobName],callback,wait)},isDebouncerActive:function(jobName){var debouncer=this._debouncers[jobName];return!!(debouncer&&debouncer.finish)},flushDebouncer:function(jobName){var debouncer=this._debouncers[jobName];if(debouncer)debouncer.complete()},cancelDebouncer:function(jobName){var debouncer=this._debouncers[jobName];\nif(debouncer)debouncer.stop()}});Polymer.DomModule=document.createElement(\"dom-module\");\nPolymer.Base._addFeature({_registerFeatures:function(){this._prepIs();this._prepBehaviors();this._prepConstructor();this._prepTemplate();this._prepShady();this._prepPropertyInfo()},_prepBehavior:function(b){this._addHostAttributes(b.hostAttributes)},_initFeatures:function(){this._registerHost();if(this._template){this._poolContent();this._beginHosting();this._stampTemplate();this._endHosting()}this._marshalHostAttributes();this._setupDebouncers();this._marshalBehaviors();this._tryReady()},_marshalBehavior:function(b){}});(function(){Polymer.nar=[];var disableUpgradeEnabled=Polymer.Settings.disableUpgradeEnabled;Polymer.Annotations={parseAnnotations:function(template,stripWhiteSpace){var list=[];var content=template._content||template.content;this._parseNodeAnnotations(content,list,stripWhiteSpace||template.hasAttribute(\"strip-whitespace\"));return list},_parseNodeAnnotations:function(node,list,stripWhiteSpace){return node.nodeType===Node.TEXT_NODE?this._parseTextNodeAnnotation(node,list):this._parseElementAnnotations(node,\nlist,stripWhiteSpace)},_bindingRegex:function(){var IDENT=\"(?:\"+\"[a-zA-Z_$][\\\\w.:$\\\\-*]*\"+\")\";var NUMBER=\"(?:\"+\"[-+]?[0-9]*\\\\.?[0-9]+(?:[eE][-+]?[0-9]+)?\"+\")\";var SQUOTE_STRING=\"(?:\"+\"'(?:[^'\\\\\\\\]|\\\\\\\\.)*'\"+\")\";var DQUOTE_STRING=\"(?:\"+'\"(?:[^\"\\\\\\\\]|\\\\\\\\.)*\"'+\")\";var STRING=\"(?:\"+SQUOTE_STRING+\"|\"+DQUOTE_STRING+\")\";var ARGUMENT=\"(?:\"+IDENT+\"|\"+NUMBER+\"|\"+STRING+\"\\\\s*\"+\")\";var ARGUMENTS=\"(?:\"+ARGUMENT+\"(?:,\\\\s*\"+ARGUMENT+\")*\"+\")\";var ARGUMENT_LIST=\"(?:\"+\"\\\\(\\\\s*\"+\"(?:\"+ARGUMENTS+\"?\"+\")\"+\"\\\\)\\\\s*\"+\")\";\nvar BINDING=\"(\"+IDENT+\"\\\\s*\"+ARGUMENT_LIST+\"?\"+\")\";var OPEN_BRACKET=\"(\\\\[\\\\[|{{)\"+\"\\\\s*\";var CLOSE_BRACKET=\"(?:]]|}})\";var NEGATE=\"(?:(!)\\\\s*)?\";var EXPRESSION=OPEN_BRACKET+NEGATE+BINDING+CLOSE_BRACKET;return new RegExp(EXPRESSION,\"g\")}(),_parseBindings:function(text){var re=this._bindingRegex;var parts=[];var lastIndex=0;var m;while((m=re.exec(text))!==null){if(m.index>lastIndex)parts.push({literal:text.slice(lastIndex,m.index)});var mode=m[1][0];var negate=Boolean(m[2]);var value=m[3].trim();var customEvent,\nnotifyEvent,colon;if(mode==\"{\"&&(colon=value.indexOf(\"::\"))>0){notifyEvent=value.substring(colon+2);value=value.substring(0,colon);customEvent=true}parts.push({compoundIndex:parts.length,value:value,mode:mode,negate:negate,event:notifyEvent,customEvent:customEvent});lastIndex=re.lastIndex}if(lastIndex&&lastIndex<text.length){var literal=text.substring(lastIndex);if(literal)parts.push({literal:literal})}if(parts.length)return parts},_literalFromParts:function(parts){var s=\"\";for(var i=0;i<parts.length;i++){var literal=\nparts[i].literal;s+=literal||\"\"}return s},_parseTextNodeAnnotation:function(node,list){var parts=this._parseBindings(node.textContent);if(parts){node.textContent=this._literalFromParts(parts)||\" \";var annote={bindings:[{kind:\"text\",name:\"textContent\",parts:parts,isCompound:parts.length!==1}]};list.push(annote);return annote}},_parseElementAnnotations:function(element,list,stripWhiteSpace){var annote={bindings:[],events:[]};if(element.localName===\"content\")list._hasContent=true;this._parseChildNodesAnnotations(element,\nannote,list,stripWhiteSpace);if(element.attributes){this._parseNodeAttributeAnnotations(element,annote,list);if(this.prepElement)this.prepElement(element)}if(annote.bindings.length||annote.events.length||annote.id)list.push(annote);return annote},_parseChildNodesAnnotations:function(root,annote,list,stripWhiteSpace){if(root.firstChild){var node=root.firstChild;var i=0;while(node){var next=node.nextSibling;if(node.localName===\"template\"&&!node.hasAttribute(\"preserve-content\"))this._parseTemplate(node,\ni,list,annote,stripWhiteSpace);if(node.localName==\"slot\")node=this._replaceSlotWithContent(node);if(node.nodeType===Node.TEXT_NODE){var n=next;while(n&&n.nodeType===Node.TEXT_NODE){node.textContent+=n.textContent;next=n.nextSibling;root.removeChild(n);n=next}if(stripWhiteSpace&&!node.textContent.trim()){root.removeChild(node);i--}}if(node.parentNode){var childAnnotation=this._parseNodeAnnotations(node,list,stripWhiteSpace);if(childAnnotation){childAnnotation.parent=annote;childAnnotation.index=i}}node=\nnext;i++}}},_replaceSlotWithContent:function(slot){var content=slot.ownerDocument.createElement(\"content\");while(slot.firstChild)content.appendChild(slot.firstChild);var attrs=slot.attributes;for(var i=0;i<attrs.length;i++){var attr=attrs[i];content.setAttribute(attr.name,attr.value)}var name=slot.getAttribute(\"name\");if(name)content.setAttribute(\"select\",\"[slot='\"+name+\"']\");slot.parentNode.replaceChild(content,slot);return content},_parseTemplate:function(node,index,list,parent,stripWhiteSpace){var content=\ndocument.createDocumentFragment();content._notes=this.parseAnnotations(node,stripWhiteSpace);content.appendChild(node.content);list.push({bindings:Polymer.nar,events:Polymer.nar,templateContent:content,parent:parent,index:index})},_parseNodeAttributeAnnotations:function(node,annotation){var attrs=Array.prototype.slice.call(node.attributes);for(var i=attrs.length-1,a;a=attrs[i];i--){var n=a.name;var v=a.value;var b;if(n.slice(0,3)===\"on-\"){node.removeAttribute(n);annotation.events.push({name:n.slice(3),\nvalue:v})}else if(b=this._parseNodeAttributeAnnotation(node,n,v))annotation.bindings.push(b);else if(n===\"id\")annotation.id=v}},_parseNodeAttributeAnnotation:function(node,name,value){var parts=this._parseBindings(value);if(parts){var origName=name;var kind=\"property\";if(name[name.length-1]==\"$\"){name=name.slice(0,-1);kind=\"attribute\"}var literal=this._literalFromParts(parts);if(literal&&kind==\"attribute\")node.setAttribute(name,literal);if(node.localName===\"input\"&&origName===\"value\")node.setAttribute(origName,\n\"\");if(disableUpgradeEnabled&&origName===\"disable-upgrade$\")node.setAttribute(name,\"\");node.removeAttribute(origName);var propertyName=Polymer.CaseMap.dashToCamelCase(name);if(kind===\"property\")name=propertyName;return{kind:kind,name:name,propertyName:propertyName,parts:parts,literal:literal,isCompound:parts.length!==1}}},findAnnotatedNode:function(root,annote){var parent=annote.parent&&Polymer.Annotations.findAnnotatedNode(root,annote.parent);if(parent)for(var n=parent.firstChild,i=0;n;n=n.nextSibling){if(annote.index===\ni++)return n}else return root}}})();\n(function(){function resolveCss(cssText,ownerDocument){return cssText.replace(CSS_URL_RX,function(m,pre,url,post){return pre+\"'\"+resolve(url.replace(/[\"']/g,\"\"),ownerDocument)+\"'\"+post})}function resolveAttrs(element,ownerDocument){for(var name in URL_ATTRS){var a$=URL_ATTRS[name];for(var i=0,l=a$.length,a,at,v;i<l&&(a=a$[i]);i++)if(name===\"*\"||element.localName===name){at=element.attributes[a];v=at&&at.value;if(v&&v.search(BINDING_RX)<0)at.value=a===\"style\"?resolveCss(v,ownerDocument):resolve(v,\nownerDocument)}}}function resolve(url,ownerDocument){if(url&&ABS_URL.test(url))return url;var resolver=getUrlResolver(ownerDocument);resolver.href=url;return resolver.href||url}var tempDoc;var tempDocBase;function resolveUrl(url,baseUri){if(!tempDoc){tempDoc=document.implementation.createHTMLDocument(\"temp\");tempDocBase=tempDoc.createElement(\"base\");tempDoc.head.appendChild(tempDocBase)}tempDocBase.href=baseUri;return resolve(url,tempDoc)}function getUrlResolver(ownerDocument){return ownerDocument.body.__urlResolver||\n(ownerDocument.body.__urlResolver=ownerDocument.createElement(\"a\"))}var CSS_URL_RX=/(url\\()([^)]*)(\\))/g;var URL_ATTRS={\"*\":[\"href\",\"src\",\"style\",\"url\"],form:[\"action\"]};var ABS_URL=/(^\\/)|(^#)|(^[\\w-\\d]*:)/;var BINDING_RX=/\\{\\{|\\[\\[/;Polymer.ResolveUrl={resolveCss:resolveCss,resolveAttrs:resolveAttrs,resolveUrl:resolveUrl}})();\nPolymer.Path={root:function(path){var dotIndex=path.indexOf(\".\");if(dotIndex===-1)return path;return path.slice(0,dotIndex)},isDeep:function(path){return path.indexOf(\".\")!==-1},isAncestor:function(base,path){return base.indexOf(path+\".\")===0},isDescendant:function(base,path){return path.indexOf(base+\".\")===0},translate:function(base,newBase,path){return newBase+path.slice(base.length)},matches:function(base,wildcard,path){return base===path||this.isAncestor(base,path)||Boolean(wildcard)&&this.isDescendant(base,\npath)}};\nPolymer.Base._addFeature({_prepAnnotations:function(){if(!this._template)this._notes=[];else{var self=this;Polymer.Annotations.prepElement=function(element){self._prepElement(element)};if(this._template._content&&this._template._content._notes)this._notes=this._template._content._notes;else{this._notes=Polymer.Annotations.parseAnnotations(this._template);this._processAnnotations(this._notes)}Polymer.Annotations.prepElement=null}},_processAnnotations:function(notes){for(var i=0;i<notes.length;i++){var note=notes[i];\nfor(var j=0;j<note.bindings.length;j++){var b=note.bindings[j];for(var k=0;k<b.parts.length;k++){var p=b.parts[k];if(!p.literal){var signature=this._parseMethod(p.value);if(signature)p.signature=signature;else p.model=Polymer.Path.root(p.value)}}}if(note.templateContent){this._processAnnotations(note.templateContent._notes);var pp=note.templateContent._parentProps=this._discoverTemplateParentProps(note.templateContent._notes);var bindings=[];for(var prop in pp){var name=\"_parent_\"+prop;bindings.push({index:note.index,\nkind:\"property\",name:name,propertyName:name,parts:[{mode:\"{\",model:prop,value:prop}]})}note.bindings=note.bindings.concat(bindings)}}},_discoverTemplateParentProps:function(notes){var pp={};for(var i=0,n;i<notes.length&&(n=notes[i]);i++){for(var j=0,b$=n.bindings,b;j<b$.length&&(b=b$[j]);j++)for(var k=0,p$=b.parts,p;k<p$.length&&(p=p$[k]);k++)if(p.signature){var args=p.signature.args;for(var kk=0;kk<args.length;kk++){var model=args[kk].model;if(model)pp[model]=true}if(p.signature.dynamicFn)pp[p.signature.method]=\ntrue}else if(p.model)pp[p.model]=true;if(n.templateContent){var tpp=n.templateContent._parentProps;Polymer.Base.mixin(pp,tpp)}}return pp},_prepElement:function(element){Polymer.ResolveUrl.resolveAttrs(element,this._template.ownerDocument)},_findAnnotatedNode:Polymer.Annotations.findAnnotatedNode,_marshalAnnotationReferences:function(){if(this._template){this._marshalIdNodes();this._marshalAnnotatedNodes();this._marshalAnnotatedListeners()}},_configureAnnotationReferences:function(){var notes=this._notes;\nvar nodes=this._nodes;for(var i=0;i<notes.length;i++){var note=notes[i];var node=nodes[i];this._configureTemplateContent(note,node);this._configureCompoundBindings(note,node)}},_configureTemplateContent:function(note,node){if(note.templateContent)node._content=note.templateContent},_configureCompoundBindings:function(note,node){var bindings=note.bindings;for(var i=0;i<bindings.length;i++){var binding=bindings[i];if(binding.isCompound){var storage=node.__compoundStorage__||(node.__compoundStorage__=\n{});var parts=binding.parts;var literals=new Array(parts.length);for(var j=0;j<parts.length;j++)literals[j]=parts[j].literal;var name=binding.name;storage[name]=literals;if(binding.literal&&binding.kind==\"property\")if(node._configValue)node._configValue(name,binding.literal);else node[name]=binding.literal}}},_marshalIdNodes:function(){this.$={};for(var i=0,l=this._notes.length,a;i<l&&(a=this._notes[i]);i++)if(a.id)this.$[a.id]=this._findAnnotatedNode(this.root,a)},_marshalAnnotatedNodes:function(){if(this._notes&&\nthis._notes.length){var r=new Array(this._notes.length);for(var i=0;i<this._notes.length;i++)r[i]=this._findAnnotatedNode(this.root,this._notes[i]);this._nodes=r}},_marshalAnnotatedListeners:function(){for(var i=0,l=this._notes.length,a;i<l&&(a=this._notes[i]);i++)if(a.events&&a.events.length){var node=this._findAnnotatedNode(this.root,a);for(var j=0,e$=a.events,e;j<e$.length&&(e=e$[j]);j++)this.listen(node,e.name,e.value)}}});\nPolymer.Base._addFeature({listeners:{},_listenListeners:function(listeners){var node,name,eventName;for(eventName in listeners){if(eventName.indexOf(\".\")<0){node=this;name=eventName}else{name=eventName.split(\".\");node=this.$[name[0]];name=name[1]}this.listen(node,name,listeners[eventName])}},listen:function(node,eventName,methodName){var handler=this._recallEventHandler(this,eventName,node,methodName);if(!handler)handler=this._createEventHandler(node,eventName,methodName);if(handler._listening)return;\nthis._listen(node,eventName,handler);handler._listening=true},_boundListenerKey:function(eventName,methodName){return eventName+\":\"+methodName},_recordEventHandler:function(host,eventName,target,methodName,handler){var hbl=host.__boundListeners;if(!hbl)hbl=host.__boundListeners=new WeakMap;var bl=hbl.get(target);if(!bl){bl={};if(!Polymer.Settings.isIE||target!=window)hbl.set(target,bl)}var key=this._boundListenerKey(eventName,methodName);bl[key]=handler},_recallEventHandler:function(host,eventName,\ntarget,methodName){var hbl=host.__boundListeners;if(!hbl)return;var bl=hbl.get(target);if(!bl)return;var key=this._boundListenerKey(eventName,methodName);return bl[key]},_createEventHandler:function(node,eventName,methodName){var host=this;var handler=function(e){if(host[methodName])host[methodName](e,e.detail);else host._warn(host._logf(\"_createEventHandler\",\"listener method `\"+methodName+\"` not defined\"))};handler._listening=false;this._recordEventHandler(host,eventName,node,methodName,handler);\nreturn handler},unlisten:function(node,eventName,methodName){var handler=this._recallEventHandler(this,eventName,node,methodName);if(handler){this._unlisten(node,eventName,handler);handler._listening=false}},_listen:function(node,eventName,handler){node.addEventListener(eventName,handler)},_unlisten:function(node,eventName,handler){node.removeEventListener(eventName,handler)}});\n(function(){var wrap=Polymer.DomApi.wrap;var HAS_NATIVE_TA=typeof document.head.style.touchAction===\"string\";var GESTURE_KEY=\"__polymerGestures\";var HANDLED_OBJ=\"__polymerGesturesHandled\";var TOUCH_ACTION=\"__polymerGesturesTouchAction\";var TAP_DISTANCE=25;var TRACK_DISTANCE=5;var TRACK_LENGTH=2;var MOUSE_TIMEOUT=2500;var MOUSE_EVENTS=[\"mousedown\",\"mousemove\",\"mouseup\",\"click\"];var MOUSE_WHICH_TO_BUTTONS=[0,1,4,2];var MOUSE_HAS_BUTTONS=function(){try{return(new MouseEvent(\"test\",{buttons:1})).buttons===\n1}catch(e){return false}}();var SUPPORTS_PASSIVE=false;(function(){try{var opts=Object.defineProperty({},\"passive\",{get:function(){SUPPORTS_PASSIVE=true}});window.addEventListener(\"test\",null,opts);window.removeEventListener(\"test\",null,opts)}catch(e){}})();var IS_TOUCH_ONLY=navigator.userAgent.match(/iP(?:[oa]d|hone)|Android/);var mouseCanceller=function(mouseEvent){var sc=mouseEvent.sourceCapabilities;if(sc&&!sc.firesTouchEvents)return;mouseEvent[HANDLED_OBJ]={skip:true};if(mouseEvent.type===\"click\"){var path=\nPolymer.dom(mouseEvent).path;for(var i=0;i<path.length;i++)if(path[i]===POINTERSTATE.mouse.target)return;mouseEvent.preventDefault();mouseEvent.stopPropagation()}};function setupTeardownMouseCanceller(setup){var events=IS_TOUCH_ONLY?[\"click\"]:MOUSE_EVENTS;for(var i=0,en;i<events.length;i++){en=events[i];if(setup)document.addEventListener(en,mouseCanceller,true);else document.removeEventListener(en,mouseCanceller,true)}}function ignoreMouse(ev){if(!POINTERSTATE.mouse.mouseIgnoreJob)setupTeardownMouseCanceller(true);\nvar unset=function(){setupTeardownMouseCanceller();POINTERSTATE.mouse.target=null;POINTERSTATE.mouse.mouseIgnoreJob=null};POINTERSTATE.mouse.target=Polymer.dom(ev).rootTarget;POINTERSTATE.mouse.mouseIgnoreJob=Polymer.Debounce(POINTERSTATE.mouse.mouseIgnoreJob,unset,MOUSE_TIMEOUT)}function hasLeftMouseButton(ev){var type=ev.type;if(MOUSE_EVENTS.indexOf(type)===-1)return false;if(type===\"mousemove\"){var buttons=ev.buttons===undefined?1:ev.buttons;if(ev instanceof window.MouseEvent&&!MOUSE_HAS_BUTTONS)buttons=\nMOUSE_WHICH_TO_BUTTONS[ev.which]||0;return Boolean(buttons&1)}else{var button=ev.button===undefined?0:ev.button;return button===0}}function isSyntheticClick(ev){if(ev.type===\"click\"){if(ev.detail===0)return true;var t=Gestures.findOriginalTarget(ev);var bcr=t.getBoundingClientRect();var x=ev.pageX,y=ev.pageY;return!(x>=bcr.left&&x<=bcr.right&&(y>=bcr.top&&y<=bcr.bottom))}return false}var POINTERSTATE={mouse:{target:null,mouseIgnoreJob:null},touch:{x:0,y:0,id:-1,scrollDecided:false}};function firstTouchAction(ev){var path=\nPolymer.dom(ev).path;var ta=\"auto\";for(var i=0,n;i<path.length;i++){n=path[i];if(n[TOUCH_ACTION]){ta=n[TOUCH_ACTION];break}}return ta}function trackDocument(stateObj,movefn,upfn){stateObj.movefn=movefn;stateObj.upfn=upfn;document.addEventListener(\"mousemove\",movefn);document.addEventListener(\"mouseup\",upfn)}function untrackDocument(stateObj){document.removeEventListener(\"mousemove\",stateObj.movefn);document.removeEventListener(\"mouseup\",stateObj.upfn);stateObj.movefn=null;stateObj.upfn=null}document.addEventListener(\"touchend\",\nignoreMouse,SUPPORTS_PASSIVE?{passive:true}:false);var Gestures={gestures:{},recognizers:[],deepTargetFind:function(x,y){var node=document.elementFromPoint(x,y);var next=node;while(next&&next.shadowRoot){next=next.shadowRoot.elementFromPoint(x,y);if(next)node=next}return node},findOriginalTarget:function(ev){if(ev.path)return ev.path[0];return ev.target},handleNative:function(ev){var handled;var type=ev.type;var node=wrap(ev.currentTarget);var gobj=node[GESTURE_KEY];if(!gobj)return;var gs=gobj[type];\nif(!gs)return;if(!ev[HANDLED_OBJ]){ev[HANDLED_OBJ]={};if(type.slice(0,5)===\"touch\"){var t=ev.changedTouches[0];if(type===\"touchstart\")if(ev.touches.length===1)POINTERSTATE.touch.id=t.identifier;if(POINTERSTATE.touch.id!==t.identifier)return;if(!HAS_NATIVE_TA)if(type===\"touchstart\"||type===\"touchmove\")Gestures.handleTouchAction(ev)}}handled=ev[HANDLED_OBJ];if(handled.skip)return;var recognizers=Gestures.recognizers;for(var i=0,r;i<recognizers.length;i++){r=recognizers[i];if(gs[r.name]&&!handled[r.name])if(r.flow&&\nr.flow.start.indexOf(ev.type)>-1&&r.reset)r.reset()}for(i=0,r;i<recognizers.length;i++){r=recognizers[i];if(gs[r.name]&&!handled[r.name]){handled[r.name]=true;r[type](ev)}}},handleTouchAction:function(ev){var t=ev.changedTouches[0];var type=ev.type;if(type===\"touchstart\"){POINTERSTATE.touch.x=t.clientX;POINTERSTATE.touch.y=t.clientY;POINTERSTATE.touch.scrollDecided=false}else if(type===\"touchmove\"){if(POINTERSTATE.touch.scrollDecided)return;POINTERSTATE.touch.scrollDecided=true;var ta=firstTouchAction(ev);\nvar prevent=false;var dx=Math.abs(POINTERSTATE.touch.x-t.clientX);var dy=Math.abs(POINTERSTATE.touch.y-t.clientY);if(!ev.cancelable);else if(ta===\"none\")prevent=true;else if(ta===\"pan-x\")prevent=dy>dx;else if(ta===\"pan-y\")prevent=dx>dy;if(prevent)ev.preventDefault();else Gestures.prevent(\"track\")}},add:function(node,evType,handler){node=wrap(node);var recognizer=this.gestures[evType];var deps=recognizer.deps;var name=recognizer.name;var gobj=node[GESTURE_KEY];if(!gobj)node[GESTURE_KEY]=gobj={};for(var i=\n0,dep,gd;i<deps.length;i++){dep=deps[i];if(IS_TOUCH_ONLY&&MOUSE_EVENTS.indexOf(dep)>-1&&dep!==\"click\")continue;gd=gobj[dep];if(!gd)gobj[dep]=gd={_count:0};if(gd._count===0)node.addEventListener(dep,this.handleNative);gd[name]=(gd[name]||0)+1;gd._count=(gd._count||0)+1}node.addEventListener(evType,handler);if(recognizer.touchAction)this.setTouchAction(node,recognizer.touchAction)},remove:function(node,evType,handler){node=wrap(node);var recognizer=this.gestures[evType];var deps=recognizer.deps;var name=\nrecognizer.name;var gobj=node[GESTURE_KEY];if(gobj)for(var i=0,dep,gd;i<deps.length;i++){dep=deps[i];gd=gobj[dep];if(gd&&gd[name]){gd[name]=(gd[name]||1)-1;gd._count=(gd._count||1)-1;if(gd._count===0)node.removeEventListener(dep,this.handleNative)}}node.removeEventListener(evType,handler)},register:function(recog){this.recognizers.push(recog);for(var i=0;i<recog.emits.length;i++)this.gestures[recog.emits[i]]=recog},findRecognizerByEvent:function(evName){for(var i=0,r;i<this.recognizers.length;i++){r=\nthis.recognizers[i];for(var j=0,n;j<r.emits.length;j++){n=r.emits[j];if(n===evName)return r}}return null},setTouchAction:function(node,value){if(HAS_NATIVE_TA)node.style.touchAction=value;node[TOUCH_ACTION]=value},fire:function(target,type,detail){var ev=Polymer.Base.fire(type,detail,{node:target,bubbles:true,cancelable:true});if(ev.defaultPrevented){var preventer=detail.preventer||detail.sourceEvent;if(preventer&&preventer.preventDefault)preventer.preventDefault()}},prevent:function(evName){var recognizer=\nthis.findRecognizerByEvent(evName);if(recognizer.info)recognizer.info.prevent=true},resetMouseCanceller:function(){if(POINTERSTATE.mouse.mouseIgnoreJob)POINTERSTATE.mouse.mouseIgnoreJob.complete()}};Gestures.register({name:\"downup\",deps:[\"mousedown\",\"touchstart\",\"touchend\"],flow:{start:[\"mousedown\",\"touchstart\"],end:[\"mouseup\",\"touchend\"]},emits:[\"down\",\"up\"],info:{movefn:null,upfn:null},reset:function(){untrackDocument(this.info)},mousedown:function(e){if(!hasLeftMouseButton(e))return;var t=Gestures.findOriginalTarget(e);\nvar self=this;var movefn=function movefn(e){if(!hasLeftMouseButton(e)){self.fire(\"up\",t,e);untrackDocument(self.info)}};var upfn=function upfn(e){if(hasLeftMouseButton(e))self.fire(\"up\",t,e);untrackDocument(self.info)};trackDocument(this.info,movefn,upfn);this.fire(\"down\",t,e)},touchstart:function(e){this.fire(\"down\",Gestures.findOriginalTarget(e),e.changedTouches[0],e)},touchend:function(e){this.fire(\"up\",Gestures.findOriginalTarget(e),e.changedTouches[0],e)},fire:function(type,target,event,preventer){Gestures.fire(target,\ntype,{x:event.clientX,y:event.clientY,sourceEvent:event,preventer:preventer,prevent:function(e){return Gestures.prevent(e)}})}});Gestures.register({name:\"track\",touchAction:\"none\",deps:[\"mousedown\",\"touchstart\",\"touchmove\",\"touchend\"],flow:{start:[\"mousedown\",\"touchstart\"],end:[\"mouseup\",\"touchend\"]},emits:[\"track\"],info:{x:0,y:0,state:\"start\",started:false,moves:[],addMove:function(move){if(this.moves.length>TRACK_LENGTH)this.moves.shift();this.moves.push(move)},movefn:null,upfn:null,prevent:false},\nreset:function(){this.info.state=\"start\";this.info.started=false;this.info.moves=[];this.info.x=0;this.info.y=0;this.info.prevent=false;untrackDocument(this.info)},hasMovedEnough:function(x,y){if(this.info.prevent)return false;if(this.info.started)return true;var dx=Math.abs(this.info.x-x);var dy=Math.abs(this.info.y-y);return dx>=TRACK_DISTANCE||dy>=TRACK_DISTANCE},mousedown:function(e){if(!hasLeftMouseButton(e))return;var t=Gestures.findOriginalTarget(e);var self=this;var movefn=function movefn(e){var x=\ne.clientX,y=e.clientY;if(self.hasMovedEnough(x,y)){self.info.state=self.info.started?e.type===\"mouseup\"?\"end\":\"track\":\"start\";if(self.info.state===\"start\")Gestures.prevent(\"tap\");self.info.addMove({x:x,y:y});if(!hasLeftMouseButton(e)){self.info.state=\"end\";untrackDocument(self.info)}self.fire(t,e);self.info.started=true}};var upfn=function upfn(e){if(self.info.started)movefn(e);untrackDocument(self.info)};trackDocument(this.info,movefn,upfn);this.info.x=e.clientX;this.info.y=e.clientY},touchstart:function(e){var ct=\ne.changedTouches[0];this.info.x=ct.clientX;this.info.y=ct.clientY},touchmove:function(e){var t=Gestures.findOriginalTarget(e);var ct=e.changedTouches[0];var x=ct.clientX,y=ct.clientY;if(this.hasMovedEnough(x,y)){if(this.info.state===\"start\")Gestures.prevent(\"tap\");this.info.addMove({x:x,y:y});this.fire(t,ct);this.info.state=\"track\";this.info.started=true}},touchend:function(e){var t=Gestures.findOriginalTarget(e);var ct=e.changedTouches[0];if(this.info.started){this.info.state=\"end\";this.info.addMove({x:ct.clientX,\ny:ct.clientY});this.fire(t,ct,e)}},fire:function(target,touch,preventer){var secondlast=this.info.moves[this.info.moves.length-2];var lastmove=this.info.moves[this.info.moves.length-1];var dx=lastmove.x-this.info.x;var dy=lastmove.y-this.info.y;var ddx,ddy=0;if(secondlast){ddx=lastmove.x-secondlast.x;ddy=lastmove.y-secondlast.y}return Gestures.fire(target,\"track\",{state:this.info.state,x:touch.clientX,y:touch.clientY,dx:dx,dy:dy,ddx:ddx,ddy:ddy,sourceEvent:touch,preventer:preventer,hover:function(){return Gestures.deepTargetFind(touch.clientX,\ntouch.clientY)}})}});Gestures.register({name:\"tap\",deps:[\"mousedown\",\"click\",\"touchstart\",\"touchend\"],flow:{start:[\"mousedown\",\"touchstart\"],end:[\"click\",\"touchend\"]},emits:[\"tap\"],info:{x:NaN,y:NaN,prevent:false},reset:function(){this.info.x=NaN;this.info.y=NaN;this.info.prevent=false},save:function(e){this.info.x=e.clientX;this.info.y=e.clientY},mousedown:function(e){if(hasLeftMouseButton(e))this.save(e)},click:function(e){if(hasLeftMouseButton(e))this.forward(e)},touchstart:function(e){this.save(e.changedTouches[0],\ne)},touchend:function(e){this.forward(e.changedTouches[0],e)},forward:function(e,preventer){var dx=Math.abs(e.clientX-this.info.x);var dy=Math.abs(e.clientY-this.info.y);var t=Gestures.findOriginalTarget(e);if(isNaN(dx)||isNaN(dy)||dx<=TAP_DISTANCE&&dy<=TAP_DISTANCE||isSyntheticClick(e))if(!this.info.prevent)Gestures.fire(t,\"tap\",{x:e.clientX,y:e.clientY,sourceEvent:e,preventer:preventer})}});var DIRECTION_MAP={x:\"pan-x\",y:\"pan-y\",none:\"none\",all:\"auto\"};Polymer.Base._addFeature({_setupGestures:function(){this.__polymerGestures=\nnull},_listen:function(node,eventName,handler){if(Gestures.gestures[eventName])Gestures.add(node,eventName,handler);else node.addEventListener(eventName,handler)},_unlisten:function(node,eventName,handler){if(Gestures.gestures[eventName])Gestures.remove(node,eventName,handler);else node.removeEventListener(eventName,handler)},setScrollDirection:function(direction,node){node=node||this;Gestures.setTouchAction(node,DIRECTION_MAP[direction]||\"auto\")}});Polymer.Gestures=Gestures})();\n(function(){Polymer.Base._addFeature({$$:function(slctr){return Polymer.dom(this.root).querySelector(slctr)},toggleClass:function(name,bool,node){node=node||this;if(arguments.length==1)bool=!node.classList.contains(name);if(bool)Polymer.dom(node).classList.add(name);else Polymer.dom(node).classList.remove(name)},toggleAttribute:function(name,bool,node){node=node||this;if(arguments.length==1)bool=!node.hasAttribute(name);if(bool)Polymer.dom(node).setAttribute(name,\"\");else Polymer.dom(node).removeAttribute(name)},\nclassFollows:function(name,toElement,fromElement){if(fromElement)Polymer.dom(fromElement).classList.remove(name);if(toElement)Polymer.dom(toElement).classList.add(name)},attributeFollows:function(name,toElement,fromElement){if(fromElement)Polymer.dom(fromElement).removeAttribute(name);if(toElement)Polymer.dom(toElement).setAttribute(name,\"\")},getEffectiveChildNodes:function(){return Polymer.dom(this).getEffectiveChildNodes()},getEffectiveChildren:function(){var list=Polymer.dom(this).getEffectiveChildNodes();\nreturn list.filter(function(n){return n.nodeType===Node.ELEMENT_NODE})},getEffectiveTextContent:function(){var cn=this.getEffectiveChildNodes();var tc=[];for(var i=0,c;c=cn[i];i++)if(c.nodeType!==Node.COMMENT_NODE)tc.push(Polymer.dom(c).textContent);return tc.join(\"\")},queryEffectiveChildren:function(slctr){var e$=Polymer.dom(this).queryDistributedElements(slctr);return e$&&e$[0]},queryAllEffectiveChildren:function(slctr){return Polymer.dom(this).queryDistributedElements(slctr)},getContentChildNodes:function(slctr){var content=\nPolymer.dom(this.root).querySelector(slctr||\"content\");return content?Polymer.dom(content).getDistributedNodes():[]},getContentChildren:function(slctr){return this.getContentChildNodes(slctr).filter(function(n){return n.nodeType===Node.ELEMENT_NODE})},fire:function(type,detail,options){options=options||Polymer.nob;var node=options.node||this;detail=detail===null||detail===undefined?{}:detail;var bubbles=options.bubbles===undefined?true:options.bubbles;var cancelable=Boolean(options.cancelable);var useCache=\noptions._useCache;var event=this._getEvent(type,bubbles,cancelable,useCache);event.detail=detail;if(useCache)this.__eventCache[type]=null;node.dispatchEvent(event);if(useCache)this.__eventCache[type]=event;return event},__eventCache:{},_getEvent:function(type,bubbles,cancelable,useCache){var event=useCache&&this.__eventCache[type];if(!event||(event.bubbles!=bubbles||event.cancelable!=cancelable))event=new Event(type,{bubbles:Boolean(bubbles),cancelable:cancelable});return event},async:function(callback,\nwaitTime){var self=this;return Polymer.Async.run(function(){callback.call(self)},waitTime)},cancelAsync:function(handle){Polymer.Async.cancel(handle)},arrayDelete:function(path,item){var index;if(Array.isArray(path)){index=path.indexOf(item);if(index>=0)return path.splice(index,1)}else{var arr=this._get(path);index=arr.indexOf(item);if(index>=0)return this.splice(path,index,1)}},transform:function(transform,node){node=node||this;node.style.webkitTransform=transform;node.style.transform=transform},\ntranslate3d:function(x,y,z,node){node=node||this;this.transform(\"translate3d(\"+x+\",\"+y+\",\"+z+\")\",node)},importHref:function(href,onload,onerror,optAsync){var link=document.createElement(\"link\");link.rel=\"import\";link.href=href;var list=Polymer.Base.importHref.imported=Polymer.Base.importHref.imported||{};var cached=list[link.href];var imprt=cached||link;var self=this;var loadListener=function(e){e.target.__firedLoad=true;e.target.removeEventListener(\"load\",loadListener);e.target.removeEventListener(\"error\",\nerrorListener);return onload.call(self,e)};var errorListener=function(e){e.target.__firedError=true;e.target.removeEventListener(\"load\",loadListener);e.target.removeEventListener(\"error\",errorListener);return onerror.call(self,e)};if(onload)imprt.addEventListener(\"load\",loadListener);if(onerror)imprt.addEventListener(\"error\",errorListener);if(cached){if(cached.__firedLoad)cached.dispatchEvent(new Event(\"load\"));if(cached.__firedError)cached.dispatchEvent(new Event(\"error\"))}else{list[link.href]=link;\noptAsync=Boolean(optAsync);if(optAsync)link.setAttribute(\"async\",\"\");document.head.appendChild(link)}return imprt},create:function(tag,props){var elt=document.createElement(tag);if(props)for(var n in props)elt[n]=props[n];return elt},isLightDescendant:function(node){return this!==node&&this.contains(node)&&Polymer.dom(this).getOwnerRoot()===Polymer.dom(node).getOwnerRoot()},isLocalDescendant:function(node){return this.root===Polymer.dom(node).getOwnerRoot()}});if(!Polymer.Settings.useNativeCustomElements){var importHref=\nPolymer.Base.importHref;Polymer.Base.importHref=function(href,onload,onerror,optAsync){CustomElements.ready=false;var loadFn=function(e){CustomElements.upgradeDocumentTree(document);CustomElements.ready=true;if(onload)return onload.call(this,e)};return importHref.call(this,href,loadFn,onerror,optAsync)}}})();\nPolymer.Bind={prepareModel:function(model){Polymer.Base.mixin(model,this._modelApi)},_modelApi:{_notifyChange:function(source,event,value){value=value===undefined?this[source]:value;event=event||Polymer.CaseMap.camelToDashCase(source)+\"-changed\";this.fire(event,{value:value},{bubbles:false,cancelable:false,_useCache:Polymer.Settings.eventDataCache||!Polymer.Settings.isIE})},_propertySetter:function(property,value,effects,fromAbove){var old=this.__data__[property];if(old!==value&&(old===old||value===\nvalue)){this.__data__[property]=value;if(typeof value==\"object\")this._clearPath(property);if(this._propertyChanged)this._propertyChanged(property,value,old);if(effects)this._effectEffects(property,value,effects,old,fromAbove)}return old},__setProperty:function(property,value,quiet,node){node=node||this;var effects=node._propertyEffects&&node._propertyEffects[property];if(effects)node._propertySetter(property,value,effects,quiet);else if(node[property]!==value)node[property]=value},_effectEffects:function(property,\nvalue,effects,old,fromAbove){for(var i=0,l=effects.length,fx;i<l&&(fx=effects[i]);i++)fx.fn.call(this,property,this[property],fx.effect,old,fromAbove)},_clearPath:function(path){for(var prop in this.__data__)if(Polymer.Path.isDescendant(path,prop))this.__data__[prop]=undefined}},ensurePropertyEffects:function(model,property){if(!model._propertyEffects)model._propertyEffects={};var fx=model._propertyEffects[property];if(!fx)fx=model._propertyEffects[property]=[];return fx},addPropertyEffect:function(model,\nproperty,kind,effect){var fx=this.ensurePropertyEffects(model,property);var propEffect={kind:kind,effect:effect,fn:Polymer.Bind[\"_\"+kind+\"Effect\"]};fx.push(propEffect);return propEffect},createBindings:function(model){var fx$=model._propertyEffects;if(fx$)for(var n in fx$){var fx=fx$[n];fx.sort(this._sortPropertyEffects);this._createAccessors(model,n,fx)}},_sortPropertyEffects:function(){var EFFECT_ORDER={\"compute\":0,\"annotation\":1,\"annotatedComputation\":2,\"reflect\":3,\"notify\":4,\"observer\":5,\"complexObserver\":6,\n\"function\":7};return function(a,b){return EFFECT_ORDER[a.kind]-EFFECT_ORDER[b.kind]}}(),_createAccessors:function(model,property,effects){var defun={get:function(){return this.__data__[property]}};var setter=function(value){this._propertySetter(property,value,effects)};var info=model.getPropertyInfo&&model.getPropertyInfo(property);if(info&&info.readOnly){if(!info.computed)model[\"_set\"+this.upper(property)]=setter}else defun.set=setter;Object.defineProperty(model,property,defun)},upper:function(name){return name[0].toUpperCase()+\nname.substring(1)},_addAnnotatedListener:function(model,index,property,path,event,negated){if(!model._bindListeners)model._bindListeners=[];var fn=this._notedListenerFactory(property,path,Polymer.Path.isDeep(path),negated);var eventName=event||Polymer.CaseMap.camelToDashCase(property)+\"-changed\";model._bindListeners.push({index:index,property:property,path:path,changedFn:fn,event:eventName})},_isEventBogus:function(e,target){return e.path&&e.path[0]!==target},_notedListenerFactory:function(property,\npath,isStructured,negated){return function(target,value,targetPath){if(targetPath){var newPath=Polymer.Path.translate(property,path,targetPath);this._notifyPath(newPath,value)}else{value=target[property];if(negated)value=!value;if(!isStructured)this[path]=value;else if(this.__data__[path]!=value)this.set(path,value)}}},prepareInstance:function(inst){inst.__data__=Object.create(null)},setupBindListeners:function(inst){var b$=inst._bindListeners;for(var i=0,l=b$.length,info;i<l&&(info=b$[i]);i++){var node=\ninst._nodes[info.index];this._addNotifyListener(node,inst,info.event,info.changedFn)}},_addNotifyListener:function(element,context,event,changedFn){element.addEventListener(event,function(e){return context._notifyListener(changedFn,e)})}};\nPolymer.Base.mixin(Polymer.Bind,{_shouldAddListener:function(effect){return effect.name&&effect.kind!=\"attribute\"&&effect.kind!=\"text\"&&!effect.isCompound&&effect.parts[0].mode===\"{\"},_annotationEffect:function(source,value,effect){if(source!=effect.value){value=this._get(effect.value);this.__data__[effect.value]=value}this._applyEffectValue(effect,value)},_reflectEffect:function(source,value,effect){this.reflectPropertyToAttribute(source,effect.attribute,value)},_notifyEffect:function(source,value,\neffect,old,fromAbove){if(!fromAbove)this._notifyChange(source,effect.event,value)},_functionEffect:function(source,value,fn,old,fromAbove){fn.call(this,source,value,old,fromAbove)},_observerEffect:function(source,value,effect,old){var fn=this[effect.method];if(fn)fn.call(this,value,old);else this._warn(this._logf(\"_observerEffect\",\"observer method `\"+effect.method+\"` not defined\"))},_complexObserverEffect:function(source,value,effect){var fn=this[effect.method];if(fn){var args=Polymer.Bind._marshalArgs(this.__data__,\neffect,source,value);if(args)fn.apply(this,args)}else if(effect.dynamicFn);else this._warn(this._logf(\"_complexObserverEffect\",\"observer method `\"+effect.method+\"` not defined\"))},_computeEffect:function(source,value,effect){var fn=this[effect.method];if(fn){var args=Polymer.Bind._marshalArgs(this.__data__,effect,source,value);if(args){var computedvalue=fn.apply(this,args);this.__setProperty(effect.name,computedvalue)}}else if(effect.dynamicFn);else this._warn(this._logf(\"_computeEffect\",\"compute method `\"+\neffect.method+\"` not defined\"))},_annotatedComputationEffect:function(source,value,effect){var computedHost=this._rootDataHost||this;var fn=computedHost[effect.method];if(fn){var args=Polymer.Bind._marshalArgs(this.__data__,effect,source,value);if(args){var computedvalue=fn.apply(computedHost,args);this._applyEffectValue(effect,computedvalue)}}else if(effect.dynamicFn);else computedHost._warn(computedHost._logf(\"_annotatedComputationEffect\",\"compute method `\"+effect.method+\"` not defined\"))},_marshalArgs:function(model,\neffect,path,value){var values=[];var args=effect.args;var bailoutEarly=args.length>1||effect.dynamicFn;for(var i=0,l=args.length;i<l;i++){var arg=args[i];var name=arg.name;var v;if(arg.literal)v=arg.value;else if(path===name)v=value;else{v=model[name];if(v===undefined&&arg.structured)v=Polymer.Base._get(name,model)}if(bailoutEarly&&v===undefined)return;if(arg.wildcard){var matches=Polymer.Path.isAncestor(path,name);values[i]={path:matches?path:name,value:matches?value:v,base:v}}else values[i]=v}return values}});\nPolymer.Base._addFeature({_addPropertyEffect:function(property,kind,effect){var prop=Polymer.Bind.addPropertyEffect(this,property,kind,effect);prop.pathFn=this[\"_\"+prop.kind+\"PathEffect\"]},_prepEffects:function(){Polymer.Bind.prepareModel(this);this._addAnnotationEffects(this._notes)},_prepBindings:function(){Polymer.Bind.createBindings(this)},_addPropertyEffects:function(properties){if(properties)for(var p in properties){var prop=properties[p];if(prop.observer)this._addObserverEffect(p,prop.observer);\nif(prop.computed){prop.readOnly=true;this._addComputedEffect(p,prop.computed)}if(prop.notify)this._addPropertyEffect(p,\"notify\",{event:Polymer.CaseMap.camelToDashCase(p)+\"-changed\"});if(prop.reflectToAttribute){var attr=Polymer.CaseMap.camelToDashCase(p);if(attr[0]===\"-\")this._warn(this._logf(\"_addPropertyEffects\",\"Property \"+p+\" cannot be reflected to attribute \"+attr+' because \"-\" is not a valid starting attribute name. Use a lowercase first letter for the property instead.'));else this._addPropertyEffect(p,\n\"reflect\",{attribute:attr})}if(prop.readOnly)Polymer.Bind.ensurePropertyEffects(this,p)}},_addComputedEffect:function(name,expression){var sig=this._parseMethod(expression);var dynamicFn=sig.dynamicFn;for(var i=0,arg;i<sig.args.length&&(arg=sig.args[i]);i++)this._addPropertyEffect(arg.model,\"compute\",{method:sig.method,args:sig.args,trigger:arg,name:name,dynamicFn:dynamicFn});if(dynamicFn)this._addPropertyEffect(sig.method,\"compute\",{method:sig.method,args:sig.args,trigger:null,name:name,dynamicFn:dynamicFn})},\n_addObserverEffect:function(property,observer){this._addPropertyEffect(property,\"observer\",{method:observer,property:property})},_addComplexObserverEffects:function(observers){if(observers)for(var i=0,o;i<observers.length&&(o=observers[i]);i++)this._addComplexObserverEffect(o)},_addComplexObserverEffect:function(observer){var sig=this._parseMethod(observer);if(!sig)throw new Error(\"Malformed observer expression '\"+observer+\"'\");var dynamicFn=sig.dynamicFn;for(var i=0,arg;i<sig.args.length&&(arg=sig.args[i]);i++)this._addPropertyEffect(arg.model,\n\"complexObserver\",{method:sig.method,args:sig.args,trigger:arg,dynamicFn:dynamicFn});if(dynamicFn)this._addPropertyEffect(sig.method,\"complexObserver\",{method:sig.method,args:sig.args,trigger:null,dynamicFn:dynamicFn})},_addAnnotationEffects:function(notes){for(var i=0,note;i<notes.length&&(note=notes[i]);i++){var b$=note.bindings;for(var j=0,binding;j<b$.length&&(binding=b$[j]);j++)this._addAnnotationEffect(binding,i)}},_addAnnotationEffect:function(note,index){if(Polymer.Bind._shouldAddListener(note))Polymer.Bind._addAnnotatedListener(this,\nindex,note.name,note.parts[0].value,note.parts[0].event,note.parts[0].negate);for(var i=0;i<note.parts.length;i++){var part=note.parts[i];if(part.signature)this._addAnnotatedComputationEffect(note,part,index);else if(!part.literal)if(note.kind===\"attribute\"&&note.name[0]===\"-\")this._warn(this._logf(\"_addAnnotationEffect\",\"Cannot set attribute \"+note.name+' because \"-\" is not a valid attribute starting character'));else this._addPropertyEffect(part.model,\"annotation\",{kind:note.kind,index:index,name:note.name,\npropertyName:note.propertyName,value:part.value,isCompound:note.isCompound,compoundIndex:part.compoundIndex,event:part.event,customEvent:part.customEvent,negate:part.negate})}},_addAnnotatedComputationEffect:function(note,part,index){var sig=part.signature;if(sig[\"static\"])this.__addAnnotatedComputationEffect(\"__static__\",index,note,part,null);else{for(var i=0,arg;i<sig.args.length&&(arg=sig.args[i]);i++)if(!arg.literal)this.__addAnnotatedComputationEffect(arg.model,index,note,part,arg);if(sig.dynamicFn)this.__addAnnotatedComputationEffect(sig.method,\nindex,note,part,null)}},__addAnnotatedComputationEffect:function(property,index,note,part,trigger){this._addPropertyEffect(property,\"annotatedComputation\",{index:index,isCompound:note.isCompound,compoundIndex:part.compoundIndex,kind:note.kind,name:note.name,negate:part.negate,method:part.signature.method,args:part.signature.args,trigger:trigger,dynamicFn:part.signature.dynamicFn})},_parseMethod:function(expression){var m=expression.match(/([^\\s]+?)\\(([\\s\\S]*)\\)/);if(m){var sig={method:m[1],\"static\":true};\nif(this.getPropertyInfo(sig.method)!==Polymer.nob){sig[\"static\"]=false;sig.dynamicFn=true}if(m[2].trim()){var args=m[2].replace(/\\\\,/g,\"&comma;\").split(\",\");return this._parseArgs(args,sig)}else{sig.args=Polymer.nar;return sig}}},_parseArgs:function(argList,sig){sig.args=argList.map(function(rawArg){var arg=this._parseArg(rawArg);if(!arg.literal)sig[\"static\"]=false;return arg},this);return sig},_parseArg:function(rawArg){var arg=rawArg.trim().replace(/&comma;/g,\",\").replace(/\\\\(.)/g,\"$1\");var a={name:arg};\nvar fc=arg[0];if(fc===\"-\")fc=arg[1];if(fc>=\"0\"&&fc<=\"9\")fc=\"#\";switch(fc){case \"'\":case '\"':a.value=arg.slice(1,-1);a.literal=true;break;case \"#\":a.value=Number(arg);a.literal=true;break}if(!a.literal){a.model=Polymer.Path.root(arg);a.structured=Polymer.Path.isDeep(arg);if(a.structured){a.wildcard=arg.slice(-2)==\".*\";if(a.wildcard)a.name=arg.slice(0,-2)}}return a},_marshalInstanceEffects:function(){Polymer.Bind.prepareInstance(this);if(this._bindListeners)Polymer.Bind.setupBindListeners(this)},_applyEffectValue:function(info,\nvalue){var node=this._nodes[info.index];var property=info.name;value=this._computeFinalAnnotationValue(node,property,value,info);if(info.kind==\"attribute\")this.serializeValueToAttribute(value,property,node);else{var pinfo=node._propertyInfo&&node._propertyInfo[property];if(pinfo&&pinfo.readOnly)return;this.__setProperty(property,value,Polymer.Settings.suppressBindingNotifications,node)}},_computeFinalAnnotationValue:function(node,property,value,info){if(info.negate)value=!value;if(info.isCompound){var storage=\nnode.__compoundStorage__[property];storage[info.compoundIndex]=value;value=storage.join(\"\")}if(info.kind!==\"attribute\"){if(property===\"className\")value=this._scopeElementClass(node,value);if(property===\"textContent\"||node.localName==\"input\"&&property==\"value\")value=value==undefined?\"\":value}return value},_executeStaticEffects:function(){if(this._propertyEffects&&this._propertyEffects.__static__)this._effectEffects(\"__static__\",null,this._propertyEffects.__static__)}});\n(function(){var usePolyfillProto=Polymer.Settings.usePolyfillProto;Polymer.Base._addFeature({_setupConfigure:function(initialConfig){this._config={};this._handlers=[];this._aboveConfig=null;if(initialConfig)for(var i in initialConfig)if(initialConfig[i]!==undefined)this._config[i]=initialConfig[i]},_marshalAttributes:function(){this._takeAttributesToModel(this._config)},_attributeChangedImpl:function(name){var model=this._clientsReadied?this:this._config;this._setAttributeToProperty(model,name)},\n_configValue:function(name,value){var info=this._propertyInfo[name];if(!info||!info.readOnly)this._config[name]=value},_beforeClientsReady:function(){this._configure()},_configure:function(){this._configureAnnotationReferences();this._configureInstanceProperties();this._aboveConfig=this.mixin({},this._config);var config={};for(var i=0;i<this.behaviors.length;i++)this._configureProperties(this.behaviors[i].properties,config);this._configureProperties(this.properties,config);this.mixin(config,this._aboveConfig);\nthis._config=config;if(this._clients&&this._clients.length)this._distributeConfig(this._config)},_configureInstanceProperties:function(){for(var i in this._propertyEffects)if(!usePolyfillProto&&this.hasOwnProperty(i)){this._configValue(i,this[i]);delete this[i]}},_configureProperties:function(properties,config){for(var i in properties){var c=properties[i];if(c.value!==undefined){var value=c.value;if(typeof value==\"function\")value=value.call(this,this._config);config[i]=value}}},_distributeConfig:function(config){var fx$=\nthis._propertyEffects;if(fx$)for(var p in config){var fx=fx$[p];if(fx)for(var i=0,l=fx.length,x;i<l&&(x=fx[i]);i++)if(x.kind===\"annotation\"){var node=this._nodes[x.effect.index];var name=x.effect.propertyName;var isAttr=x.effect.kind==\"attribute\";var hasEffect=node._propertyEffects&&node._propertyEffects[name];if(node._configValue&&(hasEffect||!isAttr)){var value=p===x.effect.value?config[p]:this._get(x.effect.value,config);value=this._computeFinalAnnotationValue(node,name,value,x.effect);if(isAttr)value=\nnode.deserialize(this.serialize(value),node._propertyInfo[name].type);node._configValue(name,value)}}}},_afterClientsReady:function(){this._executeStaticEffects();this._applyConfig(this._config,this._aboveConfig);this._flushHandlers()},_applyConfig:function(config,aboveConfig){for(var n in config)if(this[n]===undefined)this.__setProperty(n,config[n],n in aboveConfig)},_notifyListener:function(fn,e){if(!Polymer.Bind._isEventBogus(e,e.target)){var value,path;if(e.detail){value=e.detail.value;path=e.detail.path}if(!this._clientsReadied)this._queueHandler([fn,\ne.target,value,path]);else return fn.call(this,e.target,value,path)}},_queueHandler:function(args){this._handlers.push(args)},_flushHandlers:function(){var h$=this._handlers;for(var i=0,l=h$.length,h;i<l&&(h=h$[i]);i++)h[0].call(this,h[1],h[2],h[3]);this._handlers=[]}})})();\n(function(){var Path=Polymer.Path;Polymer.Base._addFeature({notifyPath:function(path,value,fromAbove){var info={};var v=this._get(path,this,info);if(arguments.length===1)value=v;if(info.path)this._notifyPath(info.path,value,fromAbove)},_notifyPath:function(path,value,fromAbove){var old=this._propertySetter(path,value);if(old!==value&&(old===old||value===value)){this._pathEffector(path,value);if(!fromAbove)this._notifyPathUp(path,value);return true}},_getPathParts:function(path){if(Array.isArray(path)){var parts=\n[];for(var i=0;i<path.length;i++){var args=path[i].toString().split(\".\");for(var j=0;j<args.length;j++)parts.push(args[j])}return parts}else return path.toString().split(\".\")},set:function(path,value,root){var prop=root||this;var parts=this._getPathParts(path);var array;var last=parts[parts.length-1];if(parts.length>1){for(var i=0;i<parts.length-1;i++){var part=parts[i];if(array&&part[0]==\"#\")prop=Polymer.Collection.get(array).getItem(part);else{prop=prop[part];if(array&&parseInt(part,10)==part)parts[i]=\nPolymer.Collection.get(array).getKey(prop)}if(!prop)return;array=Array.isArray(prop)?prop:null}if(array){var coll=Polymer.Collection.get(array);var old,key;if(last[0]==\"#\"){key=last;old=coll.getItem(key);last=array.indexOf(old);coll.setItem(key,value)}else if(parseInt(last,10)==last){old=prop[last];key=coll.getKey(old);parts[i]=key;coll.setItem(key,value)}}prop[last]=value;if(!root)this._notifyPath(parts.join(\".\"),value)}else prop[path]=value},get:function(path,root){return this._get(path,root)},\n_get:function(path,root,info){var prop=root||this;var parts=this._getPathParts(path);var array;for(var i=0;i<parts.length;i++){if(!prop)return;var part=parts[i];if(array&&part[0]==\"#\")prop=Polymer.Collection.get(array).getItem(part);else{prop=prop[part];if(info&&array&&parseInt(part,10)==part)parts[i]=Polymer.Collection.get(array).getKey(prop)}array=Array.isArray(prop)?prop:null}if(info)info.path=parts.join(\".\");return prop},_pathEffector:function(path,value){var model=Path.root(path);var fx$=this._propertyEffects&&\nthis._propertyEffects[model];if(fx$)for(var i=0,fx;i<fx$.length&&(fx=fx$[i]);i++){var fxFn=fx.pathFn;if(fxFn)fxFn.call(this,path,value,fx.effect)}if(this._boundPaths)this._notifyBoundPaths(path,value)},_annotationPathEffect:function(path,value,effect){if(Path.matches(effect.value,false,path))Polymer.Bind._annotationEffect.call(this,path,value,effect);else if(!effect.negate&&Path.isDescendant(effect.value,path)){var node=this._nodes[effect.index];if(node&&node._notifyPath){var newPath=Path.translate(effect.value,\neffect.name,path);node._notifyPath(newPath,value,true)}}},_complexObserverPathEffect:function(path,value,effect){if(Path.matches(effect.trigger.name,effect.trigger.wildcard,path))Polymer.Bind._complexObserverEffect.call(this,path,value,effect)},_computePathEffect:function(path,value,effect){if(Path.matches(effect.trigger.name,effect.trigger.wildcard,path))Polymer.Bind._computeEffect.call(this,path,value,effect)},_annotatedComputationPathEffect:function(path,value,effect){if(Path.matches(effect.trigger.name,\neffect.trigger.wildcard,path))Polymer.Bind._annotatedComputationEffect.call(this,path,value,effect)},linkPaths:function(to,from){this._boundPaths=this._boundPaths||{};if(from)this._boundPaths[to]=from;else this.unlinkPaths(to)},unlinkPaths:function(path){if(this._boundPaths)delete this._boundPaths[path]},_notifyBoundPaths:function(path,value){for(var a in this._boundPaths){var b=this._boundPaths[a];if(Path.isDescendant(a,path))this._notifyPath(Path.translate(a,b,path),value);else if(Path.isDescendant(b,\npath))this._notifyPath(Path.translate(b,a,path),value)}},_notifyPathUp:function(path,value){var rootName=Path.root(path);var dashCaseName=Polymer.CaseMap.camelToDashCase(rootName);var eventName=dashCaseName+this._EVENT_CHANGED;this.fire(eventName,{path:path,value:value},{bubbles:false,_useCache:Polymer.Settings.eventDataCache||!Polymer.Settings.isIE})},_EVENT_CHANGED:\"-changed\",notifySplices:function(path,splices){var info={};var array=this._get(path,this,info);this._notifySplices(array,info.path,\nsplices)},_notifySplices:function(array,path,splices){var change={keySplices:Polymer.Collection.applySplices(array,splices),indexSplices:splices};var splicesPath=path+\".splices\";this._notifyPath(splicesPath,change);this._notifyPath(path+\".length\",array.length);this.__data__[splicesPath]={keySplices:null,indexSplices:null}},_notifySplice:function(array,path,index,added,removed){this._notifySplices(array,path,[{index:index,addedCount:added,removed:removed,object:array,type:\"splice\"}])},push:function(path){var info=\n{};var array=this._get(path,this,info);var args=Array.prototype.slice.call(arguments,1);var len=array.length;var ret=array.push.apply(array,args);if(args.length)this._notifySplice(array,info.path,len,args.length,[]);return ret},pop:function(path){var info={};var array=this._get(path,this,info);var hadLength=Boolean(array.length);var args=Array.prototype.slice.call(arguments,1);var ret=array.pop.apply(array,args);if(hadLength)this._notifySplice(array,info.path,array.length,0,[ret]);return ret},splice:function(path,\nstart){var info={};var array=this._get(path,this,info);if(start<0)start=array.length-Math.floor(-start);else start=Math.floor(start);if(!start)start=0;var args=Array.prototype.slice.call(arguments,1);var ret=array.splice.apply(array,args);var addedCount=Math.max(args.length-2,0);if(addedCount||ret.length)this._notifySplice(array,info.path,start,addedCount,ret);return ret},shift:function(path){var info={};var array=this._get(path,this,info);var hadLength=Boolean(array.length);var args=Array.prototype.slice.call(arguments,\n1);var ret=array.shift.apply(array,args);if(hadLength)this._notifySplice(array,info.path,0,0,[ret]);return ret},unshift:function(path){var info={};var array=this._get(path,this,info);var args=Array.prototype.slice.call(arguments,1);var ret=array.unshift.apply(array,args);if(args.length)this._notifySplice(array,info.path,0,args.length,[]);return ret},prepareModelNotifyPath:function(model){this.mixin(model,{fire:Polymer.Base.fire,_getEvent:Polymer.Base._getEvent,__eventCache:Polymer.Base.__eventCache,\nnotifyPath:Polymer.Base.notifyPath,_get:Polymer.Base._get,_EVENT_CHANGED:Polymer.Base._EVENT_CHANGED,_notifyPath:Polymer.Base._notifyPath,_notifyPathUp:Polymer.Base._notifyPathUp,_pathEffector:Polymer.Base._pathEffector,_annotationPathEffect:Polymer.Base._annotationPathEffect,_complexObserverPathEffect:Polymer.Base._complexObserverPathEffect,_annotatedComputationPathEffect:Polymer.Base._annotatedComputationPathEffect,_computePathEffect:Polymer.Base._computePathEffect,_notifyBoundPaths:Polymer.Base._notifyBoundPaths,\n_getPathParts:Polymer.Base._getPathParts})}})})();Polymer.Base._addFeature({resolveUrl:function(url){var module=Polymer.DomModule[\"import\"](this.is);var root=\"\";if(module){var assetPath=module.getAttribute(\"assetpath\")||\"\";root=Polymer.ResolveUrl.resolveUrl(assetPath,module.ownerDocument.baseURI)}return Polymer.ResolveUrl.resolveUrl(url,root)}});\nPolymer.CssParse=function(){return{parse:function(text){text=this._clean(text);return this._parseCss(this._lex(text),text)},_clean:function(cssText){return cssText.replace(this._rx.comments,\"\").replace(this._rx.port,\"\")},_lex:function(text){var root={start:0,end:text.length};var n=root;for(var i=0,l=text.length;i<l;i++)switch(text[i]){case this.OPEN_BRACE:if(!n.rules)n.rules=[];var p=n;var previous=p.rules[p.rules.length-1];n={start:i+1,parent:p,previous:previous};p.rules.push(n);break;case this.CLOSE_BRACE:n.end=\ni+1;n=n.parent||root;break}return root},_parseCss:function(node,text){var t=text.substring(node.start,node.end-1);node.parsedCssText=node.cssText=t.trim();if(node.parent){var ss=node.previous?node.previous.end:node.parent.start;t=text.substring(ss,node.start-1);t=this._expandUnicodeEscapes(t);t=t.replace(this._rx.multipleSpaces,\" \");t=t.substring(t.lastIndexOf(\";\")+1);var s=node.parsedSelector=node.selector=t.trim();node.atRule=s.indexOf(this.AT_START)===0;if(node.atRule)if(s.indexOf(this.MEDIA_START)===\n0)node.type=this.types.MEDIA_RULE;else{if(s.match(this._rx.keyframesRule)){node.type=this.types.KEYFRAMES_RULE;node.keyframesName=node.selector.split(this._rx.multipleSpaces).pop()}}else if(s.indexOf(this.VAR_START)===0)node.type=this.types.MIXIN_RULE;else node.type=this.types.STYLE_RULE}var r$=node.rules;if(r$)for(var i=0,l=r$.length,r;i<l&&(r=r$[i]);i++)this._parseCss(r,text);return node},_expandUnicodeEscapes:function(s){return s.replace(/\\\\([0-9a-f]{1,6})\\s/gi,function(){var code=arguments[1],\nrepeat=6-code.length;while(repeat--)code=\"0\"+code;return\"\\\\\"+code})},stringify:function(node,preserveProperties,text){text=text||\"\";var cssText=\"\";if(node.cssText||node.rules){var r$=node.rules;if(r$&&!this._hasMixinRules(r$))for(var i=0,l=r$.length,r;i<l&&(r=r$[i]);i++)cssText=this.stringify(r,preserveProperties,cssText);else{cssText=preserveProperties?node.cssText:this.removeCustomProps(node.cssText);cssText=cssText.trim();if(cssText)cssText=\"  \"+cssText+\"\\n\"}}if(cssText){if(node.selector)text+=\nnode.selector+\" \"+this.OPEN_BRACE+\"\\n\";text+=cssText;if(node.selector)text+=this.CLOSE_BRACE+\"\\n\\n\"}return text},_hasMixinRules:function(rules){return rules[0].selector.indexOf(this.VAR_START)===0},removeCustomProps:function(cssText){cssText=this.removeCustomPropAssignment(cssText);return this.removeCustomPropApply(cssText)},removeCustomPropAssignment:function(cssText){return cssText.replace(this._rx.customProp,\"\").replace(this._rx.mixinProp,\"\")},removeCustomPropApply:function(cssText){return cssText.replace(this._rx.mixinApply,\n\"\").replace(this._rx.varApply,\"\")},types:{STYLE_RULE:1,KEYFRAMES_RULE:7,MEDIA_RULE:4,MIXIN_RULE:1E3},OPEN_BRACE:\"{\",CLOSE_BRACE:\"}\",_rx:{comments:/\\/\\*[^*]*\\*+([^\\/*][^*]*\\*+)*\\//gim,port:/@import[^;]*;/gim,customProp:/(?:^[^;\\-\\s}]+)?--[^;{}]*?:[^{};]*?(?:[;\\n]|$)/gim,mixinProp:/(?:^[^;\\-\\s}]+)?--[^;{}]*?:[^{};]*?{[^}]*?}(?:[;\\n]|$)?/gim,mixinApply:/@apply\\s*\\(?[^);]*\\)?\\s*(?:[;\\n]|$)?/gim,varApply:/[^;:]*?:[^;]*?var\\([^;]*\\)(?:[;\\n]|$)?/gim,keyframesRule:/^@[^\\s]*keyframes/,multipleSpaces:/\\s+/g},\nVAR_START:\"--\",MEDIA_START:\"@media\",AT_START:\"@\"}}();\nPolymer.StyleUtil=function(){var settings=Polymer.Settings;return{NATIVE_VARIABLES:Polymer.Settings.useNativeCSSProperties,MODULE_STYLES_SELECTOR:\"style, link[rel=import][type~=css], template\",INCLUDE_ATTR:\"include\",toCssText:function(rules,callback){if(typeof rules===\"string\")rules=this.parser.parse(rules);if(callback)this.forEachRule(rules,callback);return this.parser.stringify(rules,this.NATIVE_VARIABLES)},forRulesInStyles:function(styles,styleRuleCallback,keyframesRuleCallback){if(styles)for(var i=\n0,l=styles.length,s;i<l&&(s=styles[i]);i++)this.forEachRuleInStyle(s,styleRuleCallback,keyframesRuleCallback)},forActiveRulesInStyles:function(styles,styleRuleCallback,keyframesRuleCallback){if(styles)for(var i=0,l=styles.length,s;i<l&&(s=styles[i]);i++)this.forEachRuleInStyle(s,styleRuleCallback,keyframesRuleCallback,true)},rulesForStyle:function(style){if(!style.__cssRules&&style.textContent)style.__cssRules=this.parser.parse(style.textContent);return style.__cssRules},isKeyframesSelector:function(rule){return rule.parent&&\nrule.parent.type===this.ruleTypes.KEYFRAMES_RULE},forEachRuleInStyle:function(style,styleRuleCallback,keyframesRuleCallback,onlyActiveRules){var rules=this.rulesForStyle(style);var styleCallback,keyframeCallback;if(styleRuleCallback)styleCallback=function(rule){styleRuleCallback(rule,style)};if(keyframesRuleCallback)keyframeCallback=function(rule){keyframesRuleCallback(rule,style)};this.forEachRule(rules,styleCallback,keyframeCallback,onlyActiveRules)},forEachRule:function(node,styleRuleCallback,\nkeyframesRuleCallback,onlyActiveRules){if(!node)return;var skipRules=false;if(onlyActiveRules)if(node.type===this.ruleTypes.MEDIA_RULE){var matchMedia=node.selector.match(this.rx.MEDIA_MATCH);if(matchMedia)if(!window.matchMedia(matchMedia[1]).matches)skipRules=true}if(node.type===this.ruleTypes.STYLE_RULE)styleRuleCallback(node);else if(keyframesRuleCallback&&node.type===this.ruleTypes.KEYFRAMES_RULE)keyframesRuleCallback(node);else if(node.type===this.ruleTypes.MIXIN_RULE)skipRules=true;var r$=node.rules;\nif(r$&&!skipRules)for(var i=0,l=r$.length,r;i<l&&(r=r$[i]);i++)this.forEachRule(r,styleRuleCallback,keyframesRuleCallback,onlyActiveRules)},applyCss:function(cssText,moniker,target,contextNode){var style=this.createScopeStyle(cssText,moniker);return this.applyStyle(style,target,contextNode)},applyStyle:function(style,target,contextNode){target=target||document.head;var after=contextNode&&contextNode.nextSibling||target.firstChild;this.__lastHeadApplyNode=style;return target.insertBefore(style,after)},\ncreateScopeStyle:function(cssText,moniker){var style=document.createElement(\"style\");if(moniker)style.setAttribute(\"scope\",moniker);style.textContent=cssText;return style},__lastHeadApplyNode:null,applyStylePlaceHolder:function(moniker){var placeHolder=document.createComment(\" Shady DOM styles for \"+moniker+\" \");var after=this.__lastHeadApplyNode?this.__lastHeadApplyNode.nextSibling:null;var scope=document.head;scope.insertBefore(placeHolder,after||scope.firstChild);this.__lastHeadApplyNode=placeHolder;\nreturn placeHolder},cssFromModules:function(moduleIds,warnIfNotFound){var modules=moduleIds.trim().split(\" \");var cssText=\"\";for(var i=0;i<modules.length;i++)cssText+=this.cssFromModule(modules[i],warnIfNotFound);return cssText},cssFromModule:function(moduleId,warnIfNotFound){var m=Polymer.DomModule[\"import\"](moduleId);if(m&&!m._cssText)m._cssText=this.cssFromElement(m);if(!m&&warnIfNotFound)console.warn(\"Could not find style data in module named\",moduleId);return m&&m._cssText||\"\"},cssFromElement:function(element){var cssText=\n\"\";var content=element.content||element;var e$=Polymer.TreeApi.arrayCopy(content.querySelectorAll(this.MODULE_STYLES_SELECTOR));for(var i=0,e;i<e$.length;i++){e=e$[i];if(e.localName===\"template\"){if(!e.hasAttribute(\"preserve-content\"))cssText+=this.cssFromElement(e)}else if(e.localName===\"style\"){var include=e.getAttribute(this.INCLUDE_ATTR);if(include)cssText+=this.cssFromModules(include,true);e=e.__appliedElement||e;e.parentNode.removeChild(e);cssText+=this.resolveCss(e.textContent,element.ownerDocument)}else if(e[\"import\"]&&\ne[\"import\"].body)cssText+=this.resolveCss(e[\"import\"].body.textContent,e[\"import\"])}return cssText},isTargetedBuild:function(buildType){return settings.useNativeShadow?buildType===\"shadow\":buildType===\"shady\"},cssBuildTypeForModule:function(module){var dm=Polymer.DomModule[\"import\"](module);if(dm)return this.getCssBuildType(dm)},getCssBuildType:function(element){return element.getAttribute(\"css-build\")},_findMatchingParen:function(text,start){var level=0;for(var i=start,l=text.length;i<l;i++)switch(text[i]){case \"(\":level++;\nbreak;case \")\":if(--level===0)return i;break}return-1},processVariableAndFallback:function(str,callback){var start=str.indexOf(\"var(\");if(start===-1)return callback(str,\"\",\"\",\"\");var end=this._findMatchingParen(str,start+3);var inner=str.substring(start+4,end);var prefix=str.substring(0,start);var suffix=this.processVariableAndFallback(str.substring(end+1),callback);var comma=inner.indexOf(\",\");if(comma===-1)return callback(prefix,inner.trim(),\"\",suffix);var value=inner.substring(0,comma).trim();\nvar fallback=inner.substring(comma+1).trim();return callback(prefix,value,fallback,suffix)},rx:{VAR_ASSIGN:/(?:^|[;\\s{]\\s*)(--[\\w-]*?)\\s*:\\s*(?:([^;{]*)|{([^}]*)})(?:(?=[;\\s}])|$)/gi,MIXIN_MATCH:/(?:^|\\W+)@apply\\s*\\(?([^);\\n]*)\\)?/gi,VAR_CONSUMED:/(--[\\w-]+)\\s*([:,;)]|$)/gi,ANIMATION_MATCH:/(animation\\s*:)|(animation-name\\s*:)/,MEDIA_MATCH:/@media[^(]*(\\([^)]*\\))/,IS_VAR:/^--/,BRACKETED:/\\{[^}]*\\}/g,HOST_PREFIX:\"(?:^|[^.#[:])\",HOST_SUFFIX:\"($|[.:[\\\\s>+~])\"},resolveCss:Polymer.ResolveUrl.resolveCss,\nparser:Polymer.CssParse,ruleTypes:Polymer.CssParse.types}}();\nPolymer.StyleTransformer=function(){var styleUtil=Polymer.StyleUtil;var settings=Polymer.Settings;var api={dom:function(node,scope,useAttr,shouldRemoveScope){this._transformDom(node,scope||\"\",useAttr,shouldRemoveScope)},_transformDom:function(node,selector,useAttr,shouldRemoveScope){if(node.setAttribute)this.element(node,selector,useAttr,shouldRemoveScope);var c$=Polymer.dom(node).childNodes;for(var i=0;i<c$.length;i++)this._transformDom(c$[i],selector,useAttr,shouldRemoveScope)},element:function(element,\nscope,useAttr,shouldRemoveScope){if(useAttr)if(shouldRemoveScope)element.removeAttribute(SCOPE_NAME);else element.setAttribute(SCOPE_NAME,scope);else if(scope)if(element.classList)if(shouldRemoveScope){element.classList.remove(SCOPE_NAME);element.classList.remove(scope)}else{element.classList.add(SCOPE_NAME);element.classList.add(scope)}else if(element.getAttribute){var c=element.getAttribute(CLASS);if(shouldRemoveScope){if(c)element.setAttribute(CLASS,c.replace(SCOPE_NAME,\"\").replace(scope,\"\"))}else element.setAttribute(CLASS,\n(c?c+\" \":\"\")+SCOPE_NAME+\" \"+scope)}},elementStyles:function(element,callback){var styles=element._styles;var cssText=\"\";var cssBuildType=element.__cssBuild;var passthrough=settings.useNativeShadow||cssBuildType===\"shady\";var cb;if(passthrough){var self=this;cb=function(rule){rule.selector=self._slottedToContent(rule.selector);rule.selector=rule.selector.replace(ROOT,\":host > *\");if(callback)callback(rule)}}for(var i=0,l=styles.length,s;i<l&&(s=styles[i]);i++){var rules=styleUtil.rulesForStyle(s);\ncssText+=passthrough?styleUtil.toCssText(rules,cb):this.css(rules,element.is,element[\"extends\"],callback,element._scopeCssViaAttr)+\"\\n\\n\"}return cssText.trim()},css:function(rules,scope,ext,callback,useAttr){var hostScope=this._calcHostScope(scope,ext);scope=this._calcElementScope(scope,useAttr);var self=this;return styleUtil.toCssText(rules,function(rule){if(!rule.isScoped){self.rule(rule,scope,hostScope);rule.isScoped=true}if(callback)callback(rule,scope,hostScope)})},_calcElementScope:function(scope,\nuseAttr){if(scope)return useAttr?CSS_ATTR_PREFIX+scope+CSS_ATTR_SUFFIX:CSS_CLASS_PREFIX+scope;else return\"\"},_calcHostScope:function(scope,ext){return ext?\"[is=\"+scope+\"]\":scope},rule:function(rule,scope,hostScope){this._transformRule(rule,this._transformComplexSelector,scope,hostScope)},_transformRule:function(rule,transformer,scope,hostScope){rule.selector=rule.transformedSelector=this._transformRuleCss(rule,transformer,scope,hostScope)},_transformRuleCss:function(rule,transformer,scope,hostScope){var p$=\nrule.selector.split(COMPLEX_SELECTOR_SEP);if(!styleUtil.isKeyframesSelector(rule))for(var i=0,l=p$.length,p;i<l&&(p=p$[i]);i++)p$[i]=transformer.call(this,p,scope,hostScope);return p$.join(COMPLEX_SELECTOR_SEP)},_transformComplexSelector:function(selector,scope,hostScope){var stop=false;var hostContext=false;var self=this;selector=selector.trim();selector=this._slottedToContent(selector);selector=selector.replace(ROOT,\":host > *\");selector=selector.replace(CONTENT_START,HOST+\" $1\");selector=selector.replace(SIMPLE_SELECTOR_SEP,\nfunction(m,c,s){if(!stop){var info=self._transformCompoundSelector(s,c,scope,hostScope);stop=stop||info.stop;hostContext=hostContext||info.hostContext;c=info.combinator;s=info.value}else s=s.replace(SCOPE_JUMP,\" \");return c+s});if(hostContext)selector=selector.replace(HOST_CONTEXT_PAREN,function(m,pre,paren,post){return pre+paren+\" \"+hostScope+post+COMPLEX_SELECTOR_SEP+\" \"+pre+hostScope+paren+post});return selector},_transformCompoundSelector:function(selector,combinator,scope,hostScope){var jumpIndex=\nselector.search(SCOPE_JUMP);var hostContext=false;if(selector.indexOf(HOST_CONTEXT)>=0)hostContext=true;else if(selector.indexOf(HOST)>=0)selector=this._transformHostSelector(selector,hostScope);else if(jumpIndex!==0)selector=scope?this._transformSimpleSelector(selector,scope):selector;if(selector.indexOf(CONTENT)>=0)combinator=\"\";var stop;if(jumpIndex>=0){selector=selector.replace(SCOPE_JUMP,\" \");stop=true}return{value:selector,combinator:combinator,stop:stop,hostContext:hostContext}},_transformSimpleSelector:function(selector,\nscope){var p$=selector.split(PSEUDO_PREFIX);p$[0]+=scope;return p$.join(PSEUDO_PREFIX)},_transformHostSelector:function(selector,hostScope){var m=selector.match(HOST_PAREN);var paren=m&&m[2].trim()||\"\";if(paren)if(!paren[0].match(SIMPLE_SELECTOR_PREFIX)){var typeSelector=paren.split(SIMPLE_SELECTOR_PREFIX)[0];if(typeSelector===hostScope)return paren;else return SELECTOR_NO_MATCH}else return selector.replace(HOST_PAREN,function(m,host,paren){return hostScope+paren});else return selector.replace(HOST,\nhostScope)},documentRule:function(rule){rule.selector=rule.parsedSelector;this.normalizeRootSelector(rule);if(!settings.useNativeShadow)this._transformRule(rule,this._transformDocumentSelector)},normalizeRootSelector:function(rule){rule.selector=rule.selector.replace(ROOT,\"html\")},_transformDocumentSelector:function(selector){return selector.match(SCOPE_JUMP)?this._transformComplexSelector(selector,SCOPE_DOC_SELECTOR):this._transformSimpleSelector(selector.trim(),SCOPE_DOC_SELECTOR)},_slottedToContent:function(cssText){return cssText.replace(SLOTTED_PAREN,\nCONTENT+\"> $1\")},SCOPE_NAME:\"style-scope\"};var SCOPE_NAME=api.SCOPE_NAME;var SCOPE_DOC_SELECTOR=\":not([\"+SCOPE_NAME+\"])\"+\":not(.\"+SCOPE_NAME+\")\";var COMPLEX_SELECTOR_SEP=\",\";var SIMPLE_SELECTOR_SEP=/(^|[\\s>+~]+)((?:\\[.+?\\]|[^\\s>+~=\\[])+)/g;var SIMPLE_SELECTOR_PREFIX=/[[.:#*]/;var HOST=\":host\";var ROOT=\":root\";var HOST_PAREN=/(:host)(?:\\(((?:\\([^)(]*\\)|[^)(]*)+?)\\))/;var HOST_CONTEXT=\":host-context\";var HOST_CONTEXT_PAREN=/(.*)(?::host-context)(?:\\(((?:\\([^)(]*\\)|[^)(]*)+?)\\))(.*)/;var CONTENT=\"::content\";\nvar SCOPE_JUMP=/::content|::shadow|\\/deep\\//;var CSS_CLASS_PREFIX=\".\";var CSS_ATTR_PREFIX=\"[\"+SCOPE_NAME+\"~=\";var CSS_ATTR_SUFFIX=\"]\";var PSEUDO_PREFIX=\":\";var CLASS=\"class\";var CONTENT_START=new RegExp(\"^(\"+CONTENT+\")\");var SELECTOR_NO_MATCH=\"should_not_match\";var SLOTTED_PAREN=/(?:::slotted)(?:\\(((?:\\([^)(]*\\)|[^)(]*)+?)\\))/g;return api}();\nPolymer.StyleExtends=function(){var styleUtil=Polymer.StyleUtil;return{hasExtends:function(cssText){return Boolean(cssText.match(this.rx.EXTEND))},transform:function(style){var rules=styleUtil.rulesForStyle(style);var self=this;styleUtil.forEachRule(rules,function(rule){self._mapRuleOntoParent(rule);if(rule.parent){var m;while(m=self.rx.EXTEND.exec(rule.cssText)){var extend=m[1];var extendor=self._findExtendor(extend,rule);if(extendor)self._extendRule(rule,extendor)}}rule.cssText=rule.cssText.replace(self.rx.EXTEND,\n\"\")});return styleUtil.toCssText(rules,function(rule){if(rule.selector.match(self.rx.STRIP))rule.cssText=\"\"},true)},_mapRuleOntoParent:function(rule){if(rule.parent){var map=rule.parent.map||(rule.parent.map={});var parts=rule.selector.split(\",\");for(var i=0,p;i<parts.length;i++){p=parts[i];map[p.trim()]=rule}return map}},_findExtendor:function(extend,rule){return rule.parent&&rule.parent.map&&rule.parent.map[extend]||this._findExtendor(extend,rule.parent)},_extendRule:function(target,source){if(target.parent!==\nsource.parent)this._cloneAndAddRuleToParent(source,target.parent);target[\"extends\"]=target[\"extends\"]||[];target[\"extends\"].push(source);source.selector=source.selector.replace(this.rx.STRIP,\"\");source.selector=(source.selector&&source.selector+\",\\n\")+target.selector;if(source[\"extends\"])source[\"extends\"].forEach(function(e){this._extendRule(target,e)},this)},_cloneAndAddRuleToParent:function(rule,parent){rule=Object.create(rule);rule.parent=parent;if(rule[\"extends\"])rule[\"extends\"]=rule[\"extends\"].slice();\nparent.rules.push(rule)},rx:{EXTEND:/@extends\\(([^)]*)\\)\\s*?;/gim,STRIP:/%[^,]*$/}}}();\nPolymer.ApplyShim=function(){var styleUtil=Polymer.StyleUtil;var MIXIN_MATCH=styleUtil.rx.MIXIN_MATCH;var VAR_ASSIGN=styleUtil.rx.VAR_ASSIGN;var BAD_VAR=/var\\(\\s*(--[^,]*),\\s*(--[^)]*)\\)/g;var APPLY_NAME_CLEAN=/;\\s*/m;var INITIAL_INHERIT=/^\\s*(initial)|(inherit)\\s*$/;var MIXIN_VAR_SEP=\"_-_\";var mixinMap={};function mapSet(name,props){name=name.trim();mixinMap[name]={properties:props,dependants:{}}}function mapGet(name){name=name.trim();return mixinMap[name]}function replaceInitialOrInherit(property,\nvalue){var match=INITIAL_INHERIT.exec(value);if(match)if(match[1])value=ApplyShim._getInitialValueForProperty(property);else value=\"apply-shim-inherit\";return value}function cssTextToMap(text){var props=text.split(\";\");var property,value;var out={};for(var i=0,p,sp;i<props.length;i++){p=props[i];if(p){sp=p.split(\":\");if(sp.length>1){property=sp[0].trim();value=replaceInitialOrInherit(property,sp.slice(1).join(\":\"));out[property]=value}}}return out}function invalidateMixinEntry(mixinEntry){var currentProto=\nApplyShim.__currentElementProto;var currentElementName=currentProto&&currentProto.is;for(var elementName in mixinEntry.dependants)if(elementName!==currentElementName)mixinEntry.dependants[elementName].__applyShimInvalid=true}function produceCssProperties(matchText,propertyName,valueProperty,valueMixin){if(valueProperty)styleUtil.processVariableAndFallback(valueProperty,function(prefix,value){if(value&&mapGet(value))valueMixin=\"@apply \"+value+\";\"});if(!valueMixin)return matchText;var mixinAsProperties=\nconsumeCssProperties(valueMixin);var prefix=matchText.slice(0,matchText.indexOf(\"--\"));var mixinValues=cssTextToMap(mixinAsProperties);var combinedProps=mixinValues;var mixinEntry=mapGet(propertyName);var oldProps=mixinEntry&&mixinEntry.properties;if(oldProps){combinedProps=Object.create(oldProps);combinedProps=Polymer.Base.mixin(combinedProps,mixinValues)}else mapSet(propertyName,combinedProps);var out=[];var p,v;var needToInvalidate=false;for(p in combinedProps){v=mixinValues[p];if(v===undefined)v=\n\"initial\";if(oldProps&&!(p in oldProps))needToInvalidate=true;out.push(propertyName+MIXIN_VAR_SEP+p+\": \"+v)}if(needToInvalidate)invalidateMixinEntry(mixinEntry);if(mixinEntry)mixinEntry.properties=combinedProps;if(valueProperty)prefix=matchText+\";\"+prefix;return prefix+out.join(\"; \")+\";\"}function fixVars(matchText,varA,varB){return\"var(\"+varA+\",\"+\"var(\"+varB+\"))\"}function atApplyToCssProperties(mixinName,fallbacks){mixinName=mixinName.replace(APPLY_NAME_CLEAN,\"\");var vars=[];var mixinEntry=mapGet(mixinName);\nif(!mixinEntry){mapSet(mixinName,{});mixinEntry=mapGet(mixinName)}if(mixinEntry){var currentProto=ApplyShim.__currentElementProto;if(currentProto)mixinEntry.dependants[currentProto.is]=currentProto;var p,parts,f;for(p in mixinEntry.properties){f=fallbacks&&fallbacks[p];parts=[p,\": var(\",mixinName,MIXIN_VAR_SEP,p];if(f)parts.push(\",\",f);parts.push(\")\");vars.push(parts.join(\"\"))}}return vars.join(\"; \")}function consumeCssProperties(text){var m;while(m=MIXIN_MATCH.exec(text)){var matchText=m[0];var mixinName=\nm[1];var idx=m.index;var applyPos=idx+matchText.indexOf(\"@apply\");var afterApplyPos=idx+matchText.length;var textBeforeApply=text.slice(0,applyPos);var textAfterApply=text.slice(afterApplyPos);var defaults=cssTextToMap(textBeforeApply);var replacement=atApplyToCssProperties(mixinName,defaults);text=[textBeforeApply,replacement,textAfterApply].join(\"\");MIXIN_MATCH.lastIndex=idx+replacement.length}return text}var ApplyShim={_measureElement:null,_map:mixinMap,_separator:MIXIN_VAR_SEP,transform:function(styles,\nelementProto){this.__currentElementProto=elementProto;styleUtil.forRulesInStyles(styles,this._boundFindDefinitions);styleUtil.forRulesInStyles(styles,this._boundFindApplications);if(elementProto)elementProto.__applyShimInvalid=false;this.__currentElementProto=null},_findDefinitions:function(rule){var cssText=rule.parsedCssText;cssText=cssText.replace(BAD_VAR,fixVars);cssText=cssText.replace(VAR_ASSIGN,produceCssProperties);rule.cssText=cssText;if(rule.selector===\":root\")rule.selector=\":host > *\"},\n_findApplications:function(rule){rule.cssText=consumeCssProperties(rule.cssText)},transformRule:function(rule){this._findDefinitions(rule);this._findApplications(rule)},_getInitialValueForProperty:function(property){if(!this._measureElement){this._measureElement=document.createElement(\"meta\");this._measureElement.style.all=\"initial\";document.head.appendChild(this._measureElement)}return window.getComputedStyle(this._measureElement).getPropertyValue(property)}};ApplyShim._boundTransformRule=ApplyShim.transformRule.bind(ApplyShim);\nApplyShim._boundFindDefinitions=ApplyShim._findDefinitions.bind(ApplyShim);ApplyShim._boundFindApplications=ApplyShim._findApplications.bind(ApplyShim);return ApplyShim}();\n(function(){var prepElement=Polymer.Base._prepElement;var nativeShadow=Polymer.Settings.useNativeShadow;var styleUtil=Polymer.StyleUtil;var styleTransformer=Polymer.StyleTransformer;var styleExtends=Polymer.StyleExtends;var applyShim=Polymer.ApplyShim;var settings=Polymer.Settings;Polymer.Base._addFeature({_prepElement:function(element){if(this._encapsulateStyle&&this.__cssBuild!==\"shady\")styleTransformer.element(element,this.is,this._scopeCssViaAttr);prepElement.call(this,element)},_prepStyles:function(){if(this._encapsulateStyle===\nundefined)this._encapsulateStyle=!nativeShadow;if(!nativeShadow)this._scopeStyle=styleUtil.applyStylePlaceHolder(this.is);this.__cssBuild=styleUtil.cssBuildTypeForModule(this.is)},_prepShimStyles:function(){if(this._template){var hasTargetedCssBuild=styleUtil.isTargetedBuild(this.__cssBuild);if(settings.useNativeCSSProperties&&this.__cssBuild===\"shadow\"&&hasTargetedCssBuild)return;this._styles=this._styles||this._collectStyles();if(settings.useNativeCSSProperties&&!this.__cssBuild)applyShim.transform(this._styles,\nthis);var cssText=settings.useNativeCSSProperties&&hasTargetedCssBuild?this._styles.length&&this._styles[0].textContent.trim():styleTransformer.elementStyles(this);this._prepStyleProperties();if(!this._needsStyleProperties()&&cssText)styleUtil.applyCss(cssText,this.is,nativeShadow?this._template.content:null,this._scopeStyle)}else this._styles=[]},_collectStyles:function(){var styles=[];var cssText=\"\",m$=this.styleModules;if(m$)for(var i=0,l=m$.length,m;i<l&&(m=m$[i]);i++)cssText+=styleUtil.cssFromModule(m);\ncssText+=styleUtil.cssFromModule(this.is);var p=this._template&&this._template.parentNode;if(this._template&&(!p||p.id.toLowerCase()!==this.is))cssText+=styleUtil.cssFromElement(this._template);if(cssText){var style=document.createElement(\"style\");style.textContent=cssText;if(styleExtends.hasExtends(style.textContent))cssText=styleExtends.transform(style);styles.push(style)}return styles},_elementAdd:function(node){if(this._encapsulateStyle)if(node.__styleScoped)node.__styleScoped=false;else styleTransformer.dom(node,\nthis.is,this._scopeCssViaAttr)},_elementRemove:function(node){if(this._encapsulateStyle)styleTransformer.dom(node,this.is,this._scopeCssViaAttr,true)},scopeSubtree:function(container,shouldObserve){if(nativeShadow)return;var self=this;var scopify=function(node){if(node.nodeType===Node.ELEMENT_NODE){var className=node.getAttribute(\"class\");node.setAttribute(\"class\",self._scopeElementClass(node,className));var n$=node.querySelectorAll(\"*\");for(var i=0,n;i<n$.length&&(n=n$[i]);i++){className=n.getAttribute(\"class\");\nn.setAttribute(\"class\",self._scopeElementClass(n,className))}}};scopify(container);if(shouldObserve){var mo=new MutationObserver(function(mxns){for(var i=0,m;i<mxns.length&&(m=mxns[i]);i++)if(m.addedNodes)for(var j=0;j<m.addedNodes.length;j++)scopify(m.addedNodes[j])});mo.observe(container,{childList:true,subtree:true});return mo}}})})();\nPolymer.StyleProperties=function(){var matchesSelector=Polymer.DomApi.matchesSelector;var styleUtil=Polymer.StyleUtil;var styleTransformer=Polymer.StyleTransformer;var IS_IE=navigator.userAgent.match(\"Trident\");var settings=Polymer.Settings;return{decorateStyles:function(styles,scope){var self=this,props={},keyframes=[],ruleIndex=0;var scopeSelector=styleTransformer._calcHostScope(scope.is,scope[\"extends\"]);styleUtil.forRulesInStyles(styles,function(rule,style){self.decorateRule(rule);rule.index=\nruleIndex++;self.whenHostOrRootRule(scope,rule,style,function(info){if(rule.parent.type===styleUtil.ruleTypes.MEDIA_RULE)scope.__notStyleScopeCacheable=true;if(info.isHost){var hostContextOrFunction=info.selector.split(\" \").some(function(s){return s.indexOf(scopeSelector)===0&&s.length!==scopeSelector.length});scope.__notStyleScopeCacheable=scope.__notStyleScopeCacheable||hostContextOrFunction}});self.collectPropertiesInCssText(rule.propertyInfo.cssText,props)},function onKeyframesRule(rule){keyframes.push(rule)});\nstyles._keyframes=keyframes;var names=[];for(var i in props)names.push(i);return names},decorateRule:function(rule){if(rule.propertyInfo)return rule.propertyInfo;var info={},properties={};var hasProperties=this.collectProperties(rule,properties);if(hasProperties){info.properties=properties;rule.rules=null}info.cssText=this.collectCssText(rule);rule.propertyInfo=info;return info},collectProperties:function(rule,properties){var info=rule.propertyInfo;if(info){if(info.properties){Polymer.Base.mixin(properties,\ninfo.properties);return true}}else{var m,rx=this.rx.VAR_ASSIGN;var cssText=rule.parsedCssText;var value;var any;while(m=rx.exec(cssText)){value=(m[2]||m[3]).trim();if(value!==\"inherit\")properties[m[1].trim()]=value;any=true}return any}},collectCssText:function(rule){return this.collectConsumingCssText(rule.parsedCssText)},collectConsumingCssText:function(cssText){return cssText.replace(this.rx.BRACKETED,\"\").replace(this.rx.VAR_ASSIGN,\"\")},collectPropertiesInCssText:function(cssText,props){var m;while(m=\nthis.rx.VAR_CONSUMED.exec(cssText)){var name=m[1];if(m[2]!==\":\")props[name]=true}},reify:function(props){var names=Object.getOwnPropertyNames(props);for(var i=0,n;i<names.length;i++){n=names[i];props[n]=this.valueForProperty(props[n],props)}},valueForProperty:function(property,props){if(property)if(property.indexOf(\";\")>=0)property=this.valueForProperties(property,props);else{var self=this;var fn=function(prefix,value,fallback,suffix){var propertyValue=self.valueForProperty(props[value],props);if(!propertyValue||\npropertyValue===\"initial\")propertyValue=self.valueForProperty(props[fallback]||fallback,props)||fallback;else if(propertyValue===\"apply-shim-inherit\")propertyValue=\"inherit\";return prefix+(propertyValue||\"\")+suffix};property=styleUtil.processVariableAndFallback(property,fn)}return property&&property.trim()||\"\"},valueForProperties:function(property,props){var parts=property.split(\";\");for(var i=0,p,m;i<parts.length;i++)if(p=parts[i]){this.rx.MIXIN_MATCH.lastIndex=0;m=this.rx.MIXIN_MATCH.exec(p);if(m)p=\nthis.valueForProperty(props[m[1]],props);else{var colon=p.indexOf(\":\");if(colon!==-1){var pp=p.substring(colon);pp=pp.trim();pp=this.valueForProperty(pp,props)||pp;p=p.substring(0,colon)+pp}}parts[i]=p&&p.lastIndexOf(\";\")===p.length-1?p.slice(0,-1):p||\"\"}return parts.join(\";\")},applyProperties:function(rule,props){var output=\"\";if(!rule.propertyInfo)this.decorateRule(rule);if(rule.propertyInfo.cssText)output=this.valueForProperties(rule.propertyInfo.cssText,props);rule.cssText=output},applyKeyframeTransforms:function(rule,\nkeyframeTransforms){var input=rule.cssText;var output=rule.cssText;if(rule.hasAnimations==null)rule.hasAnimations=this.rx.ANIMATION_MATCH.test(input);if(rule.hasAnimations){var transform;if(rule.keyframeNamesToTransform==null){rule.keyframeNamesToTransform=[];for(var keyframe in keyframeTransforms){transform=keyframeTransforms[keyframe];output=transform(input);if(input!==output){input=output;rule.keyframeNamesToTransform.push(keyframe)}}}else{for(var i=0;i<rule.keyframeNamesToTransform.length;++i){transform=\nkeyframeTransforms[rule.keyframeNamesToTransform[i]];input=transform(input)}output=input}}rule.cssText=output},propertyDataFromStyles:function(styles,element){var props={},self=this;var o=[];styleUtil.forActiveRulesInStyles(styles,function(rule){if(!rule.propertyInfo)self.decorateRule(rule);var selectorToMatch=rule.transformedSelector||rule.parsedSelector;if(element&&rule.propertyInfo.properties&&selectorToMatch)if(matchesSelector.call(element,selectorToMatch)){self.collectProperties(rule,props);\naddToBitMask(rule.index,o)}});return{properties:props,key:o}},_rootSelector:/:root|:host\\s*>\\s*\\*/,_checkRoot:function(hostScope,selector){return Boolean(selector.match(this._rootSelector))||hostScope===\"html\"&&selector.indexOf(\"html\")>-1},whenHostOrRootRule:function(scope,rule,style,callback){if(!rule.propertyInfo)self.decorateRule(rule);if(!rule.propertyInfo.properties)return;var hostScope=scope.is?styleTransformer._calcHostScope(scope.is,scope[\"extends\"]):\"html\";var parsedSelector=rule.parsedSelector;\nvar isRoot=this._checkRoot(hostScope,parsedSelector);var isHost=!isRoot&&parsedSelector.indexOf(\":host\")===0;var cssBuild=scope.__cssBuild||style.__cssBuild;if(cssBuild===\"shady\"){isRoot=parsedSelector===hostScope+\" > *.\"+hostScope||parsedSelector.indexOf(\"html\")>-1;isHost=!isRoot&&parsedSelector.indexOf(hostScope)===0}if(!isRoot&&!isHost)return;var selectorToMatch=hostScope;if(isHost){if(settings.useNativeShadow&&!rule.transformedSelector)rule.transformedSelector=styleTransformer._transformRuleCss(rule,\nstyleTransformer._transformComplexSelector,scope.is,hostScope);selectorToMatch=rule.transformedSelector||rule.parsedSelector}if(isRoot&&hostScope===\"html\")selectorToMatch=rule.transformedSelector||rule.parsedSelector;callback({selector:selectorToMatch,isHost:isHost,isRoot:isRoot})},hostAndRootPropertiesForScope:function(scope){var hostProps={},rootProps={},self=this;styleUtil.forActiveRulesInStyles(scope._styles,function(rule,style){self.whenHostOrRootRule(scope,rule,style,function(info){var element=\nscope._element||scope;if(matchesSelector.call(element,info.selector))if(info.isHost)self.collectProperties(rule,hostProps);else self.collectProperties(rule,rootProps)})});return{rootProps:rootProps,hostProps:hostProps}},transformStyles:function(element,properties,scopeSelector){var self=this;var hostSelector=styleTransformer._calcHostScope(element.is,element[\"extends\"]);var rxHostSelector=element[\"extends\"]?\"\\\\\"+hostSelector.slice(0,-1)+\"\\\\]\":hostSelector;var hostRx=new RegExp(this.rx.HOST_PREFIX+\nrxHostSelector+this.rx.HOST_SUFFIX);var keyframeTransforms=this._elementKeyframeTransforms(element,scopeSelector);return styleTransformer.elementStyles(element,function(rule){self.applyProperties(rule,properties);if(!settings.useNativeShadow&&!Polymer.StyleUtil.isKeyframesSelector(rule)&&rule.cssText){self.applyKeyframeTransforms(rule,keyframeTransforms);self._scopeSelector(rule,hostRx,hostSelector,element._scopeCssViaAttr,scopeSelector)}})},_elementKeyframeTransforms:function(element,scopeSelector){var keyframesRules=\nelement._styles._keyframes;var keyframeTransforms={};if(!settings.useNativeShadow&&keyframesRules)for(var i=0,keyframesRule=keyframesRules[i];i<keyframesRules.length;keyframesRule=keyframesRules[++i]){this._scopeKeyframes(keyframesRule,scopeSelector);keyframeTransforms[keyframesRule.keyframesName]=this._keyframesRuleTransformer(keyframesRule)}return keyframeTransforms},_keyframesRuleTransformer:function(keyframesRule){return function(cssText){return cssText.replace(keyframesRule.keyframesNameRx,keyframesRule.transformedKeyframesName)}},\n_scopeKeyframes:function(rule,scopeId){rule.keyframesNameRx=new RegExp(rule.keyframesName,\"g\");rule.transformedKeyframesName=rule.keyframesName+\"-\"+scopeId;rule.transformedSelector=rule.transformedSelector||rule.selector;rule.selector=rule.transformedSelector.replace(rule.keyframesName,rule.transformedKeyframesName)},_scopeSelector:function(rule,hostRx,hostSelector,viaAttr,scopeId){rule.transformedSelector=rule.transformedSelector||rule.selector;var selector=rule.transformedSelector;var scope=viaAttr?\n\"[\"+styleTransformer.SCOPE_NAME+\"~=\"+scopeId+\"]\":\".\"+scopeId;var parts=selector.split(\",\");for(var i=0,l=parts.length,p;i<l&&(p=parts[i]);i++)parts[i]=p.match(hostRx)?p.replace(hostSelector,scope):scope+\" \"+p;rule.selector=parts.join(\",\")},applyElementScopeSelector:function(element,selector,old,viaAttr){var c=viaAttr?element.getAttribute(styleTransformer.SCOPE_NAME):element.getAttribute(\"class\")||\"\";var v=old?c.replace(old,selector):(c?c+\" \":\"\")+this.XSCOPE_NAME+\" \"+selector;if(c!==v)if(viaAttr)element.setAttribute(styleTransformer.SCOPE_NAME,\nv);else element.setAttribute(\"class\",v)},applyElementStyle:function(element,properties,selector,style){var cssText=style?style.textContent||\"\":this.transformStyles(element,properties,selector);var s=element._customStyle;if(s&&!settings.useNativeShadow&&s!==style){s._useCount--;if(s._useCount<=0&&s.parentNode)s.parentNode.removeChild(s)}if(settings.useNativeShadow)if(element._customStyle){element._customStyle.textContent=cssText;style=element._customStyle}else{if(cssText)style=styleUtil.applyCss(cssText,\nselector,element.root,element._scopeStyle)}else if(!style){if(cssText)style=styleUtil.applyCss(cssText,selector,null,element._scopeStyle)}else if(!style.parentNode){if(IS_IE&&cssText.indexOf(\"@media\")>-1)style.textContent=cssText;styleUtil.applyStyle(style,null,element._scopeStyle)}if(style){style._useCount=style._useCount||0;if(element._customStyle!=style)style._useCount++;element._customStyle=style}return style},mixinCustomStyle:function(props,customStyle){var v;for(var i in customStyle){v=customStyle[i];\nif(v||v===0)props[i]=v}},updateNativeStyleProperties:function(element,properties){var oldPropertyNames=element.__customStyleProperties;if(oldPropertyNames)for(var i=0;i<oldPropertyNames.length;i++)element.style.removeProperty(oldPropertyNames[i]);var propertyNames=[];for(var p in properties)if(properties[p]!==null){element.style.setProperty(p,properties[p]);propertyNames.push(p)}element.__customStyleProperties=propertyNames},rx:styleUtil.rx,XSCOPE_NAME:\"x-scope\"};function addToBitMask(n,bits){var o=\nparseInt(n/32);var v=1<<n%32;bits[o]=(bits[o]||0)|v}}();\n(function(){Polymer.StyleCache=function(){this.cache={}};Polymer.StyleCache.prototype={MAX:100,store:function(is,data,keyValues,keyStyles){data.keyValues=keyValues;data.styles=keyStyles;var s$=this.cache[is]=this.cache[is]||[];s$.push(data);if(s$.length>this.MAX)s$.shift()},retrieve:function(is,keyValues,keyStyles){var cache=this.cache[is];if(cache)for(var i=cache.length-1,data;i>=0;i--){data=cache[i];if(keyStyles===data.styles&&this._objectsEqual(keyValues,data.keyValues))return data}},clear:function(){this.cache=\n{}},_objectsEqual:function(target,source){var t,s;for(var i in target){t=target[i],s=source[i];if(!(typeof t===\"object\"&&t?this._objectsStrictlyEqual(t,s):t===s))return false}if(Array.isArray(target))return target.length===source.length;return true},_objectsStrictlyEqual:function(target,source){return this._objectsEqual(target,source)&&this._objectsEqual(source,target)}}})();\nPolymer.StyleDefaults=function(){var styleProperties=Polymer.StyleProperties;var StyleCache=Polymer.StyleCache;var nativeVariables=Polymer.Settings.useNativeCSSProperties;var api={_styles:[],_properties:null,customStyle:{},_styleCache:new StyleCache,_element:Polymer.DomApi.wrap(document.documentElement),addStyle:function(style){this._styles.push(style);this._properties=null},get _styleProperties(){if(!this._properties){styleProperties.decorateStyles(this._styles,this);this._styles._scopeStyleProperties=\nnull;this._properties=styleProperties.hostAndRootPropertiesForScope(this).rootProps;styleProperties.mixinCustomStyle(this._properties,this.customStyle);styleProperties.reify(this._properties)}return this._properties},hasStyleProperties:function(){return Boolean(this._properties)},_needsStyleProperties:function(){},_computeStyleProperties:function(){return this._styleProperties},updateStyles:function(properties){this._properties=null;if(properties)Polymer.Base.mixin(this.customStyle,properties);this._styleCache.clear();\nfor(var i=0,s;i<this._styles.length;i++){s=this._styles[i];s=s.__importElement||s;s._apply()}if(nativeVariables)styleProperties.updateNativeStyleProperties(document.documentElement,this.customStyle)}};return api}();\n(function(){var serializeValueToAttribute=Polymer.Base.serializeValueToAttribute;var propertyUtils=Polymer.StyleProperties;var styleTransformer=Polymer.StyleTransformer;var styleDefaults=Polymer.StyleDefaults;var nativeShadow=Polymer.Settings.useNativeShadow;var nativeVariables=Polymer.Settings.useNativeCSSProperties;Polymer.Base._addFeature({_prepStyleProperties:function(){if(!nativeVariables)this._ownStylePropertyNames=this._styles&&this._styles.length?propertyUtils.decorateStyles(this._styles,\nthis):null},customStyle:null,getComputedStyleValue:function(property){if(!nativeVariables&&!this._styleProperties)this._computeStyleProperties();return!nativeVariables&&this._styleProperties&&this._styleProperties[property]||getComputedStyle(this).getPropertyValue(property)},_setupStyleProperties:function(){this.customStyle={};this._styleCache=null;this._styleProperties=null;this._scopeSelector=null;this._ownStyleProperties=null;this._customStyle=null},_needsStyleProperties:function(){return Boolean(!nativeVariables&&\nthis._ownStylePropertyNames&&this._ownStylePropertyNames.length)},_validateApplyShim:function(){if(this.__applyShimInvalid){Polymer.ApplyShim.transform(this._styles,this.__proto__);var cssText=styleTransformer.elementStyles(this);if(nativeShadow){var templateStyle=this._template.content.querySelector(\"style\");if(templateStyle)templateStyle.textContent=cssText}else{var shadyStyle=this._scopeStyle&&this._scopeStyle.nextSibling;if(shadyStyle)shadyStyle.textContent=cssText}}},_beforeAttached:function(){if((!this._scopeSelector||\nthis.__stylePropertiesInvalid)&&this._needsStyleProperties()){this.__stylePropertiesInvalid=false;this._updateStyleProperties()}},_findStyleHost:function(){var e=this,root;while(root=Polymer.dom(e).getOwnerRoot()){if(Polymer.isInstance(root.host))return root.host;e=root.host}return styleDefaults},_updateStyleProperties:function(){var info,scope=this._findStyleHost();if(!scope._styleProperties)scope._computeStyleProperties();if(!scope._styleCache)scope._styleCache=new Polymer.StyleCache;var scopeData=\npropertyUtils.propertyDataFromStyles(scope._styles,this);var scopeCacheable=!this.__notStyleScopeCacheable;if(scopeCacheable){scopeData.key.customStyle=this.customStyle;info=scope._styleCache.retrieve(this.is,scopeData.key,this._styles)}var scopeCached=Boolean(info);if(scopeCached)this._styleProperties=info._styleProperties;else this._computeStyleProperties(scopeData.properties);this._computeOwnStyleProperties();if(!scopeCached)info=styleCache.retrieve(this.is,this._ownStyleProperties,this._styles);\nvar globalCached=Boolean(info)&&!scopeCached;var style=this._applyStyleProperties(info);if(!scopeCached){style=style&&nativeShadow?style.cloneNode(true):style;info={style:style,_scopeSelector:this._scopeSelector,_styleProperties:this._styleProperties};if(scopeCacheable){scopeData.key.customStyle={};this.mixin(scopeData.key.customStyle,this.customStyle);scope._styleCache.store(this.is,info,scopeData.key,this._styles)}if(!globalCached)styleCache.store(this.is,Object.create(info),this._ownStyleProperties,\nthis._styles)}},_computeStyleProperties:function(scopeProps){var scope=this._findStyleHost();if(!scope._styleProperties)scope._computeStyleProperties();var props=Object.create(scope._styleProperties);var hostAndRootProps=propertyUtils.hostAndRootPropertiesForScope(this);this.mixin(props,hostAndRootProps.hostProps);scopeProps=scopeProps||propertyUtils.propertyDataFromStyles(scope._styles,this).properties;this.mixin(props,scopeProps);this.mixin(props,hostAndRootProps.rootProps);propertyUtils.mixinCustomStyle(props,\nthis.customStyle);propertyUtils.reify(props);this._styleProperties=props},_computeOwnStyleProperties:function(){var props={};for(var i=0,n;i<this._ownStylePropertyNames.length;i++){n=this._ownStylePropertyNames[i];props[n]=this._styleProperties[n]}this._ownStyleProperties=props},_scopeCount:0,_applyStyleProperties:function(info){var oldScopeSelector=this._scopeSelector;this._scopeSelector=info?info._scopeSelector:this.is+\"-\"+this.__proto__._scopeCount++;var style=propertyUtils.applyElementStyle(this,\nthis._styleProperties,this._scopeSelector,info&&info.style);if(!nativeShadow)propertyUtils.applyElementScopeSelector(this,this._scopeSelector,oldScopeSelector,this._scopeCssViaAttr);return style},serializeValueToAttribute:function(value,attribute,node){node=node||this;if(attribute===\"class\"&&!nativeShadow){var host=node===this?this.domHost||this.dataHost:this;if(host)value=host._scopeElementClass(node,value)}node=this.shadyRoot&&this.shadyRoot._hasDistributed?Polymer.dom(node):node;serializeValueToAttribute.call(this,\nvalue,attribute,node)},_scopeElementClass:function(element,selector){if(!nativeShadow&&!this._scopeCssViaAttr)selector=(selector?selector+\" \":\"\")+SCOPE_NAME+\" \"+this.is+(element._scopeSelector?\" \"+XSCOPE_NAME+\" \"+element._scopeSelector:\"\");return selector},updateStyles:function(properties){if(properties)this.mixin(this.customStyle,properties);if(nativeVariables)propertyUtils.updateNativeStyleProperties(this,this.customStyle);else{if(this.isAttached)if(this._needsStyleProperties())this._updateStyleProperties();\nelse this._styleProperties=null;else this.__stylePropertiesInvalid=true;if(this._styleCache)this._styleCache.clear();this._updateRootStyles()}},_updateRootStyles:function(root){root=root||this.root;var c$=Polymer.dom(root)._query(function(e){return e.shadyRoot||e.shadowRoot});for(var i=0,l=c$.length,c;i<l&&(c=c$[i]);i++)if(c.updateStyles)c.updateStyles()}});Polymer.updateStyles=function(properties){styleDefaults.updateStyles(properties);Polymer.Base._updateRootStyles(document)};var styleCache=new Polymer.StyleCache;\nPolymer.customStyleCache=styleCache;var SCOPE_NAME=styleTransformer.SCOPE_NAME;var XSCOPE_NAME=propertyUtils.XSCOPE_NAME})();\nPolymer.Base._addFeature({_registerFeatures:function(){this._prepIs();if(this.factoryImpl)this._prepConstructor();this._prepStyles()},_finishRegisterFeatures:function(){this._prepTemplate();this._prepShimStyles();this._prepAnnotations();this._prepEffects();this._prepBehaviors();this._prepPropertyInfo();this._prepBindings();this._prepShady()},_prepBehavior:function(b){this._addPropertyEffects(b.properties);this._addComplexObserverEffects(b.observers);this._addHostAttributes(b.hostAttributes)},_initFeatures:function(){this._setupGestures();\nthis._setupConfigure(this.__data__);this._setupStyleProperties();this._setupDebouncers();this._setupShady();this._registerHost();if(this._template){this._validateApplyShim();this._poolContent();this._beginHosting();this._stampTemplate();this._endHosting();this._marshalAnnotationReferences()}this._marshalInstanceEffects();this._marshalBehaviors();this._marshalHostAttributes();this._marshalAttributes();this._tryReady()},_marshalBehavior:function(b){if(b.listeners)this._listenListeners(b.listeners)}});\n(function(){var propertyUtils=Polymer.StyleProperties;var styleUtil=Polymer.StyleUtil;var cssParse=Polymer.CssParse;var styleDefaults=Polymer.StyleDefaults;var styleTransformer=Polymer.StyleTransformer;var applyShim=Polymer.ApplyShim;var debounce=Polymer.Debounce;var settings=Polymer.Settings;var updateDebouncer;Polymer({is:\"custom-style\",\"extends\":\"style\",_template:null,properties:{include:String},ready:function(){this.__appliedElement=this.__appliedElement||this;this.__cssBuild=styleUtil.getCssBuildType(this);\nif(this.__appliedElement!==this)this.__appliedElement.__cssBuild=this.__cssBuild;this._tryApply()},attached:function(){this._tryApply()},_tryApply:function(){if(!this._appliesToDocument)if(this.parentNode&&this.parentNode.localName!==\"dom-module\"){this._appliesToDocument=true;var e=this.__appliedElement;if(!settings.useNativeCSSProperties){this.__needsUpdateStyles=styleDefaults.hasStyleProperties();styleDefaults.addStyle(e)}if(e.textContent||this.include)this._apply(true);else{var self=this;var observer=\nnew MutationObserver(function(){observer.disconnect();self._apply(true)});observer.observe(e,{childList:true})}}},_updateStyles:function(){Polymer.updateStyles()},_apply:function(initialApply){var e=this.__appliedElement;if(this.include)e.textContent=styleUtil.cssFromModules(this.include,true)+e.textContent;if(!e.textContent)return;var buildType=this.__cssBuild;var targetedBuild=styleUtil.isTargetedBuild(buildType);if(settings.useNativeCSSProperties&&targetedBuild)return;var styleRules=styleUtil.rulesForStyle(e);\nif(!targetedBuild){styleUtil.forEachRule(styleRules,function(rule){styleTransformer.documentRule(rule)});if(settings.useNativeCSSProperties&&!buildType)applyShim.transform([e])}if(settings.useNativeCSSProperties)e.textContent=styleUtil.toCssText(styleRules);else{var self=this;var fn=function fn(){self._flushCustomProperties()};if(initialApply)Polymer.RenderStatus.whenReady(fn);else fn()}},_flushCustomProperties:function(){if(this.__needsUpdateStyles){this.__needsUpdateStyles=false;updateDebouncer=\ndebounce(updateDebouncer,this._updateStyles)}else this._applyCustomProperties()},_applyCustomProperties:function(){var element=this.__appliedElement;this._computeStyleProperties();var props=this._styleProperties;var rules=styleUtil.rulesForStyle(element);if(!rules)return;element.textContent=styleUtil.toCssText(rules,function(rule){var css=rule.cssText=rule.parsedCssText;if(rule.propertyInfo&&rule.propertyInfo.cssText){css=cssParse.removeCustomPropAssignment(css);rule.cssText=propertyUtils.valueForProperties(css,\nprops)}})}})})();\nPolymer.Templatizer={properties:{__hideTemplateChildren__:{observer:\"_showHideChildren\"}},_instanceProps:Polymer.nob,_parentPropPrefix:\"_parent_\",templatize:function(template){this._templatized=template;if(!template._content)template._content=template.content;if(template._content._ctor){this.ctor=template._content._ctor;this._prepParentProperties(this.ctor.prototype,template);return}var archetype=Object.create(Polymer.Base);this._customPrepAnnotations(archetype,template);this._prepParentProperties(archetype,template);\narchetype._prepEffects();this._customPrepEffects(archetype);archetype._prepBehaviors();archetype._prepPropertyInfo();archetype._prepBindings();archetype._notifyPathUp=this._notifyPathUpImpl;archetype._scopeElementClass=this._scopeElementClassImpl;archetype.listen=this._listenImpl;archetype._showHideChildren=this._showHideChildrenImpl;archetype.__setPropertyOrig=this.__setProperty;archetype.__setProperty=this.__setPropertyImpl;var _constructor=this._constructorImpl;var ctor=function TemplateInstance(model,\nhost){_constructor.call(this,model,host)};ctor.prototype=archetype;archetype.constructor=ctor;template._content._ctor=ctor;this.ctor=ctor},_getRootDataHost:function(){return this.dataHost&&this.dataHost._rootDataHost||this.dataHost},_showHideChildrenImpl:function(hide){var c=this._children;for(var i=0;i<c.length;i++){var n=c[i];if(Boolean(hide)!=Boolean(n.__hideTemplateChildren__))if(n.nodeType===Node.TEXT_NODE)if(hide){n.__polymerTextContent__=n.textContent;n.textContent=\"\"}else n.textContent=n.__polymerTextContent__;\nelse if(n.style)if(hide){n.__polymerDisplay__=n.style.display;n.style.display=\"none\"}else n.style.display=n.__polymerDisplay__;n.__hideTemplateChildren__=hide}},__setPropertyImpl:function(property,value,fromAbove,node){if(node&&node.__hideTemplateChildren__&&property==\"textContent\")property=\"__polymerTextContent__\";this.__setPropertyOrig(property,value,fromAbove,node)},_debounceTemplate:function(fn){Polymer.dom.addDebouncer(this.debounce(\"_debounceTemplate\",fn))},_flushTemplates:function(){Polymer.dom.flush()},\n_customPrepEffects:function(archetype){var parentProps=archetype._parentProps;for(var prop in parentProps)archetype._addPropertyEffect(prop,\"function\",this._createHostPropEffector(prop));for(prop in this._instanceProps)archetype._addPropertyEffect(prop,\"function\",this._createInstancePropEffector(prop))},_customPrepAnnotations:function(archetype,template){archetype._template=template;var c=template._content;if(!c._notes){var rootDataHost=archetype._rootDataHost;if(rootDataHost)Polymer.Annotations.prepElement=\nfunction(){rootDataHost._prepElement()};c._notes=Polymer.Annotations.parseAnnotations(template);Polymer.Annotations.prepElement=null;this._processAnnotations(c._notes)}archetype._notes=c._notes;archetype._parentProps=c._parentProps},_prepParentProperties:function(archetype,template){var parentProps=this._parentProps=archetype._parentProps;if(this._forwardParentProp&&parentProps){var proto=archetype._parentPropProto;var prop;if(!proto){for(prop in this._instanceProps)delete parentProps[prop];proto=\narchetype._parentPropProto=Object.create(null);if(template!=this){Polymer.Bind.prepareModel(proto);Polymer.Base.prepareModelNotifyPath(proto)}for(prop in parentProps){var parentProp=this._parentPropPrefix+prop;var effects=[{kind:\"function\",effect:this._createForwardPropEffector(prop),fn:Polymer.Bind._functionEffect},{kind:\"notify\",fn:Polymer.Bind._notifyEffect,effect:{event:Polymer.CaseMap.camelToDashCase(parentProp)+\"-changed\"}}];proto._propertyEffects=proto._propertyEffects||{};proto._propertyEffects[parentProp]=\neffects;Polymer.Bind._createAccessors(proto,parentProp,effects)}}var self=this;if(template!=this){Polymer.Bind.prepareInstance(template);template._forwardParentProp=function(source,value){self._forwardParentProp(source,value)}}this._extendTemplate(template,proto);template._pathEffector=function(path,value,fromAbove){return self._pathEffectorImpl(path,value,fromAbove)}}},_createForwardPropEffector:function(prop){return function(source,value){this._forwardParentProp(prop,value)}},_createHostPropEffector:function(prop){var prefix=\nthis._parentPropPrefix;return function(source,value){this.dataHost._templatized[prefix+prop]=value}},_createInstancePropEffector:function(prop){return function(source,value,old,fromAbove){if(!fromAbove)this.dataHost._forwardInstanceProp(this,prop,value)}},_extendTemplate:function(template,proto){var n$=Object.getOwnPropertyNames(proto);if(proto._propertySetter)template._propertySetter=proto._propertySetter;for(var i=0,n;i<n$.length&&(n=n$[i]);i++){var val=template[n];if(val&&n==\"_propertyEffects\"){var pe=\nPolymer.Base.mixin({},val);template._propertyEffects=Polymer.Base.mixin(pe,proto._propertyEffects)}else{var pd=Object.getOwnPropertyDescriptor(proto,n);Object.defineProperty(template,n,pd);if(val!==undefined)template._propertySetter(n,val)}}},_showHideChildren:function(hidden){},_forwardInstancePath:function(inst,path,value){},_forwardInstanceProp:function(inst,prop,value){},_notifyPathUpImpl:function(path,value){var dataHost=this.dataHost;var root=Polymer.Path.root(path);dataHost._forwardInstancePath.call(dataHost,\nthis,path,value);if(root in dataHost._parentProps)dataHost._templatized._notifyPath(dataHost._parentPropPrefix+path,value)},_pathEffectorImpl:function(path,value,fromAbove){if(this._forwardParentPath)if(path.indexOf(this._parentPropPrefix)===0){var subPath=path.substring(this._parentPropPrefix.length);var model=Polymer.Path.root(subPath);if(model in this._parentProps)this._forwardParentPath(subPath,value)}Polymer.Base._pathEffector.call(this._templatized,path,value,fromAbove)},_constructorImpl:function(model,\nhost){this._rootDataHost=host._getRootDataHost();this._setupConfigure(model);this._registerHost(host);this._beginHosting();this.root=this.instanceTemplate(this._template);this.root.__noContent=!this._notes._hasContent;this.root.__styleScoped=true;this._endHosting();this._marshalAnnotatedNodes();this._marshalInstanceEffects();this._marshalAnnotatedListeners();var children=[];for(var n=this.root.firstChild;n;n=n.nextSibling){children.push(n);n._templateInstance=this}this._children=children;if(host.__hideTemplateChildren__)this._showHideChildren(true);\nthis._tryReady()},_listenImpl:function(node,eventName,methodName){var model=this;var host=this._rootDataHost;var handler=host._createEventHandler(node,eventName,methodName);var decorated=function(e){e.model=model;handler(e)};host._listen(node,eventName,decorated)},_scopeElementClassImpl:function(node,value){var host=this._rootDataHost;if(host)return host._scopeElementClass(node,value);return value},stamp:function(model){model=model||{};if(this._parentProps){var templatized=this._templatized;for(var prop in this._parentProps)if(model[prop]===\nundefined)model[prop]=templatized[this._parentPropPrefix+prop]}return new this.ctor(model,this)},modelForElement:function(el){var model;while(el)if(model=el._templateInstance)if(model.dataHost!=this)el=model.dataHost;else return model;else el=el.parentNode}};Polymer({is:\"dom-template\",\"extends\":\"template\",_template:null,behaviors:[Polymer.Templatizer],ready:function(){this.templatize(this)}});Polymer._collections=new WeakMap;\nPolymer.Collection=function(userArray){Polymer._collections.set(userArray,this);this.userArray=userArray;this.store=userArray.slice();this.initMap()};\nPolymer.Collection.prototype={constructor:Polymer.Collection,initMap:function(){var omap=this.omap=new WeakMap;var pmap=this.pmap={};var s=this.store;for(var i=0;i<s.length;i++){var item=s[i];if(item&&typeof item==\"object\")omap.set(item,i);else pmap[item]=i}},add:function(item){var key=this.store.push(item)-1;if(item&&typeof item==\"object\")this.omap.set(item,key);else this.pmap[item]=key;return\"#\"+key},removeKey:function(key){if(key=this._parseKey(key)){this._removeFromMap(this.store[key]);delete this.store[key]}},\n_removeFromMap:function(item){if(item&&typeof item==\"object\")this.omap[\"delete\"](item);else delete this.pmap[item]},remove:function(item){var key=this.getKey(item);this.removeKey(key);return key},getKey:function(item){var key;if(item&&typeof item==\"object\")key=this.omap.get(item);else key=this.pmap[item];if(key!=undefined)return\"#\"+key},getKeys:function(){return Object.keys(this.store).map(function(key){return\"#\"+key})},_parseKey:function(key){if(key&&key[0]==\"#\")return key.slice(1)},setItem:function(key,\nitem){if(key=this._parseKey(key)){var old=this.store[key];if(old)this._removeFromMap(old);if(item&&typeof item==\"object\")this.omap.set(item,key);else this.pmap[item]=key;this.store[key]=item}},getItem:function(key){if(key=this._parseKey(key))return this.store[key]},getItems:function(){var items=[],store=this.store;for(var key in store)items.push(store[key]);return items},_applySplices:function(splices){var keyMap={},key;for(var i=0,s;i<splices.length&&(s=splices[i]);i++){s.addedKeys=[];for(var j=\n0;j<s.removed.length;j++){key=this.getKey(s.removed[j]);keyMap[key]=keyMap[key]?null:-1}for(j=0;j<s.addedCount;j++){var item=this.userArray[s.index+j];key=this.getKey(item);key=key===undefined?this.add(item):key;keyMap[key]=keyMap[key]?null:1;s.addedKeys.push(key)}}var removed=[];var added=[];for(key in keyMap){if(keyMap[key]<0){this.removeKey(key);removed.push(key)}if(keyMap[key]>0)added.push(key)}return[{removed:removed,added:added}]}};\nPolymer.Collection.get=function(userArray){return Polymer._collections.get(userArray)||new Polymer.Collection(userArray)};Polymer.Collection.applySplices=function(userArray,splices){var coll=Polymer._collections.get(userArray);return coll?coll._applySplices(splices):null};\nPolymer({is:\"dom-repeat\",\"extends\":\"template\",_template:null,properties:{items:{type:Array},as:{type:String,value:\"item\"},indexAs:{type:String,value:\"index\"},sort:{type:Function,observer:\"_sortChanged\"},filter:{type:Function,observer:\"_filterChanged\"},observe:{type:String,observer:\"_observeChanged\"},delay:Number,renderedItemCount:{type:Number,notify:!Polymer.Settings.suppressTemplateNotifications,readOnly:true},initialCount:{type:Number,observer:\"_initializeChunking\"},targetFramerate:{type:Number,\nvalue:20},notifyDomChange:{type:Boolean},_targetFrameTime:{type:Number,computed:\"_computeFrameTime(targetFramerate)\"}},behaviors:[Polymer.Templatizer],observers:[\"_itemsChanged(items.*)\"],created:function(){this._instances=[];this._pool=[];this._limit=Infinity;var self=this;this._boundRenderChunk=function(){self._renderChunk()}},detached:function(){this.__isDetached=true;for(var i=0;i<this._instances.length;i++)this._detachInstance(i)},attached:function(){if(this.__isDetached){this.__isDetached=false;\nvar parent=Polymer.dom(Polymer.dom(this).parentNode);for(var i=0;i<this._instances.length;i++)this._attachInstance(i,parent)}},ready:function(){this._instanceProps={__key__:true};this._instanceProps[this.as]=true;this._instanceProps[this.indexAs]=true;if(!this.ctor)this.templatize(this)},_sortChanged:function(sort){var dataHost=this._getRootDataHost();this._sortFn=sort&&(typeof sort==\"function\"?sort:function(){return dataHost[sort].apply(dataHost,arguments)});this._needFullRefresh=true;if(this.items)this._debounceTemplate(this._render)},\n_filterChanged:function(filter){var dataHost=this._getRootDataHost();this._filterFn=filter&&(typeof filter==\"function\"?filter:function(){return dataHost[filter].apply(dataHost,arguments)});this._needFullRefresh=true;if(this.items)this._debounceTemplate(this._render)},_computeFrameTime:function(rate){return Math.ceil(1E3/rate)},_initializeChunking:function(){if(this.initialCount){this._limit=this.initialCount;this._chunkCount=this.initialCount;this._lastChunkTime=performance.now()}},_tryRenderChunk:function(){if(this.items&&\nthis._limit<this.items.length)this.debounce(\"renderChunk\",this._requestRenderChunk)},_requestRenderChunk:function(){requestAnimationFrame(this._boundRenderChunk)},_renderChunk:function(){var currChunkTime=performance.now();var ratio=this._targetFrameTime/(currChunkTime-this._lastChunkTime);this._chunkCount=Math.round(this._chunkCount*ratio)||1;this._limit+=this._chunkCount;this._lastChunkTime=currChunkTime;this._debounceTemplate(this._render)},_observeChanged:function(){this._observePaths=this.observe&&\nthis.observe.replace(\".*\",\".\").split(\" \")},_itemsChanged:function(change){if(change.path==\"items\"){if(Array.isArray(this.items))this.collection=Polymer.Collection.get(this.items);else if(!this.items)this.collection=null;else this._error(this._logf(\"dom-repeat\",\"expected array for `items`,\"+\" found\",this.items));this._keySplices=[];this._indexSplices=[];this._needFullRefresh=true;this._initializeChunking();this._debounceTemplate(this._render)}else if(change.path==\"items.splices\"){this._keySplices=\nthis._keySplices.concat(change.value.keySplices);this._indexSplices=this._indexSplices.concat(change.value.indexSplices);this._debounceTemplate(this._render)}else{var subpath=change.path.slice(6);this._forwardItemPath(subpath,change.value);this._checkObservedPaths(subpath)}},_checkObservedPaths:function(path){if(this._observePaths){path=path.substring(path.indexOf(\".\")+1);var paths=this._observePaths;for(var i=0;i<paths.length;i++)if(path.indexOf(paths[i])===0){this._needFullRefresh=true;if(this.delay)this.debounce(\"render\",\nthis._render,this.delay);else this._debounceTemplate(this._render);return}}},render:function(){this._needFullRefresh=true;this._debounceTemplate(this._render);this._flushTemplates()},_render:function(){if(this._needFullRefresh){this._applyFullRefresh();this._needFullRefresh=false}else if(this._keySplices.length)if(this._sortFn)this._applySplicesUserSort(this._keySplices);else if(this._filterFn)this._applyFullRefresh();else this._applySplicesArrayOrder(this._indexSplices);else;this._keySplices=[];\nthis._indexSplices=[];var keyToIdx=this._keyToInstIdx={};for(var i=this._instances.length-1;i>=0;i--){var inst=this._instances[i];if(inst.isPlaceholder&&i<this._limit)inst=this._insertInstance(i,inst.__key__);else if(!inst.isPlaceholder&&i>=this._limit)inst=this._downgradeInstance(i,inst.__key__);keyToIdx[inst.__key__]=i;if(!inst.isPlaceholder)inst.__setProperty(this.indexAs,i,true)}this._pool.length=0;this._setRenderedItemCount(this._instances.length);if(!Polymer.Settings.suppressTemplateNotifications||\nthis.notifyDomChange)this.fire(\"dom-change\");this._tryRenderChunk()},_applyFullRefresh:function(){var c=this.collection;var keys;if(this._sortFn)keys=c?c.getKeys():[];else{keys=[];var items=this.items;if(items)for(var i=0;i<items.length;i++)keys.push(c.getKey(items[i]))}var self=this;if(this._filterFn)keys=keys.filter(function(a){return self._filterFn(c.getItem(a))});if(this._sortFn)keys.sort(function(a,b){return self._sortFn(c.getItem(a),c.getItem(b))});for(i=0;i<keys.length;i++){var key=keys[i];\nvar inst=this._instances[i];if(inst){inst.__key__=key;if(!inst.isPlaceholder&&i<this._limit)inst.__setProperty(this.as,c.getItem(key),true)}else if(i<this._limit)this._insertInstance(i,key);else this._insertPlaceholder(i,key)}for(var j=this._instances.length-1;j>=i;j--)this._detachAndRemoveInstance(j)},_numericSort:function(a,b){return a-b},_applySplicesUserSort:function(splices){var c=this.collection;var keyMap={};var key;for(var i=0,s;i<splices.length&&(s=splices[i]);i++){for(var j=0;j<s.removed.length;j++){key=\ns.removed[j];keyMap[key]=keyMap[key]?null:-1}for(j=0;j<s.added.length;j++){key=s.added[j];keyMap[key]=keyMap[key]?null:1}}var removedIdxs=[];var addedKeys=[];for(key in keyMap){if(keyMap[key]===-1)removedIdxs.push(this._keyToInstIdx[key]);if(keyMap[key]===1)addedKeys.push(key)}if(removedIdxs.length){removedIdxs.sort(this._numericSort);for(i=removedIdxs.length-1;i>=0;i--){var idx=removedIdxs[i];if(idx!==undefined)this._detachAndRemoveInstance(idx)}}var self=this;if(addedKeys.length){if(this._filterFn)addedKeys=\naddedKeys.filter(function(a){return self._filterFn(c.getItem(a))});addedKeys.sort(function(a,b){return self._sortFn(c.getItem(a),c.getItem(b))});var start=0;for(i=0;i<addedKeys.length;i++)start=this._insertRowUserSort(start,addedKeys[i])}},_insertRowUserSort:function(start,key){var c=this.collection;var item=c.getItem(key);var end=this._instances.length-1;var idx=-1;while(start<=end){var mid=start+end>>1;var midKey=this._instances[mid].__key__;var cmp=this._sortFn(c.getItem(midKey),item);if(cmp<0)start=\nmid+1;else if(cmp>0)end=mid-1;else{idx=mid;break}}if(idx<0)idx=end+1;this._insertPlaceholder(idx,key);return idx},_applySplicesArrayOrder:function(splices){for(var i=0,s;i<splices.length&&(s=splices[i]);i++){for(var j=0;j<s.removed.length;j++)this._detachAndRemoveInstance(s.index);for(j=0;j<s.addedKeys.length;j++)this._insertPlaceholder(s.index+j,s.addedKeys[j])}},_detachInstance:function(idx){var inst=this._instances[idx];if(!inst.isPlaceholder){for(var i=0;i<inst._children.length;i++){var el=inst._children[i];\nPolymer.dom(inst.root).appendChild(el)}return inst}},_attachInstance:function(idx,parent){var inst=this._instances[idx];if(!inst.isPlaceholder)parent.insertBefore(inst.root,this)},_detachAndRemoveInstance:function(idx){var inst=this._detachInstance(idx);if(inst)this._pool.push(inst);this._instances.splice(idx,1)},_insertPlaceholder:function(idx,key){this._instances.splice(idx,0,{isPlaceholder:true,__key__:key})},_stampInstance:function(idx,key){var model={__key__:key};model[this.as]=this.collection.getItem(key);\nmodel[this.indexAs]=idx;return this.stamp(model)},_insertInstance:function(idx,key){var inst=this._pool.pop();if(inst){inst.__setProperty(this.as,this.collection.getItem(key),true);inst.__setProperty(\"__key__\",key,true)}else inst=this._stampInstance(idx,key);var beforeRow=this._instances[idx+1];var beforeNode=beforeRow&&!beforeRow.isPlaceholder?beforeRow._children[0]:this;var parentNode=Polymer.dom(this).parentNode;Polymer.dom(parentNode).insertBefore(inst.root,beforeNode);this._instances[idx]=inst;\nreturn inst},_downgradeInstance:function(idx,key){var inst=this._detachInstance(idx);if(inst)this._pool.push(inst);inst={isPlaceholder:true,__key__:key};this._instances[idx]=inst;return inst},_showHideChildren:function(hidden){for(var i=0;i<this._instances.length;i++)if(!this._instances[i].isPlaceholder)this._instances[i]._showHideChildren(hidden)},_forwardInstanceProp:function(inst,prop,value){if(prop==this.as){var idx;if(this._sortFn||this._filterFn)idx=this.items.indexOf(this.collection.getItem(inst.__key__));\nelse idx=inst[this.indexAs];this.set(\"items.\"+idx,value)}},_forwardInstancePath:function(inst,path,value){if(path.indexOf(this.as+\".\")===0)this._notifyPath(\"items.\"+inst.__key__+\".\"+path.slice(this.as.length+1),value)},_forwardParentProp:function(prop,value){var i$=this._instances;for(var i=0,inst;i<i$.length&&(inst=i$[i]);i++)if(!inst.isPlaceholder)inst.__setProperty(prop,value,true)},_forwardParentPath:function(path,value){var i$=this._instances;for(var i=0,inst;i<i$.length&&(inst=i$[i]);i++)if(!inst.isPlaceholder)inst._notifyPath(path,\nvalue,true)},_forwardItemPath:function(path,value){if(this._keyToInstIdx){var dot=path.indexOf(\".\");var key=path.substring(0,dot<0?path.length:dot);var idx=this._keyToInstIdx[key];var inst=this._instances[idx];if(inst&&!inst.isPlaceholder)if(dot>=0){path=this.as+\".\"+path.substring(dot+1);inst._notifyPath(path,value,true)}else inst.__setProperty(this.as,value,true)}},itemForElement:function(el){var instance=this.modelForElement(el);return instance&&instance[this.as]},keyForElement:function(el){var instance=\nthis.modelForElement(el);return instance&&instance.__key__},indexForElement:function(el){var instance=this.modelForElement(el);return instance&&instance[this.indexAs]}});\nPolymer({is:\"array-selector\",_template:null,properties:{items:{type:Array,observer:\"clearSelection\"},multi:{type:Boolean,value:false,observer:\"clearSelection\"},selected:{type:Object,notify:true},selectedItem:{type:Object,notify:true},toggle:{type:Boolean,value:false}},clearSelection:function(){if(Array.isArray(this.selected))for(var i=0;i<this.selected.length;i++)this.unlinkPaths(\"selected.\"+i);else{this.unlinkPaths(\"selected\");this.unlinkPaths(\"selectedItem\")}if(this.multi){if(!this.selected||this.selected.length){this.selected=\n[];this._selectedColl=Polymer.Collection.get(this.selected)}}else{this.selected=null;this._selectedColl=null}this.selectedItem=null},isSelected:function(item){if(this.multi)return this._selectedColl.getKey(item)!==undefined;else return this.selected==item},deselect:function(item){if(this.multi){if(this.isSelected(item)){var skey=this._selectedColl.getKey(item);this.arrayDelete(\"selected\",item);this.unlinkPaths(\"selected.\"+skey)}}else{this.selected=null;this.selectedItem=null;this.unlinkPaths(\"selected\");\nthis.unlinkPaths(\"selectedItem\")}},select:function(item){var icol=Polymer.Collection.get(this.items);var key=icol.getKey(item);if(this.multi)if(this.isSelected(item)){if(this.toggle)this.deselect(item)}else{this.push(\"selected\",item);var skey=this._selectedColl.getKey(item);this.linkPaths(\"selected.\"+skey,\"items.\"+key)}else if(this.toggle&&item==this.selected)this.deselect();else{this.selected=item;this.selectedItem=item;this.linkPaths(\"selected\",\"items.\"+key);this.linkPaths(\"selectedItem\",\"items.\"+\nkey)}}});\nPolymer({is:\"dom-if\",\"extends\":\"template\",_template:null,properties:{\"if\":{type:Boolean,value:false,observer:\"_queueRender\"},restamp:{type:Boolean,value:false,observer:\"_queueRender\"},notifyDomChange:{type:Boolean}},behaviors:[Polymer.Templatizer],_queueRender:function(){this._debounceTemplate(this._render)},detached:function(){if(!this.parentNode||this.parentNode.nodeType==Node.DOCUMENT_FRAGMENT_NODE&&(!Polymer.Settings.hasShadow||!(this.parentNode instanceof ShadowRoot)))this._teardownInstance()},attached:function(){if(this[\"if\"]&&\nthis.ctor)this.async(this._ensureInstance)},render:function(){this._flushTemplates()},_render:function(){if(this[\"if\"]){if(!this.ctor)this.templatize(this);this._ensureInstance();this._showHideChildren()}else if(this.restamp)this._teardownInstance();if(!this.restamp&&this._instance)this._showHideChildren();if(this[\"if\"]!=this._lastIf){if(!Polymer.Settings.suppressTemplateNotifications||this.notifyDomChange)this.fire(\"dom-change\");this._lastIf=this[\"if\"]}},_ensureInstance:function(){var parentNode=\nPolymer.dom(this).parentNode;if(parentNode){var parent=Polymer.dom(parentNode);if(!this._instance){this._instance=this.stamp();var root=this._instance.root;parent.insertBefore(root,this)}else{var c$=this._instance._children;if(c$&&c$.length){var lastChild=Polymer.dom(this).previousSibling;if(lastChild!==c$[c$.length-1])for(var i=0,n;i<c$.length&&(n=c$[i]);i++)parent.insertBefore(n,this)}}}},_teardownInstance:function(){if(this._instance){var c$=this._instance._children;if(c$&&c$.length){var parent=\nPolymer.dom(Polymer.dom(c$[0]).parentNode);for(var i=0,n;i<c$.length&&(n=c$[i]);i++)parent.removeChild(n)}this._instance=null}},_showHideChildren:function(){var hidden=this.__hideTemplateChildren__||!this[\"if\"];if(this._instance)this._instance._showHideChildren(hidden)},_forwardParentProp:function(prop,value){if(this._instance)this._instance.__setProperty(prop,value,true)},_forwardParentPath:function(path,value){if(this._instance)this._instance._notifyPath(path,value,true)}});\nPolymer({is:\"dom-bind\",properties:{notifyDomChange:{type:Boolean}},\"extends\":\"template\",_template:null,created:function(){var self=this;Polymer.RenderStatus.whenReady(function(){if(document.readyState==\"loading\")document.addEventListener(\"DOMContentLoaded\",function(){self._markImportsReady()});else self._markImportsReady()})},_ensureReady:function(){if(!this._readied)this._readySelf()},_markImportsReady:function(){this._importsReady=true;this._ensureReady()},_registerFeatures:function(){this._prepConstructor()},\n_insertChildren:function(){var parentDom=Polymer.dom(Polymer.dom(this).parentNode);parentDom.insertBefore(this.root,this)},_removeChildren:function(){if(this._children)for(var i=0;i<this._children.length;i++)this.root.appendChild(this._children[i])},_initFeatures:function(){},_scopeElementClass:function(element,selector){if(this.dataHost)return this.dataHost._scopeElementClass(element,selector);else return selector},_configureInstanceProperties:function(){},_prepConfigure:function(){var config={};\nfor(var prop in this._propertyEffects)config[prop]=this[prop];var setupConfigure=this._setupConfigure;this._setupConfigure=function(){setupConfigure.call(this,config)}},attached:function(){if(this._importsReady)this.render()},detached:function(){this._removeChildren()},render:function(){this._ensureReady();if(!this._children){this._template=this;this._prepAnnotations();this._prepEffects();this._prepBehaviors();this._prepConfigure();this._prepBindings();this._prepPropertyInfo();Polymer.Base._initFeatures.call(this);\nthis._children=Polymer.TreeApi.arrayCopyChildNodes(this.root)}this._insertChildren();if(!Polymer.Settings.suppressTemplateNotifications||this.notifyDomChange)this.fire(\"dom-change\")}});\n'use strict';var d,f={scope:{},u3:function(a,b,c){if(null==a)throw new TypeError(\"The 'this' value for String.prototype.\"+c+\" must not be null or undefined\");if(b instanceof RegExp)throw new TypeError(\"First argument to String.prototype.\"+c+\" must not be a regular expression\");return a+\"\"}};\nf.defineProperty=\"function\"==typeof Object.defineProperties?Object.defineProperty:function(a,b,c){if(c.get||c.set)throw new TypeError(\"ES3 does not support getters and setters.\");a!=Array.prototype&&a!=Object.prototype&&(a[b]=c.value)};f.KL=function(a){return\"undefined\"!=typeof window&&window===a?a:\"undefined\"!=typeof global&&null!=global?global:a};f.global=f.KL(this);\nf.si=function(a,b){if(b){var c=f.global;a=a.split(\".\");for(var e=0;e<a.length-1;e++){var g=a[e];g in c||(c[g]={});c=c[g]}a=a[a.length-1];e=c[a];b=b(e);b!=e&&null!=b&&f.defineProperty(c,a,{configurable:!0,writable:!0,value:b})}};f.EE=\"jscomp_symbol_\";f.iB=function(){f.iB=function(){};f.global.Symbol||(f.global.Symbol=f.Symbol)};f.mW=0;f.Symbol=function(a){return f.EE+(a||\"\")+f.mW++};\nf.gm=function(){f.iB();var a=f.global.Symbol.iterator;a||(a=f.global.Symbol.iterator=f.global.Symbol(\"iterator\"));\"function\"!=typeof Array.prototype[a]&&f.defineProperty(Array.prototype,a,{configurable:!0,writable:!0,value:function(){return f.Jw(this)}});f.gm=function(){}};f.Jw=function(a){var b=0;return f.MN(function(){return b<a.length?{done:!1,value:a[b++]}:{done:!0}})};f.MN=function(a){f.gm();a={next:a};a[f.global.Symbol.iterator]=function(){return this};return a};f.aa=f.aa||{};\nf.LN=function(a,b){f.gm();a instanceof String&&(a+=\"\");var c=0,e={next:function(){if(c<a.length){var g=c++;return{value:b(g,a[g]),done:!1}}e.next=function(){return{done:!0,value:void 0}};return e.next()}};e[Symbol.iterator]=function(){return e};return e};f.si(\"Array.prototype.entries\",function(a){return a?a:a=function(){return f.LN(this,function(a,c){return[a,c]})}},\"es6-impl\",\"es3\");\nf.si(\"Array.prototype.fill\",function(a){return a?a:a=function(a,c,e){var b=this.length||0;0>c&&(c=Math.max(0,b+c));if(null==e||e>b)e=b;e=Number(e);0>e&&(e=Math.max(0,b+e));for(c=Number(c||0);c<e;c++)this[c]=a;return this}},\"es6-impl\",\"es3\");f.si(\"Math.sign\",function(a){return a?a:a=function(a){a=Number(a);return 0===a||isNaN(a)?a:0<a?1:-1}},\"es6-impl\",\"es3\");f.si(\"Math.log10\",function(a){return a?a:a=function(a){return Math.log(a)/Math.LN10}},\"es6-impl\",\"es3\");\nf.si(\"Math.log2\",function(a){return a?a:a=function(a){return Math.log(a)/Math.LN2}},\"es6-impl\",\"es3\");f.a6=function(a,b,c){a instanceof String&&(a=String(a));for(var e=a.length,g=0;g<e;g++){var k=a[g];if(b.call(c,k,g,a))return{uf:g,Ak:k}}return{uf:-1,Ak:void 0}};f.NO=function(a,b){return Object.prototype.hasOwnProperty.call(a,b)};\nf.si(\"Object.assign\",function(a){return a?a:a=function(a,c){for(var b=1;b<arguments.length;b++){var g=arguments[b];if(g)for(var k in g)f.NO(g,k)&&(a[k]=g[k])}return a}},\"es6-impl\",\"es3\");f.si(\"Array.from\",function(a){return a?a:a=function(a,c,e){f.gm();c=null!=c?c:function(a){return a};var b=[],k=a[Symbol.iterator];if(\"function\"==typeof k)for(a=k.call(a);!(k=a.next()).done;)b.push(c.call(e,k.value));else for(var k=a.length,m=0;m<k;m++)b.push(c.call(e,a[m]));return b}},\"es6-impl\",\"es3\");\nf.IB=function(a){f.gm();var b=a[Symbol.iterator];return b?b.call(a):f.Jw(a)};f.oD=!0;f.wD=!1;\nf.si(\"Promise\",function(a){function b(){this.di=null}if(a&&!f.wD)return a;b.prototype.Mw=function(a){null==this.di&&(this.di=[],this.QJ());this.di.push(a);return this};b.prototype.QJ=function(){var a=this;this.Nw(function(){a.RK()})};var c=f.global.setTimeout;b.prototype.Nw=function(a){c(a,0)};b.prototype.RK=function(){for(;this.di&&this.di.length;){var a=this.di;this.di=[];for(var b=0;b<a.length;++b){var c=a[b];delete a[b];try{c()}catch(v){this.RJ(v)}}}this.di=null};b.prototype.RJ=function(a){this.Nw(function(){throw a;\n})};var e={Ju:0,hu:1,$u:2},g=function(a){this.Bm=e.Ju;this.Fs=void 0;this.nm=[];var b=this.nr();try{a(b.resolve,b.reject)}catch(q){b.reject(q)}};g.prototype.nr=function(){function a(a){return function(e){c||(c=!0,a.call(b,e))}}var b=this,c=!1;return{resolve:a(this.SP),reject:a(this.Cs)}};g.prototype.SP=function(a){if(a===this)this.Cs(new TypeError(\"A Promise cannot resolve to itself\"));else if(a instanceof g)this.TV(a);else{var b;a:switch(typeof a){case \"object\":b=null!=a;break a;case \"function\":b=\n!0;break a;default:b=!1}b?this.RP(a):this.Ix(a)}};g.prototype.RP=function(a){var b=void 0;try{b=a.then}catch(q){this.Cs(q);return}\"function\"==typeof b?this.UV(b,a):this.Ix(a)};g.prototype.Cs=function(a){this.xC(e.$u,a)};g.prototype.Ix=function(a){this.xC(e.hu,a)};g.prototype.xC=function(a,b){if(this.Bm!=e.Ju)throw Error(\"Cannot settle(\"+a+\", \"+b|\"): Promise already settled in state\"+this.Bm);this.Bm=a;this.Fs=b;this.SK()};g.prototype.SK=function(){if(null!=this.nm){for(var a=this.nm,b=0;b<a.length;++b)a[b].call(),\na[b]=null;this.nm=null}};var k=new b;g.prototype.TV=function(a){var b=this.nr();a.co(b.resolve,b.reject)};g.prototype.UV=function(a,b){var c=this.nr();try{a.call(b,c.resolve,c.reject)}catch(v){c.reject(v)}};g.prototype.then=function(a,b){function c(a,b){return\"function\"==typeof a?function(b){try{e(a(b))}catch(K){k(K)}}:b}var e,k,n=new g(function(a,b){e=a;k=b});this.co(c(a,e),c(b,k));return n};g.prototype.catch=function(a){return this.then(void 0,a)};g.prototype.co=function(a,b){function c(){switch(g.Bm){case e.hu:a(g.Fs);\nbreak;case e.$u:b(g.Fs);break;default:throw Error(\"Unexpected state: \"+g.Bm);}}var g=this;null==this.nm?k.Mw(c):this.nm.push(function(){k.Mw(c)})};g.resolve=function(a){return a instanceof g?a:new g(function(b){b(a)})};g.reject=function(a){return new g(function(b,c){c(a)})};g.race=function(a){return new g(function(b,c){for(var e=f.IB(a),k=e.next();!k.done;k=e.next())g.resolve(k.value).co(b,c)})};g.all=function(a){var b=f.IB(a),c=b.next();return c.done?g.resolve([]):new g(function(a,e){function k(b){return function(c){n[b]=\nc;m--;0==m&&a(n)}}var n=[],m=0;do n.push(void 0),m++,g.resolve(c.value).co(k(n.length-1),e),c=b.next();while(!c.done)})};f.oD&&(g.$jscomp$new$AsyncExecutor=function(){return new b});return g},\"es6-impl\",\"es3\");var h=h||{};h.global=this;h.Pe=function(a){return void 0!==a};h.xr=function(a,b,c){a=a.split(\".\");c=c||h.global;a[0]in c||!c.execScript||c.execScript(\"var \"+a[0]);for(var e;a.length&&(e=a.shift());)!a.length&&h.Pe(b)?c[e]=b:c=c[e]&&c[e]!==Object.prototype[e]?c[e]:c[e]={}};\nh.define=function(a,b){h.xr(a,b)};h.Mh=!0;h.yY=\"en\";h.Qp=!0;h.DE=!1;h.$t=!h.Mh;h.bu=!1;h.haa=function(a){if(h.es())throw Error(\"goog.provide can not be used within a goog.module.\");h.hx(a)};h.hx=function(a,b){h.xr(a,b)};h.WE=/^[a-zA-Z_$][a-zA-Z0-9._$]*$/;\nh.module=function(a){if(!h.Hb(a)||!a||-1==a.search(h.WE))throw Error(\"Invalid module identifier\");if(!h.es())throw Error(\"Module \"+a+\" has been loaded incorrectly. Note, modules cannot be loaded as normal scripts. They require some kind of pre-processing step. You're likely trying to load a module via a script tag or as a part of a concatenated bundle without rewriting the module. For more info see: https://github.com/google/closure-library/wiki/goog.module:-an-ES6-module-like-alternative-to-goog.provide.\");if(h.gg.ts)throw Error(\"goog.module may only be called once per module.\");\nh.gg.ts=a};h.module.get=function(){return null};h.module.x6=function(){return null};h.gg=null;h.es=function(){return null!=h.gg};h.module.qr=function(){h.gg.qr=!0};h.wC=function(a){if(h.$t)throw a=a||\"\",Error(\"Importing test-only code into non-debug environment\"+(a?\": \"+a:\".\"));};h.h6=function(){};h.C6=function(a,b){a=a.split(\".\");b=b||h.global;for(var c;c=a.shift();)if(h.Ch(b[c]))b=b[c];else return null;return b};h.M6=function(a,b){b=b||h.global;for(var c in a)b[c]=a[c]};\nh.O1=function(a,b,c,e){if(h.Yt){var g;a=a.replace(/\\\\/g,\"/\");var k=h.dg;e&&\"boolean\"!==typeof e||(e=e?{module:\"goog\"}:{});for(var m=0;g=b[m];m++)k.mm[g]=a,k.ns[a]=e;for(e=0;b=c[e];e++)a in k.qj||(k.qj[a]={}),k.qj[a][b]=!0}};h.rda=!1;h.xX=!0;h.$N=function(a){h.global.console&&h.global.console.error(a)};h.Daa=function(){};h.ci=\"\";h.FO=function(){};h.J1=function(){throw Error(\"unimplemented abstract method\");};\nh.P1=function(a){a.cs=void 0;a.w6=function(){if(a.cs)return a.cs;h.Mh&&(h.lB[h.lB.length]=a);return a.cs=new a}};h.lB=[];h.TD=!0;h.xE=h.Mh;h.ZN={};h.Yt=!1;h.dv=\"detect\";h.IE=\"transpile.js\";\nh.Yt&&(h.dg={ns:{},mm:{},qj:{},MC:{},Gt:{},deferred:{}},h.gB=function(){var a=h.global.document;return null!=a&&\"write\"in a},h.VK=function(){if(h.Pe(h.global.cD))h.ci=h.global.cD;else if(h.gB())for(var a=h.global.document,a=a.getElementsByTagName(\"SCRIPT\"),b=a.length-1;0<=b;--b){var c=a[b],c=c.src,e=c.lastIndexOf(\"?\"),e=-1==e?c.length:e;if(\"base.js\"==c.substr(e-7,7)){h.ci=c.substr(0,e-7);break}}},h.bs=function(a,b){var c=h.global.fX||h.KW;c(a,b)&&(h.dg.Gt[a]=!0)},h.PD=!(h.global.atob||!h.global.document||\n!h.global.document.all),h.dN=function(a,b,c){a='goog.retrieveAndExec_(\"'+a+'\", '+b+\", \"+c+\");\";h.bs(\"\",a)},h.ys=[],h.Ida=function(a,b){return h.TD&&h.Pe(h.global.JSON)?\"goog.loadModule(\"+h.global.JSON.stringify(b+\"\\n//# sourceURL\\x3d\"+a+\"\\n\")+\");\":'goog.loadModule(function(exports) {\"use strict\";'+b+\"\\n;return exports});\\n//# sourceURL\\x3d\"+a+\"\\n\"},h.YN=function(){var a=h.ys.length;if(0<a){var b=h.ys;h.ys=[];for(var c=0;c<a;c++){var e=b[c];h.NB(e)}}},h.E8=function(a){h.pB(a)&&h.GJ(a)&&(a=h.Kr(a),\nh.NB(h.ci+a))},h.pB=function(a){var b=(a=h.Kr(a))&&h.dg.ns[a]||{},c=b.lang||\"es3\";return a&&(\"goog\"==b.module||h.SB(c))?(a=h.ci+a,a in h.dg.deferred):!1},h.GJ=function(a){if((a=h.Kr(a))&&a in h.dg.qj)for(var b in h.dg.qj[a])if(!h.CN(b)&&!h.pB(b))return!1;return!0},h.NB=function(a){if(a in h.dg.deferred){var b=h.dg.deferred[a];delete h.dg.deferred[a];h.globalEval(b)}},h.j8=function(){},h.JW=function(a){h.global.document.write('\\x3cscript type\\x3d\"text/javascript\" src\\x3d\"'+a+'\"\\x3e\\x3c/script\\x3e')},\nh.LJ=function(a){var b=h.global.document,c=b.createElement(\"script\");c.type=\"text/javascript\";c.src=a;c.defer=!1;c.async=!1;b.head.appendChild(c)},h.KW=function(a,b){if(h.gB()){var c=h.global.document;if(!h.bu&&\"complete\"==c.readyState){if(c=/\\bdeps.js$/.test(a))return!1;throw Error('Cannot write \"'+a+'\" after document load');}void 0===b?h.PD?(b=\" onreadystatechange\\x3d'goog.onScriptLoad_(this, \"+ ++h.EB+\")' \",c.write('\\x3cscript type\\x3d\"text/javascript\" src\\x3d\"'+a+'\"'+b+\"\\x3e\\x3c/script\\x3e\")):\nh.bu?h.LJ(a):h.JW(a):c.write('\\x3cscript type\\x3d\"text/javascript\"\\x3e'+h.bP(b)+\"\\x3c/script\\x3e\");return!0}return!1},h.bP=function(a){return a.replace(/<\\/(SCRIPT)/ig,\"\\\\x3c\\\\$1\")},h.SB=function(a){if(\"always\"==h.dv)return!0;if(\"never\"==h.dv)return!1;h.So||(h.So=h.wK());if(a in h.So)return h.So[a];throw Error(\"Unknown language mode: \"+a);},h.So=null,h.EB=0,h.k$=function(a,b){\"complete\"==a.readyState&&h.EB==b&&h.YN();return!0},h.Jda=function(a){function b(a){if(!(a in g.Gt||a in g.MC)){g.MC[a]=!0;\nif(a in g.qj)for(var k in g.qj[a])if(!h.CN(k))if(k in g.mm)b(g.mm[k]);else throw Error(\"Undefined nameToPath for \"+k);a in e||(e[a]=!0,c.push(a))}}var c=[],e={},g=h.dg;b(a);for(a=0;a<c.length;a++){var k=c[a];h.dg.Gt[k]=!0}var m=h.gg;h.gg=null;for(a=0;a<c.length;a++)if(k=c[a]){var n=g.ns[k]||{},q=n.lang||\"es3\",q=h.SB(q);\"goog\"==n.module||q?h.dN(h.ci+k,\"goog\"==n.module,q):h.bs(h.ci+k)}else throw h.gg=m,Error(\"Undefined script input\");h.gg=m},h.Kr=function(a){return a in h.dg.mm?h.dg.mm[a]:null},h.VK(),\nh.global.gX||h.bs(h.ci+\"deps.js\"));h.Vr=null;h.AW=function(){if(null==h.Vr){var a;try{a=!(0,eval)('\"use strict\";let x \\x3d 1; function f() { return typeof x; };f() \\x3d\\x3d \"number\";')}catch(b){a=!1}h.Vr=a}return h.Vr};h.EW=function(a){return\"(function(){\"+a+\"\\n;})();\\n\"};\nh.i8=function(a){var b=h.gg;try{h.gg={ts:void 0,qr:!1};var c;if(h.isFunction(a))c=a.call(void 0,{});else if(h.Hb(a))h.AW()&&(a=h.EW(a)),c=h.XN.call(void 0,a);else throw Error(\"Invalid module definition\");var e=h.gg.ts;if(!h.Hb(e)||!e)throw Error('Invalid module name \"'+e+'\"');h.gg.qr?h.hx(e,c):h.xE&&Object.seal&&\"object\"==typeof c&&null!=c&&Object.seal(c);h.ZN[e]=c}finally{h.gg=b}};h.XN=function(a){var b={};(0,eval)(a);return b};\nh.F9=function(a){a=a.split(\"/\");for(var b=0;b<a.length;)\".\"==a[b]?a.splice(b,1):b&&\"..\"==a[b]&&a[b-1]&&\"..\"!=a[b-1]?a.splice(--b,2):b++;return a.join(\"/\")};h.VN=function(a){if(h.global.eD)return h.global.eD(a);try{var b=new h.global.XMLHttpRequest;b.open(\"get\",a,!1);b.send();return 0==b.status||200==b.status?b.responseText:null}catch(c){return null}};h.Gaa=function(){};\nh.cda=function(a,b){var c=h.global.$jscomp;c||(h.global.$jscomp=c={});var e=c.Bt;if(!e){var g=h.ci+h.IE,k=h.VN(g);if(k){(0,eval)(k+\"\\n//# sourceURL\\x3d\"+g);if(h.global.$gwtExport&&h.global.$gwtExport.$jscomp&&!h.global.$gwtExport.$jscomp.transpile)throw Error('The transpiler did not properly export the \"transpile\" method. $gwtExport: '+JSON.stringify(h.global.$gwtExport));h.global.$jscomp.Bt=h.global.$gwtExport.$jscomp.transpile;c=h.global.$jscomp;e=c.Bt}}if(!e)var m=\" requires transpilation but no transpiler was found.\",\nm=m+' Please add \"//javascript/closure:transpiler\" as a data dependency to ensure it is included.',e=c.Bt=function(a,b){h.$N(b+m);return a};return e(a,b)};\nh.df=function(a){var b=typeof a;if(\"object\"==b)if(a){if(a instanceof Array)return\"array\";if(a instanceof Object)return b;var c=Object.prototype.toString.call(a);if(\"[object Window]\"==c)return\"object\";if(\"[object Array]\"==c||\"number\"==typeof a.length&&\"undefined\"!=typeof a.splice&&\"undefined\"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable(\"splice\"))return\"array\";if(\"[object Function]\"==c||\"undefined\"!=typeof a.call&&\"undefined\"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable(\"call\"))return\"function\"}else return\"null\";\nelse if(\"function\"==b&&\"undefined\"==typeof a.call)return\"object\";return b};h.O7=function(a){return null===a};h.Ch=function(a){return null!=a};h.isArray=function(a){return\"array\"==h.df(a)};h.Gd=function(a){var b=h.df(a);return\"array\"==b||\"object\"==b&&\"number\"==typeof a.length};h.E7=function(a){return h.mj(a)&&\"function\"==typeof a.getFullYear};h.Hb=function(a){return\"string\"==typeof a};h.sk=function(a){return\"boolean\"==typeof a};h.ni=function(a){return\"number\"==typeof a};\nh.isFunction=function(a){return\"function\"==h.df(a)};h.mj=function(a){var b=typeof a;return\"object\"==b&&null!=a||\"function\"==b};h.VA=function(a){return a[h.Ki]||(a[h.Ki]=++h.uW)};h.Q6=function(a){return!!a[h.Ki]};h.yP=function(a){null!==a&&\"removeAttribute\"in a&&a.removeAttribute(h.Ki);try{delete a[h.Ki]}catch(b){}};h.Ki=\"closure_uid_\"+(1E9*Math.random()>>>0);h.uW=0;h.t6=h.VA;h.zaa=h.yP;\nh.gK=function(a){var b=h.df(a);if(\"object\"==b||\"array\"==b){if(a.clone)return a.clone();var b=\"array\"==b?[]:{},c;for(c in a)b[c]=h.gK(a[c]);return b}return a};h.YJ=function(a,b,c){return a.call.apply(a.bind,arguments)};h.XJ=function(a,b,c){if(!a)throw Error();if(2<arguments.length){var e=Array.prototype.slice.call(arguments,2);return function(){var c=Array.prototype.slice.call(arguments);Array.prototype.unshift.apply(c,e);return a.apply(b,c)}}return function(){return a.apply(b,arguments)}};\nh.bind=function(a,b,c){Function.prototype.bind&&-1!=Function.prototype.bind.toString().indexOf(\"native code\")?h.bind=h.YJ:h.bind=h.XJ;return h.bind.apply(null,arguments)};h.xs=function(a,b){var c=Array.prototype.slice.call(arguments,1);return function(){var b=c.slice();b.push.apply(b,arguments);return a.apply(this,b)}};h.mixin=function(a,b){for(var c in b)a[c]=b[c]};h.now=h.Qp&&Date.now||function(){return+new Date};\nh.globalEval=function(a){if(h.global.execScript)h.global.execScript(a,\"JavaScript\");else if(h.global.eval){if(null==h.po)if(h.global.eval(\"var _evalTest_ \\x3d 1;\"),\"undefined\"!=typeof h.global._evalTest_){try{delete h.global._evalTest_}catch(e){}h.po=!0}else h.po=!1;if(h.po)h.global.eval(a);else{var b=h.global.document,c=b.createElement(\"SCRIPT\");c.type=\"text/javascript\";c.defer=!1;c.appendChild(b.createTextNode(a));b.body.appendChild(c);b.body.removeChild(c)}}else throw Error(\"goog.globalEval not available\");\n};h.po=null;h.q6=function(a,b){if(\".\"==String(a).charAt(0))throw Error('className passed in goog.getCssName must not start with \".\". You passed: '+a);var c=function(a){return h.nx[a]||a},e=function(a){a=a.split(\"-\");for(var b=[],e=0;e<a.length;e++)b.push(c(a[e]));return b.join(\"-\")},e=h.nx?\"BY_WHOLE\"==h.zK?c:e:function(a){return a};a=b?a+\"-\"+e(b):e(a);return h.global.dD?h.global.dD(a):a};h.hba=function(a,b){h.nx=a;h.zK=b};\nh.A6=function(a,b){b&&(a=a.replace(/\\{\\$([^}]+)}/g,function(a,e){return null!=b&&e in b?b[e]:a}));return a};h.B6=function(a){return a};h.bc=function(a,b,c){h.xr(a,b,c)};h.Fg=function(a,b,c){a[b]=c};h.da=function(a,b){function c(){}c.prototype=b.prototype;a.ap=b.prototype;a.prototype=new c;a.prototype.constructor=a;a.base=function(a,c,k){for(var e=Array(arguments.length-2),g=2;g<arguments.length;g++)e[g-2]=arguments[g];return b.prototype[c].apply(a,e)}};\nh.base=function(a,b,c){var e=arguments.callee.caller;if(h.DE||h.Mh&&!e)throw Error(\"arguments.caller not defined.  goog.base() cannot be used with strict mode code. See http://www.ecma-international.org/ecma-262/5.1/#sec-C\");if(e.ap){for(var g=Array(arguments.length-1),k=1;k<arguments.length;k++)g[k-1]=arguments[k];return e.ap.constructor.apply(a,g)}g=Array(arguments.length-2);for(k=2;k<arguments.length;k++)g[k-2]=arguments[k];for(var k=!1,m=a.constructor;m;m=m.ap&&m.ap.constructor)if(m.prototype[b]===\ne)k=!0;else if(k)return m.prototype[b].apply(a,g);if(a[b]===e)return a.constructor.prototype[b].apply(a,g);throw Error(\"goog.base called from a method of one name to a method of a different name\");};h.scope=function(a){if(h.es())throw Error(\"goog.scope is not supported within a goog.module.\");a.call(h.global)};\nh.sg=function(a,b){var c=b.constructor,e=b.hW;c&&c!=Object.prototype.constructor||(c=function(){throw Error(\"cannot instantiate an interface (no constructor defined).\");});c=h.sg.xK(c,a);a&&h.da(c,a);delete b.constructor;delete b.hW;h.sg.Hw(c.prototype,b);null!=e&&(e instanceof Function?e(c):h.sg.Hw(c,e));return c};h.sg.wE=h.Mh;\nh.sg.xK=function(a,b){if(!h.sg.wE)return a;var c=!h.sg.HN(b),e=function(){var b=a.apply(this,arguments)||this;b[h.Ki]=b[h.Ki];this.constructor===e&&c&&Object.seal instanceof Function&&Object.seal(b);return b};return e};h.sg.HN=function(a){return a&&a.prototype&&a.prototype[h.PE]};h.sg.Gu=\"constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf\".split(\" \");\nh.sg.Hw=function(a,b){for(var c in b)Object.prototype.hasOwnProperty.call(b,c)&&(a[c]=b[c]);for(var e=0;e<h.sg.Gu.length;e++)c=h.sg.Gu[e],Object.prototype.hasOwnProperty.call(b,c)&&(a[c]=b[c])};h.uca=function(){};h.PE=\"goog_defineClass_legacy_unsealable\";\nh.wK=function(){function a(a,b){e?c[a]=!0:b()?c[a]=!1:e=c[a]=!0}function b(a){try{return!!(0,eval)(a)}catch(k){return!1}}var c={es3:!1},e=!1;a(\"es5\",function(){return b(\"[1,].length\\x3d\\x3d1\")});a(\"es6\",function(){return b('(()\\x3d\\x3e{\"use strict\";class X{constructor(){if(new.target!\\x3dString)throw 1;this.x\\x3d42}}let q\\x3dReflect.construct(X,[],String);if(q.x!\\x3d42||!(q instanceof String))throw 1;for(const a of[2,3]){if(a\\x3d\\x3d2)continue;function f(z\\x3d{a}){let a\\x3d0;return z.a}{function f(){return 0;}}return f()\\x3d\\x3d3}})()')});a(\"es6-impl\",\nfunction(){return!0});a(\"es7\",function(){return b(\"2 ** 2 \\x3d\\x3d 4\")});a(\"es8\",function(){return b(\"async () \\x3d\\x3e 1, true\")});return c};var l={Vb:{}};l.Vb.Ic=function(a,b){this.Zb=a;this.uc=b};d=l.Vb.Ic.prototype;d.hK=function(a){return this.uc<a.uc||this.uc==a.uc&&this.Zb<a.Zb?-1:this.uc==a.uc&&this.Zb==a.Zb?0:1};d.oC=function(){var a=this.uc>>>1,b=this.Zb>>>1|(this.uc&1)<<31;return new l.Vb.Ic(b>>>0,a>>>0)};\nd.FB=function(){var a=this.Zb<<1,b=this.uc<<1|this.Zb>>>31;return new l.Vb.Ic(a>>>0,b>>>0)};d.yO=function(){return!!(this.uc&2147483648)};d.zero=function(){return 0==this.Zb&&0==this.uc};d.add=function(a){var b=(this.Zb+a.Zb&4294967295)>>>0;a=((this.uc+a.uc&4294967295)>>>0)+(4294967296<=this.Zb+a.Zb?1:0);return new l.Vb.Ic(b>>>0,a>>>0)};d.sub=function(a){var b=(this.Zb-a.Zb&4294967295)>>>0;a=((this.uc-a.uc&4294967295)>>>0)-(0>this.Zb-a.Zb?1:0);return new l.Vb.Ic(b>>>0,a>>>0)};\nl.Vb.Ic.RB=function(a,b){var c=a&65535;a>>>=16;var e=b&65535,g=b>>>16;b=c*e+65536*(c*g&65535)+65536*(a*e&65535);for(c=a*g+(c*g>>>16)+(a*e>>>16);4294967296<=b;)b-=4294967296,c+=1;return new l.Vb.Ic(b>>>0,c>>>0)};l.Vb.Ic.prototype.zO=function(a){var b=l.Vb.Ic.RB(this.Zb,a);a=l.Vb.Ic.RB(this.uc,a);a.uc=a.Zb;a.Zb=0;return b.add(a)};\nl.Vb.Ic.prototype.OK=function(a){if(0==a)return[];for(var b=new l.Vb.Ic(0,0),c=new l.Vb.Ic(this.Zb,this.uc),e=new l.Vb.Ic(a,0),g=new l.Vb.Ic(1,0);!e.yO();)e=e.FB(),g=g.FB();for(;!g.zero();)0>=e.hK(c)&&(b=b.add(g),c=c.sub(e)),e=e.oC(),g=g.oC();return[b,c]};l.Vb.Ic.prototype.toString=function(){for(var a=\"\",b=this;!b.zero();)var c=b.OK(10),b=c[0],c=c[1],a=c.Zb+a;\"\"==a&&(a=\"0\");return a};\nl.Vb.Ic.Hx=function(a){for(var b=new l.Vb.Ic(0,0),c=new l.Vb.Ic(0,0),e=0;e<a.length;e++){if(\"0\">a[e]||\"9\"<a[e])return null;var g=parseInt(a[e],10);c.Zb=g;b=b.zO(10).add(c)}return b};l.Vb.Ic.prototype.clone=function(){return new l.Vb.Ic(this.Zb,this.uc)};l.Vb.lh=function(a,b){this.Zb=a;this.uc=b};l.Vb.lh.prototype.add=function(a){var b=(this.Zb+a.Zb&4294967295)>>>0;a=((this.uc+a.uc&4294967295)>>>0)+(4294967296<=this.Zb+a.Zb?1:0);return new l.Vb.lh(b>>>0,a>>>0)};\nl.Vb.lh.prototype.sub=function(a){var b=(this.Zb-a.Zb&4294967295)>>>0;a=((this.uc-a.uc&4294967295)>>>0)-(0>this.Zb-a.Zb?1:0);return new l.Vb.lh(b>>>0,a>>>0)};l.Vb.lh.prototype.clone=function(){return new l.Vb.lh(this.Zb,this.uc)};l.Vb.lh.prototype.toString=function(){var a=0!=(this.uc&2147483648),b=new l.Vb.Ic(this.Zb,this.uc);a&&(b=(new l.Vb.Ic(0,0)).sub(b));return(a?\"-\":\"\")+b.toString()};\nl.Vb.lh.Hx=function(a){var b=0<a.length&&\"-\"==a[0];b&&(a=a.substring(1));a=l.Vb.Ic.Hx(a);if(null===a)return null;b&&(a=(new l.Vb.Ic(0,0)).sub(a));return new l.Vb.lh(a.Zb,a.uc)};l.xa={};l.oX=function(){};l.aX=function(){};l.xa.yD={Gj:-1,kD:1,FLOAT:2,MD:3,NE:4,LD:5,ih:6,hh:7,BOOL:8,Uk:9,WX:10,WD:11,XC:12,ME:13,nD:14,yE:15,zE:16,AE:17,BE:18,pD:30,XE:31};l.xa.kb={Gj:-1,Xe:0,ih:1,jg:2,Tk:3,Jk:4,hh:5};\nl.xa.UX=function(a){var b=l.xa.yD,c=l.xa.kb;switch(a){case b.LD:case b.MD:case b.ME:case b.NE:case b.AE:case b.BE:case b.BOOL:case b.nD:case b.XE:return c.Xe;case b.kD:case b.ih:case b.zE:case b.pD:return c.ih;case b.Uk:case b.WD:case b.XC:return c.jg;case b.FLOAT:case b.hh:case b.yE:return c.hh;default:return c.Gj}};l.xa.Tm=-1;l.xa.PX=1.401298464324817E-45;l.xa.sD=1.1754943508222875E-38;l.xa.vp=3.4028234663852886E38;l.xa.QX=4.9E-324;l.xa.tD=2.2250738585072014E-308;l.xa.wp=1.7976931348623157E308;\nl.xa.JE=1048576;l.xa.KE=8388608;l.xa.Tg=2147483648;l.xa.Xf=4294967296;l.xa.ev=4503599627370496;l.xa.Mj=0x7fffffffffffffff;l.xa.Rp=1.8446744073709552E19;l.xa.z_=\"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\";h.debug={};h.debug.Error=function(a){if(Error.captureStackTrace)Error.captureStackTrace(this,h.debug.Error);else{var b=Error().stack;b&&(this.stack=b)}a&&(this.message=String(a))};h.da(h.debug.Error,Error);h.debug.Error.prototype.name=\"CustomError\";h.dom={};\nh.dom.dE={mD:1,VW:2,e_:3,bX:4,zX:5,yX:6,jZ:7,hX:8,qX:9,sX:10,rX:11,TY:12};h.json={};h.json.Tp=!1;h.json.IN=function(a){if(/^\\s*$/.test(a))return!1;var b=/\\\\[\"\\\\\\/bfnrtu]/g,c=/(?:\"[^\"\\\\\\n\\r\\u2028\\u2029\\x00-\\x08\\x0a-\\x1f]*\"|true|false|null|-?\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d+)?)[\\s\\u2028\\u2029]*(?=:|,|]|}|$)/g,e=/(?:^|:|,)(?:[\\s\\u2028\\u2029]*\\[)+/g,g=/^[\\],:{}\\s\\u2028\\u2029]*$/;return g.test(a.replace(b,\"@\").replace(c,\"]\").replace(e,\"\"))};\nh.json.parse=h.json.Tp?h.global.JSON.parse:function(a){a=String(a);if(h.json.IN(a))try{return(0,eval)(\"(\"+a+\")\")}catch(b){}throw Error(\"Invalid JSON string: \"+a);};h.json.yW=h.json.Tp?h.global.JSON.parse:function(a){return(0,eval)(\"(\"+a+\")\")};h.json.serialize=h.json.Tp?h.global.JSON.stringify:function(a,b){return(new h.json.pg(b)).serialize(a)};h.json.pg=function(a){this.Ro=a};h.json.pg.prototype.serialize=function(a){var b=[];this.Is(a,b);return b.join(\"\")};\nh.json.pg.prototype.Is=function(a,b){if(null==a)b.push(\"null\");else{if(\"object\"==typeof a){if(h.isArray(a)){this.serializeArray(a,b);return}if(a instanceof String||a instanceof Number||a instanceof Boolean)a=a.valueOf();else{this.ZP(a,b);return}}switch(typeof a){case \"string\":this.tC(a,b);break;case \"number\":this.YP(a,b);break;case \"boolean\":b.push(String(a));break;case \"function\":b.push(\"null\");break;default:throw Error(\"Unknown type: \"+typeof a);}}};\nh.json.pg.Zw={'\"':'\\\\\"',\"\\\\\":\"\\\\\\\\\",\"/\":\"\\\\/\",\"\\b\":\"\\\\b\",\"\\f\":\"\\\\f\",\"\\n\":\"\\\\n\",\"\\r\":\"\\\\r\",\"\\t\":\"\\\\t\",\"\\x0B\":\"\\\\u000b\"};h.json.pg.fK=/\\uffff/.test(\"\\uffff\")?/[\\\\\\\"\\x00-\\x1f\\x7f-\\uffff]/g:/[\\\\\\\"\\x00-\\x1f\\x7f-\\xff]/g;h.json.pg.prototype.tC=function(a,b){b.push('\"',a.replace(h.json.pg.fK,function(a){var b=h.json.pg.Zw[a];b||(b=\"\\\\u\"+(a.charCodeAt(0)|65536).toString(16).substr(1),h.json.pg.Zw[a]=b);return b}),'\"')};h.json.pg.prototype.YP=function(a,b){b.push(isFinite(a)&&!isNaN(a)?String(a):\"null\")};\nh.json.pg.prototype.serializeArray=function(a,b){var c=a.length;b.push(\"[\");for(var e=\"\",g=0;g<c;g++)b.push(e),e=a[g],this.Is(this.Ro?this.Ro.call(a,String(g),e):e,b),e=\",\";b.push(\"]\")};h.json.pg.prototype.ZP=function(a,b){b.push(\"{\");var c=\"\",e;for(e in a)if(Object.prototype.hasOwnProperty.call(a,e)){var g=a[e];\"function\"!=typeof g&&(b.push(c),this.tC(e,b),b.push(\":\"),this.Is(this.Ro?this.Ro.call(a,e,g):g,b),c=\",\")}b.push(\"}\")};h.object={};\nh.object.is=function(a,b){return a===b?0!==a||1/a===1/b:a!==a&&b!==b};h.object.forEach=function(a,b,c){for(var e in a)b.call(c,a[e],e,a)};h.object.filter=function(a,b,c){var e={},g;for(g in a)b.call(c,a[g],g,a)&&(e[g]=a[g]);return e};h.object.map=function(a,b,c){var e={},g;for(g in a)e[g]=b.call(c,a[g],g,a);return e};h.object.some=function(a,b,c){for(var e in a)if(b.call(c,a[e],e,a))return!0;return!1};h.object.every=function(a,b,c){for(var e in a)if(!b.call(c,a[e],e,a))return!1;return!0};\nh.object.zh=function(a){var b=0,c;for(c in a)b++;return b};h.object.o6=function(a){for(var b in a)return b};h.object.p6=function(a){for(var b in a)return a[b]};h.object.contains=function(a,b){return h.object.ej(a,b)};h.object.Lc=function(a){var b=[],c=0,e;for(e in a)b[c++]=a[e];return b};h.object.getKeys=function(a){var b=[],c=0,e;for(e in a)b[c++]=e;return b};h.object.L6=function(a,b){for(var c=h.Gd(b),e=c?b:arguments,c=c?0:1;c<e.length&&(a=a[e[c]],h.Pe(a));c++);return a};\nh.object.dj=function(a,b){return null!==a&&b in a};h.object.ej=function(a,b){for(var c in a)if(a[c]==b)return!0;return!1};h.object.XK=function(a,b,c){for(var e in a)if(b.call(c,a[e],e,a))return e};h.object.c6=function(a,b,c){return(b=h.object.XK(a,b,c))&&a[b]};h.object.Zc=function(a){for(var b in a)return!1;return!0};h.object.clear=function(a){for(var b in a)delete a[b]};h.object.remove=function(a,b){var c;(c=b in a)&&delete a[b];return c};\nh.object.add=function(a,b,c){if(null!==a&&b in a)throw Error('The object already contains the key \"'+b+'\"');h.object.set(a,b,c)};h.object.get=function(a,b,c){return null!==a&&b in a?a[b]:c};h.object.set=function(a,b,c){a[b]=c};h.object.kba=function(a,b,c){return b in a?a[b]:a[b]=c};h.object.mba=function(a,b,c){if(b in a)return a[b];c=c();return a[b]=c};h.object.ii=function(a,b){for(var c in a)if(!(c in b)||a[c]!==b[c])return!1;for(c in b)if(!(c in a))return!1;return!0};\nh.object.clone=function(a){var b={},c;for(c in a)b[c]=a[c];return b};h.object.xW=function(a){var b=h.df(a);if(\"object\"==b||\"array\"==b){if(h.isFunction(a.clone))return a.clone();var b=\"array\"==b?[]:{},c;for(c in a)b[c]=h.object.xW(a[c]);return b}return a};h.object.transpose=function(a){var b={},c;for(c in a)b[a[c]]=c;return b};h.object.Ku=\"constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf\".split(\" \");\nh.object.extend=function(a,b){for(var c,e,g=1;g<arguments.length;g++){e=arguments[g];for(c in e)a[c]=e[c];for(var k=0;k<h.object.Ku.length;k++)c=h.object.Ku[k],Object.prototype.hasOwnProperty.call(e,c)&&(a[c]=e[c])}};h.object.create=function(a){var b=arguments.length;if(1==b&&h.isArray(arguments[0]))return h.object.create.apply(null,arguments[0]);if(b%2)throw Error(\"Uneven number of arguments\");for(var c={},e=0;e<b;e+=2)c[arguments[e]]=arguments[e+1];return c};\nh.object.yK=function(a){var b=arguments.length;if(1==b&&h.isArray(arguments[0]))return h.object.yK.apply(null,arguments[0]);for(var c={},e=0;e<b;e++)c[arguments[e]]=!0;return c};h.object.x4=function(a){var b=a;Object.isFrozen&&!Object.isFrozen(a)&&(b=Object.create(a),Object.freeze(b));return b};h.object.K7=function(a){return!!Object.isFrozen&&Object.isFrozen(a)};\nh.object.n6=function(a,b){if(!a)return[];if(!Object.getOwnPropertyNames||!Object.getPrototypeOf)return h.object.getKeys(a);for(var c={};a&&(a!==Object.prototype||b);){for(var e=Object.getOwnPropertyNames(a),g=0;g<e.length;g++)c[e[g]]=!0;a=Object.getPrototypeOf(a)}return h.object.getKeys(c)};h.Ih={};h.Ih.object=function(a,b){return b};h.Ih.st=function(a){h.Ih.st[\" \"](a);return a};h.Ih.st[\" \"]=h.FO;h.Ih.b3=function(a,b){try{return h.Ih.st(a[b]),!0}catch(c){}return!1};\nh.Ih.cache=function(a,b,c,e){e=e?e(b):b;return Object.prototype.hasOwnProperty.call(a,e)?a[e]:a[e]=c(b)};h.ca={};h.ca.qp=!1;h.ca.vD=!1;h.ca.QE={ZD:\"\\u00a0\"};h.ca.startsWith=function(a,b){return 0==a.lastIndexOf(b,0)};h.ca.endsWith=function(a,b){var c=a.length-b.length;return 0<=c&&a.indexOf(b,c)==c};h.ca.l3=function(a,b){return 0==h.ca.Yw(b,a.substr(0,b.length))};h.ca.i3=function(a,b){return 0==h.ca.Yw(b,a.substr(a.length-b.length,b.length))};h.ca.j3=function(a,b){return a.toLowerCase()==b.toLowerCase()};\nh.ca.kW=function(a,b){for(var c=a.split(\"%s\"),e=\"\",g=Array.prototype.slice.call(arguments,1);g.length&&1<c.length;)e+=c.shift()+g.shift();return e+c.join(\"%s\")};h.ca.z3=function(a){return a.replace(/[\\s\\xa0]+/g,\" \").replace(/^\\s+|\\s+$/g,\"\")};h.ca.Co=function(a){return/^[\\s\\xa0]*$/.test(a)};h.ca.I7=function(a){return 0==a.length};h.ca.Zc=h.ca.Co;h.ca.rN=function(a){return h.ca.Co(h.ca.bO(a))};h.ca.H7=h.ca.rN;h.ca.C7=function(a){return!/[^\\t\\n\\r ]/.test(a)};h.ca.A7=function(a){return!/[^a-zA-Z]/.test(a)};\nh.ca.isNumeric=function(a){return!/[^0-9]/.test(a)};h.ca.B7=function(a){return!/[^a-zA-Z0-9]/.test(a)};h.ca.Q7=function(a){return\" \"==a};h.ca.S7=function(a){return 1==a.length&&\" \"<=a&&\"~\">=a||\"\\u0080\"<=a&&\"\\ufffd\">=a};h.ca.dca=function(a){return a.replace(/(\\r\\n|\\r|\\n)+/g,\" \")};h.ca.g3=function(a){return a.replace(/(\\r\\n|\\r|\\n)/g,\"\\n\")};h.ca.H9=function(a){return a.replace(/\\xa0|\\s/g,\" \")};h.ca.G9=function(a){return a.replace(/\\xa0|[ \\t]+/g,\" \")};\nh.ca.y3=function(a){return a.replace(/[\\t\\r\\n ]+/g,\" \").replace(/^[\\t\\r\\n ]+|[\\t\\r\\n ]+$/g,\"\")};h.ca.trim=h.Qp&&String.prototype.trim?function(a){return a.trim()}:function(a){return a.replace(/^[\\s\\xa0]+|[\\s\\xa0]+$/g,\"\")};h.ca.trimLeft=function(a){return a.replace(/^[\\s\\xa0]+/,\"\")};h.ca.trimRight=function(a){return a.replace(/[\\s\\xa0]+$/,\"\")};h.ca.Yw=function(a,b){a=String(a).toLowerCase();b=String(b).toLowerCase();return a<b?-1:a==b?0:1};\nh.ca.UB=function(a,b,c){if(a==b)return 0;if(!a)return-1;if(!b)return 1;for(var e=a.toLowerCase().match(c),g=b.toLowerCase().match(c),k=Math.min(e.length,g.length),m=0;m<k;m++){c=e[m];var n=g[m];if(c!=n)return a=parseInt(c,10),!isNaN(a)&&(b=parseInt(n,10),!isNaN(b)&&a-b)?a-b:c<n?-1:1}return e.length!=g.length?e.length-g.length:a<b?-1:1};h.ca.x7=function(a,b){return h.ca.UB(a,b,/\\d+|\\D+/g)};h.ca.$K=function(a,b){return h.ca.UB(a,b,/\\d+|\\.\\d+|\\D+/g)};h.ca.Z9=h.ca.$K;h.ca.Hm=function(a){return encodeURIComponent(String(a))};\nh.ca.ep=function(a){return decodeURIComponent(a.replace(/\\+/g,\" \"))};h.ca.AO=function(a,b){return a.replace(/(\\r\\n|\\r|\\n)/g,b?\"\\x3cbr /\\x3e\":\"\\x3cbr\\x3e\")};\nh.ca.$r=function(a,b){if(b)a=a.replace(h.ca.It,\"\\x26amp;\").replace(h.ca.Au,\"\\x26lt;\").replace(h.ca.ju,\"\\x26gt;\").replace(h.ca.Yu,\"\\x26quot;\").replace(h.ca.av,\"\\x26#39;\").replace(h.ca.Du,\"\\x26#0;\"),h.ca.qp&&(a=a.replace(h.ca.eu,\"\\x26#101;\"));else{if(!h.ca.SC.test(a))return a;-1!=a.indexOf(\"\\x26\")&&(a=a.replace(h.ca.It,\"\\x26amp;\"));-1!=a.indexOf(\"\\x3c\")&&(a=a.replace(h.ca.Au,\"\\x26lt;\"));-1!=a.indexOf(\"\\x3e\")&&(a=a.replace(h.ca.ju,\"\\x26gt;\"));-1!=a.indexOf('\"')&&(a=a.replace(h.ca.Yu,\"\\x26quot;\"));-1!=\na.indexOf(\"'\")&&(a=a.replace(h.ca.av,\"\\x26#39;\"));-1!=a.indexOf(\"\\x00\")&&(a=a.replace(h.ca.Du,\"\\x26#0;\"));h.ca.qp&&-1!=a.indexOf(\"e\")&&(a=a.replace(h.ca.eu,\"\\x26#101;\"))}return a};h.ca.It=/&/g;h.ca.Au=/</g;h.ca.ju=/>/g;h.ca.Yu=/\"/g;h.ca.av=/'/g;h.ca.Du=/\\x00/g;h.ca.eu=/e/g;h.ca.SC=h.ca.qp?/[\\x00&<>\"'e]/:/[\\x00&<>\"']/;h.ca.IC=function(a){return h.ca.contains(a,\"\\x26\")?!h.ca.vD&&\"document\"in h.global?h.ca.JC(a):h.ca.vW(a):a};h.ca.kda=function(a,b){return h.ca.contains(a,\"\\x26\")?h.ca.JC(a,b):a};\nh.ca.JC=function(a,b){var c={\"\\x26amp;\":\"\\x26\",\"\\x26lt;\":\"\\x3c\",\"\\x26gt;\":\"\\x3e\",\"\\x26quot;\":'\"'},e;e=b?b.createElement(\"div\"):h.global.document.createElement(\"div\");return a.replace(h.ca.HD,function(a,b){var g=c[a];if(g)return g;\"#\"==b.charAt(0)&&(b=Number(\"0\"+b.substr(1)),isNaN(b)||(g=String.fromCharCode(b)));g||(e.innerHTML=a+\" \",g=e.firstChild.nodeValue.slice(0,-1));return c[a]=g})};\nh.ca.vW=function(a){return a.replace(/&([^;]+);/g,function(a,c){switch(c){case \"amp\":return\"\\x26\";case \"lt\":return\"\\x3c\";case \"gt\":return\"\\x3e\";case \"quot\":return'\"';default:return\"#\"!=c.charAt(0)||(c=Number(\"0\"+c.substr(1)),isNaN(c))?a:String.fromCharCode(c)}})};h.ca.HD=/&([^;\\s<&]+);?/g;h.ca.Fda=function(a,b){return h.ca.AO(a.replace(/  /g,\" \\x26#160;\"),b)};h.ca.eaa=function(a){return a.replace(/(^|[\\n ]) /g,\"$1\"+h.ca.QE.ZD)};\nh.ca.eca=function(a,b){for(var c=b.length,e=0;e<c;e++){var g=1==c?b:b.charAt(e);if(a.charAt(0)==g&&a.charAt(a.length-1)==g)return a.substring(1,a.length-1)}return a};h.ca.truncate=function(a,b,c){c&&(a=h.ca.IC(a));a.length>b&&(a=a.substring(0,b-3)+\"...\");c&&(a=h.ca.$r(a));return a};\nh.ca.ida=function(a,b,c,e){c&&(a=h.ca.IC(a));if(e&&a.length>b){e>b&&(e=b);var g=a.length-e;b-=e;a=a.substring(0,b)+\"...\"+a.substring(g)}else a.length>b&&(g=Math.floor(b/2),e=a.length-g,g+=b%2,a=a.substring(0,g)+\"...\"+a.substring(e));c&&(a=h.ca.$r(a));return a};h.ca.tt={\"\\x00\":\"\\\\0\",\"\\b\":\"\\\\b\",\"\\f\":\"\\\\f\",\"\\n\":\"\\\\n\",\"\\r\":\"\\\\r\",\"\\t\":\"\\\\t\",\"\\x0B\":\"\\\\x0B\",'\"':'\\\\\"',\"\\\\\":\"\\\\\\\\\",\"\\x3c\":\"\\x3c\"};h.ca.Fo={\"'\":\"\\\\'\"};\nh.ca.quote=function(a){a=String(a);for(var b=['\"'],c=0;c<a.length;c++){var e=a.charAt(c),g=e.charCodeAt(0);b[c+1]=h.ca.tt[e]||(31<g&&127>g?e:h.ca.Ax(e))}b.push('\"');return b.join(\"\")};h.ca.w5=function(a){for(var b=[],c=0;c<a.length;c++)b[c]=h.ca.Ax(a.charAt(c));return b.join(\"\")};\nh.ca.Ax=function(a){if(a in h.ca.Fo)return h.ca.Fo[a];if(a in h.ca.tt)return h.ca.Fo[a]=h.ca.tt[a];var b,c=a.charCodeAt(0);if(31<c&&127>c)b=a;else{if(256>c){if(b=\"\\\\x\",16>c||256<c)b+=\"0\"}else b=\"\\\\u\",4096>c&&(b+=\"0\");b+=c.toString(16).toUpperCase()}return h.ca.Fo[a]=b};h.ca.contains=function(a,b){return-1!=a.indexOf(b)};h.ca.dK=function(a,b){return h.ca.contains(a.toLowerCase(),b.toLowerCase())};h.ca.p4=function(a,b){return a&&b?a.split(b).length-1:0};\nh.ca.xk=function(a,b,c){var e=a;0<=b&&b<a.length&&0<c&&(e=a.substr(0,b)+a.substr(b+c,a.length-b-c));return e};h.ca.remove=function(a,b){return a.replace(b,\"\")};h.ca.removeAll=function(a,b){b=new RegExp(h.ca.Bs(b),\"g\");return a.replace(b,\"\")};h.ca.replaceAll=function(a,b,c){b=new RegExp(h.ca.Bs(b),\"g\");return a.replace(b,c.replace(/\\$/g,\"$$$$\"))};h.ca.Bs=function(a){return String(a).replace(/([-()\\[\\]{}+?*.$\\^|,:#<!\\\\])/g,\"\\\\$1\").replace(/\\x08/g,\"\\\\x08\")};\nh.ca.repeat=String.prototype.repeat?function(a,b){return a.repeat(b)}:function(a,b){return Array(b+1).join(a)};h.ca.o$=function(a,b,c){a=h.Pe(c)?a.toFixed(c):String(a);c=a.indexOf(\".\");-1==c&&(c=a.length);return h.ca.repeat(\"0\",Math.max(0,b-c))+a};h.ca.bO=function(a){return null==a?\"\":String(a)};h.ca.ZJ=function(a){return Array.prototype.join.call(arguments,\"\")};h.ca.eA=function(){return Math.floor(2147483648*Math.random()).toString(36)+Math.abs(Math.floor(2147483648*Math.random())^h.now()).toString(36)};\nh.ca.yl=function(a,b){var c=0;a=h.ca.trim(String(a)).split(\".\");b=h.ca.trim(String(b)).split(\".\");for(var e=Math.max(a.length,b.length),g=0;0==c&&g<e;g++){var k=a[g]||\"\",m=b[g]||\"\";do{k=/(\\d*)(\\D*)(.*)/.exec(k)||[\"\",\"\",\"\",\"\"];m=/(\\d*)(\\D*)(.*)/.exec(m)||[\"\",\"\",\"\",\"\"];if(0==k[0].length&&0==m[0].length)break;var c=0==k[1].length?0:parseInt(k[1],10),n=0==m[1].length?0:parseInt(m[1],10),c=h.ca.jr(c,n)||h.ca.jr(0==k[2].length,0==m[2].length)||h.ca.jr(k[2],m[2]),k=k[3],m=m[3]}while(0==c)}return c};\nh.ca.jr=function(a,b){return a<b?-1:a>b?1:0};h.ca.U6=function(a){for(var b=0,c=0;c<a.length;++c)b=31*b+a.charCodeAt(c)>>>0;return b};h.ca.wW=2147483648*Math.random()|0;h.ca.z4=function(){return\"goog_\"+h.ca.wW++};h.ca.Dca=function(a){var b=Number(a);return 0==b&&h.ca.Co(a)?NaN:b};h.ca.M7=function(a){return/^[a-z]+([A-Z][a-z]*)*$/.test(a)};h.ca.T7=function(a){return/^([A-Z][a-z]*)+$/.test(a)};h.ca.Bca=function(a){return String(a).replace(/\\-([a-z])/g,function(a,c){return c.toUpperCase()})};\nh.ca.Eca=function(a){return String(a).replace(/([A-Z])/g,\"-$1\").toLowerCase()};h.ca.Fca=function(a,b){b=(b=h.Hb(b)?h.ca.Bs(b):\"\\\\s\")?\"|[\"+b+\"]+\":\"\";b=new RegExp(\"(^\"+b+\")([a-z])\",\"g\");return a.replace(b,function(a,b,g){return b+g.toUpperCase()})};h.ca.h3=function(a){return String(a.charAt(0)).toUpperCase()+String(a.substr(1)).toLowerCase()};h.ca.parseInt=function(a){isFinite(a)&&(a=String(a));return h.Hb(a)?/^\\s*-?0x/i.test(a)?parseInt(a,16):parseInt(a,10):NaN};\nh.ca.Hba=function(a,b,c){a=a.split(b);for(var e=[];0<c&&a.length;)e.push(a.shift()),c--;a.length&&e.push(a.join(b));return e};h.ca.e8=function(a,b){if(b)\"string\"==typeof b&&(b=[b]);else return a;for(var c=-1,e=0;e<b.length;e++)if(\"\"!=b[e]){var g=a.lastIndexOf(b[e]);g>c&&(c=g)}return-1==c?a:a.slice(c+1)};\nh.ca.l5=function(a,b){var c=[],e=[];if(a==b)return 0;if(!a.length||!b.length)return Math.max(a.length,b.length);for(var g=0;g<b.length+1;g++)c[g]=g;for(g=0;g<a.length;g++){e[0]=g+1;for(var k=0;k<b.length;k++){var m=Number(a[g]!=b[k]);e[k+1]=Math.min(e[k]+1,c[k+1]+1,c[k]+m)}for(k=0;k<c.length;k++)c[k]=e[k]}return e[b.length]};var d3={};\n(function(){function a(a){return function(b,c){return Eb(a(b),c)}}function b(a,b,c){var p=Math.abs(b-a)/Math.max(0,c);c=Math.pow(10,Math.floor(Math.log(p)/Math.LN10));p/=c;p>=pm?c*=10:p>=qm?c*=5:p>=rm&&(c*=2);return b<a?-c:c}function c(a){return a.length}function e(a,b,c){a=a(c);return\"translate(\"+(isFinite(a)?a:b(c))+\",0)\"}function g(a,b,c){a=a(c);return\"translate(0,\"+(isFinite(a)?a:b(c))+\")\"}function k(a){var b=a.bandwidth()/2;a.round()&&(b=Math.round(b));return function(c){return a(c)+b}}function m(){return!this.Vp}\nfunction n(a,b){function c(c){var z=null==t?b.ticks?b.ticks.apply(b,p):b.domain():t,I=null==R?b.tickFormat?b.tickFormat.apply(b,p):yh:R,r=Math.max(da,0)+n,P=1===a||3===a?e:g,H=b.range(),F=H[0]+.5,H=H[H.length-1]+.5,ca=(b.bandwidth?k:yh)(b.copy()),qa=c.selection?c.selection():c,T=qa.selectAll(\".domain\").data([null]),z=qa.selectAll(\".tick\").data(z,b).order(),A=z.exit(),L=z.enter().append(\"g\").attr(\"class\",\"tick\"),ja=z.select(\"line\"),M=z.select(\"text\"),G=1===a||4===a?-1:1,fa,Y=4===a||2===a?(fa=\"x\",\"y\"):\n(fa=\"y\",\"x\"),T=T.merge(T.enter().insert(\"path\",\".tick\").attr(\"class\",\"domain\").attr(\"stroke\",\"#000\")),z=z.merge(L),ja=ja.merge(L.append(\"line\").attr(\"stroke\",\"#000\").attr(fa+\"2\",G*da).attr(Y+\"1\",.5).attr(Y+\"2\",.5)),M=M.merge(L.append(\"text\").attr(\"fill\",\"#000\").attr(fa,G*r).attr(Y,.5).attr(\"dy\",1===a?\"0em\":3===a?\"0.71em\":\"0.32em\"));c!==qa&&(T=T.transition(c),z=z.transition(c),ja=ja.transition(c),M=M.transition(c),A=A.transition(c).attr(\"opacity\",1E-6).attr(\"transform\",function(a){return P(ca,this.parentNode.Vp||\nca,a)}),L.attr(\"opacity\",1E-6).attr(\"transform\",function(a){return P(this.parentNode.Vp||ca,ca,a)}));A.remove();T.attr(\"d\",4===a||2==a?\"M\"+G*X+\",\"+F+\"H0.5V\"+H+\"H\"+G*X:\"M\"+F+\",\"+G*X+\"V0.5H\"+H+\"V\"+G*X);z.attr(\"opacity\",1).attr(\"transform\",function(a){return P(ca,ca,a)});ja.attr(fa+\"2\",G*da);M.attr(fa,G*r).text(I);qa.filter(m).attr(\"fill\",\"none\").attr(\"font-size\",10).attr(\"font-family\",\"sans-serif\").attr(\"text-anchor\",2===a?\"start\":4===a?\"end\":\"middle\");qa.each(function(){this.Vp=ca})}var p=[],t=null,\nR=null,da=6,X=6,n=3;c.scale=function(a){return arguments.length?(b=a,c):b};c.ticks=function(){return p=bf.call(arguments),c};c.tickArguments=function(a){return arguments.length?(p=null==a?[]:bf.call(a),c):p.slice()};c.tickValues=function(a){return arguments.length?(t=null==a?null:bf.call(a),c):t&&t.slice()};c.tickFormat=function(a){return arguments.length?(R=a,c):R};c.tickSize=function(a){return arguments.length?(da=X=+a,c):da};c.tickSizeInner=function(a){return arguments.length?(da=+a,c):da};c.tickSizeOuter=\nfunction(a){return arguments.length?(X=+a,c):X};c.tickPadding=function(a){return arguments.length?(n=+a,c):n};return c}function q(a){return n(1,a)}function v(a){return n(2,a)}function B(a){return n(3,a)}function C(a){return n(4,a)}function E(){for(var a=0,b=arguments.length,c={},e;a<b;++a){if(!(e=arguments[a]+\"\")||e in c)throw Error(\"illegal type: \"+e);c[e]=[]}return new W(c)}function W(a){this.Fa=a}function J(a,b){return a.trim().split(/^|\\s+/).map(function(a){var c=\"\",p=a.indexOf(\".\");0<=p&&(c=\na.slice(p+1),a=a.slice(0,p));if(a&&!b.hasOwnProperty(a))throw Error(\"unknown type: \"+a);return{type:a,name:c}})}function K(a,b,c){for(var p=0,t=a.length;p<t;++p)if(a[p].name===b){a[p]=sm;a=a.slice(0,p).concat(a.slice(p+1));break}null!=c&&a.push({name:b,value:c});return a}function O(a){return function(){var b=this.ownerDocument,c=this.namespaceURI;return\"http://www.w3.org/1999/xhtml\"===c&&\"http://www.w3.org/1999/xhtml\"===b.documentElement.namespaceURI?b.createElement(a):b.createElementNS(c,a)}}function Q(a){return function(){return this.ownerDocument.createElementNS(a.space,\na.local)}}function ka(){return new U}function U(){this.Fa=\"@\"+(++tm).toString(36)}function aa(a,b,c){a=na(a,b,c);return function(b){var c=b.relatedTarget;c&&(c===this||c.compareDocumentPosition(this)&8)||a.call(this,b)}}function na(a,b,c){return function(p){var t=d3.event;d3.event=p;try{a.call(this,this.__data__,b,c)}finally{d3.event=t}}}function Ka(a){return a.trim().split(/^|\\s+/).map(function(a){var b=\"\",c=a.indexOf(\".\");0<=c&&(b=a.slice(c+1),a=a.slice(0,c));return{type:a,name:b}})}function ma(a){return function(){var b=\nthis.__on;if(b){for(var c=0,p=-1,e=b.length,g;c<e;++c)(g=b[c],a.type&&g.type!==a.type||g.name!==a.name)?b[++p]=g:this.removeEventListener(g.type,g.listener,g.capture);++p?b.length=p:delete this.__on}}}function cf(a,b,c){var p=zh.hasOwnProperty(a.type)?aa:na;return function(t,e,z){t=this.__on;var I;e=p(b,e,z);if(t){z=0;for(var g=t.length;z<g;++z)if((I=t[z]).type===a.type&&I.name===a.name){this.removeEventListener(I.type,I.listener,I.capture);this.addEventListener(I.type,I.listener=e,I.capture=c);I.value=\nb;return}}this.addEventListener(a.type,e,c);I={type:a.type,name:a.name,value:b,listener:e,capture:c};t?t.push(I):this.__on=[I]}}function Ya(a,b,c,e){var p=d3.event;a.sourceEvent=d3.event;d3.event=a;try{return b.apply(c,e)}finally{d3.event=p}}function df(){}function ef(){return[]}function Fb(a,b){this.ownerDocument=a.ownerDocument;this.namespaceURI=a.namespaceURI;this.Vg=null;this.Ye=a;this.__data__=b}function Dc(a,b,c,e,g,R){for(var p=0,t,z=b.length,I=R.length;p<I;++p)(t=b[p])?(t.__data__=R[p],e[p]=\nt):c[p]=new Fb(a,R[p]);for(;p<z;++p)if(t=b[p])g[p]=t}function vd(a,b,c,e,g,R,k){var p,t,z={},u=b.length,I=R.length,r=Array(u),P;for(p=0;p<u;++p)if(t=b[p])r[p]=P=\"$\"+k.call(t,t.__data__,p,b),P in z?g[p]=t:z[P]=t;for(p=0;p<I;++p)P=\"$\"+k.call(a,R[p],p,R),(t=z[P])?(e[p]=t,t.__data__=R[p],z[P]=null):c[p]=new Fb(a,R[p]);for(p=0;p<u;++p)(t=b[p])&&z[r[p]]===t&&(g[p]=t)}function wd(a,b){return a<b?-1:a>b?1:a>=b?0:NaN}function ta(a){return function(){this.removeAttribute(a)}}function Gb(a){return function(){this.removeAttributeNS(a.space,\na.local)}}function Hb(a,b){return function(){this.setAttribute(a,b)}}function um(a,b){return function(){this.setAttributeNS(a.space,a.local,b)}}function vm(a,b){return function(){var c=b.apply(this,arguments);null==c?this.removeAttribute(a):this.setAttribute(a,c)}}function wm(a,b){return function(){var c=b.apply(this,arguments);null==c?this.removeAttributeNS(a.space,a.local):this.setAttributeNS(a.space,a.local,c)}}function xm(a){return function(){this.style.removeProperty(a)}}function ym(a,b,c){return function(){this.style.setProperty(a,\nb,c)}}function zm(a,b,c){return function(){var p=b.apply(this,arguments);null==p?this.style.removeProperty(a):this.style.setProperty(a,p,c)}}function Am(a){return function(){delete this[a]}}function Bm(a,b){return function(){this[a]=b}}function Cm(a,b){return function(){var c=b.apply(this,arguments);null==c?delete this[a]:this[a]=c}}function ff(a){return a.classList||new Ah(a)}function Ah(a){this.Vv=a;this.Wi=(a.getAttribute(\"class\")||\"\").trim().split(/^|\\s+/)}function Bh(a,b){a=ff(a);for(var c=-1,\np=b.length;++c<p;)a.add(b[c])}function Ch(a,b){a=ff(a);for(var c=-1,p=b.length;++c<p;)a.remove(b[c])}function Dm(a){return function(){Bh(this,a)}}function Em(a){return function(){Ch(this,a)}}function Fm(a,b){return function(){(b.apply(this,arguments)?Bh:Ch)(this,a)}}function Gm(){this.textContent=\"\"}function Hm(a){return function(){this.textContent=a}}function Im(a){return function(){var b=a.apply(this,arguments);this.textContent=null==b?\"\":b}}function Jm(){this.innerHTML=\"\"}function Km(a){return function(){this.innerHTML=\na}}function Lm(a){return function(){var b=a.apply(this,arguments);this.innerHTML=null==b?\"\":b}}function Mm(){this.nextSibling&&this.parentNode.appendChild(this)}function Nm(){this.previousSibling&&this.parentNode.insertBefore(this,this.parentNode.firstChild)}function Om(){return null}function Pm(){var a=this.parentNode;a&&a.removeChild(this)}function Dh(a,b,c){var p=$b(a),t=p.CustomEvent;t?t=new t(b,c):(t=p.document.createEvent(\"Event\"),c?(t.initEvent(b,c.bubbles,c.cancelable),t.detail=c.detail):\nt.initEvent(b,!1,!1));a.dispatchEvent(t)}function Qm(a,b){return function(){return Dh(this,a,b)}}function Rm(a,b){return function(){return Dh(this,a,b.apply(this,arguments))}}function Ga(a,b){this.Dd=a;this.If=b}function Ib(){return new Ga([[document.documentElement]],gf)}function xd(a,b){var c=a.document.documentElement,p=Ma(a).on(\"dragstart.drag\",null);b&&(p.on(\"click.drag\",ac,!0),setTimeout(function(){p.on(\"click.drag\",null)},0));if(\"onselectstart\"in c)p.on(\"selectstart.drag\",null);else c.style.MozUserSelect=\nc.iv,delete c.iv}function hf(a,b,c,e,g,R,k,X,n,m){this.target=a;this.type=b;this.subject=c;this.identifier=e;this.active=g;this.x=R;this.y=k;this.dx=X;this.dy=n;this.Fa=m}function Sm(){return!d3.event.button}function Tm(){return this.parentNode}function Um(a){return null==a?{x:d3.event.x,y:d3.event.y}:a}function Ec(a,b){a=Object.create(a.prototype);for(var c in b)a[c]=b[c];return a}function rb(){}function sb(a){var b;a=(a+\"\").trim().toLowerCase();return(b=Vm.exec(a))?(b=parseInt(b[1],16),new za(b>>\n8&15|b>>4&240,b>>4&15|b&240,(b&15)<<4|b&15,1)):(b=Wm.exec(a))?Eh(parseInt(b[1],16)):(b=Xm.exec(a))?new za(b[1],b[2],b[3],1):(b=Ym.exec(a))?new za(255*b[1]/100,255*b[2]/100,255*b[3]/100,1):(b=Zm.exec(a))?Fh(b[1],b[2],b[3],b[4]):(b=$m.exec(a))?Fh(255*b[1]/100,255*b[2]/100,255*b[3]/100,b[4]):(b=an.exec(a))?Gh(b[1],b[2]/100,b[3]/100,1):(b=bn.exec(a))?Gh(b[1],b[2]/100,b[3]/100,b[4]):Hh.hasOwnProperty(a)?Eh(Hh[a]):\"transparent\"===a?new za(NaN,NaN,NaN,0):null}function Eh(a){return new za(a>>16&255,a>>8&\n255,a&255,1)}function Fh(a,b,c,e){0>=e&&(a=b=c=NaN);return new za(a,b,c,e)}function jf(a){a instanceof rb||(a=sb(a));if(!a)return new za;a=a.rgb();return new za(a.r,a.g,a.b,a.opacity)}function Fc(a,b,c,e){return 1===arguments.length?jf(a):new za(a,b,c,null==e?1:e)}function za(a,b,c,e){this.r=+a;this.g=+b;this.b=+c;this.opacity=+e}function Gh(a,b,c,e){0>=e?a=b=c=NaN:0>=c||1<=c?a=b=NaN:0>=b&&(a=NaN);return new db(a,b,c,e)}function cn(a){if(a instanceof db)return new db(a.h,a.s,a.l,a.opacity);a instanceof\nrb||(a=sb(a));if(!a)return new db;if(a instanceof db)return a;a=a.rgb();var b=a.r/255,c=a.g/255,p=a.b/255,e=Math.min(b,c,p),g=Math.max(b,c,p),k=NaN,X=g-e,n=(g+e)/2;X?(k=b===g?(c-p)/X+6*(c<p):c===g?(p-b)/X+2:(b-c)/X+4,X/=.5>n?g+e:2-g-e,k*=60):X=0<n&&1>n?0:k;return new db(k,X,n,a.opacity)}function yd(a,b,c,e){return 1===arguments.length?cn(a):new db(a,b,c,null==e?1:e)}function db(a,b,c,e){this.h=+a;this.s=+b;this.l=+c;this.opacity=+e}function kf(a,b,c){return 255*(60>a?b+(c-b)*a/60:180>a?c:240>a?b+\n(c-b)*(240-a)/60:b)}function lf(a){if(a instanceof kb)return new kb(a.l,a.a,a.b,a.opacity);if(a instanceof tb){var b=a.h*Ih;return new kb(a.l,Math.cos(b)*a.c,Math.sin(b)*a.c,a.opacity)}a instanceof za||(a=jf(a));var c=mf(a.r),p=mf(a.g),e=mf(a.b),b=nf((.4124564*c+.3575761*p+.1804375*e)/.95047),g=nf((.2126729*c+.7151522*p+.072175*e)/1),c=nf((.0193339*c+.119192*p+.9503041*e)/1.08883);return new kb(116*g-16,500*(b-g),200*(g-c),a.opacity)}function zd(a,b,c,e){return 1===arguments.length?lf(a):new kb(a,\nb,c,null==e?1:e)}function kb(a,b,c,e){this.l=+a;this.a=+b;this.b=+c;this.opacity=+e}function nf(a){return a>dn?Math.pow(a,1/3):a/Jh+Kh}function of(a){return a>bc?a*a*a:Jh*(a-Kh)}function pf(a){return 255*(.0031308>=a?12.92*a:1.055*Math.pow(a,1/2.4)-.055)}function mf(a){return.04045>=(a/=255)?a/12.92:Math.pow((a+.055)/1.055,2.4)}function Ad(a,b,c,e){var p;if(1===arguments.length)if(p=a,p instanceof tb)p=new tb(p.h,p.c,p.l,p.opacity);else{p instanceof kb||(p=lf(p));var t=Math.atan2(p.b,p.a)*Lh;p=new tb(0>\nt?t+360:t,Math.sqrt(p.a*p.a+p.b*p.b),p.l,p.opacity)}else p=new tb(a,b,c,null==e?1:e);return p}function tb(a,b,c,e){this.h=+a;this.c=+b;this.l=+c;this.opacity=+e}function Za(a,b,c,e){var p;if(1===arguments.length)if(p=a,p instanceof Jb)p=new Jb(p.h,p.s,p.l,p.opacity);else{p instanceof za||(p=jf(p));var t=p.r/255,z=p.g/255,g=p.b/255,t=(Mh*g+-1.7884503806*t-3.5172982438*z)/(Mh+-1.7884503806-3.5172982438),g=g-t,I=(1.97294*(z-t)- -.29227*g)/-.90649,g=(z=Math.sqrt(I*I+g*g)/(1.97294*t*(1-t)))?Math.atan2(I,\ng)*Lh-120:NaN;p=new Jb(0>g?g+360:g,z,t,p.opacity)}else p=new Jb(a,b,c,null==e?1:e);return p}function Jb(a,b,c,e){this.h=+a;this.s=+b;this.l=+c;this.opacity=+e}function Nh(a,b,c,e,g){var p=a*a,t=p*a;return((1-3*a+3*p-t)*b+(4-6*p+3*t)*c+(1+3*a+3*p-3*t)*e+t*g)/6}function Oh(a,b){return function(c){return a+c*b}}function en(a,b,c){return a=Math.pow(a,c),b=Math.pow(b,c)-a,c=1/c,function(p){return Math.pow(a+p*b,c)}}function qf(a,b){var c=b-a;return c?Oh(a,180<c||-180>c?c-360*Math.round(c/360):c):Bd(isNaN(a)?\nb:a)}function fn(a){return 1===(a=+a)?ya:function(b,c){return c-b?en(b,c,a):Bd(isNaN(b)?c:b)}}function ya(a,b){var c=b-a;return c?Oh(a,c):Bd(isNaN(a)?b:a)}function Ph(a){return function(b){var c=b.length,p=Array(c),e=Array(c),t=Array(c),g,k;for(g=0;g<c;++g)k=Fc(b[g]),p[g]=k.r||0,e[g]=k.g||0,t[g]=k.b||0;p=a(p);e=a(e);t=a(t);k.opacity=1;return function(a){k.r=p(a);k.g=e(a);k.b=t(a);return k+\"\"}}}function gn(a){return function(){return a}}function hn(a){return function(b){return a(b)+\"\"}}function jn(a){if(\"none\"===\na)return rf;Gc||(Gc=document.createElement(\"DIV\"),sf=document.documentElement,Qh=document.defaultView);Gc.style.transform=a;a=Qh.getComputedStyle(sf.appendChild(Gc),null).getPropertyValue(\"transform\");sf.removeChild(Gc);a=a.slice(7,-1).split(\",\");return Rh(+a[0],+a[1],+a[2],+a[3],+a[4],+a[5])}function kn(a){if(null==a)return rf;Cd||(Cd=document.createElementNS(\"http://www.w3.org/2000/svg\",\"g\"));Cd.setAttribute(\"transform\",a);if(!(a=Cd.transform.baseVal.consolidate()))return rf;a=a.matrix;return Rh(a.a,\na.b,a.c,a.d,a.e,a.f)}function Sh(a,b,c,e){function p(a){return a.length?a.pop()+\" \":\"\"}function t(a,p,e,t,z,g){a!==e||p!==t?(z=z.push(\"translate(\",null,b,null,c),g.push({uf:z-4,x:Na(a,e)},{uf:z-2,x:Na(p,t)})):(e||t)&&z.push(\"translate(\"+e+b+t+c)}function z(a,b,c,t){a!==b?(180<a-b?b+=360:180<b-a&&(a+=360),t.push({uf:c.push(p(c)+\"rotate(\",null,e)-2,x:Na(a,b)})):b&&c.push(p(c)+\"rotate(\"+b+e)}function g(a,b,c,t){a!==b?t.push({uf:c.push(p(c)+\"skewX(\",null,e)-2,x:Na(a,b)}):b&&c.push(p(c)+\"skewX(\"+b+e)}\nfunction I(a,b,c,e,t,z){a!==c||b!==e?(t=t.push(p(t)+\"scale(\",null,\",\",null,\")\"),z.push({uf:t-4,x:Na(a,c)},{uf:t-2,x:Na(b,e)})):1===c&&1===e||t.push(p(t)+\"scale(\"+c+\",\"+e+\")\")}return function(b,c){var p=[],e=[];b=a(b);c=a(c);t(b.zt,b.At,c.zt,c.At,p,e);z(b.rotate,c.rotate,p,e);g(b.skewX,c.skewX,p,e);I(b.Gs,b.Hs,c.Gs,c.Hs,p,e);b=c=null;return function(a){for(var b=-1,c=e.length,t;++b<c;)p[(t=e[b]).uf]=t.x(a);return p.join(\"\")}}}function Th(a){return((a=Math.exp(a))+1/a)/2}function Uh(a){return function(b,\nc){var p=a((b=yd(b)).h,(c=yd(c)).h),e=ya(b.s,c.s),t=ya(b.l,c.l),z=ya(b.opacity,c.opacity);return function(a){b.h=p(a);b.s=e(a);b.l=t(a);b.opacity=z(a);return b+\"\"}}}function ln(a,b){var c=ya((a=zd(a)).l,(b=zd(b)).l),p=ya(a.a,b.a),e=ya(a.b,b.b),t=ya(a.opacity,b.opacity);return function(b){a.l=c(b);a.a=p(b);a.b=e(b);a.opacity=t(b);return a+\"\"}}function Vh(a){return function(b,c){var p=a((b=Ad(b)).h,(c=Ad(c)).h),e=ya(b.c,c.c),t=ya(b.l,c.l),z=ya(b.opacity,c.opacity);return function(a){b.h=p(a);b.c=e(a);\nb.l=t(a);b.opacity=z(a);return b+\"\"}}}function Wh(a){return function z(b){function c(c,p){var e=a((c=Za(c)).h,(p=Za(p)).h),z=ya(c.s,p.s),g=ya(c.l,p.l),u=ya(c.opacity,p.opacity);return function(a){c.h=e(a);c.s=z(a);c.l=g(Math.pow(a,b));c.opacity=u(a);return c+\"\"}}b=+b;c.gamma=z;return c}(1)}function cc(){return ub||(Xh(mn),ub=tf.now()+uf)}function mn(){ub=0}function Hc(){this.$f=this.ml=this.Vg=null}function Dd(a,b,c){var p=new Hc;p.restart(a,b,c);return p}function Yh(){cc();++dc;for(var a=Ed,b;a;)0<=\n(b=ub-a.ml)&&a.$f.call(null,b),a=a.Vg;--dc}function Zh(){ub=(Fd=tf.now())+uf;dc=Ic=0;try{Yh()}finally{dc=0;for(var a,b=Ed,c,e=Infinity;b;)b.$f?(e>b.ml&&(e=b.ml),a=b,b=b.Vg):(c=b.Vg,b.Vg=null,b=a?a.Vg=c:Ed=c);Jc=a;vf(e);ub=0}}function nn(){var a=tf.now(),b=a-Fd;1E3<b&&(uf-=b,Fd=a)}function vf(a){if(!dc){Ic&&(Ic=clearTimeout(Ic));var b=a-ub;24<b?(Infinity>a&&(Ic=setTimeout(Zh,b)),Kc&&(Kc=clearInterval(Kc))):(Kc||(Fd=ub,Kc=setInterval(nn,1E3)),dc=1,Xh(Zh))}}function wf(a,b){a=a.zg;if(!a||!(a=a[b])||\n0<a.state)throw Error(\"too late\");return a}function Kb(a,b){a=a.zg;if(!a||!(a=a[b])||2<a.state)throw Error(\"too late\");return a}function lb(a,b){a=a.zg;if(!a||!(a=a[b]))throw Error(\"too late\");return a}function on(a,b,c){function p(a){c.state=1;c.timer.restart(e,c.delay,c.time);c.delay<=a&&e(a-c.delay)}function e(p){var u,I,r,P;if(1!==c.state)return z();for(u in g)if(P=g[u],P.name===c.name){if(3===P.state)return xf(e);4===P.state?(P.state=6,P.timer.stop(),P.on.call(\"interrupt\",a,a.__data__,P.index,\nP.group),delete g[u]):+u<b&&(P.state=6,P.timer.stop(),delete g[u])}xf(function(){3===c.state&&(c.state=4,c.timer.restart(t,c.delay,c.time),t(p))});c.state=2;c.on.call(\"start\",a,a.__data__,c.index,c.group);if(2===c.state){c.state=3;k=Array(r=c.tween.length);u=0;for(I=-1;u<r;++u)if(P=c.tween[u].value.call(a,a.__data__,c.index,c.group))k[++I]=P;k.length=I+1}}function t(b){b=b<c.duration?c.ease.call(null,b/c.duration):(c.timer.restart(z),c.state=5,1);for(var p=-1,e=k.length;++p<e;)k[p].call(null,b);5===\nc.state&&(c.on.call(\"end\",a,a.__data__,c.index,c.group),z())}function z(){c.state=6;c.timer.stop();delete g[b];for(var p in g)return;delete a.zg}var g=a.zg,k;g[b]=c;c.timer=Dd(p,0,c.time)}function pn(a,b){var c,p;return function(){var e=Kb(this,a),t=e.tween;if(t!==c){p=c=t;for(var t=0,z=p.length;t<z;++t)if(p[t].name===b){p=p.slice();p.splice(t,1);break}}e.tween=p}}function qn(a,b,c){var p,e;if(\"function\"!==typeof c)throw Error();return function(){var t=Kb(this,a),z=t.tween;if(z!==p){e=(p=z).slice();\nfor(var z={name:b,value:c},g=0,I=e.length;g<I;++g)if(e[g].name===b){e[g]=z;break}g===I&&e.push(z)}t.tween=e}}function yf(a,b,c){var p=a.Kc;a.each(function(){var a=Kb(this,p);(a.value||(a.value={}))[b]=c.apply(this,arguments)});return function(a){return lb(a,p).value[b]}}function rn(a){return function(){this.removeAttribute(a)}}function sn(a){return function(){this.removeAttributeNS(a.space,a.local)}}function tn(a,b,c){var p,e;return function(){var t=this.getAttribute(a);return t===c?null:t===p?e:\ne=b(p=t,c)}}function un(a,b,c){var p,e;return function(){var t=this.getAttributeNS(a.space,a.local);return t===c?null:t===p?e:e=b(p=t,c)}}function vn(a,b,c){var p,e,t;return function(){var z,g=c(this);if(null==g)return void this.removeAttribute(a);z=this.getAttribute(a);return z===g?null:z===p&&g===e?t:t=b(p=z,e=g)}}function wn(a,b,c){var p,e,t;return function(){var z,g=c(this);if(null==g)return void this.removeAttributeNS(a.space,a.local);z=this.getAttributeNS(a.space,a.local);return z===g?null:\nz===p&&g===e?t:t=b(p=z,e=g)}}function xn(a,b){function c(){var c=this,p=b.apply(c,arguments);return p&&function(b){c.setAttributeNS(a.space,a.local,p(b))}}c.uh=b;return c}function yn(a,b){function c(){var c=this,p=b.apply(c,arguments);return p&&function(b){c.setAttribute(a,p(b))}}c.uh=b;return c}function zn(a,b){return function(){wf(this,a).delay=+b.apply(this,arguments)}}function An(a,b){return b=+b,function(){wf(this,a).delay=b}}function Bn(a,b){return function(){Kb(this,a).duration=+b.apply(this,\narguments)}}function Cn(a,b){return b=+b,function(){Kb(this,a).duration=b}}function Dn(a,b){if(\"function\"!==typeof b)throw Error();return function(){Kb(this,a).ease=b}}function En(a){return(a+\"\").trim().split(/^|\\s+/).every(function(a){var b=a.indexOf(\".\");0<=b&&(a=a.slice(0,b));return!a||\"start\"===a})}function Fn(a,b,c){var p,e,t=En(b)?wf:Kb;return function(){var z=t(this,a),g=z.on;if(g!==p)(e=(p=g).copy()).on(b,c);z.on=e}}function Gn(a){return function(){var b=this.parentNode,c;for(c in this.zg)if(+c!==\na)return;b&&b.removeChild(this)}}function Hn(a,b){var c,p,e;return function(){var t=$b(this).getComputedStyle(this,null),z=t.getPropertyValue(a),t=(this.style.removeProperty(a),t.getPropertyValue(a));return z===t?null:z===c&&t===p?e:e=b(c=z,p=t)}}function In(a){return function(){this.style.removeProperty(a)}}function Jn(a,b,c){var p,e;return function(){var t=$b(this).getComputedStyle(this,null).getPropertyValue(a);return t===c?null:t===p?e:e=b(p=t,c)}}function Kn(a,b,c){var p,e,t;return function(){var z=\n$b(this).getComputedStyle(this,null),g=z.getPropertyValue(a),I=c(this);null==I&&(I=(this.style.removeProperty(a),z.getPropertyValue(a)));return g===I?null:g===p&&I===e?t:t=b(p=g,e=I)}}function Ln(a,b,c){function p(){var p=this,e=b.apply(p,arguments);return e&&function(b){p.style.setProperty(a,e(b),c)}}p.uh=b;return p}function Mn(a){return function(){this.textContent=a}}function Nn(a){return function(){var b=a(this);this.textContent=null==b?\"\":b}}function eb(a,b,c,e){this.Dd=a;this.If=b;this.Uj=c;\nthis.Kc=e}function $h(a){return Ib().transition(a)}function On(a){return+a}function Pn(a){return a*a}function Qn(a){return a*(2-a)}function ai(a){return(1>=(a*=2)?a*a:--a*(2-a)+1)/2}function Rn(a){return a*a*a}function Sn(a){return--a*a*a+1}function zf(a){return(1>=(a*=2)?a*a*a:(a-=2)*a*a+2)/2}function Tn(a){return 1-Math.cos(a*bi)}function Un(a){return Math.sin(a*bi)}function ci(a){return(1-Math.cos(di*a))/2}function Vn(a){return Math.pow(2,10*a-10)}function Wn(a){return 1-Math.pow(2,-10*a)}function ei(a){return(1>=\n(a*=2)?Math.pow(2,10*a-10):2-Math.pow(2,10-10*a))/2}function Xn(a){return 1-Math.sqrt(1-a*a)}function Yn(a){return Math.sqrt(1- --a*a)}function fi(a){return(1>=(a*=2)?1-Math.sqrt(1-a*a):Math.sqrt(1-(a-=2)*a)+1)/2}function Zn(a){return 1-Lc(1-a)}function Lc(a){return(a=+a)<Af?Gd*a*a:a<$n?Gd*(a-=ao)*a+.75:a<bo?Gd*(a-=co)*a+.9375:Gd*(a-=eo)*a+.984375}function fo(a){return(1>=(a*=2)?1-Lc(1-a):Lc(a-1)+1)/2}function Mc(a){return{type:a}}function go(){return!d3.event.button}function ho(){var a=this.ownerSVGElement||\nthis;return[[0,0],[a.width.baseVal.value,a.height.baseVal.value]]}function Bf(a){for(;!a.__brush;)if(!(a=a.parentNode))return;return a.__brush}function Cf(a){return a[0][0]===a[1][0]||a[0][1]===a[1][1]}function io(a){return(a=a.__brush)?a.LK.No(a.selection):null}function jo(){return Df(Hd)}function ko(){return Df(Id)}function Df(a){function b(b){var p=b.property(\"__brush\",k).selectAll(\".overlay\").data([Mc(\"overlay\")]);p.enter().append(\"rect\").attr(\"class\",\"overlay\").attr(\"pointer-events\",\"all\").attr(\"cursor\",\nmb.overlay).merge(p).each(function(){var a=Bf(this).extent;Ma(this).attr(\"x\",a[0][0]).attr(\"y\",a[0][1]).attr(\"width\",a[1][0]-a[0][0]).attr(\"height\",a[1][1]-a[0][1])});b.selectAll(\".selection\").data([Mc(\"selection\")]).enter().append(\"rect\").attr(\"class\",\"selection\").attr(\"cursor\",mb.selection).attr(\"fill\",\"#777\").attr(\"fill-opacity\",.3).attr(\"stroke\",\"#fff\").attr(\"shape-rendering\",\"crispEdges\");p=b.selectAll(\".handle\").data(a.Ur,function(a){return a.type});p.exit().remove();p.enter().append(\"rect\").attr(\"class\",\nfunction(a){return\"handle handle--\"+a.type}).attr(\"cursor\",function(a){return mb[a.type]});b.each(c).attr(\"fill\",\"none\").attr(\"pointer-events\",\"all\").style(\"-webkit-tap-highlight-color\",\"rgba(0,0,0,0)\").on(\"mousedown.brush touchstart.brush\",g)}function c(){var a=Ma(this),b=Bf(this).selection;b?(a.selectAll(\".selection\").style(\"display\",null).attr(\"x\",b[0][0]).attr(\"y\",b[0][1]).attr(\"width\",b[1][0]-b[0][0]).attr(\"height\",b[1][1]-b[0][1]),a.selectAll(\".handle\").style(\"display\",null).attr(\"x\",function(a){return\"e\"===\na.type[a.type.length-1]?b[1][0]-u/2:b[0][0]-u/2}).attr(\"y\",function(a){return\"s\"===a.type[0]?b[1][1]-u/2:b[0][1]-u/2}).attr(\"width\",function(a){return\"n\"===a.type||\"s\"===a.type?b[1][0]-b[0][0]+u:u}).attr(\"height\",function(a){return\"e\"===a.type||\"w\"===a.type?b[1][1]-b[0][1]+u:u})):a.selectAll(\".selection,.handle\").style(\"display\",\"none\").attr(\"x\",null).attr(\"y\",null).attr(\"width\",null).attr(\"height\",null)}function p(a,b){return a.__brush.zx||new e(a,b)}function e(a,b){this.Kh=a;this.Wq=b;this.state=\na.__brush;this.active=0}function g(){function b(){var a=vb(u);!aa||ka||ta||(Math.abs(a[0]-ma[0])>Math.abs(a[1]-ma[1])?ta=!0:ka=!0);ma=a;na=!0;Jd();e()}function e(){var a;Q=ma[0]-Nc[0];U=ma[1]-Nc[1];switch(P){case Ef:case gi:R&&(Q=Math.max(Y-fa,Math.min(E-J,Q)),q=fa+Q,C=J+Q);k&&(U=Math.max(jb-v,Math.min(W-O,U)),B=v+U,K=O+U);break;case ec:0>R?(Q=Math.max(Y-fa,Math.min(E-fa,Q)),q=fa+Q,C=J):0<R&&(Q=Math.max(Y-J,Math.min(E-J,Q)),q=fa,C=J+Q);0>k?(U=Math.max(jb-v,Math.min(W-v,U)),B=v+U,K=O):0<k&&(U=Math.max(jb-\nO,Math.min(W-O,U)),B=v,K=O+U);break;case fc:R&&(q=Math.max(Y,Math.min(E,fa-Q*R)),C=Math.max(Y,Math.min(E,J+Q*R))),k&&(B=Math.max(jb,Math.min(W,v-U*k)),K=Math.max(jb,Math.min(W,O+U*k)))}C<q&&(R*=-1,a=fa,fa=J,J=a,a=q,q=C,C=a,I in hi&&Oc.attr(\"cursor\",mb[I=hi[I]]));K<B&&(k*=-1,a=v,v=O,O=a,a=B,B=K,K=a,I in ii&&Oc.attr(\"cursor\",mb[I=ii[I]]));da.selection&&(X=da.selection);ka&&(q=X[0][0],C=X[1][0]);ta&&(B=X[0][1],K=X[1][1]);if(X[0][0]!==q||X[0][1]!==B||X[1][0]!==C||X[1][1]!==K)da.selection=[[q,B],[C,K]],\nc.call(u),Ka.brush()}function t(){d3.event.stopImmediatePropagation();if(d3.event.touches){if(d3.event.touches.length)return;y&&clearTimeout(y);y=setTimeout(function(){y=null},500);N.on(\"touchmove.brush touchend.brush touchcancel.brush\",null)}else xd(d3.event.view,na),no.on(\"keydown.brush keyup.brush mousemove.brush mouseup.brush\",null);N.attr(\"pointer-events\",\"all\");Oc.attr(\"cursor\",mb.overlay);da.selection&&(X=da.selection);Cf(X)&&(da.selection=null,c.call(u));Ka.end()}function z(){switch(d3.event.keyCode){case 16:aa=\nR&&k;break;case 18:P===ec&&(R&&(J=C-Q*R,fa=q+Q*R),k&&(O=K-U*k,v=B+U*k),P=fc,e());break;case 32:if(P===ec||P===fc)0>R?J=C-Q:0<R&&(fa=q-Q),0>k?O=K-U:0<k&&(v=B-U),P=Ef,Oc.attr(\"cursor\",mb.selection),e();break;default:return}Jd()}function g(){switch(d3.event.keyCode){case 16:aa&&(ka=ta=aa=!1,e());break;case 18:P===fc&&(0>R?J=C:0<R&&(fa=q),0>k?O=K:0<k&&(v=B),P=ec,e());break;case 32:P===Ef&&(d3.event.altKey?(R&&(J=C-Q*R,fa=q+Q*R),k&&(O=K-U*k,v=B+U*k),P=fc):(0>R?J=C:0<R&&(fa=q),0>k?O=K:0<k&&(v=B),P=ec),\nOc.attr(\"cursor\",mb[I]),e());break;default:return}Jd()}if(d3.event.touches){if(d3.event.changedTouches.length<d3.event.touches.length)return Jd()}else if(y)return;if(m.apply(this,arguments)){var u=this,I=d3.event.target.__data__.type,P=\"selection\"===(d3.event.metaKey?I=\"overlay\":I)?gi:d3.event.altKey?fc:ec,R=a===Id?null:oo[I],k=a===Hd?null:po[I],da=Bf(u),n=da.extent,X=da.selection,Y=n[0][0],fa,q,jb=n[0][1],v,B,E=n[1][0],J,C,W=n[1][1],O,K,Q,U,na,aa=R&&k&&d3.event.shiftKey,ka,ta,Nc=vb(u),ma=Nc,Ka=p(u,\narguments).$q();\"overlay\"===I?da.selection=X=[[fa=a===Id?Y:Nc[0],v=a===Hd?jb:Nc[1]],[J=a===Id?E:fa,O=a===Hd?W:v]]:(fa=X[0][0],v=X[0][1],J=X[1][0],O=X[1][1]);q=fa;B=v;C=J;K=O;var N=Ma(u).attr(\"pointer-events\",\"none\"),Oc=N.selectAll(\".overlay\").attr(\"cursor\",mb[I]);if(d3.event.touches)N.on(\"touchmove.brush\",b,!0).on(\"touchend.brush touchcancel.brush\",t,!0);else{var no=Ma(d3.event.view).on(\"keydown.brush\",z,!0).on(\"keyup.brush\",g,!0).on(\"mousemove.brush\",b,!0).on(\"mouseup.brush\",t,!0);Kd(d3.event.view)}d3.event.stopImmediatePropagation();\nLb(u);c.call(u);Ka.start()}}function k(){var b=this.__brush||{selection:null};b.extent=n.apply(this,arguments);b.LK=a;return b}var n=ho,m=go,q=E(b,\"start\",\"brush\",\"end\"),u=6,y;b.move=function(b,e){b.selection?b.on(\"start.brush\",function(){p(this,arguments).$q().start()}).on(\"interrupt.brush end.brush\",function(){p(this,arguments).end()}).tween(\"brush\",function(){function b(a){z.selection=1===a&&Cf(u)?null:I(a);c.call(t);r.brush()}var t=this,z=t.__brush,r=p(t,arguments),g=z.selection,u=a.input(\"function\"===\ntypeof e?e.apply(this,arguments):e,z.extent),I=Pc(g,u);return g&&u?b:b(1)}):b.each(function(){var b=this,t=arguments,z=b.__brush,r=a.input(\"function\"===typeof e?e.apply(b,t):e,z.extent),t=p(b,t).$q();Lb(b);z.selection=null==r||Cf(r)?null:r;c.call(b);t.start().brush().end()})};e.prototype={$q:function(){1===++this.active&&(this.state.zx=this,this.AC=!0);return this},start:function(){this.AC&&(this.AC=!1,this.gj(\"start\"));return this},brush:function(){this.gj(\"brush\");return this},end:function(){0===\n--this.active&&(delete this.state.zx,this.gj(\"end\"));return this},gj:function(c){Ya(new qo(b,c,a.No(this.state.selection)),q.apply,q,[c,this.Kh,this.Wq])}};b.extent=function(a){return arguments.length?(n=\"function\"===typeof a?a:ji([[+a[0][0],+a[0][1]],[+a[1][0],+a[1][1]]]),b):n};b.filter=function(a){return arguments.length?(m=\"function\"===typeof a?a:ji(!!a),b):m};b.handleSize=function(a){return arguments.length?(u=+a,b):u};b.on=function(){var a=q.on.apply(q,arguments);return a===q?b:a};return b}function ro(a){return function(b,\nc){return a(b.source.value+b.target.value,c.source.value+c.target.value)}}function Ff(){this.ub=this.xb=this.Sa=this.Va=null;this.Fa=\"\"}function Mb(){return new Ff}function so(a){return a.source}function to(a){return a.target}function uo(a){return a.radius}function vo(a){return a.startAngle}function wo(a){return a.endAngle}function Ld(){}function fb(a,b){var c=new Ld;if(a instanceof Ld)a.each(function(a,b){c.set(b,a)});else if(Array.isArray(a)){var p=-1,e=a.length,t;if(null==b)for(;++p<e;)c.set(p,\na[p]);else for(;++p<e;)c.set(b(t=a[p],p,a),t)}else if(a)for(p in a)c.set(p,a[p]);return c}function xo(){return{}}function yo(a,b,c){a[b]=c}function ki(){return fb()}function li(a,b,c){a.set(b,c)}function Md(){}function mi(a,b){var c=new Md;if(a instanceof Md)a.each(function(a){c.add(a)});else if(a){var p=-1,e=a.length;if(null==b)for(;++p<e;)c.add(a[p]);else for(;++p<e;)c.add(b(a[p],p,a))}return c}function ni(a){return new Function(\"d\",\"return {\"+a.map(function(a,b){return JSON.stringify(a)+\": d[\"+\nb+\"]\"}).join(\",\")+\"}\")}function zo(a,b){var c=ni(a);return function(p,e){return b(c(p),e,a)}}function Ao(a){var b=Object.create(null),c=[];a.forEach(function(a){for(var p in a)p in b||c.push(b[p]=p)});return c}function oi(a,b,c,e){if(isNaN(b)||isNaN(c))return a;var p,t=a.ve;e={data:e};var z=a.ub,g=a.xb,I=a.Sa,k=a.Va,u,y,r,w,H,F;if(!t)return a.ve=e,a;for(;t.length;)if((H=b>=(u=(z+I)/2))?z=u:I=u,(F=c>=(y=(g+k)/2))?g=y:k=y,p=t,!(t=t[H|=F<<1]))return p[H]=e,a;r=+a.tc.call(null,t.data);w=+a.ce.call(null,\nt.data);if(b===r&&c===w)return e.next=t,p?p[H]=e:a.ve=e,a;do p=p?p[H]=Array(4):a.ve=Array(4),(H=b>=(u=(z+I)/2))?z=u:I=u,(F=c>=(y=(g+k)/2))?g=y:k=y;while((H|=F<<1)===(F=(w>=y)<<1|r>=u));return p[F]=t,p[H]=e,a}function Bo(a){var b,c,p=a.length,e,g,k=Array(p),n=Array(p),m=Infinity,q=Infinity,u=-Infinity,y=-Infinity;for(c=0;c<p;++c)isNaN(e=+this.tc.call(null,b=a[c]))||isNaN(g=+this.ce.call(null,b))||(k[c]=e,n[c]=g,e<m&&(m=e),e>u&&(u=e),g<q&&(q=g),g>y&&(y=g));u<m&&(m=this.ub,u=this.Sa);y<q&&(q=this.xb,\ny=this.Va);this.cover(m,q).cover(u,y);for(c=0;c<p;++c)oi(this,k[c],n[c],a[c]);return this}function Co(a){for(var b=0,c=a.length;b<c;++b)this.remove(a[b]);return this}function Do(a){return a[0]}function Eo(a){return a[1]}function Nd(a,b,c){b=new Gf(null==b?Do:b,null==c?Eo:c,NaN,NaN,NaN,NaN);return null==a?b:b.addAll(a)}function Gf(a,b,c,e,g,R){this.tc=a;this.ce=b;this.ub=c;this.xb=e;this.Sa=g;this.Va=R;this.ve=void 0}function pi(a){for(var b={data:a.data},c=b;a=a.next;)c=c.next={data:a.data};return b}\nfunction Fo(a){return a.x+a.vx}function Go(a){return a.y+a.vy}function Ho(a){return a.index}function qi(a,b){a=a.get(b);if(!a)throw Error(\"missing: \"+b);return a}function Io(a){return a.x}function Jo(a){return a.y}function ri(a){if(!(b=Ko.exec(a)))throw Error(\"invalid format: \"+a);var b;a=b[1]||\" \";var c=b[2]||\"\\x3e\",e=b[3]||\"-\",p=b[4]||\"\",g=!!b[5],k=b[6]&&+b[6],n=!!b[7],m=b[8]&&+b[8].slice(1);b=b[9]||\"\";\"n\"===b?(n=!0,b=\"g\"):si[b]||(b=\"\");if(g||\"0\"===a&&\"\\x3d\"===c)g=!0,a=\"0\",c=\"\\x3d\";this.fill=a;\nthis.align=c;this.sign=e;this.symbol=p;this.zero=g;this.width=k;this.comma=n;this.precision=m;this.type=b}function Lo(a){return a}function ti(a){Od=ui(a);d3.format=Od.format;d3.formatPrefix=Od.formatPrefix;return Od}function $a(){this.reset()}function vi(a,b,c){var e=a.s=b+c,p=e-b,e=e-p;a.t=b-e+(c-p)}function wi(a){return 1<a?0:-1>a?ha:Math.acos(a)}function Oa(a){return 1<a?ra:-1>a?-ra:Math.asin(a)}function xi(a){return(a=N(a/2))*a}function sa(){}function Pd(a,b){if(a&&yi.hasOwnProperty(a.type))yi[a.type](a,\nb)}function Hf(a,b,c){var e=-1;c=a.length-c;var p;for(b.lineStart();++e<c;)p=a[e],b.point(p[0],p[1],p[2]);b.lineEnd()}function zi(a,b){var c=-1,e=a.length;for(b.polygonStart();++c<e;)Hf(a[c],b,1);b.polygonEnd()}function Mo(){gb.point=No}function Oo(){Ai(Bi,Ci)}function No(a,b){gb.point=Ai;Bi=a;Ci=b;a*=Z;b*=Z;If=a;Jf=S(b=b/2+Qd);Kf=N(b)}function Ai(a,b){a*=Z;b*=Z;b=b/2+Qd;var c=a-If,e=0<=c?1:-1,p=e*c,c=S(b);b=N(b);var t=Kf*b,g=Jf*c+t*S(p),e=t*e*N(p);Rd.add(Ba(e,g));If=a;Jf=c;Kf=b}function Sd(a){return[Ba(a[1],\na[0]),Oa(a[2])]}function Nb(a){var b=a[0];a=a[1];var c=S(a);return[c*S(b),c*N(b),N(a)]}function Td(a,b){return a[0]*b[0]+a[1]*b[1]+a[2]*b[2]}function gc(a,b){return[a[1]*b[2]-a[2]*b[1],a[2]*b[0]-a[0]*b[2],a[0]*b[1]-a[1]*b[0]]}function Lf(a,b){a[0]+=b[0];a[1]+=b[1];a[2]+=b[2]}function Ud(a,b){return[a[0]*b,a[1]*b,a[2]*b]}function Vd(a){var b=wa(a[0]*a[0]+a[1]*a[1]+a[2]*a[2]);a[0]/=b;a[1]/=b;a[2]/=b}function Mf(a,b){wb.push(nb=[ua=a,va=a]);b<Pa&&(Pa=b);b>Ta&&(Ta=b)}function Di(a,b){var c=Nb([a*Z,b*\nZ]);if(hc){var e=gc(hc,c),p=[e[1],-e[0],0],e=gc(p,e);Vd(e);var e=Sd(e),t=a-Ob,p=0<t?1:-1,g=e[0]*pa*p,t=180<ia(t);t^(p*Ob<g&&g<p*a)?(e=e[1]*pa,e>Ta&&(Ta=e)):(g=(g+360)%360-180,t^(p*Ob<g&&g<p*a))?(e=-e[1]*pa,e<Pa&&(Pa=e)):(b<Pa&&(Pa=b),b>Ta&&(Ta=b));t?a<Ob?Qa(ua,a)>Qa(ua,va)&&(va=a):Qa(a,va)>Qa(ua,va)&&(ua=a):va>=ua?(a<ua&&(ua=a),a>va&&(va=a)):a>Ob?Qa(ua,a)>Qa(ua,va)&&(va=a):Qa(a,va)>Qa(ua,va)&&(ua=a)}else wb.push(nb=[ua=a,va=a]);b<Pa&&(Pa=b);b>Ta&&(Ta=b);hc=c;Ob=a}function Ei(){ob.point=Di}function Fi(){nb[0]=\nua;nb[1]=va;ob.point=Mf;hc=null}function Gi(a,b){if(hc){var c=a-Ob;Qc.add(180<ia(c)?c+(0<c?360:-360):c)}else Hi=a,Ii=b;gb.point(a,b);Di(a,b)}function Po(){gb.lineStart()}function Qo(){Gi(Hi,Ii);gb.lineEnd();1E-6<ia(Qc)&&(ua=-(va=180));nb[0]=ua;nb[1]=va;hc=null}function Qa(a,b){return 0>(b-=a)?b+360:b}function Ro(a,b){return a[0]-b[0]}function Ji(a,b){return a[0]<=a[1]?a[0]<=b&&b<=a[1]:b<a[0]||a[1]<b}function Nf(a,b){a*=Z;b*=Z;var c=S(b);Rc(c*S(a),c*N(a),N(b))}function Rc(a,b,c){++Sc;Wd+=(a-Wd)/Sc;\nXd+=(b-Xd)/Sc;Yd+=(c-Yd)/Sc}function Ki(){ab.point=So}function So(a,b){a*=Z;b*=Z;var c=S(b);Ca=c*S(a);Da=c*N(a);Ea=N(b);ab.point=To;Rc(Ca,Da,Ea)}function To(a,b){a*=Z;b*=Z;var c=S(b),e=c*S(a);a=c*N(a);b=N(b);var p=Ba(wa((p=Da*b-Ea*a)*p+(p=Ea*e-Ca*b)*p+(p=Ca*a-Da*e)*p),Ca*e+Da*a+Ea*b);Zd+=p;$d+=p*(Ca+(Ca=e));ae+=p*(Da+(Da=a));be+=p*(Ea+(Ea=b));Rc(Ca,Da,Ea)}function Li(){ab.point=Nf}function Uo(){ab.point=Vo}function Wo(){Mi(Ni,Oi);ab.point=Nf}function Vo(a,b){Ni=a;Oi=b;a*=Z;b*=Z;ab.point=Mi;var c=\nS(b);Ca=c*S(a);Da=c*N(a);Ea=N(b);Rc(Ca,Da,Ea)}function Mi(a,b){a*=Z;b*=Z;var c=S(b),e=c*S(a);a=c*N(a);b=N(b);var c=Da*b-Ea*a,p=Ea*e-Ca*b,t=Ca*a-Da*e,g=wa(c*c+p*p+t*t),k=Ca*e+Da*a+Ea*b,n=g&&-Oa(g)/g,g=Ba(g,k);Of+=n*c;Pf+=n*p;Qf+=n*t;Zd+=g;$d+=g*(Ca+(Ca=e));ae+=g*(Da+(Da=a));be+=g*(Ea+(Ea=b));Rc(Ca,Da,Ea)}function Rf(a,b){return[a>ha?a-La:a<-ha?a+La:a,b]}function Sf(a,b,c){return(a%=La)?b||c?Pi(Qi(a),Ri(b,c)):Qi(a):b||c?Ri(b,c):Rf}function Si(a){return function(b,c){return b+=a,[b>ha?b-La:b<-ha?b+La:\nb,c]}}function Qi(a){var b=Si(a);b.invert=Si(-a);return b}function Ri(a,b){function c(a,b){var c=S(b),z=S(a)*c;a=N(a)*c;b=N(b);c=b*e+z*p;return[Ba(a*t-c*g,z*e-b*p),Oa(c*t+a*g)]}var e=S(a),p=N(a),t=S(b),g=N(b);c.invert=function(a,b){var c=S(b),z=S(a)*c;a=N(a)*c;b=N(b);c=b*t-a*g;return[Ba(a*t+b*g,z*e+c*p),Oa(c*e-z*p)]};return c}function Ti(a,b,c,e,g,k){if(c){var p=S(b),t=N(b);c*=e;if(null==g)g=b+e*La,k=b-c/2;else if(g=Ui(p,g),k=Ui(p,k),0<e?g<k:g>k)g+=e*La;for(;0<e?g>k:g<k;g-=c)b=Sd([p,-t*S(g),-t*N(g)]),\na.point(b[0],b[1])}}function Ui(a,b){b=Nb(b);b[0]-=a;Vd(b);a=wi(-b[1]);return((0>-b[2]?-a:a)+La-1E-6)%La}function ce(a,b,c,e){this.x=a;this.z=b;this.Mo=c;this.e=e;this.Ak=!1;this.n=this.p=null}function Vi(a){if(b=a.length){for(var b,c=0,e=a[0],p;++c<b;)e.n=p=a[c],p.p=e,e=p;e.n=p=a[0];p.p=e}}function Tf(a,b,c,e){function p(p,g,u,I){var r=0,w=0;if(null==p||(r=t(p,u))!==(w=t(g,u))||0>z(p,g)^0<u){do I.point(0===r||3===r?a:c,1<r?e:b);while((r=(r+u+4)%4)!==w)}else I.point(g[0],g[1])}function t(e,p){return 1E-6>\nia(e[0]-a)?0<p?0:3:1E-6>ia(e[0]-c)?0<p?2:1:1E-6>ia(e[1]-b)?0<p?1:0:0<p?3:2}function g(a,b){return z(a.x,b.x)}function z(a,b){var c=t(a,1),e=t(b,1);return c!==e?c-e:0===c?b[1]-a[1]:1===c?a[0]-b[0]:2===c?a[1]-b[1]:b[0]-a[0]}return function(t){function z(p,t){a<=p&&p<=c&&b<=t&&t<=e&&P.point(p,t)}function u(){P=R;n=[];da=[];v=!0}function I(){for(var b,c=b=0,z=da.length;c<z;++c)for(var r=da[c],u=1,I=r.length,w=r[0],k,y,R=w[0],w=w[1];u<I;++u)k=R,y=w,w=r[u],R=w[0],w=w[1],y<=e?w>e&&(R-k)*(e-y)>(w-y)*(a-k)&&\n++b:w<=e&&(R-k)*(e-y)<(w-y)*(a-k)&&--b;c=v&&b;z=(n=Uf(n)).length;if(c||z)t.polygonStart(),c&&(t.lineStart(),p(null,null,1,t),t.lineEnd()),z&&Wi(n,g,b,p,t),t.polygonEnd();P=t;n=da=A=null}function r(){B.point=k;da&&da.push(A=[]);fa=!0;Y=!1;G=q=NaN}function w(){n&&(k(X,m),M&&Y&&R.qP(),n.push(R.result()));B.point=z;Y&&P.lineEnd()}function k(p,t){var g=a<=p&&p<=c&&b<=t&&t<=e;da&&A.push([p,t]);if(fa)X=p,m=t,M=g,fa=!1,g&&(P.lineStart(),P.point(p,t));else if(g&&Y)P.point(p,t);else{var z=[G=Math.max(-1E9,\nMath.min(1E9,G)),q=Math.max(-1E9,Math.min(1E9,q))],r=[p=Math.max(-1E9,Math.min(1E9,p)),t=Math.max(-1E9,Math.min(1E9,t))];Xo(z,r,a,b,c,e)?(Y||(P.lineStart(),P.point(z[0],z[1])),P.point(r[0],r[1]),g||P.lineEnd(),v=!1):g&&(P.lineStart(),P.point(p,t),v=!1)}G=p;q=t;Y=g}var P=t,R=Xi(),n,da,A,X,m,M,G,q,Y,fa,v,B={point:z,lineStart:r,lineEnd:w,polygonStart:u,polygonEnd:I};return B}}function Yo(){ic.point=Zo;ic.lineEnd=$o}function $o(){ic.point=ic.lineEnd=sa}function Zo(a,b){a*=Z;b*=Z;Vf=a;de=N(b);ee=S(b);\nic.point=ap}function ap(a,b){a*=Z;b*=Z;var c=N(b);b=S(b);var e=ia(a-Vf),p=S(e),e=N(e),e=b*e,t=ee*c-de*b*p,p=de*c+ee*b*p;Wf.add(Ba(wa(e*e+t*t),p));Vf=a;de=c;ee=b}function Yi(a,b,c){var e=bb(a,b-1E-6,c).concat(b);return function(a){return e.map(function(b){return[a,b]})}}function Zi(a,b,c){var e=bb(a,b-1E-6,c).concat(b);return function(a){return e.map(function(b){return[b,a]})}}function $i(){function a(){return{type:\"MultiLineString\",coordinates:b()}}function b(){return bb(fe(k/r)*r,g,r).map(ca).concat(bb(fe(q/\nw)*w,m,w).map(qa)).concat(bb(fe(e/u)*u,c,u).filter(function(a){return 1E-6<ia(a%r)}).map(H)).concat(bb(fe(X/y)*y,n,y).filter(function(a){return 1E-6<ia(a%w)}).map(F))}var c,e,g,k,n,X,m,q,u=10,y=u,r=90,w=360,H,F,ca,qa,T=2.5;a.lines=function(){return b().map(function(a){return{type:\"LineString\",coordinates:a}})};a.outline=function(){return{type:\"Polygon\",coordinates:[ca(k).concat(qa(m).slice(1),ca(g).reverse().slice(1),qa(q).reverse().slice(1))]}};a.extent=function(b){return arguments.length?a.extentMajor(b).extentMinor(b):\na.extentMinor()};a.extentMajor=function(b){if(!arguments.length)return[[k,q],[g,m]];k=+b[0][0];g=+b[1][0];q=+b[0][1];m=+b[1][1];k>g&&(b=k,k=g,g=b);q>m&&(b=q,q=m,m=b);return a.precision(T)};a.extentMinor=function(b){if(!arguments.length)return[[e,X],[c,n]];e=+b[0][0];c=+b[1][0];X=+b[0][1];n=+b[1][1];e>c&&(b=e,e=c,c=b);X>n&&(b=X,X=n,n=b);return a.precision(T)};a.step=function(b){return arguments.length?a.stepMajor(b).stepMinor(b):a.stepMinor()};a.stepMajor=function(b){if(!arguments.length)return[r,\nw];r=+b[0];w=+b[1];return a};a.stepMinor=function(b){if(!arguments.length)return[u,y];u=+b[0];y=+b[1];return a};a.precision=function(b){if(!arguments.length)return T;T=+b;H=Yi(X,n,90);F=Zi(e,c,T);ca=Yi(q,m,90);qa=Zi(k,g,T);return a};return a.extentMajor([[-180,-89.999999],[180,89.999999]]).extentMinor([[-180,-80.000001],[180,80.000001]])}function bp(){return $i()()}function cp(){pb.point=dp}function dp(a,b){pb.point=aj;bj=Xf=a;cj=Yf=b}function aj(a,b){Zf.add(Yf*a-Xf*b);Xf=a;Yf=b}function ep(){aj(bj,\ncj)}function fp(a,b){a<jc&&(jc=a);a>Tc&&(Tc=a);b<ge&&(ge=b);b>he&&(he=b)}function Pb(a,b){$f+=a;ag+=b;++Uc}function dj(){Ua.point=gp}function gp(a,b){Ua.point=hp;Pb(hb=a,ib=b)}function hp(a,b){var c=a-hb,e=b-ib,c=wa(c*c+e*e);ie+=c*(hb+a)/2;je+=c*(ib+b)/2;kc+=c;Pb(hb=a,ib=b)}function ej(){Ua.point=Pb}function ip(){Ua.point=jp}function kp(){fj(gj,hj)}function jp(a,b){Ua.point=fj;Pb(gj=hb=a,hj=ib=b)}function fj(a,b){var c=a-hb,e=b-ib,c=wa(c*c+e*e);ie+=c*(hb+a)/2;je+=c*(ib+b)/2;kc+=c;c=ib*a-hb*b;bg+=\nc*(hb+a);cg+=c*(ib+b);Vc+=3*c;Pb(hb=a,ib=b)}function ij(a){this.Ia=a}function lp(a,b){Wc.point=jj;kj=Xc=a;lj=Yc=b}function jj(a,b){Xc-=a;Yc-=b;dg.add(wa(Xc*Xc+Yc*Yc));Xc=a;Yc=b}function mj(){this.Yi=[]}function nj(a){return\"m0,\"+a+\"a\"+a+\",\"+a+\" 0 1,1 0,\"+-2*a+\"a\"+a+\",\"+a+\" 0 1,1 0,\"+2*a+\"z\"}function mp(a){return 1<a.length}function np(a,b){return(0>(a=a.x)[0]?a[1]-ra-1E-6:ra-a[1])-(0>(b=b.x)[0]?b[1]-ra-1E-6:ra-b[1])}function op(a){var b=NaN,c=NaN,e=NaN,p;return{lineStart:function(){a.lineStart();\np=1},point:function(t,g){var z=0<t?ha:-ha,I=ia(t-b);if(1E-6>ia(I-ha))a.point(b,c=0<(c+g)/2?ra:-ra),a.point(e,c),a.lineEnd(),a.lineStart(),a.point(z,c),a.point(t,c),p=0;else if(e!==z&&I>=ha){1E-6>ia(b-e)&&(b-=1E-6*e);1E-6>ia(t-z)&&(t-=1E-6*z);var I=b,k=c,u=t,y=g,r,w,P=N(I-u);c=1E-6<ia(P)?lc((N(k)*(w=S(y))*N(u)-N(y)*(r=S(k))*N(I))/(r*w*P)):(k+y)/2;a.point(e,c);a.lineEnd();a.lineStart();a.point(z,c);p=0}a.point(b=t,c=g);e=z},lineEnd:function(){a.lineEnd();b=c=NaN},$w:function(){return 2-p}}}function pp(a,\nb,c,e){null==a?(c*=ra,e.point(-ha,c),e.point(0,c),e.point(ha,c),e.point(ha,0),e.point(ha,-c),e.point(0,-c),e.point(-ha,-c),e.point(-ha,0),e.point(-ha,c)):1E-6<ia(a[0]-b[0])?(a=a[0]<b[0]?ha:-ha,c=c*a/2,e.point(-a,c),e.point(0,c),e.point(a,c)):e.point(b[0],b[1])}function ke(a){return function(b){var c=new eg,e;for(e in a)c[e]=a[e];c.stream=b;return c}}function eg(){}function mc(a,b,c){var e=b[1][0]-b[0][0],p=b[1][1]-b[0][1],t=a.clipExtent&&a.clipExtent();a.scale(150).translate([0,0]);null!=t&&a.clipExtent(null);\ncb(c,a.stream(le));var g=le.result();c=Math.min(e/(g[1][0]-g[0][0]),p/(g[1][1]-g[0][1]));e=+b[0][0]+(e-c*(g[1][0]+g[0][0]))/2;b=+b[0][1]+(p-c*(g[1][1]+g[0][1]))/2;null!=t&&a.clipExtent(t);return a.scale(150*c).translate([e,b])}function oj(a){return ke({point:function(b,c){b=a(b,c);this.stream.point(b[0],b[1])}})}function pj(a,b){function c(e,p,t,g,z,k,n,u,y,r,w,H,F,m){var I=n-e,P=u-p,A=I*I+P*P;if(A>4*b&&F--){var R=g+r,da=z+w,ca=k+H,G=wa(R*R+da*da+ca*ca),X=Oa(ca/=G),Y=1E-6>ia(ia(ca)-1)||1E-6>ia(t-\ny)?(t+y)/2:Ba(da,R),q=a(Y,X),X=q[0],q=q[1],fa=X-e,v=q-p,B=P*fa-I*v;if(B*B/A>b||.3<ia((I*fa+P*v)/A-.5)||g*r+z*w+k*H<qp)c(e,p,t,g,z,k,X,q,Y,R/=G,da/=G,ca,F,m),m.point(X,q),c(X,q,Y,R,da,ca,n,u,y,r,w,H,F,m)}}return function(b){function e(c,e){c=a(c,e);b.point(c[0],c[1])}function p(){T=NaN;G.point=t;b.lineStart()}function t(e,p){var t=Nb([e,p]);p=a(e,p);c(T,A,qa,L,ja,M,T=p[0],A=p[1],qa=e,L=t[0],ja=t[1],M=t[2],16,b);b.point(T,A)}function g(){G.point=e;b.lineEnd()}function z(){p();G.point=k;G.lineEnd=u}\nfunction k(a,b){t(y=a,b);r=T;w=A;I=L;n=ja;m=M;G.point=t}function u(){c(T,A,qa,L,ja,M,r,w,y,I,n,m,16,b);G.lineEnd=g;g()}var y,r,w,I,n,m,qa,T,A,L,ja,M,G={point:e,lineStart:p,lineEnd:g,polygonStart:function(){b.polygonStart();G.lineStart=z},polygonEnd:function(){b.polygonEnd();G.lineStart=p}};return G}}function xb(a){return fg(function(){return a})()}function fg(a){function b(a){a=T(a[0]*Z,a[1]*Z);return[a[0]*n+u,y-a[1]*n]}function c(a){return(a=T.invert((a[0]-u)/n,(y-a[1])/n))&&[a[0]*pa,a[1]*pa]}function e(a,\nb){return a=k(a,b),[a[0]*n+u,y-a[1]*n]}function p(){T=Pi(qa=Sf(H,F,ca),k);var a=k(r,w);u=m-a[0]*n;y=q+a[1]*n;return g()}function g(){B=E=null;return b}var k,n=150,m=480,q=250,u,y,r=0,w=0,H=0,F=0,ca=0,qa,T,A=null,L=qj,ja=null,M,G,Xa,Y=Qb,Aa=.5,v=+Aa?pj(e,Aa):oj(e),B,E;b.stream=function(a){return B&&E===a?B:B=rp(L(qa,v(Y(E=a))))};b.clipAngle=function(a){return arguments.length?(L=+a?sp(A=a*Z,6*Z):(A=null,qj),g()):A*pa};b.clipExtent=function(a){return arguments.length?(Y=null==a?(ja=M=G=Xa=null,Qb):\nTf(ja=+a[0][0],M=+a[0][1],G=+a[1][0],Xa=+a[1][1]),g()):null==ja?null:[[ja,M],[G,Xa]]};b.scale=function(a){return arguments.length?(n=+a,p()):n};b.translate=function(a){return arguments.length?(m=+a[0],q=+a[1],p()):[m,q]};b.center=function(a){return arguments.length?(r=a[0]%360*Z,w=a[1]%360*Z,p()):[r*pa,w*pa]};b.rotate=function(a){return arguments.length?(H=a[0]%360*Z,F=a[1]%360*Z,ca=2<a.length?a[2]%360*Z:0,p()):[H*pa,F*pa,ca*pa]};b.precision=function(a){var b;arguments.length?(b=Aa=a*a,b=+b?pj(e,\nb):oj(e),b=(v=b,g())):b=wa(Aa);return b};b.fitExtent=function(a,c){return mc(b,a,c)};b.fitSize=function(a,c){return mc(b,[[0,0],a],c)};return function(){k=a.apply(this,arguments);b.invert=k.invert&&c;return p()}}function gg(a){var b=0,c=ha/3,e=fg(a);a=e(b,c);a.parallels=function(a){return arguments.length?e(b=a[0]*Z,c=a[1]*Z):[b*pa,c*pa]};return a}function tp(a){function b(a,b){return[a*c,N(b)/c]}var c=S(a);b.invert=function(a,b){return[a/c,Oa(b*c)]};return b}function rj(a,b){function c(a,b){b=wa(t-\n2*p*N(b))/p;return[b*N(a*=p),g-b*S(a)]}var e=N(a),p=(e+N(b))/2;if(1E-6>ia(p))return tp(a);var t=1+e*(2*p-e),g=wa(t)/p;c.invert=function(a,b){b=g-b;return[Ba(a,ia(b))/p*Zc(b),Oa((t-(a*a+b*b)*p*p)/(2*p))]};return c}function up(a){var b=a.length;return{point:function(c,e){for(var p=-1;++p<b;)a[p].point(c,e)},sphere:function(){for(var c=-1;++c<b;)a[c].sphere()},lineStart:function(){for(var c=-1;++c<b;)a[c].lineStart()},lineEnd:function(){for(var c=-1;++c<b;)a[c].lineEnd()},polygonStart:function(){for(var c=\n-1;++c<b;)a[c].polygonStart()},polygonEnd:function(){for(var c=-1;++c<b;)a[c].polygonEnd()}}}function sj(a){return function(b,c){var e=S(b),p=S(c),e=a(e*p);return[e*p*N(b),e*N(c)]}}function $c(a){return function(b,c){var e=wa(b*b+c*c),p=a(e),t=N(p),p=S(p);return[Ba(b*t,e*p),Oa(e&&c*t/e)]}}function me(a,b){return[a,ne(nc((ra+b)/2))]}function tj(a){var b=xb(a),c=b.scale,e=b.translate,p=b.clipExtent,g;b.scale=function(a){return arguments.length?(c(a),g&&b.clipExtent(null),b):c()};b.translate=function(a){return arguments.length?\n(e(a),g&&b.clipExtent(null),b):e()};b.clipExtent=function(a){if(!arguments.length)return g?null:p();if(g=null==a){var t=ha*c(),z=e();a=[[z[0]-t,z[1]-t],[z[0]+t,z[1]+t]]}p(a);return b};return b.clipExtent(null)}function uj(a,b){function c(a,b){0<t?b<-ra+1E-6&&(b=-ra+1E-6):b>ra-1E-6&&(b=ra-1E-6);b=t/hg(nc((ra+b)/2),p);return[b*N(p*a),t-b*S(p*a)]}var e=S(a),p=a===b?N(a):ne(e/S(b))/ne(nc((ra+b)/2)/nc((ra+a)/2)),t=e*hg(nc((ra+a)/2),p)/p;if(!p)return me;c.invert=function(a,b){b=t-b;var c=Zc(p)*wa(a*a+b*\nb);return[Ba(a,ia(b))/p*Zc(b),2*lc(hg(t/c,1/p))-ra]};return c}function ad(a,b){return[a,b]}function vj(a,b){function c(a,b){b=t-b;a*=p;return[b*N(a),t-b*S(a)]}var e=S(a),p=a===b?N(a):(e-S(b))/(b-a),t=e/p+a;if(1E-6>ia(p))return ad;c.invert=function(a,b){b=t-b;return[Ba(a,ia(b))/p*Zc(b),t-Zc(p)*wa(a*a+b*b)]};return c}function ig(a,b){var c=S(b),e=S(a)*c;return[c*N(a)/e,N(b)/e]}function oe(a,b,c,e){return 1===a&&1===b&&0===c&&0===e?Qb:ke({point:function(p,t){this.stream.point(p*a+c,t*b+e)}})}function jg(a,\nb){return[S(b)*N(a),N(b)]}function kg(a,b){var c=S(b),e=1+S(a)*c;return[c*N(a)/e,N(b)/e]}function lg(a,b){return[ne(nc((ra+b)/2)),-a]}function vp(a,b){return a.parent===b.parent?1:2}function wp(a,b){return a+b.x}function xp(a,b){return Math.max(a,b.y)}function yp(a){for(var b;b=a.children;)a=b[0];return a}function zp(a){for(var b;b=a.children;)a=b[b.length-1];return a}function Ap(a){var b=0,c=a.children,e=c&&c.length;if(e)for(;0<=--e;)b+=c[e].value;else b=1;a.value=b}function mg(a,b){var c=new oc(a);\na=+a.value&&(c.value=a.value);var e,p=[c],t,g,k,n;for(null==b&&(b=Bp);e=p.pop();)if(a&&(e.value=+e.data.value),(g=b(e.data))&&(n=g.length))for(e.children=Array(n),k=n-1;0<=k;--k)p.push(t=e.children[k]=new oc(g[k])),t.parent=e,t.depth=e.depth+1;return c.eachBefore(wj)}function Cp(){return mg(this).eachBefore(Dp)}function Bp(a){return a.children}function Dp(a){a.data=a.data.data}function wj(a){var b=0;do a.height=b;while((a=a.parent)&&a.height<++b)}function oc(a){this.data=a;this.depth=this.height=\n0;this.parent=null}function Ep(a){this.Fa=a;this.next=null}function xj(a,b){var c,e=null,p=a.head,t,g;switch(b.length){case 1:c=b[0];c={x:c.x,y:c.y,r:c.r};break;case 2:g=b[0];var k=b[1];c=g.x;t=g.y;g=g.r;var n=k.x,m=k.y,k=k.r,u=n-c,y=m-t,r=k-g,w=Math.sqrt(u*u+y*y);c={x:(c+n+u/w*r)/2,y:(t+m+y/w*r)/2,r:(w+g+k)/2};break;case 3:g=b[0];m=b[1];n=b[2];c=g.x;t=g.y;g=g.r;var y=m.x,r=m.y,H=m.r,k=n.x,w=n.y,F=n.r,n=2*(c-y),u=2*(t-r),m=2*(H-g),H=c*c+t*t-g*g-y*y-r*r+H*H,y=2*(c-k),ca=2*(t-w),r=2*(F-g),w=c*c+t*t-\ng*g-k*k-w*w+F*F,F=y*u-n*ca,k=(u*w-ca*H)/F-c,u=(ca*m-u*r)/F,w=(y*H-n*w)/F-t,n=(n*r-y*m)/F,m=u*u+n*n-1,y=2*(k*u+w*n+g);g=k*k+w*w-g*g;g=(-y-Math.sqrt(y*y-4*m*g))/(2*m);c={x:k+u*g+c,y:w+n*g+t,r:g}}for(;p;)g=p.Fa,t=p.next,(n=!c)||(n=g.x-c.x,m=g.y-c.y,k=c.r-g.r,n=k*k+1E-6>n*n+m*m,n=!n),n?(e?(a.Dm=e,e.next=null):a.head=a.Dm=null,b.push(g),c=xj(a,b),b.pop(),a.head?(p.next=a.head,a.head=p):(p.next=null,a.head=a.Dm=p),e=a.Dm,e.next=t):e=p,p=t;a.Dm=e;return c}function yj(a,b,c){var e=a.x,p=a.y,t=b.r+c.r;a=a.r+\nc.r;var g=b.x-e;b=b.y-p;var z=g*g+b*b;if(z){var k=.5+((a*=a)-(t*=t))/(2*z),t=Math.sqrt(Math.max(0,2*t*(a+z)-(a-=z)*a-t*t))/(2*z);c.x=e+k*g+t*b;c.y=p+k*b-t*g}else c.x=e+a,c.y=p}function zj(a,b){var c=b.x-a.x,e=b.y-a.y;a=a.r+b.r;return a*a-1E-6>c*c+e*e}function Aj(a,b){for(var c=a.Fa.r;a!==b;)c+=2*(a=a.next).Fa.r;return c-b.Fa.r}function Bj(a,b,c){var e=a.Fa;a=a.next.Fa;var p=e.r+a.r;b=(e.x*a.r+a.x*e.r)/p-b;c=(e.y*a.r+a.y*e.r)/p-c;return b*b+c*c}function pe(a){this.Fa=a;this.Fh=this.next=null}function Cj(a){if(!(p=\na.length))return 0;var b,c,e,p;b=a[0];b.x=0;b.y=0;if(!(1<p))return b.r;c=a[1];b.x=-c.r;c.x=b.r;c.y=0;if(!(2<p))return b.r+c.r;yj(c,b,e=a[2]);var g=b.r*b.r,k=c.r*c.r,n=e.r*e.r,m=g+k+n,q=g*b.x+k*c.x+n*e.x,k=g*b.y+k*c.y+n*e.y,u,y,r;b=new pe(b);c=new pe(c);e=new pe(e);b.next=e.Fh=c;c.next=b.Fh=e;e.next=c.Fh=b;r=3;a:for(;r<p;++r){yj(b.Fa,c.Fa,e=a[r]);e=new pe(e);g=c.next;n=b.Fh;u=c.Fa.r;y=b.Fa.r;do if(u<=y){if(zj(g.Fa,e.Fa)){u+b.Fa.r+c.Fa.r>Aj(g,c)?b=g:c=g;b.next=c;c.Fh=b;--r;continue a}u+=g.Fa.r;g=g.next}else{if(zj(n.Fa,\ne.Fa)){Aj(b,n)>y+b.Fa.r+c.Fa.r?b=n:c=n;b.next=c;c.Fh=b;--r;continue a}y+=n.Fa.r;n=n.Fh}while(g!==n.next);e.Fh=b;e.next=c;b.next=c.Fh=c=e;m+=n=e.Fa.r*e.Fa.r;q+=n*e.Fa.x;k+=n*e.Fa.y;for(g=Bj(b,u=q/m,y=k/m);(e=e.next)!==c;)(n=Bj(e,u,y))<g&&(b=e,g=n);c=b.next}b=[c.Fa];for(e=c;(e=e.next)!==c;)b.push(e.Fa);e=Dj(b);for(r=0;r<p;++r)b=a[r],b.x-=e.x,b.y-=e.y;return e.r}function qe(a){if(\"function\"!==typeof a)throw Error();return a}function Rb(){return 0}function Fp(a){return Math.sqrt(a.value)}function Ej(a){return function(b){b.children||\n(b.r=Math.max(0,+a(b)||0))}}function ng(a,b){return function(c){if(e=c.children){var e,p,t=e.length,g=a(c)*b||0,z;if(g)for(p=0;p<t;++p)e[p].r+=g;z=Cj(e);if(g)for(p=0;p<t;++p)e[p].r-=g;c.r=z+g}}}function Fj(a){return function(b){var c=b.parent;b.r*=a;c&&(b.x=c.x+a*b.x,b.y=c.y+a*b.y)}}function Gp(a){return a.id}function Hp(a){return a.parentId}function Ip(a,b){return a.parent===b.parent?1:2}function og(a){var b=a.children;return b?b[0]:a.t}function pg(a){var b=a.children;return b?b[b.length-1]:a.t}\nfunction re(a,b){this.Fa=a;this.gp=this.children=this.parent=null;this.a=this;this.s=this.c=this.ic=this.z=0;this.t=null;this.uf=b}function Jp(a){a=new re(a,0);for(var b,c=[a],e,p,g;b=c.pop();)if(p=b.Fa.children)for(b.children=Array(e=p.length),g=e-1;0<=g;--g)c.push(e=b.children[g]=new re(p[g],g)),e.parent=b;(a.parent=new re(null,0)).children=[a];return a}function Gj(a,b,c,e,g,k){for(var p=[],t=b.children,z,n,u=z=0,y=t.length,r,w=b.value,I,R,P,m,T,A;z<y;){b=g-c;r=k-e;do I=t[u++].value;while(!I&&u<\ny);R=P=I;A=Math.max(r/b,b/r)/(w*a);m=I*I*A;for(T=Math.max(P/m,m/R);u<y;++u){I+=n=t[u].value;n<R&&(R=n);n>P&&(P=n);m=I*I*A;m=Math.max(P/m,m/R);if(m>T){I-=n;break}T=m}p.push(z={value:I,wx:b<r,children:t.slice(z,u)});z.wx?bd(z,c,e,g,w?e+=r*I/w:k):se(z,c,e,w?c+=b*I/w:g,k);w-=I;z=u}return p}function Kp(a,b){return a[0]-b[0]||a[1]-b[1]}function Hj(a){for(var b=a.length,c=[0,1],e=2,p=2;p<b;++p){for(;1<e&&0>=Lp(a[c[e-2]],a[c[e-1]],a[p]);)--e;c[e++]=p}return c.slice(0,e)}function qg(a){if(!(1<=a))throw Error();\nthis.WG=a;this.$f=this._error=null;this.Wg=[];this.dl=[];this.ol=this.Ni=this.kq=this.vw=0}function Ij(a){if(!a.vw)try{for(var b=a;b.vw=b.ol&&b.Ni<b.WG;){var c=b.kq+b.Ni,e=b.Wg[c],p=e.length-1,g=e[p];e[p]=Mp(b,c);--b.ol;++b.Ni;e=g.apply(null,e);b.Wg[c]&&(b.Wg[c]=e||Np)}}catch(da){if(a.Wg[a.kq+a.Ni-1])rg(a,da);else if(!a.dl)throw da;}}function Mp(a,b){return function(c,e){a.Wg[b]&&(--a.Ni,++a.kq,a.Wg[b]=null,null==a._error&&(null!=c?rg(a,c):(a.dl[b]=e,a.ol?Ij(a):te(a))))}}function rg(a,b){var c=a.Wg.length;\na._error=b;a.dl=void 0;for(a.ol=NaN;0<=--c;)if(b=a.Wg[c])if(a.Wg[c]=null,b.abort)try{b.abort()}catch(I){}a.Ni=NaN;te(a)}function te(a){if(!a.Ni&&a.$f){var b=a.dl;a.dl=void 0;a.$f(a._error,b)}}function Jj(a){return new qg(arguments.length?+a:Infinity)}function Op(a){return function(b,c){a(null==b?c:null)}}function Pp(a,b){return function(c){return a(c.responseText,b)}}function sg(a){function b(b){var g=b+\"\",t=c.get(g);if(!t){if(p!==tg)return p;c.set(g,t=e.push(b))}return a[(t-1)%a.length]}var c=fb(),\ne=[],p=tg;a=null==a?[]:yb.call(a);b.domain=function(a){if(!arguments.length)return e.slice();e=[];c=fb();for(var p=-1,g=a.length,t,z;++p<g;)c.has(z=(t=a[p])+\"\")||c.set(z,e.push(t));return b};b.range=function(c){return arguments.length?(a=yb.call(c),b):a.slice()};b.unknown=function(a){return arguments.length?(p=a,b):p};b.copy=function(){return sg().domain(e).range(a).unknown(p)};return b}function ug(){function a(){var a=c().length,b=g[1]<g[0],p=g[b-0],t=g[1-b];k=(t-p)/Math.max(1,a-q+2*v);m&&(k=Math.floor(k));\np+=(t-p-k*(a-q))*u;n=k*(1-q);m&&(p=Math.round(p),n=Math.round(n));a=bb(a).map(function(a){return p+k*a});return e(b?a.reverse():a)}var b=sg().unknown(void 0),c=b.domain,e=b.range,g=[0,1],k,n,m=!1,q=0,v=0,u=.5;delete b.unknown;b.domain=function(b){return arguments.length?(c(b),a()):c()};b.range=function(b){return arguments.length?(g=[+b[0],+b[1]],a()):g.slice()};b.rangeRound=function(b){return g=[+b[0],+b[1]],m=!0,a()};b.bandwidth=function(){return n};b.step=function(){return k};b.round=function(b){return arguments.length?\n(m=!!b,a()):m};b.padding=function(b){return arguments.length?(q=v=Math.max(0,Math.min(1,b)),a()):q};b.paddingInner=function(b){return arguments.length?(q=Math.max(0,Math.min(1,b)),a()):q};b.paddingOuter=function(b){return arguments.length?(v=Math.max(0,Math.min(1,b)),a()):v};b.align=function(b){return arguments.length?(u=Math.max(0,Math.min(1,b)),a()):u};b.copy=function(){return ug().domain(c()).range(g).round(m).paddingInner(q).paddingOuter(v).align(u)};return a()}function Kj(a){var b=a.copy;a.padding=\na.paddingOuter;delete a.paddingInner;delete a.paddingOuter;a.copy=function(){return Kj(b())};return a}function Qp(){return Kj(ug().paddingInner(1))}function vg(a,b){return(b-=a=+a)?function(c){return(c-a)/b}:wg(b)}function Rp(a){return function(b,c){var e=a(b=+b,c=+c);return function(a){return a<=b?0:a>=c?1:e(a)}}}function Sp(a){return function(b,c){var e=a(b=+b,c=+c);return function(a){return 0>=a?b:1<=a?c:e(a)}}}function Tp(a,b,c,e){var p=a[0];a=a[1];var g=b[0];b=b[1];a<p?(p=c(a,p),g=e(b,g)):(p=\nc(p,a),g=e(g,b));return function(a){return g(p(a))}}function Up(a,b,c,e){var p=Math.min(a.length,b.length)-1,g=Array(p),t=Array(p),z=-1;a[p]<a[0]&&(a=a.slice().reverse(),b=b.slice().reverse());for(;++z<p;)g[z]=c(a[z],a[z+1]),t[z]=e(b[z],b[z+1]);return function(b){var c=Sb(a,b,1,p)-1;return t[c](g[c](b))}}function ue(a,b){return b.domain(a.domain()).range(a.range()).interpolate(a.interpolate()).clamp(a.clamp())}function ve(a,b){function c(){n=2<Math.min(p.length,g.length)?Up:Tp;m=u=null;return e}function e(b){return(m||\n(m=n(p,g,k?Rp(a):a,t)))(+b)}var p=Lj,g=Lj,t=Pc,k=!1,n,m,u;e.invert=function(a){return(u||(u=n(g,p,vg,k?Sp(b):b)))(+a)};e.domain=function(a){return arguments.length?(p=xg.call(a,Mj),c()):p.slice()};e.range=function(a){return arguments.length?(g=yb.call(a),c()):g.slice()};e.rangeRound=function(a){return g=yb.call(a),t=Nj,c()};e.clamp=function(a){return arguments.length?(k=!!a,c()):k};e.interpolate=function(a){return arguments.length?(t=a,c()):t};return c()}function cd(a){var c=a.domain;a.ticks=function(a){var b=\nc();return we(b[0],b[b.length-1],null==a?10:a)};a.tickFormat=function(a,e){var p;a:{var g=c(),t=g[0],g=g[g.length-1];a=b(t,g,null==a?10:a);e=xe(null==e?\",f\":e);switch(e.type){case \"s\":t=Math.max(Math.abs(t),Math.abs(g));null!=e.precision||isNaN(p=Oj(a,t))||(e.precision=p);p=d3.formatPrefix(e,t);break a;case \"\":case \"e\":case \"g\":case \"p\":case \"r\":null!=e.precision||isNaN(p=Pj(a,Math.max(Math.abs(t),Math.abs(g))))||(e.precision=p-(\"e\"===e.type));break;case \"f\":case \"%\":null!=e.precision||isNaN(p=Qj(a))||\n(e.precision=p-2*(\"%\"===e.type))}p=d3.format(e)}return p};a.nice=function(e){var p=c(),g=p.length-1;e=null==e?10:e;var t=p[0],k=p[g],z=b(t,k,e);z&&(z=b(Math.floor(t/z)*z,Math.ceil(k/z)*z,e),p[0]=Math.floor(t/z)*z,p[g]=Math.ceil(k/z)*z,c(p));return a};return a}function Rj(){var a=ve(vg,Na);a.copy=function(){return ue(a,Rj())};return cd(a)}function Sj(){function a(a){return+a}var b=[0,1];a.invert=a;a.domain=a.range=function(c){return arguments.length?(b=xg.call(c,Mj),a):b.slice()};a.copy=function(){return Sj().domain(b)};\nreturn cd(a)}function Vp(a,b){return(b=Math.log(b/a))?function(c){return Math.log(c/a)/b}:wg(b)}function Wp(a,b){return 0>a?function(c){return-Math.pow(-b,c)*Math.pow(-a,1-c)}:function(c){return Math.pow(b,c)*Math.pow(a,1-c)}}function Xp(a){return isFinite(a)?+(\"1e\"+a):0>a?0:a}function Tj(a){return 10===a?Xp:a===Math.E?Math.exp:function(b){return Math.pow(a,b)}}function Uj(a){return a===Math.E?Math.log:10===a&&Math.log10||2===a&&Math.log2||(a=Math.log(a),function(b){return Math.log(b)/a})}function Vj(a){return function(b){return-a(-b)}}\nfunction Wj(){function a(){g=Uj(e);k=Tj(e);0>c()[0]&&(g=Vj(g),k=Vj(k));return b}var b=ve(Vp,Wp).domain([1,10]),c=b.domain,e=10,g=Uj(10),k=Tj(10);b.base=function(b){return arguments.length?(e=+b,a()):e};b.domain=function(b){return arguments.length?(c(b),a()):c()};b.ticks=function(a){var b=c(),p=b[0],b=b[b.length-1],t;if(t=b<p)u=p,p=b,b=u;var u=g(p),z=g(b),r,w,n;r=null==a?10:+a;a=[];if(!(e%1)&&z-u<r)if(u=Math.round(u)-1,z=Math.round(z)+1,0<p)for(;u<z;++u)for(w=1,r=k(u);w<e;++w){if(n=r*w,!(n<p)){if(n>\nb)break;a.push(n)}}else for(;u<z;++u)for(w=e-1,r=k(u);1<=w;--w){if(n=r*w,!(n<p)){if(n>b)break;a.push(n)}}else a=we(u,z,Math.min(z-u,r)).map(k);return t?a.reverse():a};b.tickFormat=function(a,c){null==c&&(c=10===e?\".0e\":\",\");\"function\"!==typeof c&&(c=d3.format(c));if(Infinity===a)return c;null==a&&(a=10);var p=Math.max(1,e*a/b.ticks().length);return function(a){var b=a/k(Math.round(g(a)));b*e<e-.5&&(b*=e);return b<=p?c(a):\"\"}};b.nice=function(){return c(Xj(c(),{floor:function(a){return k(Math.floor(g(a)))},\nceil:function(a){return k(Math.ceil(g(a)))}}))};b.copy=function(){return ue(b,Wj().base(e))};return b}function pc(a,b){return 0>a?-Math.pow(-a,b):Math.pow(a,b)}function yg(){function a(a,b){return(b=pc(b,c)-(a=pc(a,c)))?function(e){return(pc(e,c)-a)/b}:wg(b)}function b(a,b){b=pc(b,c)-(a=pc(a,c));return function(e){return pc(a+b*e,1/c)}}var c=1,e=ve(a,b),g=e.domain;e.exponent=function(a){return arguments.length?(c=+a,g(g())):c};e.copy=function(){return ue(e,yg().exponent(c))};return cd(e)}function Yp(){return yg().exponent(.5)}\nfunction Yj(){function a(){var a=0,p=Math.max(1,e.length);for(g=Array(p-1);++a<p;)g[a-1]=dd(c,a/p);return b}function b(a){if(!isNaN(a=+a))return e[Sb(g,a)]}var c=[],e=[],g=[];b.invertExtent=function(a){a=e.indexOf(a);return 0>a?[NaN,NaN]:[0<a?g[a-1]:c[0],a<g.length?g[a]:c[c.length-1]]};b.domain=function(b){if(!arguments.length)return c.slice();c=[];for(var e=0,p=b.length,g;e<p;++e)(g=b[e],null==g||isNaN(g=+g))||c.push(g);c.sort(Eb);return a()};b.range=function(b){return arguments.length?(e=yb.call(b),\na()):e.slice()};b.quantiles=function(){return g.slice()};b.copy=function(){return Yj().domain(c).range(e)};return b}function Zj(){function a(a){if(a<=a)return n[Sb(k,a,0,g)]}function b(){var b=-1;for(k=Array(g);++b<g;)k[b]=((b+1)*e-(b-g)*c)/(g+1);return a}var c=0,e=1,g=1,k=[.5],n=[0,1];a.domain=function(a){return arguments.length?(c=+a[0],e=+a[1],b()):[c,e]};a.range=function(a){return arguments.length?(g=(n=yb.call(a)).length-1,b()):n.slice()};a.invertExtent=function(a){a=n.indexOf(a);return 0>a?\n[NaN,NaN]:1>a?[c,k[0]]:a>=g?[k[g-1],e]:[k[a-1],k[a]]};a.copy=function(){return Zj().domain([c,e]).range(n)};return cd(a)}function ak(){function a(a){if(a<=a)return c[Sb(b,a,0,e)]}var b=[.5],c=[0,1],e=1;a.domain=function(p){return arguments.length?(b=yb.call(p),e=Math.min(b.length,c.length-1),a):b.slice()};a.range=function(p){return arguments.length?(c=yb.call(p),e=Math.min(b.length,c.length-1),a):c.slice()};a.invertExtent=function(a){a=c.indexOf(a);return[b[a-1],b[a]]};a.copy=function(){return ak().domain(b).range(c)};\nreturn a}function xa(a,b,c,e){function p(b){return a(b=new Date(+b)),b}p.floor=p;p.ceil=function(c){return a(c=new Date(c-1)),b(c,1),a(c),c};p.round=function(a){var b=p(a),c=p.ceil(a);return a-b<c-a?b:c};p.offset=function(a,c){return b(a=new Date(+a),null==c?1:Math.floor(c)),a};p.range=function(c,e,g){var t=[];c=p.ceil(c);g=null==g?1:Math.floor(g);if(!(c<e&&0<g))return t;do t.push(new Date(+c));while(b(c,g),a(c),c<e);return t};p.filter=function(c){return xa(function(b){if(b>=b)for(;a(b),!c(b);)b.setTime(b-\n1)},function(a,e){if(a>=a)for(;0<=--e;)for(;b(a,1),!c(a););})};c&&(p.count=function(b,e){zg.setTime(+b);Ag.setTime(+e);a(zg);a(Ag);return Math.floor(c(zg,Ag))},p.every=function(a){a=Math.floor(a);return isFinite(a)&&0<a?1<a?p.filter(e?function(b){return 0===e(b)%a}:function(b){return 0===p.count(0,b)%a}):p:null});return p}function Tb(a){return xa(function(b){b.setDate(b.getDate()-(b.getDay()+7-a)%7);b.setHours(0,0,0,0)},function(a,b){a.setDate(a.getDate()+7*b)},function(a,b){return(b-a-6E4*(b.getTimezoneOffset()-\na.getTimezoneOffset()))/6048E5})}function Ub(a){return xa(function(b){b.setUTCDate(b.getUTCDate()-(b.getUTCDay()+7-a)%7);b.setUTCHours(0,0,0,0)},function(a,b){a.setUTCDate(a.getUTCDate()+7*b)},function(a,b){return(b-a)/6048E5})}function Zp(a){if(0<=a.y&&100>a.y){var b=new Date(-1,a.ic,a.d,a.kh,a.Ei,a.Sk,a.sb);b.setFullYear(a.y);return b}return new Date(a.y,a.ic,a.d,a.kh,a.Ei,a.Sk,a.sb)}function Bg(a){if(0<=a.y&&100>a.y){var b=new Date(Date.UTC(-1,a.ic,a.d,a.kh,a.Ei,a.Sk,a.sb));b.setUTCFullYear(a.y);\nreturn b}return new Date(Date.UTC(a.y,a.ic,a.d,a.kh,a.Ei,a.Sk,a.sb))}function Cg(a){return{y:a,ic:0,d:1,kh:0,Ei:0,Sk:0,sb:0}}function bk(a){function b(a,b){return function(c){var e=[],p=-1,g=0,t=a.length,r,u;for(c instanceof Date||(c=new Date(+c));++p<t;)if(37===a.charCodeAt(p)){e.push(a.slice(g,p));null!=(g=ck[r=a.charAt(++p)])?r=a.charAt(++p):g=\"e\"===r?\" \":\"0\";if(u=b[r])r=u(c,g);e.push(r);g=p+1}e.push(a.slice(g,p));return e.join(\"\")}}function c(a,b){return function(c){var p=Cg(1900),g=e(p,a,c+=\n\"\",0);if(g!=c.length)return null;\"p\"in p&&(p.kh=p.kh%12+12*p.p);if(\"W\"in p||\"U\"in p)\"w\"in p||(p.w=\"W\"in p?1:0),c=\"Z\"in p?Bg(Cg(p.y)).getUTCDay():b(Cg(p.y)).getDay(),p.ic=0,p.d=\"W\"in p?(p.w+6)%7+7*p.W-(c+5)%7:p.w+7*p.U-(c+6)%7;return\"Z\"in p?(p.kh+=p.Z/100|0,p.Ei+=p.Z%100,Bg(p)):b(p)}}function e(a,b,c,e){for(var p=0,g=b.length,t=c.length,r;p<g;){if(e>=t)return-1;r=b.charCodeAt(p++);if(37===r){if(r=b.charAt(p++),r=Ka[r in ck?b.charAt(p++):r],!r||0>(e=r(a,c,e)))return-1}else if(r!=c.charCodeAt(e++))return-1}return e}\nfunction p(a,b,c){return(b=J.exec(b.slice(c)))?(a.p=C[b[0].toLowerCase()],c+b[0].length):-1}function g(a,b,c){return(b=K.exec(b.slice(c)))?(a.w=Q[b[0].toLowerCase()],c+b[0].length):-1}function k(a,b,c){return(b=W.exec(b.slice(c)))?(a.w=O[b[0].toLowerCase()],c+b[0].length):-1}function n(a,b,c){return(b=na.exec(b.slice(c)))?(a.ic=ka[b[0].toLowerCase()],c+b[0].length):-1}function m(a,b,c){return(b=U.exec(b.slice(c)))?(a.ic=aa[b[0].toLowerCase()],c+b[0].length):-1}function q(a,b,c){return e(a,M,b,c)}\nfunction u(a,b,c){return e(a,G,b,c)}function y(a,b,c){return e(a,Xa,b,c)}function r(a){return v[a.getDay()]}function w(a){return Aa[a.getDay()]}function H(a){return E[a.getMonth()]}function F(a){return B[a.getMonth()]}function ca(a){return Y[+(12<=a.getHours())]}function qa(a){return v[a.getUTCDay()]}function T(a){return Aa[a.getUTCDay()]}function A(a){return E[a.getUTCMonth()]}function L(a){return B[a.getUTCMonth()]}function ja(a){return Y[+(12<=a.getUTCHours())]}var M=a.dateTime,G=a.date,Xa=a.time,\nY=a.periods,Aa=a.days,v=a.shortDays,B=a.months,E=a.shortMonths,J=ed(Y),C=fd(Y),W=ed(Aa),O=fd(Aa),K=ed(v),Q=fd(v),U=ed(B),aa=fd(B),na=ed(E),ka=fd(E),ta={a:r,A:w,b:H,B:F,c:null,d:dk,e:dk,H:$p,I:aq,j:bq,L:cq,m:dq,M:eq,p:ca,S:fq,U:gq,w:hq,W:iq,x:null,X:null,y:jq,Y:kq,Z:lq,\"%\":ek},ma={a:qa,A:T,b:A,B:L,c:null,d:fk,e:fk,H:mq,I:nq,j:oq,L:pq,m:qq,M:rq,p:ja,S:sq,U:tq,w:uq,W:vq,x:null,X:null,y:wq,Y:xq,Z:yq,\"%\":ek},Ka={a:g,A:k,b:n,B:m,c:q,d:gk,e:gk,H:hk,I:hk,j:zq,L:Aq,m:Bq,M:Cq,p:p,S:Dq,U:Eq,w:Fq,W:Gq,x:u,X:y,\ny:Hq,Y:Iq,Z:Jq,\"%\":Kq};ta.x=b(G,ta);ta.X=b(Xa,ta);ta.c=b(M,ta);ma.x=b(G,ma);ma.X=b(Xa,ma);ma.c=b(M,ma);return{format:function(a){var c=b(a+=\"\",ta);c.toString=function(){return a};return c},parse:function(a){var b=c(a+=\"\",Zp);b.toString=function(){return a};return b},utcFormat:function(a){var c=b(a+=\"\",ma);c.toString=function(){return a};return c},utcParse:function(a){var b=c(a,Bg);b.toString=function(){return a};return b}}}function oa(a,b,c){var e=0>a?\"-\":\"\";a=(e?-a:a)+\"\";var p=a.length;return e+\n(p<c?Array(c-p+1).join(b)+a:a)}function Lq(a){return a.replace(Mq,\"\\\\$\\x26\")}function ed(a){return new RegExp(\"^(?:\"+a.map(Lq).join(\"|\")+\")\",\"i\")}function fd(a){for(var b={},c=-1,e=a.length;++c<e;)b[a[c].toLowerCase()]=c;return b}function Fq(a,b,c){return(b=Va.exec(b.slice(c,c+1)))?(a.w=+b[0],c+b[0].length):-1}function Eq(a,b,c){return(b=Va.exec(b.slice(c)))?(a.U=+b[0],c+b[0].length):-1}function Gq(a,b,c){return(b=Va.exec(b.slice(c)))?(a.W=+b[0],c+b[0].length):-1}function Iq(a,b,c){return(b=Va.exec(b.slice(c,\nc+4)))?(a.y=+b[0],c+b[0].length):-1}function Hq(a,b,c){return(b=Va.exec(b.slice(c,c+2)))?(a.y=+b[0]+(68<+b[0]?1900:2E3),c+b[0].length):-1}function Jq(a,b,c){return(b=/^(Z)|([+-]\\d\\d)(?:\\:?(\\d\\d))?/.exec(b.slice(c,c+6)))?(a.Z=b[1]?0:-(b[2]+(b[3]||\"00\")),c+b[0].length):-1}function Bq(a,b,c){return(b=Va.exec(b.slice(c,c+2)))?(a.ic=b[0]-1,c+b[0].length):-1}function gk(a,b,c){return(b=Va.exec(b.slice(c,c+2)))?(a.d=+b[0],c+b[0].length):-1}function zq(a,b,c){return(b=Va.exec(b.slice(c,c+3)))?(a.ic=0,a.d=\n+b[0],c+b[0].length):-1}function hk(a,b,c){return(b=Va.exec(b.slice(c,c+2)))?(a.kh=+b[0],c+b[0].length):-1}function Cq(a,b,c){return(b=Va.exec(b.slice(c,c+2)))?(a.Ei=+b[0],c+b[0].length):-1}function Dq(a,b,c){return(b=Va.exec(b.slice(c,c+2)))?(a.Sk=+b[0],c+b[0].length):-1}function Aq(a,b,c){return(b=Va.exec(b.slice(c,c+3)))?(a.sb=+b[0],c+b[0].length):-1}function Kq(a,b,c){return(a=Nq.exec(b.slice(c,c+1)))?c+a[0].length:-1}function dk(a,b){return oa(a.getDate(),b,2)}function $p(a,b){return oa(a.getHours(),\nb,2)}function aq(a,b){return oa(a.getHours()%12||12,b,2)}function bq(a,b){return oa(1+ye.count(Vb(a),a),b,3)}function cq(a,b){return oa(a.getMilliseconds(),b,3)}function dq(a,b){return oa(a.getMonth()+1,b,2)}function eq(a,b){return oa(a.getMinutes(),b,2)}function fq(a,b){return oa(a.getSeconds(),b,2)}function gq(a,b){return oa(gd.count(Vb(a),a),b,2)}function hq(a){return a.getDay()}function iq(a,b){return oa(Dg.count(Vb(a),a),b,2)}function jq(a,b){return oa(a.getFullYear()%100,b,2)}function kq(a,\nb){return oa(a.getFullYear()%1E4,b,4)}function lq(a){a=a.getTimezoneOffset();return(0<a?\"-\":(a*=-1,\"+\"))+oa(a/60|0,\"0\",2)+oa(a%60,\"0\",2)}function fk(a,b){return oa(a.getUTCDate(),b,2)}function mq(a,b){return oa(a.getUTCHours(),b,2)}function nq(a,b){return oa(a.getUTCHours()%12||12,b,2)}function oq(a,b){return oa(1+ze.count(Wb(a),a),b,3)}function pq(a,b){return oa(a.getUTCMilliseconds(),b,3)}function qq(a,b){return oa(a.getUTCMonth()+1,b,2)}function rq(a,b){return oa(a.getUTCMinutes(),b,2)}function sq(a,\nb){return oa(a.getUTCSeconds(),b,2)}function tq(a,b){return oa(hd.count(Wb(a),a),b,2)}function uq(a){return a.getUTCDay()}function vq(a,b){return oa(Eg.count(Wb(a),a),b,2)}function wq(a,b){return oa(a.getUTCFullYear()%100,b,2)}function xq(a,b){return oa(a.getUTCFullYear()%1E4,b,4)}function yq(){return\"+0000\"}function ek(){return\"%\"}function ik(a){qc=bk(a);d3.timeFormat=qc.format;d3.timeParse=qc.parse;d3.utcFormat=qc.utcFormat;d3.utcParse=qc.utcParse;return qc}function Oq(a){return a.toISOString()}\nfunction Pq(a){a=new Date(a);return isNaN(a)?null:a}function Qq(a){return new Date(a)}function Rq(a){return a instanceof Date?+a:+new Date(+a)}function Fg(a,c,e,g,k,n,m,q,v){function p(b){return(m(b)<b?H:n(b)<b?F:k(b)<b?I:g(b)<b?P:c(b)<b?e(b)<b?T:A:a(b)<b?L:R)(b)}function t(c,e,p,g){null==c&&(c=10);if(\"number\"===typeof c){g=Math.abs(p-e)/c;var r=Gg(function(a){return a[2]}).right(M,g);r===M.length?(g=b(e/31536E6,p/31536E6,c),c=a):r?(r=M[g/M[r-1][2]<M[r][2]/g?r-1:r],g=r[1],c=r[0]):(g=b(e,p,c),c=q)}return null==\ng?c:c.every(g)}var z=ve(vg,Na),r=z.invert,w=z.domain,H=v(\".%L\"),F=v(\":%S\"),I=v(\"%I:%M\"),P=v(\"%I %p\"),T=v(\"%a %d\"),A=v(\"%b %d\"),L=v(\"%B\"),R=v(\"%Y\"),M=[[m,1,1E3],[m,5,5E3],[m,15,15E3],[m,30,3E4],[n,1,6E4],[n,5,3E5],[n,15,9E5],[n,30,18E5],[k,1,36E5],[k,3,108E5],[k,6,216E5],[k,12,432E5],[g,1,864E5],[g,2,1728E5],[e,1,6048E5],[c,1,2592E6],[c,3,7776E6],[a,1,31536E6]];z.invert=function(a){return new Date(r(a))};z.domain=function(a){return arguments.length?w(xg.call(a,Rq)):w().map(Qq)};z.ticks=function(a,\nb){var c=w(),e=c[0],c=c[c.length-1],p=c<e,g;p&&(g=e,e=c,c=g);g=(g=t(a,e,c,b))?g.range(e,c+1):[];return p?g.reverse():g};z.tickFormat=function(a,b){return null==b?p:v(b)};z.nice=function(a,b){var c=w();return(a=t(a,c[0],c[c.length-1],b))?w(Xj(c,a)):z};z.copy=function(){return ue(z,Fg(a,c,e,g,k,n,m,q,v))};return z}function Ae(a){var b=a.length;return function(c){return a[Math.max(0,Math.min(b-1,Math.floor(c*b)))]}}function jk(a){function b(b){b=(b-c)/(e-c);return a(p?Math.max(0,Math.min(1,b)):b)}var c=\n0,e=1,p=!1;b.domain=function(a){return arguments.length?(c=+a[0],e=+a[1],b):[c,e]};b.clamp=function(a){return arguments.length?(p=!!a,b):p};b.interpolator=function(c){return arguments.length?(a=c,b):a};b.copy=function(){return jk(a).domain([c,e]).clamp(p)};return cd(b)}function Sq(a){return a.innerRadius}function Tq(a){return a.outerRadius}function Uq(a){return a.startAngle}function Vq(a){return a.endAngle}function Wq(a){return a&&a.padAngle}function kk(a){return 1<=a?Be:-1>=a?-Be:Math.asin(a)}function Ce(a,\nb,c,e,g,k,n){var p=a-c,t=b-e;n=(n?k:-k)/Math.sqrt(p*p+t*t);var t=n*t,p=-n*p,z=a+t,u=b+p,y=c+t,r=e+p;c=(z+y)/2;e=(u+r)/2;b=y-z;a=r-u;n=b*b+a*a;k=g-k;var r=z*r-y*u,w=(0>a?-1:1)*Math.sqrt(Math.max(0,k*k*n-r*r)),z=(r*a-b*w)/n,u=(-r*b-a*w)/n,y=(r*a+b*w)/n;b=(-r*b+a*w)/n;a=z-c;n=u-e;c=y-c;e=b-e;a*a+n*n>c*c+e*e&&(z=y,u=b);return{cx:z,cy:u,bh:-t,dh:-p,wi:z*(g/k-1),yi:u*(g/k-1)}}function lk(a){this.Ia=a}function mk(a){return a[0]}function nk(a){return a[1]}function ok(a){this.Uh=a}function Hg(a){function b(b){return new ok(a(b))}\nb.Uh=a;return b}function id(a){var b=a.curve;a.angle=a.x;delete a.x;a.radius=a.y;delete a.y;a.curve=function(a){return arguments.length?b(Hg(a)):b().Uh};return a}function De(a,b,c){a.Ia.bezierCurveTo((2*a.ub+a.Sa)/3,(2*a.xb+a.Va)/3,(a.ub+2*a.Sa)/3,(a.xb+2*a.Va)/3,(a.ub+4*a.Sa+b)/6,(a.xb+4*a.Va+c)/6)}function Ee(a){this.Ia=a}function pk(a){this.Ia=a}function qk(a){this.Ia=a}function rk(a,b){this.bq=new Ee(a);this.sn=b}function Fe(a,b,c){a.Ia.bezierCurveTo(a.Sa+a.Tj*(a.Mb-a.ub),a.Va+a.Tj*(a.Nb-a.xb),\na.Mb+a.Tj*(a.Sa-b),a.Nb+a.Tj*(a.Va-c),a.Mb,a.Nb)}function Ig(a,b){this.Ia=a;this.Tj=(1-b)/6}function Jg(a,b){this.Ia=a;this.Tj=(1-b)/6}function Kg(a,b){this.Ia=a;this.Tj=(1-b)/6}function Lg(a,b,c){var e=a.Sa,g=a.Va,p=a.Mb,t=a.Nb;if(1E-12<a.sh)var k=2*a.Wh+3*a.sh*a.qg+a.Hf,z=3*a.sh*(a.sh+a.qg),e=(e*k-a.ub*a.Hf+a.Mb*a.Wh)/z,g=(g*k-a.xb*a.Hf+a.Nb*a.Wh)/z;1E-12<a.rg&&(k=2*a.Cg+3*a.rg*a.qg+a.Hf,z=3*a.rg*(a.rg+a.qg),p=(p*k+a.Sa*a.Cg-b*a.Hf)/z,t=(t*k+a.Va*a.Cg-c*a.Hf)/z);a.Ia.bezierCurveTo(e,g,p,t,a.Mb,\na.Nb)}function sk(a,b){this.Ia=a;this.bl=b}function tk(a,b){this.Ia=a;this.bl=b}function uk(a,b){this.Ia=a;this.bl=b}function vk(a){this.Ia=a}function wk(a,b,c){var e=a.Sa-a.ub,g=b-a.Sa;b=(a.Va-a.xb)/(e||0>g&&-0);a=(c-a.Va)/(g||0>e&&-0);e=(b*g+a*e)/(e+g);return((0>b?-1:1)+(0>a?-1:1))*Math.min(Math.abs(b),Math.abs(a),.5*Math.abs(e))||0}function xk(a,b){var c=a.Sa-a.ub;return c?(3*(a.Va-a.xb)/c-b)/2:b}function Mg(a,b,c){var e=a.ub,g=a.xb,p=a.Sa,t=a.Va,k=(p-e)/3;a.Ia.bezierCurveTo(e+k,g+k*b,p-k,t-k*\nc,p,t)}function Ge(a){this.Ia=a}function yk(a){this.Ia=new zk(a)}function zk(a){this.Ia=a}function Xq(a){return new Ge(a)}function Yq(a){return new yk(a)}function Ak(a){this.Ia=a}function Bk(a){var b,c=a.length-1,e,g=Array(c),p=Array(c),k=Array(c);g[0]=0;p[0]=2;k[0]=a[0]+2*a[1];for(b=1;b<c-1;++b)g[b]=1,p[b]=4,k[b]=4*a[b]+2*a[b+1];g[c-1]=2;p[c-1]=7;k[c-1]=8*a[c-1]+a[c];for(b=1;b<c;++b)e=g[b]/p[b-1],p[b]-=e,k[b]-=e*k[b-1];g[c-1]=k[c-1]/p[c-1];for(b=c-2;0<=b;--b)g[b]=(k[b]-g[b+1])/p[b];p[c-1]=(a[c]+\ng[c-1])/2;for(b=0;b<c-1;++b)p[b]=2*a[b+1]-g[b+1];return[g,p]}function He(a,b){this.Ia=a;this.Zi=b}function Zq(a){return new He(a,0)}function $q(a){return new He(a,1)}function ar(a,b){return a[b]}function Ck(a){for(var b=0,c=-1,e=a.length,g;++c<e;)if(g=+a[c][1])b+=g;return b}function br(a){return a[0]}function cr(a){return a[1]}function Ie(){this.Fa=null}function Je(a){a.qd=a.qb=a.sb=a.ac=a.Ue=a.pe=null}function jd(a,b){var c=b;b=b.ac;var e=c.qd;e?e.sb===c?e.sb=b:e.ac=b:a.Fa=b;b.qd=e;c.qd=b;c.ac=b.sb;\nc.ac&&(c.ac.qd=c);b.sb=c}function kd(a,b){var c=b;b=b.sb;var e=c.qd;e?e.sb===c?e.sb=b:e.ac=b:a.Fa=b;b.qd=e;c.qd=b;c.sb=b.ac;c.sb&&(c.sb.qd=c);b.ac=c}function Dk(a){for(;a.sb;)a=a.sb;return a}function ld(a,b,c,e){var g=[null,null],p=Fa.push(g)-1;g.left=a;g.right=b;c&&Ke(g,a,b,c);e&&Ke(g,b,a,e);Ra[a.index].halfedges.push(p);Ra[b.index].halfedges.push(p);return g}function md(a,b,c){b=[b,c];b.left=a;return b}function Ke(a,b,c,e){a[0]||a[1]?a.left===c?a[1]=e:a[0]=e:(a[0]=e,a.left=b,a.right=c)}function dr(a,\nb,c,e,g){var p=a[0],k=a[1],t=p[0],p=p[1],n=k[0],z=k[1],k=0,u=1,n=n-t,z=z-p;b-=t;if(n||!(0<b)){b/=n;if(0>n){if(b<k)return;b<u&&(u=b)}else if(0<n){if(b>u)return;b>k&&(k=b)}b=e-t;if(n||!(0>b)){b/=n;if(0>n){if(b>u)return;b>k&&(k=b)}else if(0<n){if(b<k)return;b<u&&(u=b)}b=c-p;if(z||!(0<b)){b/=z;if(0>z){if(b<k)return;b<u&&(u=b)}else if(0<z){if(b>u)return;b>k&&(k=b)}b=g-p;if(z||!(0>b)){b/=z;if(0>z){if(b>u)return;b>k&&(k=b)}else if(0<z){if(b<k)return;b<u&&(u=b)}if(!(0<k||1>u))return!0;0<k&&(a[0]=[t+k*n,p+\nk*z]);1>u&&(a[1]=[t+u*n,p+u*z]);return!0}}}}}function er(a,b,c,e,g){var p=a[1];if(p)return!0;var k=a[0],t=a.left,n=a.right,p=t[0],t=t[1],z=n[0],n=n[1],u=(p+z)/2,y=(t+n)/2,r;if(n===t){if(u<b||u>=e)return;if(p>z){if(!k)k=[u,c];else if(k[1]>=g)return;p=[u,g]}else{if(!k)k=[u,g];else if(k[1]<c)return;p=[u,c]}}else if(r=(p-z)/(n-t),u=y-r*u,-1>r||1<r)if(p>z){if(!k)k=[(c-u)/r,c];else if(k[1]>=g)return;p=[(g-u)/r,g]}else{if(!k)k=[(g-u)/r,g];else if(k[1]<c)return;p=[(c-u)/r,c]}else if(t<n){if(!k)k=[b,r*b+u];\nelse if(k[0]>=e)return;p=[e,r*e+u]}else{if(!k)k=[e,r*e+u];else if(k[0]<b)return;p=[b,r*b+u]}a[0]=k;a[1]=p;return!0}function fr(a,b){a=a.site;var c=b.left,e=b.right;a===e&&(e=c,c=a);if(e)return Math.atan2(e[1]-c[1],e[0]-c[0]);a===c?(c=b[1],e=b[0]):(c=b[0],e=b[1]);return Math.atan2(c[0]-e[0],e[1]-c[1])}function Ek(a,b){return b[+(b.left!==a.site)]}function gr(){for(var a=0,b=Ra.length,c,e,g,k;a<b;++a)if((c=Ra[a])&&(k=(e=c.halfedges).length)){var n=Array(k),m=Array(k);for(g=0;g<k;++g)n[g]=g,m[g]=fr(c,\nFa[e[g]]);n.sort(function(a,b){return m[b]-m[a]});for(g=0;g<k;++g)m[g]=e[n[g]];for(g=0;g<k;++g)e[g]=m[g]}}function hr(){Je(this);this.x=this.y=this.arc=this.site=this.cy=null}function rc(a){var b=a.Ue,c=a.pe;if(b&&c){var e=b.site,b=a.site,g=c.site;if(e!==g){var c=b[0],p=b[1],k=e[0]-c,n=e[1]-p,e=g[0]-c,m=g[1]-p,g=2*(k*m-n*e);if(!(g>=-ir)){var q=k*k+n*n,u=e*e+m*m,n=(m*q-n*u)/g,e=(k*u-e*q)/g,k=Fk.pop()||new hr;k.arc=a;k.site=b;k.x=n+c;k.y=(k.cy=e+p)+Math.sqrt(n*n+e*e);a.Yg=k;a=null;for(b=nd.Fa;b;)if(k.y<\nb.y||k.y===b.y&&k.x<=b.x)if(b.sb)b=b.sb;else{a=b.Ue;break}else if(b.ac)b=b.ac;else{a=b;break}nd.insert(a,k);a||(Ng=k)}}}}function sc(a){var b=a.Yg;b&&(b.Ue||(Ng=b.pe),nd.remove(b),Fk.push(b),Je(b),a.Yg=null)}function jr(){Je(this);this.gi=this.site=this.Yg=null}function Gk(a){var b=Hk.pop()||new jr;b.site=a;return b}function Og(a){sc(a);tc.remove(a);Hk.push(a);Je(a)}function Ik(a,b){var c=a.site,e=c[0],g=c[1],p=g-b;if(!p)return e;a=a.Ue;if(!a)return-Infinity;c=a.site;a=c[0];c=c[1];b=c-b;if(!b)return a;\nvar k=a-e,t=1/p-1/b,n=k/b;return t?(-n+Math.sqrt(n*n-2*t*(k*k/(-2*b)-c+b/2+g-p/2)))/t+e:(e+a)/2}function kr(a,b){return b[1]-a[1]||b[0]-a[0]}function Pg(a,b){var c=a.sort(kr).pop(),e,g,p;Fa=[];Ra=Array(a.length);tc=new Ie;for(nd=new Ie;;)if(p=Ng,c&&(!p||c[1]<p.y||c[1]===p.y&&c[0]<p.x)){if(c[0]!==e||c[1]!==g){var k,t;g=e=void 0;p=c;for(var n=p[0],m=p[1],u=tc.Fa;u;)if(t=Ik(u,m)-n,t>la)u=u.sb;else if((k=u.pe)?k=Ik(k,m):(k=u.site,k=k[1]===m?k[0]:Infinity),k=n-k,k>la){if(!u.ac){g=u;break}u=u.ac}else{t>\n-la?(g=u.Ue,e=u):k>-la?(g=u,e=u.pe):g=e=u;break}Ra[p.index]={site:p,halfedges:[]};t=Gk(p);tc.insert(g,t);if(g||e)if(g===e)sc(g),e=Gk(g.site),tc.insert(t,e),t.gi=e.gi=ld(g.site,t.site),rc(g),rc(e);else if(e){sc(g);sc(e);n=g.site;u=n[0];k=n[1];var y=p[0]-u,r=p[1]-k,m=e.site,w=m[0]-u,H=m[1]-k,F=2*(y*H-r*w),ca=y*y+r*r,q=w*w+H*H,u=[(H*ca-r*q)/F+u,(y*q-w*ca)/F+k];Ke(e.gi,n,m,u);t.gi=ld(n,p,null,u);e.gi=ld(p,m,null,u);rc(g);rc(e)}else t.gi=ld(g.site,t.site);e=c[0];g=c[1]}c=a.pop()}else if(p){m=p.arc;p=m.Yg;\nn=p.x;u=p.cy;p=[n,u];y=m.Ue;k=m.pe;t=[m];Og(m);for(m=y;m.Yg&&Math.abs(n-m.Yg.x)<la&&Math.abs(u-m.Yg.cy)<la;)y=m.Ue,t.unshift(m),Og(m),m=y;t.unshift(m);sc(m);for(y=k;y.Yg&&Math.abs(n-y.Yg.x)<la&&Math.abs(u-y.Yg.cy)<la;)k=y.pe,t.push(y),Og(y),y=k;t.push(y);sc(y);u=t.length;for(n=1;n<u;++n)y=t[n],m=t[n-1],Ke(y.gi,m.site,y.site,p);m=t[0];y=t[u-1];y.gi=ld(m.site,y.site,null,p);rc(m);rc(y)}else break;gr();if(b){g=+b[0][0];e=+b[0][1];a=+b[1][0];c=+b[1][1];b=g;p=e;t=a;for(var n=c,m=Fa.length,T;m--;)er(T=\nFa[m],b,p,t,n)&&dr(T,b,p,t,n)&&(Math.abs(T[0][0]-T[1][0])>la||Math.abs(T[0][1]-T[1][1])>la)||delete Fa[m];b=g;T=e;g=c;var c=Ra.length,A;e=!0;for(p=0;p<c;++p)if(t=Ra[p]){A=t.site;m=t.halfedges;for(n=m.length;n--;)Fa[m[n]]||m.splice(n,1);n=0;for(u=m.length;n<u;)if(k=Fa[m[n]],y=k[+(k.left===t.site)],r=y[0],w=y[1],H=Ek(t,Fa[m[++n%u]]),k=H[0],H=H[1],Math.abs(r-k)>la||Math.abs(w-H)>la)m.splice(n,0,Fa.push(md(A,y,Math.abs(r-b)<la&&g-w>la?[b,Math.abs(k-b)<la?H:g]:Math.abs(w-g)<la&&a-r>la?[Math.abs(H-g)<la?\nk:a,g]:Math.abs(r-a)<la&&w-T>la?[a,Math.abs(k-a)<la?H:T]:Math.abs(w-T)<la&&r-b>la?[Math.abs(H-T)<la?k:b,T]:null))-1),++u;u&&(e=!1)}if(e){n=Infinity;p=0;for(e=null;p<c;++p)if(t=Ra[p])A=t.site,m=A[0]-b,u=A[1]-T,m=m*m+u*u,m<n&&(n=m,e=t);e&&(p=[b,T],b=[b,g],g=[a,g],T=[a,T],e.halfedges.push(Fa.push(md(A=e.site,p,b))-1,Fa.push(md(A,b,g))-1,Fa.push(md(A,g,T))-1,Fa.push(md(A,T,p))-1))}for(p=0;p<c;++p)if(t=Ra[p])t.halfedges.length||delete Ra[p]}this.edges=Fa;this.cells=Ra;tc=nd=Fa=Ra=null}function lr(a,b,\nc){this.target=a;this.type=b;this.transform=c}function qb(a,b,c){this.k=a;this.x=b;this.y=c}function Jk(a){return a.__zoom||Qg}function mr(){return!d3.event.button}function nr(){var a=this,b;a instanceof SVGElement?(a=a.ownerSVGElement||a,b=a.width.baseVal.value,a=a.height.baseVal.value):(b=a.clientWidth,a=a.clientHeight);return[[0,0],[b,a]]}function Kk(){return this.__zoom||Qg}var Eb=function(a,b){return a<b?-1:a>b?1:a>=b?0:NaN},Gg=function(b){1===b.length&&(b=a(b));return{left:function(a,c,e,g){null==\ne&&(e=0);null==g&&(g=a.length);for(;e<g;){var p=e+g>>>1;0>b(a[p],c)?e=p+1:g=p}return e},right:function(a,c,e,g){null==e&&(e=0);null==g&&(g=a.length);for(;e<g;){var p=e+g>>>1;0<b(a[p],c)?g=p:e=p+1}return e}}},Lk=Gg(Eb),Sb=Lk.right,or=Lk.left,pr=function(a,b){return b<a?-1:b>a?1:b>=a?0:NaN},zb=function(a){return null===a?NaN:+a},Mk=function(a,b){var c=a.length,e=0,g,p,k=0,t=-1,n=0;if(null==b)for(;++t<c;)isNaN(g=zb(a[t]))||(p=g-e,e+=p/++n,k+=p*(g-e));else for(;++t<c;)isNaN(g=zb(b(a[t],t,a)))||(p=g-e,\ne+=p/++n,k+=p*(g-e));if(1<n)return k/(n-1)},Nk=function(a,b){return(a=Mk(a,b))?Math.sqrt(a):a},Ok=function(a,b){var c=-1,e=a.length,g,p,k;if(null==b){for(;++c<e;)if(null!=(p=a[c])&&p>=p){g=k=p;break}for(;++c<e;)null!=(p=a[c])&&(g>p&&(g=p),k<p&&(k=p))}else{for(;++c<e;)if(null!=(p=b(a[c],c,a))&&p>=p){g=k=p;break}for(;++c<e;)null!=(p=b(a[c],c,a))&&(g>p&&(g=p),k<p&&(k=p))}return[g,k]},Pk=Array.prototype,qr=Pk.slice,rr=Pk.map,Le=function(a){return function(){return a}},sr=function(a){return a},bb=function(a,\nb,c){a=+a;b=+b;c=2>(g=arguments.length)?(b=a,a=0,1):3>g?1:+c;for(var e=-1,g=Math.max(0,Math.ceil((b-a)/c))|0,p=Array(g);++e<g;)p[e]=a+e*c;return p},pm=Math.sqrt(50),qm=Math.sqrt(10),rm=Math.sqrt(2),we=function(a,c,e){e=b(a,c,e);return bb(Math.ceil(a/e)*e,Math.floor(c/e)*e+e/2,e)},Qk=function(a){return Math.ceil(Math.log(a.length)/Math.LN2)+1},tr=function(){function a(a){var g,p=a.length,k,t=Array(p);for(g=0;g<p;++g)t[g]=b(a[g],g,a);g=c(t);var n=g[0],u=g[1],y=e(t,n,u);Array.isArray(y)||(y=we(n,u,y));\nfor(var r=y.length;y[0]<=n;)y.shift(),--r;for(;y[r-1]>=u;)y.pop(),--r;var w=Array(r+1);for(g=0;g<=r;++g)k=w[g]=[],k.x0=0<g?y[g-1]:n,k.x1=g<r?y[g]:u;for(g=0;g<p;++g)k=t[g],n<=k&&k<=u&&w[Sb(y,k,0,r)].push(a[g]);return w}var b=sr,c=Ok,e=Qk;a.value=function(c){return arguments.length?(b=\"function\"===typeof c?c:Le(c),a):b};a.domain=function(b){return arguments.length?(c=\"function\"===typeof b?b:Le([b[0],b[1]]),a):c};a.thresholds=function(b){return arguments.length?(e=\"function\"===typeof b?b:Array.isArray(b)?\nLe(qr.call(b)):Le(b),a):e};return a},dd=function(a,b,c){null==c&&(c=zb);if(e=a.length){if(0>=(b=+b)||2>e)return+c(a[0],0,a);if(1<=b)return+c(a[e-1],e-1,a);var e;b*=e-1;e=Math.floor(b);var g=+c(a[e],e,a);a=+c(a[e+1],e+1,a);return g+(a-g)*(b-e)}},ur=function(a,b,c){a=rr.call(a,zb).sort(Eb);return Math.ceil((c-b)/(2*(dd(a,.75)-dd(a,.25))*Math.pow(a.length,-1/3)))},vr=function(a,b,c){return Math.ceil((c-b)/(3.5*Nk(a)*Math.pow(a.length,-1/3)))},wr=function(a,b){var c=-1,e=a.length,g,p;if(null==b){for(;++c<\ne;)if(null!=(p=a[c])&&p>=p){g=p;break}for(;++c<e;)null!=(p=a[c])&&p>g&&(g=p)}else{for(;++c<e;)if(null!=(p=b(a[c],c,a))&&p>=p){g=p;break}for(;++c<e;)null!=(p=b(a[c],c,a))&&p>g&&(g=p)}return g},xr=function(a,b){var c=0,e=a.length,g,p=-1,k=e;if(null==b)for(;++p<e;)isNaN(g=zb(a[p]))?--k:c+=g;else for(;++p<e;)isNaN(g=zb(b(a[p],p,a)))?--k:c+=g;if(k)return c/k},yr=function(a,b){var c=[],e=a.length,g,p=-1;if(null==b)for(;++p<e;)isNaN(g=zb(a[p]))||c.push(g);else for(;++p<e;)isNaN(g=zb(b(a[p],p,a)))||c.push(g);\nreturn dd(c.sort(Eb),.5)},Uf=function(a){var b=a.length,c;c=-1;for(var e=0,g,p;++c<b;)e+=a[c].length;for(g=Array(e);0<=--b;)for(p=a[b],c=p.length;0<=--c;)g[--e]=p[c];return g},Rk=function(a,b){var c=-1,e=a.length,g,p;if(null==b){for(;++c<e;)if(null!=(p=a[c])&&p>=p){g=p;break}for(;++c<e;)null!=(p=a[c])&&g>p&&(g=p)}else{for(;++c<e;)if(null!=(p=b(a[c],c,a))&&p>=p){g=p;break}for(;++c<e;)null!=(p=b(a[c],c,a))&&g>p&&(g=p)}return g},zr=function(a){for(var b=0,c=a.length-1,e=a[0],g=Array(0>c?0:c);b<c;)g[b]=\n[e,e=a[++b]];return g},Ar=function(a,b){for(var c=b.length,e=Array(c);c--;)e[c]=a[b[c]];return e},Br=function(a,b){if(e=a.length){var c=0,e,g=0,p,k=a[g];for(b||(b=Eb);++c<e;)if(0>b(p=a[c],k)||0!==b(k,k))k=p,g=c;if(0===b(k,k))return g}},Cr=function(a,b,c){c=(null==c?a.length:c)-(b=null==b?0:+b);for(var e,g;c;)g=Math.random()*c--|0,e=a[c+b],a[c+b]=a[g+b],a[g+b]=e;return a},Dr=function(a,b){var c=0,e=a.length,g,p=-1;if(null==b)for(;++p<e;){if(g=+a[p])c+=g}else for(;++p<e;)if(g=+b(a[p],p,a))c+=g;return c},\nSk=function(a){if(!(k=a.length))return[];for(var b=-1,e=Rk(a,c),g=Array(e);++b<e;)for(var p=-1,k,n=g[b]=Array(k);++p<k;)n[p]=a[p][b];return g},Er=function(){return Sk(arguments)},bf=Array.prototype.slice,yh=function(a){return a},sm={value:function(){}};W.prototype=E.prototype={constructor:W,on:function(a,b){var c=this.Fa,e=J(a+\"\",c),g,p=-1,k=e.length;if(2>arguments.length)for(;++p<k;){var n;if(n=g=(a=e[p]).type){a:{n=c[g];for(var t=0,m=n.length;t<m;++t)if((g=n[t]).name===a.name){g=g.value;break a}g=\nvoid 0}n=g}if(n)return g}else{if(null!=b&&\"function\"!==typeof b)throw Error(\"invalid callback: \"+b);for(;++p<k;)if(g=(a=e[p]).type)c[g]=K(c[g],a.name,b);else if(null==b)for(g in c)c[g]=K(c[g],a.name,null);return this}},copy:function(){var a={},b=this.Fa,c;for(c in b)a[c]=b[c].slice();return new W(a)},call:function(a,b){if(0<(g=arguments.length-2))for(var c=Array(g),e=0,g,p;e<g;++e)c[e]=arguments[e+2];if(!this.Fa.hasOwnProperty(a))throw Error(\"unknown type: \"+a);p=this.Fa[a];e=0;for(g=p.length;e<g;++e)p[e].value.apply(b,\nc)},apply:function(a,b,c){if(!this.Fa.hasOwnProperty(a))throw Error(\"unknown type: \"+a);a=this.Fa[a];for(var e=0,g=a.length;e<g;++e)a[e].value.apply(b,c)}};var Sa={svg:\"http://www.w3.org/2000/svg\",xhtml:\"http://www.w3.org/1999/xhtml\",xlink:\"http://www.w3.org/1999/xlink\",xml:\"http://www.w3.org/XML/1998/namespace\",xmlns:\"http://www.w3.org/2000/xmlns/\"},od=function(a){var b=a+=\"\",c=b.indexOf(\":\");0<=c&&\"xmlns\"!==(b=a.slice(0,c))&&(a=a.slice(c+1));return Sa.hasOwnProperty(b)?{space:Sa[b],local:a}:a},\nRg=function(a){a=od(a);return(a.local?Q:O)(a)},tm=0;U.prototype=ka.prototype={constructor:U,get:function(a){for(var b=this.Fa;!(b in a);)if(!(a=a.parentNode))return;return a[b]},set:function(a,b){return a[this.Fa]=b},remove:function(a){return this.Fa in a&&delete a[this.Fa]},toString:function(){return this.Fa}};var Tk=function(a){return function(){return this.matches(a)}};if(\"undefined\"!==typeof document){var pd=document.documentElement;if(!pd.matches)var Fr=pd.webkitMatchesSelector||pd.msMatchesSelector||\npd.mozMatchesSelector||pd.oMatchesSelector,Tk=function(a){return function(){return Fr.call(this,a)}}}var Sg=Tk,zh={};d3.event=null;if(\"undefined\"!==typeof document){var Gr=document.documentElement;\"onmouseenter\"in Gr||(zh={mouseenter:\"mouseover\",mouseleave:\"mouseout\"})}var Hr=function(a,b,c){var e=Ka(a+\"\"),g,p=e.length,k;if(2>arguments.length){var n=this.node().__on;if(n)for(var t=0,m=n.length,u;t<m;++t)for(g=0,u=n[t];g<p;++g)if((k=e[g]).type===u.type&&k.name===u.name)return u.value}else{n=b?cf:ma;\nnull==c&&(c=!1);for(g=0;g<p;++g)this.each(n(e[g],b,c));return this}},Tg=function(){for(var a=d3.event,b;b=a.sourceEvent;)a=b;return a},Ug=function(a,b){var c=a.ownerSVGElement||a;if(c.createSVGPoint)return c=c.createSVGPoint(),c.x=b.clientX,c.y=b.clientY,c=c.matrixTransform(a.getScreenCTM().inverse()),[c.x,c.y];c=a.getBoundingClientRect();return[b.clientX-c.left-a.clientLeft,b.clientY-c.top-a.clientTop]},vb=function(a){var b=Tg();b.changedTouches&&(b=b.changedTouches[0]);return Ug(a,b)},Me=function(a){return null==\na?df:function(){return this.querySelector(a)}},Ir=function(a){\"function\"!==typeof a&&(a=Me(a));for(var b=this.Dd,c=b.length,e=Array(c),g=0;g<c;++g)for(var p=b[g],k=p.length,n=e[g]=Array(k),m,q,u=0;u<k;++u)(m=p[u])&&(q=a.call(m,m.__data__,u,p))&&(\"__data__\"in m&&(q.__data__=m.__data__),n[u]=q);return new Ga(e,this.If)},Vg=function(a){return null==a?ef:function(){return this.querySelectorAll(a)}},Jr=function(a){\"function\"!==typeof a&&(a=Vg(a));for(var b=this.Dd,c=b.length,e=[],g=[],p=0;p<c;++p)for(var k=\nb[p],n=k.length,m,q=0;q<n;++q)if(m=k[q])e.push(a.call(m,m.__data__,q,k)),g.push(m);return new Ga(e,g)},Kr=function(a){\"function\"!==typeof a&&(a=Sg(a));for(var b=this.Dd,c=b.length,e=Array(c),g=0;g<c;++g)for(var p=b[g],k=p.length,n=e[g]=[],m,q=0;q<k;++q)(m=p[q])&&a.call(m,m.__data__,q,p)&&n.push(m);return new Ga(e,this.If)},Uk=function(a){return Array(a.length)},Lr=function(){return new Ga(this.DF||this.Dd.map(Uk),this.If)};Fb.prototype={constructor:Fb,appendChild:function(a){return this.Ye.insertBefore(a,\nthis.Vg)},insertBefore:function(a,b){return this.Ye.insertBefore(a,b)},querySelector:function(a){return this.Ye.querySelector(a)},querySelectorAll:function(a){return this.Ye.querySelectorAll(a)}};var Mr=function(a){return function(){return a}},Nr=function(a,b){if(!a)return w=Array(this.size()),m=-1,this.each(function(a){w[++m]=a}),w;var c=b?vd:Dc,e=this.If,g=this.Dd;\"function\"!==typeof a&&(a=Mr(a));for(var p=g.length,k=Array(p),n=Array(p),t=Array(p),m=0;m<p;++m){var u=e[m],y=g[m],r=y.length,w=a.call(u,\nu&&u.__data__,m,e),H=w.length,F=n[m]=Array(H),ca=k[m]=Array(H),r=t[m]=Array(r);c(u,y,F,ca,r,w,b);for(var y=u=0,q;u<H;++u)if(r=F[u]){for(u>=y&&(y=u+1);!(q=ca[y])&&++y<H;);r.Vg=q||null}}k=new Ga(k,e);k.DF=n;k.EF=t;return k},Or=function(){return new Ga(this.EF||this.Dd.map(Uk),this.If)},Pr=function(a){var b=this.Dd;a=a.Dd;for(var c=b.length,e=a.length,e=Math.min(c,e),g=Array(c),p=0;p<e;++p)for(var k=b[p],n=a[p],m=k.length,q=g[p]=Array(m),u,y=0;y<m;++y)if(u=k[y]||n[y])q[y]=u;for(;p<c;++p)g[p]=b[p];return new Ga(g,\nthis.If)},Qr=function(){for(var a=this.Dd,b=-1,c=a.length;++b<c;)for(var e=a[b],g=e.length-1,k=e[g],n;0<=--g;)if(n=e[g])k&&k!==n.nextSibling&&k.parentNode.insertBefore(n,k),k=n;return this},Rr=function(a){function b(b,c){return b&&c?a(b.__data__,c.__data__):!b-!c}a||(a=wd);for(var c=this.Dd,e=c.length,g=Array(e),p=0;p<e;++p){for(var k=c[p],n=k.length,m=g[p]=Array(n),q,u=0;u<n;++u)if(q=k[u])m[u]=q;m.sort(b)}return(new Ga(g,this.If)).order()},Sr=function(){var a=arguments[0];arguments[0]=this;a.apply(null,\narguments);return this},Tr=function(){var a=Array(this.size()),b=-1;this.each(function(){a[++b]=this});return a},Ur=function(){for(var a=this.Dd,b=0,c=a.length;b<c;++b)for(var e=a[b],g=0,k=e.length;g<k;++g){var n=e[g];if(n)return n}return null},Vr=function(){var a=0;this.each(function(){++a});return a},Wr=function(){return!this.node()},Xr=function(a){for(var b=this.Dd,c=0,e=b.length;c<e;++c)for(var g=b[c],k=0,p=g.length,n;k<p;++k)(n=g[k])&&a.call(n,n.__data__,k,g);return this},Yr=function(a,b){var c=\nod(a);if(2>arguments.length){var e=this.node();return c.local?e.getAttributeNS(c.space,c.local):e.getAttribute(c)}return this.each((null==b?c.local?Gb:ta:\"function\"===typeof b?c.local?wm:vm:c.local?um:Hb)(c,b))},$b=function(a){return a.ownerDocument&&a.ownerDocument.defaultView||a.document&&a||a.defaultView},Zr=function(a,b,c){var e;return 1<arguments.length?this.each((null==b?xm:\"function\"===typeof b?zm:ym)(a,b,null==c?\"\":c)):$b(e=this.node()).getComputedStyle(e,null).getPropertyValue(a)},$r=function(a,\nb){return 1<arguments.length?this.each((null==b?Am:\"function\"===typeof b?Cm:Bm)(a,b)):this.node()[a]};Ah.prototype={add:function(a){var b=this.Wi.indexOf(a);0>b&&(this.Wi.push(a),this.Vv.setAttribute(\"class\",this.Wi.join(\" \")))},remove:function(a){a=this.Wi.indexOf(a);0<=a&&(this.Wi.splice(a,1),this.Vv.setAttribute(\"class\",this.Wi.join(\" \")))},contains:function(a){return 0<=this.Wi.indexOf(a)}};var as=function(a,b){var c=(a+\"\").trim().split(/^|\\s+/);if(2>arguments.length){for(var e=ff(this.node()),\ng=-1,k=c.length;++g<k;)if(!e.contains(c[g]))return!1;return!0}return this.each((\"function\"===typeof b?Fm:b?Dm:Em)(c,b))},bs=function(a){return arguments.length?this.each(null==a?Gm:(\"function\"===typeof a?Im:Hm)(a)):this.node().textContent},cs=function(a){return arguments.length?this.each(null==a?Jm:(\"function\"===typeof a?Lm:Km)(a)):this.node().innerHTML},ds=function(){return this.each(Mm)},es=function(){return this.each(Nm)},fs=function(a){var b=\"function\"===typeof a?a:Rg(a);return this.select(function(){return this.appendChild(b.apply(this,\narguments))})},gs=function(a,b){var c=\"function\"===typeof a?a:Rg(a),e=null==b?Om:\"function\"===typeof b?b:Me(b);return this.select(function(){return this.insertBefore(c.apply(this,arguments),e.apply(this,arguments)||null)})},hs=function(){return this.each(Pm)},is=function(a){return arguments.length?this.property(\"__data__\",a):this.node().__data__},js=function(a,b){return this.each((\"function\"===typeof b?Rm:Qm)(a,b))},gf=[null];Ga.prototype=Ib.prototype={constructor:Ga,select:Ir,selectAll:Jr,filter:Kr,\ndata:Nr,enter:Lr,exit:Or,merge:Pr,order:Qr,sort:Rr,call:Sr,nodes:Tr,node:Ur,size:Vr,empty:Wr,each:Xr,attr:Yr,style:Zr,property:$r,classed:as,text:bs,html:cs,raise:ds,lower:es,append:fs,insert:gs,remove:hs,datum:is,on:Hr,dispatch:js};var Ma=function(a){return\"string\"===typeof a?new Ga([[document.querySelector(a)]],[document.documentElement]):new Ga([[a]],gf)},ks=function(a){return\"string\"===typeof a?new Ga([document.querySelectorAll(a)],[document.documentElement]):new Ga([null==a?[]:a],gf)},Ne=function(a,\nb,c){3>arguments.length&&(c=b,b=Tg().changedTouches);for(var e=0,g=b?b.length:0,k;e<g;++e)if((k=b[e]).identifier===c)return Ug(a,k);return null},ls=function(a,b){null==b&&(b=Tg().touches);for(var c=0,e=b?b.length:0,g=Array(e);c<e;++c)g[c]=Ug(a,b[c]);return g},ac=function(){d3.event.preventDefault();d3.event.stopImmediatePropagation()},Kd=function(a){var b=a.document.documentElement;a=Ma(a).on(\"dragstart.drag\",ac,!0);if(\"onselectstart\"in b)a.on(\"selectstart.drag\",ac,!0);else b.iv=b.style.MozUserSelect,\nb.style.MozUserSelect=\"none\"},Wg=function(a){return function(){return a}};hf.prototype.on=function(){var a=this.Fa.on.apply(this.Fa,arguments);return a===this.Fa?this:a};var ms=function(){function a(a){a.on(\"mousedown.drag\",b).on(\"touchstart.drag\",g).on(\"touchmove.drag\",k).on(\"touchend.drag touchcancel.drag\",n).style(\"-webkit-tap-highlight-color\",\"rgba(0,0,0,0)\")}function b(){if(!F&&q.apply(this,arguments)){var a=m(\"mouse\",v.apply(this,arguments),vb,this,arguments);a&&(Ma(d3.event.view).on(\"mousemove.drag\",\nc,!0).on(\"mouseup.drag\",e,!0),Kd(d3.event.view),d3.event.stopImmediatePropagation(),H=!1,a(\"start\"))}}function c(){ac();H=!0;y.mouse(\"drag\")}function e(){Ma(d3.event.view).on(\"mousemove.drag mouseup.drag\",null);xd(d3.event.view,H);ac();y.mouse(\"end\")}function g(){if(q.apply(this,arguments)){var a=d3.event.changedTouches,b=v.apply(this,arguments),c=a.length,e,g;for(e=0;e<c;++e)if(g=m(a[e].identifier,b,Ne,this,arguments))d3.event.stopImmediatePropagation(),g(\"start\")}}function k(){var a=d3.event.changedTouches,\nb=a.length,c,e;for(c=0;c<b;++c)if(e=y[a[c].identifier])ac(),e(\"drag\")}function n(){var a=d3.event.changedTouches,b=a.length,c,e;F&&clearTimeout(F);F=setTimeout(function(){F=null},500);for(c=0;c<b;++c)if(e=y[a[c].identifier])d3.event.stopImmediatePropagation(),e(\"end\")}function m(b,c,e,g,k){var p=e(c,b),n,A,m,t=r.copy();if(Ya(new hf(a,\"beforestart\",n,b,w,p[0],p[1],0,0,t),function(){if(null==(d3.event.subject=n=u.apply(g,k)))return!1;A=n.x-p[0]||0;m=n.y-p[1]||0;return!0}))return function lo(r){var u=\np,H;switch(r){case \"start\":y[b]=lo;H=w++;break;case \"end\":delete y[b],--w;case \"drag\":p=e(c,b),H=w}Ya(new hf(a,r,n,b,H,p[0]+A,p[1]+m,p[0]-u[0],p[1]-u[1],t),t.apply,t,[r,g,k])}}var q=Sm,v=Tm,u=Um,y={},r=E(\"start\",\"drag\",\"end\"),w=0,H,F;a.filter=function(b){return arguments.length?(q=\"function\"===typeof b?b:Wg(!!b),a):q};a.container=function(b){return arguments.length?(v=\"function\"===typeof b?b:Wg(b),a):v};a.subject=function(b){return arguments.length?(u=\"function\"===typeof b?b:Wg(b),a):u};a.on=function(){var b=\nr.on.apply(r,arguments);return b===r?a:b};return a},uc=function(a,b,c){a.prototype=b.prototype=c;c.constructor=a},vc=1/.7,Vm=/^#([0-9a-f]{3})$/,Wm=/^#([0-9a-f]{6})$/,Xm=/^rgb\\(\\s*([+-]?\\d+)\\s*,\\s*([+-]?\\d+)\\s*,\\s*([+-]?\\d+)\\s*\\)$/,Ym=/^rgb\\(\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)%\\s*,\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)%\\s*,\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)%\\s*\\)$/,Zm=/^rgba\\(\\s*([+-]?\\d+)\\s*,\\s*([+-]?\\d+)\\s*,\\s*([+-]?\\d+)\\s*,\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)\\s*\\)$/,$m=/^rgba\\(\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)%\\s*,\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)%\\s*,\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)%\\s*,\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)\\s*\\)$/,\nan=/^hsl\\(\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)\\s*,\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)%\\s*,\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)%\\s*\\)$/,bn=/^hsla\\(\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)\\s*,\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)%\\s*,\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)%\\s*,\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)\\s*\\)$/,Hh={aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,\nburlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,\ndarkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,\nlightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,\nmediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,\nred:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074};uc(rb,sb,{displayable:function(){return this.rgb().displayable()},\ntoString:function(){return this.rgb()+\"\"}});uc(za,Fc,Ec(rb,{brighter:function(a){a=null==a?vc:Math.pow(vc,a);return new za(this.r*a,this.g*a,this.b*a,this.opacity)},darker:function(a){a=null==a?.7:Math.pow(.7,a);return new za(this.r*a,this.g*a,this.b*a,this.opacity)},rgb:function(){return this},displayable:function(){return 0<=this.r&&255>=this.r&&0<=this.g&&255>=this.g&&0<=this.b&&255>=this.b&&0<=this.opacity&&1>=this.opacity},toString:function(){var a=this.opacity,a=isNaN(a)?1:Math.max(0,Math.min(1,\na));return(1===a?\"rgb(\":\"rgba(\")+Math.max(0,Math.min(255,Math.round(this.r)||0))+\", \"+Math.max(0,Math.min(255,Math.round(this.g)||0))+\", \"+Math.max(0,Math.min(255,Math.round(this.b)||0))+(1===a?\")\":\", \"+a+\")\")}}));uc(db,yd,Ec(rb,{brighter:function(a){a=null==a?vc:Math.pow(vc,a);return new db(this.h,this.s,this.l*a,this.opacity)},darker:function(a){a=null==a?.7:Math.pow(.7,a);return new db(this.h,this.s,this.l*a,this.opacity)},rgb:function(){var a=this.h%360+360*(0>this.h),b=isNaN(a)||isNaN(this.s)?\n0:this.s,c=this.l,b=c+(.5>c?c:1-c)*b,c=2*c-b;return new za(kf(240<=a?a-240:a+120,c,b),kf(a,c,b),kf(120>a?a+240:a-120,c,b),this.opacity)},displayable:function(){return(0<=this.s&&1>=this.s||isNaN(this.s))&&0<=this.l&&1>=this.l&&0<=this.opacity&&1>=this.opacity}}));var Ih=Math.PI/180,Lh=180/Math.PI,Kh=4/29,bc=6/29,Jh=3*bc*bc,dn=bc*bc*bc;uc(kb,zd,Ec(rb,{brighter:function(a){return new kb(this.l+18*(null==a?1:a),this.a,this.b,this.opacity)},darker:function(a){return new kb(this.l-18*(null==a?1:a),this.a,\nthis.b,this.opacity)},rgb:function(){var a=(this.l+16)/116,b=isNaN(this.a)?a:a+this.a/500,c=isNaN(this.b)?a:a-this.b/200,a=1*of(a),b=.95047*of(b),c=1.08883*of(c);return new za(pf(3.2404542*b-1.5371385*a-.4985314*c),pf(-.969266*b+1.8760108*a+.041556*c),pf(.0556434*b-.2040259*a+1.0572252*c),this.opacity)}}));uc(tb,Ad,Ec(rb,{brighter:function(a){return new tb(this.h,this.c,this.l+18*(null==a?1:a),this.opacity)},darker:function(a){return new tb(this.h,this.c,this.l-18*(null==a?1:a),this.opacity)},rgb:function(){return lf(this).rgb()}}));\nvar Mh=1.78277*-.29227-.1347134789;uc(Jb,Za,Ec(rb,{brighter:function(a){a=null==a?vc:Math.pow(vc,a);return new Jb(this.h,this.s,this.l*a,this.opacity)},darker:function(a){a=null==a?.7:Math.pow(.7,a);return new Jb(this.h,this.s,this.l*a,this.opacity)},rgb:function(){var a=isNaN(this.h)?0:(this.h+120)*Ih,b=+this.l,c=isNaN(this.s)?0:this.s*b*(1-b),e=Math.cos(a),a=Math.sin(a);return new za(255*(b+c*(-.14861*e+1.78277*a)),255*(b+c*(-.29227*e+-.90649*a)),255*(b+1.97294*c*e),this.opacity)}}));var Vk=function(a){var b=\na.length-1;return function(c){var e=0>=c?c=0:1<=c?(c=1,b-1):Math.floor(c*b),g=a[e],k=a[e+1],p=0<e?a[e-1]:2*g-k,n=e<b-1?a[e+2]:2*k-g;return Nh((c-e/b)*b,p,g,k,n)}},Wk=function(a){var b=a.length;return function(c){var e=Math.floor((0>(c%=1)?++c:c)*b),g=a[(e+b-1)%b],k=a[e%b],p=a[(e+1)%b],n=a[(e+2)%b];return Nh((c-e/b)*b,g,k,p,n)}},Bd=function(a){return function(){return a}},qd=function t(a){function b(a,b){var e=c((a=Fc(a)).r,(b=Fc(b)).r),g=c(a.g,b.g),k=c(a.b,b.b),u=ya(a.opacity,b.opacity);return function(b){a.r=\ne(b);a.g=g(b);a.b=k(b);a.opacity=u(b);return a+\"\"}}var c=fn(a);b.gamma=t;return b}(1),ns=Ph(Vk),os=Ph(Wk),Xk=function(a,b){var c=b?b.length:0,e=a?Math.min(c,a.length):0,g=Array(c),k=Array(c),n;for(n=0;n<e;++n)g[n]=Pc(a[n],b[n]);for(;n<c;++n)k[n]=b[n];return function(a){for(n=0;n<e;++n)k[n]=g[n](a);return k}},Yk=function(a,b){var c=new Date;return a=+a,b-=a,function(e){return c.setTime(a+b*e),c}},Na=function(a,b){return a=+a,b-=a,function(c){return a+b*c}},Zk=function(a,b){var c={},e={},g;if(null===\na||\"object\"!==typeof a)a={};if(null===b||\"object\"!==typeof b)b={};for(g in b)g in a?c[g]=Pc(a[g],b[g]):e[g]=b[g];return function(a){for(g in c)e[g]=c[g](a);return e}},Xg=/[-+]?(?:\\d+\\.?\\d*|\\.?\\d+)(?:[eE][-+]?\\d+)?/g,Yg=new RegExp(Xg.source,\"g\"),Zg=function(a,b){var c=Xg.lastIndex=Yg.lastIndex=0,e,g,k,n=-1,m=[],t=[];a+=\"\";for(b+=\"\";(e=Xg.exec(a))&&(g=Yg.exec(b));)(k=g.index)>c&&(k=b.slice(c,k),m[n]?m[n]+=k:m[++n]=k),(e=e[0])===(g=g[0])?m[n]?m[n]+=g:m[++n]=g:(m[++n]=null,t.push({uf:n,x:Na(e,g)})),c=\nYg.lastIndex;c<b.length&&(k=b.slice(c),m[n]?m[n]+=k:m[++n]=k);return 2>m.length?t[0]?hn(t[0].x):gn(b):(b=t.length,function(a){for(var c=0,e;c<b;++c)m[(e=t[c]).uf]=e.x(a);return m.join(\"\")})},Pc=function(a,b){var c=typeof b,e;return null==b||\"boolean\"===c?Bd(b):(\"number\"===c?Na:\"string\"===c?(e=sb(b))?(b=e,qd):Zg:b instanceof sb?qd:b instanceof Date?Yk:Array.isArray(b)?Xk:isNaN(b)?Zk:Na)(a,b)},Nj=function(a,b){return a=+a,b-=a,function(c){return Math.round(a+b*c)}},$k=180/Math.PI,rf={zt:0,At:0,rotate:0,\nskewX:0,Gs:1,Hs:1},Rh=function(a,b,c,e,g,k){var n,m,t;if(n=Math.sqrt(a*a+b*b))a/=n,b/=n;if(t=a*c+b*e)c-=a*t,e-=b*t;if(m=Math.sqrt(c*c+e*e))c/=m,e/=m,t/=m;a*e<b*c&&(a=-a,b=-b,t=-t,n=-n);return{zt:g,At:k,rotate:Math.atan2(b,a)*$k,skewX:Math.atan(t)*$k,Gs:n,Hs:m}},Gc,sf,Qh,Cd,al=Sh(jn,\"px, \",\"px)\",\"deg)\"),bl=Sh(kn,\", \",\")\",\")\"),rd=Math.SQRT2,cl=function(a,b){var c=a[0],e=a[1],g=a[2];a=b[0];var k=b[1];b=b[2];var n=a-c,m=k-e,k=n*n+m*m,t;if(1E-12>k)t=Math.log(b/g)/rd,b=function(a){return[c+a*n,e+a*m,g*\nMath.exp(rd*a*t)]};else{var u=Math.sqrt(k);a=(b*b-g*g+4*k)/(4*g*u);b=(b*b-g*g-4*k)/(4*b*u);var y=Math.log(Math.sqrt(a*a+1)-a);b=Math.log(Math.sqrt(b*b+1)-b);t=(b-y)/rd;b=function(a){a*=t;var b=Th(y),k,r=y;k=((r=Math.exp(r))-1/r)/2;var q=rd*a+y,r=((q=Math.exp(2*q))-1)/(q+1);k=g/(2*u)*(b*r-k);return[c+k*n,e+k*m,g*b/Th(rd*a+y)]}}b.duration=1E3*t;return b},ps=Uh(qf),qs=Uh(ya),rs=Vh(qf),ss=Vh(ya),ts=Wh(qf),Oe=Wh(ya),us=function(a,b){for(var c=Array(b),e=0;e<b;++e)c[e]=a(e/(b-1));return c},dc=0,Ic=0,Kc=\n0,Ed,Jc,Fd=0,ub=0,uf=0,tf=\"object\"===typeof performance&&performance.now?performance:Date,Xh=\"function\"===typeof requestAnimationFrame?requestAnimationFrame:function(a){setTimeout(a,17)};Hc.prototype=Dd.prototype={constructor:Hc,restart:function(a,b,c){if(\"function\"!==typeof a)throw new TypeError(\"callback is not a function\");c=(null==c?cc():+c)+(null==b?0:+b);this.Vg||Jc===this||(Jc?Jc.Vg=this:Ed=this,Jc=this);this.$f=a;this.ml=c;vf()},stop:function(){this.$f&&(this.$f=null,this.ml=Infinity,vf())}};\nvar xf=function(a,b,c){var e=new Hc;b=null==b?0:+b;e.restart(function(c){e.stop();a(c+b)},b,c);return e},vs=function(a,b,c){var e=new Hc,g=b;if(null==b)return e.restart(a,b,c),e;b=+b;c=null==c?cc():+c;e.restart(function X(k){k+=g;e.restart(X,g+=b,c);a(k)},b,c);return e},ws=E(\"start\",\"end\",\"interrupt\"),xs=[],Pe=function(a,b,c,e,g,k){var n=a.zg;if(!n)a.zg={};else if(c in n)return;on(a,c,{name:b,index:e,group:g,on:ws,tween:xs,time:k.time,delay:k.delay,duration:k.duration,ease:k.ease,timer:null,state:0})},\nLb=function(a,b){var c=a.zg,e,g,k=!0,n;if(c){b=null==b?null:b+\"\";for(n in c)(e=c[n]).name!==b?k=!1:(g=2<e.state&&5>e.state,e.state=6,e.timer.stop(),g&&e.on.call(\"interrupt\",a,a.__data__,e.index,e.group),delete c[n]);k&&delete a.zg}},ys=function(a){return this.each(function(){Lb(this,a)})},zs=function(a,b){var c=this.Kc;a+=\"\";if(2>arguments.length){for(var c=lb(this.node(),c).tween,e=0,g=c.length,k;e<g;++e)if((k=c[e]).name===a)return k.value;return null}return this.each((null==b?pn:qn)(c,a,b))},dl=\nfunction(a,b){var c;return(\"number\"===typeof b?Na:b instanceof sb?qd:(c=sb(b))?(b=c,qd):Zg)(a,b)},As=function(a,b){var c=od(a),e=\"transform\"===c?bl:dl;return this.attrTween(a,\"function\"===typeof b?(c.local?wn:vn)(c,e,yf(this,\"attr.\"+a,b)):null==b?(c.local?sn:rn)(c):(c.local?un:tn)(c,e,b))},Bs=function(a,b){var c=\"attr.\"+a;if(2>arguments.length)return(c=this.tween(c))&&c.uh;if(null==b)return this.tween(c,null);if(\"function\"!==typeof b)throw Error();var e=od(a);return this.tween(c,(e.local?xn:yn)(e,\nb))},Cs=function(a){var b=this.Kc;return arguments.length?this.each((\"function\"===typeof a?zn:An)(b,a)):lb(this.node(),b).delay},Ds=function(a){var b=this.Kc;return arguments.length?this.each((\"function\"===typeof a?Bn:Cn)(b,a)):lb(this.node(),b).duration},Es=function(a){var b=this.Kc;return arguments.length?this.each(Dn(b,a)):lb(this.node(),b).ease},Fs=function(a){\"function\"!==typeof a&&(a=Sg(a));for(var b=this.Dd,c=b.length,e=Array(c),g=0;g<c;++g)for(var k=b[g],n=k.length,m=e[g]=[],t,u=0;u<n;++u)(t=\nk[u])&&a.call(t,t.__data__,u,k)&&m.push(t);return new eb(e,this.If,this.Uj,this.Kc)},Gs=function(a){if(a.Kc!==this.Kc)throw Error();var b=this.Dd;a=a.Dd;for(var c=b.length,e=a.length,e=Math.min(c,e),g=Array(c),k=0;k<e;++k)for(var n=b[k],m=a[k],t=n.length,u=g[k]=Array(t),y,r=0;r<t;++r)if(y=n[r]||m[r])u[r]=y;for(;k<c;++k)g[k]=b[k];return new eb(g,this.If,this.Uj,this.Kc)},Hs=function(a,b){var c=this.Kc;return 2>arguments.length?lb(this.node(),c).on.on(a):this.each(Fn(c,a,b))},Is=function(){return this.on(\"end.remove\",\nGn(this.Kc))},Js=function(a){var b=this.Uj,c=this.Kc;\"function\"!==typeof a&&(a=Me(a));for(var e=this.Dd,g=e.length,k=Array(g),n=0;n<g;++n)for(var m=e[n],t=m.length,u=k[n]=Array(t),y,r,w=0;w<t;++w)(y=m[w])&&(r=a.call(y,y.__data__,w,m))&&(\"__data__\"in y&&(r.__data__=y.__data__),u[w]=r,Pe(u[w],b,c,w,u,lb(y,c)));return new eb(k,this.If,b,c)},Ks=function(a){var b=this.Uj,c=this.Kc;\"function\"!==typeof a&&(a=Vg(a));for(var e=this.Dd,g=e.length,k=[],n=[],m=0;m<g;++m)for(var t=e[m],u=t.length,y,r=0;r<u;++r)if(y=\nt[r]){for(var w=a.call(y,y.__data__,r,t),H,F=lb(y,c),q=0,qa=w.length;q<qa;++q)(H=w[q])&&Pe(H,b,c,q,w,F);k.push(w);n.push(y)}return new eb(k,n,b,c)},Ls=Ib.prototype.constructor,Ms=function(){return new Ls(this.Dd,this.If)},Ns=function(a,b,c){var e=\"transform\"===(a+=\"\")?al:dl;return null==b?this.styleTween(a,Hn(a,e)).on(\"end.style.\"+a,In(a)):this.styleTween(a,\"function\"===typeof b?Kn(a,e,yf(this,\"style.\"+a,b)):Jn(a,e,b),c)},Os=function(a,b,c){var e=\"style.\"+(a+=\"\");if(2>arguments.length)return(e=this.tween(e))&&\ne.uh;if(null==b)return this.tween(e,null);if(\"function\"!==typeof b)throw Error();return this.tween(e,Ln(a,b,null==c?\"\":c))},Ps=function(a){return this.tween(\"text\",\"function\"===typeof a?Nn(yf(this,\"text\",a)):Mn(null==a?\"\":a+\"\"))},Qs=function(){for(var a=this.Uj,b=this.Kc,c=++el,e=this.Dd,g=e.length,k=0;k<g;++k)for(var n=e[k],m=n.length,q,u=0;u<m;++u)if(q=n[u]){var y=lb(q,b);Pe(q,a,c,u,n,{time:y.time+y.delay+y.duration,delay:0,duration:y.duration,ease:y.ease})}return new eb(e,this.If,a,c)},el=0,wc=\nIb.prototype;eb.prototype=$h.prototype={constructor:eb,select:Js,selectAll:Ks,filter:Fs,merge:Gs,selection:Ms,transition:Qs,call:wc.call,nodes:wc.nodes,node:wc.node,size:wc.size,empty:wc.empty,each:wc.each,on:Hs,attr:As,attrTween:Bs,style:Ns,styleTween:Os,text:Ps,remove:Is,tween:zs,delay:Cs,duration:Ds,ease:Es};var Rs=function z(a){function b(b){return Math.pow(b,a)}a=+a;b.exponent=z;return b}(3),Ss=function I(a){function b(b){return 1-Math.pow(1-b,a)}a=+a;b.exponent=I;return b}(3),fl=function P(a){function b(b){return(1>=\n(b*=2)?Math.pow(b,a):2-Math.pow(2-b,a))/2}a=+a;b.exponent=P;return b}(3),di=Math.PI,bi=di/2,Af=4/11,ao=6/11,$n=8/11,co=9/11,bo=10/11,eo=21/22,Gd=1/Af/Af,Ts=function R(a){function b(b){return b*b*((a+1)*b-a)}a=+a;b.overshoot=R;return b}(1.70158),Us=function da(a){function b(b){return--b*b*((a+1)*b+a)+1}a=+a;b.overshoot=da;return b}(1.70158),gl=function X(a){function b(b){return(1>(b*=2)?b*b*((a+1)*b-a):(b-=2)*b*((a+1)*b+a)+2)/2}a=+a;b.overshoot=X;return b}(1.70158),xc=2*Math.PI,Vs=function fa(a,b){function c(c){return a*\nMath.pow(2,10*--c)*Math.sin((e-c)/b)}var e=Math.asin(1/(a=Math.max(1,a)))*(b/=xc);c.amplitude=function(a){return fa(a,b*xc)};c.period=function(b){return fa(a,b)};return c}(1,.3),hl=function jb(a,b){function c(c){return 1-a*Math.pow(2,-10*(c=+c))*Math.sin((c+e)/b)}var e=Math.asin(1/(a=Math.max(1,a)))*(b/=xc);c.amplitude=function(a){return jb(a,b*xc)};c.period=function(b){return jb(a,b)};return c}(1,.3),Ws=function u(a,b){function c(c){return(0>(c=2*c-1)?a*Math.pow(2,10*c)*Math.sin((e-c)/b):2-a*Math.pow(2,\n-10*c)*Math.sin((e+c)/b))/2}var e=Math.asin(1/(a=Math.max(1,a)))*(b/=xc);c.amplitude=function(a){return u(a,b*xc)};c.period=function(b){return u(a,b)};return c}(1,.3),$g={time:null,delay:0,duration:250,ease:zf},Xs=function(a){var b,c;a instanceof eb?(b=a.Kc,a=a.Uj):(b=++el,(c=$g).time=cc(),a=null==a?null:a+\"\");for(var e=this.Dd,g=e.length,k=0;k<g;++k)for(var u=e[k],n=u.length,m,A=0;A<n;++A)if(m=u[A]){var L=m,q=a,M=b,G=A,v=u,Y;if(!(Y=c))a:{Y=void 0;for(var Aa=b;!(Y=m.zg)||!(Y=Y[Aa]);)if(!(m=m.parentNode)){Y=\n($g.time=cc(),$g);break a}}Pe(L,q,M,G,v,Y)}return new eb(e,this.If,a,b)};Ib.prototype.interrupt=ys;Ib.prototype.transition=Xs;var Ys=[null],Zs=function(a,b){var c=a.zg,e,g;if(c)for(g in b=null==b?null:b+\"\",c)if(1<(e=c[g]).state&&e.name===b)return new eb([[a]],Ys,b,+g);return null},ji=function(a){return function(){return a}},qo=function(a,b,c){this.target=a;this.type=b;this.selection=c},Jd=function(){d3.event.preventDefault();d3.event.stopImmediatePropagation()},gi={name:\"drag\"},Ef={name:\"space\"},\nec={name:\"handle\"},fc={name:\"center\"},Hd={name:\"x\",Ur:[\"e\",\"w\"].map(Mc),input:function(a,b){return a&&[[a[0],b[0][1]],[a[1],b[1][1]]]},No:function(a){return a&&[a[0][0],a[1][0]]}},Id={name:\"y\",Ur:[\"n\",\"s\"].map(Mc),input:function(a,b){return a&&[[b[0][0],a[0]],[b[1][0],a[1]]]},No:function(a){return a&&[a[0][1],a[1][1]]}},$s={name:\"xy\",Ur:\"n e s w nw ne se sw\".split(\" \").map(Mc),input:function(a){return a},No:function(a){return a}},mb={overlay:\"crosshair\",selection:\"move\",n:\"ns-resize\",e:\"ew-resize\",\ns:\"ns-resize\",w:\"ew-resize\",nw:\"nwse-resize\",ne:\"nesw-resize\",se:\"nwse-resize\",sw:\"nesw-resize\"},hi={e:\"w\",w:\"e\",nw:\"ne\",ne:\"nw\",se:\"sw\",sw:\"se\"},ii={n:\"s\",s:\"n\",nw:\"sw\",ne:\"se\",se:\"ne\",sw:\"nw\"},oo={overlay:1,selection:1,n:null,e:1,s:null,w:-1,nw:-1,ne:1,se:1,sw:-1},po={overlay:1,selection:1,n:-1,e:null,s:1,w:null,nw:-1,ne:-1,se:1,sw:1},at=function(){return Df($s)},il=Math.cos,jl=Math.sin,kl=Math.PI,Qe=kl/2,ll=2*kl,ml=Math.max,bt=function(){function a(a){var k=a.length,r=[],u=bb(k),n=[],w=[],m=w.groups=\nArray(k),y=Array(k*k),H,F,q,v,B,E;H=0;for(B=-1;++B<k;){F=0;for(E=-1;++E<k;)F+=a[B][E];r.push(F);n.push(bb(k));H+=F}c&&u.sort(function(a,b){return c(r[a],r[b])});e&&n.forEach(function(b,c){b.sort(function(b,g){return e(a[c][b],a[c][g])})});v=(H=ml(0,ll-b*k)/H)?b:ll/k;F=0;for(B=-1;++B<k;){q=F;for(E=-1;++E<k;){var J=u[B],C=n[J][E],W=a[J][C],O=F,K=F+=W*H;y[C*k+J]={index:J,subindex:C,startAngle:O,endAngle:K,value:W}}m[J]={index:J,startAngle:q,endAngle:F,value:r[J]};F+=v}for(B=-1;++B<k;)for(E=B-1;++E<k;)u=\ny[E*k+B],n=y[B*k+E],(u.value||n.value)&&w.push(u.value<n.value?{source:n,target:u}:{source:u,target:n});return g?w.sort(g):w}var b=0,c=null,e=null,g=null;a.padAngle=function(c){return arguments.length?(b=ml(0,c),a):b};a.sortGroups=function(b){return arguments.length?(c=b,a):c};a.sortSubgroups=function(b){return arguments.length?(e=b,a):e};a.sortChords=function(b){return arguments.length?(null==b?g=null:(g=ro(b)).Fa=b,a):g&&g.Fa};return a},ct=Array.prototype.slice,ah=function(a){return function(){return a}},\nbh=Math.PI,ch=2*bh,dt=ch-1E-6;Ff.prototype=Mb.prototype={constructor:Ff,moveTo:function(a,b){this.Fa+=\"M\"+(this.ub=this.Sa=+a)+\",\"+(this.xb=this.Va=+b)},closePath:function(){null!==this.Sa&&(this.Sa=this.ub,this.Va=this.xb,this.Fa+=\"Z\")},lineTo:function(a,b){this.Fa+=\"L\"+(this.Sa=+a)+\",\"+(this.Va=+b)},quadraticCurveTo:function(a,b,c,e){this.Fa+=\"Q\"+ +a+\",\"+ +b+\",\"+(this.Sa=+c)+\",\"+(this.Va=+e)},bezierCurveTo:function(a,b,c,e,g,k){this.Fa+=\"C\"+ +a+\",\"+ +b+\",\"+ +c+\",\"+ +e+\",\"+(this.Sa=+g)+\",\"+(this.Va=\n+k)},arcTo:function(a,b,c,e,g){a=+a;b=+b;c=+c;e=+e;g=+g;var k=this.Sa,r=this.Va,u=c-a,n=e-b,w=k-a,m=r-b,y=w*w+m*m;if(0>g)throw Error(\"negative radius: \"+g);if(null===this.Sa)this.Fa+=\"M\"+(this.Sa=a)+\",\"+(this.Va=b);else if(1E-6<y)if(1E-6<Math.abs(m*u-n*w)&&g){c-=k;e-=r;var H=u*u+n*n,q=c*c+e*e,r=Math.sqrt(H),k=Math.sqrt(y),y=g*Math.tan((bh-Math.acos((H+y-q)/(2*r*k)))/2),k=y/k,y=y/r;1E-6<Math.abs(k-1)&&(this.Fa+=\"L\"+(a+k*w)+\",\"+(b+k*m));this.Fa+=\"A\"+g+\",\"+g+\",0,0,\"+ +(m*c>w*e)+\",\"+(this.Sa=a+y*u)+\",\"+\n(this.Va=b+y*n)}else this.Fa+=\"L\"+(this.Sa=a)+\",\"+(this.Va=b)},arc:function(a,b,c,e,g,k){a=+a;b=+b;c=+c;var r=c*Math.cos(e),u=c*Math.sin(e),n=a+r,w=b+u,m=1^k;e=k?e-g:g-e;if(0>c)throw Error(\"negative radius: \"+c);if(null===this.Sa)this.Fa+=\"M\"+n+\",\"+w;else if(1E-6<Math.abs(this.Sa-n)||1E-6<Math.abs(this.Va-w))this.Fa+=\"L\"+n+\",\"+w;c&&(e>dt?this.Fa+=\"A\"+c+\",\"+c+\",0,1,\"+m+\",\"+(a-r)+\",\"+(b-u)+\"A\"+c+\",\"+c+\",0,1,\"+m+\",\"+(this.Sa=n)+\",\"+(this.Va=w):(0>e&&(e=e%ch+ch),this.Fa+=\"A\"+c+\",\"+c+\",0,\"+ +(e>=bh)+\",\"+\nm+\",\"+(this.Sa=a+c*Math.cos(g))+\",\"+(this.Va=b+c*Math.sin(g))))},rect:function(a,b,c,e){this.Fa+=\"M\"+(this.ub=this.Sa=+a)+\",\"+(this.xb=this.Va=+b)+\"h\"+ +c+\"v\"+ +e+\"h\"+-c+\"Z\"},toString:function(){return this.Fa}};var et=function(){function a(){var a,r=ct.call(arguments),u=b.apply(this,r),w=c.apply(this,r),u=+e.apply(this,(r[0]=u,r)),m=g.apply(this,r)-Qe,y=k.apply(this,r)-Qe,H=u*il(m),q=u*jl(m),w=+e.apply(this,(r[0]=w,r)),F=g.apply(this,r)-Qe,r=k.apply(this,r)-Qe;n||(n=a=Mb());n.moveTo(H,q);n.arc(0,\n0,u,m,y);if(m!==F||y!==r)n.quadraticCurveTo(0,0,w*il(F),w*jl(F)),n.arc(0,0,w,F,r);n.quadraticCurveTo(0,0,H,q);n.closePath();if(a)return n=null,a+\"\"||null}var b=so,c=to,e=uo,g=vo,k=wo,n=null;a.radius=function(b){return arguments.length?(e=\"function\"===typeof b?b:ah(+b),a):e};a.startAngle=function(b){return arguments.length?(g=\"function\"===typeof b?b:ah(+b),a):g};a.endAngle=function(b){return arguments.length?(k=\"function\"===typeof b?b:ah(+b),a):k};a.source=function(c){return arguments.length?(b=c,\na):b};a.target=function(b){return arguments.length?(c=b,a):c};a.context=function(b){return arguments.length?(n=null==b?null:b,a):n};return a};Ld.prototype=fb.prototype={constructor:Ld,has:function(a){return\"$\"+a in this},get:function(a){return this[\"$\"+a]},set:function(a,b){this[\"$\"+a]=b;return this},remove:function(a){a=\"$\"+a;return a in this&&delete this[a]},clear:function(){for(var a in this)\"$\"===a[0]&&delete this[a]},keys:function(){var a=[],b;for(b in this)\"$\"===b[0]&&a.push(b.slice(1));return a},\nvalues:function(){var a=[],b;for(b in this)\"$\"===b[0]&&a.push(this[b]);return a},entries:function(){var a=[],b;for(b in this)\"$\"===b[0]&&a.push({key:b.slice(1),value:this[b]});return a},size:function(){var a=0,b;for(b in this)\"$\"===b[0]&&++a;return a},empty:function(){for(var a in this)if(\"$\"===a[0])return!1;return!0},each:function(a){for(var b in this)\"$\"===b[0]&&a(this[b],b.slice(1),this)}};var ft=function(){function a(b,e,r,n){if(e>=c.length)return null!=k?k(b):null!=g?b.sort(g):b;for(var u=-1,\nw=b.length,m=c[e++],A,y,H=fb(),q,F=r();++u<w;)(q=H.get(A=m(y=b[u])+\"\"))?q.push(y):H.set(A,[y]);H.each(function(b,c){n(F,c,a(b,e,r,n))});return F}function b(a,g){if(++g>c.length)return a;var r,n=e[g-1];null!=k&&g>=c.length?r=a.entries():(r=[],a.each(function(a,c){r.push({key:c,values:b(a,g)})}));return null!=n?r.sort(function(a,b){return n(a.key,b.key)}):r}var c=[],e=[],g,k,n;return n={object:function(b){return a(b,0,xo,yo)},map:function(b){return a(b,0,ki,li)},entries:function(c){return b(a(c,0,ki,\nli),0)},key:function(a){c.push(a);return n},sortKeys:function(a){e[c.length-1]=a;return n},sortValues:function(a){g=a;return n},rollup:function(a){k=a;return n}}},Xb=fb.prototype;Md.prototype=mi.prototype={constructor:Md,has:Xb.has,add:function(a){a+=\"\";this[\"$\"+a]=a;return this},remove:Xb.remove,clear:Xb.clear,values:Xb.keys,size:Xb.size,empty:Xb.empty,each:Xb.each};var gt=function(a){var b=[],c;for(c in a)b.push(c);return b},ht=function(a){var b=[],c;for(c in a)b.push(a[c]);return b},it=function(a){var b=\n[],c;for(c in a)b.push({key:c,value:a[c]});return b},dh=function(a){function b(a,b){var e,g;a=c(a,function(a,c){if(e)return e(a,c-1);g=a;e=b?zo(a,b):ni(a)});a.columns=g;return a}function c(a,b){function c(){if(n>=r)return g;if(A)return A=!1,e;var b=n,c;if(34===a.charCodeAt(b)){for(var k=b;k++<r;)if(34===a.charCodeAt(k)){if(34!==a.charCodeAt(k+1))break;++k}n=k+2;c=a.charCodeAt(k+1);13===c?(A=!0,10===a.charCodeAt(k+2)&&++n):10===c&&(A=!0);return a.slice(b+1,k).replace(/\"\"/g,'\"')}for(;n<r;){k=1;c=a.charCodeAt(n++);\nif(10===c)A=!0;else if(13===c)A=!0,10===a.charCodeAt(n)&&(++n,++k);else if(c!==m)continue;return a.slice(b,n-k)}return a.slice(b)}for(var e={},g={},k=[],r=a.length,n=0,u=0,w,A;(w=c())!==g;){for(var y=[];w!==e&&w!==g;)y.push(w),w=c();b&&null==(y=b(y,u++))||k.push(y)}return k}function e(b,c){null==c&&(c=Ao(b));return[c.map(n).join(a)].concat(b.map(function(b){return c.map(function(a){return n(b[a])}).join(a)})).join(\"\\n\")}function g(a){return a.map(k).join(\"\\n\")}function k(b){return b.map(n).join(a)}\nfunction n(a){return null==a?\"\":u.test(a+=\"\")?'\"'+a.replace(/\\\"/g,'\"\"')+'\"':a}var u=new RegExp('[\"'+a+\"\\n]\"),m=a.charCodeAt(0);return{parse:b,parseRows:c,format:e,formatRows:g}},Re=dh(\",\"),nl=Re.parse,jt=Re.parseRows,kt=Re.format,lt=Re.formatRows,Se=dh(\"\\t\"),ol=Se.parse,mt=Se.parseRows,nt=Se.format,ot=Se.formatRows,pt=function(a,b){function c(){var c,g=e.length,k,r=0,n=0;for(c=0;c<g;++c)k=e[c],r+=k.x,n+=k.y;r=r/g-a;n=n/g-b;for(c=0;c<g;++c)k=e[c],k.x-=r,k.y-=n}var e;null==a&&(a=0);null==b&&(b=0);c.initialize=\nfunction(a){e=a};c.x=function(b){return arguments.length?(a=+b,c):a};c.y=function(a){return arguments.length?(b=+a,c):b};return c},Ha=function(a){return function(){return a}},Ab=function(){return 1E-6*(Math.random()-.5)},qt=function(a){var b=+this.tc.call(null,a),c=+this.ce.call(null,a);return oi(this.cover(b,c),b,c,a)},rt=function(a,b){if(isNaN(a=+a)||isNaN(b=+b))return this;var c=this.ub,e=this.xb,g=this.Sa,k=this.Va;if(isNaN(c))g=(c=Math.floor(a))+1,k=(e=Math.floor(b))+1;else if(c>a||a>g||e>b||\nb>k){var n=g-c,u=this.ve,m,A;switch(A=(b<(e+k)/2)<<1|a<(c+g)/2){case 0:do m=Array(4),m[A]=u,u=m;while(n*=2,g=c+n,k=e+n,a>g||b>k);break;case 1:do m=Array(4),m[A]=u,u=m;while(n*=2,c=g-n,k=e+n,c>a||b>k);break;case 2:do m=Array(4),m[A]=u,u=m;while(n*=2,g=c+n,e=k-n,a>g||e>b);break;case 3:do m=Array(4),m[A]=u,u=m;while(n*=2,c=g-n,e=k-n,c>a||e>b)}this.ve&&this.ve.length&&(this.ve=u)}else return this;this.ub=c;this.xb=e;this.Sa=g;this.Va=k;return this},st=function(){var a=[];this.visit(function(b){if(!b.length){do a.push(b.data);\nwhile(b=b.next)}});return a},tt=function(a){return arguments.length?this.cover(+a[0][0],+a[0][1]).cover(+a[1][0],+a[1][1]):isNaN(this.ub)?void 0:[[this.ub,this.xb],[this.Sa,this.Va]]},Ia=function(a,b,c,e,g){this.node=a;this.x0=b;this.y0=c;this.x1=e;this.y1=g},ut=function(a,b,c){var e,g=this.ub,k=this.xb,r,n,u,m,y=this.Sa,q=this.Va,M=[],G=this.ve,v;G&&M.push(new Ia(G,g,k,y,q));null==c?c=Infinity:(g=a-c,k=b-c,y=a+c,q=b+c,c*=c);for(;v=M.pop();)if(!(!(G=v.node)||(r=v.x0)>y||(n=v.y0)>q||(u=v.x1)<g||(m=\nv.y1)<k))if(G.length){v=(r+u)/2;var Y=(n+m)/2;M.push(new Ia(G[3],v,Y,u,m),new Ia(G[2],r,Y,v,m),new Ia(G[1],v,n,u,Y),new Ia(G[0],r,n,v,Y));if(G=(b>=Y)<<1|a>=v)v=M[M.length-1],M[M.length-1]=M[M.length-1-G],M[M.length-1-G]=v}else v=a-+this.tc.call(null,G.data),Y=b-+this.ce.call(null,G.data),v=v*v+Y*Y,v<c&&(e=Math.sqrt(c=v),g=a-e,k=b-e,y=a+e,q=b+e,e=G.data);return e},vt=function(a){if(isNaN(A=+this.tc.call(null,a))||isNaN(q=+this.ce.call(null,a)))return this;var b,c=this.ve,e,g,k=this.ub,n=this.xb,u=\nthis.Sa,m=this.Va,A,q,ja,M,G,v,Y;if(!c)return this;if(c.length)for(;;){(G=A>=(ja=(k+u)/2))?k=ja:u=ja;(v=q>=(M=(n+m)/2))?n=M:m=M;if(!(b=c,c=c[G|=v<<1]))return this;if(!c.length)break;if(b[G+1&3]||b[G+2&3]||b[G+3&3])e=b,Y=G}for(;c.data!==a;)if(!(g=c,c=c.next))return this;(a=c.next)&&delete c.next;if(g)return a?g.next=a:delete g.next,this;if(!b)return this.ve=a,this;a?b[G]=a:delete b[G];(c=b[0]||b[1]||b[2]||b[3])&&c===(b[3]||b[2]||b[1]||b[0])&&!c.length&&(e?e[Y]=c:this.ve=c);return this},wt=function(){return this.ve},\nxt=function(){var a=0;this.visit(function(b){if(!b.length){do++a;while(b=b.next)}});return a},yt=function(a){var b=[],c,e=this.ve,g,k,n,u;for(e&&b.push(new Ia(e,this.ub,this.xb,this.Sa,this.Va));c=b.pop();)if(!a(e=c.node,k=c.x0,n=c.y0,u=c.x1,c=c.y1)&&e.length){var m=(k+u)/2,A=(n+c)/2;(g=e[3])&&b.push(new Ia(g,m,A,u,c));(g=e[2])&&b.push(new Ia(g,k,A,m,c));(g=e[1])&&b.push(new Ia(g,m,n,u,A));(g=e[0])&&b.push(new Ia(g,k,n,m,A))}return this},zt=function(a){var b=[],c=[],e;for(this.ve&&b.push(new Ia(this.ve,\nthis.ub,this.xb,this.Sa,this.Va));e=b.pop();){var g=e.node;if(g.length){var k,n=e.x0,u=e.y0,m=e.x1,A=e.y1,q=(n+m)/2,ja=(u+A)/2;(k=g[0])&&b.push(new Ia(k,n,u,q,ja));(k=g[1])&&b.push(new Ia(k,q,u,m,ja));(k=g[2])&&b.push(new Ia(k,n,ja,q,A));(k=g[3])&&b.push(new Ia(k,q,ja,m,A))}c.push(e)}for(;e=c.pop();)a(e.node,e.x0,e.y0,e.x1,e.y1);return this},At=function(a){return arguments.length?(this.tc=a,this):this.tc},Bt=function(a){return arguments.length?(this.ce=a,this):this.ce},Ja=Nd.prototype=Gf.prototype;\nJa.copy=function(){var a=new Gf(this.tc,this.ce,this.ub,this.xb,this.Sa,this.Va),b=this.ve,c,e;if(!b)return a;if(!b.length)return a.ve=pi(b),a;for(c=[{source:b,target:a.ve=Array(4)}];b=c.pop();)for(var g=0;4>g;++g)if(e=b.source[g])e.length?c.push({source:e,target:b.target[g]=Array(4)}):b.target[g]=pi(e);return a};Ja.add=qt;Ja.addAll=Bo;Ja.cover=rt;Ja.data=st;Ja.extent=tt;Ja.find=ut;Ja.remove=vt;Ja.removeAll=Co;Ja.root=wt;Ja.size=xt;Ja.visit=yt;Ja.visitAfter=zt;Ja.x=At;Ja.y=Bt;var Ct=function(a){function b(){function a(a,\nb,c,e,g){var k=a.data;a=a.r;var r=q+a;if(k)k.index>m.index&&(b=w-k.x-k.vx,c=y-k.y-k.vy,e=b*b+c*c,e<r*r&&(0===b&&(b=Ab(),e+=b*b),0===c&&(c=Ab(),e+=c*c),e=(r-(e=Math.sqrt(e)))/e*n,m.vx+=(b*=e)*(r=(a*=a)/(H+a)),m.vy+=(c*=e)*r,k.vx-=b*(r=1-r),k.vy-=c*r));else return b>w+r||e<w-r||c>y+r||g<y-r}for(var b,e=g.length,r,m,w,y,q,H,F=0;F<u;++F)for(r=Nd(g,Fo,Go).visitAfter(c),b=0;b<e;++b)m=g[b],q=k[m.index],H=q*q,w=m.x+m.vx,y=m.y+m.vy,r.visit(a)}function c(a){if(a.data)return a.r=k[a.data.index];for(var b=a.r=\n0;4>b;++b)a[b]&&a[b].r>a.r&&(a.r=a[b].r)}function e(){if(g){var b,c=g.length,e;k=Array(c);for(b=0;b<c;++b)e=g[b],k[e.index]=+a(e,b,g)}}var g,k,n=1,u=1;\"function\"!==typeof a&&(a=Ha(null==a?1:+a));b.initialize=function(a){g=a;e()};b.iterations=function(a){return arguments.length?(u=+a,b):u};b.strength=function(a){return arguments.length?(n=+a,b):n};b.radius=function(c){return arguments.length?(a=\"function\"===typeof c?c:Ha(+c),e(),b):a};return b},Dt=function(a){function b(a){return 1/Math.min(M[a.source.index],\nM[a.target.index])}function c(b){for(var c=0,e=a.length;c<B;++c)for(var g=0,k,r,n,u,w;g<e;++g)k=a[g],r=k.source,k=k.target,n=k.x+k.vx-r.x-r.vx||Ab(),u=k.y+k.vy-r.y-r.vy||Ab(),w=Math.sqrt(n*n+u*u),w=(w-q[g])/w*b*m[g],n*=w,u*=w,k.vx-=n*(w=G[g]),k.vy-=u*w,r.vx+=n*(w=1-w),r.vy+=u*w}function e(){if(v){var b,c=v.length,e=a.length,r=fb(v,n);b=0;for(M=Array(c);b<e;++b)c=a[b],c.index=b,\"object\"!==typeof c.source&&(c.source=qi(r,c.source)),\"object\"!==typeof c.target&&(c.target=qi(r,c.target)),M[c.source.index]=\n(M[c.source.index]||0)+1,M[c.target.index]=(M[c.target.index]||0)+1;b=0;for(G=Array(e);b<e;++b)c=a[b],G[b]=M[c.source.index]/(M[c.source.index]+M[c.target.index]);m=Array(e);g();q=Array(e);k()}}function g(){if(v)for(var b=0,c=a.length;b<c;++b)m[b]=+u(a[b],b,a)}function k(){if(v)for(var b=0,c=a.length;b<c;++b)q[b]=+A(a[b],b,a)}var n=Ho,u=b,m,A=Ha(30),q,v,M,G,B=1;null==a&&(a=[]);c.initialize=function(a){v=a;e()};c.links=function(b){return arguments.length?(a=b,e(),c):a};c.id=function(a){return arguments.length?\n(n=a,c):n};c.iterations=function(a){return arguments.length?(B=+a,c):B};c.strength=function(a){return arguments.length?(u=\"function\"===typeof a?a:Ha(+a),g(),c):u};c.distance=function(a){return arguments.length?(A=\"function\"===typeof a?a:Ha(+a),k(),c):A};return c},Et=Math.PI*(3-Math.sqrt(5)),Ft=function(a){function b(){c();G.call(\"tick\",k);n<u&&(M.stop(),G.call(\"end\",k))}function c(){var b,c=a.length,e;n+=(A-n)*m;v.each(function(a){a(n)});for(b=0;b<c;++b)e=a[b],null==e.fx?e.x+=e.vx*=q:(e.x=e.fx,e.vx=\n0),null==e.fy?e.y+=e.vy*=q:(e.y=e.fy,e.vy=0)}function e(){for(var b=0,c=a.length,e;b<c;++b){e=a[b];e.index=b;if(isNaN(e.x)||isNaN(e.y)){var g=10*Math.sqrt(b),k=b*Et;e.x=g*Math.cos(k);e.y=g*Math.sin(k)}if(isNaN(e.vx)||isNaN(e.vy))e.vx=e.vy=0}}function g(b){b.initialize&&b.initialize(a);return b}var k,n=1,u=.001,m=1-Math.pow(u,1/300),A=0,q=.6,v=fb(),M=Dd(b),G=E(\"tick\",\"end\");null==a&&(a=[]);e();return k={tick:c,restart:function(){return M.restart(b),k},stop:function(){return M.stop(),k},nodes:function(b){return arguments.length?\n(a=b,e(),v.each(g),k):a},alpha:function(a){return arguments.length?(n=+a,k):n},alphaMin:function(a){return arguments.length?(u=+a,k):u},alphaDecay:function(a){return arguments.length?(m=+a,k):+m},alphaTarget:function(a){return arguments.length?(A=+a,k):A},velocityDecay:function(a){return arguments.length?(q=1-a,k):1-q},force:function(a,b){return 1<arguments.length?(null==b?v.remove(a):v.set(a,g(b)),k):v.get(a)},find:function(b,c,e){var g,k=a.length,r,n,u,m;e=null==e?Infinity:e*e;for(g=0;g<k;++g)u=\na[g],r=b-u.x,n=c-u.y,r=r*r+n*n,r<e&&(m=u,e=r);return m},on:function(a,b){return 1<arguments.length?(G.on(a,b),k):G.on(a)}}},Gt=function(){function a(a){var b,r=g.length,u=Nd(g,Io,Jo).visitAfter(c);n=a;for(b=0;b<r;++b)k=g[b],u.visit(e)}function b(){if(g){var a,b=g.length,c;q=Array(b);for(a=0;a<b;++a)c=g[a],q[c.index]=+m(c,a,g)}}function c(a){var b=0,c,e,g,k,r;if(a.length){for(g=k=r=0;4>r;++r)(c=a[r])&&(e=c.value)&&(b+=e,g+=e*c.x,k+=e*c.y);a.x=g/b;a.y=k/b}else{c=a;c.x=c.data.x;c.y=c.data.y;do b+=q[c.data.index];\nwhile(c=c.next)}a.value=b}function e(a,b,c,e){if(!a.value)return!0;var g=a.x-k.x,r=a.y-k.y;b=e-b;e=g*g+r*r;if(b*b/v<e)return e<L&&(0===g&&(g=Ab(),e+=g*g),0===r&&(r=Ab(),e+=r*r),e<A&&(e=Math.sqrt(A*e)),k.vx+=g*a.value*n/e,k.vy+=r*a.value*n/e),!0;if(!(a.length||e>=L)){if(a.data!==k||a.next)0===g&&(g=Ab(),e+=g*g),0===r&&(r=Ab(),e+=r*r),e<A&&(e=Math.sqrt(A*e));do a.data!==k&&(b=q[a.data.index]*n/e,k.vx+=g*b,k.vy+=r*b);while(a=a.next)}}var g,k,n,m=Ha(-30),q,A=1,L=Infinity,v=.81;a.initialize=function(a){g=\na;b()};a.strength=function(c){return arguments.length?(m=\"function\"===typeof c?c:Ha(+c),b(),a):m};a.distanceMin=function(b){return arguments.length?(A=b*b,a):Math.sqrt(A)};a.distanceMax=function(b){return arguments.length?(L=b*b,a):Math.sqrt(L)};a.theta=function(b){return arguments.length?(v=b*b,a):Math.sqrt(v)};return a},Ht=function(a){function b(a){for(var b=0,c=g.length,e;b<c;++b)e=g[b],e.vx+=(n[b]-e.x)*k[b]*a}function c(){if(g){var b,c=g.length;k=Array(c);n=Array(c);for(b=0;b<c;++b)k[b]=isNaN(n[b]=\n+a(g[b],b,g))?0:+e(g[b],b,g)}}var e=Ha(.1),g,k,n;\"function\"!==typeof a&&(a=Ha(null==a?0:+a));b.initialize=function(a){g=a;c()};b.strength=function(a){return arguments.length?(e=\"function\"===typeof a?a:Ha(+a),c(),b):e};b.x=function(e){return arguments.length?(a=\"function\"===typeof e?e:Ha(+e),c(),b):a};return b},It=function(a){function b(a){for(var b=0,c=g.length,e;b<c;++b)e=g[b],e.vy+=(n[b]-e.y)*k[b]*a}function c(){if(g){var b,c=g.length;k=Array(c);n=Array(c);for(b=0;b<c;++b)k[b]=isNaN(n[b]=+a(g[b],\nb,g))?0:+e(g[b],b,g)}}var e=Ha(.1),g,k,n;\"function\"!==typeof a&&(a=Ha(null==a?0:+a));b.initialize=function(a){g=a;c()};b.strength=function(a){return arguments.length?(e=\"function\"===typeof a?a:Ha(+a),c(),b):e};b.y=function(e){return arguments.length?(a=\"function\"===typeof e?e:Ha(+e),c(),b):a};return b},Te=function(a,b){if(0>(b=(a=b?a.toExponential(b-1):a.toExponential()).indexOf(\"e\")))return null;var c=a.slice(0,b);return[1<c.length?c[0]+c.slice(2):c,+a.slice(b+1)]},yc=function(a){return a=Te(Math.abs(a)),\na?a[1]:NaN},Jt=function(a,b){return function(c,e){for(var g=c.length,k=[],n=0,r=a[0],m=0;0<g&&0<r;){m+r+1>e&&(r=Math.max(1,e-m));k.push(c.substring(g-=r,g+r));if((m+=r+1)>e)break;r=a[n=(n+1)%a.length]}return k.reverse().join(b)}},Kt=function(a,b){a=a.toPrecision(b);b=a.length;var c=1,e=-1,g;a:for(;c<b;++c)switch(a[c]){case \".\":e=g=c;break;case \"0\":0===e&&(e=c);g=c;break;case \"e\":break a;default:0<e&&(e=0)}return 0<e?a.slice(0,e)+a.slice(g+1):a},pl,Lt=function(a,b){var c=Te(a,b);if(!c)return a+\"\";\nvar e=c[0],c=c[1],c=c-(pl=3*Math.max(-8,Math.min(8,Math.floor(c/3))))+1,g=e.length;return c===g?e:c>g?e+Array(c-g+1).join(\"0\"):0<c?e.slice(0,c)+\".\"+e.slice(c):\"0.\"+Array(1-c).join(\"0\")+Te(a,Math.max(0,b+c-1))[0]},ql=function(a,b){b=Te(a,b);if(!b)return a+\"\";a=b[0];b=b[1];return 0>b?\"0.\"+Array(-b).join(\"0\")+a:a.length>b+1?a.slice(0,b+1)+\".\"+a.slice(b+1):a+Array(b-a.length+2).join(\"0\")},si={\"\":Kt,\"%\":function(a,b){return(100*a).toFixed(b)},b:function(a){return Math.round(a).toString(2)},c:function(a){return a+\n\"\"},d:function(a){return Math.round(a).toString(10)},e:function(a,b){return a.toExponential(b)},f:function(a,b){return a.toFixed(b)},g:function(a,b){return a.toPrecision(b)},o:function(a){return Math.round(a).toString(8)},p:function(a,b){return ql(100*a,b)},r:ql,s:Lt,X:function(a){return Math.round(a).toString(16).toUpperCase()},x:function(a){return Math.round(a).toString(16)}},Ko=/^(?:(.)?([<>=^]))?([+\\-\\( ])?([$#])?(0)?(\\d+)?(,)?(\\.\\d+)?([a-z%])?$/i,xe=function(a){return new ri(a)};ri.prototype.toString=\nfunction(){return this.fill+this.align+this.sign+this.symbol+(this.zero?\"0\":\"\")+(null==this.width?\"\":Math.max(1,this.width|0))+(this.comma?\",\":\"\")+(null==this.precision?\"\":\".\"+Math.max(0,this.precision|0))+this.type};var rl=\"y z a f p n \\u00b5 m  k M G T P E Z Y\".split(\" \"),ui=function(a){function b(a){function b(a){var b=H,g=v,m,A,G;if(\"c\"===F)g=B(a)+g,a=\"\";else{a=+a;var L=(0>a||0>1/a)&&(a*=-1,!0);a=B(a,y);if(L)for(m=-1,A=a.length,L=!1;++m<A;)if(G=a.charCodeAt(m),48<G&&58>G||\"x\"===F&&96<G&&103>G||\n\"X\"===F&&64<G&&71>G){L=!0;break}b=(L?\"(\"===r?r:\"-\":\"-\"===r||\"(\"===r?\"\":r)+b;g=g+(\"s\"===F?rl[8+pl/3]:\"\")+(L&&\"(\"===r?\")\":\"\");if(ca)for(m=-1,A=a.length;++m<A;)if(G=a.charCodeAt(m),48>G||57<G){g=(46===G?k+a.slice(m+1):a.slice(m))+g;a=a.slice(0,m);break}}q&&!u&&(a=e(a,Infinity));m=b.length+a.length+g.length;A=m<w?Array(w-m+1).join(c):\"\";q&&u&&(a=e(A+a,A.length?w-g.length:Infinity),A=\"\");switch(n){case \"\\x3c\":return b+a+g+A;case \"\\x3d\":return b+A+a+g;case \"^\":return A.slice(0,m=A.length>>1)+b+a+g+A.slice(m)}return A+\nb+a+g}a=xe(a);var c=a.fill,n=a.align,r=a.sign,m=a.symbol,u=a.zero,w=a.width,q=a.comma,y=a.precision,F=a.type,H=\"$\"===m?g[0]:\"#\"===m&&/[boxX]/.test(F)?\"0\"+F.toLowerCase():\"\",v=\"$\"===m?g[1]:/[%p]/.test(F)?\"%\":\"\",B=si[F],ca=!F||/[defgprs%]/.test(F),y=null==y?F?6:12:/[gprs]/.test(F)?Math.max(1,Math.min(21,y)):Math.max(0,Math.min(20,y));b.toString=function(){return a+\"\"};return b}function c(a,c){var e=b((a=xe(a),a.type=\"f\",a));a=3*Math.max(-8,Math.min(8,Math.floor(yc(c)/3)));var g=Math.pow(10,-a),k=rl[8+\na/3];return function(a){return e(g*a)+k}}var e=a.grouping&&a.thousands?Jt(a.grouping,a.thousands):Lo,g=a.currency,k=a.decimal;return{format:b,formatPrefix:c}},Od;ti({decimal:\".\",thousands:\",\",grouping:[3],currency:[\"$\",\"\"]});var Qj=function(a){return Math.max(0,-yc(Math.abs(a)))},Oj=function(a,b){return Math.max(0,3*Math.max(-8,Math.min(8,Math.floor(yc(b)/3)))-yc(Math.abs(a)))},Pj=function(a,b){a=Math.abs(a);b=Math.abs(b)-a;return Math.max(0,yc(b)-yc(a))+1};$a.prototype={constructor:$a,reset:function(){this.s=\nthis.t=0},add:function(a){vi(Ue,a,this.t);vi(this,Ue.s,this.s);this.s?this.t+=Ue.t:this.s=Ue.t},valueOf:function(){return this.s}};var Ue=new $a,ha=Math.PI,ra=ha/2,Qd=ha/4,La=2*ha,pa=180/ha,Z=ha/180,ia=Math.abs,lc=Math.atan,Ba=Math.atan2,S=Math.cos,fe=Math.ceil,sl=Math.exp,ne=Math.log,hg=Math.pow,N=Math.sin,Zc=Math.sign||function(a){return 0<a?1:0>a?-1:0},wa=Math.sqrt,nc=Math.tan,tl={Feature:function(a,b){Pd(a.geometry,b)},FeatureCollection:function(a,b){a=a.features;for(var c=-1,e=a.length;++c<e;)Pd(a[c].geometry,\nb)}},yi={YZ:function(a,b){b.sphere()},Point:function(a,b){a=a.coordinates;b.point(a[0],a[1],a[2])},MultiPoint:function(a,b){for(var c=a.coordinates,e=-1,g=c.length;++e<g;)a=c[e],b.point(a[0],a[1],a[2])},LineString:function(a,b){Hf(a.coordinates,b,0)},MultiLineString:function(a,b){a=a.coordinates;for(var c=-1,e=a.length;++c<e;)Hf(a[c],b,0)},Polygon:function(a,b){zi(a.coordinates,b)},MultiPolygon:function(a,b){a=a.coordinates;for(var c=-1,e=a.length;++c<e;)zi(a[c],b)},GeometryCollection:function(a,\nb){a=a.geometries;for(var c=-1,e=a.length;++c<e;)Pd(a[c],b)}},cb=function(a,b){if(a&&tl.hasOwnProperty(a.type))tl[a.type](a,b);else Pd(a,b)},Rd=new $a,Ve=new $a,Bi,Ci,If,Jf,Kf,gb={point:sa,lineStart:sa,lineEnd:sa,polygonStart:function(){Rd.reset();gb.lineStart=Mo;gb.lineEnd=Oo},polygonEnd:function(){var a=+Rd;Ve.add(0>a?La+a:a);this.lineStart=this.lineEnd=this.point=sa},sphere:function(){Ve.add(La)}},Mt=function(a){Ve.reset();cb(a,gb);return 2*Ve},ua,Pa,va,Ta,Ob,Hi,Ii,hc,Qc=new $a,wb,nb,ob={point:Mf,\nlineStart:Ei,lineEnd:Fi,polygonStart:function(){ob.point=Gi;ob.lineStart=Po;ob.lineEnd=Qo;Qc.reset();gb.polygonStart()},polygonEnd:function(){gb.polygonEnd();ob.point=Mf;ob.lineStart=Ei;ob.lineEnd=Fi;0>Rd?(ua=-(va=180),Pa=-(Ta=90)):1E-6<Qc?Ta=90:-1E-6>Qc&&(Pa=-90);nb[0]=ua;nb[1]=va}},Nt=function(a){var b,c,e,g,k,n;Ta=va=-(ua=Pa=Infinity);wb=[];cb(a,ob);if(b=wb.length){wb.sort(Ro);a=1;c=wb[0];for(g=[c];a<b;++a)e=wb[a],Ji(c,e[0])||Ji(c,e[1])?(Qa(c[0],e[1])>Qa(c[0],c[1])&&(c[1]=e[1]),Qa(e[0],c[1])>Qa(c[0],\nc[1])&&(c[0]=e[0])):g.push(c=e);k=-Infinity;b=g.length-1;a=0;for(c=g[b];a<=b;c=e,++a)e=g[a],(n=Qa(c[1],e[0]))>k&&(k=n,ua=e[0],va=c[1])}wb=nb=null;return Infinity===ua||Infinity===Pa?[[NaN,NaN],[NaN,NaN]]:[[ua,Pa],[va,Ta]]},Sc,Zd,Wd,Xd,Yd,$d,ae,be,Of,Pf,Qf,Ni,Oi,Ca,Da,Ea,ab={sphere:sa,point:Nf,lineStart:Ki,lineEnd:Li,polygonStart:function(){ab.lineStart=Uo;ab.lineEnd=Wo},polygonEnd:function(){ab.lineStart=Ki;ab.lineEnd=Li}},Ot=function(a){Sc=Zd=Wd=Xd=Yd=$d=ae=be=Of=Pf=Qf=0;cb(a,ab);a=Of;var b=Pf,c=\nQf,e=a*a+b*b+c*c;return 1E-12>e&&(a=$d,b=ae,c=be,1E-6>Zd&&(a=Wd,b=Xd,c=Yd),e=a*a+b*b+c*c,1E-12>e)?[NaN,NaN]:[Ba(b,a)*pa,Oa(c/wa(e))*pa]},zc=function(a){return function(){return a}},Pi=function(a,b){function c(c,e){return c=a(c,e),b(c[0],c[1])}a.invert&&b.invert&&(c.invert=function(c,e){return c=b.invert(c,e),c&&a.invert(c[0],c[1])});return c};Rf.invert=Rf;var Pt=function(a){function b(b){b=a(b[0]*Z,b[1]*Z);return b[0]*=pa,b[1]*=pa,b}a=Sf(a[0]*Z,a[1]*Z,2<a.length?a[2]*Z:0);b.invert=function(b){b=a.invert(b[0]*\nZ,b[1]*Z);return b[0]*=pa,b[1]*=pa,b};return b},Qt=function(){function a(a,b){k.push(a=n(a,b));a[0]*=pa;a[1]*=pa}function b(){var a=c.apply(this,arguments),b=e.apply(this,arguments)*Z,r=g.apply(this,arguments)*Z;k=[];n=Sf(-a[0]*Z,-a[1]*Z,0).invert;Ti(m,b,r,1);a={type:\"Polygon\",coordinates:[k]};k=n=null;return a}var c=zc([0,0]),e=zc(90),g=zc(6),k,n,m={point:a};b.center=function(a){return arguments.length?(c=\"function\"===typeof a?a:zc([+a[0],+a[1]]),b):c};b.radius=function(a){return arguments.length?\n(e=\"function\"===typeof a?a:zc(+a),b):e};b.precision=function(a){return arguments.length?(g=\"function\"===typeof a?a:zc(+a),b):g};return b},Xi=function(){var a=[],b;return{point:function(a,c){b.push([a,c])},lineStart:function(){a.push(b=[])},lineEnd:sa,qP:function(){1<a.length&&a.push(a.pop().concat(a.shift()))},result:function(){var c=a;a=[];b=null;return c}}},Xo=function(a,b,c,e,g,k){var n=a[0],r=a[1],m=b[0],w=b[1],u=0,q=1,m=m-n,w=w-r;c-=n;if(m||!(0<c)){c/=m;if(0>m){if(c<u)return;c<q&&(q=c)}else if(0<\nm){if(c>q)return;c>u&&(u=c)}c=g-n;if(m||!(0>c)){c/=m;if(0>m){if(c>q)return;c>u&&(u=c)}else if(0<m){if(c<u)return;c<q&&(q=c)}c=e-r;if(w||!(0<c)){c/=w;if(0>w){if(c<u)return;c<q&&(q=c)}else if(0<w){if(c>q)return;c>u&&(u=c)}c=k-r;if(w||!(0>c)){c/=w;if(0>w){if(c>q)return;c>u&&(u=c)}else if(0<w){if(c<u)return;c<q&&(q=c)}0<u&&(a[0]=n+u*m,a[1]=r+u*w);1>q&&(b[0]=n+q*m,b[1]=r+q*w);return!0}}}}},We=function(a,b){return 1E-6>ia(a[0]-b[0])&&1E-6>ia(a[1]-b[1])},Wi=function(a,b,c,e,g){var k=[],n=[],r;a.forEach(function(a){if(!(0>=\n(b=a.length-1))){var b,c=a[0],e=a[b];if(We(c,e)){g.lineStart();for(r=0;r<b;++r)g.point((c=a[r])[0],c[1]);g.lineEnd()}else k.push(b=new ce(c,a,null,!0)),n.push(b.Mo=new ce(c,null,b,!1)),k.push(b=new ce(e,a,null,!1)),n.push(b.Mo=new ce(e,null,b,!0))}});if(k.length){n.sort(b);Vi(k);Vi(n);r=0;for(a=n.length;r<a;++r)n[r].e=c=!c;c=k[0];for(var m;;){for(var w=c,u=!0;w.Ak;)if((w=w.n)===c)return;b=w.z;g.lineStart();do{w.Ak=w.Mo.Ak=!0;if(w.e){if(u)for(r=0,a=b.length;r<a;++r)g.point((m=b[r])[0],m[1]);else e(w.x,\nw.n.x,1,g);w=w.n}else{if(u)for(b=w.p.z,r=b.length-1;0<=r;--r)g.point((m=b[r])[0],m[1]);else e(w.x,w.p.x,-1,g);w=w.p}w=w.Mo;b=w.z;u=!u}while(!w.Ak);g.lineEnd()}}},Rt=function(){var a=0,b=0,c=960,e=500,g,k,n;return n={stream:function(n){return g&&k===n?g:g=Tf(a,b,c,e)(k=n)},extent:function(r){return arguments.length?(a=+r[0][0],b=+r[0][1],c=+r[1][0],e=+r[1][1],g=k=null,n):[[a,b],[c,e]]}}},Wf=new $a,Vf,de,ee,ic={sphere:sa,point:sa,lineStart:Yo,lineEnd:sa,polygonStart:sa,polygonEnd:sa},ul=function(a){Wf.reset();\ncb(a,ic);return+Wf},eh=[null,null],St={type:\"LineString\",coordinates:eh},Tt=function(a,b){eh[0]=a;eh[1]=b;return ul(St)},Ut=function(a,b){var c=a[0]*Z,e=a[1]*Z;a=b[0]*Z;b=b[1]*Z;var g=S(e),k=N(e),n=S(b),m=N(b),u=g*S(c),A=g*N(c),q=n*S(a),v=n*N(a),y=2*Oa(wa(xi(b-e)+g*n*xi(a-c))),G=N(y);a=y?function(a){var b=N(a*=y)/G,c=N(y-a)/G;a=c*u+b*q;var e=c*A+b*v,b=c*k+b*m;return[Ba(e,a)*pa,Ba(b,wa(a*a+e*e))*pa]}:function(){return[c*pa,e*pa]};a.distance=y;return a},Qb=function(a){return a},fh=new $a,Zf=new $a,\nbj,cj,Xf,Yf,pb={point:sa,lineStart:sa,lineEnd:sa,polygonStart:function(){pb.lineStart=cp;pb.lineEnd=ep},polygonEnd:function(){pb.lineStart=pb.lineEnd=pb.point=sa;fh.add(ia(Zf));Zf.reset()},result:function(){var a=fh/2;fh.reset();return a}},jc=Infinity,ge=jc,Tc=-jc,he=Tc,le={point:fp,lineStart:sa,lineEnd:sa,polygonStart:sa,polygonEnd:sa,result:function(){var a=[[jc,ge],[Tc,he]];Tc=he=-(ge=jc=Infinity);return a}},$f=0,ag=0,Uc=0,ie=0,je=0,kc=0,bg=0,cg=0,Vc=0,gj,hj,hb,ib,Ua={point:Pb,lineStart:dj,lineEnd:ej,\npolygonStart:function(){Ua.lineStart=ip;Ua.lineEnd=kp},polygonEnd:function(){Ua.point=Pb;Ua.lineStart=dj;Ua.lineEnd=ej},result:function(){var a=Vc?[bg/Vc,cg/Vc]:kc?[ie/kc,je/kc]:Uc?[$f/Uc,ag/Uc]:[NaN,NaN];$f=ag=Uc=ie=je=kc=bg=cg=Vc=0;return a}};ij.prototype={xq:4.5,pointRadius:function(a){return this.xq=a,this},polygonStart:function(){this.Ta=0},polygonEnd:function(){this.Ta=NaN},lineStart:function(){this.Ha=0},lineEnd:function(){0===this.Ta&&this.Ia.closePath();this.Ha=NaN},point:function(a,b){switch(this.Ha){case 0:this.Ia.moveTo(a,\nb);this.Ha=1;break;case 1:this.Ia.lineTo(a,b);break;default:this.Ia.moveTo(a+this.xq,b),this.Ia.arc(a,b,this.xq,0,La)}},result:sa};var dg=new $a,gh,kj,lj,Xc,Yc,Wc={point:sa,lineStart:function(){Wc.point=lp},lineEnd:function(){gh&&jj(kj,lj);Wc.point=sa},polygonStart:function(){gh=!0},polygonEnd:function(){gh=null},result:function(){var a=+dg;dg.reset();return a}};mj.prototype={wv:nj(4.5),pointRadius:function(a){return this.wv=nj(a),this},polygonStart:function(){this.Ta=0},polygonEnd:function(){this.Ta=\nNaN},lineStart:function(){this.Ha=0},lineEnd:function(){0===this.Ta&&this.Yi.push(\"Z\");this.Ha=NaN},point:function(a,b){switch(this.Ha){case 0:this.Yi.push(\"M\",a,\",\",b);this.Ha=1;break;case 1:this.Yi.push(\"L\",a,\",\",b);break;default:this.Yi.push(\"M\",a,\",\",b,this.wv)}},result:function(){if(this.Yi.length){var a=this.Yi.join(\"\");this.Yi=[];return a}}};var Vt=function(a,b){function c(a){a&&(\"function\"===typeof e&&k.pointRadius(+e.apply(this,arguments)),cb(a,g(k)));return k.result()}var e=4.5,g,k;c.area=\nfunction(a){cb(a,g(pb));return pb.result()};c.measure=function(a){cb(a,g(Wc));return Wc.result()};c.bounds=function(a){cb(a,g(le));return le.result()};c.centroid=function(a){cb(a,g(Ua));return Ua.result()};c.projection=function(b){return arguments.length?(g=null==b?(a=null,Qb):(a=b).stream,c):a};c.context=function(a){if(!arguments.length)return b;k=null==a?(b=null,new mj):new ij(b=a);\"function\"!==typeof e&&k.pointRadius(e);return c};c.pointRadius=function(a){if(!arguments.length)return e;e=\"function\"===\ntypeof a?a:(k.pointRadius(+a),+a);return c};return c.projection(a).context(b)},hh=new $a,vl=function(a,b,c,e){return function(g,k){function n(b,c){var e=g(b,c);a(b=e[0],c=e[1])&&k.point(b,c)}function r(a,b){a=g(a,b);G.point(a[0],a[1])}function m(){W.point=r;G.lineStart()}function w(){W.point=n;G.lineEnd()}function u(a,b){C.push([a,b]);a=g(a,b);H.point(a[0],a[1])}function q(){H.lineStart();C=[]}function v(){u(C[0][0],C[0][1]);H.lineEnd();var a=H.$w(),b=F.result(),c=b.length,e;C.pop();E.push(C);C=null;\nif(c)if(a&1){if(c=b[0],0<(b=c.length-1)){B||(k.polygonStart(),B=!0);k.lineStart();for(a=0;a<b;++a)k.point((e=c[a])[0],e[1]);k.lineEnd()}}else 1<c&&a&2&&b.push(b.pop().concat(b.shift())),J.push(b.filter(mp))}var G=b(k),y=g.invert(e[0],e[1]),F=Xi(),H=b(F),B=!1,E,J,C,W={point:n,lineStart:m,lineEnd:w,polygonStart:function(){W.point=u;W.lineStart=q;W.lineEnd=v;J=[];E=[]},polygonEnd:function(){W.point=n;W.lineStart=m;W.lineEnd=w;J=Uf(J);var a;a=E;var b=y[0],e=y[1],g=[N(b),-S(b),0],r=0,u=0;hh.reset();for(var A=\n0,q=a.length;A<q;++A)if(v=(G=a[A]).length)for(var G,v,L=G[v-1],F=L[0],M=L[1]/2+Qd,H=N(M),ja=S(M),M=0;M<v;++M,F=C,H=ca,ja=Y,L=T){var T=G[M],C=T[0],Y=T[1]/2+Qd,ca=N(Y),Y=S(Y),O=C-F,K=0<=O?1:-1,Xa=K*O,Aa=Xa>ha,H=H*ca;hh.add(Ba(H*K*N(Xa),ja*Y+H*S(Xa)));r+=Aa?O+K*La:O;Aa^F>=b^C>=b&&(L=gc(Nb(L),Nb(T)),Vd(L),F=gc(g,L),Vd(F),F=(Aa^0<=O?-1:1)*Oa(F[2]),e>F||e===F&&(L[0]||L[1]))&&(u+=Aa^0<=O?1:-1)}a=(-1E-6>r||1E-6>r&&-1E-6>hh)^u&1;J.length?(B||(k.polygonStart(),B=!0),Wi(J,np,a,c,k)):a&&(B||(k.polygonStart(),\nB=!0),k.lineStart(),c(null,null,1,k),k.lineEnd());B&&(k.polygonEnd(),B=!1);J=E=null},sphere:function(){k.polygonStart();k.lineStart();c(null,null,1,k);k.lineEnd();k.polygonEnd()}};return W}},qj=vl(function(){return!0},op,pp,[-ha,-ra]),sp=function(a,b){function c(c,e,g,k){Ti(k,a,b,g,c,e)}function e(a,b){return S(a)*S(b)>m}function g(a){var b,c,g,r,m;return{lineStart:function(){r=g=!1;m=1},point:function(w,q){var G=[w,q],v=e(w,q);q=u?v?0:n(w,q):v?n(w+(0>w?ha:-ha),q):0;!b&&(r=g=v)&&a.lineStart();v!==\ng&&(w=k(b,G),We(b,w)||We(G,w))&&(G[0]+=1E-6,G[1]+=1E-6,v=e(G[0],G[1]));if(v!==g)m=0,v?(a.lineStart(),w=k(G,b),a.point(w[0],w[1])):(w=k(b,G),a.point(w[0],w[1]),a.lineEnd()),b=w;else if(A&&b&&u^v){var y;q&c||!(y=k(G,b,!0))||(m=0,u?(a.lineStart(),a.point(y[0][0],y[0][1]),a.point(y[1][0],y[1][1]),a.lineEnd()):(a.point(y[1][0],y[1][1]),a.lineEnd(),a.lineStart(),a.point(y[0][0],y[0][1])))}!v||b&&We(b,G)||a.point(G[0],G[1]);b=G;g=v;c=q},lineEnd:function(){g&&a.lineEnd();b=null},$w:function(){return m|(r&&\ng)<<1}}}function k(a,b,c){var e=Nb(a),g=Nb(b),k=[1,0,0],e=gc(e,g),g=Td(e,e),n=e[0],r=g-n*n;if(!r)return!c&&a;g=m*g/r;r=-m*n/r;n=gc(k,e);k=Ud(k,g);e=Ud(e,r);Lf(k,e);e=n;g=Td(k,e);n=Td(e,e);r=g*g-n*(Td(k,k)-1);if(!(0>r)){var w=wa(r),r=Ud(e,(-g-w)/n);Lf(r,k);r=Sd(r);if(!c)return r;c=a[0];var A=b[0];a=a[1];b=b[1];var u;A<c&&(u=c,c=A,A=u);var q=A-c,v=1E-6>ia(q-ha),y=v||1E-6>q;!v&&b<a&&(u=a,a=b,b=u);if(y?v?0<a+b^r[1]<(1E-6>ia(r[0]-c)?a:b):a<=r[1]&&r[1]<=b:q>ha^(c<=r[0]&&r[0]<=A))return b=Ud(e,(-g+w)/n),\nLf(b,k),[r,Sd(b)]}}function n(b,c){var e=u?a:ha-a,g=0;b<-e?g|=1:b>e&&(g|=2);c<-e?g|=4:c>e&&(g|=8);return g}var m=S(a),u=0<m,A=1E-6<ia(m);return vl(e,g,c,u?[0,-a]:[-ha,a-ha])},Wt=function(a){return{stream:ke(a)}};eg.prototype={constructor:eg,point:function(a,b){this.stream.point(a,b)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}};\nvar qp=S(30*Z),rp=ke({point:function(a,b){this.stream.point(a*Z,b*Z)}}),Xe=function(){return gg(rj).scale(155.424).center([0,33.6442])},wl=function(){return Xe().parallels([29.5,45.5]).scale(1070).translate([480,250]).rotate([96,0]).center([-.6,38.7])},Xt=function(){function a(a){var b=a[0];a=a[1];return v=null,(k.point(b,a),v)||(m.point(b,a),v)||(A.point(b,a),v)}function b(){c=e=null;return a}var c,e,g=wl(),k,n=Xe().rotate([154,0]).center([-2,58.5]).parallels([55,65]),m,q=Xe().rotate([157,0]).center([-3,\n19.9]).parallels([8,18]),A,v,B={point:function(a,b){v=[a,b]}};a.invert=function(a){var b=g.scale(),c=g.translate(),e=(a[0]-c[0])/b,b=(a[1]-c[1])/b;return(.12<=b&&.234>b&&-.425<=e&&-.214>e?n:.166<=b&&.234>b&&-.214<=e&&-.115>e?q:g).invert(a)};a.stream=function(a){return c&&e===a?c:c=up([g.stream(e=a),n.stream(a),q.stream(a)])};a.precision=function(a){if(!arguments.length)return g.precision();g.precision(a);n.precision(a);q.precision(a);return b()};a.scale=function(b){if(!arguments.length)return g.scale();\ng.scale(b);n.scale(.35*b);q.scale(b);return a.translate(g.translate())};a.translate=function(a){if(!arguments.length)return g.translate();var c=g.scale(),e=+a[0],r=+a[1];k=g.translate(a).clipExtent([[e-.455*c,r-.238*c],[e+.455*c,r+.238*c]]).stream(B);m=n.translate([e-.307*c,r+.201*c]).clipExtent([[e-.425*c+1E-6,r+.12*c+1E-6],[e-.214*c-1E-6,r+.234*c-1E-6]]).stream(B);A=q.translate([e-.205*c,r+.212*c]).clipExtent([[e-.214*c+1E-6,r+.166*c+1E-6],[e-.115*c-1E-6,r+.234*c-1E-6]]).stream(B);return b()};a.fitExtent=\nfunction(b,c){return mc(a,b,c)};a.fitSize=function(b,c){return mc(a,[[0,0],b],c)};return a.scale(1070)},ih=sj(function(a){return wa(2/(1+a))});ih.invert=$c(function(a){return 2*Oa(a/2)});var Yt=function(){return xb(ih).scale(124.75).clipAngle(179.999)},jh=sj(function(a){return(a=wi(a))&&a/N(a)});jh.invert=$c(function(a){return a});var Zt=function(){return xb(jh).scale(79.4188).clipAngle(179.999)};me.invert=function(a,b){return[a,2*lc(sl(b))-ra]};var $t=function(){return tj(me).scale(961/La)},au=function(){return gg(uj).scale(109.5).parallels([30,\n30])};ad.invert=ad;var bu=function(){return xb(ad).scale(152.63)},cu=function(){return gg(vj).scale(131.154).center([0,13.9389])};ig.invert=$c(lc);var du=function(){return xb(ig).scale(144.049).clipAngle(60)},eu=function(){function a(){M=G=null;return E}var b=1,c=0,e=0,g=1,k=1,n=Qb,m=null,q,A,v,B=Qb,M,G,E;return E={stream:function(a){return M&&G===a?M:M=n(B(G=a))},clipExtent:function(b){return arguments.length?(B=null==b?(m=q=A=v=null,Qb):Tf(m=+b[0][0],q=+b[0][1],A=+b[1][0],v=+b[1][1]),a()):null==\nm?null:[[m,q],[A,v]]},scale:function(r){return arguments.length?(n=oe((b=+r)*g,b*k,c,e),a()):b},translate:function(r){return arguments.length?(n=oe(b*g,b*k,c=+r[0],e=+r[1]),a()):[c,e]},reflectX:function(r){return arguments.length?(n=oe(b*(g=r?-1:1),b*k,c,e),a()):0>g},reflectY:function(r){return arguments.length?(n=oe(b*g,b*(k=r?-1:1),c,e),a()):0>k},fitExtent:function(a,b){return mc(E,a,b)},fitSize:function(a,b){return mc(E,[[0,0],a],b)}}};jg.invert=$c(Oa);var fu=function(){return xb(jg).scale(249.5).clipAngle(90.000001)};\nkg.invert=$c(function(a){return 2*lc(a)});var gu=function(){return xb(kg).scale(250).clipAngle(142)};lg.invert=function(a,b){return[-b,2*lc(sl(a))-ra]};var hu=function(){var a=tj(lg),b=a.center,c=a.rotate;a.center=function(a){return arguments.length?b([-a[1],a[0]]):(a=b(),[a[1],-a[0]])};a.rotate=function(a){return arguments.length?c([a[0],a[1],2<a.length?a[2]+90:90]):(a=c(),[a[0],a[1],a[2]-90])};return c([0,0,90]).scale(159.155)},iu=function(){function a(a){var k,n=0;a.eachAfter(function(a){var c=\na.children;if(c){var e;e=c;e=e.reduce(wp,0)/e.length;a.x=e;a.y=1+c.reduce(xp,0)}else a.x=k?n+=b(a,k):0,a.y=0,k=a});var r=yp(a),m=zp(a),w=r.x-b(r,m)/2,q=m.x+b(m,r)/2;return a.eachAfter(g?function(b){b.x=(b.x-a.x)*c;b.y=(a.y-b.y)*e}:function(b){b.x=(b.x-w)/(q-w)*c;b.y=(1-(a.y?b.y/a.y:1))*e})}var b=vp,c=1,e=1,g=!1;a.separation=function(c){return arguments.length?(b=c,a):b};a.size=function(b){return arguments.length?(g=!1,c=+b[0],e=+b[1],a):g?null:[c,e]};a.nodeSize=function(b){return arguments.length?\n(g=!0,c=+b[0],e=+b[1],a):g?[c,e]:null};return a},ju=function(){return this.eachAfter(Ap)},ku=function(a){var b=this,c,e=[b],g,k;do for(c=e.reverse(),e=[];b=c.pop();)if(a(b),b=b.children)for(g=0,k=b.length;g<k;++g)e.push(b[g]);while(e.length);return this},lu=function(a){for(var b=this,c=[b],e;b=c.pop();)if(a(b),b=b.children)for(e=b.length-1;0<=e;--e)c.push(b[e]);return this},mu=function(a){for(var b=this,c=[b],e=[],g,k;b=c.pop();)if(e.push(b),b=b.children)for(g=0,k=b.length;g<k;++g)c.push(b[g]);for(;b=\ne.pop();)a(b);return this},nu=function(a){return this.eachAfter(function(b){for(var c=+a(b.data)||0,e=b.children,g=e&&e.length;0<=--g;)c+=e[g].value;b.value=c})},ou=function(a){return this.eachBefore(function(b){b.children&&b.children.sort(a)})},pu=function(a){var b=this,c;c=b;var e=a;if(c!==e){var g=c.ancestors(),k=e.ancestors(),n=null;c=g.pop();for(e=k.pop();c===e;)n=c,c=g.pop(),e=k.pop();c=n}for(e=[b];b!==c;)b=b.parent,e.push(b);for(b=e.length;a!==c;)e.splice(b,0,a),a=a.parent;return e},qu=function(){for(var a=\nthis,b=[a];a=a.parent;)b.push(a);return b},ru=function(){var a=[];this.each(function(b){a.push(b)});return a},su=function(){var a=[];this.eachBefore(function(b){b.children||a.push(b)});return a},tu=function(){var a=this,b=[];a.each(function(c){c!==a&&b.push({source:c.parent,target:c})});return b};oc.prototype=mg.prototype={constructor:oc,count:ju,each:ku,eachAfter:mu,eachBefore:lu,sum:nu,sort:ou,path:pu,ancestors:qu,descendants:ru,leaves:su,links:tu,copy:Cp};var Dj=function(a){for(var b,c=(a=a.slice()).length,\ne=null,g=e;c;){var k=new Ep(a[c-1]),g=g?g.next=k:e=k;a[b]=a[--c]}b={head:e,Dm:g};return xj(b,[])},uu=function(a){Cj(a);return a},Ac=function(a){return function(){return a}},vu=function(){function a(a){a.x=c/2;a.y=e/2;b?a.eachBefore(Ej(b)).eachAfter(ng(g,.5)).eachBefore(Fj(1)):a.eachBefore(Ej(Fp)).eachAfter(ng(Rb,1)).eachAfter(ng(g,a.r/Math.min(c,e))).eachBefore(Fj(Math.min(c,e)/(2*a.r)));return a}var b=null,c=1,e=1,g=Rb;a.radius=function(c){return arguments.length?(b=null==c?null:qe(c),a):b};a.size=\nfunction(b){return arguments.length?(c=+b[0],e=+b[1],a):[c,e]};a.padding=function(b){return arguments.length?(g=\"function\"===typeof b?b:Ac(+b),a):g};return a},xl=function(a){a.x0=Math.round(a.x0);a.y0=Math.round(a.y0);a.x1=Math.round(a.x1);a.y1=Math.round(a.y1)},bd=function(a,b,c,e,g){var k=a.children,n=-1,r=k.length;for(e=a.value&&(e-b)/a.value;++n<r;)a=k[n],a.y0=c,a.y1=g,a.x0=b,a.x1=b+=a.value*e},wu=function(){function a(a){var n=a.height+1;a.x0=a.y0=g;a.x1=c;a.y1=e/n;a.eachBefore(b(e,n));k&&a.eachBefore(xl);\nreturn a}function b(a,b){return function(c){c.children&&bd(c,c.x0,a*(c.depth+1)/b,c.x1,a*(c.depth+2)/b);var e=c.x0,k=c.y0,n=c.x1-g,r=c.y1-g;n<e&&(e=n=(e+n)/2);r<k&&(k=r=(k+r)/2);c.x0=e;c.y0=k;c.x1=n;c.y1=r}}var c=1,e=1,g=0,k=!1;a.round=function(b){return arguments.length?(k=!!b,a):k};a.size=function(b){return arguments.length?(c=+b[0],e=+b[1],a):[c,e]};a.padding=function(b){return arguments.length?(g=+b,a):g};return a},xu={depth:-1},yl={},yu=function(){function a(a){var e,g,k=a.length,n,r,m=Array(k),\nw,q={};for(g=0;g<k;++g)e=a[g],r=m[g]=new oc(e),null!=(w=b(e,g,a))&&(w+=\"\")&&(e=\"$\"+(r.id=w),q[e]=e in q?yl:r);for(g=0;g<k;++g)if(r=m[g],w=c(a[g],g,a),null!=w&&(w+=\"\")){e=q[\"$\"+w];if(!e)throw Error(\"missing: \"+w);if(e===yl)throw Error(\"ambiguous: \"+w);e.children?e.children.push(r):e.children=[r];r.parent=e}else{if(n)throw Error(\"multiple roots\");n=r}if(!n)throw Error(\"no root\");n.parent=xu;n.eachBefore(function(a){a.depth=a.parent.depth+1;--k}).eachBefore(wj);n.parent=null;if(0<k)throw Error(\"cycle\");\nreturn n}var b=Gp,c=Hp;a.id=function(c){return arguments.length?(b=qe(c),a):b};a.parentId=function(b){return arguments.length?(c=qe(b),a):c};return a};re.prototype=Object.create(oc.prototype);var zu=function(){function a(a){var r=Jp(a);r.eachAfter(b);r.parent.ic=-r.z;r.eachBefore(c);if(m)a.eachBefore(e);else{var w=a,q=a,u=a;a.eachBefore(function(a){a.x<w.x&&(w=a);a.x>q.x&&(q=a);a.depth>u.depth&&(u=a)});var r=w===q?1:g(w,q)/2,v=r-w.x,B=k/(q.x+r+v),E=n/(u.depth||1);a.eachBefore(function(a){a.x=(a.x+\nv)*B;a.y=a.depth*E})}return a}function b(a){var b=a.children,c=a.parent.children,e=a.uf?c[a.uf-1]:null;if(b){for(var k=0,n=0,r=a.children,m=r.length,w;0<=--m;)w=r[m],w.z+=k,w.ic+=k,k+=w.s+(n+=w.c);b=(b[0].z+b[b.length-1].z)/2;e?(a.z=e.z+g(a.Fa,e.Fa),a.ic=a.z-b):a.z=b}else e&&(a.z=e.z+g(a.Fa,e.Fa));b=a.parent;k=a;a=a.parent.gp||c[0];if(e){n=c=k;r=c.parent.children[0];m=c.ic;w=n.ic;for(var q=e.ic,u=r.ic,v;e=pg(e),c=og(c),e&&c;){r=og(r);n=pg(n);n.a=k;v=e.z+q-c.z-m+g(e.Fa,c.Fa);if(0<v){var B=e.a.parent===\nk.parent?e.a:a,E=k,F=v,y=F/(E.uf-B.uf);E.c-=y;E.s+=F;B.c+=y;E.z+=F;E.ic+=F;m+=v;w+=v}q+=e.ic;m+=c.ic;u+=r.ic;w+=n.ic}e&&!pg(n)&&(n.t=e,n.ic+=q-w);c&&!og(r)&&(r.t=c,r.ic+=m-u,a=k)}k=a;b.gp=k}function c(a){a.Fa.x=a.z+a.parent.ic;a.ic+=a.parent.ic}function e(a){a.x*=k;a.y=a.depth*n}var g=Ip,k=1,n=1,m=null;a.separation=function(b){return arguments.length?(g=b,a):g};a.size=function(b){return arguments.length?(m=!1,k=+b[0],n=+b[1],a):m?null:[k,n]};a.nodeSize=function(b){return arguments.length?(m=!0,k=\n+b[0],n=+b[1],a):m?[k,n]:null};return a},se=function(a,b,c,e,g){var k=a.children,n=-1,r=k.length;for(g=a.value&&(g-c)/a.value;++n<r;)a=k[n],a.x0=b,a.x1=e,a.y0=c,a.y1=c+=a.value*g},zl=(1+Math.sqrt(5))/2,Al=function y(a){function b(b,c,e,g,k){Gj(a,b,c,e,g,k)}b.ratio=function(a){return y(1<(a=+a)?a:1)};return b}(zl),Au=function(){function a(a){a.x0=a.y0=0;a.x1=g;a.y1=k;a.eachBefore(b);n=[0];e&&a.eachBefore(xl);return a}function b(a){var b=n[a.depth],e=a.x0+b,g=a.y0+b,k=a.x1-b,r=a.y1-b;k<e&&(e=k=(e+k)/\n2);r<g&&(g=r=(g+r)/2);a.x0=e;a.y0=g;a.x1=k;a.y1=r;a.children&&(b=n[a.depth+1]=m(a)/2,e+=E(a)-b,g+=q(a)-b,k-=v(a)-b,r-=B(a)-b,k<e&&(e=k=(e+k)/2),r<g&&(g=r=(g+r)/2),c(a,e,g,k,r))}var c=Al,e=!1,g=1,k=1,n=[0],m=Rb,q=Rb,v=Rb,B=Rb,E=Rb;a.round=function(b){return arguments.length?(e=!!b,a):e};a.size=function(b){return arguments.length?(g=+b[0],k=+b[1],a):[g,k]};a.tile=function(b){return arguments.length?(c=qe(b),a):c};a.padding=function(b){return arguments.length?a.paddingInner(b).paddingOuter(b):a.paddingInner()};\na.paddingInner=function(b){return arguments.length?(m=\"function\"===typeof b?b:Ac(+b),a):m};a.paddingOuter=function(b){return arguments.length?a.paddingTop(b).paddingRight(b).paddingBottom(b).paddingLeft(b):a.paddingTop()};a.paddingTop=function(b){return arguments.length?(q=\"function\"===typeof b?b:Ac(+b),a):q};a.paddingRight=function(b){return arguments.length?(v=\"function\"===typeof b?b:Ac(+b),a):v};a.paddingBottom=function(b){return arguments.length?(B=\"function\"===typeof b?b:Ac(+b),a):B};a.paddingLeft=\nfunction(b){return arguments.length?(E=\"function\"===typeof b?b:Ac(+b),a):E};return a},Bu=function(a,b,c,e,g){function k(a,b,c,e,g,r,m){if(a>=b-1)a=n[a],a.x0=e,a.y0=g,a.x1=r,a.y1=m;else{for(var q=w[a],A=c/2+q,v=a+1,B=b-1;v<B;){var E=v+B>>>1;w[E]<A?v=E+1:B=E}q=w[v]-q;A=c-q;m-g>r-e?(c=(g*A+m*q)/c,k(a,v,q,e,g,r,c),k(v,b,A,e,c,r,m)):(c=(e*A+r*q)/c,k(a,v,q,e,g,c,m),k(v,b,A,c,g,r,m))}}var n=a.children,r,m=n.length,q,w=Array(m+1);for(w[0]=q=r=0;r<m;++r)w[r+1]=q+=n[r].value;k(0,m,a.value,b,c,e,g)},Cu=function(a,\nb,c,e,g){(a.depth&1?se:bd)(a,b,c,e,g)},Du=function r(a){function b(b,c,e,g,k){if((n=b.XG)&&n.ratio===a)for(var n,r,m,q=-1,w,A=n.length,v=b.value;++q<A;){b=n[q];r=b.children;m=b.value=0;for(w=r.length;m<w;++m)b.value+=r[m].value;b.wx?bd(b,c,e,g,e+=(k-e)*b.value/v):se(b,c,e,c+=(g-c)*b.value/v,k);v-=b.value}else b.XG=n=Gj(a,b,c,e,g,k),n.ratio=a}b.ratio=function(a){return r(1<(a=+a)?a:1)};return b}(zl),Eu=function(a){for(var b=-1,c=a.length,e,g=a[c-1],k=0;++b<c;)e=g,g=a[b],k+=e[1]*g[0]-e[0]*g[1];return k/\n2},Fu=function(a){for(var b=-1,c=a.length,e=0,g=0,k,n=a[c-1],r,m=0;++b<c;)k=n,n=a[b],m+=r=k[0]*n[1]-n[0]*k[1],e+=(k[0]+n[0])*r,g+=(k[1]+n[1])*r;return m*=3,[e/m,g/m]},Lp=function(a,b,c){return(b[0]-a[0])*(c[1]-a[1])-(b[1]-a[1])*(c[0]-a[0])},Gu=function(a){if(3>(c=a.length))return null;var b,c,e=Array(c),g=Array(c);for(b=0;b<c;++b)e[b]=[+a[b][0],+a[b][1],b];e.sort(Kp);for(b=0;b<c;++b)g[b]=[e[b][0],-e[b][1]];c=Hj(e);var g=Hj(g),k=g[0]===c[0],n=g[g.length-1]===c[c.length-1],r=[];for(b=c.length-1;0<=\nb;--b)r.push(a[e[c[b]][2]]);for(b=+k;b<g.length-n;++b)r.push(a[e[g[b]][2]]);return r},Hu=function(a,b){var c=a.length,e=a[c-1],g=b[0];b=b[1];for(var k=e[0],n=e[1],r,m=!1,q=0;q<c;++q)e=a[q],r=e[0],e=e[1],e>b!==n>b&&g<(k-r)*(b-e)/(n-e)+r&&(m=!m),k=r,n=e;return m},Iu=function(a){for(var b=-1,c=a.length,e=a[c-1],g,k,n=e[0],e=e[1],r=0;++b<c;)g=n,k=e,e=a[b],n=e[0],e=e[1],g-=n,k-=e,r+=Math.sqrt(g*g+k*k);return r},Ju=[].slice,Np={};qg.prototype=Jj.prototype={constructor:qg,defer:function(a){if(\"function\"!==\ntypeof a||this.$f)throw Error();if(null!=this._error)return this;var b=Ju.call(arguments,1);b.push(a);++this.ol;this.Wg.push(b);Ij(this);return this},abort:function(){null==this._error&&rg(this,Error(\"abort\"));return this},await:function(a){if(\"function\"!==typeof a||this.$f)throw Error();this.$f=function(b,c){a.apply(null,[b].concat(c))};te(this);return this},awaitAll:function(a){if(\"function\"!==typeof a||this.$f)throw Error();this.$f=a;te(this);return this}};var Ku=function(a,b){a=null==a?0:+a;b=\nnull==b?1:+b;1===arguments.length?(b=a,a=0):b-=a;return function(){return Math.random()*b+a}},Bl=function(a,b){var c,e;a=null==a?0:+a;b=null==b?1:+b;return function(){var g;if(null!=c)g=c,c=null;else{do c=2*Math.random()-1,g=2*Math.random()-1,e=c*c+g*g;while(!e||1<e)}return a+b*g*Math.sqrt(-2*Math.log(e)/e)}},Lu=function(){var a=Bl.apply(this,arguments);return function(){return Math.exp(a())}},Cl=function(a){return function(){for(var b=0,c=0;c<a;++c)b+=Math.random();return b}},Mu=function(a){var b=\nCl(a);return function(){return b()/a}},Nu=function(a){return function(){return-Math.log(1-Math.random())/a}},kh=function(a,b){function c(a){var b=m.status,c,k;if(k=!b)k=(k=m.responseType)&&\"text\"!==k?m.response:m.responseText;if(k||200<=b&&300>b||304===b){if(w)try{c=w.call(e,m)}catch(mo){g.call(\"error\",e,mo);return}else c=m;g.call(\"load\",e,c)}else g.call(\"error\",e,a)}var e,g=E(\"beforesend\",\"progress\",\"load\",\"error\"),k,n=fb(),m=new XMLHttpRequest,r=null,q=null,w,v,B=0;\"undefined\"===typeof XDomainRequest||\n\"withCredentials\"in m||!/^(http(s)?:)?\\/\\//.test(a)||(m=new XDomainRequest);\"onload\"in m?m.onload=m.onerror=m.ontimeout=c:m.onreadystatechange=function(a){3<m.readyState&&c(a)};m.onprogress=function(a){g.call(\"progress\",e,a)};e={header:function(a,b){a=(a+\"\").toLowerCase();if(2>arguments.length)return n.get(a);null==b?n.remove(a):n.set(a,b+\"\");return e},mimeType:function(a){if(!arguments.length)return k;k=null==a?null:a+\"\";return e},responseType:function(a){if(!arguments.length)return v;v=a;return e},\ntimeout:function(a){if(!arguments.length)return B;B=+a;return e},user:function(a){return 1>arguments.length?r:(r=null==a?null:a+\"\",e)},password:function(a){return 1>arguments.length?q:(q=null==a?null:a+\"\",e)},response:function(a){w=a;return e},get:function(a,b){return e.send(\"GET\",a,b)},post:function(a,b){return e.send(\"POST\",a,b)},send:function(b,c,w){m.open(b,a,!0,r,q);null==k||n.has(\"accept\")||n.set(\"accept\",k+\",*/*\");m.setRequestHeader&&n.each(function(a,b){m.setRequestHeader(b,a)});null!=k&&\nm.overrideMimeType&&m.overrideMimeType(k);null!=v&&(m.responseType=v);0<B&&(m.timeout=B);null==w&&\"function\"===typeof c&&(w=c,c=null);null!=w&&1===w.length&&(w=Op(w));if(null!=w)e.on(\"error\",w).on(\"load\",function(a){w(null,a)});g.call(\"beforesend\",e,m);m.send(null==c?null:c);return e},abort:function(){m.abort();return e},on:function(){var a=g.on.apply(g,arguments);return a===g?e:a}};if(null!=b){if(\"function\"!==typeof b)throw Error(\"invalid callback: \"+b);return e.get(b)}return e},Ye=function(a,b){return function(c,\ne){c=kh(c).mimeType(a).response(b);if(null!=e){if(\"function\"!==typeof e)throw Error(\"invalid callback: \"+e);return c.get(e)}return c}},Ou=Ye(\"text/html\",function(a){return document.createRange().createContextualFragment(a.responseText)}),Pu=Ye(\"application/json\",function(a){return JSON.parse(a.responseText)}),Qu=Ye(\"text/plain\",function(a){return a.responseText}),Ru=Ye(\"application/xml\",function(a){a=a.responseXML;if(!a)throw Error(\"parse error\");return a}),Dl=function(a,b){return function(c,e,g){3>\narguments.length&&(g=e,e=null);var k=kh(c).mimeType(a);k.row=function(a){return arguments.length?k.response(Pp(b,e=a)):e};k.row(e);return g?k.get(g):k}},Su=Dl(\"text/csv\",nl),Tu=Dl(\"text/tab-separated-values\",ol),El=Array.prototype,xg=El.map,yb=El.slice,tg={name:\"implicit\"},wg=function(a){return function(){return a}},Mj=function(a){return+a},Lj=[0,1],Xj=function(a,b){a=a.slice();var c=0,e=a.length-1,g=a[c],k=a[e],n;k<g&&(n=c,c=e,e=n,n=g,g=k,k=n);a[c]=b.floor(g);a[e]=b.ceil(k);return a},zg=new Date,\nAg=new Date,Yb=xa(function(){},function(a,b){a.setTime(+a+b)},function(a,b){return b-a});Yb.every=function(a){a=Math.floor(a);return isFinite(a)&&0<a?1<a?xa(function(b){b.setTime(Math.floor(b/a)*a)},function(b,c){b.setTime(+b+c*a)},function(b,c){return(c-b)/a}):Yb:null};var Fl=Yb.range,sd=xa(function(a){a.setTime(1E3*Math.floor(a/1E3))},function(a,b){a.setTime(+a+1E3*b)},function(a,b){return(b-a)/1E3},function(a){return a.getUTCSeconds()}),Gl=sd.range,lh=xa(function(a){a.setTime(6E4*Math.floor(a/\n6E4))},function(a,b){a.setTime(+a+6E4*b)},function(a,b){return(b-a)/6E4},function(a){return a.getMinutes()}),Uu=lh.range,mh=xa(function(a){var b=6E4*a.getTimezoneOffset()%36E5;0>b&&(b+=36E5);a.setTime(36E5*Math.floor((+a-b)/36E5)+b)},function(a,b){a.setTime(+a+36E5*b)},function(a,b){return(b-a)/36E5},function(a){return a.getHours()}),Vu=mh.range,ye=xa(function(a){a.setHours(0,0,0,0)},function(a,b){a.setDate(a.getDate()+b)},function(a,b){return(b-a-6E4*(b.getTimezoneOffset()-a.getTimezoneOffset()))/\n864E5},function(a){return a.getDate()-1}),Wu=ye.range,gd=Tb(0),Dg=Tb(1),Hl=Tb(2),Il=Tb(3),Jl=Tb(4),Kl=Tb(5),Ll=Tb(6),Ml=gd.range,Xu=Dg.range,Yu=Hl.range,Zu=Il.range,$u=Jl.range,av=Kl.range,bv=Ll.range,nh=xa(function(a){a.setDate(1);a.setHours(0,0,0,0)},function(a,b){a.setMonth(a.getMonth()+b)},function(a,b){return b.getMonth()-a.getMonth()+12*(b.getFullYear()-a.getFullYear())},function(a){return a.getMonth()}),cv=nh.range,Vb=xa(function(a){a.setMonth(0,1);a.setHours(0,0,0,0)},function(a,b){a.setFullYear(a.getFullYear()+\nb)},function(a,b){return b.getFullYear()-a.getFullYear()},function(a){return a.getFullYear()});Vb.every=function(a){return isFinite(a=Math.floor(a))&&0<a?xa(function(b){b.setFullYear(Math.floor(b.getFullYear()/a)*a);b.setMonth(0,1);b.setHours(0,0,0,0)},function(b,c){b.setFullYear(b.getFullYear()+c*a)}):null};var dv=Vb.range,oh=xa(function(a){a.setUTCSeconds(0,0)},function(a,b){a.setTime(+a+6E4*b)},function(a,b){return(b-a)/6E4},function(a){return a.getUTCMinutes()}),ev=oh.range,ph=xa(function(a){a.setUTCMinutes(0,\n0,0)},function(a,b){a.setTime(+a+36E5*b)},function(a,b){return(b-a)/36E5},function(a){return a.getUTCHours()}),fv=ph.range,ze=xa(function(a){a.setUTCHours(0,0,0,0)},function(a,b){a.setUTCDate(a.getUTCDate()+b)},function(a,b){return(b-a)/864E5},function(a){return a.getUTCDate()-1}),gv=ze.range,hd=Ub(0),Eg=Ub(1),Nl=Ub(2),Ol=Ub(3),Pl=Ub(4),Ql=Ub(5),Rl=Ub(6),Sl=hd.range,hv=Eg.range,iv=Nl.range,jv=Ol.range,kv=Pl.range,lv=Ql.range,mv=Rl.range,qh=xa(function(a){a.setUTCDate(1);a.setUTCHours(0,0,0,0)},function(a,\nb){a.setUTCMonth(a.getUTCMonth()+b)},function(a,b){return b.getUTCMonth()-a.getUTCMonth()+12*(b.getUTCFullYear()-a.getUTCFullYear())},function(a){return a.getUTCMonth()}),nv=qh.range,Wb=xa(function(a){a.setUTCMonth(0,1);a.setUTCHours(0,0,0,0)},function(a,b){a.setUTCFullYear(a.getUTCFullYear()+b)},function(a,b){return b.getUTCFullYear()-a.getUTCFullYear()},function(a){return a.getUTCFullYear()});Wb.every=function(a){return isFinite(a=Math.floor(a))&&0<a?xa(function(b){b.setUTCFullYear(Math.floor(b.getUTCFullYear()/\na)*a);b.setUTCMonth(0,1);b.setUTCHours(0,0,0,0)},function(b,c){b.setUTCFullYear(b.getUTCFullYear()+c*a)}):null};var ov=Wb.range,ck={\"-\":\"\",_:\" \",0:\"0\"},Va=/^\\s*\\d+/,Nq=/^%/,Mq=/[\\\\\\^\\$\\*\\+\\?\\|\\[\\]\\(\\)\\.\\{\\}]/g,qc;ik({dateTime:\"%x, %X\",date:\"%-m/%-d/%Y\",time:\"%-I:%M:%S %p\",periods:[\"AM\",\"PM\"],days:\"Sunday Monday Tuesday Wednesday Thursday Friday Saturday\".split(\" \"),shortDays:\"Sun Mon Tue Wed Thu Fri Sat\".split(\" \"),months:\"January February March April May June July August September October November December\".split(\" \"),\nshortMonths:\"Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec\".split(\" \")});var pv=Date.prototype.toISOString?Oq:d3.utcFormat(\"%Y-%m-%dT%H:%M:%S.%LZ\"),qv=+new Date(\"2000-01-01T00:00:00.000Z\")?Pq:d3.utcParse(\"%Y-%m-%dT%H:%M:%S.%LZ\"),rv=function(){return Fg(Vb,nh,gd,ye,mh,lh,sd,Yb,d3.timeFormat).domain([new Date(2E3,0,1),new Date(2E3,0,2)])},sv=function(){return Fg(Wb,qh,hd,ze,ph,oh,sd,Yb,d3.utcFormat).domain([Date.UTC(2E3,0,1),Date.UTC(2E3,0,2)])},Bb=function(a){return a.match(/.{6}/g).map(function(a){return\"#\"+\na})},tv=Bb(\"1f77b4ff7f0e2ca02cd627289467bd8c564be377c27f7f7fbcbd2217becf\"),uv=Bb(\"393b795254a36b6ecf9c9ede6379398ca252b5cf6bcedb9c8c6d31bd9e39e7ba52e7cb94843c39ad494ad6616be7969c7b4173a55194ce6dbdde9ed6\"),vv=Bb(\"3182bd6baed69ecae1c6dbefe6550dfd8d3cfdae6bfdd0a231a35474c476a1d99bc7e9c0756bb19e9ac8bcbddcdadaeb636363969696bdbdbdd9d9d9\"),wv=Bb(\"1f77b4aec7e8ff7f0effbb782ca02c98df8ad62728ff98969467bdc5b0d58c564bc49c94e377c2f7b6d27f7f7fc7c7c7bcbd22dbdb8d17becf9edae5\"),xv=Oe(Za(300,.5,0),Za(-240,.5,1)),yv=\nOe(Za(-100,.75,.35),Za(80,1.5,.8)),zv=Oe(Za(260,.75,.35),Za(80,1.5,.8)),Ze=Za(),Av=function(a){if(0>a||1<a)a-=Math.floor(a);var b=Math.abs(a-.5);Ze.h=360*a-100;Ze.s=1.5-1.5*b;Ze.l=.8-.9*b;return Ze+\"\"},Bv=Ae(Bb(\"44015444025645045745055946075a46085c460a5d460b5e470d60470e6147106347116447136548146748166848176948186a481a6c481b6d481c6e481d6f481f70482071482173482374482475482576482677482878482979472a7a472c7a472d7b472e7c472f7d46307e46327e46337f463480453581453781453882443983443a83443b84433d84433e85423f854240864241864142874144874045884046883f47883f48893e49893e4a893e4c8a3d4d8a3d4e8a3c4f8a3c508b3b518b3b528b3a538b3a548c39558c39568c38588c38598c375a8c375b8d365c8d365d8d355e8d355f8d34608d34618d33628d33638d32648e32658e31668e31678e31688e30698e306a8e2f6b8e2f6c8e2e6d8e2e6e8e2e6f8e2d708e2d718e2c718e2c728e2c738e2b748e2b758e2a768e2a778e2a788e29798e297a8e297b8e287c8e287d8e277e8e277f8e27808e26818e26828e26828e25838e25848e25858e24868e24878e23888e23898e238a8d228b8d228c8d228d8d218e8d218f8d21908d21918c20928c20928c20938c1f948c1f958b1f968b1f978b1f988b1f998a1f9a8a1e9b8a1e9c891e9d891f9e891f9f881fa0881fa1881fa1871fa28720a38620a48621a58521a68522a78522a88423a98324aa8325ab8225ac8226ad8127ad8128ae8029af7f2ab07f2cb17e2db27d2eb37c2fb47c31b57b32b67a34b67935b77937b87838b9773aba763bbb753dbc743fbc7340bd7242be7144bf7046c06f48c16e4ac16d4cc26c4ec36b50c46a52c56954c56856c66758c7655ac8645cc8635ec96260ca6063cb5f65cb5e67cc5c69cd5b6ccd5a6ece5870cf5773d05675d05477d1537ad1517cd2507fd34e81d34d84d44b86d54989d5488bd6468ed64590d74393d74195d84098d83e9bd93c9dd93ba0da39a2da37a5db36a8db34aadc32addc30b0dd2fb2dd2db5de2bb8de29bade28bddf26c0df25c2df23c5e021c8e020cae11fcde11dd0e11cd2e21bd5e21ad8e219dae319dde318dfe318e2e418e5e419e7e419eae51aece51befe51cf1e51df4e61ef6e620f8e621fbe723fde725\")),\nCv=Ae(Bb(\"00000401000501010601010802010902020b02020d03030f03031204041405041606051806051a07061c08071e0907200a08220b09240c09260d0a290e0b2b100b2d110c2f120d31130d34140e36150e38160f3b180f3d19103f1a10421c10441d11471e114920114b21114e22115024125325125527125829115a2a115c2c115f2d11612f116331116533106734106936106b38106c390f6e3b0f703d0f713f0f72400f74420f75440f764510774710784910784a10794c117a4e117b4f127b51127c52137c54137d56147d57157e59157e5a167e5c167f5d177f5f187f601880621980641a80651a80671b80681c816a1c816b1d816d1d816e1e81701f81721f817320817521817621817822817922827b23827c23827e24828025828125818326818426818627818827818928818b29818c29818e2a81902a81912b81932b80942c80962c80982d80992d809b2e7f9c2e7f9e2f7fa02f7fa1307ea3307ea5317ea6317da8327daa337dab337cad347cae347bb0357bb2357bb3367ab5367ab73779b83779ba3878bc3978bd3977bf3a77c03a76c23b75c43c75c53c74c73d73c83e73ca3e72cc3f71cd4071cf4070d0416fd2426fd3436ed5446dd6456cd8456cd9466bdb476adc4869de4968df4a68e04c67e24d66e34e65e44f64e55064e75263e85362e95462ea5661eb5760ec5860ed5a5fee5b5eef5d5ef05f5ef1605df2625df2645cf3655cf4675cf4695cf56b5cf66c5cf66e5cf7705cf7725cf8745cf8765cf9785df9795df97b5dfa7d5efa7f5efa815ffb835ffb8560fb8761fc8961fc8a62fc8c63fc8e64fc9065fd9266fd9467fd9668fd9869fd9a6afd9b6bfe9d6cfe9f6dfea16efea36ffea571fea772fea973feaa74feac76feae77feb078feb27afeb47bfeb67cfeb77efeb97ffebb81febd82febf84fec185fec287fec488fec68afec88cfeca8dfecc8ffecd90fecf92fed194fed395fed597fed799fed89afdda9cfddc9efddea0fde0a1fde2a3fde3a5fde5a7fde7a9fde9aafdebacfcecaefceeb0fcf0b2fcf2b4fcf4b6fcf6b8fcf7b9fcf9bbfcfbbdfcfdbf\")),\nDv=Ae(Bb(\"00000401000501010601010802010a02020c02020e03021004031204031405041706041907051b08051d09061f0a07220b07240c08260d08290e092b10092d110a30120a32140b34150b37160b39180c3c190c3e1b0c411c0c431e0c451f0c48210c4a230c4c240c4f260c51280b53290b552b0b572d0b592f0a5b310a5c320a5e340a5f3609613809623909633b09643d09653e0966400a67420a68440a68450a69470b6a490b6a4a0c6b4c0c6b4d0d6c4f0d6c510e6c520e6d540f6d550f6d57106e59106e5a116e5c126e5d126e5f136e61136e62146e64156e65156e67166e69166e6a176e6c186e6d186e6f196e71196e721a6e741a6e751b6e771c6d781c6d7a1d6d7c1d6d7d1e6d7f1e6c801f6c82206c84206b85216b87216b88226a8a226a8c23698d23698f24699025689225689326679526679727669827669a28659b29649d29649f2a63a02a63a22b62a32c61a52c60a62d60a82e5fa92e5eab2f5ead305dae305cb0315bb1325ab3325ab43359b63458b73557b93556ba3655bc3754bd3853bf3952c03a51c13a50c33b4fc43c4ec63d4dc73e4cc83f4bca404acb4149cc4248ce4347cf4446d04545d24644d34743d44842d54a41d74b3fd84c3ed94d3dda4e3cdb503bdd513ade5238df5337e05536e15635e25734e35933e45a31e55c30e65d2fe75e2ee8602de9612bea632aeb6429eb6628ec6726ed6925ee6a24ef6c23ef6e21f06f20f1711ff1731df2741cf3761bf37819f47918f57b17f57d15f67e14f68013f78212f78410f8850ff8870ef8890cf98b0bf98c0af98e09fa9008fa9207fa9407fb9606fb9706fb9906fb9b06fb9d07fc9f07fca108fca309fca50afca60cfca80dfcaa0ffcac11fcae12fcb014fcb216fcb418fbb61afbb81dfbba1ffbbc21fbbe23fac026fac228fac42afac62df9c72ff9c932f9cb35f8cd37f8cf3af7d13df7d340f6d543f6d746f5d949f5db4cf4dd4ff4df53f4e156f3e35af3e55df2e661f2e865f2ea69f1ec6df1ed71f1ef75f1f179f2f27df2f482f3f586f3f68af4f88ef5f992f6fa96f8fb9af9fc9dfafda1fcffa4\")),\nEv=Ae(Bb(\"0d088710078813078916078a19068c1b068d1d068e20068f2206902406912605912805922a05932c05942e05952f059631059733059735049837049938049a3a049a3c049b3e049c3f049c41049d43039e44039e46039f48039f4903a04b03a14c02a14e02a25002a25102a35302a35502a45601a45801a45901a55b01a55c01a65e01a66001a66100a76300a76400a76600a76700a86900a86a00a86c00a86e00a86f00a87100a87201a87401a87501a87701a87801a87a02a87b02a87d03a87e03a88004a88104a78305a78405a78606a68707a68808a68a09a58b0aa58d0ba58e0ca48f0da4910ea3920fa39410a29511a19613a19814a099159f9a169f9c179e9d189d9e199da01a9ca11b9ba21d9aa31e9aa51f99a62098a72197a82296aa2395ab2494ac2694ad2793ae2892b02991b12a90b22b8fb32c8eb42e8db52f8cb6308bb7318ab83289ba3388bb3488bc3587bd3786be3885bf3984c03a83c13b82c23c81c33d80c43e7fc5407ec6417dc7427cc8437bc9447aca457acb4679cc4778cc4977cd4a76ce4b75cf4c74d04d73d14e72d24f71d35171d45270d5536fd5546ed6556dd7566cd8576bd9586ada5a6ada5b69db5c68dc5d67dd5e66de5f65de6164df6263e06363e16462e26561e26660e3685fe4695ee56a5de56b5de66c5ce76e5be76f5ae87059e97158e97257ea7457eb7556eb7655ec7754ed7953ed7a52ee7b51ef7c51ef7e50f07f4ff0804ef1814df1834cf2844bf3854bf3874af48849f48948f58b47f58c46f68d45f68f44f79044f79143f79342f89441f89540f9973ff9983ef99a3efa9b3dfa9c3cfa9e3bfb9f3afba139fba238fca338fca537fca636fca835fca934fdab33fdac33fdae32fdaf31fdb130fdb22ffdb42ffdb52efeb72dfeb82cfeba2cfebb2bfebd2afebe2afec029fdc229fdc328fdc527fdc627fdc827fdca26fdcb26fccd25fcce25fcd025fcd225fbd324fbd524fbd724fad824fada24f9dc24f9dd25f8df25f8e125f7e225f7e425f6e626f6e826f5e926f5eb27f4ed27f3ee27f3f027f2f227f1f426f1f525f0f724f0f921\")),\nea=function(a){return function(){return a}},Zb=Math.PI,Be=Zb/2,Cb=2*Zb,Fv=function(){function a(){var a,r,A=+b.apply(this,arguments),v=+c.apply(this,arguments),w=k.apply(this,arguments)-Be,B=n.apply(this,arguments)-Be,E=Math.abs(B-w),J=B>w;q||(q=a=Mb());v<A&&(r=v,v=A,A=r);if(1E-12<v)if(E>Cb-1E-12)q.moveTo(v*Math.cos(w),v*Math.sin(w)),q.arc(0,0,v,w,B,!J),1E-12<A&&(q.moveTo(A*Math.cos(B),A*Math.sin(B)),q.arc(0,0,A,B,w,J));else{var C=w,L=B;r=w;var W=B,O=E,K=E,Q=m.apply(this,arguments)/2,U=1E-12<Q&&(g?\n+g.apply(this,arguments):Math.sqrt(A*A+v*v)),H=Math.min(Math.abs(v-A)/2,+e.apply(this,arguments)),F=H,aa=H;if(1E-12<U){var na=kk(U/A*Math.sin(Q)),Q=kk(U/v*Math.sin(Q));1E-12<(O-=2*na)?(na*=J?1:-1,r+=na,W-=na):(O=0,r=W=(w+B)/2);1E-12<(K-=2*Q)?(Q*=J?1:-1,C+=Q,L-=Q):(K=0,C=L=(w+B)/2)}w=v*Math.cos(C);B=v*Math.sin(C);na=A*Math.cos(W);Q=A*Math.sin(W);if(1E-12<H){var T=v*Math.cos(L),ka=v*Math.sin(L),ta=A*Math.cos(r),ca=A*Math.sin(r);if(E<Zb){1E-12<O?(F=ta-w,aa=ca-B,E=na-T,U=Q-ka,E=(E*(B-ka)-U*(w-T))/(U*\nF-E*aa),F=[w+E*F,B+E*aa]):F=[na,Q];var aa=w-F[0],E=B-F[1],U=T-F[0],ma=ka-F[1],aa=1/Math.sin(Math.acos((aa*U+E*ma)/(Math.sqrt(aa*aa+E*E)*Math.sqrt(U*U+ma*ma)))/2),E=Math.sqrt(F[0]*F[0]+F[1]*F[1]),F=Math.min(H,(A-E)/(aa-1)),aa=Math.min(H,(v-E)/(aa+1))}}1E-12<K?1E-12<aa?(C=Ce(ta,ca,w,B,v,aa,J),L=Ce(T,ka,na,Q,v,aa,J),q.moveTo(C.cx+C.bh,C.cy+C.dh),aa<H?q.arc(C.cx,C.cy,aa,Math.atan2(C.dh,C.bh),Math.atan2(L.dh,L.bh),!J):(q.arc(C.cx,C.cy,aa,Math.atan2(C.dh,C.bh),Math.atan2(C.yi,C.wi),!J),q.arc(0,0,v,Math.atan2(C.cy+\nC.yi,C.cx+C.wi),Math.atan2(L.cy+L.yi,L.cx+L.wi),!J),q.arc(L.cx,L.cy,aa,Math.atan2(L.yi,L.wi),Math.atan2(L.dh,L.bh),!J))):(q.moveTo(w,B),q.arc(0,0,v,C,L,!J)):q.moveTo(w,B);1E-12<A&&1E-12<O?1E-12<F?(C=Ce(na,Q,T,ka,A,-F,J),L=Ce(w,B,ta,ca,A,-F,J),q.lineTo(C.cx+C.bh,C.cy+C.dh),F<H?q.arc(C.cx,C.cy,F,Math.atan2(C.dh,C.bh),Math.atan2(L.dh,L.bh),!J):(q.arc(C.cx,C.cy,F,Math.atan2(C.dh,C.bh),Math.atan2(C.yi,C.wi),!J),q.arc(0,0,A,Math.atan2(C.cy+C.yi,C.cx+C.wi),Math.atan2(L.cy+L.yi,L.cx+L.wi),J),q.arc(L.cx,L.cy,\nF,Math.atan2(L.yi,L.wi),Math.atan2(L.dh,L.bh),!J))):q.arc(0,0,A,W,r,J):q.lineTo(na,Q)}else q.moveTo(0,0);q.closePath();if(a)return q=null,a+\"\"||null}var b=Sq,c=Tq,e=ea(0),g=null,k=Uq,n=Vq,m=Wq,q=null;a.centroid=function(){var a=(+b.apply(this,arguments)+ +c.apply(this,arguments))/2,e=(+k.apply(this,arguments)+ +n.apply(this,arguments))/2-Zb/2;return[Math.cos(e)*a,Math.sin(e)*a]};a.innerRadius=function(c){return arguments.length?(b=\"function\"===typeof c?c:ea(+c),a):b};a.outerRadius=function(b){return arguments.length?\n(c=\"function\"===typeof b?b:ea(+b),a):c};a.cornerRadius=function(b){return arguments.length?(e=\"function\"===typeof b?b:ea(+b),a):e};a.padRadius=function(b){return arguments.length?(g=null==b?null:\"function\"===typeof b?b:ea(+b),a):g};a.startAngle=function(b){return arguments.length?(k=\"function\"===typeof b?b:ea(+b),a):k};a.endAngle=function(b){return arguments.length?(n=\"function\"===typeof b?b:ea(+b),a):n};a.padAngle=function(b){return arguments.length?(m=\"function\"===typeof b?b:ea(+b),a):m};a.context=\nfunction(b){return arguments.length?(q=null==b?null:b,a):q};return a};lk.prototype={areaStart:function(){this.Ta=0},areaEnd:function(){this.Ta=NaN},lineStart:function(){this.Ha=0},lineEnd:function(){(this.Ta||0!==this.Ta&&1===this.Ha)&&this.Ia.closePath();this.Ta=1-this.Ta},point:function(a,b){a=+a;b=+b;switch(this.Ha){case 0:this.Ha=1;this.Ta?this.Ia.lineTo(a,b):this.Ia.moveTo(a,b);break;case 1:this.Ha=2;default:this.Ia.lineTo(a,b)}}};var $e=function(a){return new lk(a)},rh=function(){function a(a){var m,\nr=a.length,q,A=!1,v;null==g&&(n=k(v=Mb()));for(m=0;m<=r;++m)!(m<r&&e(q=a[m],m,a))===A&&((A=!A)?n.lineStart():n.lineEnd()),A&&n.point(+b(q,m,a),+c(q,m,a));if(v)return n=null,v+\"\"||null}var b=mk,c=nk,e=ea(!0),g=null,k=$e,n=null;a.x=function(c){return arguments.length?(b=\"function\"===typeof c?c:ea(+c),a):b};a.y=function(b){return arguments.length?(c=\"function\"===typeof b?b:ea(+b),a):c};a.defined=function(b){return arguments.length?(e=\"function\"===typeof b?b:ea(!!b),a):e};a.curve=function(b){return arguments.length?\n(k=b,null!=g&&(n=k(g)),a):k};a.context=function(b){return arguments.length?(null==b?g=n=null:n=k(g=b),a):g};return a},Tl=function(){function a(a){var b,r,A,w=a.length,B,E=!1,C,J=Array(w),L=Array(w);null==m&&(v=q(C=Mb()));for(b=0;b<=w;++b){if(!(b<w&&n(B=a[b],b,a))===E)if(E=!E)r=b,v.areaStart(),v.lineStart();else{v.lineEnd();v.lineStart();for(A=b-1;A>=r;--A)v.point(J[A],L[A]);v.lineEnd();v.areaEnd()}E&&(J[b]=+c(B,b,a),L[b]=+g(B,b,a),v.point(e?+e(B,b,a):J[b],k?+k(B,b,a):L[b]))}if(C)return v=null,C+\"\"||\nnull}function b(){return rh().defined(n).curve(q).context(m)}var c=mk,e=null,g=ea(0),k=nk,n=ea(!0),m=null,q=$e,v=null;a.x=function(b){return arguments.length?(c=\"function\"===typeof b?b:ea(+b),e=null,a):c};a.x0=function(b){return arguments.length?(c=\"function\"===typeof b?b:ea(+b),a):c};a.x1=function(b){return arguments.length?(e=null==b?null:\"function\"===typeof b?b:ea(+b),a):e};a.y=function(b){return arguments.length?(g=\"function\"===typeof b?b:ea(+b),k=null,a):g};a.y0=function(b){return arguments.length?\n(g=\"function\"===typeof b?b:ea(+b),a):g};a.y1=function(b){return arguments.length?(k=null==b?null:\"function\"===typeof b?b:ea(+b),a):k};a.lineX0=a.lineY0=function(){return b().x(c).y(g)};a.lineY1=function(){return b().x(c).y(k)};a.lineX1=function(){return b().x(e).y(g)};a.defined=function(b){return arguments.length?(n=\"function\"===typeof b?b:ea(!!b),a):n};a.curve=function(b){return arguments.length?(q=b,null!=m&&(v=q(m)),a):q};a.context=function(b){return arguments.length?(null==b?m=v=null:v=q(m=b),\na):m};return a},Gv=function(a,b){return b<a?-1:b>a?1:b>=a?0:NaN},Hv=function(a){return a},Iv=function(){function a(a){var m,q=a.length,r,A;r=0;var v=Array(q),w=Array(q),B=+g.apply(this,arguments);A=Math.min(Cb,Math.max(-Cb,k.apply(this,arguments)-B));var E,C=Math.min(Math.abs(A)/q,n.apply(this,arguments)),J=C*(0>A?-1:1),W;for(m=0;m<q;++m)0<(W=w[v[m]=m]=+b(a[m],m,a))&&(r+=W);null!=c?v.sort(function(a,b){return c(w[a],w[b])}):null!=e&&v.sort(function(b,c){return e(a[b],a[c])});m=0;for(A=r?(A-q*J)/r:\n0;m<q;++m,B=E)r=v[m],W=w[r],E=B+(0<W?W*A:0)+J,w[r]={data:a[r],index:m,value:W,startAngle:B,endAngle:E,padAngle:C};return w}var b=Hv,c=Gv,e=null,g=ea(0),k=ea(Cb),n=ea(0);a.value=function(c){return arguments.length?(b=\"function\"===typeof c?c:ea(+c),a):b};a.sortValues=function(b){return arguments.length?(c=b,e=null,a):c};a.sort=function(b){return arguments.length?(e=b,c=null,a):e};a.startAngle=function(b){return arguments.length?(g=\"function\"===typeof b?b:ea(+b),a):g};a.endAngle=function(b){return arguments.length?\n(k=\"function\"===typeof b?b:ea(+b),a):k};a.padAngle=function(b){return arguments.length?(n=\"function\"===typeof b?b:ea(+b),a):n};return a},Ul=Hg($e);ok.prototype={areaStart:function(){this.Uh.areaStart()},areaEnd:function(){this.Uh.areaEnd()},lineStart:function(){this.Uh.lineStart()},lineEnd:function(){this.Uh.lineEnd()},point:function(a,b){this.Uh.point(b*Math.sin(a),b*-Math.cos(a))}};var Jv=function(){return id(rh().curve(Ul))},Kv=function(){var a=Tl().curve(Ul),b=a.curve,c=a.lineX0,e=a.lineX1,g=\na.lineY0,k=a.lineY1;a.angle=a.x;delete a.x;a.startAngle=a.x0;delete a.x0;a.endAngle=a.x1;delete a.x1;a.radius=a.y;delete a.y;a.innerRadius=a.y0;delete a.y0;a.outerRadius=a.y1;delete a.y1;a.lineStartAngle=function(){return id(c())};delete a.lineX0;a.lineEndAngle=function(){return id(e())};delete a.lineX1;a.lineInnerRadius=function(){return id(g())};delete a.lineY0;a.lineOuterRadius=function(){return id(k())};delete a.lineY1;a.curve=function(a){return arguments.length?b(Hg(a)):b().Uh};return a},sh=\n{draw:function(a,b){b=Math.sqrt(b/Zb);a.moveTo(b,0);a.arc(0,0,b,0,Cb)}},Vl={draw:function(a,b){b=Math.sqrt(b/5)/2;a.moveTo(-3*b,-b);a.lineTo(-b,-b);a.lineTo(-b,-3*b);a.lineTo(b,-3*b);a.lineTo(b,-b);a.lineTo(3*b,-b);a.lineTo(3*b,b);a.lineTo(b,b);a.lineTo(b,3*b);a.lineTo(-b,3*b);a.lineTo(-b,b);a.lineTo(-3*b,b);a.closePath()}},Wl=Math.sqrt(1/3),Lv=2*Wl,Xl={draw:function(a,b){b=Math.sqrt(b/Lv);var c=b*Wl;a.moveTo(0,-b);a.lineTo(c,0);a.lineTo(0,b);a.lineTo(-c,0);a.closePath()}},Yl=Math.sin(Zb/10)/Math.sin(7*\nZb/10),Mv=Math.sin(Cb/10)*Yl,Nv=-Math.cos(Cb/10)*Yl,Zl={draw:function(a,b){b=Math.sqrt(.8908130915292852*b);var c=Mv*b,e=Nv*b;a.moveTo(0,-b);a.lineTo(c,e);for(var g=1;5>g;++g){var k=Cb*g/5,n=Math.cos(k),k=Math.sin(k);a.lineTo(k*b,-n*b);a.lineTo(n*c-k*e,k*c+n*e)}a.closePath()}},$l={draw:function(a,b){b=Math.sqrt(b);var c=-b/2;a.rect(c,c,b,b)}},th=Math.sqrt(3),am={draw:function(a,b){b=-Math.sqrt(b/(3*th));a.moveTo(0,2*b);a.lineTo(-th*b,-b);a.lineTo(th*b,-b);a.closePath()}},Wa=Math.sqrt(3)/2,uh=1/Math.sqrt(12),\nOv=3*(uh/2+1),bm={draw:function(a,b){var c=Math.sqrt(b/Ov);b=c/2;var e=c*uh,g=b,c=c*uh+c,k=-g,n=c;a.moveTo(b,e);a.lineTo(g,c);a.lineTo(k,n);a.lineTo(-.5*b-Wa*e,Wa*b+-.5*e);a.lineTo(-.5*g-Wa*c,Wa*g+-.5*c);a.lineTo(-.5*k-Wa*n,Wa*k+-.5*n);a.lineTo(-.5*b+Wa*e,-.5*e-Wa*b);a.lineTo(-.5*g+Wa*c,-.5*c-Wa*g);a.lineTo(-.5*k+Wa*n,-.5*n-Wa*k);a.closePath()}},Pv=[sh,Vl,Xl,$l,Zl,am,bm],Qv=function(){function a(){var a;e||(e=a=Mb());b.apply(this,arguments).draw(e,+c.apply(this,arguments));if(a)return e=null,a+\"\"||\nnull}var b=ea(sh),c=ea(64),e=null;a.type=function(c){return arguments.length?(b=\"function\"===typeof c?c:ea(c),a):b};a.size=function(b){return arguments.length?(c=\"function\"===typeof b?b:ea(+b),a):c};a.context=function(b){return arguments.length?(e=null==b?null:b,a):e};return a},Db=function(){};Ee.prototype={areaStart:function(){this.Ta=0},areaEnd:function(){this.Ta=NaN},lineStart:function(){this.ub=this.Sa=this.xb=this.Va=NaN;this.Ha=0},lineEnd:function(){switch(this.Ha){case 3:De(this,this.Sa,this.Va);\ncase 2:this.Ia.lineTo(this.Sa,this.Va)}(this.Ta||0!==this.Ta&&1===this.Ha)&&this.Ia.closePath();this.Ta=1-this.Ta},point:function(a,b){a=+a;b=+b;switch(this.Ha){case 0:this.Ha=1;this.Ta?this.Ia.lineTo(a,b):this.Ia.moveTo(a,b);break;case 1:this.Ha=2;break;case 2:this.Ha=3,this.Ia.lineTo((5*this.ub+this.Sa)/6,(5*this.xb+this.Va)/6);default:De(this,a,b)}this.ub=this.Sa;this.Sa=a;this.xb=this.Va;this.Va=b}};var Rv=function(a){return new Ee(a)};pk.prototype={areaStart:Db,areaEnd:Db,lineStart:function(){this.ub=\nthis.Sa=this.Mb=this.Lf=this.ai=this.xb=this.Va=this.Nb=this.Mf=this.bi=NaN;this.Ha=0},lineEnd:function(){switch(this.Ha){case 1:this.Ia.moveTo(this.Mb,this.Nb);this.Ia.closePath();break;case 2:this.Ia.moveTo((this.Mb+2*this.Lf)/3,(this.Nb+2*this.Mf)/3);this.Ia.lineTo((this.Lf+2*this.Mb)/3,(this.Mf+2*this.Nb)/3);this.Ia.closePath();break;case 3:this.point(this.Mb,this.Nb),this.point(this.Lf,this.Mf),this.point(this.ai,this.bi)}},point:function(a,b){a=+a;b=+b;switch(this.Ha){case 0:this.Ha=1;this.Mb=\na;this.Nb=b;break;case 1:this.Ha=2;this.Lf=a;this.Mf=b;break;case 2:this.Ha=3;this.ai=a;this.bi=b;this.Ia.moveTo((this.ub+4*this.Sa+a)/6,(this.xb+4*this.Va+b)/6);break;default:De(this,a,b)}this.ub=this.Sa;this.Sa=a;this.xb=this.Va;this.Va=b}};var Sv=function(a){return new pk(a)};qk.prototype={areaStart:function(){this.Ta=0},areaEnd:function(){this.Ta=NaN},lineStart:function(){this.ub=this.Sa=this.xb=this.Va=NaN;this.Ha=0},lineEnd:function(){(this.Ta||0!==this.Ta&&3===this.Ha)&&this.Ia.closePath();\nthis.Ta=1-this.Ta},point:function(a,b){a=+a;b=+b;switch(this.Ha){case 0:this.Ha=1;break;case 1:this.Ha=2;break;case 2:this.Ha=3;var c=(this.ub+4*this.Sa+a)/6,e=(this.xb+4*this.Va+b)/6;this.Ta?this.Ia.lineTo(c,e):this.Ia.moveTo(c,e);break;case 3:this.Ha=4;default:De(this,a,b)}this.ub=this.Sa;this.Sa=a;this.xb=this.Va;this.Va=b}};var Tv=function(a){return new qk(a)};rk.prototype={lineStart:function(){this.tc=[];this.ce=[];this.bq.lineStart()},lineEnd:function(){var a=this.tc,b=this.ce,c=a.length-1;\nif(0<c)for(var e=a[0],g=b[0],k=a[c]-e,n=b[c]-g,m=-1,q;++m<=c;)q=m/c,this.bq.point(this.sn*a[m]+(1-this.sn)*(e+q*k),this.sn*b[m]+(1-this.sn)*(g+q*n));this.tc=this.ce=null;this.bq.lineEnd()},point:function(a,b){this.tc.push(+a);this.ce.push(+b)}};var Uv=function w(a){function b(b){return 1===a?new Ee(b):new rk(b,a)}b.beta=function(a){return w(+a)};return b}(.85);Ig.prototype={areaStart:function(){this.Ta=0},areaEnd:function(){this.Ta=NaN},lineStart:function(){this.ub=this.Sa=this.Mb=this.xb=this.Va=\nthis.Nb=NaN;this.Ha=0},lineEnd:function(){switch(this.Ha){case 2:this.Ia.lineTo(this.Mb,this.Nb);break;case 3:Fe(this,this.Sa,this.Va)}(this.Ta||0!==this.Ta&&1===this.Ha)&&this.Ia.closePath();this.Ta=1-this.Ta},point:function(a,b){a=+a;b=+b;switch(this.Ha){case 0:this.Ha=1;this.Ta?this.Ia.lineTo(a,b):this.Ia.moveTo(a,b);break;case 1:this.Ha=2;this.Sa=a;this.Va=b;break;case 2:this.Ha=3;default:Fe(this,a,b)}this.ub=this.Sa;this.Sa=this.Mb;this.Mb=a;this.xb=this.Va;this.Va=this.Nb;this.Nb=b}};var Vv=\nfunction H(a){function b(b){return new Ig(b,a)}b.tension=function(a){return H(+a)};return b}(0);Jg.prototype={areaStart:Db,areaEnd:Db,lineStart:function(){this.ub=this.Sa=this.Mb=this.Lf=this.ai=this.pl=this.xb=this.Va=this.Nb=this.Mf=this.bi=this.ql=NaN;this.Ha=0},lineEnd:function(){switch(this.Ha){case 1:this.Ia.moveTo(this.Lf,this.Mf);this.Ia.closePath();break;case 2:this.Ia.lineTo(this.Lf,this.Mf);this.Ia.closePath();break;case 3:this.point(this.Lf,this.Mf),this.point(this.ai,this.bi),this.point(this.pl,\nthis.ql)}},point:function(a,b){a=+a;b=+b;switch(this.Ha){case 0:this.Ha=1;this.Lf=a;this.Mf=b;break;case 1:this.Ha=2;this.Ia.moveTo(this.ai=a,this.bi=b);break;case 2:this.Ha=3;this.pl=a;this.ql=b;break;default:Fe(this,a,b)}this.ub=this.Sa;this.Sa=this.Mb;this.Mb=a;this.xb=this.Va;this.Va=this.Nb;this.Nb=b}};var Wv=function F(a){function b(b){return new Jg(b,a)}b.tension=function(a){return F(+a)};return b}(0);Kg.prototype={areaStart:function(){this.Ta=0},areaEnd:function(){this.Ta=NaN},lineStart:function(){this.ub=\nthis.Sa=this.Mb=this.xb=this.Va=this.Nb=NaN;this.Ha=0},lineEnd:function(){(this.Ta||0!==this.Ta&&3===this.Ha)&&this.Ia.closePath();this.Ta=1-this.Ta},point:function(a,b){a=+a;b=+b;switch(this.Ha){case 0:this.Ha=1;break;case 1:this.Ha=2;break;case 2:this.Ha=3;this.Ta?this.Ia.lineTo(this.Mb,this.Nb):this.Ia.moveTo(this.Mb,this.Nb);break;case 3:this.Ha=4;default:Fe(this,a,b)}this.ub=this.Sa;this.Sa=this.Mb;this.Mb=a;this.xb=this.Va;this.Va=this.Nb;this.Nb=b}};var Xv=function ca(a){function b(b){return new Kg(b,\na)}b.tension=function(a){return ca(+a)};return b}(0);sk.prototype={areaStart:function(){this.Ta=0},areaEnd:function(){this.Ta=NaN},lineStart:function(){this.ub=this.Sa=this.Mb=this.xb=this.Va=this.Nb=NaN;this.sh=this.qg=this.rg=this.Wh=this.Hf=this.Cg=this.Ha=0},lineEnd:function(){switch(this.Ha){case 2:this.Ia.lineTo(this.Mb,this.Nb);break;case 3:this.point(this.Mb,this.Nb)}(this.Ta||0!==this.Ta&&1===this.Ha)&&this.Ia.closePath();this.Ta=1-this.Ta},point:function(a,b){a=+a;b=+b;if(this.Ha){var c=\nthis.Mb-a,e=this.Nb-b;this.rg=Math.sqrt(this.Cg=Math.pow(c*c+e*e,this.bl))}switch(this.Ha){case 0:this.Ha=1;this.Ta?this.Ia.lineTo(a,b):this.Ia.moveTo(a,b);break;case 1:this.Ha=2;break;case 2:this.Ha=3;default:Lg(this,a,b)}this.sh=this.qg;this.qg=this.rg;this.Wh=this.Hf;this.Hf=this.Cg;this.ub=this.Sa;this.Sa=this.Mb;this.Mb=a;this.xb=this.Va;this.Va=this.Nb;this.Nb=b}};var Yv=function qa(a){function b(b){return a?new sk(b,a):new Ig(b,0)}b.alpha=function(a){return qa(+a)};return b}(.5);tk.prototype=\n{areaStart:Db,areaEnd:Db,lineStart:function(){this.ub=this.Sa=this.Mb=this.Lf=this.ai=this.pl=this.xb=this.Va=this.Nb=this.Mf=this.bi=this.ql=NaN;this.sh=this.qg=this.rg=this.Wh=this.Hf=this.Cg=this.Ha=0},lineEnd:function(){switch(this.Ha){case 1:this.Ia.moveTo(this.Lf,this.Mf);this.Ia.closePath();break;case 2:this.Ia.lineTo(this.Lf,this.Mf);this.Ia.closePath();break;case 3:this.point(this.Lf,this.Mf),this.point(this.ai,this.bi),this.point(this.pl,this.ql)}},point:function(a,b){a=+a;b=+b;if(this.Ha){var c=\nthis.Mb-a,e=this.Nb-b;this.rg=Math.sqrt(this.Cg=Math.pow(c*c+e*e,this.bl))}switch(this.Ha){case 0:this.Ha=1;this.Lf=a;this.Mf=b;break;case 1:this.Ha=2;this.Ia.moveTo(this.ai=a,this.bi=b);break;case 2:this.Ha=3;this.pl=a;this.ql=b;break;default:Lg(this,a,b)}this.sh=this.qg;this.qg=this.rg;this.Wh=this.Hf;this.Hf=this.Cg;this.ub=this.Sa;this.Sa=this.Mb;this.Mb=a;this.xb=this.Va;this.Va=this.Nb;this.Nb=b}};var Zv=function T(a){function b(b){return a?new tk(b,a):new Jg(b,0)}b.alpha=function(a){return T(+a)};\nreturn b}(.5);uk.prototype={areaStart:function(){this.Ta=0},areaEnd:function(){this.Ta=NaN},lineStart:function(){this.ub=this.Sa=this.Mb=this.xb=this.Va=this.Nb=NaN;this.sh=this.qg=this.rg=this.Wh=this.Hf=this.Cg=this.Ha=0},lineEnd:function(){(this.Ta||0!==this.Ta&&3===this.Ha)&&this.Ia.closePath();this.Ta=1-this.Ta},point:function(a,b){a=+a;b=+b;if(this.Ha){var c=this.Mb-a,e=this.Nb-b;this.rg=Math.sqrt(this.Cg=Math.pow(c*c+e*e,this.bl))}switch(this.Ha){case 0:this.Ha=1;break;case 1:this.Ha=2;break;\ncase 2:this.Ha=3;this.Ta?this.Ia.lineTo(this.Mb,this.Nb):this.Ia.moveTo(this.Mb,this.Nb);break;case 3:this.Ha=4;default:Lg(this,a,b)}this.sh=this.qg;this.qg=this.rg;this.Wh=this.Hf;this.Hf=this.Cg;this.ub=this.Sa;this.Sa=this.Mb;this.Mb=a;this.xb=this.Va;this.Va=this.Nb;this.Nb=b}};var $v=function A(a){function b(b){return a?new uk(b,a):new Kg(b,0)}b.alpha=function(a){return A(+a)};return b}(.5);vk.prototype={areaStart:Db,areaEnd:Db,lineStart:function(){this.Ha=0},lineEnd:function(){this.Ha&&this.Ia.closePath()},\npoint:function(a,b){a=+a;b=+b;this.Ha?this.Ia.lineTo(a,b):(this.Ha=1,this.Ia.moveTo(a,b))}};var aw=function(a){return new vk(a)};Ge.prototype={areaStart:function(){this.Ta=0},areaEnd:function(){this.Ta=NaN},lineStart:function(){this.ub=this.Sa=this.xb=this.Va=this.Pn=NaN;this.Ha=0},lineEnd:function(){switch(this.Ha){case 2:this.Ia.lineTo(this.Sa,this.Va);break;case 3:Mg(this,this.Pn,xk(this,this.Pn))}(this.Ta||0!==this.Ta&&1===this.Ha)&&this.Ia.closePath();this.Ta=1-this.Ta},point:function(a,b){var c=\nNaN;a=+a;b=+b;if(a!==this.Sa||b!==this.Va){switch(this.Ha){case 0:this.Ha=1;this.Ta?this.Ia.lineTo(a,b):this.Ia.moveTo(a,b);break;case 1:this.Ha=2;break;case 2:this.Ha=3;Mg(this,xk(this,c=wk(this,a,b)),c);break;default:Mg(this,this.Pn,c=wk(this,a,b))}this.ub=this.Sa;this.Sa=a;this.xb=this.Va;this.Va=b;this.Pn=c}}};(yk.prototype=Object.create(Ge.prototype)).point=function(a,b){Ge.prototype.point.call(this,b,a)};zk.prototype={moveTo:function(a,b){this.Ia.moveTo(b,a)},closePath:function(){this.Ia.closePath()},\nlineTo:function(a,b){this.Ia.lineTo(b,a)},bezierCurveTo:function(a,b,c,e,g,k){this.Ia.bezierCurveTo(b,a,e,c,k,g)}};Ak.prototype={areaStart:function(){this.Ta=0},areaEnd:function(){this.Ta=NaN},lineStart:function(){this.tc=[];this.ce=[]},lineEnd:function(){var a=this.tc,b=this.ce,c=a.length;if(c)if(this.Ta?this.Ia.lineTo(a[0],b[0]):this.Ia.moveTo(a[0],b[0]),2===c)this.Ia.lineTo(a[1],b[1]);else for(var e=Bk(a),g=Bk(b),k=0,n=1;n<c;++k,++n)this.Ia.bezierCurveTo(e[0][k],g[0][k],e[1][k],g[1][k],a[n],b[n]);\n(this.Ta||0!==this.Ta&&1===c)&&this.Ia.closePath();this.Ta=1-this.Ta;this.tc=this.ce=null},point:function(a,b){this.tc.push(+a);this.ce.push(+b)}};var bw=function(a){return new Ak(a)};He.prototype={areaStart:function(){this.Ta=0},areaEnd:function(){this.Ta=NaN},lineStart:function(){this.tc=this.ce=NaN;this.Ha=0},lineEnd:function(){0<this.Zi&&1>this.Zi&&2===this.Ha&&this.Ia.lineTo(this.tc,this.ce);(this.Ta||0!==this.Ta&&1===this.Ha)&&this.Ia.closePath();0<=this.Ta&&(this.Zi=1-this.Zi,this.Ta=1-this.Ta)},\npoint:function(a,b){a=+a;b=+b;switch(this.Ha){case 0:this.Ha=1;this.Ta?this.Ia.lineTo(a,b):this.Ia.moveTo(a,b);break;case 1:this.Ha=2;default:if(0>=this.Zi)this.Ia.lineTo(this.tc,b),this.Ia.lineTo(a,b);else{var c=this.tc*(1-this.Zi)+a*this.Zi;this.Ia.lineTo(c,this.ce);this.Ia.lineTo(c,b)}}this.tc=a;this.ce=b}};var cw=function(a){return new He(a,.5)},cm=Array.prototype.slice,Bc=function(a,b){if(1<(k=a.length))for(var c=1,e,g=a[b[0]],k,n=g.length;c<k;++c){e=g;for(var g=a[b[c]],m=0;m<n;++m)g[m][1]+=\ng[m][0]=isNaN(e[m][1])?e[m][0]:e[m][1]}},Cc=function(a){a=a.length;for(var b=Array(a);0<=--a;)b[a]=a;return b},dw=function(){function a(a){var k=b.apply(this,arguments),n,m=a.length,q=k.length,v=Array(q);for(n=0;n<q;++n){for(var A=k[n],B=v[n]=Array(m),E=0,C;E<m;++E)B[E]=C=[0,+g(a[E],A,E,a)],C.data=a[E];B.key=A}n=0;for(k=c(v);n<q;++n)v[k[n]].index=n;e(v,k);return v}var b=ea([]),c=Cc,e=Bc,g=ar;a.keys=function(c){return arguments.length?(b=\"function\"===typeof c?c:ea(cm.call(c)),a):b};a.value=function(b){return arguments.length?\n(g=\"function\"===typeof b?b:ea(+b),a):g};a.order=function(b){return arguments.length?(c=null==b?Cc:\"function\"===typeof b?b:ea(cm.call(b)),a):c};a.offset=function(b){return arguments.length?(e=null==b?Bc:b,a):e};return a},ew=function(a,b){if(0<(e=a.length)){for(var c,e,g=0,k=a[0].length,n;g<k;++g){for(n=c=0;c<e;++c)n+=a[c][g][1]||0;if(n)for(c=0;c<e;++c)a[c][g][1]/=n}Bc(a,b)}},fw=function(a,b){if(0<(g=a.length)){for(var c=0,e=a[b[0]],g,k=e.length;c<k;++c){for(var n=0,m=0;n<g;++n)m+=a[n][c][1]||0;e[c][1]+=\ne[c][0]=-m/2}Bc(a,b)}},gw=function(a,b){if(0<(n=a.length)&&0<(k=(g=a[b[0]]).length)){for(var c=0,e=1,g,k,n;e<k;++e){for(var m=0,q=0,v=0;m<n;++m){for(var A=a[b[m]],B=A[e][1]||0,A=A[e-1][1]||0,A=(B-A)/2,E=0;E<m;++E)var C=a[b[E]],J=C[e][1]||0,C=C[e-1][1]||0,A=A+(J-C);q+=B;v+=A*B}g[e-1][1]+=g[e-1][0]=c;q&&(c-=v/q)}g[e-1][1]+=g[e-1][0]=c;Bc(a,b)}},dm=function(a){var b=a.map(Ck);return Cc(a).sort(function(a,c){return b[a]-b[c]})},hw=function(a){return dm(a).reverse()},iw=function(a){var b=a.length,c,e=\na.map(Ck),g=Cc(a).sort(function(a,b){return e[b]-e[a]}),k=0,n=0,m=[],q=[];for(a=0;a<b;++a)c=g[a],k<n?(k+=e[c],m.push(c)):(n+=e[c],q.push(c));return q.reverse().concat(m)},jw=function(a){return Cc(a).reverse()},em=function(a){return function(){return a}};Ie.prototype={constructor:Ie,insert:function(a,b){var c,e;if(a){b.Ue=a;if(b.pe=a.pe)a.pe.Ue=b;a.pe=b;if(a.ac){for(a=a.ac;a.sb;)a=a.sb;a.sb=b}else a.ac=b;c=a}else this.Fa?(a=Dk(this.Fa),b.Ue=null,b.pe=a,a.Ue=a.sb=b,c=a):(b.Ue=b.pe=null,this.Fa=b,c=\nnull);b.sb=b.ac=null;b.qd=c;b.qb=!0;for(a=b;c&&c.qb;)b=c.qd,c===b.sb?(e=b.ac)&&e.qb?(c.qb=e.qb=!1,b.qb=!0,a=b):(a===c.ac&&(jd(this,c),a=c,c=a.qd),c.qb=!1,b.qb=!0,kd(this,b)):(e=b.sb)&&e.qb?(c.qb=e.qb=!1,b.qb=!0,a=b):(a===c.sb&&(kd(this,c),a=c,c=a.qd),c.qb=!1,b.qb=!0,jd(this,b)),c=a.qd;this.Fa.qb=!1},remove:function(a){a.pe&&(a.pe.Ue=a.Ue);a.Ue&&(a.Ue.pe=a.pe);a.pe=a.Ue=null;var b=a.qd,c=a.sb,e=a.ac,g,k;g=c?e?Dk(e):c:e;b?b.sb===a?b.sb=g:b.ac=g:this.Fa=g;c&&e?(k=g.qb,g.qb=a.qb,g.sb=c,c.qd=g,g!==e?(b=\ng.qd,g.qd=a.qd,a=g.ac,b.sb=a,g.ac=e,e.qd=g):(g.qd=b,b=g,a=g.ac)):(k=a.qb,a=g);a&&(a.qd=b);if(!k)if(a&&a.qb)a.qb=!1;else{do{if(a===this.Fa)break;if(a===b.sb){if(a=b.ac,a.qb&&(a.qb=!1,b.qb=!0,jd(this,b),a=b.ac),a.sb&&a.sb.qb||a.ac&&a.ac.qb){a.ac&&a.ac.qb||(a.sb.qb=!1,a.qb=!0,kd(this,a),a=b.ac);a.qb=b.qb;b.qb=a.ac.qb=!1;jd(this,b);a=this.Fa;break}}else if(a=b.sb,a.qb&&(a.qb=!1,b.qb=!0,kd(this,b),a=b.sb),a.sb&&a.sb.qb||a.ac&&a.ac.qb){a.sb&&a.sb.qb||(a.ac.qb=!1,a.qb=!0,jd(this,a),a=b.sb);a.qb=b.qb;b.qb=\na.sb.qb=!1;kd(this,b);a=this.Fa;break}a.qb=!0;a=b;b=b.qd}while(!a.qb);a&&(a.qb=!1)}}};var Fk=[],Ng,Hk=[],la=1E-6,ir=1E-12,tc,Ra,nd,Fa;Pg.prototype={constructor:Pg,polygons:function(){var a=this.edges;return this.cells.map(function(b){var c=b.halfedges.map(function(c){return Ek(b,a[c])});c.data=b.site.data;return c})},triangles:function(){var a=[],b=this.edges;this.cells.forEach(function(c,e){if(n=(g=c.halfedges).length){c=c.site;for(var g,k=-1,n,m,q=b[g[n-1]],q=q.left===c?q.right:q.left;++k<n;)m=\nq,q=b[g[k]],q=q.left===c?q.right:q.left,m&&q&&e<m.index&&e<q.index&&0>(c[0]-q[0])*(m[1]-c[1])-(c[0]-m[0])*(q[1]-c[1])&&a.push([c.data,m.data,q.data])}});return a},links:function(){return this.edges.filter(function(a){return a.right}).map(function(a){return{source:a.left.data,target:a.right.data}})},find:function(a,b,c){var e=this,g,k=e.NF||0;g=e.cells.length;for(var n;!(n=e.cells[k]);)if(++k>=g)return null;g=a-n.site[0];var m=b-n.site[1],q=g*g+m*m;do n=e.cells[g=k],k=null,n.halfedges.forEach(function(c){var g=\ne.edges[c];c=g.left;if(c!==n.site&&c||(c=g.right)){var g=a-c[0],m=b-c[1],g=g*g+m*m;g<q&&(q=g,k=c.index)}});while(null!==k);e.NF=g;return null==c||q<=c*c?n.site:null}};var kw=function(){function a(a){return new Pg(a.map(function(e,g){var k=[Math.round(b(e,g,a)/la)*la,Math.round(c(e,g,a)/la)*la];k.index=g;k.data=e;return k}),e)}var b=br,c=cr,e=null;a.polygons=function(b){return a(b).polygons()};a.links=function(b){return a(b).links()};a.triangles=function(b){return a(b).triangles()};a.x=function(c){return arguments.length?\n(b=\"function\"===typeof c?c:em(+c),a):b};a.y=function(b){return arguments.length?(c=\"function\"===typeof b?b:em(+b),a):c};a.extent=function(b){return arguments.length?(e=null==b?null:[[+b[0][0],+b[0][1]],[+b[1][0],+b[1][1]]],a):e&&[[e[0][0],e[0][1]],[e[1][0],e[1][1]]]};a.size=function(b){return arguments.length?(e=null==b?null:[[0,0],[+b[0],+b[1]]],a):e&&[e[1][0]-e[0][0],e[1][1]-e[0][1]]};return a},fm=function(a){return function(){return a}};qb.prototype={constructor:qb,scale:function(a){return 1===\na?this:new qb(this.k*a,this.x,this.y)},translate:function(a,b){return 0===a&0===b?this:new qb(this.k,this.x+this.k*a,this.y+this.k*b)},apply:function(a){return[a[0]*this.k+this.x,a[1]*this.k+this.y]},applyX:function(a){return a*this.k+this.x},applyY:function(a){return a*this.k+this.y},invert:function(a){return[(a[0]-this.x)/this.k,(a[1]-this.y)/this.k]},invertX:function(a){return(a-this.x)/this.k},invertY:function(a){return(a-this.y)/this.k},rescaleX:function(a){return a.copy().domain(a.range().map(this.invertX,\nthis).map(a.invert,a))},rescaleY:function(a){return a.copy().domain(a.range().map(this.invertY,this).map(a.invert,a))},toString:function(){return\"translate(\"+this.x+\",\"+this.y+\") scale(\"+this.k+\")\"}};var Qg=new qb(1,0,0);Jk.prototype=qb.prototype;var td=function(){d3.event.preventDefault();d3.event.stopImmediatePropagation()},lw=function(){function a(a){a.on(\"wheel.zoom\",q).on(\"mousedown.zoom\",v).on(\"dblclick.zoom\",B).on(\"touchstart.zoom\",C).on(\"touchmove.zoom\",J).on(\"touchend.zoom touchcancel.zoom\",\nW).style(\"-webkit-tap-highlight-color\",\"rgba(0,0,0,0)\").property(\"__zoom\",Kk)}function b(a,b){b=Math.max(K,Math.min(U,b));return b===a.k?a:new qb(b,a.x,a.y)}function c(a,b,c){var e=b[0]-c[0]*a.k;b=b[1]-c[1]*a.k;return e===a.x&&b===a.y?a:new qb(a.k,e,b)}function e(a,b){var c=a.invertX(b[0][0])-aa,e=a.invertX(b[1][0])-na,g=a.invertY(b[0][1])-ka;b=a.invertY(b[1][1])-ta;return a.translate(e>c?(c+e)/2:Math.min(0,c)||Math.max(0,e),b>g?(g+b)/2:Math.min(0,g)||Math.max(0,b))}function g(a){return[(+a[0][0]+\n+a[1][0])/2,(+a[0][1]+ +a[1][1])/2]}function k(a,b,c){a.on(\"start.zoom\",function(){n(this,arguments).start()}).on(\"interrupt.zoom end.zoom\",function(){n(this,arguments).end()}).tween(\"zoom\",function(){var a=this,e=arguments,k=n(a,e),m=Q.apply(a,e),q=c||g(m),v=Math.max(m[1][0]-m[0][0],m[1][1]-m[0][1]),m=a.__zoom,B=\"function\"===typeof b?b.apply(a,e):b,E=Ka(m.invert(q).concat(v/m.k),B.invert(q).concat(v/B.k));return function(a){if(1===a)a=B;else{a=E(a);var b=v/a[2];a=new qb(b,q[0]-a[0]*b,q[1]-a[1]*b)}k.zoom(null,\na)}})}function n(a,b){for(var c=0,e=N.length,g;c<e;++c)if((g=N[c]).Kh===a)return g;return new m(a,b)}function m(a,b){this.Kh=a;this.Wq=b;this.index=-1;this.active=0;this.extent=Q.apply(a,b)}function q(){function a(){g.Et=null;g.end()}if(O.apply(this,arguments)){var g=n(this,arguments),k=this.__zoom,m=Math.max(K,Math.min(U,k.k*Math.pow(2,-d3.event.deltaY*(d3.event.deltaMode?120:1)/500))),q=vb(this);if(g.Et){if(g.mouse[0][0]!==q[0]||g.mouse[0][1]!==q[1])g.mouse[1]=k.invert(g.mouse[0]=q);clearTimeout(g.Et)}else{if(k.k===\nm)return;g.mouse=[q,k.invert(q)];Lb(this);g.start()}td();g.Et=setTimeout(a,150);g.zoom(\"mouse\",e(c(b(k,m),g.mouse[0],g.mouse[1]),g.extent))}}function v(){function a(){td();g.xO=!0;g.zoom(\"mouse\",e(c(g.Kh.__zoom,g.mouse[0]=vb(g.Kh),g.mouse[1]),g.extent))}function b(){k.on(\"mousemove.zoom mouseup.zoom\",null);xd(d3.event.view,g.xO);td();g.end()}if(!Hb&&O.apply(this,arguments)){var g=n(this,arguments),k=Ma(d3.event.view).on(\"mousemove.zoom\",a,!0).on(\"mouseup.zoom\",b,!0),m=vb(this);Kd(d3.event.view);d3.event.stopImmediatePropagation();\ng.mouse=[m,this.__zoom.invert(m)];Lb(this);g.start()}}function B(){if(O.apply(this,arguments)){var g=this.__zoom,n=vb(this),m=g.invert(n),q=g.k*(d3.event.shiftKey?.5:2),g=e(c(b(g,q),n,m),Q.apply(this,arguments));td();0<ma?Ma(this).transition().duration(ma).call(k,g,n):Ma(this).call(a.transform,g)}}function C(){if(O.apply(this,arguments)){var a=n(this,arguments),b=d3.event.changedTouches,c,e=b.length,g,k,m;d3.event.stopImmediatePropagation();for(g=0;g<e;++g)(k=b[g],m=Ne(this,b,k.identifier),m=[m,this.__zoom.invert(m),\nk.identifier],a.Qe)?a.cf||(a.cf=m):(a.Qe=m,c=!0);if(S&&(S=clearTimeout(S),!a.cf)){a.end();(m=Ma(this).on(\"dblclick.zoom\"))&&m.apply(this,arguments);return}c&&(S=setTimeout(function(){S=null},500),Lb(this),a.start())}}function J(){var a=n(this,arguments),g=d3.event.changedTouches,k=g.length,m,q,v,B;td();S&&(S=clearTimeout(S));for(m=0;m<k;++m)q=g[m],v=Ne(this,g,q.identifier),a.Qe&&a.Qe[2]===q.identifier?a.Qe[0]=v:a.cf&&a.cf[2]===q.identifier&&(a.cf[0]=v);q=a.Kh.__zoom;if(a.cf){v=a.Qe[0];g=a.Qe[1];m=\na.cf[0];k=a.cf[1];B=(B=m[0]-v[0])*B+(B=m[1]-v[1])*B;var E=(E=k[0]-g[0])*E+(E=k[1]-g[1])*E;q=b(q,Math.sqrt(B/E));v=[(v[0]+m[0])/2,(v[1]+m[1])/2];B=[(g[0]+k[0])/2,(g[1]+k[1])/2]}else if(a.Qe)v=a.Qe[0],B=a.Qe[1];else return;a.zoom(\"touch\",e(c(q,v,B),a.extent))}function W(){var a=n(this,arguments),b=d3.event.changedTouches,c=b.length,e,g;d3.event.stopImmediatePropagation();Hb&&clearTimeout(Hb);Hb=setTimeout(function(){Hb=null},500);for(e=0;e<c;++e)g=b[e],a.Qe&&a.Qe[2]===g.identifier?delete a.Qe:a.cf&&\na.cf[2]===g.identifier&&delete a.cf;a.cf&&!a.Qe&&(a.Qe=a.cf,delete a.cf);a.Qe||a.end()}var O=mr,Q=nr,K=0,U=Infinity,aa=-U,na=U,ka=aa,ta=na,ma=250,Ka=cl,N=[],Gb=E(\"start\",\"zoom\",\"end\"),S,Hb;a.transform=function(a,b){var c=a.selection?a.selection():a;c.property(\"__zoom\",Kk);a!==c?k(a,b):c.interrupt().each(function(){n(this,arguments).start().zoom(null,\"function\"===typeof b?b.apply(this,arguments):b).end()})};a.scaleBy=function(b,c){a.scaleTo(b,function(){var a=this.__zoom.k,b=\"function\"===typeof c?\nc.apply(this,arguments):c;return a*b})};a.scaleTo=function(k,n){a.transform(k,function(){var a=Q.apply(this,arguments),k=this.__zoom,m=g(a),q=k.invert(m),v=\"function\"===typeof n?n.apply(this,arguments):n;return e(c(b(k,v),m,q),a)})};a.translateBy=function(b,c,g){a.transform(b,function(){return e(this.__zoom.translate(\"function\"===typeof c?c.apply(this,arguments):c,\"function\"===typeof g?g.apply(this,arguments):g),Q.apply(this,arguments))})};m.prototype={start:function(){1===++this.active&&(this.index=\nN.push(this)-1,this.gj(\"start\"));return this},zoom:function(a,b){this.mouse&&\"mouse\"!==a&&(this.mouse[1]=b.invert(this.mouse[0]));this.Qe&&\"touch\"!==a&&(this.Qe[1]=b.invert(this.Qe[0]));this.cf&&\"touch\"!==a&&(this.cf[1]=b.invert(this.cf[0]));this.Kh.__zoom=b;this.gj(\"zoom\");return this},end:function(){0===--this.active&&(N.splice(this.index,1),this.index=-1,this.gj(\"end\"));return this},gj:function(b){Ya(new lr(a,b,this.Kh.__zoom),Gb.apply,Gb,[b,this.Kh,this.Wq])}};a.filter=function(b){return arguments.length?\n(O=\"function\"===typeof b?b:fm(!!b),a):O};a.extent=function(b){return arguments.length?(Q=\"function\"===typeof b?b:fm([[+b[0][0],+b[0][1]],[+b[1][0],+b[1][1]]]),a):Q};a.scaleExtent=function(b){return arguments.length?(K=+b[0],U=+b[1],a):[K,U]};a.translateExtent=function(b){return arguments.length?(aa=+b[0][0],na=+b[1][0],ka=+b[0][1],ta=+b[1][1],a):[[aa,ka],[na,ta]]};a.duration=function(b){return arguments.length?(ma=+b,a):ma};a.interpolate=function(b){return arguments.length?(Ka=b,a):Ka};a.on=function(){var b=\nGb.on.apply(Gb,arguments);return b===Gb?a:b};return a};d3.version=\"4.6.0\";d3.bisect=Sb;d3.bisectRight=Sb;d3.bisectLeft=or;d3.ascending=Eb;d3.bisector=Gg;d3.descending=pr;d3.deviation=Nk;d3.extent=Ok;d3.histogram=tr;d3.thresholdFreedmanDiaconis=ur;d3.thresholdScott=vr;d3.thresholdSturges=Qk;d3.max=wr;d3.mean=xr;d3.median=yr;d3.merge=Uf;d3.min=Rk;d3.pairs=zr;d3.permute=Ar;d3.quantile=dd;d3.range=bb;d3.scan=Br;d3.shuffle=Cr;d3.sum=Dr;d3.ticks=we;d3.tickStep=b;d3.transpose=Sk;d3.variance=Mk;d3.zip=Er;\nd3.axisTop=q;d3.axisRight=v;d3.axisBottom=B;d3.axisLeft=C;d3.brush=at;d3.brushX=jo;d3.brushY=ko;d3.brushSelection=io;d3.chord=bt;d3.ribbon=et;d3.nest=ft;d3.set=mi;d3.map=fb;d3.keys=gt;d3.values=ht;d3.entries=it;d3.color=sb;d3.rgb=Fc;d3.hsl=yd;d3.lab=zd;d3.hcl=Ad;d3.cubehelix=Za;d3.dispatch=E;d3.drag=ms;d3.dragDisable=Kd;d3.dragEnable=xd;d3.dsvFormat=dh;d3.csvParse=nl;d3.csvParseRows=jt;d3.csvFormat=kt;d3.csvFormatRows=lt;d3.tsvParse=ol;d3.tsvParseRows=mt;d3.tsvFormat=nt;d3.tsvFormatRows=ot;d3.easeLinear=\nOn;d3.easeQuad=ai;d3.easeQuadIn=Pn;d3.easeQuadOut=Qn;d3.easeQuadInOut=ai;d3.easeCubic=zf;d3.easeCubicIn=Rn;d3.easeCubicOut=Sn;d3.easeCubicInOut=zf;d3.easePoly=fl;d3.easePolyIn=Rs;d3.easePolyOut=Ss;d3.easePolyInOut=fl;d3.easeSin=ci;d3.easeSinIn=Tn;d3.easeSinOut=Un;d3.easeSinInOut=ci;d3.easeExp=ei;d3.easeExpIn=Vn;d3.easeExpOut=Wn;d3.easeExpInOut=ei;d3.easeCircle=fi;d3.easeCircleIn=Xn;d3.easeCircleOut=Yn;d3.easeCircleInOut=fi;d3.easeBounce=Lc;d3.easeBounceIn=Zn;d3.easeBounceOut=Lc;d3.easeBounceInOut=\nfo;d3.easeBack=gl;d3.easeBackIn=Ts;d3.easeBackOut=Us;d3.easeBackInOut=gl;d3.easeElastic=hl;d3.easeElasticIn=Vs;d3.easeElasticOut=hl;d3.easeElasticInOut=Ws;d3.forceCenter=pt;d3.forceCollide=Ct;d3.forceLink=Dt;d3.forceManyBody=Gt;d3.forceSimulation=Ft;d3.forceX=Ht;d3.forceY=It;d3.formatDefaultLocale=ti;d3.formatLocale=ui;d3.formatSpecifier=xe;d3.precisionFixed=Qj;d3.precisionPrefix=Oj;d3.precisionRound=Pj;d3.geoArea=Mt;d3.geoBounds=Nt;d3.geoCentroid=Ot;d3.geoCircle=Qt;d3.geoClipExtent=Rt;d3.geoDistance=\nTt;d3.geoGraticule=$i;d3.geoGraticule10=bp;d3.geoInterpolate=Ut;d3.geoLength=ul;d3.geoPath=Vt;d3.geoAlbers=wl;d3.geoAlbersUsa=Xt;d3.geoAzimuthalEqualArea=Yt;d3.geoAzimuthalEqualAreaRaw=ih;d3.geoAzimuthalEquidistant=Zt;d3.geoAzimuthalEquidistantRaw=jh;d3.geoConicConformal=au;d3.geoConicConformalRaw=uj;d3.geoConicEqualArea=Xe;d3.geoConicEqualAreaRaw=rj;d3.geoConicEquidistant=cu;d3.geoConicEquidistantRaw=vj;d3.geoEquirectangular=bu;d3.geoEquirectangularRaw=ad;d3.geoGnomonic=du;d3.geoGnomonicRaw=ig;d3.geoIdentity=\neu;d3.geoProjection=xb;d3.geoProjectionMutator=fg;d3.geoMercator=$t;d3.geoMercatorRaw=me;d3.geoOrthographic=fu;d3.geoOrthographicRaw=jg;d3.geoStereographic=gu;d3.geoStereographicRaw=kg;d3.geoTransverseMercator=hu;d3.geoTransverseMercatorRaw=lg;d3.geoRotation=Pt;d3.geoStream=cb;d3.geoTransform=Wt;d3.cluster=iu;d3.hierarchy=mg;d3.pack=vu;d3.packSiblings=uu;d3.packEnclose=Dj;d3.partition=wu;d3.stratify=yu;d3.tree=zu;d3.treemap=Au;d3.treemapBinary=Bu;d3.treemapDice=bd;d3.treemapSlice=se;d3.treemapSliceDice=\nCu;d3.treemapSquarify=Al;d3.treemapResquarify=Du;d3.interpolate=Pc;d3.interpolateArray=Xk;d3.interpolateBasis=Vk;d3.interpolateBasisClosed=Wk;d3.interpolateDate=Yk;d3.interpolateNumber=Na;d3.interpolateObject=Zk;d3.interpolateRound=Nj;d3.interpolateString=Zg;d3.interpolateTransformCss=al;d3.interpolateTransformSvg=bl;d3.interpolateZoom=cl;d3.interpolateRgb=qd;d3.interpolateRgbBasis=ns;d3.interpolateRgbBasisClosed=os;d3.interpolateHsl=ps;d3.interpolateHslLong=qs;d3.interpolateLab=ln;d3.interpolateHcl=\nrs;d3.interpolateHclLong=ss;d3.interpolateCubehelix=ts;d3.interpolateCubehelixLong=Oe;d3.quantize=us;d3.path=Mb;d3.polygonArea=Eu;d3.polygonCentroid=Fu;d3.polygonHull=Gu;d3.polygonContains=Hu;d3.polygonLength=Iu;d3.quadtree=Nd;d3.queue=Jj;d3.randomUniform=Ku;d3.randomNormal=Bl;d3.randomLogNormal=Lu;d3.randomBates=Mu;d3.randomIrwinHall=Cl;d3.randomExponential=Nu;d3.request=kh;d3.html=Ou;d3.json=Pu;d3.text=Qu;d3.xml=Ru;d3.csv=Su;d3.tsv=Tu;d3.scaleBand=ug;d3.scalePoint=Qp;d3.scaleIdentity=Sj;d3.scaleLinear=\nRj;d3.scaleLog=Wj;d3.scaleOrdinal=sg;d3.scaleImplicit=tg;d3.scalePow=yg;d3.scaleSqrt=Yp;d3.scaleQuantile=Yj;d3.scaleQuantize=Zj;d3.scaleThreshold=ak;d3.scaleTime=rv;d3.scaleUtc=sv;d3.schemeCategory10=tv;d3.schemeCategory20b=uv;d3.schemeCategory20c=vv;d3.schemeCategory20=wv;d3.interpolateCubehelixDefault=xv;d3.interpolateRainbow=Av;d3.interpolateWarm=yv;d3.interpolateCool=zv;d3.interpolateViridis=Bv;d3.interpolateMagma=Cv;d3.interpolateInferno=Dv;d3.interpolatePlasma=Ev;d3.scaleSequential=jk;d3.creator=\nRg;d3.local=ka;d3.matcher=Sg;d3.mouse=vb;d3.namespace=od;d3.namespaces=Sa;d3.select=Ma;d3.selectAll=ks;d3.selection=Ib;d3.selector=Me;d3.selectorAll=Vg;d3.touch=Ne;d3.touches=ls;d3.window=$b;d3.customEvent=Ya;d3.arc=Fv;d3.area=Tl;d3.line=rh;d3.pie=Iv;d3.radialArea=Kv;d3.radialLine=Jv;d3.symbol=Qv;d3.symbols=Pv;d3.symbolCircle=sh;d3.symbolCross=Vl;d3.symbolDiamond=Xl;d3.symbolSquare=$l;d3.symbolStar=Zl;d3.symbolTriangle=am;d3.symbolWye=bm;d3.curveBasisClosed=Sv;d3.curveBasisOpen=Tv;d3.curveBasis=Rv;\nd3.curveBundle=Uv;d3.curveCardinalClosed=Wv;d3.curveCardinalOpen=Xv;d3.curveCardinal=Vv;d3.curveCatmullRomClosed=Zv;d3.curveCatmullRomOpen=$v;d3.curveCatmullRom=Yv;d3.curveLinearClosed=aw;d3.curveLinear=$e;d3.curveMonotoneX=Xq;d3.curveMonotoneY=Yq;d3.curveNatural=bw;d3.curveStep=cw;d3.curveStepAfter=$q;d3.curveStepBefore=Zq;d3.stack=dw;d3.stackOffsetExpand=ew;d3.stackOffsetNone=Bc;d3.stackOffsetSilhouette=fw;d3.stackOffsetWiggle=gw;d3.stackOrderAscending=dm;d3.stackOrderDescending=hw;d3.stackOrderInsideOut=\niw;d3.stackOrderNone=Cc;d3.stackOrderReverse=jw;d3.timeInterval=xa;d3.timeMillisecond=Yb;d3.timeMilliseconds=Fl;d3.utcMillisecond=Yb;d3.utcMilliseconds=Fl;d3.timeSecond=sd;d3.timeSeconds=Gl;d3.utcSecond=sd;d3.utcSeconds=Gl;d3.timeMinute=lh;d3.timeMinutes=Uu;d3.timeHour=mh;d3.timeHours=Vu;d3.timeDay=ye;d3.timeDays=Wu;d3.timeWeek=gd;d3.timeWeeks=Ml;d3.timeSunday=gd;d3.timeSundays=Ml;d3.timeMonday=Dg;d3.timeMondays=Xu;d3.timeTuesday=Hl;d3.timeTuesdays=Yu;d3.timeWednesday=Il;d3.timeWednesdays=Zu;d3.timeThursday=\nJl;d3.timeThursdays=$u;d3.timeFriday=Kl;d3.timeFridays=av;d3.timeSaturday=Ll;d3.timeSaturdays=bv;d3.timeMonth=nh;d3.timeMonths=cv;d3.timeYear=Vb;d3.timeYears=dv;d3.utcMinute=oh;d3.utcMinutes=ev;d3.utcHour=ph;d3.utcHours=fv;d3.utcDay=ze;d3.utcDays=gv;d3.utcWeek=hd;d3.utcWeeks=Sl;d3.utcSunday=hd;d3.utcSundays=Sl;d3.utcMonday=Eg;d3.utcMondays=hv;d3.utcTuesday=Nl;d3.utcTuesdays=iv;d3.utcWednesday=Ol;d3.utcWednesdays=jv;d3.utcThursday=Pl;d3.utcThursdays=kv;d3.utcFriday=Ql;d3.utcFridays=lv;d3.utcSaturday=\nRl;d3.utcSaturdays=mv;d3.utcMonth=qh;d3.utcMonths=nv;d3.utcYear=Wb;d3.utcYears=ov;d3.timeFormatDefaultLocale=ik;d3.timeFormatLocale=bk;d3.isoFormat=pv;d3.isoParse=qv;d3.now=cc;d3.timer=Dd;d3.timerFlush=Yh;d3.timeout=xf;d3.interval=vs;d3.transition=$h;d3.active=Zs;d3.interrupt=Lb;d3.voronoi=kw;d3.zoom=lw;d3.zoomTransform=Jk;d3.zoomIdentity=Qg;Sa.svg=Sa.svg;Sa.xhtml=Sa.xhtml;Sa.xlink=Sa.xlink;Sa.xml=Sa.xml;Sa.xmlns=Sa.xmlns})();h.R={};h.R.wg=h.Mh;\nh.R.Qm=function(a,b){b.unshift(a);h.debug.Error.call(this,h.ca.kW.apply(null,b));b.shift()};h.da(h.R.Qm,h.debug.Error);h.R.Qm.prototype.name=\"AssertionError\";h.R.hD=function(a){throw a;};h.R.wr=h.R.hD;h.R.wh=function(a,b,c,e){var g=\"Assertion failed\";if(c)var g=g+(\": \"+c),k=e;else a&&(g+=\": \"+a,k=b);a=new h.R.Qm(\"\"+g,k||[]);h.R.wr(a)};h.R.iba=function(a){h.R.wg&&(h.R.wr=a)};h.R.assert=function(a,b,c){h.R.wg&&!a&&h.R.wh(\"\",null,b,Array.prototype.slice.call(arguments,2));return a};\nh.R.fail=function(a,b){h.R.wg&&h.R.wr(new h.R.Qm(\"Failure\"+(a?\": \"+a:\"\"),Array.prototype.slice.call(arguments,1)))};h.R.ul=function(a,b,c){h.R.wg&&!h.ni(a)&&h.R.wh(\"Expected number but got %s: %s.\",[h.df(a),a],b,Array.prototype.slice.call(arguments,2));return a};h.R.Lw=function(a,b,c){h.R.wg&&!h.Hb(a)&&h.R.wh(\"Expected string but got %s: %s.\",[h.df(a),a],b,Array.prototype.slice.call(arguments,2));return a};\nh.R.d2=function(a,b,c){h.R.wg&&!h.isFunction(a)&&h.R.wh(\"Expected function but got %s: %s.\",[h.df(a),a],b,Array.prototype.slice.call(arguments,2));return a};h.R.e2=function(a,b,c){h.R.wg&&!h.mj(a)&&h.R.wh(\"Expected object but got %s: %s.\",[h.df(a),a],b,Array.prototype.slice.call(arguments,2));return a};h.R.NJ=function(a,b,c){h.R.wg&&!h.isArray(a)&&h.R.wh(\"Expected array but got %s: %s.\",[h.df(a),a],b,Array.prototype.slice.call(arguments,2));return a};\nh.R.b2=function(a,b,c){h.R.wg&&!h.sk(a)&&h.R.wh(\"Expected boolean but got %s: %s.\",[h.df(a),a],b,Array.prototype.slice.call(arguments,2));return a};h.R.c2=function(a,b,c){!h.R.wg||h.mj(a)&&a.nodeType==h.dom.dE.mD||h.R.wh(\"Expected Element but got %s: %s.\",[h.df(a),a],b,Array.prototype.slice.call(arguments,2));return a};h.R.Xq=function(a,b,c,e){!h.R.wg||a instanceof b||h.R.wh(\"Expected instanceof %s but got %s.\",[h.R.UA(b),h.R.UA(a)],c,Array.prototype.slice.call(arguments,3));return a};\nh.R.f2=function(){for(var a in Object.prototype)h.R.fail(a+\" should not be enumerable in Object.prototype.\")};h.R.UA=function(a){return a instanceof Function?a.displayName||a.name||\"unknown type name\":a instanceof Object?a.constructor.displayName||a.constructor.name||Object.prototype.toString.call(a):null===a?\"null\":typeof a};h.la={};h.la.userAgent={};h.la.userAgent.util={};h.la.userAgent.util.Cz=function(){var a=h.la.userAgent.util.$L();return a&&(a=a.userAgent)?a:\"\"};h.la.userAgent.util.$L=function(){return h.global.navigator};\nh.la.userAgent.util.LC=h.la.userAgent.util.Cz();h.la.userAgent.util.lba=function(a){h.la.userAgent.util.LC=a||h.la.userAgent.util.Cz()};h.la.userAgent.util.nk=function(){return h.la.userAgent.util.LC};h.la.userAgent.util.lc=function(a){var b=h.la.userAgent.util.nk();return h.ca.contains(b,a)};h.la.userAgent.util.hO=function(a){var b=h.la.userAgent.util.nk();return h.ca.dK(b,a)};\nh.la.userAgent.util.Bx=function(a){for(var b=/(\\w[\\w ]+)\\/([^\\s]+)\\s*(?:\\((.*?)\\))?/g,c=[],e;e=b.exec(a);)c.push([e[1],e[2],e[3]||void 0]);return c};l.Map=function(a,b){this.vh=a;this.Bk=b;this.jc={};this.tl=!0;0<this.vh.length&&this.WN()};l.Map.prototype.WN=function(){for(var a=0;a<this.vh.length;a++){var b=this.vh[a],c=b[0],b=b[1];this.jc[c.toString()]=new l.Map.fu(c,b)}this.tl=!0};\nl.Map.prototype.toArray=function(){if(this.tl){if(this.Bk){var a=this.jc,b;for(b in a)if(Object.prototype.hasOwnProperty.call(a,b)){var c=a[b].Aj;c&&c.toArray()}}}else{this.vh.length=0;a=this.Cm();a.sort();for(b=0;b<a.length;b++){var e=this.jc[a[b]];(c=e.Aj)&&c.toArray();this.vh.push([e.key,e.value])}this.tl=!0}return this.vh};\nl.Map.prototype.C=function(a,b){for(var c=this.toArray(),e=[],g=0;g<c.length;g++){var k=this.jc[c[g][0].toString()];this.Lm(k);var m=k.Aj;m?(h.R.assert(b),e.push([k.key,b(a,m)])):e.push([k.key,k.value])}return e};l.Map.l6=function(a,b,c){b=new l.Map([],b);for(var e=0;e<a.length;e++){var g=a[e][0],k=c(a[e][1]);b.set(g,k)}return b};l.Map.Ek=function(a){this.fB=0;this.vh=a};l.Map.Ek.prototype.next=function(){return this.fB<this.vh.length?{done:!1,value:this.vh[this.fB++]}:{done:!0,value:void 0}};\n\"undefined\"!=typeof Symbol&&(l.Map.Ek.prototype[Symbol.iterator]=function(){return this});d=l.Map.prototype;d.clear=function(){this.jc={};this.tl=!1};d.entries=function(){var a=[],b=this.Cm();b.sort();for(var c=0;c<b.length;c++){var e=this.jc[b[c]];a.push([e.key,this.Lm(e)])}return new l.Map.Ek(a)};d.keys=function(){var a=[],b=this.Cm();b.sort();for(var c=0;c<b.length;c++){var e=this.jc[b[c]];a.push(e.key)}return new l.Map.Ek(a)};\nd.values=function(){var a=[],b=this.Cm();b.sort();for(var c=0;c<b.length;c++){var e=this.jc[b[c]];a.push(this.Lm(e))}return new l.Map.Ek(a)};d.forEach=function(a,b){var c=this.Cm();c.sort();for(var e=0;e<c.length;e++){var g=this.jc[c[e]];a.call(b,this.Lm(g),g.key,this)}};d.set=function(a,b){var c=new l.Map.fu(a);this.Bk?(c.Aj=b,c.value=b.toArray()):c.value=b;this.jc[a.toString()]=c;this.tl=!1;return this};d.Lm=function(a){return this.Bk?(a.Aj||(a.Aj=new this.Bk(a.value)),a.Aj):a.value};\nd.get=function(a){a=a.toString();if(a=this.jc[a])return this.Lm(a)};d.has=function(a){a=a.toString();return a in this.jc};l.Map.ia=function(a,b,c,e,g){for(var k=void 0,m=void 0;b.fa()&&!b.ga();){var n=b.ka;1==n?k=c.call(b):2==n&&(a.Bk?(m=new a.Bk,e.call(b,m,g)):m=e.call(b))}h.R.assert(void 0!=k);h.R.assert(void 0!=m);a.set(k,m)};l.Map.prototype.Cm=function(){var a=this.jc,b=[],c;for(c in a)Object.prototype.hasOwnProperty.call(a,c)&&b.push(c);return b};\nl.Map.fu=function(a,b){this.key=a;this.value=b;this.Aj=void 0};h.aa={};h.mh=h.Qp;h.aa.eh=!1;h.aa.VO=function(a){return a[a.length-1]};h.aa.last=h.aa.VO;h.aa.indexOf=h.mh&&(h.aa.eh||Array.prototype.indexOf)?function(a,b,c){h.R.assert(null!=a.length);return Array.prototype.indexOf.call(a,b,c)}:function(a,b,c){c=null==c?0:0>c?Math.max(0,a.length+c):c;if(h.Hb(a))return h.Hb(b)&&1==b.length?a.indexOf(b,c):-1;for(;c<a.length;c++)if(c in a&&a[c]===b)return c;return-1};\nh.aa.lastIndexOf=h.mh&&(h.aa.eh||Array.prototype.lastIndexOf)?function(a,b,c){h.R.assert(null!=a.length);c=null==c?a.length-1:c;return Array.prototype.lastIndexOf.call(a,b,c)}:function(a,b,c){c=null==c?a.length-1:c;0>c&&(c=Math.max(0,a.length+c));if(h.Hb(a))return h.Hb(b)&&1==b.length?a.lastIndexOf(b,c):-1;for(;0<=c;c--)if(c in a&&a[c]===b)return c;return-1};\nh.aa.forEach=h.mh&&(h.aa.eh||Array.prototype.forEach)?function(a,b,c){h.R.assert(null!=a.length);Array.prototype.forEach.call(a,b,c)}:function(a,b,c){for(var e=a.length,g=h.Hb(a)?a.split(\"\"):a,k=0;k<e;k++)k in g&&b.call(c,g[k],k,a)};h.aa.Fx=function(a,b,c){for(var e=a.length,g=h.Hb(a)?a.split(\"\"):a,e=e-1;0<=e;--e)e in g&&b.call(c,g[e],e,a)};\nh.aa.filter=h.mh&&(h.aa.eh||Array.prototype.filter)?function(a,b,c){h.R.assert(null!=a.length);return Array.prototype.filter.call(a,b,c)}:function(a,b,c){for(var e=a.length,g=[],k=0,m=h.Hb(a)?a.split(\"\"):a,n=0;n<e;n++)if(n in m){var q=m[n];b.call(c,q,n,a)&&(g[k++]=q)}return g};\nh.aa.map=h.mh&&(h.aa.eh||Array.prototype.map)?function(a,b,c){h.R.assert(null!=a.length);return Array.prototype.map.call(a,b,c)}:function(a,b,c){for(var e=a.length,g=Array(e),k=h.Hb(a)?a.split(\"\"):a,m=0;m<e;m++)m in k&&(g[m]=b.call(c,k[m],m,a));return g};h.aa.reduce=h.mh&&(h.aa.eh||Array.prototype.reduce)?function(a,b,c,e){h.R.assert(null!=a.length);e&&(b=h.bind(b,e));return Array.prototype.reduce.call(a,b,c)}:function(a,b,c,e){var g=c;h.aa.forEach(a,function(c,m){g=b.call(e,g,c,m,a)});return g};\nh.aa.reduceRight=h.mh&&(h.aa.eh||Array.prototype.reduceRight)?function(a,b,c,e){h.R.assert(null!=a.length);h.R.assert(null!=b);e&&(b=h.bind(b,e));return Array.prototype.reduceRight.call(a,b,c)}:function(a,b,c,e){var g=c;h.aa.Fx(a,function(c,m){g=b.call(e,g,c,m,a)});return g};\nh.aa.some=h.mh&&(h.aa.eh||Array.prototype.some)?function(a,b,c){h.R.assert(null!=a.length);return Array.prototype.some.call(a,b,c)}:function(a,b,c){for(var e=a.length,g=h.Hb(a)?a.split(\"\"):a,k=0;k<e;k++)if(k in g&&b.call(c,g[k],k,a))return!0;return!1};h.aa.every=h.mh&&(h.aa.eh||Array.prototype.every)?function(a,b,c){h.R.assert(null!=a.length);return Array.prototype.every.call(a,b,c)}:function(a,b,c){for(var e=a.length,g=h.Hb(a)?a.split(\"\"):a,k=0;k<e;k++)if(k in g&&!b.call(c,g[k],k,a))return!1;return!0};\nh.aa.count=function(a,b,c){var e=0;h.aa.forEach(a,function(a,k,m){b.call(c,a,k,m)&&++e},c);return e};h.aa.find=function(a,b,c){b=h.aa.findIndex(a,b,c);return 0>b?null:h.Hb(a)?a.charAt(b):a[b]};h.aa.findIndex=function(a,b,c){for(var e=a.length,g=h.Hb(a)?a.split(\"\"):a,k=0;k<e;k++)if(k in g&&b.call(c,g[k],k,a))return k;return-1};h.aa.b6=function(a,b,c){b=h.aa.WK(a,b,c);return 0>b?null:h.Hb(a)?a.charAt(b):a[b]};\nh.aa.WK=function(a,b,c){for(var e=a.length,g=h.Hb(a)?a.split(\"\"):a,e=e-1;0<=e;e--)if(e in g&&b.call(c,g[e],e,a))return e;return-1};h.aa.contains=function(a,b){return 0<=h.aa.indexOf(a,b)};h.aa.Zc=function(a){return 0==a.length};h.aa.clear=function(a){if(!h.isArray(a))for(var b=a.length-1;0<=b;b--)delete a[b];a.length=0};h.aa.insert=function(a,b){h.aa.contains(a,b)||a.push(b)};h.aa.kB=function(a,b,c){h.aa.splice(a,c,0,b)};h.aa.v7=function(a,b,c){h.xs(h.aa.splice,a,c,0).apply(null,b)};\nh.aa.insertBefore=function(a,b,c){var e;2==arguments.length||0>(e=h.aa.indexOf(a,c))?a.push(b):h.aa.kB(a,b,e)};h.aa.remove=function(a,b){b=h.aa.indexOf(a,b);var c;(c=0<=b)&&h.aa.xk(a,b);return c};h.aa.Baa=function(a,b){b=h.aa.lastIndexOf(a,b);return 0<=b?(h.aa.xk(a,b),!0):!1};h.aa.xk=function(a,b){h.R.assert(null!=a.length);return 1==Array.prototype.splice.call(a,b,1).length};h.aa.Aaa=function(a,b,c){b=h.aa.findIndex(a,b,c);return 0<=b?(h.aa.xk(a,b),!0):!1};\nh.aa.yaa=function(a,b,c){var e=0;h.aa.Fx(a,function(g,k){b.call(c,g,k,a)&&h.aa.xk(a,k)&&e++});return e};h.aa.concat=function(a){return Array.prototype.concat.apply(Array.prototype,arguments)};h.aa.join=function(a){return Array.prototype.concat.apply(Array.prototype,arguments)};h.aa.toArray=function(a){var b=a.length;if(0<b){for(var c=Array(b),e=0;e<b;e++)c[e]=a[e];return c}return[]};h.aa.clone=h.aa.toArray;\nh.aa.extend=function(a,b){for(var c=1;c<arguments.length;c++){var e=arguments[c];if(h.Gd(e)){var g=a.length||0,k=e.length||0;a.length=g+k;for(var m=0;m<k;m++)a[g+m]=e[m]}else a.push(e)}};h.aa.splice=function(a,b,c,e){h.R.assert(null!=a.length);return Array.prototype.splice.apply(a,h.aa.slice(arguments,1))};h.aa.slice=function(a,b,c){h.R.assert(null!=a.length);return 2>=arguments.length?Array.prototype.slice.call(a,b):Array.prototype.slice.call(a,b,c)};\nh.aa.tP=function(a,b,c){b=b||a;var e=function(a){return h.mj(a)?\"o\"+h.VA(a):(typeof a).charAt(0)+a};c=c||e;for(var e={},g=0,k=0;k<a.length;){var m=a[k++],n=c(m);Object.prototype.hasOwnProperty.call(e,n)||(e[n]=!0,b[g++]=m)}b.length=g};h.aa.Sw=function(a,b,c){return h.aa.Tw(a,c||h.aa.fi,!1,b)};h.aa.F2=function(a,b,c){return h.aa.Tw(a,b,!0,void 0,c)};h.aa.Tw=function(a,b,c,e,g){for(var k=0,m=a.length,n;k<m;){var q=k+m>>1,v;v=c?b.call(g,a[q],q,a):b(e,a[q]);0<v?k=q+1:(m=q,n=!v)}return n?k:~k};\nh.aa.sort=function(a,b){a.sort(b||h.aa.fi)};h.aa.Lba=function(a,b){function c(a,b){return k(a.value,b.value)||a.index-b.index}for(var e=Array(a.length),g=0;g<a.length;g++)e[g]={index:g,value:a[g]};var k=b||h.aa.fi;h.aa.sort(e,c);for(g=0;g<a.length;g++)a[g]=e[g].value};h.aa.bW=function(a,b,c){var e=c||h.aa.fi;h.aa.sort(a,function(a,c){return e(b(a),b(c))})};h.aa.Cba=function(a,b,c){h.aa.bW(a,function(a){return a[b]},c)};\nh.aa.yB=function(a,b,c){b=b||h.aa.fi;for(var e=1;e<a.length;e++){var g=b(a[e-1],a[e]);if(0<g||0==g&&c)return!1}return!0};h.aa.ii=function(a,b,c){if(!h.Gd(a)||!h.Gd(b)||a.length!=b.length)return!1;var e=a.length;c=c||h.aa.tx;for(var g=0;g<e;g++)if(!c(a[g],b[g]))return!1;return!0};h.aa.I3=function(a,b,c){c=c||h.aa.fi;for(var e=Math.min(a.length,b.length),g=0;g<e;g++){var k=c(a[g],b[g]);if(0!=k)return k}return h.aa.fi(a.length,b.length)};h.aa.fi=function(a,b){return a>b?1:a<b?-1:0};\nh.aa.z7=function(a,b){return-h.aa.fi(a,b)};h.aa.tx=function(a,b){return a===b};h.aa.D2=function(a,b,c){c=h.aa.Sw(a,b,c);return 0>c?(h.aa.kB(a,b,-(c+1)),!0):!1};h.aa.E2=function(a,b,c){b=h.aa.Sw(a,b,c);return 0<=b?h.aa.xk(a,b):!1};h.aa.J2=function(a,b,c){for(var e={},g=0;g<a.length;g++){var k=a[g],m=b.call(c,k,g,a);h.Pe(m)&&(m=e[m]||(e[m]=[]),m.push(k))}return e};h.aa.C=function(a,b,c){var e={};h.aa.forEach(a,function(g,k){e[b.call(c,g,k,a)]=g});return e};\nh.aa.range=function(a,b,c){var e=[],g=0,k=a;c=c||1;void 0!==b&&(g=a,k=b);if(0>c*(k-g))return[];if(0<c)for(a=g;a<k;a+=c)e.push(a);else for(a=g;a>k;a+=c)e.push(a);return e};h.aa.repeat=function(a,b){for(var c=[],e=0;e<b;e++)c[e]=a;return c};h.aa.ZK=function(a){for(var b=[],c=0;c<arguments.length;c++){var e=arguments[c];if(h.isArray(e))for(var g=0;g<e.length;g+=8192)for(var k=h.aa.slice(e,g,g+8192),k=h.aa.ZK.apply(null,k),m=0;m<k.length;m++)b.push(k[m]);else b.push(e)}return b};\nh.aa.rotate=function(a,b){h.R.assert(null!=a.length);a.length&&(b%=a.length,0<b?Array.prototype.unshift.apply(a,a.splice(-b,b)):0>b&&Array.prototype.push.apply(a,a.splice(0,-b)));return a};h.aa.l9=function(a,b,c){h.R.assert(0<=b&&b<a.length);h.R.assert(0<=c&&c<a.length);b=Array.prototype.splice.call(a,b,1);Array.prototype.splice.call(a,c,0,b[0])};\nh.aa.zip=function(a){if(!arguments.length)return[];for(var b=[],c=arguments[0].length,e=1;e<arguments.length;e++)arguments[e].length<c&&(c=arguments[e].length);for(e=0;e<c;e++){for(var g=[],k=0;k<arguments.length;k++)g.push(arguments[k][e]);b.push(g)}return b};h.aa.shuffle=function(a,b){b=b||Math.random;for(var c=a.length-1;0<c;c--){var e=Math.floor(b()*(c+1)),g=a[c];a[c]=a[e];a[e]=g}};h.aa.i4=function(a,b){var c=[];h.aa.forEach(b,function(b){c.push(a[b])});return c};\nh.aa.Y3=function(a,b,c){return h.aa.concat.apply([],h.aa.map(a,b,c))};h.la.userAgent.platform={};h.la.userAgent.platform.mB=function(){return h.la.userAgent.util.lc(\"Android\")};h.la.userAgent.platform.js=function(){return h.la.userAgent.util.lc(\"iPod\")};h.la.userAgent.platform.hs=function(){return h.la.userAgent.util.lc(\"iPhone\")&&!h.la.userAgent.util.lc(\"iPod\")&&!h.la.userAgent.util.lc(\"iPad\")};h.la.userAgent.platform.gs=function(){return h.la.userAgent.util.lc(\"iPad\")};\nh.la.userAgent.platform.fs=function(){return h.la.userAgent.platform.hs()||h.la.userAgent.platform.gs()||h.la.userAgent.platform.js()};h.la.userAgent.platform.tB=function(){return h.la.userAgent.util.lc(\"Macintosh\")};h.la.userAgent.platform.wN=function(){return h.la.userAgent.util.lc(\"Linux\")};h.la.userAgent.platform.AB=function(){return h.la.userAgent.util.lc(\"Windows\")};h.la.userAgent.platform.oB=function(){return h.la.userAgent.util.lc(\"CrOS\")};\nh.la.userAgent.platform.getVersion=function(){var a=h.la.userAgent.util.nk(),b=\"\";h.la.userAgent.platform.AB()?(b=/Windows (?:NT|Phone) ([0-9.]+)/,b=(a=b.exec(a))?a[1]:\"0.0\"):h.la.userAgent.platform.fs()?(b=/(?:iPhone|iPod|iPad|CPU)\\s+OS\\s+(\\S+)/,b=(a=b.exec(a))&&a[1].replace(/_/g,\".\")):h.la.userAgent.platform.tB()?(b=/Mac OS X ([0-9_.]+)/,b=(a=b.exec(a))?a[1].replace(/_/g,\".\"):\"10\"):h.la.userAgent.platform.mB()?(b=/Android\\s+([^\\);]+)(\\)|;)/,b=(a=b.exec(a))&&a[1]):h.la.userAgent.platform.oB()&&(b=\n/(?:CrOS\\s+(?:i686|x86_64)\\s+([0-9.]+))/,b=(a=b.exec(a))&&a[1]);return b||\"\"};h.la.userAgent.platform.jm=function(a){return 0<=h.ca.yl(h.la.userAgent.platform.getVersion(),a)};h.cb={};h.cb.CC=function(a){for(var b=[],c=0,e=0;e<a.length;e++){for(var g=a.charCodeAt(e);255<g;)b[c++]=g&255,g>>=8;b[c++]=g}return b};h.cb.V2=function(a){if(8192>=a.length)return String.fromCharCode.apply(null,a);for(var b=\"\",c=0;c<a.length;c+=8192)var e=h.aa.slice(a,c,c+8192),b=b+String.fromCharCode.apply(null,e);return b};\nh.cb.U2=function(a){return h.aa.map(a,function(a){a=a.toString(16);return 1<a.length?a:\"0\"+a}).join(\"\")};h.cb.W6=function(a){h.R.assert(0==a.length%2,\"Key string length must be multiple of 2\");for(var b=[],c=0;c<a.length;c+=2)b.push(parseInt(a.substring(c,c+2),16));return b};\nh.cb.cca=function(a){for(var b=[],c=0,e=0;e<a.length;e++){var g=a.charCodeAt(e);128>g?b[c++]=g:(2048>g?b[c++]=g>>6|192:(55296==(g&64512)&&e+1<a.length&&56320==(a.charCodeAt(e+1)&64512)?(g=65536+((g&1023)<<10)+(a.charCodeAt(++e)&1023),b[c++]=g>>18|240,b[c++]=g>>12&63|128):b[c++]=g>>12|224,b[c++]=g>>6&63|128),b[c++]=g&63|128)}return b};\nh.cb.sda=function(a){for(var b=[],c=0,e=0;c<a.length;){var g=a[c++];if(128>g)b[e++]=String.fromCharCode(g);else if(191<g&&224>g){var k=a[c++];b[e++]=String.fromCharCode((g&31)<<6|k&63)}else if(239<g&&365>g){var k=a[c++],m=a[c++],n=a[c++],g=((g&7)<<18|(k&63)<<12|(m&63)<<6|n&63)-65536;b[e++]=String.fromCharCode(55296+(g>>10));b[e++]=String.fromCharCode(56320+(g&1023))}else k=a[c++],m=a[c++],b[e++]=String.fromCharCode((g&15)<<12|(k&63)<<6|m&63)}return b.join(\"\")};\nh.cb.Kda=function(a,b){h.R.assert(a.length==b.length,\"XOR array lengths must match\");for(var c=[],e=0;e<a.length;e++)c.push(a[e]^b[e]);return c};h.la.userAgent.fb={};h.la.userAgent.fb.LB=function(){return h.la.userAgent.util.lc(\"Opera\")};h.la.userAgent.fb.fO=function(){return h.la.userAgent.util.lc(\"Trident\")||h.la.userAgent.util.lc(\"MSIE\")};h.la.userAgent.fb.qs=function(){return h.la.userAgent.util.lc(\"Edge\")};h.la.userAgent.fb.eO=function(){return h.la.userAgent.util.lc(\"Firefox\")};\nh.la.userAgent.fb.MB=function(){return h.la.userAgent.util.lc(\"Safari\")&&!(h.la.userAgent.fb.os()||h.la.userAgent.fb.ps()||h.la.userAgent.fb.LB()||h.la.userAgent.fb.qs()||h.la.userAgent.fb.xB()||h.la.userAgent.util.lc(\"Android\"))};h.la.userAgent.fb.ps=function(){return h.la.userAgent.util.lc(\"Coast\")};h.la.userAgent.fb.gO=function(){return(h.la.userAgent.util.lc(\"iPad\")||h.la.userAgent.util.lc(\"iPhone\"))&&!h.la.userAgent.fb.MB()&&!h.la.userAgent.fb.os()&&!h.la.userAgent.fb.ps()&&h.la.userAgent.util.lc(\"AppleWebKit\")};\nh.la.userAgent.fb.os=function(){return(h.la.userAgent.util.lc(\"Chrome\")||h.la.userAgent.util.lc(\"CriOS\"))&&!h.la.userAgent.fb.qs()};h.la.userAgent.fb.dO=function(){return h.la.userAgent.util.lc(\"Android\")&&!(h.la.userAgent.fb.ds()||h.la.userAgent.fb.qB()||h.la.userAgent.fb.ks()||h.la.userAgent.fb.xB())};h.la.userAgent.fb.ks=h.la.userAgent.fb.LB;h.la.userAgent.fb.sB=h.la.userAgent.fb.fO;h.la.userAgent.fb.tk=h.la.userAgent.fb.qs;h.la.userAgent.fb.qB=h.la.userAgent.fb.eO;h.la.userAgent.fb.EN=h.la.userAgent.fb.MB;\nh.la.userAgent.fb.D7=h.la.userAgent.fb.ps;h.la.userAgent.fb.L7=h.la.userAgent.fb.gO;h.la.userAgent.fb.ds=h.la.userAgent.fb.os;h.la.userAgent.fb.lN=h.la.userAgent.fb.dO;h.la.userAgent.fb.xB=function(){return h.la.userAgent.util.lc(\"Silk\")};\nh.la.userAgent.fb.getVersion=function(){function a(a){a=h.aa.find(a,e);return c[a]||\"\"}var b=h.la.userAgent.util.nk();if(h.la.userAgent.fb.sB())return h.la.userAgent.fb.LL(b);var b=h.la.userAgent.util.Bx(b),c={};h.aa.forEach(b,function(a){var b=a[0];a=a[1];c[b]=a});var e=h.xs(h.object.dj,c);return h.la.userAgent.fb.ks()?a([\"Version\",\"Opera\"]):h.la.userAgent.fb.tk()?a([\"Edge\"]):h.la.userAgent.fb.ds()?a([\"Chrome\",\"CriOS\"]):(b=b[2])&&b[1]||\"\"};\nh.la.userAgent.fb.jm=function(a){return 0<=h.ca.yl(h.la.userAgent.fb.getVersion(),a)};h.la.userAgent.fb.LL=function(a){var b=/rv: *([\\d\\.]*)/.exec(a);if(b&&b[1])return b[1];var b=\"\",c=/MSIE +([\\d\\.]+)/.exec(a);if(c&&c[1])if(a=/Trident\\/(\\d.\\d)/.exec(a),\"7.0\"==c[1])if(a&&a[1])switch(a[1]){case \"4.0\":b=\"8.0\";break;case \"5.0\":b=\"9.0\";break;case \"6.0\":b=\"10.0\";break;case \"7.0\":b=\"11.0\"}else b=\"7.0\";else b=c[1];return b};h.la.userAgent.de={};h.la.userAgent.de.P7=function(){return h.la.userAgent.util.lc(\"Presto\")};\nh.la.userAgent.de.GN=function(){return h.la.userAgent.util.lc(\"Trident\")||h.la.userAgent.util.lc(\"MSIE\")};h.la.userAgent.de.tk=function(){return h.la.userAgent.util.lc(\"Edge\")};h.la.userAgent.de.zB=function(){return h.la.userAgent.util.hO(\"WebKit\")&&!h.la.userAgent.de.tk()};h.la.userAgent.de.sN=function(){return h.la.userAgent.util.lc(\"Gecko\")&&!h.la.userAgent.de.zB()&&!h.la.userAgent.de.GN()&&!h.la.userAgent.de.tk()};\nh.la.userAgent.de.getVersion=function(){var a=h.la.userAgent.util.nk();if(a){var a=h.la.userAgent.util.Bx(a),b=h.la.userAgent.de.yL(a);if(b)return\"Gecko\"==b[0]?h.la.userAgent.de.MM(a,\"Firefox\"):b[1];var a=a[0],c;if(a&&(c=a[2])&&(c=/Trident\\/([^\\s;]+)/.exec(c)))return c[1]}return\"\"};h.la.userAgent.de.yL=function(a){if(!h.la.userAgent.de.tk())return a[1];for(var b=0;b<a.length;b++){var c=a[b];if(\"Edge\"==c[0])return c}};\nh.la.userAgent.de.jm=function(a){return 0<=h.ca.yl(h.la.userAgent.de.getVersion(),a)};h.la.userAgent.de.MM=function(a,b){return(a=h.aa.find(a,function(a){return b==a[0]}))&&a[1]||\"\"};h.userAgent={};h.userAgent.jp=!1;h.userAgent.ip=!1;h.userAgent.Lt=!1;h.userAgent.Qt=!1;h.userAgent.lp=!1;h.userAgent.mp=!1;h.userAgent.UC=!1;h.userAgent.Fk=h.userAgent.jp||h.userAgent.ip||h.userAgent.Lt||h.userAgent.lp||h.userAgent.Qt||h.userAgent.mp;h.userAgent.KM=function(){return h.la.userAgent.util.nk()};\nh.userAgent.Dz=function(){return h.global.navigator||null};h.userAgent.cn=h.userAgent.Fk?h.userAgent.mp:h.la.userAgent.fb.ks();h.userAgent.Oh=h.userAgent.Fk?h.userAgent.jp:h.la.userAgent.fb.sB();h.userAgent.Rm=h.userAgent.Fk?h.userAgent.ip:h.la.userAgent.de.tk();h.userAgent.wX=h.userAgent.Rm||h.userAgent.Oh;h.userAgent.iu=h.userAgent.Fk?h.userAgent.Lt:h.la.userAgent.de.sN();h.userAgent.nn=h.userAgent.Fk?h.userAgent.Qt||h.userAgent.lp:h.la.userAgent.de.zB();\nh.userAgent.xN=function(){return h.userAgent.nn&&h.la.userAgent.util.lc(\"Mobile\")};h.userAgent.NY=h.userAgent.lp||h.userAgent.xN();h.userAgent.Np=h.userAgent.nn;h.userAgent.JK=function(){var a=h.userAgent.Dz();return a&&a.platform||\"\"};h.userAgent.gZ=h.userAgent.JK();h.userAgent.Nt=!1;h.userAgent.Rt=!1;h.userAgent.Mt=!1;h.userAgent.St=!1;h.userAgent.Dk=!1;h.userAgent.Dj=!1;h.userAgent.Cj=!1;h.userAgent.kp=!1;\nh.userAgent.nh=h.userAgent.Nt||h.userAgent.Rt||h.userAgent.Mt||h.userAgent.St||h.userAgent.Dk||h.userAgent.Dj||h.userAgent.Cj||h.userAgent.kp;h.userAgent.GY=h.userAgent.nh?h.userAgent.Nt:h.la.userAgent.platform.tB();h.userAgent.x_=h.userAgent.nh?h.userAgent.Rt:h.la.userAgent.platform.AB();h.userAgent.vN=function(){return h.la.userAgent.platform.wN()||h.la.userAgent.platform.oB()};h.userAgent.wY=h.userAgent.nh?h.userAgent.Mt:h.userAgent.vN();\nh.userAgent.KN=function(){var a=h.userAgent.Dz();return!!a&&h.ca.contains(a.appVersion||\"\",\"X11\")};h.userAgent.y_=h.userAgent.nh?h.userAgent.St:h.userAgent.KN();h.userAgent.TC=h.userAgent.nh?h.userAgent.Dk:h.la.userAgent.platform.mB();h.userAgent.OD=h.userAgent.nh?h.userAgent.Dj:h.la.userAgent.platform.hs();h.userAgent.ND=h.userAgent.nh?h.userAgent.Cj:h.la.userAgent.platform.gs();h.userAgent.jY=h.userAgent.nh?h.userAgent.kp:h.la.userAgent.platform.js();\nh.userAgent.iY=h.userAgent.nh?h.userAgent.Dj||h.userAgent.Cj||h.userAgent.kp:h.la.userAgent.platform.fs();h.userAgent.KK=function(){var a=\"\",b=h.userAgent.NM();b&&(a=b?b[1]:\"\");return h.userAgent.Oh&&(b=h.userAgent.Hy(),null!=b&&b>parseFloat(a))?String(b):a};\nh.userAgent.NM=function(){var a=h.userAgent.KM();if(h.userAgent.iu)return/rv\\:([^\\);]+)(\\)|;)/.exec(a);if(h.userAgent.Rm)return/Edge\\/([\\d\\.]+)/.exec(a);if(h.userAgent.Oh)return/\\b(?:MSIE|rv)[: ]([^\\);]+)(\\)|;)/.exec(a);if(h.userAgent.nn)return/WebKit\\/(\\S+)/.exec(a);if(h.userAgent.cn)return/(?:Version)[ \\/]?(\\S+)/.exec(a)};h.userAgent.Hy=function(){var a=h.global.document;return a?a.documentMode:void 0};h.userAgent.VERSION=h.userAgent.KK();h.userAgent.compare=function(a,b){return h.ca.yl(a,b)};\nh.userAgent.JN={};h.userAgent.jm=function(a){return h.userAgent.UC||h.Ih.cache(h.userAgent.JN,a,function(){return 0<=h.ca.yl(h.userAgent.VERSION,a)})};h.userAgent.U7=h.userAgent.jm;h.userAgent.qN=function(a){return Number(h.userAgent.jD)>=a};h.userAgent.G7=h.userAgent.qN;var ba;var ga=h.global.document,ud=h.userAgent.Hy();ba=ga&&h.userAgent.Oh?ud||(\"CSS1Compat\"==ga.compatMode?parseInt(h.userAgent.VERSION,10):5):void 0;h.userAgent.jD=ba;h.userAgent.product={};h.userAgent.product.Kt=!1;\nh.userAgent.product.Dj=!1;h.userAgent.product.Cj=!1;h.userAgent.product.Dk=!1;h.userAgent.product.Jt=!1;h.userAgent.product.Pt=!1;h.userAgent.product.Lj=h.userAgent.jp||h.userAgent.ip||h.userAgent.mp||h.userAgent.product.Kt||h.userAgent.product.Dj||h.userAgent.product.Cj||h.userAgent.product.Dk||h.userAgent.product.Jt||h.userAgent.product.Pt;h.userAgent.product.cn=h.userAgent.cn;h.userAgent.product.Oh=h.userAgent.Oh;h.userAgent.product.Rm=h.userAgent.Rm;\nh.userAgent.product.OX=h.userAgent.product.Lj?h.userAgent.product.Kt:h.la.userAgent.fb.qB();h.userAgent.product.tN=function(){return h.la.userAgent.platform.hs()||h.la.userAgent.platform.js()};h.userAgent.product.OD=h.userAgent.product.Lj?h.userAgent.product.Dj:h.userAgent.product.tN();h.userAgent.product.ND=h.userAgent.product.Lj?h.userAgent.product.Cj:h.la.userAgent.platform.gs();h.userAgent.product.TC=h.userAgent.product.Lj?h.userAgent.product.Dk:h.la.userAgent.fb.lN();\nh.userAgent.product.dX=h.userAgent.product.Lj?h.userAgent.product.Jt:h.la.userAgent.fb.ds();h.userAgent.product.FN=function(){return h.la.userAgent.fb.EN()&&!h.la.userAgent.platform.fs()};h.userAgent.product.Np=h.userAgent.product.Lj?h.userAgent.product.Pt:h.userAgent.product.FN();h.cb.pb={};h.cb.pb.xl=null;h.cb.pb.fo=null;h.cb.pb.gr=null;h.cb.pb.rp=\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\";h.cb.pb.cu=h.cb.pb.rp+\"+/\\x3d\";h.cb.pb.du=h.cb.pb.rp+\"-_.\";\nh.cb.pb.Ot=h.userAgent.iu||h.userAgent.nn&&!h.userAgent.product.Np||h.userAgent.cn;h.cb.pb.DD=h.cb.pb.Ot||\"function\"==typeof h.global.btoa;h.cb.pb.CD=h.cb.pb.Ot||!h.userAgent.product.Np&&!h.userAgent.Oh&&\"function\"==typeof h.global.atob;\nh.cb.pb.ur=function(a,b){h.R.assert(h.Gd(a),\"encodeByteArray takes an array as a parameter\");h.cb.pb.hm();b=b?h.cb.pb.gr:h.cb.pb.xl;for(var c=[],e=0;e<a.length;e+=3){var g=a[e],k=e+1<a.length,m=k?a[e+1]:0,n=e+2<a.length,q=n?a[e+2]:0,v=g>>2,g=(g&3)<<4|m>>4,m=(m&15)<<2|q>>6,q=q&63;n||(q=64,k||(m=64));c.push(b[v],b[g],b[m],b[q])}return c.join(\"\")};h.cb.pb.o5=function(a,b){return h.cb.pb.DD&&!b?h.global.btoa(a):h.cb.pb.ur(h.cb.CC(a),b)};\nh.cb.pb.T4=function(a,b){function c(a){e+=String.fromCharCode(a)}if(h.cb.pb.CD&&!b)return h.global.atob(a);var e=\"\";h.cb.pb.rr(a,c);return e};h.cb.pb.U4=function(a){function b(a){c.push(a)}var c=[];h.cb.pb.rr(a,b);return c};h.cb.pb.qx=function(a){function b(a){c[e++]=a}h.R.assert(!h.userAgent.Oh||h.userAgent.jm(\"10\"),\"Browser does not support typed arrays\");var c=new Uint8Array(Math.ceil(3*a.length/4)),e=0;h.cb.pb.rr(a,b);return c.subarray(0,e)};\nh.cb.pb.rr=function(a,b){function c(b){for(;e<a.length;){var c=a.charAt(e++),g=h.cb.pb.fo[c];if(null!=g)return g;if(!h.ca.Co(c))throw Error(\"Unknown base64 encoding at char: \"+c);}return b}h.cb.pb.hm();for(var e=0;;){var g=c(-1),k=c(0),m=c(64),n=c(64);if(64===n&&-1===g)break;g=g<<2|k>>4;b(g);64!=m&&(k=k<<4&240|m>>2,b(k),64!=n&&(m=m<<6&192|n,b(m)))}};\nh.cb.pb.hm=function(){if(!h.cb.pb.xl){h.cb.pb.xl={};h.cb.pb.fo={};h.cb.pb.gr={};for(var a=0;a<h.cb.pb.cu.length;a++)h.cb.pb.xl[a]=h.cb.pb.cu.charAt(a),h.cb.pb.fo[h.cb.pb.xl[a]]=a,h.cb.pb.gr[a]=h.cb.pb.du.charAt(a),a>=h.cb.pb.rp.length&&(h.cb.pb.fo[h.cb.pb.du.charAt(a)]=a)}};l.O={};l.O.Oc=0;l.O.Wc=0;l.O.zC=function(a){var b=a>>>0;a=Math.floor((a-b)/l.xa.Xf)>>>0;l.O.Oc=b;l.O.Wc=a};\nl.O.$o=function(a){var b=0>a;a=Math.abs(a);var c=a>>>0;a=Math.floor((a-c)/l.xa.Xf);a>>>=0;b&&(a=~a>>>0,c=~c>>>0,c+=1,4294967295<c&&(c=0,a++,4294967295<a&&(a=0)));l.O.Oc=c;l.O.Wc=a};l.O.Iba=function(a){var b=0>a;a=2*Math.abs(a);l.O.zC(a);a=l.O.Oc;var c=l.O.Wc;b&&(0==a?0==c?c=a=4294967295:(c--,a=4294967295):a--);l.O.Oc=a;l.O.Wc=c};\nl.O.cW=function(a){var b=0>a?1:0;a=b?-a:a;var c;0===a?0<1/a?(l.O.Wc=0,l.O.Oc=0):(l.O.Wc=0,l.O.Oc=2147483648):isNaN(a)?(l.O.Wc=0,l.O.Oc=2147483647):a>l.xa.vp?(l.O.Wc=0,l.O.Oc=(b<<31|2139095040)>>>0):a<l.xa.sD?(a=Math.round(a/Math.pow(2,-149)),l.O.Wc=0,l.O.Oc=(b<<31|a)>>>0):(c=Math.floor(Math.log(a)/Math.LN2),a*=Math.pow(2,-c),a=Math.round(a*l.xa.KE)&8388607,l.O.Wc=0,l.O.Oc=(b<<31|c+127<<23|a)>>>0)};\nl.O.dW=function(a){var b=0>a?1:0;a=b?-a:a;if(0===a)l.O.Wc=0<1/a?0:2147483648,l.O.Oc=0;else if(isNaN(a))l.O.Wc=2147483647,l.O.Oc=4294967295;else if(a>l.xa.wp)l.O.Wc=(b<<31|2146435072)>>>0,l.O.Oc=0;else if(a<l.xa.tD){var c=a/Math.pow(2,-1074);a=c/l.xa.Xf;l.O.Wc=(b<<31|a)>>>0;l.O.Oc=c>>>0}else{var e=Math.floor(Math.log(a)/Math.LN2);1024==e&&(e=1023);c=a*Math.pow(2,-e);a=c*l.xa.JE&1048575;c=c*l.xa.ev>>>0;l.O.Wc=(b<<31|e+1023<<20|a)>>>0;l.O.Oc=c}};\nl.O.ut=function(a){var b=a.charCodeAt(0),c=a.charCodeAt(1),e=a.charCodeAt(2),g=a.charCodeAt(3),k=a.charCodeAt(4),m=a.charCodeAt(5),n=a.charCodeAt(6);a=a.charCodeAt(7);l.O.Oc=b+(c<<8)+(e<<16)+(g<<24)>>>0;l.O.Wc=k+(m<<8)+(n<<16)+(a<<24)>>>0};l.O.km=function(a,b){return b*l.xa.Xf+a};l.O.ls=function(a,b){var c=b&2147483648;c&&(a=~a+1>>>0,b=~b>>>0,0==a&&(b=b+1>>>0));a=l.O.km(a,b);return c?-a:a};\nl.O.X7=function(a,b){var c=a&1;a=(a>>>1|b<<31)>>>0;b>>>=1;c&&(a=a+1>>>0,0==a&&(b=b+1>>>0));a=l.O.km(a,b);return c?-a:a};l.O.ON=function(a){var b=2*(a>>31)+1,c=a>>>23&255;a&=8388607;return 255==c?a?NaN:Infinity*b:0==c?b*Math.pow(2,-149)*a:b*Math.pow(2,c-150)*(a+Math.pow(2,23))};l.O.PN=function(a,b){var c=2*(b>>31)+1,e=b>>>20&2047;a=l.xa.Xf*(b&1048575)+a;return 2047==e?a?NaN:Infinity*c:0==e?c*Math.pow(2,-1074)*a:c*Math.pow(2,e-1075)*(a+l.xa.ev)};\nl.O.QN=function(a,b){var c=a>>>0&255,e=a>>>8&255,g=a>>>16&255;a=a>>>24&255;var k=b>>>0&255,m=b>>>8&255,n=b>>>16&255;b=b>>>24&255;return String.fromCharCode(c,e,g,a,k,m,n,b)};l.O.Ej=\"0123456789abcdef\".split(\"\");\nl.O.BB=function(a,b){function c(a){for(var b=1E7,c=0;7>c;c++){var b=b/10,e=a/b%10>>>0;if(0!=e||k)k=!0,m+=g[e]}}if(2097151>=b)return\"\"+(l.xa.Xf*b+a);var e=a&16777215;a=(a>>>24|b<<8)>>>0&16777215;b=b>>16&65535;e=e+6777216*a+6710656*b;a+=8147497*b;b*=2;1E7<=e&&(a+=Math.floor(e/1E7),e%=1E7);1E7<=a&&(b+=Math.floor(a/1E7),a%=1E7);var g=l.O.Ej,k=!1,m=\"\";(b||k)&&c(b);(a||k)&&c(a);(e||k)&&c(e);return m};\nl.O.RN=function(a,b){var c=b&2147483648;if(c){a=~a+1>>>0;var e=0==a?1:0;b=~b+e>>>0}a=l.O.BB(a,b);return c?\"-\"+a:a};l.O.YM=function(a,b){l.O.ut(a);a=l.O.Oc;var c=l.O.Wc;return b?l.O.RN(a,c):l.O.BB(a,c)};l.O.R6=function(a,b){for(var c=Array(a.length),e=0;e<a.length;e++)c[e]=l.O.YM(a[e],b);return c};\nl.O.FK=function(a){function b(a,b){for(var c=0;8>c&&(1!==a||0<b);c++)b=a*g[c]+b,g[c]=b&255,b>>>=8}function c(){for(var a=0;8>a;a++)g[a]=~g[a]&255}h.R.assert(0<a.length);var e=!1;\"-\"===a[0]&&(e=!0,a=a.slice(1));for(var g=[0,0,0,0,0,0,0,0],k=0;k<a.length;k++)b(10,l.O.Ej.indexOf(a[k]));e&&(c(),b(1,1));return String.fromCharCode.apply(null,g)};l.O.Gba=function(a){l.O.ut(l.O.FK(a))};\nl.O.S6=function(a){var b=Array(18);b[0]=\"0\";b[1]=\"x\";for(var c=0;8>c;c++){var e=a.charCodeAt(7-c);b[2*c+2]=l.O.Ej[e>>4];b[2*c+3]=l.O.Ej[e&15]}return a=b.join(\"\")};l.O.V6=function(a){a=a.toLowerCase();h.R.assert(18==a.length);h.R.assert(\"0\"==a[0]);h.R.assert(\"x\"==a[1]);for(var b=\"\",c=0;8>c;c++)var e=l.O.Ej.indexOf(a[2*c+2]),g=l.O.Ej.indexOf(a[2*c+3]),b=String.fromCharCode(16*e+g)+b;return b};l.O.T6=function(a,b){l.O.ut(a);a=l.O.Oc;var c=l.O.Wc;return b?l.O.ls(a,c):l.O.km(a,c)};\nl.O.Y9=function(a){l.O.$o(a);return l.O.QN(l.O.Oc,l.O.Wc)};l.O.s4=function(a,b,c){for(var e=0,g=b;g<c;g++)e+=a[g]>>7;return c-b-e};l.O.r4=function(a,b,c,e){var g=0;e=8*e+l.xa.kb.Xe;if(128>e)for(;b<c&&a[b++]==e;)for(g++;;){var k=a[b++];if(0==(k&128))break}else for(;b<c;){for(k=e;128<k;){if(a[b]!=(k&127|128))return g;b++;k>>=7}if(a[b++]!=k)break;for(g++;k=a[b++],0!=(k&128););}return g};\nl.O.kx=function(a,b,c,e,g){var k=0;if(128>e)for(;b<c&&a[b++]==e;)k++,b+=g;else for(;b<c;){for(var m=e;128<m;){if(a[b++]!=(m&127|128))return k;m>>=7}if(a[b++]!=m)break;k++;b+=g}return k};l.O.n4=function(a,b,c,e){e=8*e+l.xa.kb.hh;return l.O.kx(a,b,c,e,4)};l.O.o4=function(a,b,c,e){e=8*e+l.xa.kb.ih;return l.O.kx(a,b,c,e,8)};\nl.O.m4=function(a,b,c,e){var g=0;for(e=8*e+l.xa.kb.jg;b<c;){for(var k=e;128<k;){if(a[b++]!=(k&127|128))return g;k>>=7}if(a[b++]!=k)break;g++;for(var m=0,n=1;k=a[b++],m+=(k&127)*n,n*=128,0!=(k&128););b+=m}return g};l.O.R4=function(a){var b='\"';if(a){a=l.O.fr(a);for(var c=0;c<a.length;c++)b+=\"\\\\x\",16>a[c]&&(b+=\"0\"),b+=a[c].toString(16)}return b+'\"'};l.O.S4=function(a){return h.Hb(a)?h.ca.quote(a):a.toString()};\nl.O.CC=function(a){for(var b=new Uint8Array(a.length),c=0;c<a.length;c++){var e=a.charCodeAt(c);if(255<e)throw Error(\"Conversion error: string contains codepoint outside of byte range\");b[c]=e}return b};l.O.fr=function(a){if(a.constructor===Uint8Array)return a;if(a.constructor===ArrayBuffer)return new Uint8Array(a);if(a.constructor===Array)return new Uint8Array(a);if(a.constructor===String)return h.cb.pb.qx(a);h.R.fail(\"Type not convertible to Uint8Array.\");return new Uint8Array(0)};\nl.Di=function(a,b,c,e,g){this.qo=a;this.Ex=b;this.ctor=c;this.xt=e;this.Eo=g};l.Fj=function(a,b,c,e,g,k){this.Dx=a;this.br=b;this.cr=c;this.Rw=e;this.UJ=g;this.AN=k};l.Di.prototype.uk=function(){return!!this.ctor};l.u=function(){};l.u.ha=!0;l.u.VX=!h.$t;l.u.AD=!0;l.u.VC=!1;l.u.$m=!0;l.u.Vk=\"function\"==typeof Uint8Array;l.u.Sl=function(a,b){return b+a.Iw};\nl.u.initialize=function(a,b,c,e,g,k){a.tb=l.u.$m?null:{};b||(b=c?[c]:[]);a.OB=c?String(c):void 0;a.Iw=0===c?-1:0;a.aa=b;l.u.iO(a,e);a.lo={};if(g)for(b=0;b<g.length;b++)c=g[b],c<a.wk?(c=l.u.Sl(a,c),a.aa[c]=a.aa[c]||(l.u.$m?l.u.Ik:[])):a.Oe[c]=a.Oe[c]||(l.u.$m?l.u.Ik:[]);k&&k.length&&h.aa.forEach(k,h.xs(l.u.ex,a))};l.u.Ik=h.Mh&&Object.freeze?Object.freeze([]):[];l.u.oN=function(a){return l.u.VC?a instanceof Array:h.isArray(a)};\nl.u.iO=function(a,b){if(a.aa.length){var c=a.aa.length-1,e=a.aa[c];if(e&&\"object\"==typeof e&&!l.u.oN(e)&&!(l.u.Vk&&e instanceof Uint8Array)){a.wk=c-a.Iw;a.Oe=e;return}}-1<b?(a.wk=b,b=l.u.Sl(a,b),a.Oe=l.u.$m?null:a.aa[b]={}):a.wk=Number.MAX_VALUE};l.u.kO=function(a){var b=l.u.Sl(a,a.wk);a.aa[b]||(a.Oe=a.aa[b]={})};l.u.Ka=function(a,b,c){for(var e=[],g=0;g<a.length;g++)e[g]=b.call(a[g],c,a[g]);return e};\nl.u.pW=function(a,b,c,e,g){for(var k in c){var m=c[k],n=e.call(a,m);if(n){for(var q in m.Ex)if(m.Ex.hasOwnProperty(q))break;b[q]=m.xt?m.Eo?l.u.Ka(n,m.xt,g):m.xt(g,n):n}}};\nl.u.XP=function(a,b,c,e){for(var g in c){var k=c[g],m=k.Dx;if(!k.cr)throw Error(\"Message extension present that was generated without binary serialization support\");var n=e.call(a,m);if(n)if(m.uk())if(k.Rw)k.cr.call(b,m.qo,n,k.Rw);else throw Error(\"Message extension present holding submessage without binary support enabled, and message is being serialized to binary format\");else k.cr.call(b,m.qo,n)}};\nl.u.kP=function(a,b,c,e,g){var k=c[b.ka];if(k){c=k.Dx;if(!k.br)throw Error(\"Deserializing extension whose generated code does not support binary format\");var m;c.uk()?(m=new c.ctor,k.br.call(b,m,k.UJ)):m=k.br.call(b);c.Eo&&!k.AN?(b=e.call(a,c))?b.push(m):g.call(a,c,[m]):g.call(a,c,m)}else b.ea()};l.u.D=function(a,b){if(b<a.wk){b=l.u.Sl(a,b);var c=a.aa[b];return c===l.u.Ik?a.aa[b]=[]:c}c=a.Oe[b];return c===l.u.Ik?a.Oe[b]=[]:c};l.u.Na=function(a,b){a=l.u.D(a,b);return null==a?a:+a};\nl.u.gb=function(a,b){var c=l.u.D(a,b);a.lo||(a.lo={});if(!a.lo[b]){for(var e=0;e<c.length;e++)c[e]=+c[e];a.lo[b]=!0}return c};l.u.ao=function(a){if(null==a||h.Hb(a))return a;if(l.u.Vk&&a instanceof Uint8Array)return h.cb.pb.ur(a);h.R.fail(\"Cannot coerce to b64 string: \"+h.df(a));return null};l.u.hr=function(a){if(null==a||a instanceof Uint8Array)return a;if(h.Hb(a))return h.cb.pb.qx(a);h.R.fail(\"Cannot coerce to Uint8Array: \"+h.df(a));return null};\nl.u.W2=function(a){l.u.Kw(a);return!a.length||h.Hb(a[0])?a:h.aa.map(a,l.u.ao)};l.u.X2=function(a){l.u.Kw(a);return!a.length||a[0]instanceof Uint8Array?a:h.aa.map(a,l.u.hr)};l.u.Kw=function(a){if(h.Mh&&a&&1<a.length){var b=h.df(a[0]);h.aa.forEach(a,function(a){h.df(a)!=b&&h.R.fail(\"Inconsistent type in JSPB repeated field array. Got \"+h.df(a)+\" expected \"+b)})}};l.u.va=function(a,b,c){a=l.u.D(a,b);return null==a?c:a};l.u.s6=l.u.va;\nl.u.z6=function(a,b,c,e){a.tb||(a.tb={});if(b in a.tb)return a.tb[b];if(!c)return c=l.u.D(a,b),c||(c=[],l.u.J(a,b,c)),a.tb[b]=new l.Map(c,e)};l.u.J=function(a,b,c){b<a.wk?a.aa[l.u.Sl(a,b)]=c:a.Oe[b]=c};l.u.ib=function(a,b,c,e){a=l.u.D(a,b);void 0!=e?a.splice(e,0,c):a.push(c)};l.u.vC=function(a,b,c,e){(c=l.u.ex(a,c))&&c!==b&&void 0!==e&&(a.tb&&c in a.tb&&(a.tb[c]=void 0),l.u.J(a,c,void 0));l.u.J(a,b,e)};\nl.u.ex=function(a,b){var c,e;h.aa.forEach(b,function(b){var g=l.u.D(a,b);h.Ch(g)&&(c=b,e=g,l.u.J(a,b,void 0))});return c?(l.u.J(a,c,e),c):0};l.u.sa=function(a,b,c,e){a.tb||(a.tb={});if(!a.tb[c]){var g=l.u.D(a,c);if(e||g)a.tb[c]=new b(g)}return a.tb[c]};l.u.Ma=function(a,b,c){l.u.NC(a,b,c);b=a.tb[c];b==l.u.Ik&&(b=a.tb[c]=[]);return b};l.u.NC=function(a,b,c){a.tb||(a.tb={});if(!a.tb[c]){for(var e=l.u.D(a,c),g=[],k=0;k<e.length;k++)g[k]=new b(e[k]);a.tb[c]=g}};\nl.u.Ca=function(a,b,c){a.tb||(a.tb={});var e=c?c.toArray():c;a.tb[b]=c;l.u.J(a,b,e)};l.u.Nc=function(a,b,c,e){a.tb||(a.tb={});var g=e?e.toArray():e;a.tb[b]=e;l.u.vC(a,b,c,g)};l.u.mt=function(a,b,c){a.tb||(a.tb={});c=c||[];for(var e=[],g=0;g<c.length;g++)e[g]=c[g].toArray();a.tb[b]=c;l.u.J(a,b,e)};l.u.La=function(a,b,c,e,g){l.u.NC(a,e,b);var k=a.tb[b];k||(k=a.tb[b]=[]);c=c?c:new e;a=l.u.D(a,b);void 0!=g?(k.splice(g,0,c),a.splice(g,0,c.toArray())):(k.push(c),a.push(c.toArray()));return c};\nl.u.Cca=function(a,b,c,e){for(var g={},k=0;k<a.length;k++)g[b.call(a[k])]=c?c.call(a[k],e,a[k]):a[k];return g};l.u.prototype.DC=function(){if(this.tb)for(var a in this.tb){var b=this.tb[a];if(h.isArray(b))for(var c=0;c<b.length;c++)b[c]&&b[c].toArray();else b&&b.toArray()}};l.u.prototype.toArray=function(){this.DC();return this.aa};l.u.bn=h.global.JSON&&h.global.JSON.stringify||\"object\"===typeof JSON&&JSON.stringify;\nl.u.prototype.serialize=l.u.Vk?function(){h.R.assert(l.u.bn);var a=Uint8Array.prototype.toJSON;Uint8Array.prototype.toJSON=function(){return h.cb.pb.ur(this)};try{var b=l.u.bn.call(null,this.toArray(),l.u.Js)}finally{Uint8Array.prototype.toJSON=a}return b}:l.u.bn?function(){return l.u.bn.call(null,this.toArray(),l.u.Js)}:function(){return h.json.serialize(this.toArray(),l.u.Js)};l.u.Js=function(a,b){if(h.ni(b)){if(isNaN(b))return\"NaN\";if(Infinity===b)return\"Infinity\";if(-Infinity===b)return\"-Infinity\"}return b};\nl.u.K=function(a,b){a=new a(h.json.yW(b));h.R.Xq(a,l.u);return a};l.u.R2=function(a){var b=l.u.eC[a[0]];if(!b)throw Error(\"Unknown JsPb message type: \"+a[0]);return new b(a)};l.u.AD&&(l.u.prototype.toString=function(){this.DC();return this.aa.toString()});\nl.u.prototype.getExtension=function(a){if(this.Oe){this.tb||(this.tb={});var b=a.qo;if(a.Eo){if(a.uk())return this.tb[b]||(this.tb[b]=h.aa.map(this.Oe[b]||[],function(b){return new a.ctor(b)})),this.tb[b]}else if(a.uk())return!this.tb[b]&&this.Oe[b]&&(this.tb[b]=new a.ctor(this.Oe[b])),this.tb[b];return this.Oe[b]}};\nl.u.prototype.yR=function(a,b){var c=this;c.tb||(c.tb={});l.u.kO(c);var e=a.qo;a.Eo?(b=b||[],a.uk()?(c.tb[e]=b,c.Oe[e]=h.aa.map(b,function(a){return a.toArray()})):c.Oe[e]=b):a.uk()?(c.tb[e]=b,c.Oe[e]=b?b.toArray():b):c.Oe[e]=b;return c};l.u.a5=function(a,b){if(!(a instanceof b.constructor))throw Error(\"Messages have different types.\");var c=a.toArray();b=b.toArray();var e=[],g=0,k=c.length>b.length?c.length:b.length;a.OB&&(e[0]=a.OB,g=1);for(;g<k;g++)l.u.jo(c[g],b[g])||(e[g]=b[g]);return new a.constructor(e)};\nl.u.ii=function(a,b){return a==b||!(!a||!b)&&a instanceof b.constructor&&l.u.jo(a.toArray(),b.toArray())};l.u.bx=function(a,b){a=a||{};b=b||{};var c={},e;for(e in a)c[e]=0;for(e in b)c[e]=0;for(e in c)if(!l.u.jo(a[e],b[e]))return!1;return!0};\nl.u.jo=function(a,b){if(a==b)return!0;if(!h.mj(a)||!h.mj(b)||a.constructor!=b.constructor)return!1;if(l.u.Vk&&a.constructor===Uint8Array){if(a.length!=b.length)return!1;for(var c=0;c<a.length;c++)if(a[c]!=b[c])return!1;return!0}if(a.constructor===Array){for(var e=void 0,g=void 0,k=Math.max(a.length,b.length),c=0;c<k;c++){var m=a[c],n=b[c];m&&m.constructor==Object&&(h.R.assert(void 0===e),h.R.assert(c===a.length-1),e=m,m=void 0);n&&n.constructor==Object&&(h.R.assert(void 0===g),h.R.assert(c===b.length-\n1),g=n,n=void 0);if(!l.u.jo(m,n))return!1}return e||g?(e=e||{},g=g||{},l.u.bx(e,g)):!0}if(a.constructor===Object)return l.u.bx(a,b);throw Error(\"Invalid type in JSPB array\");};l.u.prototype.ho=function(){return l.u.ho(this)};l.u.prototype.clone=function(){return l.u.ho(this)};l.u.clone=function(a){return l.u.ho(a)};l.u.ho=function(a){return new a.constructor(l.u.ir(a.toArray()))};\nl.u.j4=function(a,b){h.R.Xq(a,l.u);h.R.Xq(b,l.u);h.R.assert(a.constructor==b.constructor,\"Copy source and target message should have the same type.\");a=l.u.clone(a);for(var c=b.toArray(),e=a.toArray(),g=c.length=0;g<e.length;g++)c[g]=e[g];b.tb=a.tb;b.Oe=a.Oe};\nl.u.ir=function(a){var b;if(h.isArray(a)){for(var c=Array(a.length),e=0;e<a.length;e++)null!=(b=a[e])&&(c[e]=\"object\"==typeof b?l.u.ir(b):b);return c}if(l.u.Vk&&a instanceof Uint8Array)return new Uint8Array(a);c={};for(e in a)null!=(b=a[e])&&(c[e]=\"object\"==typeof b?l.u.ir(b):b);return c};l.u.taa=function(a,b){l.u.eC[a]=b;b.I8=a};l.u.eC={};l.u.nj={};l.u.oi={};l.fh=function(a,b,c){this.gk=this.vs=this.vb=null;this.Wa=0;this.pi=null;this.vl=!0;this.hm(a,b,c)};\nl.fh.prototype.hm=function(a,b,c){a&&b&&(this.vb=a,this.vs=b);this.gk=c||null;this.Wa=0;this.pi=null;this.vl=!this.vb&&!this.gk;this.next()};l.fh.Nf=[];l.fh.ck=function(a,b,c){if(l.fh.Nf.length){var e=l.fh.Nf.pop();e.hm(a,b,c);return e}return new l.fh(a,b,c)};d=l.fh.prototype;d.Br=function(){this.clear();100>l.fh.Nf.length&&l.fh.Nf.push(this)};d.clear=function(){this.vb&&this.vb.Br();this.gk=this.vs=this.vb=null;this.Wa=0;this.pi=null;this.vl=!0};d.get=function(){return this.pi};d.Yq=function(){return this.vl};\nd.next=function(){var a=this.pi;this.vb?this.vb.Yq()?(this.pi=null,this.vl=!0):this.pi=this.vs.call(this.vb):this.gk&&(this.Wa==this.gk.length?(this.pi=null,this.vl=!0):this.pi=this.gk[this.Wa++]);return a};l.vg=function(a,b,c){this.Ed=null;this.Em=this.Fm=this.Wa=this.$e=this.yj=0;this.tg=!1;a&&this.vm(a,b,c)};l.vg.Nf=[];l.vg.ck=function(a,b,c){if(l.vg.Nf.length){var e=l.vg.Nf.pop();a&&e.vm(a,b,c);return e}return new l.vg(a,b,c)};d=l.vg.prototype;\nd.Br=function(){this.clear();100>l.vg.Nf.length&&l.vg.Nf.push(this)};d.clone=function(){return l.vg.ck(this.Ed,this.yj,this.$e-this.yj)};d.clear=function(){this.Ed=null;this.Wa=this.$e=this.yj=0;this.tg=!1};d.vm=function(a,b,c){this.Ed=l.O.fr(a);this.yj=h.Pe(b)?b:0;this.$e=h.Pe(c)?this.yj+c:this.Ed.length;this.Wa=this.yj};d.setEnd=function(a){this.$e=a};d.reset=function(){this.Wa=this.yj};d.Ol=function(){return this.Wa};d.YQ=function(a){this.Wa=a};\nd.advance=function(a){this.Wa+=a;h.R.assert(this.Wa<=this.$e)};d.Yq=function(){return this.Wa==this.$e};d.getError=function(){return this.tg||0>this.Wa||this.Wa>this.$e};\nd.dC=function(){for(var a,b=0,c=0,e=0;4>e;e++)if(a=this.Ed[this.Wa++],b|=(a&127)<<7*e,128>a){this.Fm=b>>>0;this.Em=0;return}a=this.Ed[this.Wa++];b|=(a&127)<<28;c|=(a&127)>>4;if(128>a)this.Fm=b>>>0,this.Em=c>>>0;else{for(e=0;5>e;e++)if(a=this.Ed[this.Wa++],c|=(a&127)<<7*e+3,128>a){this.Fm=b>>>0;this.Em=c>>>0;return}h.R.fail(\"Failed to read varint, encoding is invalid.\");this.tg=!0}};d.$V=function(){for(;this.Ed[this.Wa]&128;)this.Wa++;this.Wa++};\nd.Hh=function(){var a,b=this.Ed;a=b[this.Wa+0];var c=a&127;if(128>a)return this.Wa+=1,h.R.assert(this.Wa<=this.$e),c;a=b[this.Wa+1];c|=(a&127)<<7;if(128>a)return this.Wa+=2,h.R.assert(this.Wa<=this.$e),c;a=b[this.Wa+2];c|=(a&127)<<14;if(128>a)return this.Wa+=3,h.R.assert(this.Wa<=this.$e),c;a=b[this.Wa+3];c|=(a&127)<<21;if(128>a)return this.Wa+=4,h.R.assert(this.Wa<=this.$e),c;a=b[this.Wa+4];c|=(a&15)<<28;if(128>a)return h.R.assert(0==(a&240)),this.Wa+=5,h.R.assert(this.Wa<=this.$e),c>>>0;h.R.assert(240==\n(a&240));h.R.assert(255==b[this.Wa+5]);h.R.assert(255==b[this.Wa+6]);h.R.assert(255==b[this.Wa+7]);h.R.assert(255==b[this.Wa+8]);h.R.assert(1==b[this.Wa+9]);this.Wa+=10;h.R.assert(this.Wa<=this.$e);return c};d.bC=l.vg.prototype.Hh;d.nP=function(){this.dC();return l.O.km(this.Fm,this.Em)};d.cC=function(){this.dC();return l.O.ls(this.Fm,this.Em)};\nd.Jg=function(){var a=this.Ed[this.Wa+0],b=this.Ed[this.Wa+1],c=this.Ed[this.Wa+2],e=this.Ed[this.Wa+3];this.Wa+=4;h.R.assert(this.Wa<=this.$e);return(a<<0|b<<8|c<<16|e<<24)>>>0};d.ee=function(){var a=this.Jg(),b=this.Jg();return l.O.km(a,b)};d.Ya=function(){var a=this.Ed[this.Wa+0],b=this.Ed[this.Wa+1],c=this.Ed[this.Wa+2],e=this.Ed[this.Wa+3];this.Wa+=4;h.R.assert(this.Wa<=this.$e);return a<<0|b<<8|c<<16|e<<24};d.ad=function(){var a=this.Jg(),b=this.Jg();return l.O.ls(a,b)};\nd.ti=function(){var a=this.Jg();return l.O.ON(a,0)};d.pa=function(){var a=this.Jg(),b=this.Jg();return l.O.PN(a,b)};d.vf=function(){return!!this.Ed[this.Wa++]};d.we=function(){return this.bC()};\nd.Aa=function(a){var b=this.Ed,c=this.Wa;a=c+a;for(var e=[],g=\"\";c<a;){var k=b[c++];if(128>k)e.push(k);else if(192>k)continue;else if(224>k){var m=b[c++];e.push((k&31)<<6|m&63)}else if(240>k){var m=b[c++],n=b[c++];e.push((k&15)<<12|(m&63)<<6|n&63)}else if(248>k){var m=b[c++],n=b[c++],q=b[c++],m=(k&7)<<18|(m&63)<<12|(n&63)<<6|q&63,m=m-65536,k=(m&1023)+56320,m=(m>>10&1023)+55296;e.push(m,k)}8192<=e.length&&(g+=String.fromCharCode.apply(null,e),e.length=0)}g+=String.fromCharCode.apply(null,e);this.Wa=\nc;return g};d.qm=function(a){if(0>a||this.Wa+a>this.Ed.length)return this.tg=!0,h.R.fail(\"Invalid byte length!\"),new Uint8Array(0);var b=this.Ed.subarray(this.Wa,this.Wa+a);this.Wa+=a;h.R.assert(this.Wa<=this.$e);return b};l.Tt=function(){this.hc=[]};d=l.Tt.prototype;d.length=function(){return this.hc.length};d.end=function(){var a=this.hc;this.hc=[];return a};\nd.QC=function(a,b){h.R.assert(a==Math.floor(a));h.R.assert(b==Math.floor(b));h.R.assert(0<=a&&a<l.xa.Xf);for(h.R.assert(0<=b&&b<l.xa.Xf);0<b||127<a;)this.hc.push(a&127|128),a=(a>>>7|b<<25)>>>0,b>>>=7;this.hc.push(a)};d.MW=function(a,b){h.R.assert(a==Math.floor(a));h.R.assert(b==Math.floor(b));h.R.assert(0<=a&&a<l.xa.Xf);h.R.assert(0<=b&&b<l.xa.Xf);this.Pg(a);this.Pg(b)};d.Nm=function(a){h.R.assert(a==Math.floor(a));for(h.R.assert(0<=a&&a<l.xa.Xf);127<a;)this.hc.push(a&127|128),a>>>=7;this.hc.push(a)};\nd.Ft=function(a){h.R.assert(a==Math.floor(a));h.R.assert(a>=-l.xa.Tg&&a<l.xa.Tg);if(0<=a)this.Nm(a);else{for(var b=0;9>b;b++)this.hc.push(a&127|128),a>>=7;this.hc.push(1)}};d.OW=function(a){h.R.assert(a==Math.floor(a));h.R.assert(0<=a&&a<l.xa.Rp);l.O.$o(a);this.QC(l.O.Oc,l.O.Wc)};d.LW=function(a){h.R.assert(a==Math.floor(a));h.R.assert(a>=-l.xa.Mj&&a<l.xa.Mj);l.O.$o(a);this.QC(l.O.Oc,l.O.Wc)};\nd.Pg=function(a){h.R.assert(a==Math.floor(a));h.R.assert(0<=a&&a<l.xa.Xf);this.hc.push(a>>>0&255);this.hc.push(a>>>8&255);this.hc.push(a>>>16&255);this.hc.push(a>>>24&255)};d.ye=function(a){h.R.assert(a==Math.floor(a));h.R.assert(0<=a&&a<l.xa.Rp);l.O.zC(a);this.Pg(l.O.Oc);this.Pg(l.O.Wc)};d.$a=function(a){h.R.assert(a==Math.floor(a));h.R.assert(a>=-l.xa.Tg&&a<l.xa.Tg);this.hc.push(a>>>0&255);this.hc.push(a>>>8&255);this.hc.push(a>>>16&255);this.hc.push(a>>>24&255)};\nd.td=function(a){h.R.assert(a==Math.floor(a));h.R.assert(a>=-l.xa.Mj&&a<l.xa.Mj);l.O.$o(a);this.MW(l.O.Oc,l.O.Wc)};d.vi=function(a){h.R.assert(a>=-l.xa.vp&&a<=l.xa.vp);l.O.cW(a);this.Pg(l.O.Oc)};d.ya=function(a){h.R.assert(a>=-l.xa.wp&&a<=l.xa.wp);l.O.dW(a);this.Pg(l.O.Oc);this.Pg(l.O.Wc)};d.kf=function(a){h.R.assert(h.sk(a));this.hc.push(a?1:0)};d.xe=function(a){h.R.assert(a==Math.floor(a));h.R.assert(a>=-l.xa.Tg&&a<l.xa.Tg);this.Ft(a)};d.fp=function(a){this.hc.push.apply(this.hc,a)};\nd.Ja=function(a){for(var b=this.hc.length,c=0;c<a.length;c++){var e=a.charCodeAt(c);if(128>e)this.hc.push(e);else if(2048>e)this.hc.push(e>>6|192),this.hc.push(e&63|128);else if(65536>e)if(55296<=e&&56319>=e&&c+1<a.length){var g=a.charCodeAt(c+1);56320<=g&&57343>=g&&(e=1024*(e-55296)+g-56320+65536,this.hc.push(e>>18|240),this.hc.push(e>>12&63|128),this.hc.push(e>>6&63|128),this.hc.push(e&63|128),c++)}else this.hc.push(e>>12|224),this.hc.push(e>>6&63|128),this.hc.push(e&63|128)}return a=this.hc.length-\nb};l.ba=function(a,b,c){this.vb=l.vg.ck(a,b,c);this.ka=l.xa.Tm;this.Dc=l.xa.kb.Gj;this.tg=!1};l.ba.Nf=[];l.ba.ck=function(a,b,c){if(l.ba.Nf.length){var e=l.ba.Nf.pop();a&&e.vb.vm(a,b,c);return e}return new l.ba(a,b,c)};d=l.ba.prototype;d.ck=l.ba.ck;d.Br=function(){this.vb.clear();this.ka=l.xa.Tm;this.Dc=l.xa.kb.Gj;this.tg=!1;100>l.ba.Nf.length&&l.ba.Nf.push(this)};d.Ol=function(){return this.vb.Ol()};d.ga=function(){return this.Dc==l.xa.kb.Jk};d.getError=function(){return this.tg||this.vb.getError()};\nd.vm=function(a,b,c){this.vb.vm(a,b,c);this.ka=l.xa.Tm;this.Dc=l.xa.kb.Gj};d.reset=function(){this.vb.reset();this.ka=l.xa.Tm;this.Dc=l.xa.kb.Gj};d.advance=function(a){this.vb.advance(a)};d.fa=function(){if(this.vb.Yq())return!1;if(this.getError())return h.R.fail(\"Decoder hit an error\"),!1;var a=this.vb.Hh(),b=a>>>3,a=a&7;if(a!=l.xa.kb.Xe&&a!=l.xa.kb.hh&&a!=l.xa.kb.ih&&a!=l.xa.kb.jg&&a!=l.xa.kb.Tk&&a!=l.xa.kb.Jk)return h.R.fail(\"Invalid wire type\"),this.tg=!0,!1;this.ka=b;this.Dc=a;return!0};\nd.aW=function(){this.Dc!=l.xa.kb.Xe?(h.R.fail(\"Invalid wire type for skipVarintField\"),this.ea()):this.vb.$V()};d.WV=function(){if(this.Dc!=l.xa.kb.jg)h.R.fail(\"Invalid wire type for skipDelimitedField\"),this.ea();else{var a=this.vb.Hh();this.vb.advance(a)}};d.XV=function(){this.Dc!=l.xa.kb.hh?(h.R.fail(\"Invalid wire type for skipFixed32Field\"),this.ea()):this.vb.advance(4)};d.YV=function(){this.Dc!=l.xa.kb.ih?(h.R.fail(\"Invalid wire type for skipFixed64Field\"),this.ea()):this.vb.advance(8)};\nd.ZV=function(){var a=[this.ka];do{if(!this.fa()){h.R.fail(\"Unmatched start-group tag: stream EOF\");this.tg=!0;break}if(this.Dc==l.xa.kb.Tk)a.push(this.ka);else if(this.Dc==l.xa.kb.Jk&&this.ka!=a.pop()){h.R.fail(\"Unmatched end-group tag\");this.tg=!0;break}}while(0<a.length)};d.ea=function(){switch(this.Dc){case l.xa.kb.Xe:this.aW();break;case l.xa.kb.ih:this.YV();break;case l.xa.kb.jg:this.WV();break;case l.xa.kb.hh:this.XV();break;case l.xa.kb.Tk:this.ZV();break;default:h.R.fail(\"Invalid wire encoding for field.\")}};\nd.T=function(a,b){h.R.assert(this.Dc==l.xa.kb.jg);var c=this.vb.$e,e=this.vb.Hh(),e=this.vb.Ol()+e;this.vb.setEnd(e);b(a,this);this.vb.YQ(e);this.vb.setEnd(c)};d.lP=function(a,b,c){h.R.assert(this.Dc==l.xa.kb.Tk);h.R.assert(this.ka==a);c(b,this);this.tg||this.Dc==l.xa.kb.Jk||(h.R.fail(\"Group submessage did not end with an END_GROUP tag\"),this.tg=!0)};d.Ya=function(){h.R.assert(this.Dc==l.xa.kb.Xe);return this.vb.bC()};d.ad=function(){h.R.assert(this.Dc==l.xa.kb.Xe);return this.vb.cC()};\nd.Jg=function(){h.R.assert(this.Dc==l.xa.kb.Xe);return this.vb.Hh()};d.ee=function(){h.R.assert(this.Dc==l.xa.kb.Xe);return this.vb.nP()};d.ti=function(){h.R.assert(this.Dc==l.xa.kb.hh);return this.vb.ti()};d.pa=function(){h.R.assert(this.Dc==l.xa.kb.ih);return this.vb.pa()};d.vf=function(){h.R.assert(this.Dc==l.xa.kb.Xe);return!!this.vb.Hh()};d.we=function(){h.R.assert(this.Dc==l.xa.kb.Xe);return this.vb.cC()};d.Aa=function(){h.R.assert(this.Dc==l.xa.kb.jg);var a=this.vb.Hh();return this.vb.Aa(a)};\nd.qm=function(){h.R.assert(this.Dc==l.xa.kb.jg);var a=this.vb.Hh();return this.vb.qm(a)};d.mP=function(a){h.R.assert(this.Dc==l.xa.kb.jg);for(var b=this.vb.Hh(),b=this.vb.Ol()+b,c=[];this.vb.Ol()<b;)c.push(a.call(this.vb));return c};d.rm=function(){return this.mP(this.vb.pa)};l.Bi=function(){this.Yn=[];this.Lh=0;this.Ze=new l.Tt};d=l.Bi.prototype;d.MJ=function(a){var b=this.Ze.end();this.Yn.push(b);this.Yn.push(a);this.Lh+=b.length+a.length};\nd.ar=function(a){this.hg(a,l.xa.kb.jg);a=this.Ze.end();this.Yn.push(a);this.Lh+=a.length;a.push(this.Lh);return a};d.vr=function(a){var b=a.pop(),b=this.Lh+this.Ze.length()-b;for(h.R.assert(0<=b);127<b;)a.push(b&127|128),b>>>=7,this.Lh++;a.push(b);this.Lh++};d.reset=function(){this.Yn=[];this.Ze.end();this.Lh=0};d.hg=function(a,b){h.R.assert(1<=a&&a==Math.floor(a));a=8*a+b;this.Ze.Nm(a)};d.NW=function(a,b){null!=b&&(this.hg(a,l.xa.kb.Xe),this.Ze.Nm(b))};\nd.OC=function(a,b){null!=b&&(this.hg(a,l.xa.kb.Xe),this.Ze.Ft(b))};d.RC=function(a,b){null!=b&&(this.hg(a,l.xa.kb.Xe),this.Ze.OW(b))};d.PC=function(a,b){null!=b&&(this.hg(a,l.xa.kb.Xe),this.Ze.LW(b))};d.$a=function(a,b){null!=b&&(h.R.assert(b>=-l.xa.Tg&&b<l.xa.Tg),this.OC(a,b))};d.td=function(a,b){null!=b&&(h.R.assert(b>=-l.xa.Mj&&b<l.xa.Mj),this.PC(a,b))};d.Pg=function(a,b){null!=b&&(h.R.assert(0<=b&&b<l.xa.Xf),this.NW(a,b))};d.ye=function(a,b){null!=b&&(h.R.assert(0<=b&&b<l.xa.Rp),this.RC(a,b))};\nd.vi=function(a,b){null!=b&&(this.hg(a,l.xa.kb.hh),this.Ze.vi(b))};d.ya=function(a,b){null!=b&&(this.hg(a,l.xa.kb.ih),this.Ze.ya(b))};d.kf=function(a,b){null!=b&&(h.R.assert(h.sk(b)),this.hg(a,l.xa.kb.Xe),this.Ze.kf(b))};d.xe=function(a,b){null!=b&&(h.R.assert(b>=-l.xa.Tg&&b<l.xa.Tg),this.hg(a,l.xa.kb.Xe),this.Ze.Ft(b))};d.Ja=function(a,b){null!=b&&(a=this.ar(a),this.Ze.Ja(b),this.vr(a))};d.fp=function(a,b){null!=b&&(b=l.O.fr(b),this.hg(a,l.xa.kb.jg),this.Ze.Nm(b.length),this.MJ(b))};\nd.oa=function(a,b,c){null!=b&&(a=this.ar(a),c(b,this),this.vr(a))};d.GW=function(a,b){if(null!=b)for(var c=0;c<b.length;c++)this.OC(a,b[c])};d.HW=function(a,b){if(null!=b)for(var c=0;c<b.length;c++)this.PC(a,b[c])};d.IW=function(a,b){if(null!=b)for(var c=0;c<b.length;c++)this.RC(a,b[c])};d.bd=function(a,b){if(null!=b)for(var c=0;c<b.length;c++)this.ya(a,b[c])};d.oc=function(a,b){if(null!=b)for(var c=0;c<b.length;c++)this.Ja(a,b[c])};\nd.Oa=function(a,b,c){if(null!=b)for(var e=0;e<b.length;e++){var g=this.ar(a);c(b[e],this);this.vr(g)}};d.FW=function(a,b,c){if(null!=b)for(var e=0;e<b.length;e++)this.hg(a,l.xa.kb.Tk),c(b[e],this),this.hg(a,l.xa.kb.Jk)};d.Mm=function(a,b){if(null!=b&&b.length)for(this.hg(a,l.xa.kb.jg),this.Ze.Nm(8*b.length),a=0;a<b.length;a++)this.Ze.ya(b[a])};var x={i:{}};x.i.za={};x.i.za.me=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.za.me,l.u);\nl.u.ha&&(x.i.za.me.prototype.C=function(a){return x.i.za.me.C(a,this)},x.i.za.me.C=function(a,b){var c={o9:l.u.D(b,1),tda:l.u.D(b,2)};a&&(c.ja=b);return c});x.i.za.me.ia=function(a){a=new l.ba(a);var b=new x.i.za.me;return x.i.za.me.F(b,a)};x.i.za.me.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.$S(c);break;case 2:c=b.Aa();a.HV(c);break;default:b.ea()}}return a};x.i.za.me.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Ja(1,c);c=l.u.D(a,2);null!=c&&b.Ja(2,c)};\nx.i.za.me.prototype.$S=function(a){l.u.J(this,1,a)};x.i.za.me.prototype.HV=function(a){l.u.J(this,2,a)};x.i.za.me.K=function(a){return l.u.K(x.i.za.me,a)};x.i.za.nf=function(a){l.u.initialize(this,a,0,-1,x.i.za.nf.na,null)};h.da(x.i.za.nf,l.u);x.i.za.nf.na=[1];l.u.ha&&(x.i.za.nf.prototype.C=function(a){return x.i.za.nf.C(a,this)},x.i.za.nf.C=function(a,b){var c={U5:l.u.Ka(b.Wy(),x.i.za.me.C,a)};a&&(c.ja=b);return c});\nx.i.za.nf.ia=function(a){a=new l.ba(a);var b=new x.i.za.nf;return x.i.za.nf.F(b,a)};x.i.za.nf.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.za.me;b.T(c,x.i.za.me.F);a.mI(c);break;default:b.ea()}}return a};x.i.za.nf.G=function(a,b){a=a.Wy();0<a.length&&b.Oa(1,a,x.i.za.me.G)};x.i.za.nf.prototype.Wy=function(){return l.u.Ma(this,x.i.za.me,1)};x.i.za.nf.prototype.mI=function(a,b){return l.u.La(this,1,a,x.i.za.me,b)};x.i.za.nf.K=function(a){return l.u.K(x.i.za.nf,a)};\nx.i.za.kd=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.za.kd,l.u);l.u.ha&&(x.i.za.kd.prototype.C=function(a){return x.i.za.kd.C(a,this)},x.i.za.kd.C=function(a,b){var c={name:l.u.D(b,1),value:l.u.D(b,2)};a&&(c.ja=b);return c});x.i.za.kd.ia=function(a){a=new l.ba(a);var b=new x.i.za.kd;return x.i.za.kd.F(b,a)};x.i.za.kd.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.fe(c);break;case 2:c=b.Aa();a.setValue(c);break;default:b.ea()}}return a};\nx.i.za.kd.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Ja(1,c);c=l.u.D(a,2);null!=c&&b.Ja(2,c)};x.i.za.kd.prototype.getName=function(){return l.u.D(this,1)};x.i.za.kd.prototype.fe=function(a){l.u.J(this,1,a)};x.i.za.kd.prototype.getValue=function(){return l.u.D(this,2)};x.i.za.kd.prototype.setValue=function(a){l.u.J(this,2,a)};x.i.za.kd.K=function(a){return l.u.K(x.i.za.kd,a)};x.i.za.vd=function(a){l.u.initialize(this,a,0,-1,x.i.za.vd.na,null)};h.da(x.i.za.vd,l.u);x.i.za.vd.na=[1,2];\nl.u.ha&&(x.i.za.vd.prototype.C=function(a){return x.i.za.vd.C(a,this)},x.i.za.vd.C=function(a,b){var c={Cx:l.u.Ka(b.Zg(),x.i.za.kd.C,a),L8:l.u.gb(b,2),aK:l.u.D(b,3)};a&&(c.ja=b);return c});x.i.za.vd.ia=function(a){a=new l.ba(a);var b=new x.i.za.vd;return x.i.za.vd.F(b,a)};x.i.za.vd.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.za.kd;b.T(c,x.i.za.kd.F);a.sl(c);break;case 2:c=b.pa();a.BI(c);break;case 3:c=b.vf();a.uC(c);break;default:b.ea()}}return a};\nx.i.za.vd.G=function(a,b){var c;c=a.Zg();0<c.length&&b.Oa(1,c,x.i.za.kd.G);c=a.Bh();0<c.length&&b.bd(2,c);c=l.u.D(a,3);null!=c&&b.kf(3,c)};d=x.i.za.vd.prototype;d.Zg=function(){return l.u.Ma(this,x.i.za.kd,1)};d.Us=function(a){l.u.mt(this,1,a)};d.sl=function(a,b){return l.u.La(this,1,a,x.i.za.kd,b)};d.Bh=function(){return l.u.gb(this,2)};d.GS=function(a){l.u.J(this,2,a||[])};d.BI=function(a,b){l.u.ib(this,2,a,b)};d.to=function(){return l.u.D(this,3)};d.uC=function(a){l.u.J(this,3,a)};\nx.i.za.vd.K=function(a){return l.u.K(x.i.za.vd,a)};x.i.za.Te=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.za.Te,l.u);l.u.ha&&(x.i.za.Te.prototype.C=function(a){return x.i.za.Te.C(a,this)},x.i.za.Te.C=function(a,b){var c={Zq:l.u.D(b,1),pO:l.u.D(b,2),Qba:l.u.D(b,3),q5:l.u.D(b,4),Pba:l.u.D(b,5),p5:l.u.D(b,6)};a&&(c.ja=b);return c});x.i.za.Te.ia=function(a){a=new l.ba(a);var b=new x.i.za.Te;return x.i.za.Te.F(b,a)};\nx.i.za.Te.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.rj(c);break;case 2:c=b.Aa();a.$s(c);break;case 3:c=b.ad();a.TU(c);break;case 4:c=b.ad();a.qR(c);break;case 5:c=b.Ya();a.SU(c);break;case 6:c=b.Ya();a.pR(c);break;default:b.ea()}}return a};x.i.za.Te.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Ja(1,c);c=l.u.D(a,2);null!=c&&b.Ja(2,c);c=l.u.D(a,3);null!=c&&b.td(3,c);c=l.u.D(a,4);null!=c&&b.td(4,c);c=l.u.D(a,5);null!=c&&b.$a(5,c);c=l.u.D(a,6);null!=c&&b.$a(6,c)};\nd=x.i.za.Te.prototype;d.Jl=function(){return l.u.D(this,1)};d.rj=function(a){l.u.J(this,1,a)};d.$s=function(a){l.u.J(this,2,a)};d.TU=function(a){l.u.J(this,3,a)};d.qR=function(a){l.u.J(this,4,a)};d.SU=function(a){l.u.J(this,5,a)};d.pR=function(a){l.u.J(this,6,a)};x.i.za.Te.K=function(a){return l.u.K(x.i.za.Te,a)};x.i.za.oe=function(a){l.u.initialize(this,a,0,-1,x.i.za.oe.na,null)};h.da(x.i.za.oe,l.u);x.i.za.oe.na=[2,3];\nl.u.ha&&(x.i.za.oe.prototype.C=function(a){return x.i.za.oe.C(a,this)},x.i.za.oe.C=function(a,b){var c,e={c9:(c=b.yz())&&x.i.za.Te.C(a,c),J8:l.u.D(b,2),J4:l.u.Ka(b.By(),x.i.za.vd.C,a)};a&&(e.ja=b);return e});x.i.za.oe.ia=function(a){a=new l.ba(a);var b=new x.i.za.oe;return x.i.za.oe.F(b,a)};\nx.i.za.oe.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.za.Te;b.T(c,x.i.za.Te.F);a.TS(c);break;case 2:c=b.Aa();a.zI(c);break;case 3:c=new x.i.za.vd;b.T(c,x.i.za.vd.F);a.QH(c);break;default:b.ea()}}return a};x.i.za.oe.G=function(a,b){var c;c=a.yz();null!=c&&b.oa(1,c,x.i.za.Te.G);c=a.VL();0<c.length&&b.oc(2,c);c=a.By();0<c.length&&b.Oa(3,c,x.i.za.vd.G)};d=x.i.za.oe.prototype;d.yz=function(){return l.u.sa(this,x.i.za.Te,1)};d.TS=function(a){l.u.Ca(this,1,a)};\nd.VL=function(){return l.u.D(this,2)};d.zI=function(a,b){l.u.ib(this,2,a,b)};d.By=function(){return l.u.Ma(this,x.i.za.vd,3)};d.QH=function(a,b){return l.u.La(this,3,a,x.i.za.vd,b)};x.i.za.oe.K=function(a){return l.u.K(x.i.za.oe,a)};\nvar D={Event:{Ut:\"change\",bD:\"click\",au:\"dblclick\",xu:\"keyup\",KD:\"immediate-value-change\",fv:\"update-focus-range\",Op:\"select\",Vt:\"clear-selection\",kY:\"iron-select\",$Y:\"onmouseover\"},Pf:{Kj:\"Overall\",gu:\"feature\",o_:\"weighted examples\",ZC:\"calibration\",Cu:\"model_id\",yu:\"links\"},Nh:5,Pk:{Uk:0,FLOAT:1,INT:2,GD:3,Mp:4,an:5},HB:function(a,b){var c=[];a.forEach(function(a){c.push(b(a))});return c.join(\"_X_\")},Vy:function(a){a=a?a.Zg():null;return a&&0!=a.length?a=D.HB(a,function(a){return h.R.Lw(a.getName())}):\nD.Pf.Kj},Ah:function(a){var b=D.Vy(a);if(b==D.Pf.Kj)return b;a=a.Zg();var c=D.HB(a,function(a){return h.R.Lw(a.getValue())});return(1<a.length?\"XX_\":\"\")+b+\":\"+c}};D.ei=d3;h.bc(\"lantern.d3v4\",D.ei);D.data={};D.data.Sh=function(){};h.Fg(D.data.Sh.prototype,\"getDataTable\",D.data.Sh.prototype.getDataTable);h.Fg(D.data.Sh.prototype,\"getHeader\",D.data.Sh.prototype.Gr);h.Fg(D.data.Sh.prototype,\"getFormats\",D.data.Sh.prototype.Fr);h.Fg(D.data.Sh.prototype,\"readyToRender\",D.data.Sh.prototype.zs);\nD.Jb=function(a,b){if(!Array.isArray(b))throw\"invalid non-array input data\";this.metrics_=a;this.tf=b;this.yr={};this.tf.forEach(function(a){var b=a.Ah();this.yr[b]=a}.bind(this))};D.Jb.bv={Wt:\"p\",JSON:\"j\",IZ:\"colab\"};D.Jb.vK=function(a,b){return b.map(function(b){return D.Jb.Xw(a,JSON.parse(b.metricValues),b.feature)})};\nD.Jb.Xw=function(a,b,c){var e=c?c.split(\":\"):[D.Pf.Kj];a=a.map(function(a){return a==D.Pf.ZC?b.averageLabel?b.averageRefinedPrediction/b.averageLabel:0:b[a]});return new D.Jb.Series(e[0],c||D.Pf.Kj,a,!1)};D.Jb.prototype.ki=function(a){return this.metrics_.indexOf(a)};D.Jb.prototype.lk=function(){return this.metrics_};D.Jb.prototype.qM=function(){return this.tf};h.Fg(D.Jb.prototype,\"getSeriesList\",D.Jb.prototype.qM);D.Jb.prototype.filter=function(a){return new D.Jb(this.metrics_,this.tf.filter(a))};\nD.Jb.prototype.getColumnRange=function(a){var b=this.ki(a);return this.tf.reduce(function(a,e){e=e.Bh();return{min:Math.min(a.min,e[b]),max:Math.max(a.max,e[b])}},{min:Infinity,max:-Infinity})};h.Fg(D.Jb.prototype,\"getColumnRange\",D.Jb.prototype.getColumnRange);D.Jb.prototype.vB=function(){return 0<this.tf.length&&this.tf[0].Ah()==D.Pf.Kj};h.Fg(D.Jb.prototype,\"isOverallColumn\",D.Jb.prototype.vB);d=D.Jb.prototype;d.Xr=function(){return this.tf.some(function(a){return a.to()})};\nd.lA=function(a){h.R.assert(a in this.yr);return this.yr[a]};d.Hl=function(a){return this.lA(a).Bh()};d.WL=function(a,b){b=this.ki(b);h.R.assert(0<=b);return this.Hl(a)[b]};d.jk=function(){return this.tf.map(function(a){return a.Ah()})};d.rL=function(a,b){var c=this.Hl(a),c=[a].concat(c);b&&c.push(a);return c};d.getDataTable=function(a){var b=[],c=this.Xr();this.tf.forEach(function(e){\"\"!==a&&e.Hg()!=a||b.push(this.rL(e.Ah(),c))}.bind(this));return b};d.Zc=function(){return!this.tf.length||!this.metrics_.length};\nd.ii=function(a){var b=a.tf;if(this.metrics_!==a.lk()||this.tf.length!=b.length)return!1;for(a=0;a<this.tf.length;a++)if(this.tf[a]!==b[a])return!1;return!0};d.zs=function(){return!this.Zc()};d.Gr=function(a){a=[D.Pf.gu].concat(a);this.Xr()&&a.push(D.Pf.yu);return a};d.Fr=function(a){a=Object.assign({},a);a[D.Pf.gu]={type:D.Pk.Mp};return a};d.Gw=function(a,b){(b=b.transform)&&b.withDataSeries&&(a=b.withDataSeries(this.lA(a)));return a};\nD.Jb.Vw=function(a,b,c){var e=D.Jb.bv;switch(c){case e.JSON:b=b.map(function(b){return D.Jb.Xw(a,b.metrics,b.slice)});break;case e.Wt:b=b.map(D.Jb.Series.dL);break;default:b=D.Jb.vK(a,b)}return new D.Jb(a,b)};D.Jb.Series=function(a,b,c,e){this.jK=a;this.TK=b;this.BW=c;this.RM=e};D.Jb.Series.prototype.Hg=function(){return this.jK};D.Jb.Series.prototype.Ah=function(){return this.TK};D.Jb.Series.prototype.Bh=function(){return this.BW};h.Fg(D.Jb.Series.prototype,\"getMetricValuesList\",D.Jb.Series.prototype.Bh);\nD.Jb.Series.prototype.to=function(){return this.RM};D.Jb.Series.dL=function(a){return new D.Jb.Series(D.Vy(a),D.Ah(a),a.Bh(),!!a.to())};h.wC(\"goog.testing.stacktrace\");h.ra={};h.ra.Pa={};h.ra.Pa.jh=function(a,b,c,e){this.lr=a;this.Lo=b;this.Ew=c;this.vk=e};h.ra.Pa.jh.prototype.getName=function(){return this.Lo};h.ra.Pa.jh.prototype.nN=function(){return!this.Lo||\"[object Object]\"==this.lr};\nh.ra.Pa.jh.prototype.nW=function(){var a=h.ra.Pa.aN,b=h.ra.Pa.jO,b=[this.lr?a(this.lr)+\".\":\"\",this.Lo?a(b(this.Lo)):\"anonymous\",this.Ew?\" [as \"+a(b(this.Ew))+\"]\":\"\"];this.vk&&(b.push(\" at \"),b.push(a(this.vk)));return b.join(\"\")};h.ra.Pa.UD=20;h.ra.Pa.VD=5E5;h.ra.Pa.Sf=\"[a-zA-Z_$][\\\\w$]*\";h.ra.Pa.RE=\"(?: \\\\[as (\"+h.ra.Pa.Sf+\")\\\\])?\";h.ra.Pa.SE=\"(?:((?:new )?(?:\\\\[object Object\\\\]|\"+h.ra.Pa.Sf+\"(?:\\\\.\"+h.ra.Pa.Sf+\")*))\\\\.)?\";h.ra.Pa.UE=\"(?:new )?(?:\"+h.ra.Pa.Sf+\"|\\x3canonymous\\x3e)\";\nh.ra.Pa.TE=\" \"+h.ra.Pa.SE+\"(\"+h.ra.Pa.UE+\")\"+h.ra.Pa.RE;h.ra.Pa.Sp=\"((?:http|https|file)://[^\\\\s)]+|javascript:.*)\";h.ra.Pa.aD=\" (?:\\\\(unknown source\\\\)|\\\\(native\\\\)|\\\\((.+)\\\\)|(.+))\";h.ra.Pa.VE=new RegExp(\"^    at(?:\"+h.ra.Pa.TE+\")?\"+h.ra.Pa.aD+\"$\");h.ra.Pa.qD=\"(\"+h.ra.Pa.Sf+\"(?:\\\\.\"+h.ra.Pa.Sf+\")*)?(\\\\(.*\\\\))?@\";h.ra.Pa.rD=new RegExp(\"^\"+h.ra.Pa.qD+\"(?::0|\"+h.ra.Pa.Sp+\")$\");h.ra.Pa.eE=\"\\x3canonymous function(?:\\\\: (?:(\"+h.ra.Pa.Sf+\"(?:\\\\.\"+h.ra.Pa.Sf+\")*)\\\\.)?(\"+h.ra.Pa.Sf+\"))?\\x3e\";\nh.ra.Pa.fE=\"(?:(?:(\"+h.ra.Pa.Sf+\")|\"+h.ra.Pa.eE+\")(\\\\(.*\\\\)))?@\";h.ra.Pa.gE=new RegExp(\"^\"+h.ra.Pa.fE+h.ra.Pa.Sp+\"?$\");h.ra.Pa.xD=new RegExp(\"^function (\"+h.ra.Pa.Sf+\")\");h.ra.Pa.ID=\"(\"+h.ra.Pa.Sf+\"(?:\\\\.\"+h.ra.Pa.Sf+\")*(?:\\\\s+\\\\w+)*)\";h.ra.Pa.JD=new RegExp(\"^   at \"+h.ra.Pa.ID+\"\\\\s*\\\\((eval code:[^)]*|Unknown script code:[^)]*|\"+h.ra.Pa.Sp+\")\\\\)?$\");\nh.ra.Pa.cL=function(){for(var a=[],b=arguments.callee.caller,c=0;b&&c<h.ra.Pa.UD;){var e=Function.prototype.toString.call(b),e=(e=e.match(h.ra.Pa.xD))?e[1]:\"\";a.push(new h.ra.Pa.jh(\"\",e,\"\",\"\"));try{b=b.caller}catch(g){break}c++}return a};\nh.ra.Pa.UO=function(a){var b=a.match(h.ra.Pa.VE);return b?new h.ra.Pa.jh(b[1]||\"\",b[2]||\"\",b[3]||\"\",b[4]||b[5]||b[6]||\"\"):a.length>h.ra.Pa.VD?null:(b=a.match(h.ra.Pa.rD))?new h.ra.Pa.jh(\"\",b[1]||\"\",\"\",b[3]||\"\"):(b=a.match(h.ra.Pa.gE))?new h.ra.Pa.jh(b[2]||\"\",b[1]||b[3]||\"\",\"\",b[5]||\"\"):(b=a.match(h.ra.Pa.JD))?new h.ra.Pa.jh(\"\",b[1]||\"\",\"\",b[2]||\"\"):null};h.ra.Pa.eR=function(a){h.ra.Pa.ux=a};h.ra.Pa.jO=function(a){return h.ra.Pa.ux?h.ra.Pa.ux(a):a};\nh.ra.Pa.aN=function(a){return a.replace(/&/g,\"\\x26amp;\").replace(/</g,\"\\x26lt;\").replace(/>/g,\"\\x26gt;\").replace(/\"/g,\"\\x26quot;\")};h.ra.Pa.Gx=function(a){for(var b=a.length-1;a[b]&&a[b].nN();)b--;for(var c=-1,e=0;e<a.length;e++)if(a[e]&&\"_assert\"==a[e].getName()){c=e;break}for(var g=[],e=c+1;e<=b;e++)g.push(\"\\x3e \"),a[e]?g.push(a[e].nW()):g.push(\"(unknown)\"),g.push(\"\\n\");return g.join(\"\")};\nh.ra.Pa.XB=function(a){a=a.replace(/\\s*$/,\"\").split(\"\\n\");for(var b=[],c=0;c<a.length;c++)b.push(h.ra.Pa.UO(a[c]));return b};h.ra.Pa.f3=function(a){a=h.ra.Pa.XB(a);return h.ra.Pa.Gx(a)};h.ra.Pa.ZL=function(){var a=Error();if(a.stack)return a.stack;try{null.x()}catch(b){return b.stack}return\"\"};h.ra.Pa.get=function(){var a=h.ra.Pa.ZL(),a=a?h.isArray(a)?h.ra.Pa.bK(a):h.ra.Pa.XB(a):h.ra.Pa.cL();return h.ra.Pa.Gx(a)};\nh.ra.Pa.bK=function(a){for(var b=[],c=0;c<a.length;c++){var e=a[c],g=e.getFunctionName()||\"unknown\",k=e.getFileName(),e=k?k+\":\"+e.getLineNumber()+\":\"+e.getColumnNumber():\"unknown\";b.push(new h.ra.Pa.jh(\"\",g,\"\",e))}return b};h.bc(\"setDeobfuscateFunctionName\",h.ra.Pa.eR);h.wC(\"goog.testing.JsUnitException\");h.ra.R={};\nvar af=function(a,b){return a==b},vh=function(a,b){return a.toString()===b.toString()},wh={String:af,Number:af,Boolean:af,Date:function(a,b){return a.getTime()==b.getTime()},RegExp:vh,Function:vh};h.ra.R.VB=function(a,b,c){return Math.abs(a-b)<=c};h.ra.R.$O={Number:h.ra.R.VB};\nvar _trueTypeOf=function(a){var b=typeof a;try{switch(b){case \"object\":if(null==a){b=\"null\";break}case \"function\":switch(a.constructor){case (new String(\"\")).constructor:b=\"String\";break;case (new Boolean(!0)).constructor:b=\"Boolean\";break;case (new Number(0)).constructor:b=\"Number\";break;case [].constructor:b=\"Array\";break;case RegExp().constructor:b=\"RegExp\";break;case (new Date).constructor:b=\"Date\";break;case Function:b=\"Function\";break;default:var c=a.constructor.toString().match(/function\\s*([^( ]+)\\(/);\nc&&(b=c[1])}}}catch(e){}finally{b=b.substr(0,1).toUpperCase()+b.substr(1)}return b},_displayStringForValue=function(a){var b;try{b=\"\\x3c\"+String(a)+\"\\x3e\"}catch(c){b=\"\\x3ctoString failed: \"+c.message+\"\\x3e\"}null!==a&&void 0!==a&&(b+=\" (\"+_trueTypeOf(a)+\")\");return b},xh=function(a){h.ra.R.pm(\"Call to fail()\",a)},gm=function(a,b){return b.length==a+1?b[0]:null},hm=function(a,b,c){return c.length==b+1?c[a]:c[a-1]},_validateArguments=function(a,b){a=b.length==a||b.length==a+1&&h.Hb(b[0]);_assert(null,\na,\"Incorrect arguments passed to assert function\")},_getCurrentTestCase=function(){var a=h.global.G_testRunner;return a?a.wca:null},_assert=function(a,b,c){b||h.ra.R.pm(a,c)};\nh.ra.R.ji=function(a,b){var c=\"Expected \"+_displayStringForValue(a)+\" but was \"+_displayStringForValue(b);if(\"string\"==typeof a&&\"string\"==typeof b){for(var e=Math.min(a.length,b.length),g=0;g<e&&a.charAt(g)==b.charAt(g);)g++;for(var k=0;k<e&&a.charAt(a.length-k-1)==b.charAt(b.length-k-1);)k++;g+k>e&&(k=0);if(2<g||2<k)e=function(a){var b=Math.max(0,g-2),c=Math.min(a.length,a.length-(k-2));return(0<b?\"...\":\"\")+a.substring(b,c)+(c<a.length?\"...\":\"\")},c+=\"\\nDifference was at position \"+g+\". Expected [\"+\ne(a)+\"] vs. actual [\"+e(b)+\"]\"}return c};\nvar im=function(a,b){_validateArguments(1,arguments);var c=gm(1,arguments),e=hm(1,1,arguments);_assert(c,h.sk(e),\"Bad argument to assert(boolean)\");_assert(c,e,\"Call to assert(boolean) with false\")},jm=function(a,b){_validateArguments(1,arguments);var c=hm(1,1,arguments),e=gm(1,arguments);_assert(e,\"function\"==typeof c,\"Argument passed to assertThrows is not a function\");try{c()}catch(g){return g&&h.Hb(g.stacktrace)&&h.Hb(g.message)&&(c=g.message.length-g.stacktrace.length,g.message.indexOf(g.stacktrace,\nc)==c&&(g.message=g.message.substr(0,c-14))),c=_getCurrentTestCase(),g&&g.isJsUnitException&&c&&c.O5&&h.ra.R.pm(e,\"Function passed to assertThrows caught a JsUnitException (usually from an assert or call to fail()). If this is expected, use assertThrowsJsUnitException instead.\"),g}h.ra.R.pm(e,\"No exception thrown from function passed to assertThrows\")},km=function(a,b){_validateArguments(1,arguments);var c=gm(1,arguments),e=hm(1,1,arguments);_assert(c,\"function\"==typeof e,\"Argument passed to assertNotThrows is not a function\");\ntry{return e()}catch(g){c=c?c+\"\\n\":\"\",c+=\"A non expected exception was thrown from function passed to assertNotThrows\",e=g.stack||g.stacktrace||g.toString(),h.ra.R.pm(c,e)}},lm=function(a,b){try{h.ra.R.cK(a)}catch(c){return(a=_getCurrentTestCase())?a.y7(c):h.global.console.error(\"Failed to remove expected exception: no test case is installed.\"),c.uN||xh(\"Expected a JsUnitException\"),\"undefined\"!=typeof b&&c.message!=b&&xh(\"Expected message [\"+b+\"] but got [\"+c.message+\"]\"),c}a=\"Expected a failure\";\n\"undefined\"!=typeof b&&(a+=\": \"+b);throw new h.ra.Ok(a);},mm=function(a,b){_validateArguments(1,arguments);var c=gm(1,arguments),e=hm(1,1,arguments);_assert(c,h.sk(e),\"Bad argument to assertTrue(boolean)\");_assert(c,e,\"Call to assertTrue(boolean) with false\")},nm=function(a,b){_validateArguments(1,arguments);var c=gm(1,arguments),e=hm(1,1,arguments);_assert(c,h.sk(e),\"Bad argument to assertFalse(boolean)\");_assert(c,!e,\"Call to assertFalse(boolean) with true\")},om=function(a,b,c){_validateArguments(2,\narguments);var e=hm(1,2,arguments),g=hm(2,2,arguments);_assert(gm(2,arguments),e===g,h.ra.R.ji(e,g))},mw=function(a,b,c){_validateArguments(2,arguments);var e=hm(1,2,arguments),g=hm(2,2,arguments);_assert(gm(2,arguments),e!==g,\"Expected not to be \"+_displayStringForValue(g))},nw=function(a,b){_validateArguments(1,arguments);var c=hm(1,1,arguments);_assert(gm(1,arguments),null===c,h.ra.R.ji(null,c))},ow=function(a,b){_validateArguments(1,arguments);var c=hm(1,1,arguments);_assert(gm(1,arguments),null!==\nc,\"Expected not to be \"+_displayStringForValue(null))},pw=function(a,b){_validateArguments(1,arguments);var c=hm(1,1,arguments);_assert(gm(1,arguments),void 0===c,h.ra.R.ji(void 0,c))},qw=function(a,b){_validateArguments(1,arguments);var c=hm(1,1,arguments);_assert(gm(1,arguments),void 0!==c,\"Expected not to be \"+_displayStringForValue(void 0))},rw=function(a,b){_validateArguments(1,arguments);ow.apply(null,arguments);qw.apply(null,arguments)},sw=function(a,b){_validateArguments(1,arguments);var c=\nhm(1,1,arguments);_assert(gm(1,arguments),void 0!==c&&null!==c&&\"string\"==typeof c&&\"\"!==c,\"Expected non-empty string but was \"+_displayStringForValue(c))},tw=function(a,b){_validateArguments(1,arguments);var c=hm(1,1,arguments);_assert(gm(1,arguments),isNaN(c),\"Expected NaN\")},uw=function(a,b){_validateArguments(1,arguments);var c=hm(1,1,arguments);_assert(gm(1,arguments),!isNaN(c),\"Expected not NaN\")};\nh.ra.R.cK=function(a){var b=h.global.G_testRunner,c=b.logTestFailure;try{b.logTestFailure=void 0,a()}finally{b.logTestFailure=c}};h.ra.R.sp=null;h.ra.R.tp=\"\";\nh.ra.R.zr=function(a,b,c){function e(a,b,c){for(var e=0;e<m.length;++e){var q=m[e]===a,v=n[e]===b;if(q||v){q&&v||k.push(\"Asymmetric cycle detected at \"+c);return}}m.push(a);n.push(b);g(a,b,c);m.pop();n.pop()}function g(a,b,c){if(a!==b){var g=_trueTypeOf(a),n=_trueTypeOf(b);if(g==n){var m=\"Array\"==g,v=q(g,a,b);if(v!=h.ra.R.sp)v!=h.ra.R.tp&&k.push(c+\": \"+v);else if(m&&a.length!=b.length)k.push(c+\": Expected \"+a.length+\"-element array but got a \"+b.length+\"-element array\");else{var B=c+(m?\"[%s]\":c?\".%s\":\n\"%s\");if(\"undefined\"!=typeof Map&&a instanceof Map||\"undefined\"!=typeof Set&&a instanceof Set)a.forEach(function(a,g){b.has(g)?b.get&&e(a,b.get(g),B.replace(\"%s\",g)):k.push(g+\" not present in actual \"+(c||n))}),b.forEach(function(b,e){a.has(e)||k.push(e+\" not present in expected \"+(c||g))});else if(a.__iterator__)h.isFunction(a.ii)?a.ii(b)||k.push(\"equals() returned false for \"+(c||g)):a.jc?e(a.jc,b.jc,B.replace(\"%s\",\"map_\")):k.push(\"unable to check \"+(c||g)+\" for equality: it has an iterator we do not know how to handle. please add an equals method\");\nelse{for(var C in a)m&&h.ra.R.nB(C)||(C in b?e(a[C],b[C],B.replace(\"%s\",C)):k.push(\"property \"+C+\" not present in actual \"+(c||n)));for(C in b)m&&h.ra.R.nB(C)||C in a||k.push(\"property \"+C+\" not present in expected \"+(c||g));if(m)for(C=0;C<a.length;C++)e(a[C],b[C],B.replace(\"%s\",String(C)))}}}else k.push(c+\" \"+h.ra.R.ji(a,b))}}var k=[],m=[],n=[],q=c||function(a,b,c){a=wh[a];return a?(a=a(b,c))?h.ra.R.tp:h.ra.R.ji(b,c):h.ra.R.sp};e(a,b,\"\");return 0==k.length?null:h.ra.R.ji(a,b)+\"\\n   \"+k.join(\"\\n   \")};\nvar vw=function(a,b,c){_validateArguments(2,arguments);var e=hm(1,2,arguments),g=hm(2,2,arguments),k=gm(2,arguments)?gm(2,arguments):\"\",e=h.ra.R.zr(e,g);_assert(k,!e,e)},ww=function(a,b,c,e){_validateArguments(3,arguments);var g=hm(1,3,arguments),k=hm(2,3,arguments),m=hm(3,3,arguments),n=gm(3,arguments)?gm(3,arguments):\"\",q=function(a,b,c){a=h.ra.R.$O[a];return a?(a=a(b,c,m))?h.ra.R.tp:h.ra.R.ji(b,c)+\" which was more than \"+m+\" away\":h.ra.R.sp},g=h.ra.R.zr(g,k,q);_assert(n,!g,g)},xw=function(a,b,\nc){_validateArguments(2,arguments);var e=hm(1,2,arguments),g=hm(2,2,arguments),k=gm(2,arguments)?gm(2,arguments):\"\",e=h.ra.R.zr(e,g);_assert(k,e,\"Objects should not be equal\")},yw=function(a,b,c){_validateArguments(2,arguments);var e=hm(1,2,arguments),g=hm(2,2,arguments),k=gm(2,arguments)?gm(2,arguments):\"\",m=_trueTypeOf(e);_assert(k,\"Array\"==m,\"Expected an array for assertArrayEquals but found a \"+m);m=_trueTypeOf(g);_assert(k,\"Array\"==m,\"Expected an array for assertArrayEquals but found a \"+m);\nvw(k,Array.prototype.concat.call(e),Array.prototype.concat.call(g))},zw=function(a,b,c){_validateArguments(2,arguments);var e=hm(1,2,arguments),g=hm(2,2,arguments),k=gm(2,arguments)?gm(2,arguments):\"\";if(e){om(\"length mismatch: \"+k,e.length,g.length);for(var m=0;m<e.length;++m)om(\"mismatch at index \"+m+\": \"+k,e[m],g[m])}else im(k,!g)},Bw=function(a,b,c,e){_validateArguments(3,arguments);var g=hm(1,3,arguments),k=hm(2,3,arguments),m=hm(3,3,arguments),n=gm(3,arguments)?gm(3,arguments):\"\";if(g){om(\"length mismatch: \"+\nn,g.length,k.length);for(var q=0;q<g.length;++q)Aw(n,g[q],k[q],m)}else im(n,!k)},Cw=function(a,b,c){_validateArguments(2,arguments);var e=hm(1,2,arguments),g=hm(2,2,arguments),k=gm(2,arguments);mm(\"Bad arguments to assertSameElements(opt_message, expected: ArrayLike, actual: ArrayLike)\",h.Gd(e)&&h.Gd(g));e=h.ra.R.wt(e);g=h.ra.R.wt(g);_assert(k,e.length==g.length,\"Expected \"+e.length+\" elements: [\"+e+\"], got \"+g.length+\" elements: [\"+g+\"]\");for(var m=h.ra.R.wt(e),n=0;n<g.length;n++){var q=h.ra.R.hB(m,\ng[n]);_assert(k,-1!=q,\"Expected [\"+e+\"], got [\"+g+\"]\");m.splice(q,1)}},Dw=function(a,b){_validateArguments(1,arguments);var c=hm(1,1,arguments);c||_assert(gm(1,arguments),!1,\"Expected to evaluate to true\")},Ew=function(a,b){_validateArguments(1,arguments);var c=hm(1,1,arguments);c&&_assert(gm(1,arguments),!1,\"Expected to evaluate to false\")},Gw=function(a,b,c){_validateArguments(2,arguments);var e=hm(1,2,arguments),g=hm(2,2,arguments),e=Fw(e),g=Fw(g);_assert(gm(2,arguments),e===g,h.ra.R.ji(e,g))},\nHw=function(a,b,c){_validateArguments(2,arguments);var e=hm(1,2,arguments),g=hm(2,2,arguments),k=gm(2,arguments),m;for(m in e)_assert(k,m in g,\"Expected hash had key \"+m+\" that was not found\"),_assert(k,e[m]==g[m],\"Value for key \"+m+\" mismatch - expected \\x3d \"+e[m]+\", actual \\x3d \"+g[m]);for(m in g)_assert(k,m in e,\"Actual hash had key \"+m+\" that was not expected\")},Aw=function(a,b,c,e){_validateArguments(3,arguments);var g=hm(1,3,arguments),k=hm(2,3,arguments),m=hm(3,3,arguments);_assert(gm(3,arguments),\nh.ra.R.VB(g,k,m),\"Expected \"+g+\", but got \"+k+\" which was more than \"+m+\" away\")},Iw=function(a,b,c){_validateArguments(2,arguments);var e=hm(1,2,arguments),g=hm(2,2,arguments);_assert(gm(2,arguments),h.ra.R.jx(g,e),\"Expected '\"+g+\"' to contain '\"+e+\"'\")},Jw=function(a,b,c){_validateArguments(2,arguments);var e=hm(1,2,arguments),g=hm(2,2,arguments);_assert(gm(2,arguments),!h.ra.R.jx(g,e),\"Expected '\"+g+\"' not to contain '\"+e+\"'\")},Kw=function(a,b,c){_validateArguments(2,arguments);var e=hm(1,2,arguments),\ng=hm(2,2,arguments);\"string\"==typeof e&&(e=new RegExp(e));_assert(gm(2,arguments),e.test(g),\"Expected '\"+g+\"' to match RegExp \"+e.toString())};h.ra.R.wt=function(a){for(var b=[],c=0;c<a.length;c++)b[c]=a[c];return b};h.ra.R.hB=function(a,b){if(a.indexOf)return a.indexOf(b);for(var c=0;c<a.length;c++)if(a[c]===b)return c;return-1};h.ra.R.jx=function(a,b){return-1!=h.ra.R.hB(a,b)};var Fw=function(a){var b=document.createElement(\"DIV\");b.innerHTML=a;return b.innerHTML.replace(/^\\s+|\\s+$/g,\"\")};\nh.ra.R.pm=function(a,b){a=new h.ra.Ok(a,b);if(b=_getCurrentTestCase())b.oaa(a);else throw h.global.console.error(\"Failed to save thrown exception: no test case is installed.\"),a;};h.ra.R.nB=function(a){return(a|0)==a};h.ra.Ok=function(a,b){this.uN=!0;this.message=(a?a:\"\")+(a&&b?\"\\n\":\"\")+(b?b:\"\");h.ra.Pa.get();Error.captureStackTrace?Error.captureStackTrace(this,h.ra.Ok):this.stack=Error().stack||\"\"};h.da(h.ra.Ok,Error);h.ra.Ok.prototype.toString=function(){return this.message};h.bc(\"fail\",xh);\nh.bc(\"assert\",im);h.bc(\"assertThrows\",jm);h.bc(\"assertNotThrows\",km);h.bc(\"assertThrowsJsUnitException\",lm);h.bc(\"assertTrue\",mm);h.bc(\"assertFalse\",nm);h.bc(\"assertEquals\",om);h.bc(\"assertNotEquals\",mw);h.bc(\"assertNull\",nw);h.bc(\"assertNotNull\",ow);h.bc(\"assertUndefined\",pw);h.bc(\"assertNotUndefined\",qw);h.bc(\"assertNotNullNorUndefined\",rw);h.bc(\"assertNonEmptyString\",sw);h.bc(\"assertNaN\",tw);h.bc(\"assertNotNaN\",uw);h.bc(\"assertObjectEquals\",vw);h.bc(\"assertObjectRoughlyEquals\",ww);\nh.bc(\"assertObjectNotEquals\",xw);h.bc(\"assertArrayEquals\",yw);h.bc(\"assertElementsEquals\",zw);h.bc(\"assertElementsRoughlyEqual\",Bw);h.bc(\"assertSameElements\",Cw);h.bc(\"assertEvaluatesToTrue\",Dw);h.bc(\"assertEvaluatesToFalse\",Ew);h.bc(\"assertHTMLEquals\",Gw);h.bc(\"assertHashEquals\",Hw);h.bc(\"assertRoughlyEquals\",Aw);h.bc(\"assertContains\",Iw);h.bc(\"assertNotContains\",Jw);h.bc(\"assertRegExp\",Kw);D.Wf=function(a){this.Dh=a};\nD.Wf.prototype.UL=function(a,b){return this.Dh.map(function(c){return[c.id,c.data.WL(a,b)]})};h.Fg(D.Wf.prototype,\"getMetricDataTable\",D.Wf.prototype.UL);D.Wf.prototype.getDataTable=function(a){return this.Dh.map(function(b){var c=b.data.Hl(a);return[b.id].concat(c)})};\nD.Wf.prototype.jk=function(){var a={};this.Dh.forEach(function(b){b=b.data.jk();b.forEach(function(b){b in a?a[b]++:a[b]=1})});return Object.keys(a).filter(function(b){var c=a[b]==this.Dh.length;if(!c)throw'feature \"'+b+'\" is not present in all models';return c}.bind(this))};h.Fg(D.Wf.prototype,\"getFeatures\",D.Wf.prototype.jk);\nD.Wf.prototype.lk=function(){var a={};this.Dh.forEach(function(b){b=b.data.lk();b.forEach(function(b){b in a?a[b]++:a[b]=1})});return Object.keys(a).filter(function(b){var c=a[b]==this.Dh.length;if(!c)throw'metric \"'+b+'\" is not present in all models';return c}.bind(this))};D.Wf.prototype.XL=function(){return this.Dh.map(function(a){return a.id})};h.Fg(D.Wf.prototype,\"getModelIds\",D.Wf.prototype.XL);d=D.Wf.prototype;d.Zc=function(){return!this.Dh.length||this.Dh[0].data.Zc()};\nd.zs=function(a){return!this.Zc()&&\"\"!=a};d.Gr=function(a){return[D.Pf.Cu].concat(a)};d.Fr=function(a){a=Object.assign({},a);a[D.Pf.Cu]={type:D.Pk.Mp};return a};d.Gw=function(a){return a};D.test={};D.test.Event={Ut:\"change\",bD:\"click\",au:\"dblclick\",xu:\"keyup\",Op:\"select\",Vt:\"clear-selection\"};\nD.test.J6=function(){return{metrics:[\"weighted_examples\",\"metric_a\",\"metric_b\"],slices:[{af:{name:\"col\",value:\"1\"},wf:[4,.333,.002]},{af:{name:\"col\",value:\"2\"},wf:[9,.997,.753]},{af:{name:\"col\",value:\"3\"},wf:[1,1.14,.198]},{af:{name:\"col\",value:\"4\"},wf:[12,.18,.332]}]}};\nD.test.H6=function(a,b){for(var c=[\"weighted_examples\"],e=0;e<b;e++)c.push(\"metric_\"+String.fromCharCode(97+e));for(var g=[],e=0;e<a;e++){for(var k=[Math.ceil(100*Math.random())],m=0;m<b;m++)k.push(Math.random());g.push({af:{name:\"col\",value:\"\"+(e+1)},wf:k})}return{metrics:c,slices:g}};\nD.test.K6=function(){return[{metrics:[\"weighted_examples\",\"metric_a\",\"metric_b\",\"metric_c\"],slices:[{af:{name:\"Overall\",value:\"\"},wf:[100,1,1,1]},{af:{name:\"col\",value:\"1\"},wf:[4,.333,.002,.183]},{af:{name:\"col\",value:\"2\"},wf:[9,.997,.753,.629]}]},{metrics:[\"weighted_examples\",\"metric_a\",\"metric_b\",\"metric_c\"],slices:[{af:{name:\"Overall\",value:\"\"},wf:[200,.999,.999,.999]},{af:{name:\"col\",value:\"1\"},wf:[2,.111,.009,.215]},{af:{name:\"col\",value:\"2\"},wf:[5,.666,.831,.731]}]},{metrics:[\"weighted_examples\",\n\"metric_a\",\"metric_b\",\"metric_c\"],slices:[{af:{name:\"Overall\",value:\"\"},wf:[300,.888,.888,.888]},{af:{name:\"col\",value:\"1\"},wf:[2,.222,.012,.091]},{af:{name:\"col\",value:\"2\"},wf:[5,.777,.353,.662]}]}]};\nD.test.I6=function(a,b,c){for(var e,g=[\"weighted_examples\"],k=0;k<c;k++)g.push(\"metric_\"+String.fromCharCode(97+k));e=[];for(k=0;k<a;k++){for(var m=[],n=0;n<b+1;n++){var q;q=0==n?{name:\"Overall\",value:\"\"}:{name:\"col\",value:\"\"+n};for(var v=[Math.ceil(100*Math.random())],B=0;B<c;B++)v.push(Math.random());m.push({af:q,wf:v})}e.push({metrics:g,slices:m})}return e};\nD.test.EK=function(a){return a.slices.map(function(a){var b=[];if(a.af){var e=new x.i.za.kd;e.fe(a.af.name);e.setValue(a.af.value);b.push(e)}e=new x.i.za.vd;e.Us(b);e.GS(a.wf);a.aK&&e.uC(!0);return e})};D.test.DK=function(a){return D.Jb.Vw(a.metrics,D.test.EK(a),D.Jb.bv.Wt)};D.test.fba=function(a){a=a.map(function(a,c){return{id:\"version_\"+(c+1),data:D.test.DK(a)}});return new D.Wf(a)};\nD.test.xL=function(a,b,c){c=void 0==c?{}:c;a=a.getElementsByTagName(b);b=[];for(var e=0;e<a.length;e++){var g=!0,k;for(k in c){var m=c[k];switch(k){case \"textContent\":var n=a[e].textContent.match(/^\\s*(\\S+.*\\S+|\\S+)\\s*$/),g=g&(n&&n[1]===m);break;case \"class\":g&=a[e].classList.contains(m);break;case \"visible\":g&=m?\"none\"!=a[e].style.display:\"none\"==a[e].style.display;break;default:g&=a[e].getAttribute(k)===c[k]}if(!g)break}g&&b.push(a[e])}return b};\nD.test.F5=function(a,b,c,e){a=D.test.xL(a,c,e);om(a.length,b)};D.test.fireEvent=function(a,b,c){a.dispatchEvent(new CustomEvent(b,{detail:c}))};h.gc={};h.gc.cj=function(a){return function(){return a}};h.gc.LX=h.gc.cj(!1);h.gc.i_=h.gc.cj(!0);h.gc.UY=h.gc.cj(null);h.gc.bN=function(a){return a};h.gc.error=function(a){return function(){throw Error(a);}};h.gc.fail=function(a){return function(){throw a;}};\nh.gc.lock=function(a,b){b=b||0;return function(){return a.apply(this,Array.prototype.slice.call(arguments,0,b))}};h.gc.I9=function(a){return function(){return arguments[a]}};h.gc.u$=function(a,b){var c=Array.prototype.slice.call(arguments,1);return function(){var b=Array.prototype.slice.call(arguments);b.push.apply(b,c);return a.apply(this,b)}};h.gc.Hda=function(a,b){return h.gc.rC(a,h.gc.cj(b))};h.gc.t5=function(a,b){return function(c){return b?a==c:a===c}};\nh.gc.J3=function(a,b){var c=arguments,e=c.length;return function(){var a;e&&(a=c[e-1].apply(this,arguments));for(var b=e-2;0<=b;b--)a=c[b].call(this,a);return a}};h.gc.rC=function(a){var b=arguments,c=b.length;return function(){for(var a,g=0;g<c;g++)a=b[g].apply(this,arguments);return a}};h.gc.T1=function(a){var b=arguments,c=b.length;return function(){for(var a=0;a<c;a++)if(!b[a].apply(this,arguments))return!1;return!0}};\nh.gc.m$=function(a){var b=arguments,c=b.length;return function(){for(var a=0;a<c;a++)if(b[a].apply(this,arguments))return!0;return!1}};h.gc.not=function(a){return function(){return!a.apply(this,arguments)}};h.gc.create=function(a,b){var c=function(){};c.prototype=a.prototype;c=new c;a.apply(c,Array.prototype.slice.call(arguments,1));return c};h.gc.YC=!0;h.gc.Y2=function(a){var b=!1,c;return function(){if(!h.gc.YC)return a();b||(c=a(),b=!0);return c}};\nh.gc.once=function(a){var b=a;return function(){if(b){var a=b;b=null;a()}}};h.gc.debounce=function(a,b,c){var e=0;return function(g){h.global.clearTimeout(e);var k=arguments;e=h.global.setTimeout(function(){a.apply(c,k)},b)}};h.gc.Aca=function(a,b,c){var e=0,g=!1,k=[],m=function(){e=0;g&&(g=!1,n())},n=function(){e=h.global.setTimeout(m,b);a.apply(c,k)};return function(a){k=arguments;e?g=!0:n()}};\nh.gc.raa=function(a,b,c){var e=0,g=function(){e=0};return function(k){e||(e=h.global.setTimeout(g,b),a.apply(c,arguments))}};h.uri={};h.uri.O={};h.uri.O.Gk={Ht:38,EQUAL:61,BD:35,qE:63};h.uri.O.$n=function(a,b,c,e,g,k,m){var n=\"\";a&&(n+=a+\":\");c&&(n+=\"//\",b&&(n+=b+\"@\"),n+=c,e&&(n+=\":\"+e));g&&(n+=g);k&&(n+=\"?\"+k);m&&(n+=\"#\"+m);return n};h.uri.O.eW=/^(?:([^:/?#.]+):)?(?:\\/\\/(?:([^/?#]*)@)?([^/#?]*?)(?::([0-9]+))?(?=[/#?]|$))?([^?#]+)?(?:\\?([^#]*))?(?:#([\\s\\S]*))?$/;\nh.uri.O.Ib={Ii:1,mn:2,gh:3,oh:4,Fp:5,kn:6,xp:7};h.uri.O.split=function(a){return a.match(h.uri.O.eW)};h.uri.O.oo=function(a,b){return a?b?decodeURI(a):decodeURIComponent(a):a};h.uri.O.hk=function(a,b){return h.uri.O.split(b)[a]||null};h.uri.O.bm=function(a){return h.uri.O.hk(h.uri.O.Ib.Ii,a)};h.uri.O.r6=function(a){a=h.uri.O.bm(a);!a&&h.global.self&&h.global.self.location&&(a=h.global.self.location.protocol,a=a.substr(0,a.length-1));return a?a.toLowerCase():\"\"};\nh.uri.O.LM=function(a){return h.uri.O.hk(h.uri.O.Ib.mn,a)};h.uri.O.yo=function(a){return h.uri.O.oo(h.uri.O.LM(a))};h.uri.O.vL=function(a){return h.uri.O.hk(h.uri.O.Ib.gh,a)};h.uri.O.uo=function(a){return h.uri.O.oo(h.uri.O.vL(a),!0)};h.uri.O.wo=function(a){return Number(h.uri.O.hk(h.uri.O.Ib.oh,a))||null};h.uri.O.eM=function(a){return h.uri.O.hk(h.uri.O.Ib.Fp,a)};h.uri.O.ij=function(a){return h.uri.O.oo(h.uri.O.eM(a),!0)};h.uri.O.Mr=function(a){return h.uri.O.hk(h.uri.O.Ib.kn,a)};\nh.uri.O.JL=function(a){var b=a.indexOf(\"#\");return 0>b?null:a.substr(b+1)};h.uri.O.jba=function(a,b){return h.uri.O.uP(a)+(b?\"#\"+b:\"\")};h.uri.O.vo=function(a){return h.uri.O.oo(h.uri.O.JL(a))};h.uri.O.u6=function(a){a=h.uri.O.split(a);return h.uri.O.$n(a[h.uri.O.Ib.Ii],a[h.uri.O.Ib.mn],a[h.uri.O.Ib.gh],a[h.uri.O.Ib.oh])};h.uri.O.D6=function(a){a=h.uri.O.split(a);return h.uri.O.$n(a[h.uri.O.Ib.Ii],null,a[h.uri.O.Ib.gh],a[h.uri.O.Ib.oh])};\nh.uri.O.G6=function(a){a=h.uri.O.split(a);return h.uri.O.$n(null,null,null,null,a[h.uri.O.Ib.Fp],a[h.uri.O.Ib.kn],a[h.uri.O.Ib.xp])};h.uri.O.uP=function(a){var b=a.indexOf(\"#\");return 0>b?a:a.substr(0,b)};h.uri.O.ZM=function(a,b){a=h.uri.O.split(a);b=h.uri.O.split(b);return a[h.uri.O.Ib.gh]==b[h.uri.O.Ib.gh]&&a[h.uri.O.Ib.Ii]==b[h.uri.O.Ib.Ii]&&a[h.uri.O.Ib.oh]==b[h.uri.O.Ib.oh]};\nh.uri.O.OJ=function(a){h.R.assert(0>a.indexOf(\"#\")&&0>a.indexOf(\"?\"),\"goog.uri.utils: Fragment or query identifiers are not supported: [%s]\",a)};h.uri.O.SO=function(a,b){if(a){a=a.split(\"\\x26\");for(var c=0;c<a.length;c++){var e=a[c].indexOf(\"\\x3d\"),g,k=null;0<=e?(g=a[c].substring(0,e),k=a[c].substring(e+1)):g=a[c];b(g,k?h.ca.ep(k):\"\")}}};h.uri.O.Vq=function(a){if(a[1]){var b=a[0],c=b.indexOf(\"#\");0<=c&&(a.push(b.substr(c)),a[0]=b=b.substr(0,c));c=b.indexOf(\"?\");0>c?a[1]=\"?\":c==b.length-1&&(a[1]=void 0)}return a.join(\"\")};\nh.uri.O.Uq=function(a,b,c){if(h.isArray(b)){h.R.NJ(b);for(var e=0;e<b.length;e++)h.uri.O.Uq(a,String(b[e]),c)}else null!=b&&c.push(\"\\x26\",a,\"\"===b?\"\":\"\\x3d\",h.ca.Hm(b))};h.uri.O.dr=function(a,b,c){h.R.assert(0==Math.max(b.length-(c||0),0)%2,\"goog.uri.utils: Key/value lists must be even in length.\");for(c=c||0;c<b.length;c+=2)h.uri.O.Uq(b[c],b[c+1],a);return a};h.uri.O.S2=function(a,b){a=h.uri.O.dr([],a,b);a[0]=\"\";return a.join(\"\")};h.uri.O.Ww=function(a,b){for(var c in b)h.uri.O.Uq(c,b[c],a);return a};\nh.uri.O.T2=function(a){a=h.uri.O.Ww([],a);a[0]=\"\";return a.join(\"\")};h.uri.O.Y1=function(a,b){return h.uri.O.Vq(2==arguments.length?h.uri.O.dr([a],arguments[1],0):h.uri.O.dr([a],arguments,1))};h.uri.O.Z1=function(a,b){return h.uri.O.Vq(h.uri.O.Ww([a],b))};h.uri.O.KJ=function(a,b,c){a=[a,\"\\x26\",b];h.Ch(c)&&a.push(\"\\x3d\",h.ca.Hm(c));return h.uri.O.Vq(a)};\nh.uri.O.ro=function(a,b,c,e){for(var g=c.length;0<=(b=a.indexOf(c,b))&&b<e;){var k=a.charCodeAt(b-1);if(k==h.uri.O.Gk.Ht||k==h.uri.O.Gk.qE)if(k=a.charCodeAt(b+g),!k||k==h.uri.O.Gk.EQUAL||k==h.uri.O.Gk.Ht||k==h.uri.O.Gk.BD)return b;b+=g+1}return-1};h.uri.O.Ao=/#|$/;h.uri.O.P6=function(a,b){return 0<=h.uri.O.ro(a,0,b,a.search(h.uri.O.Ao))};\nh.uri.O.E6=function(a,b){var c=a.search(h.uri.O.Ao),e=h.uri.O.ro(a,0,b,c);if(0>e)return null;var g=a.indexOf(\"\\x26\",e);if(0>g||g>c)g=c;e+=b.length+1;return h.ca.ep(a.substr(e,g-e))};h.uri.O.F6=function(a,b){for(var c=a.search(h.uri.O.Ao),e=0,g,k=[];0<=(g=h.uri.O.ro(a,e,b,c));){e=a.indexOf(\"\\x26\",g);if(0>e||e>c)e=c;g+=b.length+1;k.push(h.ca.ep(a.substr(g,e-g)))}return k};h.uri.O.sW=/[?&]($|#)/;\nh.uri.O.wP=function(a,b){for(var c=a.search(h.uri.O.Ao),e=0,g,k=[];0<=(g=h.uri.O.ro(a,e,b,c));)k.push(a.substring(e,g)),e=Math.min(a.indexOf(\"\\x26\",g)+1||c,c);k.push(a.substr(e));return k.join(\"\").replace(h.uri.O.sW,\"$1\")};h.uri.O.HT=function(a,b,c){return h.uri.O.KJ(h.uri.O.wP(a,b),b,c)};h.uri.O.a2=function(a,b){h.uri.O.OJ(a);h.ca.endsWith(a,\"/\")&&(a=a.substr(0,a.length-1));h.ca.startsWith(b,\"/\")&&(b=b.substr(1));return h.ca.ZJ(a,\"/\",b)};\nh.uri.O.uj=function(a,b){h.ca.startsWith(b,\"/\")||(b=\"/\"+b);a=h.uri.O.split(a);return h.uri.O.$n(a[h.uri.O.Ib.Ii],a[h.uri.O.Ib.mn],a[h.uri.O.Ib.gh],a[h.uri.O.Ib.oh],b,a[h.uri.O.Ib.kn],a[h.uri.O.Ib.xp])};h.uri.O.cv={Zu:\"zx\"};h.uri.O.cO=function(a){return h.uri.O.HT(a,h.uri.O.cv.Zu,h.ca.eA())};h.Ab={};h.Ab.paa=function(a){return Math.floor(Math.random()*a)};h.Ab.lda=function(a,b){return a+Math.random()*(b-a)};h.Ab.clamp=function(a,b,c){return Math.min(Math.max(a,b),c)};\nh.Ab.PB=function(a,b){a%=b;return 0>a*b?a+b:a};h.Ab.h8=function(a,b,c){return a+c*(b-a)};h.Ab.p9=function(a,b,c){return Math.abs(a-b)<=(c||1E-6)};h.Ab.vt=function(a){return h.Ab.PB(a,360)};h.Ab.Mba=function(a){return h.Ab.PB(a,2*Math.PI)};h.Ab.FC=function(a){return a*Math.PI/180};h.Ab.oW=function(a){return 180*a/Math.PI};h.Ab.V1=function(a,b){return b*Math.cos(h.Ab.FC(a))};h.Ab.W1=function(a,b){return b*Math.sin(h.Ab.FC(a))};h.Ab.angle=function(a,b,c,e){return h.Ab.vt(h.Ab.oW(Math.atan2(e-b,c-a)))};\nh.Ab.U1=function(a,b){a=h.Ab.vt(b)-h.Ab.vt(a);180<a?a-=360:-180>=a&&(a=360+a);return a};h.Ab.sign=function(a){return 0<a?1:0>a?-1:a};\nh.Ab.o8=function(a,b,c,e){c=c||function(a,b){return a==b};e=e||function(b){return a[b]};for(var g=a.length,k=b.length,m=[],n=0;n<g+1;n++)m[n]=[],m[n][0]=0;for(var q=0;q<k+1;q++)m[0][q]=0;for(n=1;n<=g;n++)for(q=1;q<=k;q++)c(a[n-1],b[q-1])?m[n][q]=m[n-1][q-1]+1:m[n][q]=Math.max(m[n-1][q],m[n][q-1]);for(var v=[],n=g,q=k;0<n&&0<q;)c(a[n-1],b[q-1])?(v.unshift(e(n-1,q-1)),n--,q--):m[n-1][q]>m[n][q-1]?n--:q--;return v};h.Ab.sum=function(a){return h.aa.reduce(arguments,function(a,c){return a+c},0)};\nh.Ab.Pw=function(a){return h.Ab.sum.apply(null,arguments)/arguments.length};h.Ab.VP=function(a){var b=arguments.length;if(2>b)return 0;var c=h.Ab.Pw.apply(null,arguments);return b=h.Ab.sum.apply(null,h.aa.map(arguments,function(a){return Math.pow(a-c,2)}))/(b-1)};h.Ab.fW=function(a){return Math.sqrt(h.Ab.VP.apply(null,arguments))};h.Ab.Do=function(a){return isFinite(a)&&0==a%1};h.Ab.J7=function(a){return isFinite(a)&&!isNaN(a)};h.Ab.N7=function(a){return 0==a&&0>1/a};\nh.Ab.k8=function(a){if(0<a){var b=Math.round(Math.log(a)*Math.LOG10E);return b-(parseFloat(\"1e\"+b)>a?1:0)}return 0==a?-Infinity:NaN};h.Ab.Raa=function(a,b){h.R.assert(!h.Pe(b)||0<b);return Math.floor(a+(b||2E-15))};h.Ab.Qaa=function(a,b){h.R.assert(!h.Pe(b)||0<b);return Math.ceil(a-(b||2E-15))};h.Eb={};h.Eb.zh=function(a){return a.zh&&\"function\"==typeof a.zh?a.zh():h.Gd(a)||h.Hb(a)?a.length:h.object.zh(a)};\nh.Eb.Lc=function(a){if(a.Lc&&\"function\"==typeof a.Lc)return a.Lc();if(h.Hb(a))return a.split(\"\");if(h.Gd(a)){for(var b=[],c=a.length,e=0;e<c;e++)b.push(a[e]);return b}return h.object.Lc(a)};h.Eb.getKeys=function(a){if(a.getKeys&&\"function\"==typeof a.getKeys)return a.getKeys();if(!a.Lc||\"function\"!=typeof a.Lc){if(h.Gd(a)||h.Hb(a)){var b=[];a=a.length;for(var c=0;c<a;c++)b.push(c);return b}return h.object.getKeys(a)}};\nh.Eb.contains=function(a,b){return a.contains&&\"function\"==typeof a.contains?a.contains(b):a.ej&&\"function\"==typeof a.ej?a.ej(b):h.Gd(a)||h.Hb(a)?h.aa.contains(a,b):h.object.ej(a,b)};h.Eb.Zc=function(a){return a.Zc&&\"function\"==typeof a.Zc?a.Zc():h.Gd(a)||h.Hb(a)?h.aa.Zc(a):h.object.Zc(a)};h.Eb.clear=function(a){a.clear&&\"function\"==typeof a.clear?a.clear():h.Gd(a)?h.aa.clear(a):h.object.clear(a)};\nh.Eb.forEach=function(a,b,c){if(a.forEach&&\"function\"==typeof a.forEach)a.forEach(b,c);else if(h.Gd(a)||h.Hb(a))h.aa.forEach(a,b,c);else for(var e=h.Eb.getKeys(a),g=h.Eb.Lc(a),k=g.length,m=0;m<k;m++)b.call(c,g[m],e&&e[m],a)};\nh.Eb.filter=function(a,b,c){if(\"function\"==typeof a.filter)return a.filter(b,c);if(h.Gd(a)||h.Hb(a))return h.aa.filter(a,b,c);var e,g=h.Eb.getKeys(a),k=h.Eb.Lc(a),m=k.length;if(g){e={};for(var n=0;n<m;n++)b.call(c,k[n],g[n],a)&&(e[g[n]]=k[n])}else for(e=[],n=0;n<m;n++)b.call(c,k[n],void 0,a)&&e.push(k[n]);return e};\nh.Eb.map=function(a,b,c){if(\"function\"==typeof a.map)return a.map(b,c);if(h.Gd(a)||h.Hb(a))return h.aa.map(a,b,c);var e,g=h.Eb.getKeys(a),k=h.Eb.Lc(a),m=k.length;if(g){e={};for(var n=0;n<m;n++)e[g[n]]=b.call(c,k[n],g[n],a)}else for(e=[],n=0;n<m;n++)e[n]=b.call(c,k[n],void 0,a);return e};\nh.Eb.some=function(a,b,c){if(\"function\"==typeof a.some)return a.some(b,c);if(h.Gd(a)||h.Hb(a))return h.aa.some(a,b,c);for(var e=h.Eb.getKeys(a),g=h.Eb.Lc(a),k=g.length,m=0;m<k;m++)if(b.call(c,g[m],e&&e[m],a))return!0;return!1};h.Eb.every=function(a,b,c){if(\"function\"==typeof a.every)return a.every(b,c);if(h.Gd(a)||h.Hb(a))return h.aa.every(a,b,c);for(var e=h.Eb.getKeys(a),g=h.Eb.Lc(a),k=g.length,m=0;m<k;m++)if(!b.call(c,g[m],e&&e[m],a))return!1;return!0};h.ta={};\nh.ta.We=\"StopIteration\"in h.global?h.global.StopIteration:{message:\"StopIteration\",stack:\"\"};h.ta.Iterator=function(){};h.ta.Iterator.prototype.next=function(){throw h.ta.We;};h.ta.Iterator.prototype.Wp=function(){return this};h.ta.Hd=function(a){if(a instanceof h.ta.Iterator)return a;if(\"function\"==typeof a.Wp)return a.Wp(!1);if(h.Gd(a)){var b=0,c=new h.ta.Iterator;c.next=function(){for(;;){if(b>=a.length)throw h.ta.We;if(b in a)return a[b++];b++}};return c}throw Error(\"Not implemented\");};\nh.ta.forEach=function(a,b,c){if(h.Gd(a))try{h.aa.forEach(a,b,c)}catch(e){if(e!==h.ta.We)throw e;}else{a=h.ta.Hd(a);try{for(;;)b.call(c,a.next(),void 0,a)}catch(e){if(e!==h.ta.We)throw e;}}};h.ta.filter=function(a,b,c){var e=h.ta.Hd(a);a=new h.ta.Iterator;a.next=function(){for(;;){var a=e.next();if(b.call(c,a,void 0,e))return a}};return a};h.ta.Y5=function(a,b,c){return h.ta.filter(a,h.gc.not(b),c)};\nh.ta.range=function(a,b,c){var e=0,g=a,k=c||1;1<arguments.length&&(e=a,g=b);if(0==k)throw Error(\"Range step argument must not be zero\");var m=new h.ta.Iterator;m.next=function(){if(0<k&&e>=g||0>k&&e<=g)throw h.ta.We;var a=e;e+=k;return a};return m};h.ta.join=function(a,b){return h.ta.toArray(a).join(b)};h.ta.map=function(a,b,c){var e=h.ta.Hd(a);a=new h.ta.Iterator;a.next=function(){var a=e.next();return b.call(c,a,void 0,e)};return a};\nh.ta.reduce=function(a,b,c,e){var g=c;h.ta.forEach(a,function(a){g=b.call(e,g,a)});return g};h.ta.some=function(a,b,c){a=h.ta.Hd(a);try{for(;;)if(b.call(c,a.next(),void 0,a))return!0}catch(e){if(e!==h.ta.We)throw e;}return!1};h.ta.every=function(a,b,c){a=h.ta.Hd(a);try{for(;;)if(!b.call(c,a.next(),void 0,a))return!1}catch(e){if(e!==h.ta.We)throw e;}return!0};h.ta.p3=function(a){return h.ta.eK(arguments)};\nh.ta.eK=function(a){var b=h.ta.Hd(a);a=new h.ta.Iterator;var c=null;a.next=function(){for(;;){if(null==c){var a=b.next();c=h.ta.Hd(a)}try{return c.next()}catch(g){if(g!==h.ta.We)throw g;c=null}}};return a};h.ta.i5=function(a,b,c){var e=h.ta.Hd(a);a=new h.ta.Iterator;var g=!0;a.next=function(){for(;;){var a=e.next();if(!g||!b.call(c,a,void 0,e))return g=!1,a}};return a};\nh.ta.vca=function(a,b,c){var e=h.ta.Hd(a);a=new h.ta.Iterator;a.next=function(){var a=e.next();if(b.call(c,a,void 0,e))return a;throw h.ta.We;};return a};h.ta.toArray=function(a){if(h.Gd(a))return h.aa.toArray(a);a=h.ta.Hd(a);var b=[];h.ta.forEach(a,function(a){b.push(a)});return b};h.ta.ii=function(a,b,c){var e={};a=h.ta.RW(e,a,b);var g=c||h.aa.tx;return h.ta.every(a,function(a){return g(a[0],a[1])})};h.ta.DO=function(a,b){try{return h.ta.Hd(a).next()}catch(c){if(c!=h.ta.We)throw c;return b}};\nh.ta.product=function(a){var b=h.aa.some(arguments,function(a){return!a.length});if(b||!arguments.length)return new h.ta.Iterator;var b=new h.ta.Iterator,c=arguments,e=h.aa.repeat(0,c.length);b.next=function(){if(e){for(var a=h.aa.map(e,function(a,b){return c[b][a]}),b=e.length-1;0<=b;b--){h.R.assert(e);if(e[b]<c[b].length-1){e[b]++;break}if(0==b){e=null;break}e[b]=0}return a}throw h.ta.We;};return b};\nh.ta.E4=function(a){var b=h.ta.Hd(a),c=[],e=0;a=new h.ta.Iterator;var g=!1;a.next=function(){var a=null;if(!g)try{return a=b.next(),c.push(a),a}catch(m){if(m!=h.ta.We||h.aa.Zc(c))throw m;g=!0}a=c[e];e=(e+1)%c.length;return a};return a};h.ta.count=function(a,b){var c=a||0,e=h.Pe(b)?b:1;a=new h.ta.Iterator;a.next=function(){var a=c;c+=e;return a};return a};h.ta.repeat=function(a){var b=new h.ta.Iterator;b.next=h.gc.cj(a);return b};\nh.ta.K1=function(a){var b=h.ta.Hd(a),c=0;a=new h.ta.Iterator;a.next=function(){return c+=b.next()};return a};h.ta.zip=function(a){var b=arguments,c=new h.ta.Iterator;if(0<b.length){var e=h.aa.map(b,h.ta.Hd);c.next=function(){var a=h.aa.map(e,function(a){return a.next()});return a}}return c};\nh.ta.RW=function(a,b){var c=h.aa.slice(arguments,1),e=new h.ta.Iterator;if(0<c.length){var g=h.aa.map(c,h.ta.Hd);e.next=function(){var b=!1,c=h.aa.map(g,function(c){var e;try{e=c.next(),b=!0}catch(v){if(v!==h.ta.We)throw v;e=a}return e});if(!b)throw h.ta.We;return c}}return e};h.ta.L3=function(a,b){var c=h.ta.Hd(b);return h.ta.filter(a,function(){return!!c.next()})};h.ta.Sm=function(a,b){this.iterator=h.ta.Hd(a);this.DB=b||h.gc.bN};h.da(h.ta.Sm,h.ta.Iterator);\nh.ta.Sm.prototype.next=function(){for(;this.Bl==this.EC;)this.mo=this.iterator.next(),this.Bl=this.DB(this.mo);this.EC=this.Bl;return[this.Bl,this.QM(this.EC)]};h.ta.Sm.prototype.QM=function(a){for(var b=[];this.Bl==a;){b.push(this.mo);try{this.mo=this.iterator.next()}catch(c){if(c!==h.ta.We)throw c;break}this.Bl=this.DB(this.mo)}return b};h.ta.O6=function(a,b){return new h.ta.Sm(a,b)};\nh.ta.Nba=function(a,b,c){var e=h.ta.Hd(a);a=new h.ta.Iterator;a.next=function(){var a=h.ta.toArray(e.next());return b.apply(c,h.aa.concat(a,void 0,e))};return a};h.ta.tee=function(a,b){var c=h.ta.Hd(a);a=h.ni(b)?b:2;var e=h.aa.map(h.aa.range(a),function(){return[]}),g=function(){var a=c.next();h.aa.forEach(e,function(b){b.push(a)})};a=function(a){var b=new h.ta.Iterator;b.next=function(){h.aa.Zc(a)&&g();h.R.assert(!h.aa.Zc(a));return a.shift()};return b};return h.aa.map(e,a)};\nh.ta.s5=function(a,b){return h.ta.zip(h.ta.count(b),a)};h.ta.TN=function(a,b){h.R.assert(h.Ab.Do(b)&&0<=b);var c=h.ta.Hd(a);a=new h.ta.Iterator;var e=b;a.next=function(){if(0<e--)return c.next();throw h.ta.We;};return a};h.ta.pK=function(a,b){h.R.assert(h.Ab.Do(b)&&0<=b);for(a=h.ta.Hd(a);0<b--;)h.ta.DO(a,null);return a};h.ta.slice=function(a,b,c){h.R.assert(h.Ab.Do(b)&&0<=b);a=h.ta.pK(a,b);h.ni(c)&&(h.R.assert(h.Ab.Do(c)&&c>=b),a=h.ta.TN(a,c-b));return a};\nh.ta.SM=function(a){var b=[];h.aa.tP(a,b);return a.length!=b.length};h.ta.WO=function(a,b){a=h.ta.toArray(a);b=h.ni(b)?b:a.length;b=h.aa.repeat(a,b);b=h.ta.product.apply(void 0,b);return h.ta.filter(b,function(a){return!h.ta.SM(a)})};h.ta.F3=function(a,b){function c(a){return e[a]}var e=h.ta.toArray(a);a=h.ta.range(e.length);b=h.ta.WO(a,b);var g=h.ta.filter(b,function(a){return h.aa.yB(a)});b=new h.ta.Iterator;b.next=function(){return h.aa.map(g.next(),c)};return b};\nh.ta.G3=function(a,b){function c(a){return e[a]}var e=h.ta.toArray(a);a=h.aa.range(e.length);b=h.aa.repeat(a,b);b=h.ta.product.apply(void 0,b);var g=h.ta.filter(b,function(a){return h.aa.yB(a)});b=new h.ta.Iterator;b.next=function(){return h.aa.map(g.next(),c)};return b};h.Eb.Map=function(a,b){this.jc={};this.Mc=[];this.Im=this.Cc=0;var c=arguments.length;if(1<c){if(c%2)throw Error(\"Uneven number of arguments\");for(var e=0;e<c;e+=2)this.set(arguments[e],arguments[e+1])}else a&&this.addAll(a)};d=h.Eb.Map.prototype;\nd.zh=function(){return this.Cc};d.Lc=function(){this.ek();for(var a=[],b=0;b<this.Mc.length;b++){var c=this.Mc[b];a.push(this.jc[c])}return a};d.getKeys=function(){this.ek();return this.Mc.concat()};d.dj=function(a){return h.Eb.Map.jj(this.jc,a)};d.ej=function(a){for(var b=0;b<this.Mc.length;b++){var c=this.Mc[b];if(h.Eb.Map.jj(this.jc,c)&&this.jc[c]==a)return!0}return!1};\nd.ii=function(a,b){if(this===a)return!0;if(this.Cc!=a.zh())return!1;b=b||h.Eb.Map.HK;this.ek();for(var c,e=0;c=this.Mc[e];e++)if(!b(this.get(c),a.get(c)))return!1;return!0};h.Eb.Map.HK=function(a,b){return a===b};d=h.Eb.Map.prototype;d.Zc=function(){return 0==this.Cc};d.clear=function(){this.jc={};this.Im=this.Cc=this.Mc.length=0};d.remove=function(a){return h.Eb.Map.jj(this.jc,a)?(delete this.jc[a],this.Cc--,this.Im++,this.Mc.length>2*this.Cc&&this.ek(),!0):!1};\nd.ek=function(){if(this.Cc!=this.Mc.length){for(var a=0,b=0;a<this.Mc.length;){var c=this.Mc[a];h.Eb.Map.jj(this.jc,c)&&(this.Mc[b++]=c);a++}this.Mc.length=b}if(this.Cc!=this.Mc.length){for(var e={},b=a=0;a<this.Mc.length;)c=this.Mc[a],h.Eb.Map.jj(e,c)||(this.Mc[b++]=c,e[c]=1),a++;this.Mc.length=b}};d.get=function(a,b){return h.Eb.Map.jj(this.jc,a)?this.jc[a]:b};d.set=function(a,b){h.Eb.Map.jj(this.jc,a)||(this.Cc++,this.Mc.push(a),this.Im++);this.jc[a]=b};\nd.addAll=function(a){var b;a instanceof h.Eb.Map?(b=a.getKeys(),a=a.Lc()):(b=h.object.getKeys(a),a=h.object.Lc(a));for(var c=0;c<b.length;c++)this.set(b[c],a[c])};d.forEach=function(a,b){for(var c=this.getKeys(),e=0;e<c.length;e++){var g=c[e],k=this.get(g);a.call(b,k,g,this)}};d.clone=function(){return new h.Eb.Map(this)};d.transpose=function(){for(var a=new h.Eb.Map,b=0;b<this.Mc.length;b++){var c=this.Mc[b],e=this.jc[c];a.set(e,c)}return a};\nd.C=function(){this.ek();for(var a={},b=0;b<this.Mc.length;b++){var c=this.Mc[b];a[c]=this.jc[c]}return a};d.Wp=function(a){this.ek();var b=0,c=this.Im,e=this,g=new h.ta.Iterator;g.next=function(){if(c!=e.Im)throw Error(\"The map has changed since the iterator was created\");if(b>=e.Mc.length)throw h.ta.We;var g=e.Mc[b++];return a?g:e.jc[g]};return g};h.Eb.Map.jj=function(a,b){return Object.prototype.hasOwnProperty.call(a,b)};\nh.ab=function(a,b){this.tr=this.Dt=this.yk=\"\";this.Po=null;this.Ar=this.vk=\"\";this.ug=this.DN=!1;var c;a instanceof h.ab?(this.ug=h.Pe(b)?b:a.ug,this.Wo(a.bm()),this.Xo(a.yo()),this.To(a.uo()),this.Vo(a.wo()),this.uj(a.ij()),this.zm(a.Mr().clone()),this.Uo(a.vo())):a&&(c=h.uri.O.split(String(a)))?(this.ug=!!b,this.Wo(c[h.uri.O.Ib.Ii]||\"\",!0),this.Xo(c[h.uri.O.Ib.mn]||\"\",!0),this.To(c[h.uri.O.Ib.gh]||\"\",!0),this.Vo(c[h.uri.O.Ib.oh]),this.uj(c[h.uri.O.Ib.Fp]||\"\",!0),this.zm(c[h.uri.O.Ib.kn]||\"\",!0),\nthis.Uo(c[h.uri.O.Ib.xp]||\"\",!0)):(this.ug=!!b,this.Gh=new h.ab.Sg(null,null,this.ug))};h.ab.ZO=!1;h.ab.rE=h.uri.O.cv.Zu;d=h.ab.prototype;\nd.toString=function(){var a=[],b=this.bm();b&&a.push(h.ab.Gl(b,h.ab.aC,!0),\":\");var c=this.uo();if(c||\"file\"==b)a.push(\"//\"),(b=this.yo())&&a.push(h.ab.Gl(b,h.ab.aC,!0),\"@\"),a.push(h.ab.fC(h.ca.Hm(c))),c=this.wo(),null!=c&&a.push(\":\",String(c));if(c=this.ij())this.Wr()&&\"/\"!=c.charAt(0)&&a.push(\"/\"),a.push(h.ab.Gl(c,\"/\"==c.charAt(0)?h.ab.gP:h.ab.jP,!0));(c=this.Ky())&&a.push(\"?\",c);(c=this.vo())&&a.push(\"#\",h.ab.Gl(c,h.ab.hP));return a.join(\"\")};\nd.resolve=function(a){var b=this.clone(),c=a.WM();c?b.Wo(a.bm()):c=a.XM();c?b.Xo(a.yo()):c=a.Wr();c?b.To(a.uo()):c=a.UM();var e=a.ij();if(c)b.Vo(a.wo());else if(c=a.Yr()){if(\"/\"!=e.charAt(0))if(this.Wr()&&!this.Yr())e=\"/\"+e;else{var g=b.ij().lastIndexOf(\"/\");-1!=g&&(e=b.ij().substr(0,g+1)+e)}e=h.ab.sP(e)}c?b.uj(e):c=a.VM();c?b.zm(a.Mr().clone()):c=a.TM();c&&b.Uo(a.vo());return b};d.clone=function(){return new h.ab(this)};d.bm=function(){return this.yk};\nd.Wo=function(a,b){this.xh();if(this.yk=b?h.ab.El(a,!0):a)this.yk=this.yk.replace(/:$/,\"\");return this};d.WM=function(){return!!this.yk};d.yo=function(){return this.Dt};d.Xo=function(a,b){this.xh();this.Dt=b?h.ab.El(a):a;return this};d.XM=function(){return!!this.Dt};d.uo=function(){return this.tr};d.To=function(a,b){this.xh();this.tr=b?h.ab.El(a,!0):a;return this};d.Wr=function(){return!!this.tr};d.wo=function(){return this.Po};\nd.Vo=function(a){this.xh();if(a){a=Number(a);if(isNaN(a)||0>a)throw Error(\"Bad port number \"+a);this.Po=a}else this.Po=null;return this};d.UM=function(){return null!=this.Po};d.ij=function(){return this.vk};d.uj=function(a,b){this.xh();this.vk=b?h.ab.El(a,!0):a;return this};d.Yr=function(){return!!this.vk};d.VM=function(){return\"\"!==this.Gh.toString()};\nd.zm=function(a,b){this.xh();a instanceof h.ab.Sg?(this.Gh=a,this.Gh.Ws(this.ug)):(b||(a=h.ab.Gl(a,h.ab.iP)),this.Gh=new h.ab.Sg(a,null,this.ug));return this};d.setQuery=function(a,b){return this.zm(a,b)};d.Ky=function(){return this.Gh.toString()};d.Mr=function(){return this.Gh};d.getQuery=function(){return this.Ky()};d.IT=function(a,b){this.xh();this.Gh.set(a,b);return this};d.vo=function(){return this.Ar};d.Uo=function(a,b){this.xh();this.Ar=b?h.ab.El(a):a;return this};d.TM=function(){return!!this.Ar};\nd.cO=function(){this.xh();this.IT(h.ab.rE,h.ca.eA());return this};d.xh=function(){if(this.DN)throw Error(\"Tried to modify a read-only Uri\");};d.Ws=function(a){this.ug=a;this.Gh&&this.Gh.Ws(a);return this};h.ab.parse=function(a,b){return a instanceof h.ab?a.clone():new h.ab(a,b)};h.ab.create=function(a,b,c,e,g,k,m,n){n=new h.ab(null,n);a&&n.Wo(a);b&&n.Xo(b);c&&n.To(c);e&&n.Vo(e);g&&n.uj(g);k&&n.zm(k);m&&n.Uo(m);return n};\nh.ab.resolve=function(a,b){a instanceof h.ab||(a=h.ab.parse(a));b instanceof h.ab||(b=h.ab.parse(b));return a.resolve(b)};h.ab.sP=function(a){if(\"..\"==a||\".\"==a)return\"\";if(h.ca.contains(a,\"./\")||h.ca.contains(a,\"/.\")){var b=h.ca.startsWith(a,\"/\");a=a.split(\"/\");for(var c=[],e=0;e<a.length;){var g=a[e++];\".\"==g?b&&e==a.length&&c.push(\"\"):\"..\"==g?((1<c.length||1==c.length&&\"\"!=c[0])&&c.pop(),b&&e==a.length&&c.push(\"\")):(c.push(g),b=!0)}return c.join(\"/\")}return a};\nh.ab.El=function(a,b){return a?b?decodeURI(a.replace(/%25/g,\"%2525\")):decodeURIComponent(a):\"\"};h.ab.Gl=function(a,b,c){return h.Hb(a)?(a=encodeURI(a).replace(b,h.ab.PK),c&&(a=h.ab.fC(a)),a):null};h.ab.PK=function(a){a=a.charCodeAt(0);return\"%\"+(a>>4&15).toString(16)+(a&15).toString(16)};h.ab.fC=function(a){return a.replace(/%25([0-9a-fA-F]{2})/g,\"%$1\")};h.ab.aC=/[#\\/\\?@]/g;h.ab.jP=/[\\#\\?:]/g;h.ab.gP=/[\\#\\?]/g;h.ab.iP=/[\\#\\?@]/g;h.ab.hP=/#/g;\nh.ab.ZM=function(a,b){a=h.uri.O.split(a);b=h.uri.O.split(b);return a[h.uri.O.Ib.gh]==b[h.uri.O.Ib.gh]&&a[h.uri.O.Ib.oh]==b[h.uri.O.Ib.oh]};h.ab.Sg=function(a,b,c){this.Cc=this.sd=null;this.hi=a||null;this.ug=!!c};h.ab.Sg.prototype.yh=function(){if(!this.sd&&(this.sd=new h.Eb.Map,this.Cc=0,this.hi)){var a=this;h.uri.O.SO(this.hi,function(b,c){a.add(h.ca.ep(b),c)})}};\nh.ab.Sg.w4=function(a,b,c){b=h.Eb.getKeys(a);if(\"undefined\"==typeof b)throw Error(\"Keys are undefined\");c=new h.ab.Sg(null,null,c);a=h.Eb.Lc(a);for(var e=0;e<b.length;e++){var g=b[e],k=a[e];h.isArray(k)?c.Yo(g,k):c.add(g,k)}return c};h.ab.Sg.v4=function(a,b,c,e){if(a.length!=b.length)throw Error(\"Mismatched lengths for keys/values\");c=new h.ab.Sg(null,null,e);for(e=0;e<a.length;e++)c.add(a[e],b[e]);return c};d=h.ab.Sg.prototype;d.zh=function(){this.yh();return this.Cc};\nd.add=function(a,b){this.yh();this.qk();a=this.kk(a);var c=this.sd.get(a);c||this.sd.set(a,c=[]);c.push(b);this.Cc=h.R.ul(this.Cc)+1;return this};d.remove=function(a){this.yh();a=this.kk(a);return this.sd.dj(a)?(this.qk(),this.Cc=h.R.ul(this.Cc)-this.sd.get(a).length,this.sd.remove(a)):!1};d.clear=function(){this.qk();this.sd=null;this.Cc=0};d.Zc=function(){this.yh();return 0==this.Cc};d.dj=function(a){this.yh();a=this.kk(a);return this.sd.dj(a)};\nd.ej=function(a){var b=this.Lc();return h.aa.contains(b,a)};d.getKeys=function(){this.yh();for(var a=this.sd.Lc(),b=this.sd.getKeys(),c=[],e=0;e<b.length;e++)for(var g=a[e],k=0;k<g.length;k++)c.push(b[e]);return c};d.Lc=function(a){this.yh();var b=[];if(h.Hb(a))this.dj(a)&&(b=h.aa.concat(b,this.sd.get(this.kk(a))));else{a=this.sd.Lc();for(var c=0;c<a.length;c++)b=h.aa.concat(b,a[c])}return b};\nd.set=function(a,b){this.yh();this.qk();a=this.kk(a);this.dj(a)&&(this.Cc=h.R.ul(this.Cc)-this.sd.get(a).length);this.sd.set(a,[b]);this.Cc=h.R.ul(this.Cc)+1;return this};d.get=function(a,b){a=a?this.Lc(a):[];return h.ab.ZO?0<a.length?a[0]:b:0<a.length?String(a[0]):b};d.Yo=function(a,b){this.remove(a);0<b.length&&(this.qk(),this.sd.set(this.kk(a),h.aa.clone(b)),this.Cc=h.R.ul(this.Cc)+b.length)};\nd.toString=function(){if(this.hi)return this.hi;if(!this.sd)return\"\";for(var a=[],b=this.sd.getKeys(),c=0;c<b.length;c++)for(var e=b[c],g=h.ca.Hm(e),e=this.Lc(e),k=0;k<e.length;k++){var m=g;\"\"!==e[k]&&(m+=\"\\x3d\"+h.ca.Hm(e[k]));a.push(m)}return this.hi=a.join(\"\\x26\")};d.qk=function(){this.hi=null};d.clone=function(){var a=new h.ab.Sg;a.hi=this.hi;this.sd&&(a.sd=this.sd.clone(),a.Cc=this.Cc);return a};d.kk=function(a){a=String(a);this.ug&&(a=a.toLowerCase());return a};\nd.Ws=function(a){var b=a&&!this.ug;b&&(this.yh(),this.qk(),this.sd.forEach(function(a,b){var c=b.toLowerCase();b!=c&&(this.remove(b),this.Yo(c,a))},this));this.ug=a};d.extend=function(a){for(var b=0;b<arguments.length;b++){var c=arguments[b];h.Eb.forEach(c,function(a,b){this.add(b,a)},this)}};x.google={};x.google.N={};x.google.N.ge=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.google.N.ge,l.u);\nl.u.ha&&(x.google.N.ge.prototype.C=function(a){return x.google.N.ge.C(a,this)},x.google.N.ge.C=function(a,b){var c={jda:l.u.va(b,1,\"\"),value:b.Qr()};a&&(c.ja=b);return c});x.google.N.ge.ia=function(a){a=new l.ba(a);var b=new x.google.N.ge;return x.google.N.ge.F(b,a)};x.google.N.ge.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.pt(c);break;case 2:c=b.qm();a.setValue(c);break;default:b.ea()}}return a};\nx.google.N.ge.G=function(a,b){var c;c=a.TA();0<c.length&&b.Ja(1,c);c=a.Rr();0<c.length&&b.fp(2,c)};d=x.google.N.ge.prototype;d.TA=function(){return l.u.va(this,1,\"\")};d.pt=function(a){l.u.J(this,1,a)};d.getValue=function(){return l.u.va(this,2,\"\")};d.Qr=function(){return l.u.ao(this.getValue())};d.Rr=function(){return l.u.hr(this.getValue())};d.setValue=function(a){l.u.J(this,2,a)};x.google.N.ge.K=function(a){return l.u.K(x.google.N.ge,a)};x.google.N.ge.prototype.getTypeName=function(){return this.TA().split(\"/\").pop()};\nx.google.N.ge.prototype.pack=function(a,b,c){c||(c=\"type.googleapis.com/\");\"/\"!=c.substr(-1)?this.pt(c+\"/\"+b):this.pt(c+b);this.setValue(a)};x.google.N.Ba=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.google.N.Ba,l.u);l.u.ha&&(x.google.N.Ba.prototype.C=function(a){return x.google.N.Ba.C(a,this)},x.google.N.Ba.C=function(a,b){var c={value:+l.u.va(b,1,0)};a&&(c.ja=b);return c});x.google.N.Ba.ia=function(a){a=new l.ba(a);var b=new x.google.N.Ba;return x.google.N.Ba.F(b,a)};\nx.google.N.Ba.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.pa();a.setValue(c);break;default:b.ea()}}return a};x.google.N.Ba.G=function(a,b){a=a.getValue();0!==a&&b.ya(1,a)};x.google.N.Ba.prototype.getValue=function(){return+l.u.va(this,1,0)};x.google.N.Ba.prototype.setValue=function(a){l.u.J(this,1,a)};x.google.N.Ba.K=function(a){return l.u.K(x.google.N.Ba,a)};x.google.N.Rf=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.google.N.Rf,l.u);\nl.u.ha&&(x.google.N.Rf.prototype.C=function(a){return x.google.N.Rf.C(a,this)},x.google.N.Rf.C=function(a,b){var c={value:+l.u.va(b,1,0)};a&&(c.ja=b);return c});x.google.N.Rf.ia=function(a){a=new l.ba(a);var b=new x.google.N.Rf;return x.google.N.Rf.F(b,a)};x.google.N.Rf.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.ti();a.setValue(c);break;default:b.ea()}}return a};x.google.N.Rf.G=function(a,b){a=a.getValue();0!==a&&b.vi(1,a)};\nx.google.N.Rf.prototype.getValue=function(){return+l.u.va(this,1,0)};x.google.N.Rf.prototype.setValue=function(a){l.u.J(this,1,a)};x.google.N.Rf.K=function(a){return l.u.K(x.google.N.Rf,a)};x.google.N.Tf=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.google.N.Tf,l.u);l.u.ha&&(x.google.N.Tf.prototype.C=function(a){return x.google.N.Tf.C(a,this)},x.google.N.Tf.C=function(a,b){var c={value:l.u.va(b,1,0)};a&&(c.ja=b);return c});\nx.google.N.Tf.ia=function(a){a=new l.ba(a);var b=new x.google.N.Tf;return x.google.N.Tf.F(b,a)};x.google.N.Tf.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.ad();a.setValue(c);break;default:b.ea()}}return a};x.google.N.Tf.G=function(a,b){a=a.getValue();0!==a&&b.td(1,a)};x.google.N.Tf.prototype.getValue=function(){return l.u.va(this,1,0)};x.google.N.Tf.prototype.setValue=function(a){l.u.J(this,1,a)};x.google.N.Tf.K=function(a){return l.u.K(x.google.N.Tf,a)};\nx.google.N.Zf=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.google.N.Zf,l.u);l.u.ha&&(x.google.N.Zf.prototype.C=function(a){return x.google.N.Zf.C(a,this)},x.google.N.Zf.C=function(a,b){var c={value:l.u.va(b,1,0)};a&&(c.ja=b);return c});x.google.N.Zf.ia=function(a){a=new l.ba(a);var b=new x.google.N.Zf;return x.google.N.Zf.F(b,a)};x.google.N.Zf.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.ee();a.setValue(c);break;default:b.ea()}}return a};\nx.google.N.Zf.G=function(a,b){a=a.getValue();0!==a&&b.ye(1,a)};x.google.N.Zf.prototype.getValue=function(){return l.u.va(this,1,0)};x.google.N.Zf.prototype.setValue=function(a){l.u.J(this,1,a)};x.google.N.Zf.K=function(a){return l.u.K(x.google.N.Zf,a)};x.google.N.qc=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.google.N.qc,l.u);l.u.ha&&(x.google.N.qc.prototype.C=function(a){return x.google.N.qc.C(a,this)},x.google.N.qc.C=function(a,b){var c={value:l.u.va(b,1,0)};a&&(c.ja=b);return c});\nx.google.N.qc.ia=function(a){a=new l.ba(a);var b=new x.google.N.qc;return x.google.N.qc.F(b,a)};x.google.N.qc.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Ya();a.setValue(c);break;default:b.ea()}}return a};x.google.N.qc.G=function(a,b){a=a.getValue();0!==a&&b.$a(1,a)};x.google.N.qc.prototype.getValue=function(){return l.u.va(this,1,0)};x.google.N.qc.prototype.setValue=function(a){l.u.J(this,1,a)};x.google.N.qc.K=function(a){return l.u.K(x.google.N.qc,a)};\nx.google.N.Yf=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.google.N.Yf,l.u);l.u.ha&&(x.google.N.Yf.prototype.C=function(a){return x.google.N.Yf.C(a,this)},x.google.N.Yf.C=function(a,b){var c={value:l.u.va(b,1,0)};a&&(c.ja=b);return c});x.google.N.Yf.ia=function(a){a=new l.ba(a);var b=new x.google.N.Yf;return x.google.N.Yf.F(b,a)};x.google.N.Yf.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Jg();a.setValue(c);break;default:b.ea()}}return a};\nx.google.N.Yf.G=function(a,b){a=a.getValue();0!==a&&b.Pg(1,a)};x.google.N.Yf.prototype.getValue=function(){return l.u.va(this,1,0)};x.google.N.Yf.prototype.setValue=function(a){l.u.J(this,1,a)};x.google.N.Yf.K=function(a){return l.u.K(x.google.N.Yf,a)};x.google.N.Of=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.google.N.Of,l.u);l.u.ha&&(x.google.N.Of.prototype.C=function(a){return x.google.N.Of.C(a,this)},x.google.N.Of.C=function(a,b){var c={value:l.u.va(b,1,!1)};a&&(c.ja=b);return c});\nx.google.N.Of.ia=function(a){a=new l.ba(a);var b=new x.google.N.Of;return x.google.N.Of.F(b,a)};x.google.N.Of.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.vf();a.setValue(c);break;default:b.ea()}}return a};x.google.N.Of.G=function(a,b){(a=a.getValue())&&b.kf(1,a)};x.google.N.Of.prototype.getValue=function(){return l.u.va(this,1,!1)};x.google.N.Of.prototype.setValue=function(a){l.u.J(this,1,a)};x.google.N.Of.K=function(a){return l.u.K(x.google.N.Of,a)};\nx.google.N.Ke=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.google.N.Ke,l.u);l.u.ha&&(x.google.N.Ke.prototype.C=function(a){return x.google.N.Ke.C(a,this)},x.google.N.Ke.C=function(a,b){var c={value:l.u.va(b,1,\"\")};a&&(c.ja=b);return c});x.google.N.Ke.ia=function(a){a=new l.ba(a);var b=new x.google.N.Ke;return x.google.N.Ke.F(b,a)};x.google.N.Ke.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.setValue(c);break;default:b.ea()}}return a};\nx.google.N.Ke.G=function(a,b){a=a.getValue();0<a.length&&b.Ja(1,a)};x.google.N.Ke.prototype.getValue=function(){return l.u.va(this,1,\"\")};x.google.N.Ke.prototype.setValue=function(a){l.u.J(this,1,a)};x.google.N.Ke.K=function(a){return l.u.K(x.google.N.Ke,a)};x.google.N.mf=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.google.N.mf,l.u);l.u.ha&&(x.google.N.mf.prototype.C=function(a){return x.google.N.mf.C(a,this)},x.google.N.mf.C=function(a,b){var c={value:b.Qr()};a&&(c.ja=b);return c});\nx.google.N.mf.ia=function(a){a=new l.ba(a);var b=new x.google.N.mf;return x.google.N.mf.F(b,a)};x.google.N.mf.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.qm();a.setValue(c);break;default:b.ea()}}return a};x.google.N.mf.G=function(a,b){a=a.Rr();0<a.length&&b.fp(1,a)};x.google.N.mf.prototype.getValue=function(){return l.u.va(this,1,\"\")};x.google.N.mf.prototype.Qr=function(){return l.u.ao(this.getValue())};x.google.N.mf.prototype.Rr=function(){return l.u.hr(this.getValue())};\nx.google.N.mf.prototype.setValue=function(a){l.u.J(this,1,a)};x.google.N.mf.K=function(a){return l.u.K(x.google.N.mf,a)};x.qa={};x.qa.Yc=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.qa.Yc,l.u);l.u.ha&&(x.qa.Yc.prototype.C=function(a){return x.qa.Yc.C(a,this)},x.qa.Yc.C=function(a,b){var c={O8:+l.u.va(b,1,0),S8:l.u.Na(b,2),W$:+l.u.va(b,3,.1),sca:l.u.va(b,4,!0),T8:l.u.D(b,5),H5:l.u.D(b,6),n5:l.u.D(b,7)};a&&(c.ja=b);return c});\nx.qa.Yc.ia=function(a){a=new l.ba(a);var b=new x.qa.Yc;return x.qa.Yc.F(b,a)};x.qa.Yc.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.pa();a.JS(c);break;case 2:c=b.pa();a.NS(c);break;case 3:c=b.pa();a.dU(c);break;case 4:c=b.vf();a.eV(c);break;case 5:c=b.Ya();a.OS(c);break;case 6:c=b.Aa();a.wR(c);break;case 7:c=b.vf();a.oR(c);break;default:b.ea()}}return a};\nx.qa.Yc.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.ya(1,c);c=l.u.D(a,2);null!=c&&b.ya(2,c);c=l.u.D(a,3);null!=c&&b.ya(3,c);c=l.u.D(a,4);null!=c&&b.kf(4,c);c=l.u.D(a,5);null!=c&&b.$a(5,c);c=l.u.D(a,6);null!=c&&b.Ja(6,c);c=l.u.D(a,7);null!=c&&b.kf(7,c)};d=x.qa.Yc.prototype;d.JS=function(a){l.u.J(this,1,a)};d.NS=function(a){l.u.J(this,2,a)};d.dU=function(a){l.u.J(this,3,a)};d.eV=function(a){l.u.J(this,4,a)};d.OS=function(a){l.u.J(this,5,a)};d.wR=function(a){l.u.J(this,6,a)};\nd.oR=function(a){l.u.J(this,7,a)};x.qa.Yc.K=function(a){return l.u.K(x.qa.Yc,a)};x.qa.eb=function(a){l.u.initialize(this,a,0,-1,x.qa.eb.na,null)};h.da(x.qa.eb,l.u);x.qa.eb.na=[1,2,3,4];l.u.ha&&(x.qa.eb.prototype.C=function(a){return x.qa.eb.C(a,this)},x.qa.eb.C=function(a,b){var c={fca:l.u.Ka(b.BA(),x.qa.eb.Tb.C,a),lca:l.u.Ka(b.DA(),x.qa.eb.Tb.C,a),hca:l.u.Ka(b.CA(),x.qa.eb.Tb.C,a),nca:l.u.Ka(b.EA(),x.qa.eb.Tb.C,a),sO:l.u.D(b,5),tO:l.u.D(b,6)};a&&(c.ja=b);return c});\nx.qa.eb.ia=function(a){a=new l.ba(a);var b=new x.qa.eb;return x.qa.eb.F(b,a)};x.qa.eb.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.qa.eb.Tb;b.T(c,x.qa.eb.Tb.F);a.pJ(c);break;case 2:c=new x.qa.eb.Tb;b.T(c,x.qa.eb.Tb.F);a.uJ(c);break;case 3:c=new x.qa.eb.Tb;b.T(c,x.qa.eb.Tb.F);a.rJ(c);break;case 4:c=new x.qa.eb.Tb;b.T(c,x.qa.eb.Tb.F);a.wJ(c);break;case 5:c=b.Ya();a.bt(c);break;case 6:c=b.Ya();a.ct(c);break;default:b.ea()}}return a};\nx.qa.eb.G=function(a,b){var c;c=a.BA();0<c.length&&b.Oa(1,c,x.qa.eb.Tb.G);c=a.DA();0<c.length&&b.Oa(2,c,x.qa.eb.Tb.G);c=a.CA();0<c.length&&b.Oa(3,c,x.qa.eb.Tb.G);c=a.EA();0<c.length&&b.Oa(4,c,x.qa.eb.Tb.G);c=l.u.D(a,5);null!=c&&b.$a(5,c);c=l.u.D(a,6);null!=c&&b.$a(6,c)};d=x.qa.eb.prototype;d.BA=function(){return l.u.Ma(this,x.qa.eb.Tb,1)};d.pJ=function(a,b){return l.u.La(this,1,a,x.qa.eb.Tb,b)};d.DA=function(){return l.u.Ma(this,x.qa.eb.Tb,2)};\nd.uJ=function(a,b){return l.u.La(this,2,a,x.qa.eb.Tb,b)};d.CA=function(){return l.u.Ma(this,x.qa.eb.Tb,3)};d.rJ=function(a,b){return l.u.La(this,3,a,x.qa.eb.Tb,b)};d.EA=function(){return l.u.Ma(this,x.qa.eb.Tb,4)};d.wJ=function(a,b){return l.u.La(this,4,a,x.qa.eb.Tb,b)};d.bt=function(a){l.u.J(this,5,a)};d.ct=function(a){l.u.J(this,6,a)};x.qa.eb.K=function(a){return l.u.K(x.qa.eb,a)};x.qa.eb.Tb=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.qa.eb.Tb,l.u);\nl.u.ha&&(x.qa.eb.Tb.prototype.C=function(a){return x.qa.eb.Tb.C(a,this)},x.qa.eb.Tb.C=function(a,b){var c={aj:l.u.D(b,1),lowerBound:l.u.Na(b,2),upperBound:l.u.Na(b,3),n7:l.u.D(b,4)};a&&(c.ja=b);return c});x.qa.eb.Tb.ia=function(a){a=new l.ba(a);var b=new x.qa.eb.Tb;return x.qa.eb.Tb.F(b,a)};x.qa.eb.Tb.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.xf(c);break;case 2:c=b.pa();a.tj(c);break;case 3:c=b.pa();a.xj(c);break;case 4:c=b.vf();a.YR(c);break;default:b.ea()}}return a};\nx.qa.eb.Tb.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Ja(1,c);c=l.u.D(a,2);null!=c&&b.ya(2,c);c=l.u.D(a,3);null!=c&&b.ya(3,c);c=l.u.D(a,4);null!=c&&b.kf(4,c)};d=x.qa.eb.Tb.prototype;d.Hg=function(){return l.u.D(this,1)};d.xf=function(a){l.u.J(this,1,a)};d.Xl=function(){return l.u.Na(this,2)};d.tj=function(a){l.u.J(this,2,a)};d.em=function(){return l.u.Na(this,3)};d.xj=function(a){l.u.J(this,3,a)};d.YR=function(a){l.u.J(this,4,a)};x.qa.eb.Tb.K=function(a){return l.u.K(x.qa.eb.Tb,a)};\nx.qa.te=function(a){l.u.initialize(this,a,0,-1,x.qa.te.na,null)};h.da(x.qa.te,l.u);x.qa.te.na=[5,6];l.u.ha&&(x.qa.te.prototype.C=function(a){return x.qa.te.C(a,this)},x.qa.te.C=function(a,b){var c={K9:l.u.va(b,1,7),L9:l.u.va(b,2,14),u4:+l.u.va(b,3,3),t4:+l.u.va(b,4,.3),cN:l.u.D(b,5),UP:l.u.D(b,6)};a&&(c.ja=b);return c});x.qa.te.ia=function(a){a=new l.ba(a);var b=new x.qa.te;return x.qa.te.F(b,a)};\nx.qa.te.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Ya();a.nT(c);break;case 2:c=b.Ya();a.oT(c);break;case 3:c=b.pa();a.UQ(c);break;case 4:c=b.pa();a.TQ(c);break;case 5:c=b.Aa();a.Oq(c);break;case 6:c=b.Aa();a.Sq(c);break;default:b.ea()}}return a};x.qa.te.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.$a(1,c);c=l.u.D(a,2);null!=c&&b.$a(2,c);c=l.u.D(a,3);null!=c&&b.ya(3,c);c=l.u.D(a,4);null!=c&&b.ya(4,c);c=a.Hr();0<c.length&&b.oc(5,c);c=a.Or();0<c.length&&b.oc(6,c)};d=x.qa.te.prototype;\nd.nT=function(a){l.u.J(this,1,a)};d.oT=function(a){l.u.J(this,2,a)};d.UQ=function(a){l.u.J(this,3,a)};d.TQ=function(a){l.u.J(this,4,a)};d.Hr=function(){return l.u.D(this,5)};d.Oq=function(a,b){l.u.ib(this,5,a,b)};d.Or=function(){return l.u.D(this,6)};d.Sq=function(a,b){l.u.ib(this,6,a,b)};x.qa.te.K=function(a){return l.u.K(x.qa.te,a)};x.qa.Tc=function(a){l.u.initialize(this,a,0,-1,x.qa.Tc.na,null)};h.da(x.qa.Tc,l.u);x.qa.Tc.na=[9,6,8];\nl.u.ha&&(x.qa.Tc.prototype.C=function(a){return x.qa.Tc.C(a,this)},x.qa.Tc.C=function(a,b){var c={Gda:l.u.va(b,1,10),sO:l.u.va(b,2,1),tO:l.u.D(b,3),P8:+l.u.va(b,4,.05),Mda:+l.u.va(b,5,5),UP:l.u.D(b,9),cN:l.u.D(b,6),o7:l.u.D(b,8),k9:l.u.va(b,7,1)};a&&(c.ja=b);return c});x.qa.Tc.ia=function(a){a=new l.ba(a);var b=new x.qa.Tc;return x.qa.Tc.F(b,a)};\nx.qa.Tc.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Ya();a.QV(c);break;case 2:c=b.Ya();a.bt(c);break;case 3:c=b.Ya();a.ct(c);break;case 4:c=b.pa();a.KS(c);break;case 5:c=b.pa();a.SV(c);break;case 9:c=b.Aa();a.Sq(c);break;case 6:c=b.Aa();a.Oq(c);break;case 8:c=b.Aa();a.qI(c);break;case 7:c=b.Ya();a.YS(c);break;default:b.ea()}}return a};\nx.qa.Tc.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.$a(1,c);c=l.u.D(a,2);null!=c&&b.$a(2,c);c=l.u.D(a,3);null!=c&&b.$a(3,c);c=l.u.D(a,4);null!=c&&b.ya(4,c);c=l.u.D(a,5);null!=c&&b.ya(5,c);c=a.Or();0<c.length&&b.oc(9,c);c=a.Hr();0<c.length&&b.oc(6,c);c=a.ML();0<c.length&&b.oc(8,c);c=l.u.D(a,7);null!=c&&b.$a(7,c)};d=x.qa.Tc.prototype;d.QV=function(a){l.u.J(this,1,a)};d.bt=function(a){l.u.J(this,2,a)};d.ct=function(a){l.u.J(this,3,a)};d.KS=function(a){l.u.J(this,4,a)};\nd.SV=function(a){l.u.J(this,5,a)};d.Or=function(){return l.u.D(this,9)};d.Sq=function(a,b){l.u.ib(this,9,a,b)};d.Hr=function(){return l.u.D(this,6)};d.Oq=function(a,b){l.u.ib(this,6,a,b)};d.ML=function(){return l.u.D(this,8)};d.qI=function(a,b){l.u.ib(this,8,a,b)};d.YS=function(a){l.u.J(this,7,a)};x.qa.Tc.K=function(a){return l.u.K(x.qa.Tc,a)};x.qa.Af=function(a){l.u.initialize(this,a,0,-1,x.qa.Af.na,null)};h.da(x.qa.Af,l.u);x.qa.Af.na=[2,8];\nl.u.ha&&(x.qa.Af.prototype.C=function(a){return x.qa.Af.C(a,this)},x.qa.Af.C=function(a,b){var c,e={z$:l.u.va(b,1,300),I5:l.u.D(b,2),Z2:(c=b.ey())&&x.qa.Yc.C(a,c),W8:l.u.Ka(b.uz(),x.qa.Yc.C,a),qba:(c=b.pA())&&x.qa.eb.C(a,c),pba:(c=b.oA())&&x.qa.te.C(a,c),oba:(c=b.nA())&&x.qa.Tc.C(a,c)};a&&(e.ja=b);return e});x.qa.Af.ia=function(a){a=new l.ba(a);var b=new x.qa.Af;return x.qa.Af.F(b,a)};\nx.qa.Af.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Ya();a.OT(c);break;case 2:c=b.Aa();a.fI(c);break;case 3:c=new x.qa.Yc;b.T(c,x.qa.Yc.F);a.zQ(c);break;case 8:c=new x.qa.Yc;b.T(c,x.qa.Yc.F);a.CI(c);break;case 4:c=new x.qa.eb;b.T(c,x.qa.eb.F);a.FU(c);break;case 6:c=new x.qa.te;b.T(c,x.qa.te.F);a.EU(c);break;case 7:c=new x.qa.Tc;b.T(c,x.qa.Tc.F);a.DU(c);break;default:b.ea()}}return a};\nx.qa.Af.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.$a(1,c);c=a.CL();0<c.length&&b.oc(2,c);c=a.ey();null!=c&&b.oa(3,c,x.qa.Yc.G);c=a.uz();0<c.length&&b.Oa(8,c,x.qa.Yc.G);c=a.pA();null!=c&&b.oa(4,c,x.qa.eb.G);c=a.oA();null!=c&&b.oa(6,c,x.qa.te.G);c=a.nA();null!=c&&b.oa(7,c,x.qa.Tc.G)};d=x.qa.Af.prototype;d.OT=function(a){l.u.J(this,1,a)};d.CL=function(){return l.u.D(this,2)};d.fI=function(a,b){l.u.ib(this,2,a,b)};d.ey=function(){return l.u.sa(this,x.qa.Yc,3)};d.zQ=function(a){l.u.Ca(this,3,a)};\nd.uz=function(){return l.u.Ma(this,x.qa.Yc,8)};d.CI=function(a,b){return l.u.La(this,8,a,x.qa.Yc,b)};d.pA=function(){return l.u.sa(this,x.qa.eb,4)};d.FU=function(a){l.u.Ca(this,4,a)};d.oA=function(){return l.u.sa(this,x.qa.te,6)};d.EU=function(a){l.u.Ca(this,6,a)};d.nA=function(){return l.u.sa(this,x.qa.Tc,7)};d.DU=function(a){l.u.Ca(this,7,a)};x.qa.Af.K=function(a){return l.u.K(x.qa.Af,a)};x.i.Hc=function(a){l.u.initialize(this,a,0,-1,x.i.Hc.na,null)};h.da(x.i.Hc,l.u);x.i.Hc.na=[4];\nl.u.ha&&(x.i.Hc.prototype.C=function(a){return x.i.Hc.C(a,this)},x.i.Hc.C=function(a,b){var c={W7:l.u.D(b,1),o3:l.u.D(b,2),Fba:l.u.D(b,3),d9:l.u.D(b,4),user:l.u.D(b,5)};a&&(c.ja=b);return c});x.i.Hc.ia=function(a){a=new l.ba(a);var b=new x.i.Hc;return x.i.Hc.F(b,a)};x.i.Hc.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.eS(c);break;case 2:c=b.Aa();a.setCell(c);break;case 3:c=b.Aa();a.NU(c);break;case 4:c=b.Aa();a.GI(c);break;case 5:c=b.Aa();a.GV(c);break;default:b.ea()}}return a};\nx.i.Hc.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Ja(1,c);c=l.u.D(a,2);null!=c&&b.Ja(2,c);c=l.u.D(a,3);null!=c&&b.Ja(3,c);c=a.YL();0<c.length&&b.oc(4,c);c=l.u.D(a,5);null!=c&&b.Ja(5,c)};d=x.i.Hc.prototype;d.eS=function(a){l.u.J(this,1,a)};d.setCell=function(a){l.u.J(this,2,a)};d.NU=function(a){l.u.J(this,3,a)};d.YL=function(){return l.u.D(this,4)};d.GI=function(a,b){l.u.ib(this,4,a,b)};d.GV=function(a){l.u.J(this,5,a)};x.i.Hc.K=function(a){return l.u.K(x.i.Hc,a)};\nx.i.rf=function(a){l.u.initialize(this,a,0,-1,x.i.rf.na,null)};h.da(x.i.rf,l.u);x.i.rf.na=[1];l.u.ha&&(x.i.rf.prototype.C=function(a){return x.i.rf.C(a,this)},x.i.rf.C=function(a,b){var c={NN:l.u.Ka(b.Ul(),x.i.Hc.C,a)};a&&(c.ja=b);return c});x.i.rf.ia=function(a){a=new l.ba(a);var b=new x.i.rf;return x.i.rf.F(b,a)};x.i.rf.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.Hc;b.T(c,x.i.Hc.F);a.Pq(c);break;default:b.ea()}}return a};\nx.i.rf.G=function(a,b){a=a.Ul();0<a.length&&b.Oa(1,a,x.i.Hc.G)};x.i.rf.prototype.Ul=function(){return l.u.Ma(this,x.i.Hc,1)};x.i.rf.prototype.Pq=function(a,b){return l.u.La(this,1,a,x.i.Hc,b)};x.i.rf.K=function(a){return l.u.K(x.i.rf,a)};x.jb={};x.jb.lb={};x.jb.lb.mb=function(a){l.u.initialize(this,a,0,1,null,null)};h.da(x.jb.lb.mb,l.u);\nl.u.ha&&(x.jb.lb.mb.prototype.C=function(a){return x.jb.lb.mb.C(a,this)},x.jb.lb.mb.C=function(a,b){var c={};l.u.pW(b,c,l.u.nj,x.jb.lb.mb.prototype.getExtension,a);a&&(c.ja=b);return c});x.jb.lb.mb.ia=function(a){a=new l.ba(a);var b=new x.jb.lb.mb;return x.jb.lb.mb.F(b,a)};x.jb.lb.mb.F=function(a,b){for(;b.fa()&&!b.ga();)l.u.kP(a,b,l.u.oi,x.jb.lb.mb.prototype.getExtension,x.jb.lb.mb.prototype.yR);return a};x.jb.lb.mb.G=function(a,b){l.u.XP(a,b,l.u.oi,x.jb.lb.mb.prototype.getExtension)};\nx.jb.lb.mb.K=function(a){return l.u.K(x.jb.lb.mb,a)};x.V={};x.V.Wb=function(a){l.u.initialize(this,a,0,-1,null,x.V.Wb.Ob)};h.da(x.V.Wb,l.u);x.V.Wb.Ob=[[1,2,3,4,5,6,7,8,9,10]];x.V.Wb.FY={EY:0,DY:1,RZ:2,hZ:3,AY:4,cY:5,dZ:6,ZW:7,FX:8,eZ:9,v_:10};\nl.u.ha&&(x.V.Wb.prototype.C=function(a){return x.V.Wb.C(a,this)},x.V.Wb.C=function(a,b){var c,e={lm:(c=b.eg())&&x.google.N.ge.C(a,c),Jba:(c=b.uA())&&x.V.jf.C(a,c),XO:(c=b.Zl())&&x.V.gf.C(a,c),aO:(c=b.Wl())&&x.V.ef.C(a,c),m7:(c=b.fz())&&x.V.Pd.C(a,c),p$:(c=b.Mz())&&x.V.He.C(a,c),A2:(c=b.Vx())&&x.V.Jd.C(a,c),L5:(c=b.Ty())&&x.V.De.C(a,c),q$:(c=b.Nz())&&x.V.ff.C(a,c),Cda:(c=b.$A())&&x.V.be.C(a,c)};a&&(e.ja=b);return e});x.V.Wb.ia=function(a){a=new l.ba(a);var b=new x.V.Wb;return x.V.Wb.F(b,a)};\nx.V.Wb.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.google.N.ge;b.T(c,x.google.N.ge.F);a.Ng(c);break;case 2:c=new x.V.jf;b.T(c,x.V.jf.F);a.OU(c);break;case 3:c=new x.V.gf;b.T(c,x.V.gf.F);a.gt(c);break;case 4:c=new x.V.ef;b.T(c,x.V.ef.F);a.Zs(c);break;case 5:c=new x.V.Pd;b.T(c,x.V.Pd.F);a.XR(c);break;case 6:c=new x.V.He;b.T(c,x.V.He.F);a.FT(c);break;case 7:c=new x.V.Jd;b.T(c,x.V.Jd.F);a.rQ(c);break;case 8:c=new x.V.De;b.T(c,x.V.De.F);a.xR(c);break;case 9:c=new x.V.ff;\nb.T(c,x.V.ff.F);a.GT(c);break;case 10:c=new x.V.be;b.T(c,x.V.be.F);a.OV(c);break;default:b.ea()}}return a};\nx.V.Wb.G=function(a,b){var c;c=a.eg();null!=c&&b.oa(1,c,x.google.N.ge.G);c=a.uA();null!=c&&b.oa(2,c,x.V.jf.G);c=a.Zl();null!=c&&b.oa(3,c,x.V.gf.G);c=a.Wl();null!=c&&b.oa(4,c,x.V.ef.G);c=a.fz();null!=c&&b.oa(5,c,x.V.Pd.G);c=a.Mz();null!=c&&b.oa(6,c,x.V.He.G);c=a.Vx();null!=c&&b.oa(7,c,x.V.Jd.G);c=a.Ty();null!=c&&b.oa(8,c,x.V.De.G);c=a.Nz();null!=c&&b.oa(9,c,x.V.ff.G);c=a.$A();null!=c&&b.oa(10,c,x.V.be.G)};d=x.V.Wb.prototype;d.eg=function(){return l.u.sa(this,x.google.N.ge,1)};\nd.Ng=function(a){l.u.Nc(this,1,x.V.Wb.Ob[0],a)};d.uA=function(){return l.u.sa(this,x.V.jf,2)};d.OU=function(a){l.u.Nc(this,2,x.V.Wb.Ob[0],a)};d.Zl=function(){return l.u.sa(this,x.V.gf,3)};d.gt=function(a){l.u.Nc(this,3,x.V.Wb.Ob[0],a)};d.Wl=function(){return l.u.sa(this,x.V.ef,4)};d.Zs=function(a){l.u.Nc(this,4,x.V.Wb.Ob[0],a)};d.fz=function(){return l.u.sa(this,x.V.Pd,5)};d.XR=function(a){l.u.Nc(this,5,x.V.Wb.Ob[0],a)};d.Mz=function(){return l.u.sa(this,x.V.He,6)};\nd.FT=function(a){l.u.Nc(this,6,x.V.Wb.Ob[0],a)};d.Vx=function(){return l.u.sa(this,x.V.Jd,7)};d.rQ=function(a){l.u.Nc(this,7,x.V.Wb.Ob[0],a)};d.Ty=function(){return l.u.sa(this,x.V.De,8)};d.xR=function(a){l.u.Nc(this,8,x.V.Wb.Ob[0],a)};d.Nz=function(){return l.u.sa(this,x.V.ff,9)};d.GT=function(a){l.u.Nc(this,9,x.V.Wb.Ob[0],a)};d.$A=function(){return l.u.sa(this,x.V.be,10)};d.OV=function(a){l.u.Nc(this,10,x.V.Wb.Ob[0],a)};x.V.Wb.K=function(a){return l.u.K(x.V.Wb,a)};\nx.V.jf=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.V.jf,l.u);l.u.ha&&(x.V.jf.prototype.C=function(a){return x.V.jf.C(a,this)},x.V.jf.C=function(a,b){var c={};a&&(c.ja=b);return c});x.V.jf.ia=function(a){a=new l.ba(a);var b=new x.V.jf;return x.V.jf.F(b,a)};x.V.jf.F=function(a,b){for(;b.fa()&&!b.ga();)b.ea();return a};x.V.jf.G=function(){};x.V.jf.K=function(a){return l.u.K(x.V.jf,a)};x.V.gf=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.V.gf,l.u);\nl.u.ha&&(x.V.gf.prototype.C=function(a){return x.V.gf.C(a,this)},x.V.gf.C=function(a,b){var c={};a&&(c.ja=b);return c});x.V.gf.ia=function(a){a=new l.ba(a);var b=new x.V.gf;return x.V.gf.F(b,a)};x.V.gf.F=function(a,b){for(;b.fa()&&!b.ga();)b.ea();return a};x.V.gf.G=function(){};x.V.gf.K=function(a){return l.u.K(x.V.gf,a)};x.V.ef=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.V.ef,l.u);\nl.u.ha&&(x.V.ef.prototype.C=function(a){return x.V.ef.C(a,this)},x.V.ef.C=function(a,b){var c={};a&&(c.ja=b);return c});x.V.ef.ia=function(a){a=new l.ba(a);var b=new x.V.ef;return x.V.ef.F(b,a)};x.V.ef.F=function(a,b){for(;b.fa()&&!b.ga();)b.ea();return a};x.V.ef.G=function(){};x.V.ef.K=function(a){return l.u.K(x.V.ef,a)};x.V.Pd=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.V.Pd,l.u);\nl.u.ha&&(x.V.Pd.prototype.C=function(a){return x.V.Pd.C(a,this)},x.V.Pd.C=function(a,b){var c={w8:+l.u.va(b,1,0),u7:+l.u.va(b,2,0)};a&&(c.ja=b);return c});x.V.Pd.ia=function(a){a=new l.ba(a);var b=new x.V.Pd;return x.V.Pd.F(b,a)};x.V.Pd.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.pa();a.xS(c);break;case 2:c=b.pa();a.bS(c);break;default:b.ea()}}return a};x.V.Pd.G=function(a,b){var c;c=a.TL();0!==c&&b.ya(1,c);c=a.OL();0!==c&&b.ya(2,c)};\nx.V.Pd.prototype.TL=function(){return+l.u.va(this,1,0)};x.V.Pd.prototype.xS=function(a){l.u.J(this,1,a)};x.V.Pd.prototype.OL=function(){return+l.u.va(this,2,0)};x.V.Pd.prototype.bS=function(a){l.u.J(this,2,a)};x.V.Pd.K=function(a){return l.u.K(x.V.Pd,a)};x.V.He=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.V.He,l.u);l.u.ha&&(x.V.He.prototype.C=function(a){return x.V.He.C(a,this)},x.V.He.C=function(a,b){var c={iK:+l.u.va(b,1,0)};a&&(c.ja=b);return c});\nx.V.He.ia=function(a){a=new l.ba(a);var b=new x.V.He;return x.V.He.F(b,a)};x.V.He.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.pa();a.Ms(c);break;default:b.ea()}}return a};x.V.He.G=function(a,b){a=a.Cr();0!==a&&b.ya(1,a)};x.V.He.prototype.Cr=function(){return+l.u.va(this,1,0)};x.V.He.prototype.Ms=function(a){l.u.J(this,1,a)};x.V.He.K=function(a){return l.u.K(x.V.He,a)};x.V.ff=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.V.ff,l.u);\nl.u.ha&&(x.V.ff.prototype.C=function(a){return x.V.ff.C(a,this)},x.V.ff.C=function(a,b){var c={};a&&(c.ja=b);return c});x.V.ff.ia=function(a){a=new l.ba(a);var b=new x.V.ff;return x.V.ff.F(b,a)};x.V.ff.F=function(a,b){for(;b.fa()&&!b.ga();)b.ea();return a};x.V.ff.G=function(){};x.V.ff.K=function(a){return l.u.K(x.V.ff,a)};x.V.De=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.V.De,l.u);\nl.u.ha&&(x.V.De.prototype.C=function(a){return x.V.De.C(a,this)},x.V.De.C=function(a,b){var c={iK:+l.u.va(b,1,0)};a&&(c.ja=b);return c});x.V.De.ia=function(a){a=new l.ba(a);var b=new x.V.De;return x.V.De.F(b,a)};x.V.De.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.pa();a.Ms(c);break;default:b.ea()}}return a};x.V.De.G=function(a,b){a=a.Cr();0!==a&&b.ya(1,a)};x.V.De.prototype.Cr=function(){return+l.u.va(this,1,0)};x.V.De.prototype.Ms=function(a){l.u.J(this,1,a)};\nx.V.De.K=function(a){return l.u.K(x.V.De,a)};x.V.Cd=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.V.Cd,l.u);l.u.ha&&(x.V.Cd.prototype.C=function(a){return x.V.Cd.C(a,this)},x.V.Cd.C=function(a,b){var c,e={weight:+l.u.va(b,1,0),lm:(c=b.eg())&&x.V.Wb.C(a,c)};a&&(e.ja=b);return e});x.V.Cd.ia=function(a){a=new l.ba(a);var b=new x.V.Cd;return x.V.Cd.F(b,a)};\nx.V.Cd.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.pa();a.qt(c);break;case 2:c=new x.V.Wb;b.T(c,x.V.Wb.F);a.Ng(c);break;default:b.ea()}}return a};x.V.Cd.G=function(a,b){var c;c=a.Sr();0!==c&&b.ya(1,c);c=a.eg();null!=c&&b.oa(2,c,x.V.Wb.G)};x.V.Cd.prototype.Sr=function(){return+l.u.va(this,1,0)};x.V.Cd.prototype.qt=function(a){l.u.J(this,1,a)};x.V.Cd.prototype.eg=function(){return l.u.sa(this,x.V.Wb,2)};x.V.Cd.prototype.Ng=function(a){l.u.Ca(this,2,a)};\nx.V.Cd.K=function(a){return l.u.K(x.V.Cd,a)};x.V.be=function(a){l.u.initialize(this,a,0,-1,x.V.be.na,null)};h.da(x.V.be,l.u);x.V.be.na=[1];l.u.ha&&(x.V.be.prototype.C=function(a){return x.V.be.C(a,this)},x.V.be.C=function(a,b){var c={Q1:l.u.Ka(b.Jx(),x.V.Cd.C,a)};a&&(c.ja=b);return c});x.V.be.ia=function(a){a=new l.ba(a);var b=new x.V.be;return x.V.be.F(b,a)};x.V.be.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.V.Cd;b.T(c,x.V.Cd.F);a.sH(c);break;default:b.ea()}}return a};\nx.V.be.G=function(a,b){a=a.Jx();0<a.length&&b.Oa(1,a,x.V.Cd.G)};x.V.be.prototype.Jx=function(){return l.u.Ma(this,x.V.Cd,1)};x.V.be.prototype.sH=function(a,b){return l.u.La(this,1,a,x.V.Cd,b)};x.V.be.K=function(a){return l.u.K(x.V.be,a)};x.V.Jd=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.V.Jd,l.u);l.u.ha&&(x.V.Jd.prototype.C=function(a){return x.V.Jd.C(a,this)},x.V.Jd.C=function(a,b){var c={I$:+l.u.va(b,1,0),u9:+l.u.va(b,2,0)};a&&(c.ja=b);return c});\nx.V.Jd.ia=function(a){a=new l.ba(a);var b=new x.V.Jd;return x.V.Jd.F(b,a)};x.V.Jd.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.pa();a.UT(c);break;case 2:c=b.pa();a.eT(c);break;default:b.ea()}}return a};x.V.Jd.G=function(a,b){var c;c=a.hM();0!==c&&b.ya(1,c);c=a.bM();0!==c&&b.ya(2,c)};x.V.Jd.prototype.hM=function(){return+l.u.va(this,1,0)};x.V.Jd.prototype.UT=function(a){l.u.J(this,1,a)};x.V.Jd.prototype.bM=function(){return+l.u.va(this,2,0)};\nx.V.Jd.prototype.eT=function(a){l.u.J(this,2,a)};x.V.Jd.K=function(a){return l.u.K(x.V.Jd,a)};x.i.nb=function(a){l.u.initialize(this,a,0,-1,x.i.nb.na,null)};h.da(x.i.nb,l.u);x.i.nb.na=[1,2,7];l.u.ha&&(x.i.nb.prototype.C=function(a){return x.i.nb.C(a,this)},x.i.nb.C=function(a,b){var c={H2:l.u.gb(b,1),O2:l.u.D(b,2),h5:l.u.gb(b,7),min:+l.u.D(b,3),max:+l.u.D(b,4),sum:+l.u.D(b,5),rca:+l.u.D(b,6)};a&&(c.ja=b);return c});x.i.nb.ia=function(a){a=new l.ba(a);var b=new x.i.nb;return x.i.nb.F(b,a)};\nx.i.nb.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.pa();a.BH(c);break;case 2:c=b.ad();a.EH(c);break;case 7:c=b.pa();a.XH(c);break;case 3:c=b.pa();a.IS(c);break;case 4:c=b.pa();a.wS(c);break;case 5:c=b.pa();a.wj(c);break;case 6:c=b.pa();a.dV(c);break;default:b.ea()}}return a};\nx.i.nb.G=function(a,b){var c;c=a.kL();0<c.length&&b.bd(1,c);c=a.lL();0<c.length&&b.HW(2,c);c=a.wL();0<c.length&&b.bd(7,c);c=l.u.D(a,3);null!=c&&b.ya(3,c);c=l.u.D(a,4);null!=c&&b.ya(4,c);c=l.u.D(a,5);null!=c&&b.ya(5,c);c=l.u.D(a,6);null!=c&&b.ya(6,c)};d=x.i.nb.prototype;d.kL=function(){return l.u.gb(this,1)};d.BH=function(a,b){l.u.ib(this,1,a,b)};d.lL=function(){return l.u.D(this,2)};d.EH=function(a,b){l.u.ib(this,2,a,b)};d.wL=function(){return l.u.gb(this,7)};d.XH=function(a,b){l.u.ib(this,7,a,b)};\nd.IS=function(a){l.u.J(this,3,a)};d.wS=function(a){l.u.J(this,4,a)};d.wj=function(a){l.u.J(this,5,a)};d.dV=function(a){l.u.J(this,6,a)};x.i.nb.K=function(a){return l.u.K(x.i.nb,a)};x.i.wd=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.wd,l.u);l.u.ha&&(x.i.wd.prototype.C=function(a){return x.i.wd.C(a,this)},x.i.wd.C=function(a,b){var c={l8:+l.u.D(b,1),m8:+l.u.D(b,2),numBuckets:l.u.D(b,3)};a&&(c.ja=b);return c});x.i.wd.ia=function(a){a=new l.ba(a);var b=new x.i.wd;return x.i.wd.F(b,a)};\nx.i.wd.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.pa();a.pS(c);break;case 2:c=b.pa();a.qS(c);break;case 3:c=b.Ya();a.xm(c);break;default:b.ea()}}return a};x.i.wd.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.ya(1,c);c=l.u.D(a,2);null!=c&&b.ya(2,c);c=l.u.D(a,3);null!=c&&b.$a(3,c)};x.i.wd.$c=new l.Di(14413783,{$c:0},x.i.wd,x.i.wd.C,0);l.u.oi[14413783]=new l.Fj(x.i.wd.$c,l.ba.prototype.T,l.Bi.prototype.oa,x.i.wd.G,x.i.wd.F,!1);l.u.nj[14413783]=x.i.wd.$c;\nx.i.wd.prototype.pS=function(a){l.u.J(this,1,a)};x.i.wd.prototype.qS=function(a){l.u.J(this,2,a)};x.i.wd.prototype.xm=function(a){l.u.J(this,3,a)};x.i.wd.K=function(a){return l.u.K(x.i.wd,a)};x.i.xd=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.xd,l.u);l.u.ha&&(x.i.xd.prototype.C=function(a){return x.i.xd.C(a,this)},x.i.xd.C=function(a,b){var c={mean:+l.u.D(b,1),fW:+l.u.D(b,2),numBuckets:l.u.D(b,3)};a&&(c.ja=b);return c});\nx.i.xd.ia=function(a){a=new l.ba(a);var b=new x.i.xd;return x.i.xd.F(b,a)};x.i.xd.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.pa();a.FS(c);break;case 2:c=b.pa();a.QU(c);break;case 3:c=b.Ya();a.xm(c);break;default:b.ea()}}return a};x.i.xd.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.ya(1,c);c=l.u.D(a,2);null!=c&&b.ya(2,c);c=l.u.D(a,3);null!=c&&b.$a(3,c)};x.i.xd.$c=new l.Di(19393435,{$c:0},x.i.xd,x.i.xd.C,0);\nl.u.oi[19393435]=new l.Fj(x.i.xd.$c,l.ba.prototype.T,l.Bi.prototype.oa,x.i.xd.G,x.i.xd.F,!1);l.u.nj[19393435]=x.i.xd.$c;x.i.xd.prototype.FS=function(a){l.u.J(this,1,a)};x.i.xd.prototype.QU=function(a){l.u.J(this,2,a)};x.i.xd.prototype.xm=function(a){l.u.J(this,3,a)};x.i.xd.K=function(a){return l.u.K(x.i.xd,a)};x.i.hd=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.hd,l.u);\nl.u.ha&&(x.i.hd.prototype.C=function(a){return x.i.hd.C(a,this)},x.i.hd.C=function(a,b){var c={K2:+l.u.D(b,1),Q2:+l.u.D(b,2),P2:+l.u.D(b,3),numBuckets:+l.u.D(b,4)};a&&(c.ja=b);return c});x.i.hd.ia=function(a){a=new l.ba(a);var b=new x.i.hd;return x.i.hd.F(b,a)};x.i.hd.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.pa();a.vQ(c);break;case 2:c=b.pa();a.yQ(c);break;case 3:c=b.pa();a.xQ(c);break;case 4:c=b.pa();a.xm(c);break;default:b.ea()}}return a};\nx.i.hd.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.ya(1,c);c=l.u.D(a,2);null!=c&&b.ya(2,c);c=l.u.D(a,3);null!=c&&b.ya(3,c);c=l.u.D(a,4);null!=c&&b.ya(4,c)};x.i.hd.$c=new l.Di(14410962,{$c:0},x.i.hd,x.i.hd.C,0);l.u.oi[14410962]=new l.Fj(x.i.hd.$c,l.ba.prototype.T,l.Bi.prototype.oa,x.i.hd.G,x.i.hd.F,!1);l.u.nj[14410962]=x.i.hd.$c;x.i.hd.prototype.vQ=function(a){l.u.J(this,1,a)};x.i.hd.prototype.yQ=function(a){l.u.J(this,2,a)};x.i.hd.prototype.xQ=function(a){l.u.J(this,3,a)};\nx.i.hd.prototype.xm=function(a){l.u.J(this,4,a)};x.i.hd.K=function(a){return l.u.K(x.i.hd,a)};x.i.gd=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.gd,l.u);l.u.ha&&(x.i.gd.prototype.C=function(a){return x.i.gd.C(a,this)},x.i.gd.C=function(a,b){var c,e={J$:(c=b.Rz())&&x.jb.lb.mb.C(a,c),v9:(c=b.Ez())&&x.jb.lb.mb.C(a,c)};a&&(e.ja=b);return e});x.i.gd.ia=function(a){a=new l.ba(a);var b=new x.i.gd;return x.i.gd.F(b,a)};\nx.i.gd.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.jb.lb.mb;b.T(c,x.jb.lb.mb.F);a.VT(c);break;case 2:c=new x.jb.lb.mb;b.T(c,x.jb.lb.mb.F);a.fT(c);break;default:b.ea()}}return a};x.i.gd.G=function(a,b){var c;c=a.Rz();null!=c&&b.oa(1,c,x.jb.lb.mb.G);c=a.Ez();null!=c&&b.oa(2,c,x.jb.lb.mb.G)};x.i.gd.$c=new l.Di(13180573,{$c:0},x.i.gd,x.i.gd.C,0);l.u.oi[13180573]=new l.Fj(x.i.gd.$c,l.ba.prototype.T,l.Bi.prototype.oa,x.i.gd.G,x.i.gd.F,!1);l.u.nj[13180573]=x.i.gd.$c;\nx.i.gd.prototype.Rz=function(){return l.u.sa(this,x.jb.lb.mb,1,1)};x.i.gd.prototype.VT=function(a){l.u.Ca(this,1,a)};x.i.gd.prototype.Ez=function(){return l.u.sa(this,x.jb.lb.mb,2)};x.i.gd.prototype.fT=function(a){l.u.Ca(this,2,a)};x.i.gd.K=function(a){return l.u.K(x.i.gd,a)};x.i.Qc=function(a){l.u.initialize(this,a,0,-1,x.i.Qc.na,null)};h.da(x.i.Qc,l.u);x.i.Qc.na=[1,2];\nl.u.ha&&(x.i.Qc.prototype.C=function(a){return x.i.Qc.C(a,this)},x.i.Qc.C=function(a,b){var c={mda:l.u.gb(b,1),J9:l.u.D(b,2)};a&&(c.ja=b);return c});x.i.Qc.ia=function(a){a=new l.ba(a);var b=new x.i.Qc;return x.i.Qc.F(b,a)};x.i.Qc.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.pa();a.BJ(c);break;case 2:c=b.Ya();a.LI(c);break;default:b.ea()}}return a};x.i.Qc.G=function(a,b){var c;c=a.IM();0<c.length&&b.bd(1,c);c=a.cM();0<c.length&&b.GW(2,c)};\nx.i.Qc.$c=new l.Di(14460333,{$c:0},x.i.Qc,x.i.Qc.C,0);l.u.oi[14460333]=new l.Fj(x.i.Qc.$c,l.ba.prototype.T,l.Bi.prototype.oa,x.i.Qc.G,x.i.Qc.F,!1);l.u.nj[14460333]=x.i.Qc.$c;x.i.Qc.prototype.IM=function(){return l.u.gb(this,1)};x.i.Qc.prototype.BJ=function(a,b){l.u.ib(this,1,a,b)};x.i.Qc.prototype.cM=function(){return l.u.D(this,2)};x.i.Qc.prototype.LI=function(a,b){l.u.ib(this,2,a,b)};x.i.Qc.K=function(a){return l.u.K(x.i.Qc,a)};x.i.Qf=function(a){l.u.initialize(this,a,0,-1,null,null)};\nh.da(x.i.Qf,l.u);l.u.ha&&(x.i.Qf.prototype.C=function(a){return x.i.Qf.C(a,this)},x.i.Qf.C=function(a,b){var c,e={Y6:(c=b.$y())&&x.jb.lb.mb.C(a,c)};a&&(e.ja=b);return e});x.i.Qf.ia=function(a){a=new l.ba(a);var b=new x.i.Qf;return x.i.Qf.F(b,a)};x.i.Qf.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.jb.lb.mb;b.T(c,x.jb.lb.mb.F);a.KR(c);break;default:b.ea()}}return a};x.i.Qf.G=function(a,b){a=a.$y();null!=a&&b.oa(1,a,x.jb.lb.mb.G)};\nx.i.Qf.prototype.$y=function(){return l.u.sa(this,x.jb.lb.mb,1,1)};x.i.Qf.prototype.KR=function(a){l.u.Ca(this,1,a)};x.i.Qf.K=function(a){return l.u.K(x.i.Qf,a)};x.Xa={};x.Xa.Ec=function(a){l.u.initialize(this,a,0,-1,x.Xa.Ec.na,null)};h.da(x.Xa.Ec,l.u);x.Xa.Ec.na=[1,9];\nl.u.ha&&(x.Xa.Ec.prototype.C=function(a){return x.Xa.Ec.C(a,this)},x.Xa.Ec.C=function(a,b){var c,e={Cx:l.u.Ka(b.Zg(),x.jb.lb.mb.C,a),nba:l.u.D(b,2),F7:l.u.va(b,3,!1),startTime:l.u.va(b,4,0),endTime:l.u.va(b,5,0x7fffffffffffffff),Uaa:+l.u.va(b,7,1),R1:(c=b.Kx())&&x.jb.lb.mb.C(a,c),X1:l.u.D(b,9)};a&&(e.ja=b);return e});x.Xa.Ec.ia=function(a){a=new l.ba(a);var b=new x.Xa.Ec;return x.Xa.Ec.F(b,a)};\nx.Xa.Ec.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.jb.lb.mb;b.T(c,x.jb.lb.mb.F);a.sl(c);break;case 2:c=b.Aa();a.CU(c);break;case 3:c=b.vf();a.dS(c);break;case 4:c=b.ad();a.vj(c);break;case 5:c=b.ad();a.sj(c);break;case 7:c=b.pa();a.yU(c);break;case 8:c=new x.jb.lb.mb;b.T(c,x.jb.lb.mb.F);a.eQ(c);break;case 9:c=b.Aa();a.uH(c);break;default:b.ea()}}return a};\nx.Xa.Ec.G=function(a,b){var c;c=a.Zg();0<c.length&&b.Oa(1,c,x.jb.lb.mb.G);c=l.u.D(a,2);null!=c&&b.Ja(2,c);c=l.u.D(a,3);null!=c&&b.kf(3,c);c=l.u.D(a,4);null!=c&&b.td(4,c);c=l.u.D(a,5);null!=c&&b.td(5,c);c=l.u.D(a,7);null!=c&&b.ya(7,c);c=a.Kx();null!=c&&b.oa(8,c,x.jb.lb.mb.G);c=a.gL();0<c.length&&b.oc(9,c)};d=x.Xa.Ec.prototype;d.Zg=function(){return l.u.Ma(this,x.jb.lb.mb,1)};d.Us=function(a){l.u.mt(this,1,a)};d.sl=function(a,b){return l.u.La(this,1,a,x.jb.lb.mb,b)};d.CU=function(a){l.u.J(this,2,a)};\nd.dS=function(a){l.u.J(this,3,a)};d.getStartTime=function(){return l.u.va(this,4,0)};d.vj=function(a){l.u.J(this,4,a)};d.sj=function(a){l.u.J(this,5,a)};d.yU=function(a){l.u.J(this,7,a)};d.Kx=function(){return l.u.sa(this,x.jb.lb.mb,8)};d.eQ=function(a){l.u.Ca(this,8,a)};d.gL=function(){return l.u.D(this,9)};d.uH=function(a,b){l.u.ib(this,9,a,b)};x.Xa.Ec.K=function(a){return l.u.K(x.Xa.Ec,a)};x.Xa.wb=function(a){l.u.initialize(this,a,0,-1,x.Xa.wb.na,null)};h.da(x.Xa.wb,l.u);x.Xa.wb.na=[1];\nl.u.ha&&(x.Xa.wb.prototype.C=function(a){return x.Xa.wb.C(a,this)},x.Xa.wb.C=function(a,b){var c={h2:l.u.Ka(b.Nx(),x.Xa.wb.Xc.C,a),B4:l.u.va(b,4,!1),A4:l.u.va(b,5,!1),y4:l.u.va(b,6,!1)};a&&(c.ja=b);return c});x.Xa.wb.ia=function(a){a=new l.ba(a);var b=new x.Xa.wb;return x.Xa.wb.F(b,a)};\nx.Xa.wb.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.Xa.wb.Xc;b.lP(1,c,x.Xa.wb.Xc.F);a.vH(c);break;case 4:c=b.vf();a.XQ(c);break;case 5:c=b.vf();a.WQ(c);break;case 6:c=b.vf();a.VQ(c);break;default:b.ea()}}return a};x.Xa.wb.G=function(a,b){var c;c=a.Nx();0<c.length&&b.FW(1,c,x.Xa.wb.Xc.G);c=l.u.D(a,4);null!=c&&b.kf(4,c);c=l.u.D(a,5);null!=c&&b.kf(5,c);c=l.u.D(a,6);null!=c&&b.kf(6,c)};x.Xa.wb.$c=new l.Di(19252665,{$c:0},x.Xa.wb,x.Xa.wb.C,0);\nl.u.oi[19252665]=new l.Fj(x.Xa.wb.$c,l.ba.prototype.T,l.Bi.prototype.oa,x.Xa.wb.G,x.Xa.wb.F,!1);l.u.nj[19252665]=x.Xa.wb.$c;d=x.Xa.wb.prototype;d.Nx=function(){return l.u.Ma(this,x.Xa.wb.Xc,1)};d.vH=function(a,b){return l.u.La(this,1,a,x.Xa.wb.Xc,b)};d.XQ=function(a){l.u.J(this,4,a)};d.WQ=function(a){l.u.J(this,5,a)};d.VQ=function(a){l.u.J(this,6,a)};x.Xa.wb.K=function(a){return l.u.K(x.Xa.wb,a)};x.Xa.wb.Xc=function(a){l.u.initialize(this,a,0,-1,x.Xa.wb.Xc.na,null)};h.da(x.Xa.wb.Xc,l.u);\nx.Xa.wb.Xc.na=[1,2];l.u.ha&&(x.Xa.wb.Xc.prototype.C=function(a){return x.Xa.wb.Xc.C(a,this)},x.Xa.wb.Xc.C=function(a,b){var c={SJ:l.u.Ka(b.Il(),x.Xa.Ec.C,a),Z3:l.u.Ka(b.oy(),x.jb.lb.mb.C,a)};a&&(c.ja=b);return c});x.Xa.wb.Xc.ia=function(a){a=new l.ba(a);var b=new x.Xa.wb.Xc;return x.Xa.wb.Xc.F(b,a)};x.Xa.wb.Xc.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 2:c=new x.Xa.Ec;b.T(c,x.Xa.Ec.F);a.Lq(c);break;case 3:c=new x.jb.lb.mb;b.T(c,x.jb.lb.mb.F);a.KH(c);break;default:b.ea()}}return a};\nx.Xa.wb.Xc.G=function(a,b){var c;c=a.Il();0<c.length&&b.Oa(2,c,x.Xa.Ec.G);c=a.oy();0<c.length&&b.Oa(3,c,x.jb.lb.mb.G)};x.Xa.wb.Xc.prototype.Il=function(){return l.u.Ma(this,x.Xa.Ec,1)};x.Xa.wb.Xc.prototype.Lq=function(a,b){return l.u.La(this,1,a,x.Xa.Ec,b)};x.Xa.wb.Xc.prototype.oy=function(){return l.u.Ma(this,x.jb.lb.mb,2)};x.Xa.wb.Xc.prototype.KH=function(a,b){return l.u.La(this,2,a,x.jb.lb.mb,b)};x.Xa.wb.Xc.K=function(a){return l.u.K(x.Xa.wb.Xc,a)};\nx.i.Zd=function(a){l.u.initialize(this,a,0,-1,null,x.i.Zd.Ob)};h.da(x.i.Zd,l.u);x.i.Zd.Ob=[[1,2]];x.i.Zd.a_={TZ:0,fZ:1,hY:2};l.u.ha&&(x.i.Zd.prototype.C=function(a){return x.i.Zd.C(a,this)},x.i.Zd.C=function(a,b){var c,e={y$:(c=b.Oz())&&x.i.wc.C(a,c),iN:(c=b.Tl())&&x.i.Rc.C(a,c)};a&&(e.ja=b);return e});x.i.Zd.ia=function(a){a=new l.ba(a);var b=new x.i.Zd;return x.i.Zd.F(b,a)};\nx.i.Zd.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.wc;b.T(c,x.i.wc.F);a.NT(c);break;case 2:c=new x.i.Rc;b.T(c,x.i.Rc.F);a.Xs(c);break;default:b.ea()}}return a};x.i.Zd.G=function(a,b){var c;c=a.Oz();null!=c&&b.oa(1,c,x.i.wc.G);c=a.Tl();null!=c&&b.oa(2,c,x.i.Rc.G)};x.i.Zd.prototype.Oz=function(){return l.u.sa(this,x.i.wc,1)};x.i.Zd.prototype.NT=function(a){l.u.Nc(this,1,x.i.Zd.Ob[0],a)};x.i.Zd.prototype.Tl=function(){return l.u.sa(this,x.i.Rc,2)};\nx.i.Zd.prototype.Xs=function(a){l.u.Nc(this,2,x.i.Zd.Ob[0],a)};x.i.Zd.K=function(a){return l.u.K(x.i.Zd,a)};x.i.wc=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.wc,l.u);l.u.ha&&(x.i.wc.prototype.C=function(a){return x.i.wc.C(a,this)},x.i.wc.C=function(a,b){var c,e={I4:(c=b.Ay())&&x.i.Gc.C(a,c),rO:(c=b.Yl())&&x.i.Rb.C(a,c),Tba:(c=b.yA())&&x.i.mc.C(a,c)};a&&(e.ja=b);return e});x.i.wc.ia=function(a){a=new l.ba(a);var b=new x.i.wc;return x.i.wc.F(b,a)};\nx.i.wc.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.Gc;b.T(c,x.i.Gc.F);a.aR(c);break;case 2:c=new x.i.Rb;b.T(c,x.i.Rb.F);a.at(c);break;case 3:c=new x.i.mc;b.T(c,x.i.mc.F);a.VU(c);break;default:b.ea()}}return a};x.i.wc.G=function(a,b){var c;c=a.Ay();null!=c&&b.oa(1,c,x.i.Gc.G);c=a.Yl();null!=c&&b.oa(2,c,x.i.Rb.G);c=a.yA();null!=c&&b.oa(3,c,x.i.mc.G)};d=x.i.wc.prototype;d.Ay=function(){return l.u.sa(this,x.i.Gc,1)};d.aR=function(a){l.u.Ca(this,1,a)};\nd.Yl=function(){return l.u.sa(this,x.i.Rb,2)};d.at=function(a){l.u.Ca(this,2,a)};d.yA=function(){return l.u.sa(this,x.i.mc,3)};d.VU=function(a){l.u.Ca(this,3,a)};x.i.wc.K=function(a){return l.u.K(x.i.wc,a)};x.i.ig=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.ig,l.u);\nl.u.ha&&(x.i.ig.prototype.C=function(a){return x.i.ig.C(a,this)},x.i.ig.C=function(a,b){var c,e={y5:(c=b.My())&&x.i.Gc.C(a,c),g4:(c=b.uy())&&x.i.Rb.C(a,c),dda:(c=b.RA())&&x.i.Rb.C(a,c),h4:(c=b.wy())&&x.i.mc.C(a,c),eda:(c=b.SA())&&x.i.mc.C(a,c),H3:(c=b.ny())&&x.i.ke.C(a,c)};a&&(e.ja=b);return e});x.i.ig.ia=function(a){a=new l.ba(a);var b=new x.i.ig;return x.i.ig.F(b,a)};\nx.i.ig.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.Gc;b.T(c,x.i.Gc.F);a.tR(c);break;case 2:c=new x.i.Rb;b.T(c,x.i.Rb.F);a.QQ(c);break;case 3:c=new x.i.Rb;b.T(c,x.i.Rb.F);a.zV(c);break;case 4:c=new x.i.mc;b.T(c,x.i.mc.F);a.RQ(c);break;case 5:c=new x.i.mc;b.T(c,x.i.mc.F);a.AV(c);break;case 6:c=new x.i.ke;b.T(c,x.i.ke.F);a.LQ(c);break;default:b.ea()}}return a};\nx.i.ig.G=function(a,b){var c;c=a.My();null!=c&&b.oa(1,c,x.i.Gc.G);c=a.uy();null!=c&&b.oa(2,c,x.i.Rb.G);c=a.RA();null!=c&&b.oa(3,c,x.i.Rb.G);c=a.wy();null!=c&&b.oa(4,c,x.i.mc.G);c=a.SA();null!=c&&b.oa(5,c,x.i.mc.G);c=a.ny();null!=c&&b.oa(6,c,x.i.ke.G)};d=x.i.ig.prototype;d.My=function(){return l.u.sa(this,x.i.Gc,1)};d.tR=function(a){l.u.Ca(this,1,a)};d.uy=function(){return l.u.sa(this,x.i.Rb,2)};d.QQ=function(a){l.u.Ca(this,2,a)};d.RA=function(){return l.u.sa(this,x.i.Rb,3)};\nd.zV=function(a){l.u.Ca(this,3,a)};d.wy=function(){return l.u.sa(this,x.i.mc,4)};d.RQ=function(a){l.u.Ca(this,4,a)};d.SA=function(){return l.u.sa(this,x.i.mc,5)};d.AV=function(a){l.u.Ca(this,5,a)};d.ny=function(){return l.u.sa(this,x.i.ke,6)};d.LQ=function(a){l.u.Ca(this,6,a)};x.i.ig.K=function(a){return l.u.K(x.i.ig,a)};x.i.Rc=function(a){l.u.initialize(this,a,0,-1,x.i.Rc.na,null)};h.da(x.i.Rc,l.u);x.i.Rc.na=[2];\nl.u.ha&&(x.i.Rc.prototype.C=function(a){return x.i.Rc.C(a,this)},x.i.Rc.C=function(a,b){var c,e={rO:(c=b.Yl())&&x.i.Rb.C(a,c),uaa:l.u.Ka(b.gA(),x.i.rc.C,a),Sca:(c=b.MA())&&x.i.rc.C(a,c),lm:(c=b.eg())&&x.V.Wb.C(a,c)};a&&(e.ja=b);return e});x.i.Rc.ia=function(a){a=new l.ba(a);var b=new x.i.Rc;return x.i.Rc.F(b,a)};\nx.i.Rc.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.Rb;b.T(c,x.i.Rb.F);a.at(c);break;case 2:c=new x.i.rc;b.T(c,x.i.rc.F);a.ZI(c);break;case 3:c=new x.i.rc;b.T(c,x.i.rc.F);a.tV(c);break;case 4:c=new x.V.Wb;b.T(c,x.V.Wb.F);a.Ng(c);break;default:b.ea()}}return a};x.i.Rc.G=function(a,b){var c;c=a.Yl();null!=c&&b.oa(1,c,x.i.Rb.G);c=a.gA();0<c.length&&b.Oa(2,c,x.i.rc.G);c=a.MA();null!=c&&b.oa(3,c,x.i.rc.G);c=a.eg();null!=c&&b.oa(4,c,x.V.Wb.G)};d=x.i.Rc.prototype;\nd.Yl=function(){return l.u.sa(this,x.i.Rb,1)};d.at=function(a){l.u.Ca(this,1,a)};d.gA=function(){return l.u.Ma(this,x.i.rc,2)};d.ZI=function(a,b){return l.u.La(this,2,a,x.i.rc,b)};d.MA=function(){return l.u.sa(this,x.i.rc,3)};d.tV=function(a){l.u.Ca(this,3,a)};d.eg=function(){return l.u.sa(this,x.V.Wb,4)};d.Ng=function(a){l.u.Ca(this,4,a)};x.i.Rc.K=function(a){return l.u.K(x.i.Rc,a)};x.i.Id=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.Id,l.u);\nl.u.ha&&(x.i.Id.prototype.C=function(a){return x.i.Id.C(a,this)},x.i.Id.C=function(a,b){var c={Zq:l.u.va(b,1,\"\"),rP:l.u.va(b,2,\"\")};a&&(c.ja=b);return c});x.i.Id.ia=function(a){a=new l.ba(a);var b=new x.i.Id;return x.i.Id.F(b,a)};x.i.Id.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.rj(c);break;case 2:c=b.Aa();a.lt(c);break;default:b.ea()}}return a};x.i.Id.G=function(a,b){var c;c=a.Jl();0<c.length&&b.Ja(1,c);c=a.xo();0<c.length&&b.Ja(2,c)};\nx.i.Id.prototype.Jl=function(){return l.u.va(this,1,\"\")};x.i.Id.prototype.rj=function(a){l.u.J(this,1,a)};x.i.Id.prototype.xo=function(){return l.u.va(this,2,\"\")};x.i.Id.prototype.lt=function(a){l.u.J(this,2,a)};x.i.Id.K=function(a){return l.u.K(x.i.Id,a)};x.i.Rb=function(a){l.u.initialize(this,a,0,-1,null,x.i.Rb.Ob)};h.da(x.i.Rb,l.u);x.i.Rb.Ob=[[3,4]];x.i.Rb.vE={uE:0,CZ:3,SW:4};\nl.u.ha&&(x.i.Rb.prototype.C=function(a){return x.i.Rb.C(a,this)},x.i.Rb.C=function(a,b){var c,e={rP:(c=b.xo())&&x.i.Id.C(a,c),I1:l.u.va(b,4,\"\"),TJ:(c=b.Kl())&&x.i.yc.C(a,c),xaa:l.u.va(b,1,\"\")};a&&(e.ja=b);return e});x.i.Rb.ia=function(a){a=new l.ba(a);var b=new x.i.Rb;return x.i.Rb.F(b,a)};\nx.i.Rb.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 3:c=new x.i.Id;b.T(c,x.i.Id.F);a.lt(c);break;case 4:c=b.Aa();a.aQ(c);break;case 2:c=new x.i.yc;b.T(c,x.i.yc.F);a.Ls(c);break;case 1:c=b.Aa();a.uU(c);break;default:b.ea()}}return a};x.i.Rb.G=function(a,b){var c;c=a.xo();null!=c&&b.oa(3,c,x.i.Id.G);c=l.u.D(a,4);null!=c&&b.Ja(4,c);c=a.Kl();null!=c&&b.oa(2,c,x.i.yc.G);c=a.nM();0<c.length&&b.Ja(1,c)};d=x.i.Rb.prototype;d.xo=function(){return l.u.sa(this,x.i.Id,3)};\nd.lt=function(a){l.u.Nc(this,3,x.i.Rb.Ob[0],a)};d.aQ=function(a){l.u.vC(this,4,x.i.Rb.Ob[0],a)};d.Kl=function(){return l.u.sa(this,x.i.yc,2)};d.Ls=function(a){l.u.Ca(this,2,a)};d.nM=function(){return l.u.va(this,1,\"\")};d.uU=function(a){l.u.J(this,1,a)};x.i.Rb.K=function(a){return l.u.K(x.i.Rb,a)};x.i.Bd=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.Bd,l.u);\nl.u.ha&&(x.i.Bd.prototype.C=function(a){return x.i.Bd.C(a,this)},x.i.Bd.C=function(a,b){var c={A3:l.u.va(b,1,\"\"),value:l.u.va(b,2,\"\")};a&&(c.ja=b);return c});x.i.Bd.ia=function(a){a=new l.ba(a);var b=new x.i.Bd;return x.i.Bd.F(b,a)};x.i.Bd.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.IQ(c);break;case 2:c=b.Aa();a.setValue(c);break;default:b.ea()}}return a};x.i.Bd.G=function(a,b){var c;c=a.oL();0<c.length&&b.Ja(1,c);c=a.getValue();0<c.length&&b.Ja(2,c)};\nx.i.Bd.prototype.oL=function(){return l.u.va(this,1,\"\")};x.i.Bd.prototype.IQ=function(a){l.u.J(this,1,a)};x.i.Bd.prototype.getValue=function(){return l.u.va(this,2,\"\")};x.i.Bd.prototype.setValue=function(a){l.u.J(this,2,a)};x.i.Bd.K=function(a){return l.u.K(x.i.Bd,a)};x.i.ud=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.ud,l.u);l.u.ha&&(x.i.ud.prototype.C=function(a){return x.i.ud.C(a,this)},x.i.ud.C=function(a,b){var c={Fl:l.u.va(b,1,0),version:l.u.va(b,2,0)};a&&(c.ja=b);return c});\nx.i.ud.ia=function(a){a=new l.ba(a);var b=new x.i.ud;return x.i.ud.F(b,a)};x.i.ud.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Ya();a.Mg(c);break;case 2:c=b.Ya();a.setVersion(c);break;default:b.ea()}}return a};x.i.ud.G=function(a,b){var c;c=a.ik();0!==c&&b.$a(1,c);c=a.getVersion();0!==c&&b.$a(2,c)};x.i.ud.prototype.ik=function(){return l.u.va(this,1,0)};x.i.ud.prototype.Mg=function(a){l.u.J(this,1,a)};x.i.ud.prototype.getVersion=function(){return l.u.va(this,2,0)};\nx.i.ud.prototype.setVersion=function(a){l.u.J(this,2,a)};x.i.ud.K=function(a){return l.u.K(x.i.ud,a)};x.i.yb=function(a){l.u.initialize(this,a,0,-1,null,x.i.yb.Ob)};h.da(x.i.yb,l.u);x.i.yb.Ob=[[1]];x.i.yb.vE={uE:0,NX:1};l.u.ha&&(x.i.yb.prototype.C=function(a){return x.i.yb.C(a,this)},x.i.yb.C=function(a,b){var c,e={X5:(c=b.Xy())&&x.i.yb.Od.C(a,c)};a&&(e.ja=b);return e});x.i.yb.ia=function(a){a=new l.ba(a);var b=new x.i.yb;return x.i.yb.F(b,a)};\nx.i.yb.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.yb.Od;b.T(c,x.i.yb.Od.F);a.DR(c);break;default:b.ea()}}return a};x.i.yb.G=function(a,b){a=a.Xy();null!=a&&b.oa(1,a,x.i.yb.Od.G)};x.i.yb.prototype.Xy=function(){return l.u.sa(this,x.i.yb.Od,1)};x.i.yb.prototype.DR=function(a){l.u.Nc(this,1,x.i.yb.Ob[0],a)};x.i.yb.K=function(a){return l.u.K(x.i.yb,a)};x.i.yb.Od=function(a){l.u.initialize(this,a,0,-1,x.i.yb.Od.na,null)};h.da(x.i.yb.Od,l.u);x.i.yb.Od.na=[1];\nl.u.ha&&(x.i.yb.Od.prototype.C=function(a){return x.i.yb.Od.C(a,this)},x.i.yb.Od.C=function(a,b){var c={W5:l.u.D(b,1)};a&&(c.ja=b);return c});x.i.yb.Od.ia=function(a){a=new l.ba(a);var b=new x.i.yb.Od;return x.i.yb.Od.F(b,a)};x.i.yb.Od.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.nI(c);break;default:b.ea()}}return a};x.i.yb.Od.G=function(a,b){a=a.IL();0<a.length&&b.oc(1,a)};x.i.yb.Od.prototype.IL=function(){return l.u.D(this,1)};\nx.i.yb.Od.prototype.nI=function(a,b){l.u.ib(this,1,a,b)};x.i.yb.Od.K=function(a){return l.u.K(x.i.yb.Od,a)};x.i.Gc=function(a){l.u.initialize(this,a,0,-1,x.i.Gc.na,null)};h.da(x.i.Gc,l.u);x.i.Gc.na=[6,2];l.u.ha&&(x.i.Gc.prototype.C=function(a){return x.i.Gc.C(a,this)},x.i.Gc.C=function(a,b){var c,e={q7:(c=b.hz())&&x.i.yb.C(a,c),zba:l.u.Ka(b.rA(),x.i.Bd.C,a),Zq:l.u.va(b,1,\"\"),Q4:l.u.Ka(b.Ey(),x.i.ud.C,a),m3:l.u.va(b,5,0)};a&&(e.ja=b);return e});\nx.i.Gc.ia=function(a){a=new l.ba(a);var b=new x.i.Gc;return x.i.Gc.F(b,a)};x.i.Gc.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 7:c=new x.i.yb;b.T(c,x.i.yb.F);a.$R(c);break;case 6:c=new x.i.Bd;b.T(c,x.i.Bd.F);a.hJ(c);break;case 1:c=b.Aa();a.rj(c);break;case 2:c=new x.i.ud;b.T(c,x.i.ud.F);a.UH(c);break;case 5:c=b.we();a.CQ(c);break;default:b.ea()}}return a};\nx.i.Gc.G=function(a,b){var c;c=a.hz();null!=c&&b.oa(7,c,x.i.yb.G);c=a.rA();0<c.length&&b.Oa(6,c,x.i.Bd.G);c=a.Jl();0<c.length&&b.Ja(1,c);c=a.Ey();0<c.length&&b.Oa(2,c,x.i.ud.G);c=a.nL();0!==c&&b.xe(5,c)};d=x.i.Gc.prototype;d.hz=function(){return l.u.sa(this,x.i.yb,7)};d.$R=function(a){l.u.Ca(this,7,a)};d.rA=function(){return l.u.Ma(this,x.i.Bd,6)};d.hJ=function(a,b){return l.u.La(this,6,a,x.i.Bd,b)};d.Jl=function(){return l.u.va(this,1,\"\")};d.rj=function(a){l.u.J(this,1,a)};\nd.Ey=function(){return l.u.Ma(this,x.i.ud,2)};d.UH=function(a,b){return l.u.La(this,2,a,x.i.ud,b)};d.nL=function(){return l.u.va(this,5,0)};d.CQ=function(a){l.u.J(this,5,a)};x.i.Gc.K=function(a){return l.u.K(x.i.Gc,a)};x.i.Gc.kX={Ai:0,f_:1,aY:2};x.i.Je=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.Je,l.u);\nl.u.ha&&(x.i.Je.prototype.C=function(a){return x.i.Je.C(a,this)},x.i.Je.C=function(a,b){var c,e={k:(c=b.lz())&&x.google.N.qc.C(a,c),value:+l.u.va(b,2,0),Lca:+l.u.va(b,3,0)};a&&(e.ja=b);return e});x.i.Je.ia=function(a){a=new l.ba(a);var b=new x.i.Je;return x.i.Je.F(b,a)};x.i.Je.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.google.N.qc;b.T(c,x.google.N.qc.F);a.fS(c);break;case 2:c=b.pa();a.setValue(c);break;case 3:c=b.pa();a.mV(c);break;default:b.ea()}}return a};\nx.i.Je.G=function(a,b){var c;c=a.lz();null!=c&&b.oa(1,c,x.google.N.qc.G);c=a.getValue();0!==c&&b.ya(2,c);c=a.EM();0!==c&&b.ya(3,c)};d=x.i.Je.prototype;d.lz=function(){return l.u.sa(this,x.google.N.qc,1)};d.fS=function(a){l.u.Ca(this,1,a)};d.getValue=function(){return+l.u.va(this,2,0)};d.setValue=function(a){l.u.J(this,2,a)};d.EM=function(){return+l.u.va(this,3,0)};d.mV=function(a){l.u.J(this,3,a)};x.i.Je.K=function(a){return l.u.K(x.i.Je,a)};\nx.i.mc=function(a){l.u.initialize(this,a,0,-1,x.i.mc.na,null)};h.da(x.i.mc,l.u);x.i.mc.na=[16,11,12,20];\nl.u.ha&&(x.i.mc.prototype.C=function(a){return x.i.mc.C(a,this)},x.i.mc.C=function(a,b){var c,e={XO:(c=b.Zl())&&x.google.N.Ba.C(a,c),Kba:(c=b.vA())&&x.google.N.Ba.C(a,c),aO:(c=b.Wl())&&x.google.N.Ba.C(a,c),C$:(c=b.Qz())&&x.google.N.Ba.C(a,c),o2:(c=b.Sx())&&x.google.N.Ba.C(a,c),n2:(c=b.Rx())&&x.google.N.Ba.C(a,c),Oca:(c=b.IA())&&x.google.N.Ba.C(a,c),wl:(c=b.Gg())&&x.google.N.Ba.C(a,c),I2:(c=b.Zx())&&x.i.Re.C(a,c),$B:(c=b.mk())&&x.google.N.Ba.C(a,c),kaa:(c=b.cA())&&x.google.N.Ba.C(a,c),jaa:(c=b.bA())&&\nx.google.N.Ba.C(a,c),Kca:(c=b.HA())&&x.google.N.Ba.C(a,c),G2:l.u.Ka(b.Yx(),x.i.Ga.C,a),C2:(c=b.Xx())&&x.i.dd.C(a,c),d4:(c=b.ty())&&x.i.Za.C(a,c),L2:l.u.Ka(b.$x(),x.i.Pc.C,a),M2:l.u.Ka(b.ay(),x.i.Pc.C,a),P$:l.u.Ka(b.Tz(),x.i.Je.C,a),j2:(c=b.Ox())&&x.google.N.Ba.C(a,c)};a&&(e.ja=b);return e});x.i.mc.ia=function(a){a=new l.ba(a);var b=new x.i.mc;return x.i.mc.F(b,a)};\nx.i.mc.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.google.N.Ba;b.T(c,x.google.N.Ba.F);a.gt(c);break;case 2:c=new x.google.N.Ba;b.T(c,x.google.N.Ba.F);a.PU(c);break;case 3:c=new x.google.N.Ba;b.T(c,x.google.N.Ba.F);a.Zs(c);break;case 4:c=new x.google.N.Ba;b.T(c,x.google.N.Ba.F);a.PT(c);break;case 5:c=new x.google.N.Ba;b.T(c,x.google.N.Ba.F);a.lQ(c);break;case 6:c=new x.google.N.Ba;b.T(c,x.google.N.Ba.F);a.kQ(c);break;case 7:c=new x.google.N.Ba;b.T(c,x.google.N.Ba.F);\na.pV(c);break;case 8:c=new x.google.N.Ba;b.T(c,x.google.N.Ba.F);a.Kg(c);break;case 17:c=new x.i.Re;b.T(c,x.i.Re.F);a.uQ(c);break;case 9:c=new x.google.N.Ba;b.T(c,x.google.N.Ba.F);a.ym(c);break;case 14:c=new x.google.N.Ba;b.T(c,x.google.N.Ba.F);a.pU(c);break;case 15:c=new x.google.N.Ba;b.T(c,x.google.N.Ba.F);a.oU(c);break;case 19:c=new x.google.N.Ba;b.T(c,x.google.N.Ba.F);a.lV(c);break;case 16:c=new x.i.Ga;b.T(c,x.i.Ga.F);a.AH(c);break;case 18:c=new x.i.dd;b.T(c,x.i.dd.F);a.tQ(c);break;case 10:c=new x.i.Za;\nb.T(c,x.i.Za.F);a.OQ(c);break;case 11:c=new x.i.Pc;b.T(c,x.i.Pc.F);a.CH(c);break;case 12:c=new x.i.Pc;b.T(c,x.i.Pc.F);a.DH(c);break;case 20:c=new x.i.Je;b.T(c,x.i.Je.F);a.WI(c);break;case 13:c=new x.google.N.Ba;b.T(c,x.google.N.Ba.F);a.hQ(c);break;default:b.ea()}}return a};\nx.i.mc.G=function(a,b){var c;c=a.Zl();null!=c&&b.oa(1,c,x.google.N.Ba.G);c=a.vA();null!=c&&b.oa(2,c,x.google.N.Ba.G);c=a.Wl();null!=c&&b.oa(3,c,x.google.N.Ba.G);c=a.Qz();null!=c&&b.oa(4,c,x.google.N.Ba.G);c=a.Sx();null!=c&&b.oa(5,c,x.google.N.Ba.G);c=a.Rx();null!=c&&b.oa(6,c,x.google.N.Ba.G);c=a.IA();null!=c&&b.oa(7,c,x.google.N.Ba.G);c=a.Gg();null!=c&&b.oa(8,c,x.google.N.Ba.G);c=a.Zx();null!=c&&b.oa(17,c,x.i.Re.G);c=a.mk();null!=c&&b.oa(9,c,x.google.N.Ba.G);c=a.cA();null!=c&&b.oa(14,c,x.google.N.Ba.G);\nc=a.bA();null!=c&&b.oa(15,c,x.google.N.Ba.G);c=a.HA();null!=c&&b.oa(19,c,x.google.N.Ba.G);c=a.Yx();0<c.length&&b.Oa(16,c,x.i.Ga.G);c=a.Xx();null!=c&&b.oa(18,c,x.i.dd.G);c=a.ty();null!=c&&b.oa(10,c,x.i.Za.G);c=a.$x();0<c.length&&b.Oa(11,c,x.i.Pc.G);c=a.ay();0<c.length&&b.Oa(12,c,x.i.Pc.G);c=a.Tz();0<c.length&&b.Oa(20,c,x.i.Je.G);c=a.Ox();null!=c&&b.oa(13,c,x.google.N.Ba.G)};d=x.i.mc.prototype;d.Zl=function(){return l.u.sa(this,x.google.N.Ba,1)};d.gt=function(a){l.u.Ca(this,1,a)};\nd.vA=function(){return l.u.sa(this,x.google.N.Ba,2)};d.PU=function(a){l.u.Ca(this,2,a)};d.Wl=function(){return l.u.sa(this,x.google.N.Ba,3)};d.Zs=function(a){l.u.Ca(this,3,a)};d.Qz=function(){return l.u.sa(this,x.google.N.Ba,4)};d.PT=function(a){l.u.Ca(this,4,a)};d.Sx=function(){return l.u.sa(this,x.google.N.Ba,5)};d.lQ=function(a){l.u.Ca(this,5,a)};d.Rx=function(){return l.u.sa(this,x.google.N.Ba,6)};d.kQ=function(a){l.u.Ca(this,6,a)};d.IA=function(){return l.u.sa(this,x.google.N.Ba,7)};\nd.pV=function(a){l.u.Ca(this,7,a)};d.Gg=function(){return l.u.sa(this,x.google.N.Ba,8)};d.Kg=function(a){l.u.Ca(this,8,a)};d.Zx=function(){return l.u.sa(this,x.i.Re,17)};d.uQ=function(a){l.u.Ca(this,17,a)};d.mk=function(){return l.u.sa(this,x.google.N.Ba,9)};d.ym=function(a){l.u.Ca(this,9,a)};d.cA=function(){return l.u.sa(this,x.google.N.Ba,14)};d.pU=function(a){l.u.Ca(this,14,a)};d.bA=function(){return l.u.sa(this,x.google.N.Ba,15)};d.oU=function(a){l.u.Ca(this,15,a)};\nd.HA=function(){return l.u.sa(this,x.google.N.Ba,19)};d.lV=function(a){l.u.Ca(this,19,a)};d.Yx=function(){return l.u.Ma(this,x.i.Ga,16)};d.AH=function(a,b){return l.u.La(this,16,a,x.i.Ga,b)};d.Xx=function(){return l.u.sa(this,x.i.dd,18)};d.tQ=function(a){l.u.Ca(this,18,a)};d.ty=function(){return l.u.sa(this,x.i.Za,10)};d.OQ=function(a){l.u.Ca(this,10,a)};d.$x=function(){return l.u.Ma(this,x.i.Pc,11)};d.CH=function(a,b){return l.u.La(this,11,a,x.i.Pc,b)};d.ay=function(){return l.u.Ma(this,x.i.Pc,12)};\nd.DH=function(a,b){return l.u.La(this,12,a,x.i.Pc,b)};d.Tz=function(){return l.u.Ma(this,x.i.Je,20)};d.WI=function(a,b){return l.u.La(this,20,a,x.i.Je,b)};d.Ox=function(){return l.u.sa(this,x.google.N.Ba,13)};d.hQ=function(a){l.u.Ca(this,13,a)};x.i.mc.K=function(a){return l.u.K(x.i.mc,a)};x.i.Za=function(a){l.u.initialize(this,a,0,-1,null,x.i.Za.Ob)};h.da(x.i.Za,l.u);x.i.Za.Ob=[[1,2]];x.i.Za.lX={eX:0,$W:1,PY:2};\nl.u.ha&&(x.i.Za.prototype.C=function(a){return x.i.Za.C(a,this)},x.i.Za.C=function(a,b){var c,e={B2:(c=b.Wx())&&x.i.Za.Kd.C(a,c),n9:(c=b.Bz())&&x.i.Za.nd.C(a,c)};a&&(e.ja=b);return e});x.i.Za.ia=function(a){a=new l.ba(a);var b=new x.i.Za;return x.i.Za.F(b,a)};x.i.Za.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.Za.Kd;b.T(c,x.i.Za.Kd.F);a.sQ(c);break;case 2:c=new x.i.Za.nd;b.T(c,x.i.Za.nd.F);a.ZS(c);break;default:b.ea()}}return a};\nx.i.Za.G=function(a,b){var c;c=a.Wx();null!=c&&b.oa(1,c,x.i.Za.Kd.G);c=a.Bz();null!=c&&b.oa(2,c,x.i.Za.nd.G)};x.i.Za.prototype.Wx=function(){return l.u.sa(this,x.i.Za.Kd,1)};x.i.Za.prototype.sQ=function(a){l.u.Nc(this,1,x.i.Za.Ob[0],a)};x.i.Za.prototype.Bz=function(){return l.u.sa(this,x.i.Za.nd,2)};x.i.Za.prototype.ZS=function(a){l.u.Nc(this,2,x.i.Za.Ob[0],a)};x.i.Za.K=function(a){return l.u.K(x.i.Za,a)};x.i.Za.Kd=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.Za.Kd,l.u);\nl.u.ha&&(x.i.Za.Kd.prototype.C=function(a){return x.i.Za.Kd.C(a,this)},x.i.Za.Kd.C=function(a,b){var c,e={TJ:(c=b.Kl())&&x.i.yc.C(a,c),matrix:(c=b.rz())&&x.i.dd.C(a,c)};a&&(e.ja=b);return e});x.i.Za.Kd.ia=function(a){a=new l.ba(a);var b=new x.i.Za.Kd;return x.i.Za.Kd.F(b,a)};x.i.Za.Kd.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.yc;b.T(c,x.i.yc.F);a.Ls(c);break;case 2:c=new x.i.dd;b.T(c,x.i.dd.F);a.setMatrix(c);break;default:b.ea()}}return a};\nx.i.Za.Kd.G=function(a,b){var c;c=a.Kl();null!=c&&b.oa(1,c,x.i.yc.G);c=a.rz();null!=c&&b.oa(2,c,x.i.dd.G)};x.i.Za.Kd.prototype.Kl=function(){return l.u.sa(this,x.i.yc,1)};x.i.Za.Kd.prototype.Ls=function(a){l.u.Ca(this,1,a)};x.i.Za.Kd.prototype.rz=function(){return l.u.sa(this,x.i.dd,2)};x.i.Za.Kd.prototype.setMatrix=function(a){l.u.Ca(this,2,a)};x.i.Za.Kd.K=function(a){return l.u.K(x.i.Za.Kd,a)};x.i.Za.nd=function(a){l.u.initialize(this,a,0,-1,x.i.Za.nd.na,null)};h.da(x.i.Za.nd,l.u);\nx.i.Za.nd.na=[1];l.u.ha&&(x.i.Za.nd.prototype.C=function(a){return x.i.Za.nd.C(a,this)},x.i.Za.nd.C=function(a,b){var c,e={daa:l.u.gb(b,1),N2:(c=b.by())&&x.i.ed.C(a,c)};a&&(e.ja=b);return e});x.i.Za.nd.ia=function(a){a=new l.ba(a);var b=new x.i.Za.nd;return x.i.Za.nd.F(b,a)};x.i.Za.nd.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.rm();a.kU(c);break;case 2:c=new x.i.ed;b.T(c,x.i.ed.F);a.wQ(c);break;default:b.ea()}}return a};\nx.i.Za.nd.G=function(a,b){var c;c=a.mM();0<c.length&&b.Mm(1,c);c=a.by();null!=c&&b.oa(2,c,x.i.ed.G)};x.i.Za.nd.prototype.mM=function(){return l.u.gb(this,1)};x.i.Za.nd.prototype.kU=function(a){l.u.J(this,1,a||[])};x.i.Za.nd.prototype.by=function(){return l.u.sa(this,x.i.ed,2)};x.i.Za.nd.prototype.wQ=function(a){l.u.Ca(this,2,a)};x.i.Za.nd.K=function(a){return l.u.K(x.i.Za.nd,a)};x.i.Re=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.Re,l.u);\nl.u.ha&&(x.i.Re.prototype.C=function(a){return x.i.Re.C(a,this)},x.i.Re.C=function(a,b){var c,e={lowerBound:(c=b.Xl())&&x.google.N.Ba.C(a,c),upperBound:(c=b.em())&&x.google.N.Ba.C(a,c),value:(c=b.getValue())&&x.google.N.Ba.C(a,c)};a&&(e.ja=b);return e});x.i.Re.ia=function(a){a=new l.ba(a);var b=new x.i.Re;return x.i.Re.F(b,a)};\nx.i.Re.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.google.N.Ba;b.T(c,x.google.N.Ba.F);a.tj(c);break;case 2:c=new x.google.N.Ba;b.T(c,x.google.N.Ba.F);a.xj(c);break;case 3:c=new x.google.N.Ba;b.T(c,x.google.N.Ba.F);a.setValue(c);break;default:b.ea()}}return a};x.i.Re.G=function(a,b){var c;c=a.Xl();null!=c&&b.oa(1,c,x.google.N.Ba.G);c=a.em();null!=c&&b.oa(2,c,x.google.N.Ba.G);c=a.getValue();null!=c&&b.oa(3,c,x.google.N.Ba.G)};d=x.i.Re.prototype;\nd.Xl=function(){return l.u.sa(this,x.google.N.Ba,1)};d.tj=function(a){l.u.Ca(this,1,a)};d.em=function(){return l.u.sa(this,x.google.N.Ba,2)};d.xj=function(a){l.u.Ca(this,2,a)};d.getValue=function(){return l.u.sa(this,x.google.N.Ba,3)};d.setValue=function(a){l.u.Ca(this,3,a)};x.i.Re.K=function(a){return l.u.K(x.i.Re,a)};x.i.Ga=function(a){l.u.initialize(this,a,0,-1,null,x.i.Ga.Ob)};h.da(x.i.Ga,l.u);x.i.Ga.Ob=[[1,2,3,4]];x.i.Ga.aF={$E:0,fD:1,sE:2,tE:3,gD:4};\nl.u.ha&&(x.i.Ga.prototype.C=function(a){return x.i.Ga.C(a,this)},x.i.Ga.C=function(a,b){var c,e={cj:(c=b.Nl())&&x.i.Ga.cc.C(a,c),oP:(c=b.$l())&&x.i.Ga.dc.C(a,c),pP:(c=b.am())&&x.i.Ga.ec.C(a,c),BK:(c=b.Pl())&&x.i.Ga.Bb.C(a,c),CK:(c=b.Ql())&&x.google.N.qc.C(a,c),value:+l.u.va(b,6,0)};a&&(e.ja=b);return e});x.i.Ga.ia=function(a){a=new l.ba(a);var b=new x.i.Ga;return x.i.Ga.F(b,a)};\nx.i.Ga.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.Ga.cc;b.T(c,x.i.Ga.cc.F);a.Os(c);break;case 2:c=new x.i.Ga.dc;b.T(c,x.i.Ga.dc.F);a.jt(c);break;case 3:c=new x.i.Ga.ec;b.T(c,x.i.Ga.ec.F);a.kt(c);break;case 4:c=new x.i.Ga.Bb;b.T(c,x.i.Ga.Bb.F);a.Ps(c);break;case 5:c=new x.google.N.qc;b.T(c,x.google.N.qc.F);a.Qs(c);break;case 6:c=b.pa();a.setValue(c);break;default:b.ea()}}return a};\nx.i.Ga.G=function(a,b){var c;c=a.Nl();null!=c&&b.oa(1,c,x.i.Ga.cc.G);c=a.$l();null!=c&&b.oa(2,c,x.i.Ga.dc.G);c=a.am();null!=c&&b.oa(3,c,x.i.Ga.ec.G);c=a.Pl();null!=c&&b.oa(4,c,x.i.Ga.Bb.G);c=a.Ql();null!=c&&b.oa(5,c,x.google.N.qc.G);c=a.getValue();0!==c&&b.ya(6,c)};d=x.i.Ga.prototype;d.Nl=function(){return l.u.sa(this,x.i.Ga.cc,1)};d.Os=function(a){l.u.Nc(this,1,x.i.Ga.Ob[0],a)};d.$l=function(){return l.u.sa(this,x.i.Ga.dc,2)};d.jt=function(a){l.u.Nc(this,2,x.i.Ga.Ob[0],a)};\nd.am=function(){return l.u.sa(this,x.i.Ga.ec,3)};d.kt=function(a){l.u.Nc(this,3,x.i.Ga.Ob[0],a)};d.Pl=function(){return l.u.sa(this,x.i.Ga.Bb,4)};d.Ps=function(a){l.u.Nc(this,4,x.i.Ga.Ob[0],a)};d.Ql=function(){return l.u.sa(this,x.google.N.qc,5)};d.Qs=function(a){l.u.Ca(this,5,a)};d.getValue=function(){return+l.u.va(this,6,0)};d.setValue=function(a){l.u.J(this,6,a)};x.i.Ga.K=function(a){return l.u.K(x.i.Ga,a)};x.i.Ga.cc=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.Ga.cc,l.u);\nl.u.ha&&(x.i.Ga.cc.prototype.C=function(a){return x.i.Ga.cc.C(a,this)},x.i.Ga.cc.C=function(a,b){var c={};a&&(c.ja=b);return c});x.i.Ga.cc.ia=function(a){a=new l.ba(a);var b=new x.i.Ga.cc;return x.i.Ga.cc.F(b,a)};x.i.Ga.cc.F=function(a,b){for(;b.fa()&&!b.ga();)b.ea();return a};x.i.Ga.cc.G=function(){};x.i.Ga.cc.K=function(a){return l.u.K(x.i.Ga.cc,a)};x.i.Ga.dc=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.Ga.dc,l.u);\nl.u.ha&&(x.i.Ga.dc.prototype.C=function(a){return x.i.Ga.dc.C(a,this)},x.i.Ga.dc.C=function(a,b){var c={};a&&(c.ja=b);return c});x.i.Ga.dc.ia=function(a){a=new l.ba(a);var b=new x.i.Ga.dc;return x.i.Ga.dc.F(b,a)};x.i.Ga.dc.F=function(a,b){for(;b.fa()&&!b.ga();)b.ea();return a};x.i.Ga.dc.G=function(){};x.i.Ga.dc.K=function(a){return l.u.K(x.i.Ga.dc,a)};x.i.Ga.ec=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.Ga.ec,l.u);\nl.u.ha&&(x.i.Ga.ec.prototype.C=function(a){return x.i.Ga.ec.C(a,this)},x.i.Ga.ec.C=function(a,b){var c={};a&&(c.ja=b);return c});x.i.Ga.ec.ia=function(a){a=new l.ba(a);var b=new x.i.Ga.ec;return x.i.Ga.ec.F(b,a)};x.i.Ga.ec.F=function(a,b){for(;b.fa()&&!b.ga();)b.ea();return a};x.i.Ga.ec.G=function(){};x.i.Ga.ec.K=function(a){return l.u.K(x.i.Ga.ec,a)};x.i.Ga.Bb=function(a){l.u.initialize(this,a,0,-1,x.i.Ga.Bb.na,null)};h.da(x.i.Ga.Bb,l.u);x.i.Ga.Bb.na=[1];\nl.u.ha&&(x.i.Ga.Bb.prototype.C=function(a){return x.i.Ga.Bb.C(a,this)},x.i.Ga.Bb.C=function(a,b){var c={DW:l.u.gb(b,1)};a&&(c.ja=b);return c});x.i.Ga.Bb.ia=function(a){a=new l.ba(a);var b=new x.i.Ga.Bb;return x.i.Ga.Bb.F(b,a)};x.i.Ga.Bb.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.rm();a.rt(c);break;default:b.ea()}}return a};x.i.Ga.Bb.G=function(a,b){a=a.Tr();0<a.length&&b.Mm(1,a)};x.i.Ga.Bb.prototype.Tr=function(){return l.u.gb(this,1)};\nx.i.Ga.Bb.prototype.rt=function(a){l.u.J(this,1,a||[])};x.i.Ga.Bb.K=function(a){return l.u.K(x.i.Ga.Bb,a)};x.i.Vd=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.Vd,l.u);l.u.ha&&(x.i.Vd.prototype.C=function(a){return x.i.Vd.C(a,this)},x.i.Vd.C=function(a,b){var c,e={aj:(c=b.Hg())&&x.google.N.Ke.C(a,c),type:l.u.va(b,2,0),sign:l.u.va(b,3,0),weight:+l.u.va(b,4,0)};a&&(e.ja=b);return e});x.i.Vd.ia=function(a){a=new l.ba(a);var b=new x.i.Vd;return x.i.Vd.F(b,a)};\nx.i.Vd.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.google.N.Ke;b.T(c,x.google.N.Ke.F);a.xf(c);break;case 2:c=b.we();a.yf(c);break;case 3:c=b.we();a.IU(c);break;case 4:c=b.pa();a.qt(c);break;default:b.ea()}}return a};x.i.Vd.G=function(a,b){var c;c=a.Hg();null!=c&&b.oa(1,c,x.google.N.Ke.G);c=a.mi();0!==c&&b.xe(2,c);c=a.tM();0!==c&&b.xe(3,c);c=a.Sr();0!==c&&b.ya(4,c)};d=x.i.Vd.prototype;d.Hg=function(){return l.u.sa(this,x.google.N.Ke,1)};\nd.xf=function(a){l.u.Ca(this,1,a)};d.mi=function(){return l.u.va(this,2,0)};d.yf=function(a){l.u.J(this,2,a)};d.tM=function(){return l.u.va(this,3,0)};d.IU=function(a){l.u.J(this,3,a)};d.Sr=function(){return+l.u.va(this,4,0)};d.qt=function(a){l.u.J(this,4,a)};x.i.Vd.K=function(a){return l.u.K(x.i.Vd,a)};x.i.Vd.yg={sY:0,tY:1,uY:2};x.i.Vd.WZ={Ai:0,lE:1,$D:2};x.i.rc=function(a){l.u.initialize(this,a,0,-1,x.i.rc.na,null)};h.da(x.i.rc,l.u);x.i.rc.na=[1];\nl.u.ha&&(x.i.rc.prototype.C=function(a){return x.i.rc.C(a,this)},x.i.rc.C=function(a,b){var c={vaa:l.u.Ka(b.hA(),x.i.Vd.C,a),value:+l.u.va(b,2,0)};a&&(c.ja=b);return c});x.i.rc.ia=function(a){a=new l.ba(a);var b=new x.i.rc;return x.i.rc.F(b,a)};x.i.rc.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.Vd;b.T(c,x.i.Vd.F);a.$I(c);break;case 2:c=b.pa();a.setValue(c);break;default:b.ea()}}return a};\nx.i.rc.G=function(a,b){var c;c=a.hA();0<c.length&&b.Oa(1,c,x.i.Vd.G);c=a.getValue();0!==c&&b.ya(2,c)};x.i.rc.prototype.hA=function(){return l.u.Ma(this,x.i.Vd,1)};x.i.rc.prototype.$I=function(a,b){return l.u.La(this,1,a,x.i.Vd,b)};x.i.rc.prototype.getValue=function(){return+l.u.va(this,2,0)};x.i.rc.prototype.setValue=function(a){l.u.J(this,2,a)};x.i.rc.K=function(a){return l.u.K(x.i.rc,a)};x.i.yc=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.yc,l.u);\nl.u.ha&&(x.i.yc.prototype.C=function(a){return x.i.yc.C(a,this)},x.i.yc.C=function(a,b){var c={caa:+l.u.va(b,1,0),zca:l.u.va(b,2,0)};a&&(c.ja=b);return c});x.i.yc.ia=function(a){a=new l.ba(a);var b=new x.i.yc;return x.i.yc.F(b,a)};x.i.yc.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.pa();a.jU(c);break;case 2:c=b.we();a.gV(c);break;default:b.ea()}}return a};x.i.yc.G=function(a,b){var c;c=a.lM();0!==c&&b.ya(1,c);c=a.DM();0!==c&&b.xe(2,c)};\nx.i.yc.prototype.lM=function(){return+l.u.va(this,1,0)};x.i.yc.prototype.jU=function(a){l.u.J(this,1,a)};x.i.yc.prototype.DM=function(){return l.u.va(this,2,0)};x.i.yc.prototype.gV=function(a){l.u.J(this,2,a)};x.i.yc.K=function(a){return l.u.K(x.i.yc,a)};x.i.yc.k_={l_:0,lE:1,$D:2};x.i.dd=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.dd,l.u);\nl.u.ha&&(x.i.dd.prototype.C=function(a){return x.i.dd.C(a,this)},x.i.dd.C=function(a,b){var c={hda:+l.u.va(b,1,0),R5:+l.u.va(b,2,0),fda:+l.u.va(b,3,0),P5:+l.u.va(b,4,0)};a&&(c.ja=b);return c});x.i.dd.ia=function(a){a=new l.ba(a);var b=new x.i.dd;return x.i.dd.F(b,a)};x.i.dd.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.pa();a.CV(c);break;case 2:c=b.pa();a.AR(c);break;case 3:c=b.pa();a.BV(c);break;case 4:c=b.pa();a.zR(c);break;default:b.ea()}}return a};\nx.i.dd.G=function(a,b){var c;c=a.HM();0!==c&&b.ya(1,c);c=a.GL();0!==c&&b.ya(2,c);c=a.FM();0!==c&&b.ya(3,c);c=a.EL();0!==c&&b.ya(4,c)};d=x.i.dd.prototype;d.HM=function(){return+l.u.va(this,1,0)};d.CV=function(a){l.u.J(this,1,a)};d.GL=function(){return+l.u.va(this,2,0)};d.AR=function(a){l.u.J(this,2,a)};d.FM=function(){return+l.u.va(this,3,0)};d.BV=function(a){l.u.J(this,3,a)};d.EL=function(){return+l.u.va(this,4,0)};d.zR=function(a){l.u.J(this,4,a)};x.i.dd.K=function(a){return l.u.K(x.i.dd,a)};\nx.i.ed=function(a){l.u.initialize(this,a,0,-1,x.i.ed.na,null)};h.da(x.i.ed,l.u);x.i.ed.na=[1,2];l.u.ha&&(x.i.ed.prototype.C=function(a){return x.i.ed.C(a,this)},x.i.ed.C=function(a,b){var c={t9:l.u.gb(b,1),H$:l.u.gb(b,2)};a&&(c.ja=b);return c});x.i.ed.ia=function(a){a=new l.ba(a);var b=new x.i.ed;return x.i.ed.F(b,a)};x.i.ed.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.rm();a.dT(c);break;case 2:c=b.rm();a.TT(c);break;default:b.ea()}}return a};\nx.i.ed.G=function(a,b){var c;c=a.aM();0<c.length&&b.Mm(1,c);c=a.gM();0<c.length&&b.Mm(2,c)};x.i.ed.prototype.aM=function(){return l.u.gb(this,1)};x.i.ed.prototype.dT=function(a){l.u.J(this,1,a||[])};x.i.ed.prototype.gM=function(){return l.u.gb(this,2)};x.i.ed.prototype.TT=function(a){l.u.J(this,2,a||[])};x.i.ed.K=function(a){return l.u.K(x.i.ed,a)};x.i.Pc=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.Pc,l.u);\nl.u.ha&&(x.i.Pc.prototype.C=function(a){return x.i.Pc.C(a,this)},x.i.Pc.C=function(a,b){var c,e={r8:+l.u.va(b,1,0),pda:+l.u.va(b,2,0),X9:(c=b.Iz())&&x.google.N.Ba.C(a,c),Pca:(c=b.JA())&&x.google.N.Ba.C(a,c),Rca:(c=b.LA())&&x.google.N.Ba.C(a,c),Qca:(c=b.KA())&&x.google.N.Ba.C(a,c)};a&&(e.ja=b);return e});x.i.Pc.ia=function(a){a=new l.ba(a);var b=new x.i.Pc;return x.i.Pc.F(b,a)};\nx.i.Pc.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.pa();a.sS(c);break;case 2:c=b.pa();a.DV(c);break;case 3:c=new x.google.N.Ba;b.T(c,x.google.N.Ba.F);a.zT(c);break;case 4:c=new x.google.N.Ba;b.T(c,x.google.N.Ba.F);a.qV(c);break;case 5:c=new x.google.N.Ba;b.T(c,x.google.N.Ba.F);a.sV(c);break;case 6:c=new x.google.N.Ba;b.T(c,x.google.N.Ba.F);a.rV(c);break;default:b.ea()}}return a};\nx.i.Pc.G=function(a,b){var c;c=a.SL();0!==c&&b.ya(1,c);c=a.JM();0!==c&&b.ya(2,c);c=a.Iz();null!=c&&b.oa(3,c,x.google.N.Ba.G);c=a.JA();null!=c&&b.oa(4,c,x.google.N.Ba.G);c=a.LA();null!=c&&b.oa(5,c,x.google.N.Ba.G);c=a.KA();null!=c&&b.oa(6,c,x.google.N.Ba.G)};d=x.i.Pc.prototype;d.SL=function(){return+l.u.va(this,1,0)};d.sS=function(a){l.u.J(this,1,a)};d.JM=function(){return+l.u.va(this,2,0)};d.DV=function(a){l.u.J(this,2,a)};d.Iz=function(){return l.u.sa(this,x.google.N.Ba,3)};\nd.zT=function(a){l.u.Ca(this,3,a)};d.JA=function(){return l.u.sa(this,x.google.N.Ba,4)};d.qV=function(a){l.u.Ca(this,4,a)};d.LA=function(){return l.u.sa(this,x.google.N.Ba,5)};d.sV=function(a){l.u.Ca(this,5,a)};d.KA=function(){return l.u.sa(this,x.google.N.Ba,6)};d.rV=function(a){l.u.Ca(this,6,a)};x.i.Pc.K=function(a){return l.u.K(x.i.Pc,a)};x.i.ua=function(a){l.u.initialize(this,a,0,-1,null,x.i.ua.Ob)};h.da(x.i.ua,l.u);x.i.ua.Ob=[[1,2,3,4,7]];x.i.ua.aF={$E:0,BZ:1,sE:2,tE:3,gD:4,fD:7};\nl.u.ha&&(x.i.ua.prototype.C=function(a){return x.i.ua.C(a,this)},x.i.ua.C=function(a,b){var c,e={qaa:(c=b.fA())&&x.i.ua.hf.C(a,c),oP:(c=b.$l())&&x.i.ua.dc.C(a,c),pP:(c=b.am())&&x.i.ua.ec.C(a,c),BK:(c=b.Pl())&&x.i.ua.Bb.C(a,c),cj:(c=b.Nl())&&x.i.ua.cc.C(a,c),CK:(c=b.Ql())&&x.google.N.qc.C(a,c),value:+l.u.va(b,6,0)};a&&(e.ja=b);return e});x.i.ua.ia=function(a){a=new l.ba(a);var b=new x.i.ua;return x.i.ua.F(b,a)};\nx.i.ua.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.ua.hf;b.T(c,x.i.ua.hf.F);a.sU(c);break;case 2:c=new x.i.ua.dc;b.T(c,x.i.ua.dc.F);a.jt(c);break;case 3:c=new x.i.ua.ec;b.T(c,x.i.ua.ec.F);a.kt(c);break;case 4:c=new x.i.ua.Bb;b.T(c,x.i.ua.Bb.F);a.Ps(c);break;case 7:c=new x.i.ua.cc;b.T(c,x.i.ua.cc.F);a.Os(c);break;case 5:c=new x.google.N.qc;b.T(c,x.google.N.qc.F);a.Qs(c);break;case 6:c=b.pa();a.setValue(c);break;default:b.ea()}}return a};\nx.i.ua.G=function(a,b){var c;c=a.fA();null!=c&&b.oa(1,c,x.i.ua.hf.G);c=a.$l();null!=c&&b.oa(2,c,x.i.ua.dc.G);c=a.am();null!=c&&b.oa(3,c,x.i.ua.ec.G);c=a.Pl();null!=c&&b.oa(4,c,x.i.ua.Bb.G);c=a.Nl();null!=c&&b.oa(7,c,x.i.ua.cc.G);c=a.Ql();null!=c&&b.oa(5,c,x.google.N.qc.G);c=a.getValue();0!==c&&b.ya(6,c)};d=x.i.ua.prototype;d.fA=function(){return l.u.sa(this,x.i.ua.hf,1)};d.sU=function(a){l.u.Nc(this,1,x.i.ua.Ob[0],a)};d.$l=function(){return l.u.sa(this,x.i.ua.dc,2)};\nd.jt=function(a){l.u.Nc(this,2,x.i.ua.Ob[0],a)};d.am=function(){return l.u.sa(this,x.i.ua.ec,3)};d.kt=function(a){l.u.Nc(this,3,x.i.ua.Ob[0],a)};d.Pl=function(){return l.u.sa(this,x.i.ua.Bb,4)};d.Ps=function(a){l.u.Nc(this,4,x.i.ua.Ob[0],a)};d.Nl=function(){return l.u.sa(this,x.i.ua.cc,7)};d.Os=function(a){l.u.Nc(this,7,x.i.ua.Ob[0],a)};d.Ql=function(){return l.u.sa(this,x.google.N.qc,5)};d.Qs=function(a){l.u.Ca(this,5,a)};d.getValue=function(){return+l.u.va(this,6,0)};\nd.setValue=function(a){l.u.J(this,6,a)};x.i.ua.K=function(a){return l.u.K(x.i.ua,a)};x.i.ua.hf=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.ua.hf,l.u);l.u.ha&&(x.i.ua.hf.prototype.C=function(a){return x.i.ua.hf.C(a,this)},x.i.ua.hf.C=function(a,b){var c={};a&&(c.ja=b);return c});x.i.ua.hf.ia=function(a){a=new l.ba(a);var b=new x.i.ua.hf;return x.i.ua.hf.F(b,a)};x.i.ua.hf.F=function(a,b){for(;b.fa()&&!b.ga();)b.ea();return a};x.i.ua.hf.G=function(){};\nx.i.ua.hf.K=function(a){return l.u.K(x.i.ua.hf,a)};x.i.ua.dc=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.ua.dc,l.u);l.u.ha&&(x.i.ua.dc.prototype.C=function(a){return x.i.ua.dc.C(a,this)},x.i.ua.dc.C=function(a,b){var c={};a&&(c.ja=b);return c});x.i.ua.dc.ia=function(a){a=new l.ba(a);var b=new x.i.ua.dc;return x.i.ua.dc.F(b,a)};x.i.ua.dc.F=function(a,b){for(;b.fa()&&!b.ga();)b.ea();return a};x.i.ua.dc.G=function(){};x.i.ua.dc.K=function(a){return l.u.K(x.i.ua.dc,a)};\nx.i.ua.ec=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.ua.ec,l.u);l.u.ha&&(x.i.ua.ec.prototype.C=function(a){return x.i.ua.ec.C(a,this)},x.i.ua.ec.C=function(a,b){var c={};a&&(c.ja=b);return c});x.i.ua.ec.ia=function(a){a=new l.ba(a);var b=new x.i.ua.ec;return x.i.ua.ec.F(b,a)};x.i.ua.ec.F=function(a,b){for(;b.fa()&&!b.ga();)b.ea();return a};x.i.ua.ec.G=function(){};x.i.ua.ec.K=function(a){return l.u.K(x.i.ua.ec,a)};x.i.ua.Bb=function(a){l.u.initialize(this,a,0,-1,x.i.ua.Bb.na,null)};\nh.da(x.i.ua.Bb,l.u);x.i.ua.Bb.na=[1];l.u.ha&&(x.i.ua.Bb.prototype.C=function(a){return x.i.ua.Bb.C(a,this)},x.i.ua.Bb.C=function(a,b){var c={DW:l.u.gb(b,1)};a&&(c.ja=b);return c});x.i.ua.Bb.ia=function(a){a=new l.ba(a);var b=new x.i.ua.Bb;return x.i.ua.Bb.F(b,a)};x.i.ua.Bb.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.rm();a.rt(c);break;default:b.ea()}}return a};x.i.ua.Bb.G=function(a,b){a=a.Tr();0<a.length&&b.Mm(1,a)};\nx.i.ua.Bb.prototype.Tr=function(){return l.u.gb(this,1)};x.i.ua.Bb.prototype.rt=function(a){l.u.J(this,1,a||[])};x.i.ua.Bb.K=function(a){return l.u.K(x.i.ua.Bb,a)};x.i.ua.cc=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.ua.cc,l.u);l.u.ha&&(x.i.ua.cc.prototype.C=function(a){return x.i.ua.cc.C(a,this)},x.i.ua.cc.C=function(a,b){var c={};a&&(c.ja=b);return c});x.i.ua.cc.ia=function(a){a=new l.ba(a);var b=new x.i.ua.cc;return x.i.ua.cc.F(b,a)};\nx.i.ua.cc.F=function(a,b){for(;b.fa()&&!b.ga();)b.ea();return a};x.i.ua.cc.G=function(){};x.i.ua.cc.K=function(a){return l.u.K(x.i.ua.cc,a)};x.i.ke=function(a){l.u.initialize(this,a,0,-1,x.i.ke.na,null)};h.da(x.i.ke,l.u);x.i.ke.na=[1,2,3];l.u.ha&&(x.i.ke.prototype.C=function(a){return x.i.ke.C(a,this)},x.i.ke.C=function(a,b){var c,e={q3:l.u.Ka(b.iy(),x.i.ua.C,a),laa:l.u.Ka(b.dA(),x.i.ua.C,a),w7:l.u.Ka(b.jz(),x.i.ua.C,a),m2:(c=b.Qx())&&x.google.N.Ba.C(a,c)};a&&(e.ja=b);return e});\nx.i.ke.ia=function(a){a=new l.ba(a);var b=new x.i.ke;return x.i.ke.F(b,a)};x.i.ke.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.ua;b.T(c,x.i.ua.F);a.HH(c);break;case 2:c=new x.i.ua;b.T(c,x.i.ua.F);a.YI(c);break;case 3:c=new x.i.ua;b.T(c,x.i.ua.F);a.tI(c);break;case 4:c=new x.google.N.Ba;b.T(c,x.google.N.Ba.F);a.jQ(c);break;default:b.ea()}}return a};\nx.i.ke.G=function(a,b){var c;c=a.iy();0<c.length&&b.Oa(1,c,x.i.ua.G);c=a.dA();0<c.length&&b.Oa(2,c,x.i.ua.G);c=a.jz();0<c.length&&b.Oa(3,c,x.i.ua.G);c=a.Qx();null!=c&&b.oa(4,c,x.google.N.Ba.G)};d=x.i.ke.prototype;d.iy=function(){return l.u.Ma(this,x.i.ua,1)};d.HH=function(a,b){return l.u.La(this,1,a,x.i.ua,b)};d.dA=function(){return l.u.Ma(this,x.i.ua,2)};d.YI=function(a,b){return l.u.La(this,2,a,x.i.ua,b)};d.jz=function(){return l.u.Ma(this,x.i.ua,3)};\nd.tI=function(a,b){return l.u.La(this,3,a,x.i.ua,b)};d.Qx=function(){return l.u.sa(this,x.google.N.Ba,4)};d.jQ=function(a){l.u.Ca(this,4,a)};x.i.ke.K=function(a){return l.u.K(x.i.ke,a)};x.i.vc=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.vc,l.u);l.u.ha&&(x.i.vc.prototype.C=function(a){return x.i.vc.C(a,this)},x.i.vc.C=function(a,b){var c,e={g2:(c=b.Mx())&&x.Xa.Ec.C(a,c),aj:l.u.D(b,2)};a&&(e.ja=b);return e});x.i.vc.ia=function(a){a=new l.ba(a);var b=new x.i.vc;return x.i.vc.F(b,a)};\nx.i.vc.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.Xa.Ec;b.T(c,x.Xa.Ec.F);a.fQ(c);break;case 2:c=b.Aa();a.xf(c);break;default:b.ea()}}return a};x.i.vc.G=function(a,b){var c;c=a.Mx();null!=c&&b.oa(1,c,x.Xa.Ec.G);c=l.u.D(a,2);null!=c&&b.Ja(2,c)};x.i.vc.prototype.Mx=function(){return l.u.sa(this,x.Xa.Ec,1,1)};x.i.vc.prototype.fQ=function(a){l.u.Ca(this,1,a)};x.i.vc.prototype.Hg=function(){return l.u.D(this,2)};x.i.vc.prototype.xf=function(a){l.u.J(this,2,a)};\nx.i.vc.K=function(a){return l.u.K(x.i.vc,a)};x.i.Lb=function(a){l.u.initialize(this,a,0,-1,x.i.Lb.na,null)};h.da(x.i.Lb,l.u);x.i.Lb.na=[6,7,9];l.u.ha&&(x.i.Lb.prototype.C=function(a){return x.i.Lb.C(a,this)},x.i.Lb.C=function(a,b){var c,e={cluster:l.u.D(b,1),channel:l.u.D(b,2),Saa:l.u.Na(b,3),M8:l.u.va(b,4,15),B3:l.u.va(b,5,3),SJ:l.u.Ka(b.Il(),x.i.vc.C,a),B5:l.u.Ka(b.Oy(),x.jb.lb.mb.C,a),qda:l.u.va(b,8,!0),Eda:l.u.D(b,9),v3:(c=b.ky())&&x.i.Lb.Ae.C(a,c)};a&&(e.ja=b);return e});\nx.i.Lb.ia=function(a){a=new l.ba(a);var b=new x.i.Lb;return x.i.Lb.F(b,a)};\nx.i.Lb.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.HQ(c);break;case 2:c=b.Aa();a.DQ(c);break;case 3:c=b.ti();a.xU(c);break;case 4:c=b.Ya();a.HS(c);break;case 5:c=b.we();a.JQ(c);break;case 6:c=new x.i.vc;b.T(c,x.i.vc.F);a.Lq(c);break;case 7:c=new x.jb.lb.mb;b.T(c,x.jb.lb.mb.F);a.bI(c);break;case 8:c=b.vf();a.FV(c);break;case 9:c=b.Aa();a.EJ(c);break;case 10:c=new x.i.Lb.Ae;b.T(c,x.i.Lb.Ae.F);a.FQ(c);break;default:b.ea()}}return a};\nx.i.Lb.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Ja(1,c);c=l.u.D(a,2);null!=c&&b.Ja(2,c);c=l.u.D(a,3);null!=c&&b.vi(3,c);c=l.u.D(a,4);null!=c&&b.$a(4,c);c=l.u.D(a,5);null!=c&&b.xe(5,c);c=a.Il();0<c.length&&b.Oa(6,c,x.i.vc.G);c=a.Oy();0<c.length&&b.Oa(7,c,x.jb.lb.mb.G);c=l.u.D(a,8);null!=c&&b.kf(8,c);c=a.PM();0<c.length&&b.oc(9,c);c=a.ky();null!=c&&b.oa(10,c,x.i.Lb.Ae.G)};d=x.i.Lb.prototype;d.HQ=function(a){l.u.J(this,1,a)};d.DQ=function(a){l.u.J(this,2,a)};d.xU=function(a){l.u.J(this,3,a)};\nd.HS=function(a){l.u.J(this,4,a)};d.JQ=function(a){l.u.J(this,5,a)};d.Il=function(){return l.u.Ma(this,x.i.vc,6)};d.Lq=function(a,b){return l.u.La(this,6,a,x.i.vc,b)};d.Oy=function(){return l.u.Ma(this,x.jb.lb.mb,7)};d.bI=function(a,b){return l.u.La(this,7,a,x.jb.lb.mb,b)};d.FV=function(a){l.u.J(this,8,a)};d.PM=function(){return l.u.D(this,9)};d.EJ=function(a,b){l.u.ib(this,9,a,b)};d.ky=function(){return l.u.sa(this,x.i.Lb.Ae,10)};d.FQ=function(a){l.u.Ca(this,10,a)};\nx.i.Lb.K=function(a){return l.u.K(x.i.Lb,a)};x.i.Lb.Ae=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.Lb.Ae,l.u);l.u.ha&&(x.i.Lb.Ae.prototype.C=function(a){return x.i.Lb.Ae.C(a,this)},x.i.Lb.Ae.C=function(a,b){var c={i9:l.u.D(b,1),aca:l.u.D(b,2)};a&&(c.ja=b);return c});x.i.Lb.Ae.ia=function(a){a=new l.ba(a);var b=new x.i.Lb.Ae;return x.i.Lb.Ae.F(b,a)};x.i.Lb.Ae.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.XS(c);break;case 2:c=b.vf();a.aV(c);break;default:b.ea()}}return a};\nx.i.Lb.Ae.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Ja(1,c);c=l.u.D(a,2);null!=c&&b.kf(2,c)};x.i.Lb.Ae.prototype.XS=function(a){l.u.J(this,1,a)};x.i.Lb.Ae.prototype.aV=function(a){l.u.J(this,2,a)};x.i.Lb.Ae.K=function(a){return l.u.K(x.i.Lb.Ae,a)};x.i.Gb=function(a){l.u.initialize(this,a,0,-1,x.i.Gb.na,null)};h.da(x.i.Gb,l.u);x.i.Gb.na=[8,12,9,10,11];\nl.u.ha&&(x.i.Gb.prototype.C=function(a){return x.i.Gb.C(a,this)},x.i.Gb.C=function(a,b){var c={e6:l.u.Ka(b.Yy(),x.i.Lb.C,a),C9:l.u.Ka(b.Gz(),x.i.vc.C,a),M5:l.u.D(b,9),gba:l.u.Ka(b.mA(),x.i.Gb.Fc.C,a),S1:l.u.Ka(b.Lx(),x.i.Gb.Fc.C,a)};a&&(c.ja=b);return c});x.i.Gb.ia=function(a){a=new l.ba(a);var b=new x.i.Gb;return x.i.Gb.F(b,a)};\nx.i.Gb.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 8:c=new x.i.Lb;b.T(c,x.i.Lb.F);a.oI(c);break;case 12:c=new x.i.vc;b.T(c,x.i.vc.F);a.KI(c);break;case 9:c=b.Aa();a.iI(c);break;case 10:c=new x.i.Gb.Fc;b.T(c,x.i.Gb.Fc.F);a.eJ(c);break;case 11:c=new x.i.Gb.Fc;b.T(c,x.i.Gb.Fc.F);a.tH(c);break;default:b.ea()}}return a};\nx.i.Gb.G=function(a,b){var c;c=a.Yy();0<c.length&&b.Oa(8,c,x.i.Lb.G);c=a.Gz();0<c.length&&b.Oa(12,c,x.i.vc.G);c=a.DL();0<c.length&&b.oc(9,c);c=a.mA();0<c.length&&b.Oa(10,c,x.i.Gb.Fc.G);c=a.Lx();0<c.length&&b.Oa(11,c,x.i.Gb.Fc.G)};d=x.i.Gb.prototype;d.Yy=function(){return l.u.Ma(this,x.i.Lb,8)};d.oI=function(a,b){return l.u.La(this,8,a,x.i.Lb,b)};d.Gz=function(){return l.u.Ma(this,x.i.vc,12)};d.KI=function(a,b){return l.u.La(this,12,a,x.i.vc,b)};d.DL=function(){return l.u.D(this,9)};\nd.iI=function(a,b){l.u.ib(this,9,a,b)};d.mA=function(){return l.u.Ma(this,x.i.Gb.Fc,10)};d.eJ=function(a,b){return l.u.La(this,10,a,x.i.Gb.Fc,b)};d.Lx=function(){return l.u.Ma(this,x.i.Gb.Fc,11)};d.tH=function(a,b){return l.u.La(this,11,a,x.i.Gb.Fc,b)};x.i.Gb.K=function(a){return l.u.K(x.i.Gb,a)};x.i.Gb.Fc=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.Gb.Fc,l.u);\nl.u.ha&&(x.i.Gb.Fc.prototype.C=function(a){return x.i.Gb.Fc.C(a,this)},x.i.Gb.Fc.C=function(a,b){var c={Eba:l.u.D(b,2),W4:l.u.D(b,3)};a&&(c.ja=b);return c});x.i.Gb.Fc.ia=function(a){a=new l.ba(a);var b=new x.i.Gb.Fc;return x.i.Gb.Fc.F(b,a)};x.i.Gb.Fc.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 2:c=b.Aa();a.MU(c);break;case 3:c=b.Aa();a.fR(c);break;default:b.ea()}}return a};x.i.Gb.Fc.G=function(a,b){var c;c=l.u.D(a,2);null!=c&&b.Ja(2,c);c=l.u.D(a,3);null!=c&&b.Ja(3,c)};\nx.i.Gb.Fc.prototype.MU=function(a){l.u.J(this,2,a)};x.i.Gb.Fc.prototype.fR=function(a){l.u.J(this,3,a)};x.i.Gb.Fc.K=function(a){return l.u.K(x.i.Gb.Fc,a)};x.i.qe=function(a){l.u.initialize(this,a,0,-1,x.i.qe.na,null)};h.da(x.i.qe,l.u);x.i.qe.na=[10];\nl.u.ha&&(x.i.qe.prototype.C=function(a){return x.i.qe.C(a,this)},x.i.qe.C=function(a,b){var c,e={Oba:l.u.D(b,2),j7:l.u.va(b,3,24),h7:l.u.D(b,4),N$:l.u.D(b,5),z9:l.u.D(b,6),V8:l.u.D(b,7),d7:l.u.Na(b,9),l2:l.u.Ka(b.Px(),x.i.cd.C,a),k7:l.u.D(b,8),s7:l.u.va(b,12,\"UTC\"),maa:l.u.D(b,13),D8:l.u.D(b,15),Bba:l.u.D(b,14),Dba:(c=b.tA())&&x.i.Xd.C(a,c)};a&&(e.ja=b);return e});x.i.qe.ia=function(a){a=new l.ba(a);var b=new x.i.qe;return x.i.qe.F(b,a)};\nx.i.qe.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 2:c=b.Aa();a.RU(c);break;case 3:c=b.Ya();a.UR(c);break;case 4:c=b.Ya();a.SR(c);break;case 5:c=b.Ya();a.ZT(c);break;case 6:c=b.Ya();a.jT(c);break;case 7:c=b.Ya();a.QS(c);break;case 9:c=b.ti();a.OR(c);break;case 10:c=new x.i.cd;b.T(c,x.i.cd.F);a.wH(c);break;case 8:c=b.Ya();a.VR(c);break;case 12:c=b.Aa();a.aS(c);break;case 13:c=b.Aa();a.qU(c);break;case 15:c=b.ad();a.ES(c);break;case 14:c=b.Aa();a.KU(c);break;case 16:c=new x.i.Xd;\nb.T(c,x.i.Xd.F);a.LU(c);break;default:b.ea()}}return a};\nx.i.qe.G=function(a,b){var c;c=l.u.D(a,2);null!=c&&b.Ja(2,c);c=l.u.D(a,3);null!=c&&b.$a(3,c);c=l.u.D(a,4);null!=c&&b.$a(4,c);c=l.u.D(a,5);null!=c&&b.$a(5,c);c=l.u.D(a,6);null!=c&&b.$a(6,c);c=l.u.D(a,7);null!=c&&b.$a(7,c);c=l.u.D(a,9);null!=c&&b.vi(9,c);c=a.Px();0<c.length&&b.Oa(10,c,x.i.cd.G);c=l.u.D(a,8);null!=c&&b.$a(8,c);c=l.u.D(a,12);null!=c&&b.Ja(12,c);c=l.u.D(a,13);null!=c&&b.Ja(13,c);c=l.u.D(a,15);null!=c&&b.td(15,c);c=l.u.D(a,14);null!=c&&b.Ja(14,c);c=a.tA();null!=c&&b.oa(16,c,x.i.Xd.G)};\nd=x.i.qe.prototype;d.getStartDate=function(){return l.u.D(this,2)};d.RU=function(a){l.u.J(this,2,a)};d.UR=function(a){l.u.J(this,3,a)};d.SR=function(a){l.u.J(this,4,a)};d.ZT=function(a){l.u.J(this,5,a)};d.jT=function(a){l.u.J(this,6,a)};d.QS=function(a){l.u.J(this,7,a)};d.OR=function(a){l.u.J(this,9,a)};d.Px=function(){return l.u.Ma(this,x.i.cd,10)};d.wH=function(a,b){return l.u.La(this,10,a,x.i.cd,b)};d.VR=function(a){l.u.J(this,8,a)};d.aS=function(a){l.u.J(this,12,a)};\nd.qU=function(a){l.u.J(this,13,a)};d.ES=function(a){l.u.J(this,15,a)};d.KU=function(a){l.u.J(this,14,a)};d.tA=function(){return l.u.sa(this,x.i.Xd,16)};d.LU=function(a){l.u.Ca(this,16,a)};x.i.qe.K=function(a){return l.u.K(x.i.qe,a)};x.i.Xd=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.Xd,l.u);l.u.ha&&(x.i.Xd.prototype.C=function(a){return x.i.Xd.C(a,this)},x.i.Xd.C=function(a,b){var c={naa:+l.u.va(b,1,1),Lda:+l.u.va(b,2,1),Haa:l.u.D(b,3),X4:l.u.D(b,4)};a&&(c.ja=b);return c});\nx.i.Xd.ia=function(a){a=new l.ba(a);var b=new x.i.Xd;return x.i.Xd.F(b,a)};x.i.Xd.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.ti();a.rU(c);break;case 2:c=b.ti();a.RV(c);break;case 3:c=b.Aa();a.vU(c);break;case 4:c=b.vf();a.gR(c);break;default:b.ea()}}return a};x.i.Xd.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.vi(1,c);c=l.u.D(a,2);null!=c&&b.vi(2,c);c=l.u.D(a,3);null!=c&&b.Ja(3,c);c=l.u.D(a,4);null!=c&&b.kf(4,c)};x.i.Xd.prototype.rU=function(a){l.u.J(this,1,a)};\nx.i.Xd.prototype.RV=function(a){l.u.J(this,2,a)};x.i.Xd.prototype.vU=function(a){l.u.J(this,3,a)};x.i.Xd.prototype.gR=function(a){l.u.J(this,4,a)};x.i.Xd.K=function(a){return l.u.K(x.i.Xd,a)};x.i.cd=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.cd,l.u);l.u.ha&&(x.i.cd.prototype.C=function(a){return x.i.cd.C(a,this)},x.i.cd.C=function(a,b){var c={type:l.u.D(b,1),aj:l.u.D(b,2)};a&&(c.ja=b);return c});x.i.cd.ia=function(a){a=new l.ba(a);var b=new x.i.cd;return x.i.cd.F(b,a)};\nx.i.cd.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.we();a.yf(c);break;case 2:c=b.Aa();a.xf(c);break;default:b.ea()}}return a};x.i.cd.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.xe(1,c);c=l.u.D(a,2);null!=c&&b.Ja(2,c)};x.i.cd.prototype.mi=function(){return l.u.D(this,1)};x.i.cd.prototype.yf=function(a){l.u.J(this,1,a)};x.i.cd.prototype.Hg=function(){return l.u.D(this,2)};x.i.cd.prototype.xf=function(a){l.u.J(this,2,a)};x.i.cd.K=function(a){return l.u.K(x.i.cd,a)};\nx.i.cd.XW={QZ:0,PZ:1,LZ:2};x.i.Le=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.Le,l.u);l.u.ha&&(x.i.Le.prototype.C=function(a){return x.i.Le.C(a,this)},x.i.Le.C=function(a,b){var c,e={aj:l.u.D(b,1),IO:l.u.D(b,2),R9:l.u.D(b,3),P9:l.u.D(b,4),G$:+l.u.D(b,5),s9:+l.u.D(b,6),Z6:(c=b.az())&&x.i.nb.C(a,c)};a&&(e.ja=b);return e});x.i.Le.ia=function(a){a=new l.ba(a);var b=new x.i.Le;return x.i.Le.F(b,a)};\nx.i.Le.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.xf(c);break;case 2:c=b.ad();a.ft(c);break;case 3:c=b.ad();a.uT(c);break;case 4:c=b.ad();a.sT(c);break;case 5:c=b.pa();a.ST(c);break;case 6:c=b.pa();a.cT(c);break;case 7:c=new x.i.nb;b.T(c,x.i.nb.F);a.LR(c);break;default:b.ea()}}return a};\nx.i.Le.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Ja(1,c);c=l.u.D(a,2);null!=c&&b.td(2,c);c=l.u.D(a,3);null!=c&&b.td(3,c);c=l.u.D(a,4);null!=c&&b.td(4,c);c=l.u.D(a,5);null!=c&&b.ya(5,c);c=l.u.D(a,6);null!=c&&b.ya(6,c);c=a.az();null!=c&&b.oa(7,c,x.i.nb.G)};d=x.i.Le.prototype;d.Hg=function(){return l.u.D(this,1)};d.xf=function(a){l.u.J(this,1,a)};d.ft=function(a){l.u.J(this,2,a)};d.uT=function(a){l.u.J(this,3,a)};d.sT=function(a){l.u.J(this,4,a)};d.ST=function(a){l.u.J(this,5,a)};\nd.cT=function(a){l.u.J(this,6,a)};d.az=function(){return l.u.sa(this,x.i.nb,7)};d.LR=function(a){l.u.Ca(this,7,a)};x.i.Le.K=function(a){return l.u.K(x.i.Le,a)};x.i.ae=function(a){l.u.initialize(this,a,0,-1,x.i.ae.na,null)};h.da(x.i.ae,l.u);x.i.ae.na=[1];l.u.ha&&(x.i.ae.prototype.C=function(a){return x.i.ae.C(a,this)},x.i.ae.C=function(a,b){var c={Ada:l.u.Ka(b.YA(),x.i.Le.C,a)};a&&(c.ja=b);return c});x.i.ae.ia=function(a){a=new l.ba(a);var b=new x.i.ae;return x.i.ae.F(b,a)};\nx.i.ae.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.Le;b.T(c,x.i.Le.F);a.DJ(c);break;default:b.ea()}}return a};x.i.ae.G=function(a,b){a=a.YA();0<a.length&&b.Oa(1,a,x.i.Le.G)};x.i.ae.prototype.YA=function(){return l.u.Ma(this,x.i.Le,1)};x.i.ae.prototype.DJ=function(a,b){return l.u.La(this,1,a,x.i.Le,b)};x.i.ae.K=function(a){return l.u.K(x.i.ae,a)};x.i.fc=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.fc,l.u);\nl.u.ha&&(x.i.fc.prototype.C=function(a){return x.i.fc.C(a,this)},x.i.fc.C=function(a,b){var c={Xba:l.u.D(b,1),value:+l.u.D(b,2)};a&&(c.ja=b);return c});x.i.fc.ia=function(a){a=new l.ba(a);var b=new x.i.fc;return x.i.fc.F(b,a)};x.i.fc.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.we();a.YU(c);break;case 2:c=b.pa();a.setValue(c);break;default:b.ea()}}return a};x.i.fc.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.xe(1,c);c=l.u.D(a,2);null!=c&&b.ya(2,c)};\nx.i.fc.prototype.YU=function(a){l.u.J(this,1,a)};x.i.fc.prototype.getValue=function(){return+l.u.D(this,2)};x.i.fc.prototype.setValue=function(a){l.u.J(this,2,a)};x.i.fc.K=function(a){return l.u.K(x.i.fc,a)};x.i.fc.b_={gY:0,p_:1,r_:2,s_:3,t_:4,q_:5,u_:6,w_:7};x.i.ze=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.ze,l.u);\nl.u.ha&&(x.i.ze.prototype.C=function(a){return x.i.ze.C(a,this)},x.i.ze.C=function(a,b){var c,e={V$:(c=b.Xz())&&x.i.nb.C(a,c),Y$:(c=b.Zz())&&x.i.nb.C(a,c),T$:(c=b.Vz())&&x.i.nb.C(a,c),X$:(c=b.Yz())&&x.i.nb.C(a,c),aaa:(c=b.$z())&&x.i.nb.C(a,c),a7:l.u.va(b,6,0)};a&&(e.ja=b);return e});x.i.ze.ia=function(a){a=new l.ba(a);var b=new x.i.ze;return x.i.ze.F(b,a)};\nx.i.ze.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.nb;b.T(c,x.i.nb.F);a.cU(c);break;case 2:c=new x.i.nb;b.T(c,x.i.nb.F);a.fU(c);break;case 3:c=new x.i.nb;b.T(c,x.i.nb.F);a.aU(c);break;case 4:c=new x.i.nb;b.T(c,x.i.nb.F);a.eU(c);break;case 5:c=new x.i.nb;b.T(c,x.i.nb.F);a.hU(c);break;case 6:c=b.we();a.MR(c);break;default:b.ea()}}return a};\nx.i.ze.G=function(a,b){var c;c=a.Xz();null!=c&&b.oa(1,c,x.i.nb.G);c=a.Zz();null!=c&&b.oa(2,c,x.i.nb.G);c=a.Vz();null!=c&&b.oa(3,c,x.i.nb.G);c=a.Yz();null!=c&&b.oa(4,c,x.i.nb.G);c=a.$z();null!=c&&b.oa(5,c,x.i.nb.G);c=l.u.D(a,6);null!=c&&b.xe(6,c)};d=x.i.ze.prototype;d.Xz=function(){return l.u.sa(this,x.i.nb,1,1)};d.cU=function(a){l.u.Ca(this,1,a)};d.Zz=function(){return l.u.sa(this,x.i.nb,2,1)};d.fU=function(a){l.u.Ca(this,2,a)};d.Vz=function(){return l.u.sa(this,x.i.nb,3,1)};\nd.aU=function(a){l.u.Ca(this,3,a)};d.Yz=function(){return l.u.sa(this,x.i.nb,4)};d.eU=function(a){l.u.Ca(this,4,a)};d.$z=function(){return l.u.sa(this,x.i.nb,5)};d.hU=function(a){l.u.Ca(this,5,a)};d.MR=function(a){l.u.J(this,6,a)};x.i.ze.K=function(a){return l.u.K(x.i.ze,a)};x.i.ze.eY={$X:0,ZX:1};x.i.Cf=function(a){l.u.initialize(this,a,0,-1,x.i.Cf.na,null)};h.da(x.i.Cf,l.u);x.i.Cf.na=[1,2,3,4,5,6,7,8,9,10,11,12];\nl.u.ha&&(x.i.Cf.prototype.C=function(a){return x.i.Cf.C(a,this)},x.i.Cf.C=function(a,b){var c={v2:l.u.gb(b,1),t2:l.u.gb(b,2),u2:l.u.gb(b,3),q4:l.u.gb(b,4),l4:l.u.gb(b,5),a8:l.u.gb(b,6),q8:l.u.gb(b,7),p8:l.u.gb(b,8),Q5:l.u.gb(b,9),gda:l.u.gb(b,10),Q$:l.u.gb(b,11),E$:l.u.gb(b,12),Mca:+l.u.D(b,13),Ica:+l.u.D(b,14),Hca:+l.u.D(b,16),wl:+l.u.D(b,18),Nca:l.u.Na(b,15),Jca:l.u.Na(b,17),Ow:l.u.Na(b,19)};a&&(c.ja=b);return c});x.i.Cf.ia=function(a){a=new l.ba(a);var b=new x.i.Cf;return x.i.Cf.F(b,a)};\nx.i.Cf.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.pa();a.zH(c);break;case 2:c=b.pa();a.xH(c);break;case 3:c=b.pa();a.yH(c);break;case 4:c=b.pa();a.NH(c);break;case 5:c=b.pa();a.MH(c);break;case 6:c=b.pa();a.vI(c);break;case 7:c=b.pa();a.yI(c);break;case 8:c=b.pa();a.xI(c);break;case 9:c=b.pa();a.kI(c);break;case 10:c=b.pa();a.AJ(c);break;case 11:c=b.pa();a.XI(c);break;case 12:c=b.pa();a.UI(c);break;case 13:c=b.pa();a.nV(c);break;case 14:c=b.pa();a.jV(c);break;case 16:c=\nb.pa();a.iV(c);break;case 18:c=b.pa();a.Kg(c);break;case 15:c=b.pa();a.oV(c);break;case 17:c=b.pa();a.kV(c);break;case 19:c=b.pa();a.um(c);break;default:b.ea()}}return a};\nx.i.Cf.G=function(a,b){var c;c=a.jL();0<c.length&&b.bd(1,c);c=a.hL();0<c.length&&b.bd(2,c);c=a.iL();0<c.length&&b.bd(3,c);c=a.qL();0<c.length&&b.bd(4,c);c=a.pL();0<c.length&&b.bd(5,c);c=a.PL();0<c.length&&b.bd(6,c);c=a.RL();0<c.length&&b.bd(7,c);c=a.QL();0<c.length&&b.bd(8,c);c=a.FL();0<c.length&&b.bd(9,c);c=a.GM();0<c.length&&b.bd(10,c);c=a.iM();0<c.length&&b.bd(11,c);c=a.fM();0<c.length&&b.bd(12,c);c=l.u.D(a,13);null!=c&&b.ya(13,c);c=l.u.D(a,14);null!=c&&b.ya(14,c);c=l.u.D(a,16);null!=c&&b.ya(16,\nc);c=l.u.D(a,18);null!=c&&b.ya(18,c);c=l.u.D(a,15);null!=c&&b.ya(15,c);c=l.u.D(a,17);null!=c&&b.ya(17,c);c=l.u.D(a,19);null!=c&&b.ya(19,c)};d=x.i.Cf.prototype;d.jL=function(){return l.u.gb(this,1)};d.zH=function(a,b){l.u.ib(this,1,a,b)};d.hL=function(){return l.u.gb(this,2)};d.xH=function(a,b){l.u.ib(this,2,a,b)};d.iL=function(){return l.u.gb(this,3)};d.yH=function(a,b){l.u.ib(this,3,a,b)};d.qL=function(){return l.u.gb(this,4)};d.NH=function(a,b){l.u.ib(this,4,a,b)};\nd.pL=function(){return l.u.gb(this,5)};d.MH=function(a,b){l.u.ib(this,5,a,b)};d.PL=function(){return l.u.gb(this,6)};d.vI=function(a,b){l.u.ib(this,6,a,b)};d.RL=function(){return l.u.gb(this,7)};d.yI=function(a,b){l.u.ib(this,7,a,b)};d.QL=function(){return l.u.gb(this,8)};d.xI=function(a,b){l.u.ib(this,8,a,b)};d.FL=function(){return l.u.gb(this,9)};d.kI=function(a,b){l.u.ib(this,9,a,b)};d.GM=function(){return l.u.gb(this,10)};d.AJ=function(a,b){l.u.ib(this,10,a,b)};\nd.iM=function(){return l.u.gb(this,11)};d.XI=function(a,b){l.u.ib(this,11,a,b)};d.fM=function(){return l.u.gb(this,12)};d.UI=function(a,b){l.u.ib(this,12,a,b)};d.nV=function(a){l.u.J(this,13,a)};d.jV=function(a){l.u.J(this,14,a)};d.iV=function(a){l.u.J(this,16,a)};d.Gg=function(){return+l.u.D(this,18)};d.Kg=function(a){l.u.J(this,18,a)};d.oV=function(a){l.u.J(this,15,a)};d.kV=function(a){l.u.J(this,17,a)};d.so=function(){return l.u.Na(this,19)};d.um=function(a){l.u.J(this,19,a)};\nx.i.Cf.K=function(a){return l.u.K(x.i.Cf,a)};x.i.xc=function(a){l.u.initialize(this,a,0,-1,x.i.xc.na,null)};h.da(x.i.xc,l.u);x.i.xc.na=[1,2,3];l.u.ha&&(x.i.xc.prototype.C=function(a){return x.i.xc.C(a,this)},x.i.xc.C=function(a,b){var c,e={Yba:l.u.Ka(b.AA(),x.i.fc.C,a),O$:l.u.Ka(b.Sz(),x.i.fc.C,a),A9:l.u.Ka(b.Fz(),x.i.fc.C,a),U$:(c=b.Wz())&&x.i.nb.C(a,c),a3:(c=b.gy())&&x.i.ze.C(a,c),S9:l.u.va(b,6,0),Z$:b.kM()};a&&(e.ja=b);return e});\nx.i.xc.ia=function(a){a=new l.ba(a);var b=new x.i.xc;return x.i.xc.F(b,a)};x.i.xc.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.fc;b.T(c,x.i.fc.F);a.kJ(c);break;case 2:c=new x.i.fc;b.T(c,x.i.fc.F);a.VI(c);break;case 3:c=new x.i.fc;b.T(c,x.i.fc.F);a.JI(c);break;case 4:c=new x.i.nb;b.T(c,x.i.nb.F);a.bU(c);break;case 5:c=new x.i.ze;b.T(c,x.i.ze.F);a.AQ(c);break;case 6:c=b.Ya();a.vT(c);break;case 7:c=b.qm();a.gU(c);break;default:b.ea()}}return a};\nx.i.xc.G=function(a,b){var c;c=a.AA();0<c.length&&b.Oa(1,c,x.i.fc.G);c=a.Sz();0<c.length&&b.Oa(2,c,x.i.fc.G);c=a.Fz();0<c.length&&b.Oa(3,c,x.i.fc.G);c=a.Wz();null!=c&&b.oa(4,c,x.i.nb.G);c=a.gy();null!=c&&b.oa(5,c,x.i.ze.G);c=l.u.D(a,6);null!=c&&b.$a(6,c);c=l.u.D(a,7);null!=c&&b.fp(7,c)};d=x.i.xc.prototype;d.AA=function(){return l.u.Ma(this,x.i.fc,1)};d.kJ=function(a,b){return l.u.La(this,1,a,x.i.fc,b)};d.Sz=function(){return l.u.Ma(this,x.i.fc,2)};\nd.VI=function(a,b){return l.u.La(this,2,a,x.i.fc,b)};d.Fz=function(){return l.u.Ma(this,x.i.fc,3)};d.JI=function(a,b){return l.u.La(this,3,a,x.i.fc,b)};d.Wz=function(){return l.u.sa(this,x.i.nb,4)};d.bU=function(a){l.u.Ca(this,4,a)};d.gy=function(){return l.u.sa(this,x.i.ze,5)};d.AQ=function(a){l.u.Ca(this,5,a)};d.vT=function(a){l.u.J(this,6,a)};d.jM=function(){return l.u.D(this,7)};d.kM=function(){return l.u.ao(this.jM())};d.gU=function(a){l.u.J(this,7,a)};\nx.i.xc.K=function(a){return l.u.K(x.i.xc,a)};x.i.xc.KX={MY:0,iZ:1,SY:2};x.i.Md=function(a){l.u.initialize(this,a,0,-1,x.i.Md.na,null)};h.da(x.i.Md,l.u);x.i.Md.na=[22];\nl.u.ha&&(x.i.Md.prototype.C=function(a){return x.i.Md.C(a,this)},x.i.Md.C=function(a,b){var c={aj:l.u.D(b,1),dba:+l.u.va(b,2,0),Q9:l.u.va(b,3,0),cba:+l.u.va(b,4,0),vda:l.u.D(b,5),HO:l.u.va(b,6,0),x8:+l.u.va(b,7,0),IO:l.u.va(b,8,0),C8:l.u.D(b,9),kca:l.u.Na(b,10),qca:l.u.Na(b,11),N9:l.u.Na(b,12),w3:l.u.D(b,13),L1:l.u.D(b,14),M1:l.u.D(b,15),N1:l.u.D(b,16),g7:+l.u.va(b,17,0),L$:l.u.Na(b,18),x9:l.u.Na(b,19),M$:l.u.Na(b,20),y9:l.u.Na(b,21),e3:l.u.gb(b,22)};a&&(c.ja=b);return c});\nx.i.Md.ia=function(a){a=new l.ba(a);var b=new x.i.Md;return x.i.Md.F(b,a)};\nx.i.Md.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.xf(c);break;case 2:c=b.pa();a.AU(c);break;case 3:c=b.ad();a.tT(c);break;case 4:c=b.pa();a.zU(c);break;case 5:c=b.Ya();a.JV(c);break;case 6:c=b.ad();a.et(c);break;case 7:c=b.ti();a.yS(c);break;case 8:c=b.ee();a.ft(c);break;case 9:c=b.Ya();a.DS(c);break;case 10:c=b.pa();a.bV(c);break;case 11:c=b.pa();a.cV(c);break;case 12:c=b.pa();a.qT(c);break;case 13:c=b.ee();a.GQ(c);break;case 14:c=b.ee();a.bQ(c);break;case 15:c=\nb.ee();a.cQ(c);break;case 16:c=b.ee();a.dQ(c);break;case 17:c=b.pa();a.RR(c);break;case 18:c=b.pa();a.XT(c);break;case 19:c=b.pa();a.hT(c);break;case 20:c=b.pa();a.YT(c);break;case 21:c=b.pa();a.iT(c);break;case 22:c=b.pa();a.FH(c);break;default:b.ea()}}return a};\nx.i.Md.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Ja(1,c);c=l.u.D(a,2);null!=c&&b.ya(2,c);c=l.u.D(a,3);null!=c&&b.td(3,c);c=l.u.D(a,4);null!=c&&b.ya(4,c);c=l.u.D(a,5);null!=c&&b.$a(5,c);c=l.u.D(a,6);null!=c&&b.td(6,c);c=l.u.D(a,7);null!=c&&b.vi(7,c);c=l.u.D(a,8);null!=c&&b.ye(8,c);c=l.u.D(a,9);null!=c&&b.$a(9,c);c=l.u.D(a,10);null!=c&&b.ya(10,c);c=l.u.D(a,11);null!=c&&b.ya(11,c);c=l.u.D(a,12);null!=c&&b.ya(12,c);c=l.u.D(a,13);null!=c&&b.ye(13,c);c=l.u.D(a,14);null!=c&&b.ye(14,c);c=l.u.D(a,15);\nnull!=c&&b.ye(15,c);c=l.u.D(a,16);null!=c&&b.ye(16,c);c=l.u.D(a,17);null!=c&&b.ya(17,c);c=l.u.D(a,18);null!=c&&b.ya(18,c);c=l.u.D(a,19);null!=c&&b.ya(19,c);c=l.u.D(a,20);null!=c&&b.ya(20,c);c=l.u.D(a,21);null!=c&&b.ya(21,c);c=a.mL();0<c.length&&b.bd(22,c)};d=x.i.Md.prototype;d.Hg=function(){return l.u.D(this,1)};d.xf=function(a){l.u.J(this,1,a)};d.AU=function(a){l.u.J(this,2,a)};d.tT=function(a){l.u.J(this,3,a)};d.zU=function(a){l.u.J(this,4,a)};d.JV=function(a){l.u.J(this,5,a)};\nd.et=function(a){l.u.J(this,6,a)};d.yS=function(a){l.u.J(this,7,a)};d.ft=function(a){l.u.J(this,8,a)};d.DS=function(a){l.u.J(this,9,a)};d.bV=function(a){l.u.J(this,10,a)};d.cV=function(a){l.u.J(this,11,a)};d.qT=function(a){l.u.J(this,12,a)};d.GQ=function(a){l.u.J(this,13,a)};d.bQ=function(a){l.u.J(this,14,a)};d.cQ=function(a){l.u.J(this,15,a)};d.dQ=function(a){l.u.J(this,16,a)};d.RR=function(a){l.u.J(this,17,a)};d.XT=function(a){l.u.J(this,18,a)};d.hT=function(a){l.u.J(this,19,a)};\nd.YT=function(a){l.u.J(this,20,a)};d.iT=function(a){l.u.J(this,21,a)};d.mL=function(){return l.u.gb(this,22)};d.FH=function(a,b){l.u.ib(this,22,a,b)};x.i.Md.K=function(a){return l.u.K(x.i.Md,a)};x.i.$d=function(a){l.u.initialize(this,a,0,-1,x.i.$d.na,null)};h.da(x.i.$d,l.u);x.i.$d.na=[1,2,6];\nl.u.ha&&(x.i.$d.prototype.C=function(a){return x.i.$d.C(a,this)},x.i.$d.C=function(a,b){var c,e={Vca:l.u.Ka(b.OA(),x.i.xc.C,a),c7:l.u.Ka(b.bz(),x.i.xc.C,a),xda:l.u.Na(b,3),E3:l.u.Ka(b.my(),x.i.Md.C,a),Bj:l.u.D(b,4),zda:(c=b.XA())&&x.i.ae.C(a,c)};a&&(e.ja=b);return e});x.i.$d.ia=function(a){a=new l.ba(a);var b=new x.i.$d;return x.i.$d.F(b,a)};\nx.i.$d.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.xc;b.T(c,x.i.xc.F);a.zJ(c);break;case 2:c=new x.i.xc;b.T(c,x.i.xc.F);a.pI(c);break;case 3:c=b.pa();a.LV(c);break;case 6:c=new x.i.Md;b.T(c,x.i.Md.F);a.JH(c);break;case 4:c=b.Ya();a.zf(c);break;case 5:c=new x.i.ae;b.T(c,x.i.ae.F);a.MV(c);break;default:b.ea()}}return a};\nx.i.$d.G=function(a,b){var c;c=a.OA();0<c.length&&b.Oa(1,c,x.i.xc.G);c=a.bz();0<c.length&&b.Oa(2,c,x.i.xc.G);c=l.u.D(a,3);null!=c&&b.ya(3,c);c=a.my();0<c.length&&b.Oa(6,c,x.i.Md.G);c=l.u.D(a,4);null!=c&&b.$a(4,c);c=a.XA();null!=c&&b.oa(5,c,x.i.ae.G)};d=x.i.$d.prototype;d.OA=function(){return l.u.Ma(this,x.i.xc,1)};d.zJ=function(a,b){return l.u.La(this,1,a,x.i.xc,b)};d.bz=function(){return l.u.Ma(this,x.i.xc,2)};d.pI=function(a,b){return l.u.La(this,2,a,x.i.xc,b)};d.LV=function(a){l.u.J(this,3,a)};\nd.my=function(){return l.u.Ma(this,x.i.Md,6)};d.JH=function(a,b){return l.u.La(this,6,a,x.i.Md,b)};d.zf=function(a){l.u.J(this,4,a)};d.XA=function(){return l.u.sa(this,x.i.ae,5)};d.MV=function(a){l.u.Ca(this,5,a)};x.i.$d.K=function(a){return l.u.K(x.i.$d,a)};x.i.$d.lD={g_:0,bY:1,WY:2};x.i.Ef=function(a){l.u.initialize(this,a,0,-1,x.i.Ef.na,null)};h.da(x.i.Ef,l.u);x.i.Ef.na=[3];\nl.u.ha&&(x.i.Ef.prototype.C=function(a){return x.i.Ef.C(a,this)},x.i.Ef.C=function(a,b){var c,e={tW:(c=b.dm())&&x.i.$d.C(a,c),e9:l.u.D(b,2),L4:l.u.D(b,3)};a&&(e.ja=b);return e});x.i.Ef.ia=function(a){a=new l.ba(a);var b=new x.i.Ef;return x.i.Ef.F(b,a)};x.i.Ef.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.$d;b.T(c,x.i.$d.F);a.ot(c);break;case 2:c=b.Aa();a.US(c);break;case 3:c=b.Aa();a.SH(c);break;default:b.ea()}}return a};\nx.i.Ef.G=function(a,b){var c;c=a.dm();null!=c&&b.oa(1,c,x.i.$d.G);c=l.u.D(a,2);null!=c&&b.Ja(2,c);c=a.sL();0<c.length&&b.oc(3,c)};d=x.i.Ef.prototype;d.dm=function(){return l.u.sa(this,x.i.$d,1,1)};d.ot=function(a){l.u.Ca(this,1,a)};d.US=function(a){l.u.J(this,2,a)};d.sL=function(){return l.u.D(this,3)};d.SH=function(a,b){l.u.ib(this,3,a,b)};x.i.Ef.K=function(a){return l.u.K(x.i.Ef,a)};x.i.Bf=function(a){l.u.initialize(this,a,0,-1,x.i.Bf.na,null)};h.da(x.i.Bf,l.u);x.i.Bf.na=[1,2,3,4];\nl.u.ha&&(x.i.Bf.prototype.C=function(a){return x.i.Bf.C(a,this)},x.i.Bf.C=function(a,b){var c={b$:l.u.Ka(b.Jz(),x.i.Ie.C,a),g$:l.u.Ka(b.Kz(),x.i.Ub.C,a),A5:l.u.Ka(b.Ny(),x.i.Ub.C,a),iW:l.u.Ka(b.cm(),x.i.rd.C,a)};a&&(c.ja=b);return c});x.i.Bf.ia=function(a){a=new l.ba(a);var b=new x.i.Bf;return x.i.Bf.F(b,a)};\nx.i.Bf.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.Ie;b.T(c,x.i.Ie.F);a.NI(c);break;case 2:c=new x.i.Ub;b.T(c,x.i.Ub.F);a.OI(c);break;case 3:c=new x.i.Ub;b.T(c,x.i.Ub.F);a.aI(c);break;case 4:c=new x.i.rd;b.T(c,x.i.rd.F);a.Tq(c);break;default:b.ea()}}return a};x.i.Bf.G=function(a,b){var c;c=a.Jz();0<c.length&&b.Oa(1,c,x.i.Ie.G);c=a.Kz();0<c.length&&b.Oa(2,c,x.i.Ub.G);c=a.Ny();0<c.length&&b.Oa(3,c,x.i.Ub.G);c=a.cm();0<c.length&&b.Oa(4,c,x.i.rd.G)};d=x.i.Bf.prototype;\nd.Jz=function(){return l.u.Ma(this,x.i.Ie,1)};d.NI=function(a,b){return l.u.La(this,1,a,x.i.Ie,b)};d.Kz=function(){return l.u.Ma(this,x.i.Ub,2)};d.OI=function(a,b){return l.u.La(this,2,a,x.i.Ub,b)};d.Ny=function(){return l.u.Ma(this,x.i.Ub,3)};d.aI=function(a,b){return l.u.La(this,3,a,x.i.Ub,b)};d.cm=function(){return l.u.Ma(this,x.i.rd,4)};d.Tq=function(a,b){return l.u.La(this,4,a,x.i.rd,b)};x.i.Bf.K=function(a){return l.u.K(x.i.Bf,a)};x.i.Ie=function(a){l.u.initialize(this,a,0,-1,null,null)};\nh.da(x.i.Ie,l.u);l.u.ha&&(x.i.Ie.prototype.C=function(a){return x.i.Ie.C(a,this)},x.i.Ie.C=function(a,b){var c={Bj:l.u.D(b,1),date:l.u.D(b,2),value:l.u.Na(b,3)};a&&(c.ja=b);return c});x.i.Ie.ia=function(a){a=new l.ba(a);var b=new x.i.Ie;return x.i.Ie.F(b,a)};x.i.Ie.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Ya();a.zf(c);break;case 2:c=b.Ya();a.setDate(c);break;case 3:c=b.pa();a.setValue(c);break;default:b.ea()}}return a};\nx.i.Ie.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.$a(1,c);c=l.u.D(a,2);null!=c&&b.$a(2,c);c=l.u.D(a,3);null!=c&&b.ya(3,c)};d=x.i.Ie.prototype;d.zf=function(a){l.u.J(this,1,a)};d.getDate=function(){return l.u.D(this,2)};d.setDate=function(a){l.u.J(this,2,a)};d.getValue=function(){return l.u.Na(this,3)};d.setValue=function(a){l.u.J(this,3,a)};x.i.Ie.K=function(a){return l.u.K(x.i.Ie,a)};x.i.rd=function(a){l.u.initialize(this,a,0,-1,x.i.rd.na,null)};h.da(x.i.rd,l.u);x.i.rd.na=[2];\nl.u.ha&&(x.i.rd.prototype.C=function(a){return x.i.rd.C(a,this)},x.i.rd.C=function(a,b){var c={gW:l.u.D(b,1),Jm:l.u.Ka(b.bf(),x.i.Ub.C,a)};a&&(c.ja=b);return c});x.i.rd.ia=function(a){a=new l.ba(a);var b=new x.i.rd;return x.i.rd.F(b,a)};x.i.rd.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.we();a.nt(c);break;case 2:c=new x.i.Ub;b.T(c,x.i.Ub.F);a.Eg(c);break;default:b.ea()}}return a};\nx.i.rd.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.xe(1,c);c=a.bf();0<c.length&&b.Oa(2,c,x.i.Ub.G)};x.i.rd.prototype.nt=function(a){l.u.J(this,1,a)};x.i.rd.prototype.bf=function(){return l.u.Ma(this,x.i.Ub,2)};x.i.rd.prototype.Eg=function(a,b){return l.u.La(this,2,a,x.i.Ub,b)};x.i.rd.K=function(a){return l.u.K(x.i.rd,a)};x.i.Ub=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.Ub,l.u);\nl.u.ha&&(x.i.Ub.prototype.C=function(a){return x.i.Ub.C(a,this)},x.i.Ub.C=function(a,b){var c,e={Bj:l.u.D(b,1),time:l.u.Na(b,5),tW:(c=b.dm())&&x.i.od.C(a,c),i7:(c=b.ez())&&x.i.od.C(a,c),H4:l.u.D(b,6)};a&&(e.ja=b);return e});x.i.Ub.ia=function(a){a=new l.ba(a);var b=new x.i.Ub;return x.i.Ub.F(b,a)};\nx.i.Ub.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Ya();a.zf(c);break;case 5:c=b.pa();a.setTime(c);break;case 3:c=new x.i.od;b.T(c,x.i.od.F);a.ot(c);break;case 4:c=new x.i.od;b.T(c,x.i.od.F);a.TR(c);break;case 6:c=b.Ya();a.$Q(c);break;default:b.ea()}}return a};x.i.Ub.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.$a(1,c);c=l.u.D(a,5);null!=c&&b.ya(5,c);c=a.dm();null!=c&&b.oa(3,c,x.i.od.G);c=a.ez();null!=c&&b.oa(4,c,x.i.od.G);c=l.u.D(a,6);null!=c&&b.$a(6,c)};d=x.i.Ub.prototype;\nd.zf=function(a){l.u.J(this,1,a)};d.getTime=function(){return l.u.Na(this,5)};d.setTime=function(a){l.u.J(this,5,a)};d.dm=function(){return l.u.sa(this,x.i.od,3)};d.ot=function(a){l.u.Ca(this,3,a)};d.ez=function(){return l.u.sa(this,x.i.od,4)};d.TR=function(a){l.u.Ca(this,4,a)};d.$Q=function(a){l.u.J(this,6,a)};x.i.Ub.K=function(a){return l.u.K(x.i.Ub,a)};x.i.od=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.od,l.u);\nl.u.ha&&(x.i.od.prototype.C=function(a){return x.i.od.C(a,this)},x.i.od.C=function(a,b){var c={wl:l.u.Na(b,2),i2:l.u.Na(b,8),Ow:l.u.Na(b,3),instanceCount:l.u.Na(b,5),lm:l.u.Na(b,1),r9:l.u.Na(b,6),F$:l.u.Na(b,7),eP:l.u.Na(b,4)};a&&(c.ja=b);return c});x.i.od.ia=function(a){a=new l.ba(a);var b=new x.i.od;return x.i.od.F(b,a)};\nx.i.od.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 2:c=b.pa();a.Kg(c);break;case 8:c=b.pa();a.gQ(c);break;case 3:c=b.pa();a.um(c);break;case 5:c=b.pa();a.cS(c);break;case 1:c=b.pa();a.Ng(c);break;case 6:c=b.pa();a.bT(c);break;case 7:c=b.pa();a.RT(c);break;case 4:c=b.pa();a.ht(c);break;default:b.ea()}}return a};\nx.i.od.G=function(a,b){var c;c=l.u.D(a,2);null!=c&&b.ya(2,c);c=l.u.D(a,8);null!=c&&b.ya(8,c);c=l.u.D(a,3);null!=c&&b.ya(3,c);c=l.u.D(a,5);null!=c&&b.ya(5,c);c=l.u.D(a,1);null!=c&&b.ya(1,c);c=l.u.D(a,6);null!=c&&b.ya(6,c);c=l.u.D(a,7);null!=c&&b.ya(7,c);c=l.u.D(a,4);null!=c&&b.ya(4,c)};d=x.i.od.prototype;d.Gg=function(){return l.u.Na(this,2)};d.Kg=function(a){l.u.J(this,2,a)};d.gQ=function(a){l.u.J(this,8,a)};d.so=function(){return l.u.Na(this,3)};d.um=function(a){l.u.J(this,3,a)};\nd.cS=function(a){l.u.J(this,5,a)};d.eg=function(){return l.u.Na(this,1)};d.Ng=function(a){l.u.J(this,1,a)};d.bT=function(a){l.u.J(this,6,a)};d.RT=function(a){l.u.J(this,7,a)};d.Nr=function(){return l.u.Na(this,4)};d.ht=function(a){l.u.J(this,4,a)};x.i.od.K=function(a){return l.u.K(x.i.od,a)};x.i.ZZ={ZY:1,BX:2};x.P={};x.P.Rd=function(a){l.u.initialize(this,a,0,-1,x.P.Rd.na,null)};h.da(x.P.Rd,l.u);x.P.Rd.na=[3,4,5];\nl.u.ha&&(x.P.Rd.prototype.C=function(a){return x.P.Rd.C(a,this)},x.P.Rd.C=function(a,b){var c,e={name:l.u.D(b,1),a4:l.u.D(b,2),Eaa:l.u.D(b,3),E5:l.u.D(b,4),J5:l.u.Ka(b.Ry(),x.P.Ge.C,a),y8:l.u.D(b,6),A8:l.u.D(b,7),z8:l.u.D(b,8),B8:l.u.D(b,9),m6:(c=b.Zy())&&x.P.he.C(a,c),N6:l.u.D(b,11),x5:l.u.D(b,12),T9:l.u.D(b,13),z5:l.u.D(b,14),Q8:l.u.D(b,15)};a&&(e.ja=b);return e});x.P.Rd.ia=function(a){a=new l.ba(a);var b=new x.P.Rd;return x.P.Rd.F(b,a)};\nx.P.Rd.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.fe(c);break;case 2:c=b.Aa();a.NQ(c);break;case 3:c=b.Aa();a.aJ(c);break;case 4:c=b.Aa();a.dI(c);break;case 5:c=new x.P.Ge;b.T(c,x.P.Ge.F);a.gI(c);break;case 6:c=b.Ya();a.zS(c);break;case 7:c=b.Ya();a.BS(c);break;case 8:c=b.Ya();a.AS(c);break;case 9:c=b.Ya();a.CS(c);break;case 10:c=new x.P.he;b.T(c,x.P.he.F);a.IR(c);break;case 11:c=b.Aa();a.JR(c);break;case 12:c=b.Aa();a.sR(c);break;case 13:c=b.Ya();a.wT(c);break;\ncase 14:c=b.we();a.uR(c);break;case 15:c=b.Ya();a.LS(c);break;default:b.ea()}}return a};\nx.P.Rd.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Ja(1,c);c=l.u.D(a,2);null!=c&&b.Ja(2,c);c=a.oM();0<c.length&&b.oc(3,c);c=a.AL();0<c.length&&b.oc(4,c);c=a.Ry();0<c.length&&b.Oa(5,c,x.P.Ge.G);c=l.u.D(a,6);null!=c&&b.$a(6,c);c=l.u.D(a,7);null!=c&&b.$a(7,c);c=l.u.D(a,8);null!=c&&b.$a(8,c);c=l.u.D(a,9);null!=c&&b.$a(9,c);c=a.Zy();null!=c&&b.oa(10,c,x.P.he.G);c=l.u.D(a,11);null!=c&&b.Ja(11,c);c=l.u.D(a,12);null!=c&&b.Ja(12,c);c=l.u.D(a,13);null!=c&&b.$a(13,c);c=l.u.D(a,14);null!=c&&b.xe(14,c);c=l.u.D(a,\n15);null!=c&&b.$a(15,c)};d=x.P.Rd.prototype;d.getName=function(){return l.u.D(this,1)};d.fe=function(a){l.u.J(this,1,a)};d.NQ=function(a){l.u.J(this,2,a)};d.oM=function(){return l.u.D(this,3)};d.aJ=function(a,b){l.u.ib(this,3,a,b)};d.AL=function(){return l.u.D(this,4)};d.dI=function(a,b){l.u.ib(this,4,a,b)};d.Ry=function(){return l.u.Ma(this,x.P.Ge,5)};d.gI=function(a,b){return l.u.La(this,5,a,x.P.Ge,b)};d.zS=function(a){l.u.J(this,6,a)};d.BS=function(a){l.u.J(this,7,a)};\nd.AS=function(a){l.u.J(this,8,a)};d.CS=function(a){l.u.J(this,9,a)};d.Zy=function(){return l.u.sa(this,x.P.he,10)};d.IR=function(a){l.u.Ca(this,10,a)};d.JR=function(a){l.u.J(this,11,a)};d.sR=function(a){l.u.J(this,12,a)};d.wT=function(a){l.u.J(this,13,a)};d.uR=function(a){l.u.J(this,14,a)};d.LS=function(a){l.u.J(this,15,a)};x.P.Rd.K=function(a){return l.u.K(x.P.Rd,a)};x.P.he=function(a){l.u.initialize(this,a,0,-1,x.P.he.na,null)};h.da(x.P.he,l.u);x.P.he.na=[1,2,3,4,5,6];\nl.u.ha&&(x.P.he.prototype.C=function(a){return x.P.he.C(a,this)},x.P.he.C=function(a,b){var c={K5:l.u.Ka(b.Sy(),x.P.Ac.C,a),eba:l.u.Ka(b.kA(),x.P.Ac.C,a),g8:l.u.Ka(b.oz(),x.P.Fb.C,a),Z8:l.u.Ka(b.wz(),x.P.Td.C,a),h$:l.u.Ka(b.Lz(),x.P.Bc.C,a),Wba:l.u.Ka(b.zA(),x.P.pd.C,a)};a&&(c.ja=b);return c});x.P.he.ia=function(a){a=new l.ba(a);var b=new x.P.he;return x.P.he.F(b,a)};\nx.P.he.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.P.Ac;b.T(c,x.P.Ac.F);a.hI(c);break;case 2:c=new x.P.Ac;b.T(c,x.P.Ac.F);a.dJ(c);break;case 3:c=new x.P.Fb;b.T(c,x.P.Fb.F);a.wI(c);break;case 4:c=new x.P.Td;b.T(c,x.P.Td.F);a.EI(c);break;case 5:c=new x.P.Bc;b.T(c,x.P.Bc.F);a.QI(c);break;case 6:c=new x.P.pd;b.T(c,x.P.pd.F);a.jJ(c);break;default:b.ea()}}return a};\nx.P.he.G=function(a,b){var c;c=a.Sy();0<c.length&&b.Oa(1,c,x.P.Ac.G);c=a.kA();0<c.length&&b.Oa(2,c,x.P.Ac.G);c=a.oz();0<c.length&&b.Oa(3,c,x.P.Fb.G);c=a.wz();0<c.length&&b.Oa(4,c,x.P.Td.G);c=a.Lz();0<c.length&&b.Oa(5,c,x.P.Bc.G);c=a.zA();0<c.length&&b.Oa(6,c,x.P.pd.G)};d=x.P.he.prototype;d.Sy=function(){return l.u.Ma(this,x.P.Ac,1)};d.hI=function(a,b){return l.u.La(this,1,a,x.P.Ac,b)};d.kA=function(){return l.u.Ma(this,x.P.Ac,2)};d.dJ=function(a,b){return l.u.La(this,2,a,x.P.Ac,b)};\nd.oz=function(){return l.u.Ma(this,x.P.Fb,3)};d.wI=function(a,b){return l.u.La(this,3,a,x.P.Fb,b)};d.wz=function(){return l.u.Ma(this,x.P.Td,4)};d.EI=function(a,b){return l.u.La(this,4,a,x.P.Td,b)};d.Lz=function(){return l.u.Ma(this,x.P.Bc,5)};d.QI=function(a,b){return l.u.La(this,5,a,x.P.Bc,b)};d.zA=function(){return l.u.Ma(this,x.P.pd,6)};d.jJ=function(a,b){return l.u.La(this,6,a,x.P.pd,b)};x.P.he.K=function(a){return l.u.K(x.P.he,a)};x.P.Ac=function(a){l.u.initialize(this,a,0,-1,x.P.Ac.na,null)};\nh.da(x.P.Ac,l.u);x.P.Ac.na=[5];l.u.ha&&(x.P.Ac.prototype.C=function(a){return x.P.Ac.C(a,this)},x.P.Ac.C=function(a,b){var c,e={mK:(c=b.Ml())&&x.P.Sc.C(a,c),Zca:l.u.D(b,2),Yca:l.u.D(b,3),R8:l.u.D(b,4),bba:l.u.D(b,5)};a&&(e.ja=b);return e});x.P.Ac.ia=function(a){a=new l.ba(a);var b=new x.P.Ac;return x.P.Ac.F(b,a)};\nx.P.Ac.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.P.Sc;b.T(c,x.P.Sc.F);a.Ns(c);break;case 2:c=b.Ya();a.yV(c);break;case 3:c=b.Ya();a.xV(c);break;case 4:c=b.Ya();a.MS(c);break;case 5:c=b.Aa();a.cJ(c);break;default:b.ea()}}return a};x.P.Ac.G=function(a,b){var c;c=a.Ml();null!=c&&b.oa(1,c,x.P.Sc.G);c=l.u.D(a,2);null!=c&&b.$a(2,c);c=l.u.D(a,3);null!=c&&b.$a(3,c);c=l.u.D(a,4);null!=c&&b.$a(4,c);c=a.pM();0<c.length&&b.oc(5,c)};d=x.P.Ac.prototype;\nd.Ml=function(){return l.u.sa(this,x.P.Sc,1)};d.Ns=function(a){l.u.Ca(this,1,a)};d.yV=function(a){l.u.J(this,2,a)};d.xV=function(a){l.u.J(this,3,a)};d.MS=function(a){l.u.J(this,4,a)};d.pM=function(){return l.u.D(this,5)};d.cJ=function(a,b){l.u.ib(this,5,a,b)};x.P.Ac.K=function(a){return l.u.K(x.P.Ac,a)};x.P.Fb=function(a){l.u.initialize(this,a,0,-1,x.P.Fb.na,null)};h.da(x.P.Fb,l.u);x.P.Fb.na=[3];\nl.u.ha&&(x.P.Fb.prototype.C=function(a){return x.P.Fb.C(a,this)},x.P.Fb.C=function(a,b){var c,e={mK:(c=b.Ml())&&x.P.Sc.C(a,c),f4:l.u.D(b,2),G5:l.u.D(b,3),Uba:(c=b.getStats())&&x.P.Ud.C(a,c),d6:l.u.D(b,5),N4:l.u.D(b,6),x$:l.u.Na(b,7),f9:l.u.Na(b,8),Jaa:(c=b.iA())&&x.P.Fb.re.C(a,c)};a&&(e.ja=b);return e});x.P.Fb.ia=function(a){a=new l.ba(a);var b=new x.P.Fb;return x.P.Fb.F(b,a)};\nx.P.Fb.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.P.Sc;b.T(c,x.P.Sc.F);a.Ns(c);break;case 2:c=b.Aa();a.PQ(c);break;case 3:c=b.Aa();a.eI(c);break;case 4:c=new x.P.Ud;b.T(c,x.P.Ud.F);a.WU(c);break;case 5:c=b.Ya();a.ER(c);break;case 6:c=b.Aa();a.bR(c);break;case 7:c=b.pa();a.MT(c);break;case 8:c=b.pa();a.VS(c);break;case 9:c=new x.P.Fb.re;b.T(c,x.P.Fb.re.F);a.wU(c);break;default:b.ea()}}return a};\nx.P.Fb.G=function(a,b){var c;c=a.Ml();null!=c&&b.oa(1,c,x.P.Sc.G);c=l.u.D(a,2);null!=c&&b.Ja(2,c);c=a.BL();0<c.length&&b.oc(3,c);c=a.getStats();null!=c&&b.oa(4,c,x.P.Ud.G);c=l.u.D(a,5);null!=c&&b.$a(5,c);c=l.u.D(a,6);null!=c&&b.Ja(6,c);c=l.u.D(a,7);null!=c&&b.ya(7,c);c=l.u.D(a,8);null!=c&&b.ya(8,c);c=a.iA();null!=c&&b.oa(9,c,x.P.Fb.re.G)};d=x.P.Fb.prototype;d.Ml=function(){return l.u.sa(this,x.P.Sc,1)};d.Ns=function(a){l.u.Ca(this,1,a)};d.PQ=function(a){l.u.J(this,2,a)};\nd.BL=function(){return l.u.D(this,3)};d.eI=function(a,b){l.u.ib(this,3,a,b)};d.getStats=function(){return l.u.sa(this,x.P.Ud,4)};d.WU=function(a){l.u.Ca(this,4,a)};d.ER=function(a){l.u.J(this,5,a)};d.bR=function(a){l.u.J(this,6,a)};d.MT=function(a){l.u.J(this,7,a)};d.VS=function(a){l.u.J(this,8,a)};d.iA=function(){return l.u.sa(this,x.P.Fb.re,9)};d.wU=function(a){l.u.Ca(this,9,a)};x.P.Fb.K=function(a){return l.u.K(x.P.Fb,a)};x.P.Fb.re=function(a){l.u.initialize(this,a,0,-1,null,null)};\nh.da(x.P.Fb.re,l.u);l.u.ha&&(x.P.Fb.re.prototype.C=function(a){return x.P.Fb.re.C(a,this)},x.P.Fb.re.C=function(a,b){var c={V9:l.u.D(b,1),U9:l.u.D(b,2),faa:l.u.D(b,3)};a&&(c.ja=b);return c});x.P.Fb.re.ia=function(a){a=new l.ba(a);var b=new x.P.Fb.re;return x.P.Fb.re.F(b,a)};x.P.Fb.re.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Ya();a.yT(c);break;case 2:c=b.Ya();a.xT(c);break;case 3:c=b.Ya();a.mU(c);break;default:b.ea()}}return a};\nx.P.Fb.re.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.$a(1,c);c=l.u.D(a,2);null!=c&&b.$a(2,c);c=l.u.D(a,3);null!=c&&b.$a(3,c)};x.P.Fb.re.prototype.yT=function(a){l.u.J(this,1,a)};x.P.Fb.re.prototype.xT=function(a){l.u.J(this,2,a)};x.P.Fb.re.prototype.mU=function(a){l.u.J(this,3,a)};x.P.Fb.re.K=function(a){return l.u.K(x.P.Fb.re,a)};x.P.Sc=function(a){l.u.initialize(this,a,0,-1,x.P.Sc.na,null)};h.da(x.P.Sc,l.u);x.P.Sc.na=[7,8];\nl.u.ha&&(x.P.Sc.prototype.C=function(a){return x.P.Sc.C(a,this)},x.P.Sc.C=function(a,b){var c={name:l.u.D(b,1),Y8:l.u.D(b,2),id:l.u.D(b,3),status:l.u.D(b,4),r$:l.u.D(b,5),s$:l.u.D(b,6),r7:l.u.D(b,7),a9:l.u.Ka(b.xz(),x.P.Fe.C,a),h9:l.u.D(b,9),O4:l.u.D(b,10),P4:l.u.D(b,11)};a&&(c.ja=b);return c});x.P.Sc.ia=function(a){a=new l.ba(a);var b=new x.P.Sc;return x.P.Sc.F(b,a)};\nx.P.Sc.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.fe(c);break;case 2:c=b.Aa();a.RS(c);break;case 3:c=b.Ya();a.Vs(c);break;case 4:c=b.we();a.ZU(c);break;case 5:c=b.Aa();a.JT(c);break;case 6:c=b.we();a.KT(c);break;case 7:c=b.Aa();a.rI(c);break;case 8:c=new x.P.Fe;b.T(c,x.P.Fe.F);a.FI(c);break;case 9:c=b.Aa();a.WS(c);break;case 10:c=b.Aa();a.cR(c);break;case 11:c=b.Aa();a.dR(c);break;default:b.ea()}}return a};\nx.P.Sc.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Ja(1,c);c=l.u.D(a,2);null!=c&&b.Ja(2,c);c=l.u.D(a,3);null!=c&&b.$a(3,c);c=l.u.D(a,4);null!=c&&b.xe(4,c);c=l.u.D(a,5);null!=c&&b.Ja(5,c);c=l.u.D(a,6);null!=c&&b.xe(6,c);c=a.NL();0<c.length&&b.oc(7,c);c=a.xz();0<c.length&&b.Oa(8,c,x.P.Fe.G);c=l.u.D(a,9);null!=c&&b.Ja(9,c);c=l.u.D(a,10);null!=c&&b.Ja(10,c);c=l.u.D(a,11);null!=c&&b.Ja(11,c)};d=x.P.Sc.prototype;d.getName=function(){return l.u.D(this,1)};d.fe=function(a){l.u.J(this,1,a)};\nd.RS=function(a){l.u.J(this,2,a)};d.Vs=function(a){l.u.J(this,3,a)};d.ZU=function(a){l.u.J(this,4,a)};d.JT=function(a){l.u.J(this,5,a)};d.KT=function(a){l.u.J(this,6,a)};d.NL=function(){return l.u.D(this,7)};d.rI=function(a,b){l.u.ib(this,7,a,b)};d.xz=function(){return l.u.Ma(this,x.P.Fe,8)};d.FI=function(a,b){return l.u.La(this,8,a,x.P.Fe,b)};d.WS=function(a){l.u.J(this,9,a)};d.cR=function(a){l.u.J(this,10,a)};d.dR=function(a){l.u.J(this,11,a)};x.P.Sc.K=function(a){return l.u.K(x.P.Sc,a)};\nx.P.Ud=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.P.Ud,l.u);l.u.ha&&(x.P.Ud.prototype.C=function(a){return x.P.Ud.C(a,this)},x.P.Ud.C=function(a,b){var c={e$:l.u.Na(b,1),c$:l.u.Na(b,2),f$:l.u.Na(b,3),d$:l.u.Na(b,4)};a&&(c.ja=b);return c});x.P.Ud.ia=function(a){a=new l.ba(a);var b=new x.P.Ud;return x.P.Ud.F(b,a)};\nx.P.Ud.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.pa();a.CT(c);break;case 2:c=b.pa();a.AT(c);break;case 3:c=b.pa();a.DT(c);break;case 4:c=b.pa();a.BT(c);break;default:b.ea()}}return a};x.P.Ud.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.ya(1,c);c=l.u.D(a,2);null!=c&&b.ya(2,c);c=l.u.D(a,3);null!=c&&b.ya(3,c);c=l.u.D(a,4);null!=c&&b.ya(4,c)};x.P.Ud.prototype.CT=function(a){l.u.J(this,1,a)};x.P.Ud.prototype.AT=function(a){l.u.J(this,2,a)};\nx.P.Ud.prototype.DT=function(a){l.u.J(this,3,a)};x.P.Ud.prototype.BT=function(a){l.u.J(this,4,a)};x.P.Ud.K=function(a){return l.u.K(x.P.Ud,a)};x.P.Fe=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.P.Fe,l.u);l.u.ha&&(x.P.Fe.prototype.C=function(a){return x.P.Fe.C(a,this)},x.P.Fe.C=function(a,b){var c={b9:l.u.D(b,1),name:l.u.D(b,2),value:l.u.Na(b,3)};a&&(c.ja=b);return c});x.P.Fe.ia=function(a){a=new l.ba(a);var b=new x.P.Fe;return x.P.Fe.F(b,a)};\nx.P.Fe.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.we();a.SS(c);break;case 2:c=b.Aa();a.fe(c);break;case 3:c=b.pa();a.setValue(c);break;default:b.ea()}}return a};x.P.Fe.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.xe(1,c);c=l.u.D(a,2);null!=c&&b.Ja(2,c);c=l.u.D(a,3);null!=c&&b.ya(3,c)};d=x.P.Fe.prototype;d.SS=function(a){l.u.J(this,1,a)};d.getName=function(){return l.u.D(this,2)};d.fe=function(a){l.u.J(this,2,a)};d.getValue=function(){return l.u.Na(this,3)};\nd.setValue=function(a){l.u.J(this,3,a)};x.P.Fe.K=function(a){return l.u.K(x.P.Fe,a)};x.P.Ge=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.P.Ge,l.u);l.u.ha&&(x.P.Ge.prototype.C=function(a){return x.P.Ge.C(a,this)},x.P.Ge.C=function(a,b){var c={name:l.u.D(b,1),lowerBound:l.u.Na(b,2),upperBound:l.u.Na(b,3),c5:l.u.Na(b,4)};a&&(c.ja=b);return c});x.P.Ge.ia=function(a){a=new l.ba(a);var b=new x.P.Ge;return x.P.Ge.F(b,a)};\nx.P.Ge.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.fe(c);break;case 2:c=b.pa();a.tj(c);break;case 3:c=b.pa();a.xj(c);break;case 4:c=b.pa();a.jR(c);break;default:b.ea()}}return a};x.P.Ge.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Ja(1,c);c=l.u.D(a,2);null!=c&&b.ya(2,c);c=l.u.D(a,3);null!=c&&b.ya(3,c);c=l.u.D(a,4);null!=c&&b.ya(4,c)};d=x.P.Ge.prototype;d.getName=function(){return l.u.D(this,1)};d.fe=function(a){l.u.J(this,1,a)};\nd.Xl=function(){return l.u.Na(this,2)};d.tj=function(a){l.u.J(this,2,a)};d.em=function(){return l.u.Na(this,3)};d.xj=function(a){l.u.J(this,3,a)};d.jR=function(a){l.u.J(this,4,a)};x.P.Ge.K=function(a){return l.u.K(x.P.Ge,a)};x.P.Td=function(a){l.u.initialize(this,a,0,-1,x.P.Td.na,null)};h.da(x.P.Td,l.u);x.P.Td.na=[3];l.u.ha&&(x.P.Td.prototype.C=function(a){return x.P.Td.C(a,this)},x.P.Td.C=function(a,b){var c={name:l.u.D(b,1),value:l.u.Na(b,2),bca:l.u.D(b,3)};a&&(c.ja=b);return c});\nx.P.Td.ia=function(a){a=new l.ba(a);var b=new x.P.Td;return x.P.Td.F(b,a)};x.P.Td.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.fe(c);break;case 2:c=b.pa();a.setValue(c);break;case 3:c=b.Aa();a.mJ(c);break;default:b.ea()}}return a};x.P.Td.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Ja(1,c);c=l.u.D(a,2);null!=c&&b.ya(2,c);c=a.vM();0<c.length&&b.oc(3,c)};d=x.P.Td.prototype;d.getName=function(){return l.u.D(this,1)};d.fe=function(a){l.u.J(this,1,a)};\nd.getValue=function(){return l.u.Na(this,2)};d.setValue=function(a){l.u.J(this,2,a)};d.vM=function(){return l.u.D(this,3)};d.mJ=function(a,b){l.u.ib(this,3,a,b)};x.P.Td.K=function(a){return l.u.K(x.P.Td,a)};x.P.pd=function(a){l.u.initialize(this,a,0,-1,x.P.pd.na,null)};h.da(x.P.pd,l.u);x.P.pd.na=[2];l.u.ha&&(x.P.pd.prototype.C=function(a){return x.P.pd.C(a,this)},x.P.pd.C=function(a,b){var c={gW:l.u.D(b,1),Jm:l.u.Ka(b.bf(),x.P.Bc.C,a)};a&&(c.ja=b);return c});\nx.P.pd.ia=function(a){a=new l.ba(a);var b=new x.P.pd;return x.P.pd.F(b,a)};x.P.pd.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.we();a.nt(c);break;case 2:c=new x.P.Bc;b.T(c,x.P.Bc.F);a.Eg(c);break;default:b.ea()}}return a};x.P.pd.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.xe(1,c);c=a.bf();0<c.length&&b.Oa(2,c,x.P.Bc.G)};x.P.pd.prototype.nt=function(a){l.u.J(this,1,a)};x.P.pd.prototype.bf=function(){return l.u.Ma(this,x.P.Bc,2)};\nx.P.pd.prototype.Eg=function(a,b){return l.u.La(this,2,a,x.P.Bc,b)};x.P.pd.K=function(a){return l.u.K(x.P.pd,a)};x.P.Bc=function(a){l.u.initialize(this,a,0,-1,x.P.Bc.na,null)};h.da(x.P.Bc,l.u);x.P.Bc.na=[1,2];l.u.ha&&(x.P.Bc.prototype.C=function(a){return x.P.Bc.C(a,this)},x.P.Bc.C=function(a,b){var c={qO:l.u.D(b,1),g9:l.u.Ka(b.zz(),x.i.Ub.C,a),f8:l.u.Na(b,3)};a&&(c.ja=b);return c});x.P.Bc.ia=function(a){a=new l.ba(a);var b=new x.P.Bc;return x.P.Bc.F(b,a)};\nx.P.Bc.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.Rq(c);break;case 2:c=new x.i.Ub;b.T(c,x.i.Ub.F);a.HI(c);break;case 3:c=b.pa();a.mS(c);break;default:b.ea()}}return a};x.P.Bc.G=function(a,b){var c;c=a.Ir();0<c.length&&b.oc(1,c);c=a.zz();0<c.length&&b.Oa(2,c,x.i.Ub.G);c=l.u.D(a,3);null!=c&&b.ya(3,c)};d=x.P.Bc.prototype;d.Ir=function(){return l.u.D(this,1)};d.Rq=function(a,b){l.u.ib(this,1,a,b)};d.zz=function(){return l.u.Ma(this,x.i.Ub,2)};\nd.HI=function(a,b){return l.u.La(this,2,a,x.i.Ub,b)};d.mS=function(a){l.u.J(this,3,a)};x.P.Bc.K=function(a){return l.u.K(x.P.Bc,a)};x.P.c_={EZ:1,fY:2,SZ:3,xY:4,kZ:5,DZ:6};x.P.JX={WW:1,CY:2};x.P.RY={NONE:1,EX:2,DX:3,GZ:4,SD:5,HZ:6,vY:7};x.i.Pb=function(a){l.u.initialize(this,a,0,-1,x.i.Pb.na,null)};h.da(x.i.Pb,l.u);x.i.Pb.na=[1];\nl.u.ha&&(x.i.Pb.prototype.C=function(a){return x.i.Pb.C(a,this)},x.i.Pb.C=function(a,b){var c,e={D3:l.u.Ka(b.ly(),x.i.Pb.Nd.C,a),t3:(c=b.jy())&&x.qa.Tc.C(a,c)};a&&(e.ja=b);return e});x.i.Pb.ia=function(a){a=new l.ba(a);var b=new x.i.Pb;return x.i.Pb.F(b,a)};x.i.Pb.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.Pb.Nd;b.T(c,x.i.Pb.Nd.F);a.IH(c);break;case 2:c=new x.qa.Tc;b.T(c,x.qa.Tc.F);a.EQ(c);break;default:b.ea()}}return a};\nx.i.Pb.G=function(a,b){var c;c=a.ly();0<c.length&&b.Oa(1,c,x.i.Pb.Nd.G);c=a.jy();null!=c&&b.oa(2,c,x.qa.Tc.G)};x.i.Pb.prototype.ly=function(){return l.u.Ma(this,x.i.Pb.Nd,1)};x.i.Pb.prototype.IH=function(a,b){return l.u.La(this,1,a,x.i.Pb.Nd,b)};x.i.Pb.prototype.jy=function(){return l.u.sa(this,x.qa.Tc,2)};x.i.Pb.prototype.EQ=function(a){l.u.Ca(this,2,a)};x.i.Pb.K=function(a){return l.u.K(x.i.Pb,a)};x.i.Pb.Nd=function(a){l.u.initialize(this,a,0,-1,x.i.Pb.Nd.na,null)};h.da(x.i.Pb.Nd,l.u);\nx.i.Pb.Nd.na=[2,3,4,5,6,7,8,9];l.u.ha&&(x.i.Pb.Nd.prototype.C=function(a){return x.i.Pb.Nd.C(a,this)},x.i.Pb.Nd.C=function(a,b){var c={aj:l.u.D(b,1),M4:l.u.D(b,2),gca:l.u.gb(b,3),ica:l.u.gb(b,4),mca:l.u.gb(b,5),oca:l.u.gb(b,6),jca:l.u.gb(b,7),pca:l.u.gb(b,8),W9:l.u.D(b,9)};a&&(c.ja=b);return c});x.i.Pb.Nd.ia=function(a){a=new l.ba(a);var b=new x.i.Pb.Nd;return x.i.Pb.Nd.F(b,a)};\nx.i.Pb.Nd.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.xf(c);break;case 2:c=b.Aa();a.TH(c);break;case 3:c=b.pa();a.oJ(c);break;case 4:c=b.pa();a.qJ(c);break;case 5:c=b.pa();a.tJ(c);break;case 6:c=b.pa();a.vJ(c);break;case 7:c=b.pa();a.nJ(c);break;case 8:c=b.pa();a.sJ(c);break;case 9:c=b.ee();a.MI(c);break;default:b.ea()}}return a};\nx.i.Pb.Nd.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Ja(1,c);c=a.tL();0<c.length&&b.oc(2,c);c=a.wM();0<c.length&&b.bd(3,c);c=a.xM();0<c.length&&b.bd(4,c);c=a.zM();0<c.length&&b.bd(5,c);c=a.AM();0<c.length&&b.bd(6,c);c=a.yM();0<c.length&&b.bd(7,c);c=a.BM();0<c.length&&b.bd(8,c);c=a.dM();0<c.length&&b.IW(9,c)};d=x.i.Pb.Nd.prototype;d.Hg=function(){return l.u.D(this,1)};d.xf=function(a){l.u.J(this,1,a)};d.tL=function(){return l.u.D(this,2)};d.TH=function(a,b){l.u.ib(this,2,a,b)};\nd.wM=function(){return l.u.gb(this,3)};d.oJ=function(a,b){l.u.ib(this,3,a,b)};d.xM=function(){return l.u.gb(this,4)};d.qJ=function(a,b){l.u.ib(this,4,a,b)};d.zM=function(){return l.u.gb(this,5)};d.tJ=function(a,b){l.u.ib(this,5,a,b)};d.AM=function(){return l.u.gb(this,6)};d.vJ=function(a,b){l.u.ib(this,6,a,b)};d.yM=function(){return l.u.gb(this,7)};d.nJ=function(a,b){l.u.ib(this,7,a,b)};d.BM=function(){return l.u.gb(this,8)};d.sJ=function(a,b){l.u.ib(this,8,a,b)};\nd.dM=function(){return l.u.D(this,9)};d.MI=function(a,b){l.u.ib(this,9,a,b)};x.i.Pb.Nd.K=function(a){return l.u.K(x.i.Pb.Nd,a)};x.i.Xb=function(a){l.u.initialize(this,a,0,-1,x.i.Xb.na,null)};h.da(x.i.Xb,l.u);x.i.Xb.na=[2];l.u.ha&&(x.i.Xb.prototype.C=function(a){return x.i.Xb.C(a,this)},x.i.Xb.C=function(a,b){var c={t8:l.u.D(b,1),kK:l.u.Ka(b.Ll(),x.i.Xb.Be.C,a)};a&&(c.ja=b);return c});x.i.Xb.ia=function(a){a=new l.ba(a);var b=new x.i.Xb;return x.i.Xb.F(b,a)};\nx.i.Xb.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.uS(c);break;case 2:c=new x.i.Xb.Be;b.T(c,x.i.Xb.Be.F);a.Mq(c);break;default:b.ea()}}return a};x.i.Xb.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Ja(1,c);c=a.Ll();0<c.length&&b.Oa(2,c,x.i.Xb.Be.G)};x.i.Xb.prototype.uS=function(a){l.u.J(this,1,a)};x.i.Xb.prototype.Ll=function(){return l.u.Ma(this,x.i.Xb.Be,2)};x.i.Xb.prototype.Mq=function(a,b){return l.u.La(this,2,a,x.i.Xb.Be,b)};\nx.i.Xb.K=function(a){return l.u.K(x.i.Xb,a)};x.i.Xb.Be=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.Xb.Be,l.u);l.u.ha&&(x.i.Xb.Be.prototype.C=function(a){return x.i.Xb.Be.C(a,this)},x.i.Xb.Be.C=function(a,b){var c={name:l.u.D(b,1),HO:l.u.D(b,2),lastIndex:l.u.D(b,3),rC:l.u.D(b,4),u8:l.u.D(b,5)};a&&(c.ja=b);return c});x.i.Xb.Be.ia=function(a){a=new l.ba(a);var b=new x.i.Xb.Be;return x.i.Xb.Be.F(b,a)};\nx.i.Xb.Be.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.fe(c);break;case 2:c=b.ad();a.et(c);break;case 3:c=b.ad();a.lS(c);break;case 4:c=b.ad();a.BU(c);break;case 5:c=b.ee();a.vS(c);break;default:b.ea()}}return a};x.i.Xb.Be.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Ja(1,c);c=l.u.D(a,2);null!=c&&b.td(2,c);c=l.u.D(a,3);null!=c&&b.td(3,c);c=l.u.D(a,4);null!=c&&b.td(4,c);c=l.u.D(a,5);null!=c&&b.ye(5,c)};d=x.i.Xb.Be.prototype;d.getName=function(){return l.u.D(this,1)};\nd.fe=function(a){l.u.J(this,1,a)};d.et=function(a){l.u.J(this,2,a)};d.lS=function(a){l.u.J(this,3,a)};d.BU=function(a){l.u.J(this,4,a)};d.vS=function(a){l.u.J(this,5,a)};x.i.Xb.Be.K=function(a){return l.u.K(x.i.Xb.Be,a)};x.i.Sb=function(a){l.u.initialize(this,a,0,-1,x.i.Sb.na,null)};h.da(x.i.Sb,l.u);x.i.Sb.na=[2];l.u.ha&&(x.i.Sb.prototype.C=function(a){return x.i.Sb.C(a,this)},x.i.Sb.C=function(a,b){var c={GO:l.u.D(b,1),NK:l.u.Ka(b.Rl(),x.i.Sb.Kb.C,a)};a&&(c.ja=b);return c});\nx.i.Sb.ia=function(a){a=new l.ba(a);var b=new x.i.Sb;return x.i.Sb.F(b,a)};x.i.Sb.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Jg();a.dt(c);break;case 2:c=new x.i.Sb.Kb;b.T(c,x.i.Sb.Kb.F);a.Nq(c);break;default:b.ea()}}return a};x.i.Sb.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Pg(1,c);c=a.Rl();0<c.length&&b.Oa(2,c,x.i.Sb.Kb.G)};x.i.Sb.prototype.dt=function(a){l.u.J(this,1,a)};x.i.Sb.prototype.Rl=function(){return l.u.Ma(this,x.i.Sb.Kb,2)};\nx.i.Sb.prototype.Nq=function(a,b){return l.u.La(this,2,a,x.i.Sb.Kb,b)};x.i.Sb.K=function(a){return l.u.K(x.i.Sb,a)};x.i.Sb.Kb=function(a){l.u.initialize(this,a,0,-1,x.i.Sb.Kb.na,null)};h.da(x.i.Sb.Kb,l.u);x.i.Sb.Kb.na=[7,8];l.u.ha&&(x.i.Sb.Kb.prototype.C=function(a){return x.i.Sb.Kb.C(a,this)},x.i.Sb.Kb.C=function(a,b){var c={Fl:l.u.D(b,1),Bj:l.u.D(b,2),SN:l.u.D(b,3),MK:l.u.D(b,4),creationTime:l.u.D(b,5),FJ:l.u.D(b,6),sba:l.u.D(b,7),tba:l.u.D(b,8),error:l.u.D(b,9)};a&&(c.ja=b);return c});\nx.i.Sb.Kb.ia=function(a){a=new l.ba(a);var b=new x.i.Sb.Kb;return x.i.Sb.Kb.F(b,a)};x.i.Sb.Kb.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Ya();a.Mg(c);break;case 2:c=b.Ya();a.zf(c);break;case 3:c=b.ad();a.Ys(c);break;case 4:c=b.ad();a.Rs(c);break;case 5:c=b.ad();a.Lg(c);break;case 6:c=b.ad();a.Ks(c);break;case 7:c=b.Aa();a.fJ(c);break;case 8:c=b.Aa();a.gJ(c);break;case 9:c=b.Aa();a.Jh(c);break;default:b.ea()}}return a};\nx.i.Sb.Kb.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.$a(1,c);c=l.u.D(a,2);null!=c&&b.$a(2,c);c=l.u.D(a,3);null!=c&&b.td(3,c);c=l.u.D(a,4);null!=c&&b.td(4,c);c=l.u.D(a,5);null!=c&&b.td(5,c);c=l.u.D(a,6);null!=c&&b.td(6,c);c=a.rM();0<c.length&&b.oc(7,c);c=a.sM();0<c.length&&b.oc(8,c);c=l.u.D(a,9);null!=c&&b.Ja(9,c)};d=x.i.Sb.Kb.prototype;d.ik=function(){return l.u.D(this,1)};d.Mg=function(a){l.u.J(this,1,a)};d.zf=function(a){l.u.J(this,2,a)};d.Ys=function(a){l.u.J(this,3,a)};\nd.Rs=function(a){l.u.J(this,4,a)};d.Lg=function(a){l.u.J(this,5,a)};d.Ks=function(a){l.u.J(this,6,a)};d.rM=function(){return l.u.D(this,7)};d.fJ=function(a,b){l.u.ib(this,7,a,b)};d.sM=function(){return l.u.D(this,8)};d.gJ=function(a,b){l.u.ib(this,8,a,b)};d.getError=function(){return l.u.D(this,9)};d.Jh=function(a){l.u.J(this,9,a)};x.i.Sb.Kb.K=function(a){return l.u.K(x.i.Sb.Kb,a)};x.i.Yb=function(a){l.u.initialize(this,a,0,-1,x.i.Yb.na,null)};h.da(x.i.Yb,l.u);x.i.Yb.na=[2];\nl.u.ha&&(x.i.Yb.prototype.C=function(a){return x.i.Yb.C(a,this)},x.i.Yb.C=function(a,b){var c={GO:l.u.D(b,1),NK:l.u.Ka(b.Rl(),x.i.Yb.Kb.C,a)};a&&(c.ja=b);return c});x.i.Yb.ia=function(a){a=new l.ba(a);var b=new x.i.Yb;return x.i.Yb.F(b,a)};x.i.Yb.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Jg();a.dt(c);break;case 2:c=new x.i.Yb.Kb;b.T(c,x.i.Yb.Kb.F);a.Nq(c);break;default:b.ea()}}return a};\nx.i.Yb.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Pg(1,c);c=a.Rl();0<c.length&&b.Oa(2,c,x.i.Yb.Kb.G)};x.i.Yb.prototype.dt=function(a){l.u.J(this,1,a)};x.i.Yb.prototype.Rl=function(){return l.u.Ma(this,x.i.Yb.Kb,2)};x.i.Yb.prototype.Nq=function(a,b){return l.u.La(this,2,a,x.i.Yb.Kb,b)};x.i.Yb.K=function(a){return l.u.K(x.i.Yb,a)};x.i.Yb.Kb=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.Yb.Kb,l.u);\nl.u.ha&&(x.i.Yb.Kb.prototype.C=function(a){return x.i.Yb.Kb.C(a,this)},x.i.Yb.Kb.C=function(a,b){var c={Fl:l.u.D(b,1),Bj:l.u.D(b,2),SN:l.u.D(b,3),MK:l.u.D(b,4),creationTime:l.u.D(b,5),FJ:l.u.D(b,6),K$:l.u.D(b,7),w9:l.u.D(b,8),e5:l.u.D(b,9),error:l.u.D(b,10)};a&&(c.ja=b);return c});x.i.Yb.Kb.ia=function(a){a=new l.ba(a);var b=new x.i.Yb.Kb;return x.i.Yb.Kb.F(b,a)};\nx.i.Yb.Kb.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Ya();a.Mg(c);break;case 2:c=b.Ya();a.zf(c);break;case 3:c=b.ad();a.Ys(c);break;case 4:c=b.ee();a.Rs(c);break;case 5:c=b.ee();a.Lg(c);break;case 6:c=b.ee();a.Ks(c);break;case 7:c=b.ee();a.WT(c);break;case 8:c=b.ee();a.gT(c);break;case 9:c=b.Aa();a.kR(c);break;case 10:c=b.Aa();a.Jh(c);break;default:b.ea()}}return a};\nx.i.Yb.Kb.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.$a(1,c);c=l.u.D(a,2);null!=c&&b.$a(2,c);c=l.u.D(a,3);null!=c&&b.td(3,c);c=l.u.D(a,4);null!=c&&b.ye(4,c);c=l.u.D(a,5);null!=c&&b.ye(5,c);c=l.u.D(a,6);null!=c&&b.ye(6,c);c=l.u.D(a,7);null!=c&&b.ye(7,c);c=l.u.D(a,8);null!=c&&b.ye(8,c);c=l.u.D(a,9);null!=c&&b.Ja(9,c);c=l.u.D(a,10);null!=c&&b.Ja(10,c)};d=x.i.Yb.Kb.prototype;d.ik=function(){return l.u.D(this,1)};d.Mg=function(a){l.u.J(this,1,a)};d.zf=function(a){l.u.J(this,2,a)};\nd.Ys=function(a){l.u.J(this,3,a)};d.Rs=function(a){l.u.J(this,4,a)};d.Lg=function(a){l.u.J(this,5,a)};d.Ks=function(a){l.u.J(this,6,a)};d.WT=function(a){l.u.J(this,7,a)};d.gT=function(a){l.u.J(this,8,a)};d.kR=function(a){l.u.J(this,9,a)};d.getError=function(){return l.u.D(this,10)};d.Jh=function(a){l.u.J(this,10,a)};x.i.Yb.Kb.K=function(a){return l.u.K(x.i.Yb.Kb,a)};x.i.ma=function(a){l.u.initialize(this,a,0,-1,x.i.ma.na,null)};h.da(x.i.ma,l.u);x.i.ma.na=[1,2,3,5];\nl.u.ha&&(x.i.ma.prototype.C=function(a){return x.i.ma.C(a,this)},x.i.ma.C=function(a,b){var c,e={t7:l.u.Ka(b.iz(),x.i.ma.nc.C,a),N5:l.u.Ka(b.Uy(),x.i.ma.nc.C,a),Rba:l.u.Ka(b.wA(),x.i.ma.Db.C,a),s8:(c=b.qz())&&x.i.ma.Qd.C(a,c),Uca:l.u.Ka(b.NA(),x.i.ma.zc.C,a)};a&&(e.ja=b);return e});x.i.ma.ia=function(a){a=new l.ba(a);var b=new x.i.ma;return x.i.ma.F(b,a)};\nx.i.ma.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.ma.nc;b.T(c,x.i.ma.nc.F);a.sI(c);break;case 2:c=new x.i.ma.nc;b.T(c,x.i.ma.nc.F);a.jI(c);break;case 3:c=new x.i.ma.Db;b.T(c,x.i.ma.Db.F);a.iJ(c);break;case 4:c=new x.i.ma.Qd;b.T(c,x.i.ma.Qd.F);a.tS(c);break;case 5:c=new x.i.ma.zc;b.T(c,x.i.ma.zc.F);a.yJ(c);break;default:b.ea()}}return a};\nx.i.ma.G=function(a,b){var c;c=a.iz();0<c.length&&b.Oa(1,c,x.i.ma.nc.G);c=a.Uy();0<c.length&&b.Oa(2,c,x.i.ma.nc.G);c=a.wA();0<c.length&&b.Oa(3,c,x.i.ma.Db.G);c=a.qz();null!=c&&b.oa(4,c,x.i.ma.Qd.G);c=a.NA();0<c.length&&b.Oa(5,c,x.i.ma.zc.G)};d=x.i.ma.prototype;d.iz=function(){return l.u.Ma(this,x.i.ma.nc,1)};d.sI=function(a,b){return l.u.La(this,1,a,x.i.ma.nc,b)};d.Uy=function(){return l.u.Ma(this,x.i.ma.nc,2)};d.jI=function(a,b){return l.u.La(this,2,a,x.i.ma.nc,b)};\nd.wA=function(){return l.u.Ma(this,x.i.ma.Db,3)};d.iJ=function(a,b){return l.u.La(this,3,a,x.i.ma.Db,b)};d.qz=function(){return l.u.sa(this,x.i.ma.Qd,4)};d.tS=function(a){l.u.Ca(this,4,a)};d.NA=function(){return l.u.Ma(this,x.i.ma.zc,5)};d.yJ=function(a,b){return l.u.La(this,5,a,x.i.ma.zc,b)};x.i.ma.K=function(a){return l.u.K(x.i.ma,a)};x.i.ma.Version=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.ma.Version,l.u);\nl.u.ha&&(x.i.ma.Version.prototype.C=function(a){return x.i.ma.Version.C(a,this)},x.i.ma.Version.C=function(a,b){var c={Bj:l.u.D(b,1),creationTime:l.u.D(b,2)};a&&(c.ja=b);return c});x.i.ma.Version.ia=function(a){a=new l.ba(a);var b=new x.i.ma.Version;return x.i.ma.Version.F(b,a)};x.i.ma.Version.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Ya();a.zf(c);break;case 2:c=b.Ya();a.Lg(c);break;default:b.ea()}}return a};\nx.i.ma.Version.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.$a(1,c);c=l.u.D(a,2);null!=c&&b.$a(2,c)};x.i.ma.Version.prototype.zf=function(a){l.u.J(this,1,a)};x.i.ma.Version.prototype.Lg=function(a){l.u.J(this,2,a)};x.i.ma.Version.K=function(a){return l.u.K(x.i.ma.Version,a)};x.i.ma.zc=function(a){l.u.initialize(this,a,0,-1,x.i.ma.zc.na,null)};h.da(x.i.ma.zc,l.u);x.i.ma.zc.na=[4];\nl.u.ha&&(x.i.ma.zc.prototype.C=function(a){return x.i.ma.zc.C(a,this)},x.i.ma.zc.C=function(a,b){var c={Fl:l.u.D(b,1),startTime:l.u.D(b,2),endTime:l.u.D(b,3),Jm:l.u.Ka(b.bf(),x.i.ma.Version.C,a)};a&&(c.ja=b);return c});x.i.ma.zc.ia=function(a){a=new l.ba(a);var b=new x.i.ma.zc;return x.i.ma.zc.F(b,a)};\nx.i.ma.zc.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Ya();a.Mg(c);break;case 2:c=b.Ya();a.vj(c);break;case 3:c=b.Ya();a.sj(c);break;case 4:c=new x.i.ma.Version;b.T(c,x.i.ma.Version.F);a.Eg(c);break;default:b.ea()}}return a};x.i.ma.zc.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.$a(1,c);c=l.u.D(a,2);null!=c&&b.$a(2,c);c=l.u.D(a,3);null!=c&&b.$a(3,c);c=a.bf();0<c.length&&b.Oa(4,c,x.i.ma.Version.G)};d=x.i.ma.zc.prototype;d.ik=function(){return l.u.D(this,1)};\nd.Mg=function(a){l.u.J(this,1,a)};d.getStartTime=function(){return l.u.D(this,2)};d.vj=function(a){l.u.J(this,2,a)};d.sj=function(a){l.u.J(this,3,a)};d.bf=function(){return l.u.Ma(this,x.i.ma.Version,4)};d.Eg=function(a,b){return l.u.La(this,4,a,x.i.ma.Version,b)};x.i.ma.zc.K=function(a){return l.u.K(x.i.ma.zc,a)};x.i.ma.nc=function(a){l.u.initialize(this,a,0,-1,x.i.ma.nc.na,null)};h.da(x.i.ma.nc,l.u);x.i.ma.nc.na=[2];\nl.u.ha&&(x.i.ma.nc.prototype.C=function(a){return x.i.ma.nc.C(a,this)},x.i.ma.nc.C=function(a,b){var c={type:l.u.D(b,1),b5:l.u.Ka(b.Gy(),x.i.ma.zc.C,a)};a&&(c.ja=b);return c});x.i.ma.nc.ia=function(a){a=new l.ba(a);var b=new x.i.ma.nc;return x.i.ma.nc.F(b,a)};x.i.ma.nc.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.yf(c);break;case 2:c=new x.i.ma.zc;b.T(c,x.i.ma.zc.F);a.VH(c);break;default:b.ea()}}return a};\nx.i.ma.nc.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Ja(1,c);c=a.Gy();0<c.length&&b.Oa(2,c,x.i.ma.zc.G)};x.i.ma.nc.prototype.mi=function(){return l.u.D(this,1)};x.i.ma.nc.prototype.yf=function(a){l.u.J(this,1,a)};x.i.ma.nc.prototype.Gy=function(){return l.u.Ma(this,x.i.ma.zc,2)};x.i.ma.nc.prototype.VH=function(a,b){return l.u.La(this,2,a,x.i.ma.zc,b)};x.i.ma.nc.K=function(a){return l.u.K(x.i.ma.nc,a)};x.i.ma.Db=function(a){l.u.initialize(this,a,0,-1,x.i.ma.Db.na,null)};h.da(x.i.ma.Db,l.u);\nx.i.ma.Db.na=[4];l.u.ha&&(x.i.ma.Db.prototype.C=function(a){return x.i.ma.Db.C(a,this)},x.i.ma.Db.C=function(a,b){var c={Fl:l.u.D(b,1),startTime:l.u.D(b,2),endTime:l.u.D(b,3),iW:l.u.Ka(b.cm(),x.i.ma.Db.Yd.C,a)};a&&(c.ja=b);return c});x.i.ma.Db.ia=function(a){a=new l.ba(a);var b=new x.i.ma.Db;return x.i.ma.Db.F(b,a)};\nx.i.ma.Db.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Ya();a.Mg(c);break;case 2:c=b.Ya();a.vj(c);break;case 3:c=b.Ya();a.sj(c);break;case 4:c=new x.i.ma.Db.Yd;b.T(c,x.i.ma.Db.Yd.F);a.Tq(c);break;default:b.ea()}}return a};x.i.ma.Db.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.$a(1,c);c=l.u.D(a,2);null!=c&&b.$a(2,c);c=l.u.D(a,3);null!=c&&b.$a(3,c);c=a.cm();0<c.length&&b.Oa(4,c,x.i.ma.Db.Yd.G)};d=x.i.ma.Db.prototype;d.ik=function(){return l.u.D(this,1)};\nd.Mg=function(a){l.u.J(this,1,a)};d.getStartTime=function(){return l.u.D(this,2)};d.vj=function(a){l.u.J(this,2,a)};d.sj=function(a){l.u.J(this,3,a)};d.cm=function(){return l.u.Ma(this,x.i.ma.Db.Yd,4)};d.Tq=function(a,b){return l.u.La(this,4,a,x.i.ma.Db.Yd,b)};x.i.ma.Db.K=function(a){return l.u.K(x.i.ma.Db,a)};x.i.ma.Db.Yd=function(a){l.u.initialize(this,a,0,-1,x.i.ma.Db.Yd.na,null)};h.da(x.i.ma.Db.Yd,l.u);x.i.ma.Db.Yd.na=[3];\nl.u.ha&&(x.i.ma.Db.Yd.prototype.C=function(a){return x.i.ma.Db.Yd.C(a,this)},x.i.ma.Db.Yd.C=function(a,b){var c={name:l.u.D(b,1),type:l.u.D(b,2),Jm:l.u.Ka(b.bf(),x.i.ma.Version.C,a)};a&&(c.ja=b);return c});x.i.ma.Db.Yd.ia=function(a){a=new l.ba(a);var b=new x.i.ma.Db.Yd;return x.i.ma.Db.Yd.F(b,a)};x.i.ma.Db.Yd.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.fe(c);break;case 2:c=b.Aa();a.yf(c);break;case 3:c=new x.i.ma.Version;b.T(c,x.i.ma.Version.F);a.Eg(c);break;default:b.ea()}}return a};\nx.i.ma.Db.Yd.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Ja(1,c);c=l.u.D(a,2);null!=c&&b.Ja(2,c);c=a.bf();0<c.length&&b.Oa(3,c,x.i.ma.Version.G)};d=x.i.ma.Db.Yd.prototype;d.getName=function(){return l.u.D(this,1)};d.fe=function(a){l.u.J(this,1,a)};d.mi=function(){return l.u.D(this,2)};d.yf=function(a){l.u.J(this,2,a)};d.bf=function(){return l.u.Ma(this,x.i.ma.Version,3)};d.Eg=function(a,b){return l.u.La(this,3,a,x.i.ma.Version,b)};x.i.ma.Db.Yd.K=function(a){return l.u.K(x.i.ma.Db.Yd,a)};\nx.i.ma.Qd=function(a){l.u.initialize(this,a,0,-1,x.i.ma.Qd.na,null)};h.da(x.i.ma.Qd,l.u);x.i.ma.Qd.na=[1];l.u.ha&&(x.i.ma.Qd.prototype.C=function(a){return x.i.ma.Qd.C(a,this)},x.i.ma.Qd.C=function(a,b){var c={Jm:l.u.Ka(b.bf(),x.i.ma.Version.C,a)};a&&(c.ja=b);return c});x.i.ma.Qd.ia=function(a){a=new l.ba(a);var b=new x.i.ma.Qd;return x.i.ma.Qd.F(b,a)};x.i.ma.Qd.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.ma.Version;b.T(c,x.i.ma.Version.F);a.Eg(c);break;default:b.ea()}}return a};\nx.i.ma.Qd.G=function(a,b){a=a.bf();0<a.length&&b.Oa(1,a,x.i.ma.Version.G)};x.i.ma.Qd.prototype.bf=function(){return l.u.Ma(this,x.i.ma.Version,1)};x.i.ma.Qd.prototype.Eg=function(a,b){return l.u.La(this,1,a,x.i.ma.Version,b)};x.i.ma.Qd.K=function(a){return l.u.K(x.i.ma.Qd,a)};x.i.kg=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.kg,l.u);l.u.ha&&(x.i.kg.prototype.C=function(a){return x.i.kg.C(a,this)},x.i.kg.C=function(a,b){var c={l7:l.u.D(b,1)};a&&(c.ja=b);return c});\nx.i.kg.ia=function(a){a=new l.ba(a);var b=new x.i.kg;return x.i.kg.F(b,a)};x.i.kg.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.WR(c);break;default:b.ea()}}return a};x.i.kg.G=function(a,b){a=l.u.D(a,1);null!=a&&b.Ja(1,a)};x.i.kg.prototype.WR=function(a){l.u.J(this,1,a)};x.i.kg.K=function(a){return l.u.K(x.i.kg,a)};x.i.lf=function(a){l.u.initialize(this,a,0,-1,x.i.lf.na,null)};h.da(x.i.lf,l.u);x.i.lf.na=[1];\nl.u.ha&&(x.i.lf.prototype.C=function(a){return x.i.lf.C(a,this)},x.i.lf.C=function(a,b){var c={X8:l.u.Ka(b.vz(),x.P.Rd.C,a)};a&&(c.ja=b);return c});x.i.lf.ia=function(a){a=new l.ba(a);var b=new x.i.lf;return x.i.lf.F(b,a)};x.i.lf.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.P.Rd;b.T(c,x.P.Rd.F);a.DI(c);break;default:b.ea()}}return a};x.i.lf.G=function(a,b){a=a.vz();0<a.length&&b.Oa(1,a,x.P.Rd.G)};x.i.lf.prototype.vz=function(){return l.u.Ma(this,x.P.Rd,1)};\nx.i.lf.prototype.DI=function(a,b){return l.u.La(this,1,a,x.P.Rd,b)};x.i.lf.K=function(a){return l.u.K(x.i.lf,a)};x.i.Link=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.Link,l.u);l.u.ha&&(x.i.Link.prototype.C=function(a){return x.i.Link.C(a,this)},x.i.Link.C=function(a,b){var c={id:l.u.D(b,1),url:l.u.D(b,2)};a&&(c.ja=b);return c});x.i.Link.ia=function(a){a=new l.ba(a);var b=new x.i.Link;return x.i.Link.F(b,a)};\nx.i.Link.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.Vs(c);break;case 2:c=b.Aa();a.EV(c);break;default:b.ea()}}return a};x.i.Link.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Ja(1,c);c=l.u.D(a,2);null!=c&&b.Ja(2,c)};x.i.Link.prototype.Vs=function(a){l.u.J(this,1,a)};x.i.Link.prototype.getUrl=function(){return l.u.D(this,2)};x.i.Link.prototype.EV=function(a){l.u.J(this,2,a)};x.i.Link.K=function(a){return l.u.K(x.i.Link,a)};\nx.i.Ea=function(a){l.u.initialize(this,a,0,-1,x.i.Ea.na,null)};h.da(x.i.Ea,l.u);x.i.Ea.na=[15];\nl.u.ha&&(x.i.Ea.prototype.C=function(a){return x.i.Ea.C(a,this)},x.i.Ea.C=function(a,b){var c,e={Bj:l.u.D(b,1),creationTime:l.u.D(b,2),Wca:(c=b.PA())&&x.i.Ea.$b.C(a,c),e7:(c=b.cz())&&x.i.Ea.$b.C(a,c),D9:(c=b.Hz())&&x.i.Ea.$b.C(a,c),Y7:(c=b.mz())&&x.i.Ea.$b.C(a,c),Z7:(c=b.nz())&&x.i.Ea.rb.C(a,c),S$:(c=b.Uz())&&x.i.Ea.rb.C(a,c),baa:(c=b.aA())&&x.i.Ea.rb.C(a,c),wl:(c=b.Gg())&&x.i.Ea.rb.C(a,c),Ow:(c=b.so())&&x.i.Ea.rb.C(a,c),eP:(c=b.Nr())&&x.i.Ea.rb.C(a,c),Bda:(c=b.ZA())&&x.i.Ea.rb.C(a,c),C3:l.u.D(b,\n14),UN:l.u.Ka(b.Vl(),x.i.Link.C,a),O9:l.u.Na(b,16),Xca:(c=b.QA())&&x.i.wc.C(a,c),f7:(c=b.dz())&&x.i.wc.C(a,c),iN:(c=b.Tl())&&x.i.Rc.C(a,c)};a&&(e.ja=b);return e});x.i.Ea.ia=function(a){a=new l.ba(a);var b=new x.i.Ea;return x.i.Ea.F(b,a)};\nx.i.Ea.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Ya();a.zf(c);break;case 2:c=b.ee();a.Lg(c);break;case 3:c=new x.i.Ea.$b;b.T(c,x.i.Ea.$b.F);a.vV(c);break;case 4:c=new x.i.Ea.$b;b.T(c,x.i.Ea.$b.F);a.PR(c);break;case 5:c=new x.i.Ea.$b;b.T(c,x.i.Ea.$b.F);a.lT(c);break;case 6:c=new x.i.Ea.$b;b.T(c,x.i.Ea.$b.F);a.hS(c);break;case 7:c=new x.i.Ea.rb;b.T(c,x.i.Ea.rb.F);a.iS(c);break;case 8:c=new x.i.Ea.rb;b.T(c,x.i.Ea.rb.F);a.$T(c);break;case 9:c=new x.i.Ea.rb;b.T(c,x.i.Ea.rb.F);\na.iU(c);break;case 10:c=new x.i.Ea.rb;b.T(c,x.i.Ea.rb.F);a.Kg(c);break;case 11:c=new x.i.Ea.rb;b.T(c,x.i.Ea.rb.F);a.um(c);break;case 12:c=new x.i.Ea.rb;b.T(c,x.i.Ea.rb.F);a.ht(c);break;case 13:c=new x.i.Ea.rb;b.T(c,x.i.Ea.rb.F);a.NV(c);break;case 14:c=b.vf();a.KQ(c);break;case 15:c=new x.i.Link;b.T(c,x.i.Link.F);a.Qq(c);break;case 16:c=b.pa();a.rT(c);break;case 17:c=new x.i.wc;b.T(c,x.i.wc.F);a.wV(c);break;case 18:c=new x.i.wc;b.T(c,x.i.wc.F);a.QR(c);break;case 19:c=new x.i.Rc;b.T(c,x.i.Rc.F);a.Xs(c);\nbreak;default:b.ea()}}return a};\nx.i.Ea.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.$a(1,c);c=l.u.D(a,2);null!=c&&b.ye(2,c);c=a.PA();null!=c&&b.oa(3,c,x.i.Ea.$b.G);c=a.cz();null!=c&&b.oa(4,c,x.i.Ea.$b.G);c=a.Hz();null!=c&&b.oa(5,c,x.i.Ea.$b.G);c=a.mz();null!=c&&b.oa(6,c,x.i.Ea.$b.G);c=a.nz();null!=c&&b.oa(7,c,x.i.Ea.rb.G);c=a.Uz();null!=c&&b.oa(8,c,x.i.Ea.rb.G);c=a.aA();null!=c&&b.oa(9,c,x.i.Ea.rb.G);c=a.Gg();null!=c&&b.oa(10,c,x.i.Ea.rb.G);c=a.so();null!=c&&b.oa(11,c,x.i.Ea.rb.G);c=a.Nr();null!=c&&b.oa(12,c,x.i.Ea.rb.G);c=a.ZA();\nnull!=c&&b.oa(13,c,x.i.Ea.rb.G);c=l.u.D(a,14);null!=c&&b.kf(14,c);c=a.Vl();0<c.length&&b.Oa(15,c,x.i.Link.G);c=l.u.D(a,16);null!=c&&b.ya(16,c);c=a.QA();null!=c&&b.oa(17,c,x.i.wc.G);c=a.dz();null!=c&&b.oa(18,c,x.i.wc.G);c=a.Tl();null!=c&&b.oa(19,c,x.i.Rc.G)};d=x.i.Ea.prototype;d.zf=function(a){l.u.J(this,1,a)};d.Lg=function(a){l.u.J(this,2,a)};d.PA=function(){return l.u.sa(this,x.i.Ea.$b,3)};d.vV=function(a){l.u.Ca(this,3,a)};d.cz=function(){return l.u.sa(this,x.i.Ea.$b,4)};\nd.PR=function(a){l.u.Ca(this,4,a)};d.Hz=function(){return l.u.sa(this,x.i.Ea.$b,5)};d.lT=function(a){l.u.Ca(this,5,a)};d.mz=function(){return l.u.sa(this,x.i.Ea.$b,6)};d.hS=function(a){l.u.Ca(this,6,a)};d.nz=function(){return l.u.sa(this,x.i.Ea.rb,7)};d.iS=function(a){l.u.Ca(this,7,a)};d.Uz=function(){return l.u.sa(this,x.i.Ea.rb,8)};d.$T=function(a){l.u.Ca(this,8,a)};d.aA=function(){return l.u.sa(this,x.i.Ea.rb,9)};d.iU=function(a){l.u.Ca(this,9,a)};d.Gg=function(){return l.u.sa(this,x.i.Ea.rb,10)};\nd.Kg=function(a){l.u.Ca(this,10,a)};d.so=function(){return l.u.sa(this,x.i.Ea.rb,11)};d.um=function(a){l.u.Ca(this,11,a)};d.Nr=function(){return l.u.sa(this,x.i.Ea.rb,12)};d.ht=function(a){l.u.Ca(this,12,a)};d.ZA=function(){return l.u.sa(this,x.i.Ea.rb,13)};d.NV=function(a){l.u.Ca(this,13,a)};d.KQ=function(a){l.u.J(this,14,a)};d.Vl=function(){return l.u.Ma(this,x.i.Link,15)};d.Qq=function(a,b){return l.u.La(this,15,a,x.i.Link,b)};d.rT=function(a){l.u.J(this,16,a)};\nd.QA=function(){return l.u.sa(this,x.i.wc,17)};d.wV=function(a){l.u.Ca(this,17,a)};d.dz=function(){return l.u.sa(this,x.i.wc,18)};d.QR=function(a){l.u.Ca(this,18,a)};d.Tl=function(){return l.u.sa(this,x.i.Rc,19)};d.Xs=function(a){l.u.Ca(this,19,a)};x.i.Ea.K=function(a){return l.u.K(x.i.Ea,a)};x.i.Ea.rb=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.Ea.rb,l.u);\nl.u.ha&&(x.i.Ea.rb.prototype.C=function(a){return x.i.Ea.rb.C(a,this)},x.i.Ea.rb.C=function(a,b){var c={Tca:l.u.Na(b,1),b7:l.u.Na(b,2)};a&&(c.ja=b);return c});x.i.Ea.rb.ia=function(a){a=new l.ba(a);var b=new x.i.Ea.rb;return x.i.Ea.rb.F(b,a)};x.i.Ea.rb.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.pa();a.uV(c);break;case 2:c=b.pa();a.NR(c);break;default:b.ea()}}return a};x.i.Ea.rb.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.ya(1,c);c=l.u.D(a,2);null!=c&&b.ya(2,c)};\nx.i.Ea.rb.prototype.uV=function(a){l.u.J(this,1,a)};x.i.Ea.rb.prototype.NR=function(a){l.u.J(this,2,a)};x.i.Ea.rb.K=function(a){return l.u.K(x.i.Ea.rb,a)};x.i.Ea.$b=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.Ea.$b,l.u);l.u.ha&&(x.i.Ea.$b.prototype.C=function(a){return x.i.Ea.$b.C(a,this)},x.i.Ea.$b.C=function(a,b){var c={U8:l.u.Na(b,1),D$:l.u.Na(b,2),q9:l.u.Na(b,3)};a&&(c.ja=b);return c});x.i.Ea.$b.ia=function(a){a=new l.ba(a);var b=new x.i.Ea.$b;return x.i.Ea.$b.F(b,a)};\nx.i.Ea.$b.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.pa();a.PS(c);break;case 2:c=b.pa();a.QT(c);break;case 3:c=b.pa();a.aT(c);break;default:b.ea()}}return a};x.i.Ea.$b.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.ya(1,c);c=l.u.D(a,2);null!=c&&b.ya(2,c);c=l.u.D(a,3);null!=c&&b.ya(3,c)};x.i.Ea.$b.prototype.PS=function(a){l.u.J(this,1,a)};x.i.Ea.$b.prototype.QT=function(a){l.u.J(this,2,a)};x.i.Ea.$b.prototype.aT=function(a){l.u.J(this,3,a)};\nx.i.Ea.$b.K=function(a){return l.u.K(x.i.Ea.$b,a)};x.i.Qb=function(a){l.u.initialize(this,a,0,-1,x.i.Qb.na,null)};h.da(x.i.Qb,l.u);x.i.Qb.na=[3,4,5,6];l.u.ha&&(x.i.Qb.prototype.C=function(a){return x.i.Qb.C(a,this)},x.i.Qb.C=function(a,b){var c={name:l.u.D(b,1),path:l.u.D(b,2),j5:l.u.Ka(b.Iy(),x.i.Qb.Ce.C,a),Gca:l.u.Ka(b.GA(),x.i.Link.C,a),C4:l.u.Ka(b.xy(),x.i.Link.C,a),D4:l.u.Ka(b.yy(),x.i.Link.C,a)};a&&(c.ja=b);return c});x.i.Qb.ia=function(a){a=new l.ba(a);var b=new x.i.Qb;return x.i.Qb.F(b,a)};\nx.i.Qb.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.fe(c);break;case 2:c=b.Aa();a.uj(c);break;case 3:c=new x.i.Qb.Ce;b.T(c,x.i.Qb.Ce.F);a.YH(c);break;case 4:c=new x.i.Link;b.T(c,x.i.Link.F);a.xJ(c);break;case 5:c=new x.i.Link;b.T(c,x.i.Link.F);a.OH(c);break;case 6:c=new x.i.Link;b.T(c,x.i.Link.F);a.PH(c);break;default:b.ea()}}return a};\nx.i.Qb.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Ja(1,c);c=l.u.D(a,2);null!=c&&b.Ja(2,c);c=a.Iy();0<c.length&&b.Oa(3,c,x.i.Qb.Ce.G);c=a.GA();0<c.length&&b.Oa(4,c,x.i.Link.G);c=a.xy();0<c.length&&b.Oa(5,c,x.i.Link.G);c=a.yy();0<c.length&&b.Oa(6,c,x.i.Link.G)};d=x.i.Qb.prototype;d.getName=function(){return l.u.D(this,1)};d.fe=function(a){l.u.J(this,1,a)};d.ij=function(){return l.u.D(this,2)};d.uj=function(a){l.u.J(this,2,a)};d.Yr=function(){return null!=l.u.D(this,2)};\nd.Iy=function(){return l.u.Ma(this,x.i.Qb.Ce,3)};d.YH=function(a,b){return l.u.La(this,3,a,x.i.Qb.Ce,b)};d.GA=function(){return l.u.Ma(this,x.i.Link,4)};d.xJ=function(a,b){return l.u.La(this,4,a,x.i.Link,b)};d.xy=function(){return l.u.Ma(this,x.i.Link,5)};d.OH=function(a,b){return l.u.La(this,5,a,x.i.Link,b)};d.yy=function(){return l.u.Ma(this,x.i.Link,6)};d.PH=function(a,b){return l.u.La(this,6,a,x.i.Link,b)};x.i.Qb.K=function(a){return l.u.K(x.i.Qb,a)};\nx.i.Qb.Ce=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.Qb.Ce,l.u);l.u.ha&&(x.i.Qb.Ce.prototype.C=function(a){return x.i.Qb.Ce.C(a,this)},x.i.Qb.Ce.C=function(a,b){var c={type:l.u.D(b,1),Bj:l.u.D(b,2),creationTime:l.u.D(b,3),wda:l.u.D(b,4)};a&&(c.ja=b);return c});x.i.Qb.Ce.ia=function(a){a=new l.ba(a);var b=new x.i.Qb.Ce;return x.i.Qb.Ce.F(b,a)};\nx.i.Qb.Ce.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.yf(c);break;case 2:c=b.Ya();a.zf(c);break;case 3:c=b.ee();a.Lg(c);break;case 4:c=b.Aa();a.KV(c);break;default:b.ea()}}return a};x.i.Qb.Ce.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Ja(1,c);c=l.u.D(a,2);null!=c&&b.$a(2,c);c=l.u.D(a,3);null!=c&&b.ye(3,c);c=l.u.D(a,4);null!=c&&b.Ja(4,c)};d=x.i.Qb.Ce.prototype;d.mi=function(){return l.u.D(this,1)};d.yf=function(a){l.u.J(this,1,a)};\nd.zf=function(a){l.u.J(this,2,a)};d.Lg=function(a){l.u.J(this,3,a)};d.KV=function(a){l.u.J(this,4,a)};x.i.Qb.Ce.K=function(a){return l.u.K(x.i.Qb.Ce,a)};x.i.qf=function(a){l.u.initialize(this,a,0,-1,x.i.qf.na,null)};h.da(x.i.qf,l.u);x.i.qf.na=[1];l.u.ha&&(x.i.qf.prototype.C=function(a){return x.i.qf.C(a,this)},x.i.qf.C=function(a,b){var c={j9:l.u.Ka(b.Az(),x.i.Sd.C,a)};a&&(c.ja=b);return c});x.i.qf.ia=function(a){a=new l.ba(a);var b=new x.i.qf;return x.i.qf.F(b,a)};\nx.i.qf.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.Sd;b.T(c,x.i.Sd.F);a.II(c);break;default:b.ea()}}return a};x.i.qf.G=function(a,b){a=a.Az();0<a.length&&b.Oa(1,a,x.i.Sd.G)};x.i.qf.prototype.Az=function(){return l.u.Ma(this,x.i.Sd,1)};x.i.qf.prototype.II=function(a,b){return l.u.La(this,1,a,x.i.Sd,b)};x.i.qf.K=function(a){return l.u.K(x.i.qf,a)};x.i.pf=function(a){l.u.initialize(this,a,0,-1,x.i.pf.na,null)};h.da(x.i.pf,l.u);x.i.pf.na=[1];\nl.u.ha&&(x.i.pf.prototype.C=function(a){return x.i.pf.C(a,this)},x.i.pf.C=function(a,b){var c={T5:l.u.D(b,1)};a&&(c.ja=b);return c});x.i.pf.ia=function(a){a=new l.ba(a);var b=new x.i.pf;return x.i.pf.F(b,a)};x.i.pf.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.lI(c);break;default:b.ea()}}return a};x.i.pf.G=function(a,b){a=a.HL();0<a.length&&b.oc(1,a)};x.i.pf.prototype.HL=function(){return l.u.D(this,1)};x.i.pf.prototype.lI=function(a,b){l.u.ib(this,1,a,b)};\nx.i.pf.K=function(a){return l.u.K(x.i.pf,a)};x.i.Cb=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.Cb,l.u);l.u.ha&&(x.i.Cb.prototype.C=function(a){return x.i.Cb.C(a,this)},x.i.Cb.C=function(a,b){var c,e={uda:l.u.D(b,1),c3:l.u.D(b,2),creationTime:l.u.D(b,3),v$:l.u.D(b,4),z2:l.u.D(b,5),Z4:l.u.D(b,6),Fl:l.u.D(b,7),version:l.u.D(b,8),w2:(c=b.Ux())&&x.i.Cb.md.C(a,c),Y4:(c=b.Fy())&&x.i.Cb.md.C(a,c),fP:l.u.Na(b,11),error:l.u.D(b,12)};a&&(e.ja=b);return e});\nx.i.Cb.ia=function(a){a=new l.ba(a);var b=new x.i.Cb;return x.i.Cb.F(b,a)};\nx.i.Cb.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.IV(c);break;case 2:c=b.Ya();a.BQ(c);break;case 3:c=b.ad();a.Lg(c);break;case 4:c=b.vf();a.LT(c);break;case 5:c=b.Ya();a.qQ(c);break;case 6:c=b.Ya();a.iR(c);break;case 7:c=b.Ya();a.Mg(c);break;case 8:c=b.Ya();a.setVersion(c);break;case 9:c=new x.i.Cb.md;b.T(c,x.i.Cb.md.F);a.pQ(c);break;case 10:c=new x.i.Cb.md;b.T(c,x.i.Cb.md.F);a.hR(c);break;case 11:c=b.pa();a.it(c);break;case 12:c=b.Aa();a.Jh(c);break;default:b.ea()}}return a};\nx.i.Cb.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Ja(1,c);c=l.u.D(a,2);null!=c&&b.$a(2,c);c=l.u.D(a,3);null!=c&&b.td(3,c);c=l.u.D(a,4);null!=c&&b.kf(4,c);c=l.u.D(a,5);null!=c&&b.$a(5,c);c=l.u.D(a,6);null!=c&&b.$a(6,c);c=l.u.D(a,7);null!=c&&b.$a(7,c);c=l.u.D(a,8);null!=c&&b.$a(8,c);c=a.Ux();null!=c&&b.oa(9,c,x.i.Cb.md.G);c=a.Fy();null!=c&&b.oa(10,c,x.i.Cb.md.G);c=l.u.D(a,11);null!=c&&b.ya(11,c);c=l.u.D(a,12);null!=c&&b.Ja(12,c)};d=x.i.Cb.prototype;d.IV=function(a){l.u.J(this,1,a)};\nd.BQ=function(a){l.u.J(this,2,a)};d.Lg=function(a){l.u.J(this,3,a)};d.LT=function(a){l.u.J(this,4,a)};d.qQ=function(a){l.u.J(this,5,a)};d.iR=function(a){l.u.J(this,6,a)};d.ik=function(){return l.u.D(this,7)};d.Mg=function(a){l.u.J(this,7,a)};d.getVersion=function(){return l.u.D(this,8)};d.setVersion=function(a){l.u.J(this,8,a)};d.Ux=function(){return l.u.sa(this,x.i.Cb.md,9)};d.pQ=function(a){l.u.Ca(this,9,a)};d.Fy=function(){return l.u.sa(this,x.i.Cb.md,10)};d.hR=function(a){l.u.Ca(this,10,a)};\nd.it=function(a){l.u.J(this,11,a)};d.getError=function(){return l.u.D(this,12)};d.Jh=function(a){l.u.J(this,12,a)};x.i.Cb.K=function(a){return l.u.K(x.i.Cb,a)};x.i.Cb.md=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.Cb.md,l.u);l.u.ha&&(x.i.Cb.md.prototype.C=function(a){return x.i.Cb.md.C(a,this)},x.i.Cb.md.C=function(a,b){var c={lm:l.u.Na(b,1),wl:l.u.Na(b,2),$B:l.u.Na(b,3),QK:l.u.Na(b,4),q2:l.u.Na(b,5),s2:l.u.Na(b,6)};a&&(c.ja=b);return c});\nx.i.Cb.md.ia=function(a){a=new l.ba(a);var b=new x.i.Cb.md;return x.i.Cb.md.F(b,a)};x.i.Cb.md.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.pa();a.Ng(c);break;case 2:c=b.pa();a.Kg(c);break;case 3:c=b.pa();a.ym(c);break;case 4:c=b.pa();a.Ss(c);break;case 5:c=b.pa();a.nQ(c);break;case 6:c=b.pa();a.oQ(c);break;default:b.ea()}}return a};\nx.i.Cb.md.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.ya(1,c);c=l.u.D(a,2);null!=c&&b.ya(2,c);c=l.u.D(a,3);null!=c&&b.ya(3,c);c=l.u.D(a,4);null!=c&&b.ya(4,c);c=l.u.D(a,5);null!=c&&b.ya(5,c);c=l.u.D(a,6);null!=c&&b.ya(6,c)};d=x.i.Cb.md.prototype;d.eg=function(){return l.u.Na(this,1)};d.Ng=function(a){l.u.J(this,1,a)};d.Gg=function(){return l.u.Na(this,2)};d.Kg=function(a){l.u.J(this,2,a)};d.mk=function(){return l.u.Na(this,3)};d.ym=function(a){l.u.J(this,3,a)};\nd.Er=function(){return l.u.Na(this,4)};d.Ss=function(a){l.u.J(this,4,a)};d.nQ=function(a){l.u.J(this,5,a)};d.oQ=function(a){l.u.J(this,6,a)};x.i.Cb.md.K=function(a){return l.u.K(x.i.Cb.md,a)};x.i.pc=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.pc,l.u);l.u.ha&&(x.i.pc.prototype.C=function(a){return x.i.pc.C(a,this)},x.i.pc.C=function(a,b){var c={absolute:l.u.Na(b,1),waa:l.u.Na(b,2)};a&&(c.ja=b);return c});x.i.pc.ia=function(a){a=new l.ba(a);var b=new x.i.pc;return x.i.pc.F(b,a)};\nx.i.pc.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.pa();a.$P(c);break;case 2:c=b.pa();a.tU(c);break;default:b.ea()}}return a};x.i.pc.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.ya(1,c);c=l.u.D(a,2);null!=c&&b.ya(2,c)};x.i.pc.prototype.$P=function(a){l.u.J(this,1,a)};x.i.pc.prototype.tU=function(a){l.u.J(this,2,a)};x.i.pc.K=function(a){return l.u.K(x.i.pc,a)};x.i.Jc=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.Jc,l.u);\nl.u.ha&&(x.i.Jc.prototype.C=function(a){return x.i.Jc.C(a,this)},x.i.Jc.C=function(a,b){var c={lowerBound:l.u.Na(b,1),upperBound:l.u.Na(b,2)};a&&(c.ja=b);return c});x.i.Jc.ia=function(a){a=new l.ba(a);var b=new x.i.Jc;return x.i.Jc.F(b,a)};x.i.Jc.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.pa();a.tj(c);break;case 2:c=b.pa();a.xj(c);break;default:b.ea()}}return a};x.i.Jc.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.ya(1,c);c=l.u.D(a,2);null!=c&&b.ya(2,c)};\nx.i.Jc.prototype.Xl=function(){return l.u.Na(this,1)};x.i.Jc.prototype.tj=function(a){l.u.J(this,1,a)};x.i.Jc.prototype.em=function(){return l.u.Na(this,2)};x.i.Jc.prototype.xj=function(a){l.u.J(this,2,a)};x.i.Jc.K=function(a){return l.u.K(x.i.Jc,a)};x.i.Se=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.Se,l.u);\nl.u.ha&&(x.i.Se.prototype.C=function(a){return x.i.Se.C(a,this)},x.i.Se.C=function(a,b){var c,e={lm:(c=b.eg())&&x.i.pc.C(a,c),wl:(c=b.Gg())&&x.i.pc.C(a,c),$B:(c=b.mk())&&x.i.pc.C(a,c),fP:l.u.Na(b,4),p2:(c=b.Tx())&&x.i.Jc.C(a,c),QK:(c=b.Er())&&x.i.Jc.C(a,c)};a&&(e.ja=b);return e});x.i.Se.ia=function(a){a=new l.ba(a);var b=new x.i.Se;return x.i.Se.F(b,a)};\nx.i.Se.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.pc;b.T(c,x.i.pc.F);a.Ng(c);break;case 2:c=new x.i.pc;b.T(c,x.i.pc.F);a.Kg(c);break;case 3:c=new x.i.pc;b.T(c,x.i.pc.F);a.ym(c);break;case 4:c=b.pa();a.it(c);break;case 5:c=new x.i.Jc;b.T(c,x.i.Jc.F);a.mQ(c);break;case 6:c=new x.i.Jc;b.T(c,x.i.Jc.F);a.Ss(c);break;default:b.ea()}}return a};\nx.i.Se.G=function(a,b){var c;c=a.eg();null!=c&&b.oa(1,c,x.i.pc.G);c=a.Gg();null!=c&&b.oa(2,c,x.i.pc.G);c=a.mk();null!=c&&b.oa(3,c,x.i.pc.G);c=l.u.D(a,4);null!=c&&b.ya(4,c);c=a.Tx();null!=c&&b.oa(5,c,x.i.Jc.G);c=a.Er();null!=c&&b.oa(6,c,x.i.Jc.G)};d=x.i.Se.prototype;d.eg=function(){return l.u.sa(this,x.i.pc,1)};d.Ng=function(a){l.u.Ca(this,1,a)};d.Gg=function(){return l.u.sa(this,x.i.pc,2)};d.Kg=function(a){l.u.Ca(this,2,a)};d.mk=function(){return l.u.sa(this,x.i.pc,3)};\nd.ym=function(a){l.u.Ca(this,3,a)};d.it=function(a){l.u.J(this,4,a)};d.Tx=function(){return l.u.sa(this,x.i.Jc,5)};d.mQ=function(a){l.u.Ca(this,5,a)};d.Er=function(){return l.u.sa(this,x.i.Jc,6)};d.Ss=function(a){l.u.Ca(this,6,a)};x.i.Se.K=function(a){return l.u.K(x.i.Se,a)};x.i.Gf=function(a){l.u.initialize(this,a,0,-1,x.i.Gf.na,null)};h.da(x.i.Gf,l.u);x.i.Gf.na=[2,4];\nl.u.ha&&(x.i.Gf.prototype.C=function(a){return x.i.Gf.C(a,this)},x.i.Gf.C=function(a,b){var c,e={pO:l.u.D(b,1),B$:l.u.Ka(b.Pz(),x.i.Cb.C,a),thresholds:(c=b.FA())&&x.i.Se.C(a,c),v5:l.u.D(b,4)};a&&(e.ja=b);return e});x.i.Gf.ia=function(a){a=new l.ba(a);var b=new x.i.Gf;return x.i.Gf.F(b,a)};\nx.i.Gf.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.$s(c);break;case 2:c=new x.i.Cb;b.T(c,x.i.Cb.F);a.TI(c);break;case 3:c=new x.i.Se;b.T(c,x.i.Se.F);a.hV(c);break;case 4:c=b.Aa();a.$H(c);break;default:b.ea()}}return a};x.i.Gf.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Ja(1,c);c=a.Pz();0<c.length&&b.Oa(2,c,x.i.Cb.G);c=a.FA();null!=c&&b.oa(3,c,x.i.Se.G);c=a.zL();0<c.length&&b.oc(4,c)};d=x.i.Gf.prototype;d.$s=function(a){l.u.J(this,1,a)};\nd.Pz=function(){return l.u.Ma(this,x.i.Cb,2)};d.TI=function(a,b){return l.u.La(this,2,a,x.i.Cb,b)};d.FA=function(){return l.u.sa(this,x.i.Se,3)};d.hV=function(a){l.u.Ca(this,3,a)};d.zL=function(){return l.u.D(this,4)};d.$H=function(a,b){l.u.ib(this,4,a,b)};x.i.Gf.K=function(a){return l.u.K(x.i.Gf,a)};x.i.Uf=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.Uf,l.u);\nl.u.ha&&(x.i.Uf.prototype.C=function(a){return x.i.Uf.C(a,this)},x.i.Uf.C=function(a,b){var c,e={Aba:(c=b.sA())&&x.i.za.oe.C(a,c)};a&&(e.ja=b);return e});x.i.Uf.ia=function(a){a=new l.ba(a);var b=new x.i.Uf;return x.i.Uf.F(b,a)};x.i.Uf.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.za.oe;b.T(c,x.i.za.oe.F);a.JU(c);break;default:b.ea()}}return a};x.i.Uf.G=function(a,b){a=a.sA();null!=a&&b.oa(1,a,x.i.za.oe.G)};\nx.i.Uf.prototype.sA=function(){return l.u.sa(this,x.i.za.oe,1)};x.i.Uf.prototype.JU=function(a){l.u.Ca(this,1,a)};x.i.Uf.K=function(a){return l.u.K(x.i.Uf,a)};x.i.Ra=function(a){l.u.initialize(this,a,0,-1,x.i.Ra.na,null)};h.da(x.i.Ra,l.u);x.i.Ra.na=[1];l.u.ha&&(x.i.Ra.prototype.C=function(a){return x.i.Ra.C(a,this)},x.i.Ra.C=function(a,b){var c={K8:l.u.Ka(b.sz(),x.i.Ra.zd.C,a)};a&&(c.ja=b);return c});x.i.Ra.ia=function(a){a=new l.ba(a);var b=new x.i.Ra;return x.i.Ra.F(b,a)};\nx.i.Ra.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.Ra.zd;b.T(c,x.i.Ra.zd.F);a.AI(c);break;default:b.ea()}}return a};x.i.Ra.G=function(a,b){a=a.sz();0<a.length&&b.Oa(1,a,x.i.Ra.zd.G)};x.i.Ra.prototype.sz=function(){return l.u.Ma(this,x.i.Ra.zd,1)};x.i.Ra.prototype.AI=function(a,b){return l.u.La(this,1,a,x.i.Ra.zd,b)};x.i.Ra.K=function(a){return l.u.K(x.i.Ra,a)};x.i.Ra.je=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.Ra.je,l.u);\nl.u.ha&&(x.i.Ra.je.prototype.C=function(a){return x.i.Ra.je.C(a,this)},x.i.Ra.je.C=function(a,b){var c={S5:l.u.D(b,1),Dda:l.u.Na(b,2)};a&&(c.ja=b);return c});x.i.Ra.je.ia=function(a){a=new l.ba(a);var b=new x.i.Ra.je;return x.i.Ra.je.F(b,a)};x.i.Ra.je.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.BR(c);break;case 2:c=b.pa();a.PV(c);break;default:b.ea()}}return a};x.i.Ra.je.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Ja(1,c);c=l.u.D(a,2);null!=c&&b.ya(2,c)};\nx.i.Ra.je.prototype.BR=function(a){l.u.J(this,1,a)};x.i.Ra.je.prototype.PV=function(a){l.u.J(this,2,a)};x.i.Ra.je.K=function(a){return l.u.K(x.i.Ra.je,a)};x.i.Ra.Wd=function(a){l.u.initialize(this,a,0,-1,x.i.Ra.Wd.na,null)};h.da(x.i.Ra.Wd,l.u);x.i.Ra.Wd.na=[1];l.u.ha&&(x.i.Ra.Wd.prototype.C=function(a){return x.i.Ra.Wd.C(a,this)},x.i.Ra.Wd.C=function(a,b){var c={kK:l.u.Ka(b.Ll(),x.i.Ra.je.C,a)};a&&(c.ja=b);return c});\nx.i.Ra.Wd.ia=function(a){a=new l.ba(a);var b=new x.i.Ra.Wd;return x.i.Ra.Wd.F(b,a)};x.i.Ra.Wd.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.Ra.je;b.T(c,x.i.Ra.je.F);a.Mq(c);break;default:b.ea()}}return a};x.i.Ra.Wd.G=function(a,b){a=a.Ll();0<a.length&&b.Oa(1,a,x.i.Ra.je.G)};x.i.Ra.Wd.prototype.Ll=function(){return l.u.Ma(this,x.i.Ra.je,1)};x.i.Ra.Wd.prototype.Mq=function(a,b){return l.u.La(this,1,a,x.i.Ra.je,b)};x.i.Ra.Wd.K=function(a){return l.u.K(x.i.Ra.Wd,a)};\nx.i.Ra.zd=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.Ra.zd,l.u);l.u.ha&&(x.i.Ra.zd.prototype.C=function(a){return x.i.Ra.zd.C(a,this)},x.i.Ra.zd.C=function(a,b){var c,e={key:l.u.D(b,1),value:(c=b.getValue())&&x.i.Ra.Wd.C(a,c)};a&&(e.ja=b);return e});x.i.Ra.zd.ia=function(a){a=new l.ba(a);var b=new x.i.Ra.zd;return x.i.Ra.zd.F(b,a)};\nx.i.Ra.zd.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.gS(c);break;case 2:c=new x.i.Ra.Wd;b.T(c,x.i.Ra.Wd.F);a.setValue(c);break;default:b.ea()}}return a};x.i.Ra.zd.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Ja(1,c);c=a.getValue();null!=c&&b.oa(2,c,x.i.Ra.Wd.G)};x.i.Ra.zd.prototype.getKey=function(){return l.u.D(this,1)};x.i.Ra.zd.prototype.gS=function(a){l.u.J(this,1,a)};x.i.Ra.zd.prototype.getValue=function(){return l.u.sa(this,x.i.Ra.Wd,2)};\nx.i.Ra.zd.prototype.setValue=function(a){l.u.Ca(this,2,a)};x.i.Ra.zd.K=function(a){return l.u.K(x.i.Ra.zd,a)};x.i.Sd=function(a){l.u.initialize(this,a,0,-1,x.i.Sd.na,null)};h.da(x.i.Sd,l.u);x.i.Sd.na=[2];l.u.ha&&(x.i.Sd.prototype.C=function(a){return x.i.Sd.C(a,this)},x.i.Sd.C=function(a,b){var c,e={info:(c=b.gz())&&x.i.Qb.C(a,c),Jm:l.u.Ka(b.bf(),x.i.Ea.C,a),error:l.u.D(b,3)};a&&(e.ja=b);return e});x.i.Sd.ia=function(a){a=new l.ba(a);var b=new x.i.Sd;return x.i.Sd.F(b,a)};\nx.i.Sd.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.Qb;b.T(c,x.i.Qb.F);a.ZR(c);break;case 2:c=new x.i.Ea;b.T(c,x.i.Ea.F);a.Eg(c);break;case 3:c=b.Aa();a.Jh(c);break;default:b.ea()}}return a};x.i.Sd.G=function(a,b){var c;c=a.gz();null!=c&&b.oa(1,c,x.i.Qb.G);c=a.bf();0<c.length&&b.Oa(2,c,x.i.Ea.G);c=l.u.D(a,3);null!=c&&b.Ja(3,c)};d=x.i.Sd.prototype;d.gz=function(){return l.u.sa(this,x.i.Qb,1)};d.ZR=function(a){l.u.Ca(this,1,a)};\nd.bf=function(){return l.u.Ma(this,x.i.Ea,2)};d.Eg=function(a,b){return l.u.La(this,2,a,x.i.Ea,b)};d.getError=function(){return l.u.D(this,3)};d.Jh=function(a){l.u.J(this,3,a)};x.i.Sd.K=function(a){return l.u.K(x.i.Sd,a)};x.i.wa=function(a){l.u.initialize(this,a,0,-1,x.i.wa.na,null)};h.da(x.i.wa,l.u);x.i.wa.na=[1,5,6];\nl.u.ha&&(x.i.wa.prototype.C=function(a){return x.i.wa.C(a,this)},x.i.wa.C=function(a,b){var c={yda:l.u.D(b,1),Vba:l.u.D(b,2),startTime:l.u.D(b,3),endTime:l.u.D(b,4),Cx:l.u.Ka(b.Zg(),x.i.wa.Qa.C,a),C5:l.u.Ka(b.Py(),x.i.wa.yd.C,a)};a&&(c.ja=b);return c});x.i.wa.ia=function(a){a=new l.ba(a);var b=new x.i.wa;return x.i.wa.F(b,a)};\nx.i.wa.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.CJ(c);break;case 2:c=b.Aa();a.XU(c);break;case 3:c=b.ee();a.vj(c);break;case 4:c=b.ee();a.sj(c);break;case 5:c=new x.i.wa.Qa;b.T(c,x.i.wa.Qa.F);a.sl(c);break;case 6:c=new x.i.wa.yd;b.T(c,x.i.wa.yd.F);a.cI(c);break;default:b.ea()}}return a};\nx.i.wa.G=function(a,b){var c;c=a.OM();0<c.length&&b.oc(1,c);c=l.u.D(a,2);null!=c&&b.Ja(2,c);c=l.u.D(a,3);null!=c&&b.ye(3,c);c=l.u.D(a,4);null!=c&&b.ye(4,c);c=a.Zg();0<c.length&&b.Oa(5,c,x.i.wa.Qa.G);c=a.Py();0<c.length&&b.Oa(6,c,x.i.wa.yd.G)};d=x.i.wa.prototype;d.OM=function(){return l.u.D(this,1)};d.CJ=function(a,b){l.u.ib(this,1,a,b)};d.XU=function(a){l.u.J(this,2,a)};d.getStartTime=function(){return l.u.D(this,3)};d.vj=function(a){l.u.J(this,3,a)};d.sj=function(a){l.u.J(this,4,a)};\nd.Zg=function(){return l.u.Ma(this,x.i.wa.Qa,5)};d.Us=function(a){l.u.mt(this,5,a)};d.sl=function(a,b){return l.u.La(this,5,a,x.i.wa.Qa,b)};d.Py=function(){return l.u.Ma(this,x.i.wa.yd,6)};d.cI=function(a,b){return l.u.La(this,6,a,x.i.wa.yd,b)};x.i.wa.K=function(a){return l.u.K(x.i.wa,a)};x.i.wa.Qa=function(a){l.u.initialize(this,a,0,-1,x.i.wa.Qa.na,null)};h.da(x.i.wa.Qa,l.u);x.i.wa.Qa.na=[6];\nl.u.ha&&(x.i.wa.Qa.prototype.C=function(a){return x.i.wa.Qa.C(a,this)},x.i.wa.Qa.C=function(a,b){var c,e={V5:l.u.D(b,1),D5:(c=b.Qy())&&x.i.wa.Qa.Uc.C(a,c),labels:(c=b.getLabels())&&x.i.wa.Qa.Uc.C(a,c),b8:l.u.Na(b,4),values:(c=b.Lc())&&x.i.wa.Qa.ue.C(a,c),n3:l.u.Ka(b.hy(),x.i.wa.Qa.ie.C,a)};a&&(e.ja=b);return e});x.i.wa.Qa.ia=function(a){a=new l.ba(a);var b=new x.i.wa.Qa;return x.i.wa.Qa.F(b,a)};\nx.i.wa.Qa.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.CR(c);break;case 2:c=new x.i.wa.Qa.Uc;b.T(c,x.i.wa.Qa.Uc.F);a.vR(c);break;case 3:c=new x.i.wa.Qa.Uc;b.T(c,x.i.wa.Qa.Uc.F);a.jS(c);break;case 4:c=b.pa();a.kS(c);break;case 5:c=new x.i.wa.Qa.ue;b.T(c,x.i.wa.Qa.ue.F);a.Yo(c);break;case 6:c=new x.i.wa.Qa.ie;b.T(c,x.i.wa.Qa.ie.F);a.GH(c);break;default:b.ea()}}return a};\nx.i.wa.Qa.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Ja(1,c);c=a.Qy();null!=c&&b.oa(2,c,x.i.wa.Qa.Uc.G);c=a.getLabels();null!=c&&b.oa(3,c,x.i.wa.Qa.Uc.G);c=l.u.D(a,4);null!=c&&b.ya(4,c);c=a.Lc();null!=c&&b.oa(5,c,x.i.wa.Qa.ue.G);c=a.hy();0<c.length&&b.Oa(6,c,x.i.wa.Qa.ie.G)};d=x.i.wa.Qa.prototype;d.Ah=function(){return l.u.D(this,1)};d.CR=function(a){l.u.J(this,1,a)};d.Qy=function(){return l.u.sa(this,x.i.wa.Qa.Uc,2)};d.vR=function(a){l.u.Ca(this,2,a)};\nd.getLabels=function(){return l.u.sa(this,x.i.wa.Qa.Uc,3)};d.jS=function(a){l.u.Ca(this,3,a)};d.kS=function(a){l.u.J(this,4,a)};d.Lc=function(){return l.u.sa(this,x.i.wa.Qa.ue,5)};d.Yo=function(a){l.u.Ca(this,5,a)};d.hy=function(){return l.u.Ma(this,x.i.wa.Qa.ie,6)};d.GH=function(a,b){return l.u.La(this,6,a,x.i.wa.Qa.ie,b)};x.i.wa.Qa.K=function(a){return l.u.K(x.i.wa.Qa,a)};x.i.wa.Qa.ie=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.wa.Qa.ie,l.u);\nl.u.ha&&(x.i.wa.Qa.ie.prototype.C=function(a){return x.i.wa.Qa.ie.C(a,this)},x.i.wa.Qa.ie.C=function(a,b){var c={UK:l.u.Na(b,1),gaa:l.u.Na(b,2)};a&&(c.ja=b);return c});x.i.wa.Qa.ie.ia=function(a){a=new l.ba(a);var b=new x.i.wa.Qa.ie;return x.i.wa.Qa.ie.F(b,a)};x.i.wa.Qa.ie.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.pa();a.Ts(c);break;case 2:c=b.pa();a.nU(c);break;default:b.ea()}}return a};\nx.i.wa.Qa.ie.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.ya(1,c);c=l.u.D(a,2);null!=c&&b.ya(2,c)};x.i.wa.Qa.ie.prototype.Ts=function(a){l.u.J(this,1,a)};x.i.wa.Qa.ie.prototype.nU=function(a){l.u.J(this,2,a)};x.i.wa.Qa.ie.K=function(a){return l.u.K(x.i.wa.Qa.ie,a)};x.i.wa.Qa.ue=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.wa.Qa.ue,l.u);\nl.u.ha&&(x.i.wa.Qa.ue.prototype.C=function(a){return x.i.wa.Qa.ue.C(a,this)},x.i.wa.Qa.ue.C=function(a,b){var c={sum:l.u.Na(b,1),Pw:l.u.Na(b,2),$ba:l.u.Na(b,3)};a&&(c.ja=b);return c});x.i.wa.Qa.ue.ia=function(a){a=new l.ba(a);var b=new x.i.wa.Qa.ue;return x.i.wa.Qa.ue.F(b,a)};x.i.wa.Qa.ue.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.pa();a.wj(c);break;case 2:c=b.pa();a.iQ(c);break;case 3:c=b.pa();a.$U(c);break;default:b.ea()}}return a};\nx.i.wa.Qa.ue.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.ya(1,c);c=l.u.D(a,2);null!=c&&b.ya(2,c);c=l.u.D(a,3);null!=c&&b.ya(3,c)};x.i.wa.Qa.ue.prototype.wj=function(a){l.u.J(this,1,a)};x.i.wa.Qa.ue.prototype.iQ=function(a){l.u.J(this,2,a)};x.i.wa.Qa.ue.prototype.$U=function(a){l.u.J(this,3,a)};x.i.wa.Qa.ue.K=function(a){return l.u.K(x.i.wa.Qa.ue,a)};x.i.wa.Qa.Uc=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.wa.Qa.Uc,l.u);\nl.u.ha&&(x.i.wa.Qa.Uc.prototype.C=function(a){return x.i.wa.Qa.Uc.C(a,this)},x.i.wa.Qa.Uc.C=function(a,b){var c={sum:l.u.Na(b,1),j6:l.u.Na(b,2),k6:l.u.Na(b,3)};a&&(c.ja=b);return c});x.i.wa.Qa.Uc.ia=function(a){a=new l.ba(a);var b=new x.i.wa.Qa.Uc;return x.i.wa.Qa.Uc.F(b,a)};x.i.wa.Qa.Uc.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.pa();a.wj(c);break;case 2:c=b.pa();a.GR(c);break;case 3:c=b.pa();a.HR(c);break;default:b.ea()}}return a};\nx.i.wa.Qa.Uc.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.ya(1,c);c=l.u.D(a,2);null!=c&&b.ya(2,c);c=l.u.D(a,3);null!=c&&b.ya(3,c)};x.i.wa.Qa.Uc.prototype.wj=function(a){l.u.J(this,1,a)};x.i.wa.Qa.Uc.prototype.GR=function(a){l.u.J(this,2,a)};x.i.wa.Qa.Uc.prototype.HR=function(a){l.u.J(this,3,a)};x.i.wa.Qa.Uc.K=function(a){return l.u.K(x.i.wa.Qa.Uc,a)};x.i.wa.yd=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.wa.yd,l.u);\nl.u.ha&&(x.i.wa.yd.prototype.C=function(a){return x.i.wa.yd.C(a,this)},x.i.wa.yd.C=function(a,b){var c={count:l.u.D(b,1),sum:l.u.Na(b,2),i6:l.u.Na(b,3)};a&&(c.ja=b);return c});x.i.wa.yd.ia=function(a){a=new l.ba(a);var b=new x.i.wa.yd;return x.i.wa.yd.F(b,a)};x.i.wa.yd.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Ya();a.SQ(c);break;case 2:c=b.pa();a.wj(c);break;case 3:c=b.pa();a.FR(c);break;default:b.ea()}}return a};\nx.i.wa.yd.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.$a(1,c);c=l.u.D(a,2);null!=c&&b.ya(2,c);c=l.u.D(a,3);null!=c&&b.ya(3,c)};x.i.wa.yd.prototype.zh=function(){return l.u.D(this,1)};x.i.wa.yd.prototype.SQ=function(a){l.u.J(this,1,a)};x.i.wa.yd.prototype.wj=function(a){l.u.J(this,2,a)};x.i.wa.yd.prototype.FR=function(a){l.u.J(this,3,a)};x.i.wa.yd.K=function(a){return l.u.K(x.i.wa.yd,a)};x.i.le=function(a){l.u.initialize(this,a,0,-1,x.i.le.na,null)};h.da(x.i.le,l.u);x.i.le.na=[7];\nl.u.ha&&(x.i.le.prototype.C=function(a){return x.i.le.C(a,this)},x.i.le.C=function(a,b){var c,e={G4:(c=b.zy())&&x.i.qe.C(a,c),M9:l.u.D(b,2),length:l.u.D(b,3),B9:l.u.D(b,4),i$:l.u.D(b,5),numColumns:l.u.D(b,6),b4:l.u.Ka(b.sy(),x.i.Link.C,a)};a&&(e.ja=b);return e});x.i.le.ia=function(a){a=new l.ba(a);var b=new x.i.le;return x.i.le.F(b,a)};\nx.i.le.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.qe;b.T(c,x.i.qe.F);a.ZQ(c);break;case 2:c=b.Ya();a.pT(c);break;case 3:c=b.ad();a.nS(c);break;case 4:c=b.ee();a.kT(c);break;case 5:c=b.ee();a.ET(c);break;case 6:c=b.Ya();a.mT(c);break;case 7:c=new x.i.Link;b.T(c,x.i.Link.F);a.LH(c);break;default:b.ea()}}return a};\nx.i.le.G=function(a,b){var c;c=a.zy();null!=c&&b.oa(1,c,x.i.qe.G);c=l.u.D(a,2);null!=c&&b.$a(2,c);c=l.u.D(a,3);null!=c&&b.td(3,c);c=l.u.D(a,4);null!=c&&b.ye(4,c);c=l.u.D(a,5);null!=c&&b.ye(5,c);c=l.u.D(a,6);null!=c&&b.$a(6,c);c=a.sy();0<c.length&&b.Oa(7,c,x.i.Link.G)};d=x.i.le.prototype;d.zy=function(){return l.u.sa(this,x.i.qe,1)};d.ZQ=function(a){l.u.Ca(this,1,a)};d.pT=function(a){l.u.J(this,2,a)};d.nS=function(a){l.u.J(this,3,a)};d.kT=function(a){l.u.J(this,4,a)};\nd.ET=function(a){l.u.J(this,5,a)};d.mT=function(a){l.u.J(this,6,a)};d.sy=function(){return l.u.Ma(this,x.i.Link,7)};d.LH=function(a,b){return l.u.La(this,7,a,x.i.Link,b)};x.i.le.K=function(a){return l.u.K(x.i.le,a)};x.i.Df=function(a){l.u.initialize(this,a,0,-1,x.i.Df.na,null)};h.da(x.i.Df,l.u);x.i.Df.na=[3,4];\nl.u.ha&&(x.i.Df.prototype.C=function(a){return x.i.Df.C(a,this)},x.i.Df.C=function(a,b){var c,e={name:l.u.D(b,1),Zq:l.u.D(b,2),UN:l.u.Ka(b.Vl(),x.i.Link.C,a),qO:l.u.D(b,4),gx:(c=b.qy())&&x.i.le.C(a,c)};a&&(e.ja=b);return e});x.i.Df.ia=function(a){a=new l.ba(a);var b=new x.i.Df;return x.i.Df.F(b,a)};\nx.i.Df.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.fe(c);break;case 2:c=b.Aa();a.rj(c);break;case 3:c=new x.i.Link;b.T(c,x.i.Link.F);a.Qq(c);break;case 4:c=b.Aa();a.Rq(c);break;case 5:c=new x.i.le;b.T(c,x.i.le.F);a.MQ(c);break;default:b.ea()}}return a};x.i.Df.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Ja(1,c);c=l.u.D(a,2);null!=c&&b.Ja(2,c);c=a.Vl();0<c.length&&b.Oa(3,c,x.i.Link.G);c=a.Ir();0<c.length&&b.oc(4,c);c=a.qy();null!=c&&b.oa(5,c,x.i.le.G)};d=x.i.Df.prototype;\nd.getName=function(){return l.u.D(this,1)};d.fe=function(a){l.u.J(this,1,a)};d.Jl=function(){return l.u.D(this,2)};d.rj=function(a){l.u.J(this,2,a)};d.Vl=function(){return l.u.Ma(this,x.i.Link,3)};d.Qq=function(a,b){return l.u.La(this,3,a,x.i.Link,b)};d.Ir=function(){return l.u.D(this,4)};d.Rq=function(a,b){l.u.ib(this,4,a,b)};d.qy=function(){return l.u.sa(this,x.i.le,5)};d.MQ=function(a){l.u.Ca(this,5,a)};x.i.Df.K=function(a){return l.u.K(x.i.Df,a)};\nx.i.Da=function(a){l.u.initialize(this,a,0,-1,x.i.Da.na,null)};h.da(x.i.Da,l.u);x.i.Da.na=[1,2];l.u.ha&&(x.i.Da.prototype.C=function(a){return x.i.Da.C(a,this)},x.i.Da.C=function(a,b){var c,e={V7:l.u.Ka(b.kz(),x.i.Da.ld.C,a),K4:l.u.Ka(b.Dy(),x.i.Da.fd.C,a),rba:(c=b.qA())&&x.i.Da.Ad.C(a,c)};a&&(e.ja=b);return e});x.i.Da.ia=function(a){a=new l.ba(a);var b=new x.i.Da;return x.i.Da.F(b,a)};\nx.i.Da.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.Da.ld;b.T(c,x.i.Da.ld.F);a.uI(c);break;case 2:c=new x.i.Da.fd;b.T(c,x.i.Da.fd.F);a.RH(c);break;case 3:c=new x.i.Da.Ad;b.T(c,x.i.Da.Ad.F);a.GU(c);break;default:b.ea()}}return a};x.i.Da.G=function(a,b){var c;c=a.kz();0<c.length&&b.Oa(1,c,x.i.Da.ld.G);c=a.Dy();0<c.length&&b.Oa(2,c,x.i.Da.fd.G);c=a.qA();null!=c&&b.oa(3,c,x.i.Da.Ad.G)};d=x.i.Da.prototype;d.kz=function(){return l.u.Ma(this,x.i.Da.ld,1)};\nd.uI=function(a,b){return l.u.La(this,1,a,x.i.Da.ld,b)};d.Dy=function(){return l.u.Ma(this,x.i.Da.fd,2)};d.RH=function(a,b){return l.u.La(this,2,a,x.i.Da.fd,b)};d.qA=function(){return l.u.sa(this,x.i.Da.Ad,3)};d.GU=function(a){l.u.Ca(this,3,a)};x.i.Da.K=function(a){return l.u.K(x.i.Da,a)};x.i.Da.sc=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.Da.sc,l.u);\nl.u.ha&&(x.i.Da.sc.prototype.C=function(a){return x.i.Da.sc.C(a,this)},x.i.Da.sc.C=function(a,b){var c,e={state:l.u.D(b,1),uba:l.u.D(b,2),n8:l.u.D(b,3),link:(c=b.pz())&&x.i.Link.C(a,c)};a&&(e.ja=b);return e});x.i.Da.sc.ia=function(a){a=new l.ba(a);var b=new x.i.Da.sc;return x.i.Da.sc.F(b,a)};\nx.i.Da.sc.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.we();a.setState(c);break;case 2:c=b.Aa();a.HU(c);break;case 3:c=b.Aa();a.rS(c);break;case 4:c=new x.i.Link;b.T(c,x.i.Link.F);a.oS(c);break;default:b.ea()}}return a};x.i.Da.sc.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.xe(1,c);c=l.u.D(a,2);null!=c&&b.Ja(2,c);c=l.u.D(a,3);null!=c&&b.Ja(3,c);c=a.pz();null!=c&&b.oa(4,c,x.i.Link.G)};d=x.i.Da.sc.prototype;d.getState=function(){return l.u.D(this,1)};\nd.setState=function(a){l.u.J(this,1,a)};d.HU=function(a){l.u.J(this,2,a)};d.rS=function(a){l.u.J(this,3,a)};d.pz=function(){return l.u.sa(this,x.i.Link,4)};d.oS=function(a){l.u.Ca(this,4,a)};x.i.Da.sc.K=function(a){return l.u.K(x.i.Da.sc,a)};x.i.Da.sc.$Z={YX:0,n_:1,AX:2,pX:3,LY:4};x.i.Da.ld=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.Da.ld,l.u);\nl.u.ha&&(x.i.Da.ld.prototype.C=function(a){return x.i.Da.ld.C(a,this)},x.i.Da.ld.C=function(a,b){var c,e={type:l.u.D(b,1),BC:(c=b.li())&&x.i.Da.sc.C(a,c)};a&&(e.ja=b);return e});x.i.Da.ld.ia=function(a){a=new l.ba(a);var b=new x.i.Da.ld;return x.i.Da.ld.F(b,a)};x.i.Da.ld.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.we();a.yf(c);break;case 2:c=new x.i.Da.sc;b.T(c,x.i.Da.sc.F);a.Am(c);break;default:b.ea()}}return a};\nx.i.Da.ld.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.xe(1,c);c=a.li();null!=c&&b.oa(2,c,x.i.Da.sc.G)};x.i.Da.ld.prototype.mi=function(){return l.u.D(this,1)};x.i.Da.ld.prototype.yf=function(a){l.u.J(this,1,a)};x.i.Da.ld.prototype.li=function(){return l.u.sa(this,x.i.Da.sc,2)};x.i.Da.ld.prototype.Am=function(a){l.u.Ca(this,2,a)};x.i.Da.ld.K=function(a){return l.u.K(x.i.Da.ld,a)};x.i.Da.ld.rY={JZ:0,h_:1,MX:2,SD:3,OY:4,CX:5,jX:6};x.i.Da.fd=function(a){l.u.initialize(this,a,0,-1,null,null)};\nh.da(x.i.Da.fd,l.u);l.u.ha&&(x.i.Da.fd.prototype.C=function(a){return x.i.Da.fd.C(a,this)},x.i.Da.fd.C=function(a,b){var c,e={type:l.u.D(b,1),BC:(c=b.li())&&x.i.Da.sc.C(a,c)};a&&(e.ja=b);return e});x.i.Da.fd.ia=function(a){a=new l.ba(a);var b=new x.i.Da.fd;return x.i.Da.fd.F(b,a)};x.i.Da.fd.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.we();a.yf(c);break;case 2:c=new x.i.Da.sc;b.T(c,x.i.Da.sc.F);a.Am(c);break;default:b.ea()}}return a};\nx.i.Da.fd.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.xe(1,c);c=a.li();null!=c&&b.oa(2,c,x.i.Da.sc.G)};x.i.Da.fd.prototype.mi=function(){return l.u.D(this,1)};x.i.Da.fd.prototype.yf=function(a){l.u.J(this,1,a)};x.i.Da.fd.prototype.li=function(){return l.u.sa(this,x.i.Da.sc,2)};x.i.Da.fd.prototype.Am=function(a){l.u.Ca(this,2,a)};x.i.Da.fd.K=function(a){return l.u.K(x.i.Da.fd,a)};x.i.Da.fd.lD={KZ:0,HY:1,NZ:2,OZ:3,GX:4,MZ:5};x.i.Da.Ad=function(a){l.u.initialize(this,a,0,-1,null,null)};\nh.da(x.i.Da.Ad,l.u);l.u.ha&&(x.i.Da.Ad.prototype.C=function(a){return x.i.Da.Ad.C(a,this)},x.i.Da.Ad.C=function(a,b){var c,e={type:l.u.D(b,1),BC:(c=b.li())&&x.i.Da.sc.C(a,c)};a&&(e.ja=b);return e});x.i.Da.Ad.ia=function(a){a=new l.ba(a);var b=new x.i.Da.Ad;return x.i.Da.Ad.F(b,a)};x.i.Da.Ad.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.we();a.yf(c);break;case 2:c=new x.i.Da.sc;b.T(c,x.i.Da.sc.F);a.Am(c);break;default:b.ea()}}return a};\nx.i.Da.Ad.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.xe(1,c);c=a.li();null!=c&&b.oa(2,c,x.i.Da.sc.G)};x.i.Da.Ad.prototype.mi=function(){return l.u.D(this,1)};x.i.Da.Ad.prototype.yf=function(a){l.u.J(this,1,a)};x.i.Da.Ad.prototype.li=function(){return l.u.sa(this,x.i.Da.sc,2)};x.i.Da.Ad.prototype.Am=function(a){l.u.Ca(this,2,a)};x.i.Da.Ad.K=function(a){return l.u.K(x.i.Da.Ad,a)};x.i.Da.Ad.UZ={BY:0,RX:1,iX:2};x.i.jd=function(a){l.u.initialize(this,a,0,-1,x.i.jd.na,null)};h.da(x.i.jd,l.u);\nx.i.jd.na=[1];l.u.ha&&(x.i.jd.prototype.C=function(a){return x.i.jd.C(a,this)},x.i.jd.C=function(a,b){var c={Zba:l.u.D(b,1),state:l.u.D(b,2)};a&&(c.ja=b);return c});x.i.jd.ia=function(a){a=new l.ba(a);var b=new x.i.jd;return x.i.jd.F(b,a)};x.i.jd.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.lJ(c);break;case 2:c=b.Aa();a.setState(c);break;default:b.ea()}}return a};x.i.jd.G=function(a,b){var c;c=a.uM();0<c.length&&b.oc(1,c);c=l.u.D(a,2);null!=c&&b.Ja(2,c)};\nx.i.jd.prototype.uM=function(){return l.u.D(this,1)};x.i.jd.prototype.lJ=function(a,b){l.u.ib(this,1,a,b)};x.i.jd.prototype.getState=function(){return l.u.D(this,2)};x.i.jd.prototype.setState=function(a){l.u.J(this,2,a)};x.i.jd.K=function(a){return l.u.K(x.i.jd,a)};x.i.Ee=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.Ee,l.u);\nl.u.ha&&(x.i.Ee.prototype.C=function(a){return x.i.Ee.C(a,this)},x.i.Ee.C=function(a,b){var c,e={Sba:(c=b.xA())&&x.i.Hc.C(a,c),u5:l.u.D(b,2),k5:(c=b.Jy())&&x.i.jd.C(a,c)};a&&(e.ja=b);return e});x.i.Ee.ia=function(a){a=new l.ba(a);var b=new x.i.Ee;return x.i.Ee.F(b,a)};x.i.Ee.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.Hc;b.T(c,x.i.Hc.F);a.UU(c);break;case 2:c=b.Aa();a.rR(c);break;case 3:c=new x.i.jd;b.T(c,x.i.jd.F);a.nR(c);break;default:b.ea()}}return a};\nx.i.Ee.G=function(a,b){var c;c=a.xA();null!=c&&b.oa(1,c,x.i.Hc.G);c=l.u.D(a,2);null!=c&&b.Ja(2,c);c=a.Jy();null!=c&&b.oa(3,c,x.i.jd.G)};d=x.i.Ee.prototype;d.xA=function(){return l.u.sa(this,x.i.Hc,1)};d.UU=function(a){l.u.Ca(this,1,a)};d.rR=function(a){l.u.J(this,2,a)};d.Jy=function(){return l.u.sa(this,x.i.jd,3)};d.nR=function(a){l.u.Ca(this,3,a)};x.i.Ee.K=function(a){return l.u.K(x.i.Ee,a)};x.i.Ve=function(a){l.u.initialize(this,a,0,-1,x.i.Ve.na,null)};h.da(x.i.Ve,l.u);x.i.Ve.na=[1];\nl.u.ha&&(x.i.Ve.prototype.C=function(a){return x.i.Ve.C(a,this)},x.i.Ve.C=function(a,b){var c={NN:l.u.Ka(b.Ul(),x.i.Ee.C,a),error:l.u.D(b,2)};a&&(c.ja=b);return c});x.i.Ve.ia=function(a){a=new l.ba(a);var b=new x.i.Ve;return x.i.Ve.F(b,a)};x.i.Ve.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.Ee;b.T(c,x.i.Ee.F);a.Pq(c);break;case 2:c=b.Aa();a.Jh(c);break;default:b.ea()}}return a};\nx.i.Ve.G=function(a,b){var c;c=a.Ul();0<c.length&&b.Oa(1,c,x.i.Ee.G);c=l.u.D(a,2);null!=c&&b.Ja(2,c)};x.i.Ve.prototype.Ul=function(){return l.u.Ma(this,x.i.Ee,1)};x.i.Ve.prototype.Pq=function(a,b){return l.u.La(this,1,a,x.i.Ee,b)};x.i.Ve.prototype.getError=function(){return l.u.D(this,2)};x.i.Ve.prototype.Jh=function(a){l.u.J(this,2,a)};x.i.Ve.K=function(a){return l.u.K(x.i.Ve,a)};x.i.bb=function(a){l.u.initialize(this,a,0,-1,x.i.bb.na,null)};h.da(x.i.bb,l.u);x.i.bb.na=[3,4];\nl.u.ha&&(x.i.bb.prototype.C=function(a){return x.i.bb.C(a,this)},x.i.bb.C=function(a,b){var c={tca:l.u.D(b,1),g5:l.u.D(b,2),d5:l.u.D(b,3),Oaa:l.u.Ka(b.jA(),x.i.bb.zb.C,a)};a&&(c.ja=b);return c});x.i.bb.ia=function(a){a=new l.ba(a);var b=new x.i.bb;return x.i.bb.F(b,a)};x.i.bb.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.fV(c);break;case 2:c=b.Aa();a.mR(c);break;case 3:c=b.Aa();a.WH(c);break;case 4:c=new x.i.bb.zb;b.T(c,x.i.bb.zb.F);a.addRows(c);break;default:b.ea()}}return a};\nx.i.bb.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Ja(1,c);c=l.u.D(a,2);null!=c&&b.Ja(2,c);c=a.uL();0<c.length&&b.oc(3,c);c=a.jA();0<c.length&&b.Oa(4,c,x.i.bb.zb.G)};d=x.i.bb.prototype;d.fV=function(a){l.u.J(this,1,a)};d.mR=function(a){l.u.J(this,2,a)};d.uL=function(){return l.u.D(this,3)};d.WH=function(a,b){l.u.ib(this,3,a,b)};d.jA=function(){return l.u.Ma(this,x.i.bb.zb,4)};d.addRows=function(a,b){return l.u.La(this,4,a,x.i.bb.zb,b)};x.i.bb.K=function(a){return l.u.K(x.i.bb,a)};\nx.i.bb.zb=function(a){l.u.initialize(this,a,0,-1,x.i.bb.zb.na,null)};h.da(x.i.bb.zb,l.u);x.i.bb.zb.na=[2];l.u.ha&&(x.i.bb.zb.prototype.C=function(a){return x.i.bb.zb.C(a,this)},x.i.bb.zb.C=function(a,b){var c={f5:l.u.D(b,1),r5:l.u.Ka(b.Ly(),x.i.bb.zb.Ld.C,a)};a&&(c.ja=b);return c});x.i.bb.zb.ia=function(a){a=new l.ba(a);var b=new x.i.bb.zb;return x.i.bb.zb.F(b,a)};\nx.i.bb.zb.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.lR(c);break;case 2:c=new x.i.bb.zb.Ld;b.T(c,x.i.bb.zb.Ld.F);a.ZH(c);break;default:b.ea()}}return a};x.i.bb.zb.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Ja(1,c);c=a.Ly();0<c.length&&b.Oa(2,c,x.i.bb.zb.Ld.G)};x.i.bb.zb.prototype.lR=function(a){l.u.J(this,1,a)};x.i.bb.zb.prototype.Ly=function(){return l.u.Ma(this,x.i.bb.zb.Ld,2)};x.i.bb.zb.prototype.ZH=function(a,b){return l.u.La(this,2,a,x.i.bb.zb.Ld,b)};\nx.i.bb.zb.K=function(a){return l.u.K(x.i.bb.zb,a)};x.i.bb.zb.Ld=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.bb.zb.Ld,l.u);l.u.ha&&(x.i.bb.zb.Ld.prototype.C=function(a){return x.i.bb.zb.Ld.C(a,this)},x.i.bb.zb.Ld.C=function(a,b){var c={aj:l.u.D(b,1),UK:l.u.D(b,2)};a&&(c.ja=b);return c});x.i.bb.zb.Ld.ia=function(a){a=new l.ba(a);var b=new x.i.bb.zb.Ld;return x.i.bb.zb.Ld.F(b,a)};\nx.i.bb.zb.Ld.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.xf(c);break;case 2:c=b.Aa();a.Ts(c);break;default:b.ea()}}return a};x.i.bb.zb.Ld.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Ja(1,c);c=l.u.D(a,2);null!=c&&b.Ja(2,c)};x.i.bb.zb.Ld.prototype.Hg=function(){return l.u.D(this,1)};x.i.bb.zb.Ld.prototype.xf=function(a){l.u.J(this,1,a)};x.i.bb.zb.Ld.prototype.Ts=function(a){l.u.J(this,2,a)};x.i.bb.zb.Ld.K=function(a){return l.u.K(x.i.bb.zb.Ld,a)};D.data.Ua={};\nD.data.Ua.Xu={RD:\"k\",HE:\"totalPositives\",Li:\"value\"};D.data.Ua.Up={OE:0,FLOAT:1,op:2,Uk:3,an:4,Gp:5};D.data.Ua.pp={zu:\"lowerBound\",gv:\"upperBound\",Li:\"value\"};D.data.Ua.AP=function(a,b){var c=D.data.Ua.pp,c=a[c.Li]-b[c.Li];return{f:D.data.Ua.lx(a,b,c,\"bounded-value\"),v:c}};D.data.Ua.GP=function(a,b){var c=Math.min(a.length,b.length)-1,e=D.data.Ua.Lr(a,c)-D.data.Ua.Lr(b,c);return{f:D.data.Ua.lx([a[c]],[b[c]],e,\"precision-at-k\"),v:e}};D.data.Ua.Lr=function(a,b){var c=D.data.Ua.Xu;return a[b][c.Li]};\nD.data.Ua.CP=function(a,b){return D.data.Ua.jC(a-b,a,b)};D.data.Ua.jC=function(a,b,c){return{f:D.data.Ua.mx(D.data.Ua.ui(b),D.data.Ua.ui(c),D.data.Ua.ui(a)),v:a}};D.data.Ua.mx=function(a,b,c,e){return\"\\x3cmetric-diff diff\\x3d\"+c+\" \"+D.data.Ua.mr(\"first\",a)+\" \"+D.data.Ua.mr(\"second\",b)+(e?\" type\\x3d\"+e:\"\")+\"\\x3e\\x3c/metric-diff\\x3e\"};D.data.Ua.lx=function(a,b,c,e){return D.data.Ua.mx(JSON.stringify(a),JSON.stringify(b),D.data.Ua.ui(c),e)};D.data.Ua.mr=function(a,b){return a+'\\x3d\"'+h.ca.$r(b)+'\"'};\nD.data.Ua.lC=function(a){return{f:\"Unsupported: \"+JSON.stringify(a),v:0}};D.data.Ua.iC=function(a){return{f:D.data.Ua.ui(a),v:a}};D.data.Ua.DP=function(a){return{f:\"\"+a,v:a}};D.data.Ua.HP=function(a){var b=a.lastIndexOf(\"_\")>a.lastIndexOf(\":\")?\"_\":\":\",b=a.split(b),b=1<b.length?parseFloat(b[b.length-1]):NaN;return{f:a,v:isNaN(b)?a:b}};D.data.Ua.kC=function(a){return{f:a,v:a}};\nD.data.Ua.zP=function(a){var b=D.data.Ua.pp,c=a[b.Li];return{f:\"\\x3cbounded-value value\\x3d\"+D.data.Ua.ui(c)+\" lower-bound\\x3d\"+D.data.Ua.ui(a[b.zu])+\" upper-bound\\x3d\"+D.data.Ua.ui(a[b.gv])+\"\\x3e\\x3c/bounded-value\\x3e\",v:c}};D.data.Ua.Caa=function(){return{f:\"Null\",v:0}};D.data.Ua.ui=function(a){return a.toFixed(D.Nh)};D.data.Ua.FP=function(a){return{f:\"\\x3cprecision-at-k \"+D.data.Ua.mr(\"data\",JSON.stringify(a))+\"\\x3e\\x3c/precision-at-k\\x3e\",v:D.data.Ua.Lr(a,0)}};\nD.data.Ua.mC=function(a){var b=D.data.Ua.Up;switch(D.data.Ua.WA(a)){case b.op:return D.data.Ua.zP(a);case b.FLOAT:return D.data.Ua.iC(a);case b.Uk:return D.data.Ua.kC(a);case b.an:return D.data.Ua.IP(a.first,a.second,a.R$);case b.Gp:return D.data.Ua.FP(a);default:return h.Ch(a)?D.data.Ua.lC(a):{f:\"Null\",v:0}}};\nD.data.Ua.IP=function(a,b,c){var e=D.data.Ua.Up;switch(D.data.Ua.WA(a)){case e.op:return D.data.Ua.AP(a,b);case e.Gp:return D.data.Ua.GP(a,b);case e.FLOAT:return h.Pe(c)?D.data.Ua.jC(c,a,b):D.data.Ua.CP(a,b);default:return h.Ch(a)&&h.Ch(b)?D.data.Ua.lC({A:a,B:b}):{f:\"Null\",v:0}}};\nD.data.Ua.WA=function(a){var b=D.data.Ua.Up,c=D.data.Ua.pp;if(h.ni(a))return b.FLOAT;if(h.Hb(a))return b.Uk;if(h.mj(a)){if(h.Pe(a[c.zu])&&h.Pe(a[c.gv])&&h.Pe(a[c.Li]))return b.op;if(h.Pe(a.first)&&h.Pe(a.second))return b.an;if(D.data.Ua.BN(a))return b.Gp}return b.OE};D.data.Ua.BN=function(a){var b=D.data.Ua.Xu;if(Array.isArray(a)){for(var c=0<a.length,e=0,g;c&&(g=a[e]);e++)c=g[b.RD]&&g[b.HE]&&h.Ch(g[b.Li]);return c}return!1};\nD.data.Ua.JP=function(a,b,c){return h.Ch(a)?c?D.data.Ua.KP(b.Gw(a,c),c.type):D.data.Ua.mC(a):{f:\"Null\",v:0}};D.data.Ua.KP=function(a,b){var c=D.Pk;switch(b){case c.Mp:return D.data.Ua.HP(a);case c.INT:return D.data.Ua.DP(a);case c.FLOAT:return D.data.Ua.iC(a);case c.an:return D.data.Ua.mC(a);default:return D.data.Ua.kC(a)}};\nPolymer({is:\"gviz-loader\",properties:{staticState_:{type:Object,value:{ms:0,bB:0,CB:[],cB:[]}}},Io:function(a){var b=this;window.google&&window.google.load?(this.staticState_.ms=1,this.GB(a)):(this.staticState_.CB.push(a),this.staticState_.ms||(this.staticState_.ms=1,window.__googleApiLoaderCallbackForGvizLoader=function(){b.staticState_.CB.forEach(function(a){b.GB(a)})},a=document.createElement(\"script\"),a.type=\"text/javascript\",a.async=!0,a.src=\"https://www.google.com/jsapi?callback\\x3d__googleApiLoaderCallbackForGvizLoader\",\ndocument.head.appendChild(a)))},GB:function(a){var b=this;window.google&&window.google.visualization&&window.google.visualization.ColumnChart?a():(this.staticState_.cB.push(a),this.staticState_.bB||(this.staticState_.bB=1,window.google.load(\"visualization\",\"1\",{packages:[\"corechart\",\"table\"],callback:function(){b.staticState_.cB.forEach(function(a){a()})}})))},load:function(a){this.Io(function(){a&&a()})},create:function(a,b){var c=this;return{then:function(a){c.Io(function(){b?a(new google.visualization.ColumnChart(b)):\na()})}}},Dl:function(a){var b=this;return{then:function(c){b.Io(function(){c(google.visualization.arrayToDataTable(a))})}}},no:function(a){var b=this;return{then:function(c){b.Io(function(){c(new google.visualization.DataView(a))})}}}});var V={Ij:{}};V.Ij.Ij={};V.Ph={};V.Ph.Ph={};\n(function(){var a={},b={},c=null;Polymer.Ph=function(a){if(a)for(var b in a)switch(b){case \"type\":case \"key\":case \"value\":this[b]=a[b]}};Polymer.Ph=Polymer({is:\"iron-meta\",properties:{type:{type:String,value:\"default\",observer:\"xw\"},key:{type:String,observer:\"Qv\"},value:{type:Object,notify:!0,observer:\"Iq\"},self:{type:Boolean,observer:\"s1\"},list:{type:Array,notify:!0}},hostAttributes:{hidden:!0},factoryImpl:function(a){if(a)for(var b in a)switch(b){case \"type\":case \"key\":case \"value\":this[b]=a[b]}},\ncreated:function(){this.mG=a;this.lG=b},Qv:function(a,b){this.jw(b)},Iq:function(){this.jw(this.key)},s1:function(a){a&&(this.value=this)},xw:function(c){this.yw(this.key);a[c]||(a[c]={});this.th=a[c];b[c]||(b[c]=[]);this.list=b[c];this.gw(this.key,this.value)},er:function(a){return this.th&&this.th[a]},jw:function(a){this.yw(a);this.gw(this.key,this.value)},yw:function(a){this.gH(a,this.th,this.list)},gw:function(a,b){this.Zh(a,b,this.th,this.list)},Zh:function(a,b,c,m){a&&c&&void 0!==b&&(c[a]=b,\nm.push(b))},gH:function(a,b,c){if(a&&b&&a in b){var e=b[a];delete b[a];this.arrayDelete(c,e)}}});Polymer.Ph.y6=function(){null===c&&(c=new Polymer.Ph);return c};Polymer.tu=function(a){if(a)for(var b in a)switch(b){case \"type\":case \"key\":this[b]=a[b]}};Polymer.tu.prototype._setValue=function(){};Polymer.tu=Polymer({is:\"iron-meta-query\",properties:{type:{type:String,value:\"default\",observer:\"xw\"},key:{type:String,observer:\"Qv\"},value:{type:Object,notify:!0,readOnly:!0},list:{type:Array,notify:!0}},\nfactoryImpl:function(a){if(a)for(var b in a)switch(b){case \"type\":case \"key\":this[b]=a[b]}},created:function(){this.mG=a;this.lG=b},Qv:function(a){this._setValue(this.th&&this.th[a])},xw:function(c){this.th=a[c];this.list=b[c];this.key&&this.Qv(this.key)},er:function(a){return this.th&&this.th[a]}})})();V.pu={};V.pu.pu={};\nPolymer({is:\"iron-icon\",properties:{icon:{type:String},theme:{type:String},src:{type:String},_meta:{value:Polymer.Base.create(\"iron-meta\",{type:\"iconset\"})}},observers:[\"Aw(_meta,isAttached)\",\"Aw(theme,isAttached)\",\"YG(src,isAttached)\",\"u0(icon,isAttached)\"],bF:\"icons\",u0:function(a){a=(a||\"\").split(\":\");this.Mv=a.pop();this.Nv=a.pop()||this.bF;this.Aw()},YG:function(){this.Aw()},mH:function(){return this.icon||!this.src},Aw:function(){this.mH()?(this.rh&&this.rh.parentNode&&Polymer.dom(this.root).removeChild(this.rh),\n\"\"===this.Mv?this.Qj&&this.Qj.removeIcon(this):this.Nv&&this._meta&&((this.Qj=this._meta.er(this.Nv))?(this.Qj.applyIcon(this,this.Mv,this.theme),this.unlisten(window,\"iron-iconset-added\",\"Aw\")):this.listen(window,\"iron-iconset-added\",\"Aw\"))):(this.Qj&&this.Qj.removeIcon(this),this.rh||(this.rh=document.createElement(\"img\"),this.rh.style.width=\"100%\",this.rh.style.height=\"100%\",this.rh.draggable=!1),this.rh.src=this.src,Polymer.dom(this.root).appendChild(this.rh))}});V.qu={};V.qu.qu={};\nPolymer({is:\"iron-iconset-svg\",properties:{name:{type:String,observer:\"H0\"},size:{type:Number,value:24},rtlMirroring:{type:Boolean,value:!1}},attached:function(){this.style.display=\"none\"},v6:function(){this.En=this.Dv();return Object.keys(this.En).map(function(a){return this.name+\":\"+a},this)},applyIcon:function(a,b){a=a.root||a;this.removeIcon(a);if(b=this.oF(b,this.rtlMirroring&&this.ZG(a))){var c=Polymer.dom(a);c.insertBefore(b,c.childNodes[0]);return a.Cq=b}return null},removeIcon:function(a){a=\na.root||a;a.Cq&&(Polymer.dom(a).removeChild(a.Cq),a.Cq=null)},ZG:function(a){null==this.nv&&(a&&a.nodeType!==Node.ELEMENT_NODE&&(a=a.host),this.nv=a&&\"rtl\"===window.getComputedStyle(a).direction);return this.nv},H0:function(){new Polymer.Ph({type:\"iconset\",key:this.name,value:this});this.async(function(){this.fire(\"iron-iconset-added\",this,{node:window})})},Dv:function(){var a=Object.create(null);Polymer.dom(this).querySelectorAll(\"[id]\").forEach(function(b){a[b.id]=b});return a},oF:function(a,b){this.En=\nthis.En||this.Dv();return this.IG(this.En[a],this.size,b)},IG:function(a,b,c){if(a){a=a.cloneNode(!0);var e=document.createElementNS(\"http://www.w3.org/2000/svg\",\"svg\");b=a.getAttribute(\"viewBox\")||\"0 0 \"+b+\" \"+b;var g=\"pointer-events: none; display: block; width: 100%; height: 100%;\";c&&a.hasAttribute(\"mirror-in-rtl\")&&(g+=\"-webkit-transform:scale(-1,1);transform:scale(-1,1);\");e.setAttribute(\"viewBox\",b);e.setAttribute(\"preserveAspectRatio\",\"xMidYMid meet\");e.style.cssText=g;e.appendChild(a).removeAttribute(\"id\");\nreturn e}return null}});V.og={};V.og.YW={};V.og.nX={};V.og.vX={};V.og.HX={};V.og.dY={};V.og.lY={};V.og.og={};V.og.QY={};V.og.XY={};V.og.AZ={};V.og.XZ={};V.Jj={};V.Jj.Jj={};\nPolymer.Jj={properties:{_parentResizable:{type:Object,observer:\"c1\"},_notifyingDescendant:{type:Boolean,value:!1}},listeners:{\"iron-request-resize-notifications\":\"T0\"},created:function(){this.fl=[];this.cq=this.ri.bind(this)},attached:function(){this.fire(\"iron-request-resize-notifications\",null,{node:this,bubbles:!0,cancelable:!0});this._parentResizable||(window.addEventListener(\"resize\",this.cq),this.ri())},detached:function(){this._parentResizable?this._parentResizable.jW(this):window.removeEventListener(\"resize\",\nthis.cq);this._parentResizable=null},ri:function(){this.isAttached&&(this.fl.forEach(function(a){this.Wv(a)},this),this.Jv())},PJ:function(a){this._parentResizable=a},jW:function(a){var b=this.fl.indexOf(a);-1<b&&(this.fl.splice(b,1),this.unlisten(a,\"iron-resize\",\"L0\"))},Faa:function(){return!0},L0:function(a){this._notifyingDescendant?a.stopPropagation():Polymer.Settings.useShadow||this.Jv()},Jv:function(){this.fire(\"iron-resize\",null,{node:this,bubbles:!1})},T0:function(a){var b=a.path?a.path[0]:\na.target;b!==this&&(-1===this.fl.indexOf(b)&&(this.fl.push(b),this.listen(b,\"iron-resize\",\"L0\")),b.PJ(this),this.Wv(b),a.stopPropagation())},c1:function(a){a&&window.removeEventListener(\"resize\",this.cq)},Wv:function(a){this.isAttached&&(this._notifyingDescendant=!0,a.ri(),this._notifyingDescendant=!1)}};V.mg={};V.mg.mg={};\n(function(){function a(a,b){var c=\"\";if(a)if(a=a.toLowerCase(),\" \"===a||B.test(a))c=\"space\";else if(C.test(a))c=\"esc\";else if(1==a.length){if(!b||n.test(a))c=a}else c=v.test(a)?a.replace(\"arrow\",\"\"):\"multiply\"==a?\"*\":a;return c}function b(b,c){var e;e=c;var n=b.zo,m;if(!(m=a(e.key,n))){m=e.keyIdentifier;var v=\"\";m&&(m in g?v=g[m]:q.test(m)?(m=parseInt(m.replace(\"U+\",\"0x\"),16),v=String.fromCharCode(m).toLowerCase()):v=m.toLowerCase());m=v}m||(m=e.keyCode,v=\"\",Number(m)&&(v=65<=m&&90>=m?String.fromCharCode(32+\nm):112<=m&&123>=m?\"f\"+(m-112):48<=m&&57>=m?String(m-48):96<=m&&105>=m?String(m-96):k[m]),m=v);e=m||a(e.detail?e.detail.key:e.detail,n)||\"\";return e===b.key&&(!b.zo||!!c.shiftKey===!!b.shiftKey&&!!c.ctrlKey===!!b.ctrlKey&&!!c.altKey===!!b.altKey&&!!c.metaKey===!!b.metaKey)}function c(a){return 1===a.length?{lK:a,key:a,event:\"keydown\"}:a.split(\"+\").reduce(function(a,b){var c=b.split(\":\");b=c[0];c=c[1];b in m?(a[m[b]]=!0,a.zo=!0):(a.key=b,a.event=c||\"keydown\");return a},{lK:a.split(\":\").shift()})}function e(a){return a.trim().split(\" \").map(function(a){return c(a)})}\nvar g={\"U+0008\":\"backspace\",\"U+0009\":\"tab\",\"U+001B\":\"esc\",\"U+0020\":\"space\",\"U+007F\":\"del\"},k={8:\"backspace\",9:\"tab\",13:\"enter\",27:\"esc\",33:\"pageup\",34:\"pagedown\",35:\"end\",36:\"home\",32:\"space\",37:\"left\",38:\"up\",39:\"right\",40:\"down\",46:\"del\",106:\"*\"},m={shift:\"shiftKey\",ctrl:\"ctrlKey\",alt:\"altKey\",meta:\"metaKey\"},n=/[a-z0-9*]/,q=/U\\+/,v=/^arrow/,B=/^space(bar)?/,C=/^escape$/;Polymer.mg={properties:{keyEventTarget:{type:Object,value:function(){return this}},stopKeyboardEventPropagation:{type:Boolean,\nvalue:!1},_boundKeyHandlers:{type:Array,value:function(){return[]}},_imperativeKeyBindings:{type:Object,value:function(){return{}}}},observers:[\"Aq(keyEventTarget,_boundKeyHandlers)\"],$g:{},registered:function(){this.Jn()},attached:function(){this.uq()},detached:function(){this.Gq()},SI:function(a,b){this._imperativeKeyBindings[a]=b;this.Jn();this.Aq()},vP:function(){this._imperativeKeyBindings={};this.Jn();this.Aq()},Ho:function(a,c){c=e(c);for(var g=0;g<c.length;++g)if(b(c[g],a))return!0;return!1},\nxv:function(){var a=this.behaviors.map(function(a){return a.$g});-1===a.indexOf(this.$g)&&a.push(this.$g);return a},Jn:function(){this.Vi={};this.xv().forEach(function(a){for(var b in a)this.Zp(b,a[b])},this);for(var a in this._imperativeKeyBindings)this.Zp(a,this._imperativeKeyBindings[a]);for(var b in this.Vi)this.Vi[b].sort(function(a,b){a=a[0].zo;b=b[0].zo;return a===b?0:a?-1:1})},Zp:function(a,b){e(a).forEach(function(a){this.Vi[a.event]=this.Vi[a.event]||[];this.Vi[a.event].push([a,b])},this)},\nAq:function(){this.Gq();this.isAttached&&this.uq()},uq:function(){this.keyEventTarget&&Object.keys(this.Vi).forEach(function(a){var b=this.Vi[a],b=this.$v.bind(this,b);this._boundKeyHandlers.push([this.keyEventTarget,a,b]);this.keyEventTarget.addEventListener(a,b)},this)},Gq:function(){for(var a,b,c;this._boundKeyHandlers.length;)a=this._boundKeyHandlers.pop(),b=a[0],c=a[1],a=a[2],b.removeEventListener(c,a)},$v:function(a,c){this.stopKeyboardEventPropagation&&c.stopPropagation();if(!c.defaultPrevented)for(var e=\n0;e<a.length;e++){var g=a[e][0],k=a[e][1];if(b(g,c)&&(this.ww(g,k,c),c.defaultPrevented))break}},ww:function(a,b,c){var e=Object.create(a);e.Go=c;a=new CustomEvent(a.event,{detail:e,cancelable:!0});this[b].call(this,a);a.defaultPrevented&&c.preventDefault()}}})();V.Uu={};V.Uu.Uu={};\n(function(){function a(a){this.element=a;this.width=this.Zn.width;this.height=this.Zn.height;this.size=Math.max(this.width,this.height)}function b(a){this.element=a;this.color=window.getComputedStyle(a).color;this.Ck=document.createElement(\"div\");this.Og=document.createElement(\"div\");this.Ck.style.backgroundColor=this.color;this.Ck.classList.add(\"wave\");this.Og.classList.add(\"wave-container\");Polymer.dom(this.Og).appendChild(this.Ck);this.nC()}var c={distance:function(a,b,c,m){a-=c;b-=m;return Math.sqrt(a*\na+b*b)},now:window.performance&&window.performance.now?window.performance.now.bind(window.performance):Date.now};a.prototype={get Zn(){return this.element.getBoundingClientRect()},eL:function(a,b){var e=c.distance(a,b,0,0),g=c.distance(a,b,this.width,0),n=c.distance(a,b,0,this.height);a=c.distance(a,b,this.width,this.height);return Math.max(e,g,n,a)}};b.Zm=300;b.prototype={get recenters(){return this.element.recenters},get center(){return this.element.center},get uO(){var a;if(!this.Ko)return 0;a=\nc.now()-this.Ko;this.oj&&(a-=this.QB);return a},get QB(){return this.oj?c.now()-this.oj:0},get vO(){return this.uO/1E3},get us(){return this.QB/1E3},get wO(){return this.vO+this.us},get initialOpacity(){return this.element.initialOpacity},get opacityDecayVelocity(){return this.element.opacityDecayVelocity},get radius(){var a=this.Fd.width*this.Fd.width,c=this.Fd.height*this.Fd.height,a=1.1*Math.min(Math.sqrt(a+c),b.Zm)+5,c=1.1-a/b.Zm*.2,c=this.wO/c,a=a*(1-Math.pow(80,-c));return Math.abs(a)},get opacity(){return this.oj?\nMath.max(0,this.initialOpacity-this.us*this.opacityDecayVelocity):this.initialOpacity},get MO(){var a=.3*this.us,b=this.opacity;return Math.max(0,Math.min(a,b))},get uB(){return.01>this.opacity&&this.radius>=Math.min(this.rs,b.Zm)},get wB(){return this.opacity>=this.initialOpacity&&this.radius>=Math.min(this.rs,b.Zm)},get mN(){return this.oj?this.uB:this.wB},get HC(){return Math.min(1,this.radius/this.Fd.size*2/Math.sqrt(2))},get PW(){return this.Om?this.xi+this.HC*(this.Om-this.xi):this.xi},get QW(){return this.Pm?\nthis.zi+this.HC*(this.Pm-this.zi):this.zi},get yN(){return this.Ko&&!this.oj},nC:function(){this.Pm=this.Om=this.zi=this.xi=this.oj=this.Ko=this.rs=0;this.Fd=new a(this.element)},draw:function(){var a,b,c;this.Ck.style.opacity=this.opacity;a=this.radius/(this.Fd.size/2);b=this.PW-this.Fd.width/2;c=this.QW-this.Fd.height/2;this.Og.style.webkitTransform=\"translate(\"+b+\"px, \"+c+\"px)\";this.Og.style.transform=\"translate3d(\"+b+\"px, \"+c+\"px, 0)\";this.Ck.style.webkitTransform=\"scale(\"+a+\",\"+a+\")\";this.Ck.style.transform=\n\"scale3d(\"+a+\",\"+a+\",1)\"},fk:function(a){var b=this.Fd.width/2,e=this.Fd.height/2;this.nC();this.Ko=c.now();this.center?(this.xi=b,this.zi=e,c.distance(this.xi,this.zi,this.Om,this.Pm)):(this.xi=a?a.detail.x-this.Fd.Zn.left:this.Fd.width/2,this.zi=a?a.detail.y-this.Fd.Zn.top:this.Fd.height/2);this.recenters&&(this.Om=b,this.Pm=e,c.distance(this.xi,this.zi,this.Om,this.Pm));this.rs=this.Fd.eL(this.xi,this.zi);this.Og.style.top=(this.Fd.height-this.Fd.size)/2+\"px\";this.Og.style.left=(this.Fd.width-\nthis.Fd.size)/2+\"px\";this.Og.style.width=this.Fd.size+\"px\";this.Og.style.height=this.Fd.size+\"px\"},zk:function(){this.yN&&(this.oj=c.now())},remove:function(){Polymer.dom(this.Og.parentNode).removeChild(this.Og)}};Polymer({is:\"paper-ripple\",behaviors:[Polymer.mg],properties:{initialOpacity:{type:Number,value:.25},opacityDecayVelocity:{type:Number,value:.8},recenters:{type:Boolean,value:!1},center:{type:Boolean,value:!1},ripples:{type:Array,value:function(){return[]}},animating:{type:Boolean,readOnly:!0,\nreflectToAttribute:!0,value:!1},holdDown:{type:Boolean,value:!1,observer:\"t0\"},noink:{type:Boolean,value:!1},_animating:{type:Boolean},_boundAnimate:{type:Function,value:function(){return this.animate.bind(this)}}},get target(){var a=Polymer.dom(this).getOwnerRoot();return a=11==this.parentNode.nodeType?a.host:this.parentNode},$g:{\"enter:keydown\":\"O0\",\"space:keydown\":\"X0\",\"space:keyup\":\"Y0\"},attached:function(){this.keyEventTarget=this.target;this.listen(this.target,\"up\",\"Ct\");this.listen(this.target,\n\"down\",\"bp\")},detached:function(){this.unlisten(this.target,\"up\",\"Ct\");this.unlisten(this.target,\"down\",\"bp\")},get VV(){for(var a=0;a<this.ripples.length;++a)if(!this.ripples[a].mN)return!0;return!1},vba:function(){this.fk(null);this.async(function(){this.zk()},1)},bp:function(a){this.noink||this.fk(a)},fk:function(a){if(!(this.holdDown&&0<this.ripples.length)){var b=this.bJ();b.fk(a);this._animating||this.animate()}},Ct:function(a){this.noink||this.zk(a)},zk:function(a){this.holdDown||(this.ripples.forEach(function(b){b.zk(a)}),\nthis.animate())},JO:function(){this._animating=!1;this.$.background.style.backgroundColor=null;this.fire(\"transitionend\")},bJ:function(){var a=new b(this);Polymer.dom(this.$.waves).appendChild(a.Og);this.$.background.style.backgroundColor=a.color;this.ripples.push(a);this._setAnimating(!0);return a},xP:function(a){var b=this.ripples.indexOf(a);0>b||(this.ripples.splice(b,1),a.remove(),this.ripples.length||this._setAnimating(!1))},animate:function(){var a,b;this._animating=!0;for(a=0;a<this.ripples.length;++a)b=\nthis.ripples[a],b.draw(),this.$.background.style.opacity=b.MO,b.uB&&!b.wB&&this.xP(b);this.VV||0!==this.ripples.length?window.requestAnimationFrame(this._boundAnimate):this.JO()},O0:function(){this.bp();this.async(this.Ct,1)},X0:function(){this.bp()},Y0:function(){this.Ct()},t0:function(a,b){void 0!==b&&(a?this.fk():this.zk())}})})();V.en={};V.en.qh={};\nPolymer.qh={properties:{noink:{type:Boolean,observer:\"I0\"},_rippleContainer:{type:Object}},tn:function(){this.focused&&this.hj()},Fv:function(a){Polymer.Um.Fv.call(this,a);this.pressed&&this.hj(a)},hj:function(a){if(!this.kj()){this.Ne=this.Ri();this.Ne.noink=this.noink;var b=this._rippleContainer||this.root;b&&Polymer.dom(b).appendChild(this.Ne);if(a){var b=Polymer.dom(this._rippleContainer||this),c=Polymer.dom(a).rootTarget;b.deepContains(c)&&this.Ne.bp(a)}}},Pr:function(){this.hj();return this.Ne},\nkj:function(){return!!this.Ne},Ri:function(){return document.createElement(\"paper-ripple\")},I0:function(a){this.kj()&&(this.Ne.noink=a)}};V.mu={};V.mu.ng={};\nPolymer.ng={properties:{focused:{type:Boolean,value:!1,notify:!0,readOnly:!0,reflectToAttribute:!0},disabled:{type:Boolean,value:!1,notify:!0,observer:\"iq\",reflectToAttribute:!0},_oldTabIndex:{type:Number},_boundFocusBlurHandler:{type:Function,value:function(){return this.zn.bind(this)}}},observers:[\"lF(focused,disabled)\"],ready:function(){this.addEventListener(\"focus\",this._boundFocusBlurHandler,!0);this.addEventListener(\"blur\",this._boundFocusBlurHandler,!0)},zn:function(a){if(a.target===this)this._setFocused(\"focus\"===\na.type);else if(!this.shadowRoot){var b=Polymer.dom(a).localTarget;this.isLightDescendant(b)||this.fire(a.type,{sourceEvent:a},{node:this,bubbles:a.bubbles,cancelable:a.cancelable})}},iq:function(a){this.setAttribute(\"aria-disabled\",a?\"true\":\"false\");this.style.pointerEvents=a?\"none\":\"\";a?(this._oldTabIndex=this.tabIndex,this._setFocused(!1),this.tabIndex=-1,this.blur()):void 0!==this._oldTabIndex&&(this.tabIndex=this._oldTabIndex)},lF:function(){this.vn&&this.vn()}};V.mu.Hj={};\nPolymer.Um={properties:{pressed:{type:Boolean,readOnly:!0,value:!1,reflectToAttribute:!0,observer:\"e1\"},toggles:{type:Boolean,value:!1,reflectToAttribute:!0},active:{type:Boolean,value:!1,notify:!0,reflectToAttribute:!0},pointerDown:{type:Boolean,readOnly:!0,value:!1},receivedFocusFromKeyboard:{type:Boolean,readOnly:!0},ariaActiveAttribute:{type:String,value:\"aria-pressed\",observer:\"G_\"}},listeners:{down:\"Fv\",up:\"A1\",tap:\"v1\"},observers:[\"e0(focused)\",\"D_(active,ariaActiveAttribute)\"],$g:{\"enter:keydown\":\"gF\",\n\"space:keydown\":\"tw\",\"space:keyup\":\"uw\"},G0:/^mouse/,v1:function(){this.toggles?this.Bw(!this.active):this.active=!1},e0:function(a){this._setReceivedFocusFromKeyboard(!this.pointerDown&&a)},Bw:function(a){this.active!==a&&(this.active=a,this.fire(\"change\"))},Fv:function(){this._setPointerDown(!0);this._setPressed(!0);this._setReceivedFocusFromKeyboard(!1)},A1:function(){this._setPointerDown(!1);this._setPressed(!1)},tw:function(a){a=a.detail.Go;var b=Polymer.dom(a).localTarget;this.isLightDescendant(b)||\n(a.preventDefault(),a.stopImmediatePropagation(),this._setPressed(!0))},uw:function(a){a=a.detail.Go;a=Polymer.dom(a).localTarget;this.isLightDescendant(a)||(this.pressed&&this.gF(),this._setPressed(!1))},gF:function(){this.async(function(){this.click()},1)},e1:function(){this.gq()},G_:function(a,b){b&&b!=a&&this.hasAttribute(b)&&this.removeAttribute(b)},D_:function(a){this.toggles?this.setAttribute(this.ariaActiveAttribute,a?\"true\":\"false\"):this.removeAttribute(this.ariaActiveAttribute);this.gq()},\nvn:function(){this.disabled?this._setPressed(!1):this.gq()},gq:function(){this.tn&&this.tn()}};Polymer.Hj=[Polymer.mg,Polymer.Um];V.en.Mu={};\nPolymer.Nu={properties:{elevation:{type:Number,reflectToAttribute:!0,readOnly:!0}},observers:[\"uv(focused,disabled,active,pressed,receivedFocusFromKeyboard)\",\"Y_(receivedFocusFromKeyboard)\"],hostAttributes:{role:\"button\",tabindex:\"0\",animated:!0},uv:function(){var a=1;this.disabled?a=0:this.active||this.pressed?a=4:this.receivedFocusFromKeyboard&&(a=3);this._setElevation(a)},Y_:function(a){this.toggleClass(\"keyboard-focus\",a)},tw:function(a){Polymer.Um.tw.call(this,a);this.kj()&&1>this.Pr().ripples.length&&\nthis.Ne.bp()},uw:function(a){Polymer.Um.uw.call(this,a);this.kj()&&this.Ne.Ct()}};Polymer.Mu=[Polymer.Hj,Polymer.ng,Polymer.qh,Polymer.Nu];V.Vf={};V.Vf.FE={};V.Lp={};V.Lp.wZ={};V.Lp.Lp={};Polymer({is:\"paper-material\",properties:{elevation:{type:Number,reflectToAttribute:!0,value:1},animated:{type:Boolean,reflectToAttribute:!0,value:!1}}});V.Lu={};V.Lu.Lu={};\nPolymer({is:\"paper-button\",behaviors:[Polymer.Mu],properties:{raised:{type:Boolean,reflectToAttribute:!0,value:!1,observer:\"uv\"}},uv:function(){this.raised?Polymer.Nu.uv.apply(this):this._setElevation(0)}});V.ru={};V.ru.ru={};\nPolymer({is:\"iron-image\",properties:{src:{observer:\"YG\",type:String,value:\"\"},alt:{type:String,value:null},preventLoad:{type:Boolean,value:!1,observer:\"f1\"},sizing:{type:String,value:null,reflectToAttribute:!0},position:{type:String,value:\"center\"},preload:{type:Boolean,value:!1},placeholder:{type:String,value:null,observer:\"d1\"},fade:{type:Boolean,value:!1},loaded:{notify:!0,readOnly:!0,type:Boolean,value:!1},loading:{notify:!0,readOnly:!0,type:Boolean,value:!1},error:{notify:!0,readOnly:!0,type:Boolean,\nvalue:!1},width:{observer:\"G1\",type:Number,value:null},height:{observer:\"r0\",type:Number,value:null}},observers:[\"z1(sizing,position)\"],ready:function(){var a=this.$.img;a.onload=function(){this.$.img.src===this.Nn(this.src)&&(this._setLoading(!1),this._setLoaded(!0),this._setError(!1))}.bind(this);a.onerror=function(){this.$.img.src===this.Nn(this.src)&&(this.zq(),this._setLoading(!1),this._setLoaded(!1),this._setError(!0))}.bind(this);this.mw=\"\"},Sv:function(a){a?this.$.img.src=a:this.$.img.removeAttribute(\"src\");\nthis.$.sizedImgDiv.style.backgroundImage=a?'url(\"'+a+'\")':\"\";this._setLoading(!!a);this._setLoaded(!1);this._setError(!1)},zq:function(){this.$.img.removeAttribute(\"src\");this.$.sizedImgDiv.style.backgroundImage=\"\";this._setLoading(!1);this._setLoaded(!1);this._setError(!1)},a0:function(){return!this.preload||!this.fade&&!this.loading&&this.loaded},$_:function(){return this.preload&&this.fade&&!this.loading&&this.loaded?\"faded-out\":\"\"},V_:function(){return!this.sizing},T_:function(){return\"\"===this.alt?\n\"true\":void 0},U_:function(){if(null!==this.alt)return this.alt;if(\"\"===this.src)return\"\";var a=(new URL(this.Nn(this.src))).pathname.split(\"/\");return a[a.length-1]},W_:function(){return!!this.sizing},G1:function(){this.style.width=isNaN(this.width)?this.width:this.width+\"px\"},r0:function(){this.style.height=isNaN(this.height)?this.height:this.height+\"px\"},f1:function(){this.preventLoad||this.loaded||(this.zq(),this.Sv(this.src))},YG:function(a){var b=this.Nn(a);b!==this.mw&&(this.mw=b,this.zq(),\nthis.preventLoad||this.Sv(a))},d1:function(){this.$.placeholder.style.backgroundImage=this.placeholder?'url(\"'+this.placeholder+'\")':\"\"},z1:function(){var a=this.$.sizedImgDiv.style,b=this.$.placeholder.style;a.backgroundSize=b.backgroundSize=this.sizing;a.backgroundPosition=b.backgroundPosition=this.sizing?this.position:\"\";a.backgroundRepeat=b.backgroundRepeat=this.sizing?\"no-repeat\":\"\"},Nn:function(a){var b=this.ownerDocument.baseURI;return b?(new URL(a,b)).href:a}});V.Vf.mX={};V.Vf.tX={};\nV.Ou={};V.Ou.Ou={};\nPolymer({is:\"paper-card\",properties:{heading:{type:String,value:\"\",observer:\"q0\"},image:{type:String,value:\"\"},alt:{type:String},preloadImage:{type:Boolean,value:!1},fadeImage:{type:Boolean,value:!1},placeholderImage:{type:String,value:null},elevation:{type:Number,value:1,reflectToAttribute:!0},animatedShadow:{type:Boolean,value:!1},animated:{type:Boolean,reflectToAttribute:!0,readOnly:!0,computed:\"R_(animatedShadow)\"}},A0:function(a){return a?\"false\":\"true\"},q0:function(a){this.getAttribute(\"aria-label\");this.setAttribute(\"aria-label\",\na)},S_:function(a){return a?\" over-image\":\"\"},R_:function(a){return a}});V.Gi={};V.Gi.Rh={};\nPolymer.Rh={properties:{animationTiming:{type:Object,value:function(){return{duration:500,easing:\"cubic-bezier(0.4, 0, 0.2, 1)\",fill:\"both\"}}}},zN:!0,zj:function(a){if(a.timing)for(var b in a.timing)this.animationTiming[b]=a.timing[b];return this.animationTiming},lU:function(a,b,c){for(var e={transform:[\"webkitTransform\"],transformOrigin:[\"mozTransformOrigin\",\"webkitTransformOrigin\"]},e=e[b],g,k=0;g=e[k];k++)a.style[g]=c;a.style[b]=c},complete:function(){}};\n(function(){!function(a,b){var c={},e={},g={};!function(a){function b(a){if(\"number\"==typeof a)return a;var b={},c;for(c in a)b[c]=a[c];return b}function c(){this.BF=this.tF=0;this.FF=\"none\";this.cG=0;this.dG=1;this.yF=0;this.Dg=1;this.uF=\"normal\";this.zF=\"linear\";this.Gv=aa}function e(){return a.Bo(\"Invalid timing inputs\",\"2016-03-02\",\"TypeError exceptions will be thrown instead.\",!0)}function g(b,e){var g=new c;return e&&(g.fill=\"both\",g.duration=\"auto\"),\"number\"!=typeof b||isNaN(b)?void 0!==b&&\nObject.getOwnPropertyNames(b).forEach(function(c){\"auto\"==b[c]||(\"number\"==typeof g[c]||\"duration\"==c)&&(\"number\"!=typeof b[c]||isNaN(b[c]))||\"fill\"==c&&-1==ka.indexOf(b[c])||\"direction\"==c&&-1==U.indexOf(b[c])||\"playbackRate\"==c&&1!==b[c]&&a.Bo(\"AnimationEffectTiming.playbackRate\",\"2014-11-28\",\"Use Animation.playbackRate instead.\")||(g[c]=b[c])}):g.duration=b,g}function k(a){return\"number\"==typeof a&&(a=isNaN(a)?{duration:0}:{duration:a}),a}function C(b,c){return b=a.ws(b),g(b,c)}function E(a,b,\nc,e){return 0>a||1<a||0>c||1<c?aa:function(g){if(0==g||1==g)return g;for(var k=0,n=1;;){var m=(k+n)/2,q=3*a*(1-m)*(1-m)*m+3*c*(1-m)*m*m+m*m*m;if(1E-4>Math.abs(g-q))return 3*b*(1-m)*(1-m)*m+3*e*(1-m)*m*m+m*m*m;g>q?k=m:n=m}}}function W(a,b){return function(c){if(1<=c)return 1;var e=1/a;return c+=b*e,c-c%e}}function J(a){Ya||(Ya=document.createElement(\"div\").style);Ya.Fw=\"\";Ya.Fw=a;var b=Ya.Fw;if(\"\"==b&&e())throw new TypeError(a+\" is not a valid value for easing\");return(a=df.exec(b))?E.apply(this,a.slice(1).map(Number)):\n(a=ef.exec(b))?W(Number(a[1]),{start:na,N8:Ka,end:ma}[a[2]]):(b=cf[b])?b:aa}function K(a){return Math.abs(a.duration*a.iterations/a.playbackRate)}function O(a,b,c){return null==b?Fb:b<c.delay?Dc:b>=c.delay+a?vd:wd}function Q(a,b,c){var e=O(a,b,c);a:{var g=c.fill;switch(e){case Dc:b=\"backwards\"==g||\"both\"==g?0:null;break a;case wd:b-=c.delay;break a;case vd:b=\"forwards\"==g||\"both\"==g?a:null;break a;case Fb:b=null;break a}b=void 0}if(null===b)return null;if(0===a)return e===Dc?0:1;e=c.iterationStart*\nc.duration;b=(0>c.playbackRate?b-a:b)*c.playbackRate+e;a=c.duration;a=b===1/0||b===-(1/0)||b-e==c.duration*c.iterations&&c.iterations&&0==(c.iterations+c.iterationStart)%1?a:b%a;e=c.duration;b=0===b?0:a==e?c.iterationStart+c.iterations-1:Math.floor(b/e);e=c.duration;b=1<=b%2;a=(b=\"normal\"==c.direction||c.direction==(b?\"alternate-reverse\":\"alternate\"))?a:e-a;a/=e;a=e*c.Gv(a);return a/c.duration}var ka=[\"backwards\",\"forwards\",\"both\",\"none\"],U=[\"reverse\",\"alternate\",\"alternate-reverse\"],aa=function(a){return a};\nc.prototype={$h:function(b,c){this[\"_\"+b]=c;this.kc&&(this.kc.ak[b]=c,this.kc.Kf=a.pj(this.kc.ak),this.kc.rl=a.dk(this.kc.Kf),this.kc.hb&&this.kc.hb.hl())},get playbackRate(){return this.Dg},set delay(a){this.$h(\"delay\",a)},get delay(){return this.tF},set endDelay(a){this.$h(\"endDelay\",a)},get endDelay(){return this.BF},set fill(a){this.$h(\"fill\",a)},get fill(){return this.FF},set iterationStart(a){if((isNaN(a)||0>a)&&e())throw new TypeError(\"iterationStart must be a non-negative number, received: \"+\ntiming.iterationStart);this.$h(\"iterationStart\",a)},get iterationStart(){return this.cG},set duration(a){if(\"auto\"!=a&&(isNaN(a)||0>a)&&e())throw new TypeError(\"duration must be non-negative or auto, received: \"+a);this.$h(\"duration\",a)},get duration(){return this.yF},set direction(a){this.$h(\"direction\",a)},get direction(){return this.uF},set easing(a){this.Gv=J(a);this.$h(\"easing\",a)},get easing(){return this.zF},set iterations(a){if((isNaN(a)||0>a)&&e())throw new TypeError(\"iterations must be non-negative, received: \"+\na);this.$h(\"iterations\",a)},get iterations(){return this.dG}};var na=1,Ka=.5,ma=0,cf={ease:E(.25,.1,.25,1),\"ease-in\":E(.42,0,1,1),\"ease-out\":E(0,0,.58,1),\"ease-in-out\":E(.42,0,.58,1),\"step-start\":W(1,na),\"step-middle\":W(1,Ka),\"step-end\":W(1,ma)},Ya=null,df=/cubic-bezier\\(\\s*(-?\\d+\\.?\\d*|-?\\.\\d+)\\s*,\\s*(-?\\d+\\.?\\d*|-?\\.\\d+)\\s*,\\s*(-?\\d+\\.?\\d*|-?\\.\\d+)\\s*,\\s*(-?\\d+\\.?\\d*|-?\\.\\d+)\\s*\\)/,ef=/steps\\(\\s*(\\d+)\\s*,\\s*(start|middle|end)\\s*\\)/,Fb=0,Dc=1,vd=2,wd=3;a.io=b;a.KB=g;a.ws=k;a.pj=C;a.dk=K;a.bo=Q;a.$J=\nO;a.rW=J}(c,null);(function(a){function b(a){var b=[],c;for(c in a)if(!(c in[\"easing\",\"offset\",\"composite\"])){var e=a[c];Array.isArray(e)||(e=[e]);for(var g,k=e.length,n=0;k>n;n++)g={},\"offset\"in a?g.offset=a.offset:1==k?g.offset=1:g.offset=n/(k-1),\"easing\"in a&&(g.easing=a.easing),\"composite\"in a&&(g.nK=a.nK),g[c]=e[n],b.push(g)}return b.sort(function(a,b){return a.offset-b.offset}),b}function c(a){function c(){var a=k.length;null==k[a-1].offset&&(k[a-1].offset=1);1<a&&null==k[0].offset&&(k[0].offset=\n0);for(var b=0,c=k[0].offset,e=1;a>e;e++){var g=k[e].offset;if(null!=g){for(var n=1;e-b>n;n++)k[b+n].offset=c+(g-c)*n/(e-b);b=e;c=g}}}if(null==a)return[];window.Symbol&&Symbol.iterator&&Array.prototype.from&&a[Symbol.iterator]&&(a=Array.from(a));Array.isArray(a)||(a=b(a));var k=a.map(function(a){var b={},c;for(c in a){var k=a[c];if(\"offset\"==c){if(null!=k&&(k=Number(k),!isFinite(k)))throw new TypeError(\"keyframe offsets must be numbers.\");}else{if(\"composite\"==c)throw{type:DOMException.NOT_SUPPORTED_ERR,\nname:\"NotSupportedError\",message:\"add compositing is not supported\"};k=\"\"+k}var n=void 0,m=c,q=k,k=b,v=e[m];if(v)for(n in g.style[m]=q,v)m=v[n],q=g.style[m],k[m]=m in C?C[m][q]||q:q;else k[m]=m in C?C[m][q]||q:q}return void 0==b.offset&&(b.offset=null),b});a=!0;for(var n=-(1/0),m=0;m<k.length;m++){var q=k[m].offset;if(null!=q){if(n>q)throw{code:DOMException.INVALID_MODIFICATION_ERR,name:\"InvalidModificationError\",message:\"Keyframes are not loosely sorted by offset. Sort or specify offsets.\"};n=q}else a=\n!1}return k=k.filter(function(a){return 0<=a.offset&&1>=a.offset}),a||c(),k}var e={background:\"backgroundImage backgroundPosition backgroundSize backgroundRepeat backgroundAttachment backgroundOrigin backgroundClip backgroundColor\".split(\" \"),border:\"borderTopColor borderTopStyle borderTopWidth borderRightColor borderRightStyle borderRightWidth borderBottomColor borderBottomStyle borderBottomWidth borderLeftColor borderLeftStyle borderLeftWidth\".split(\" \"),borderBottom:[\"borderBottomWidth\",\"borderBottomStyle\",\n\"borderBottomColor\"],borderColor:[\"borderTopColor\",\"borderRightColor\",\"borderBottomColor\",\"borderLeftColor\"],borderLeft:[\"borderLeftWidth\",\"borderLeftStyle\",\"borderLeftColor\"],borderRadius:[\"borderTopLeftRadius\",\"borderTopRightRadius\",\"borderBottomRightRadius\",\"borderBottomLeftRadius\"],borderRight:[\"borderRightWidth\",\"borderRightStyle\",\"borderRightColor\"],borderTop:[\"borderTopWidth\",\"borderTopStyle\",\"borderTopColor\"],borderWidth:[\"borderTopWidth\",\"borderRightWidth\",\"borderBottomWidth\",\"borderLeftWidth\"],\nflex:[\"flexGrow\",\"flexShrink\",\"flexBasis\"],font:\"fontFamily fontSize fontStyle fontVariant fontWeight lineHeight\".split(\" \"),margin:[\"marginTop\",\"marginRight\",\"marginBottom\",\"marginLeft\"],outline:[\"outlineColor\",\"outlineStyle\",\"outlineWidth\"],padding:[\"paddingTop\",\"paddingRight\",\"paddingBottom\",\"paddingLeft\"]},g=document.createElementNS(\"http://www.w3.org/1999/xhtml\",\"div\"),k={yca:\"1px\",lO:\"3px\",xca:\"5px\"},C={borderBottomWidth:k,borderLeftWidth:k,borderRightWidth:k,borderTopWidth:k,fontSize:{\"xx-small\":\"60%\",\n\"x-small\":\"75%\",small:\"89%\",lO:\"100%\",d8:\"120%\",\"x-large\":\"150%\",\"xx-large\":\"200%\"},fontWeight:{E9:\"400\",bold:\"700\"},outlineWidth:k,textShadow:{EO:\"0px 0px 0px transparent\"},boxShadow:{EO:\"0px 0px 0px 0px transparent\"}};a.uK=b;a.TB=c})(c,null);(function(a){var b={};a.Bo=function(a,c,e,g){g=g?\"are\":\"is\";var k=new Date;c=new Date(c);return c.setMonth(c.getMonth()+3),c>k?(a in b||console.warn(\"Web Animations: \"+a+\" \"+g+\" deprecated and will stop working on \"+c.toDateString()+\". \"+e),b[a]=!0,!1):!0};\na.IK=function(b,c,e,g){var k=g?\"are\":\"is\";if(a.Bo(b,c,e,g))throw Error(b+\" \"+k+\" no longer supported. \"+e);}})(c);(function(){if(document.documentElement.animate){var a=document.documentElement.animate([],0),b=!0;if(a&&(b=!1,\"play currentTime pause reverse playbackRate cancel finish startTime playState\".split(\" \").forEach(function(c){void 0===a[c]&&(b=!0)})),!b)return}!function(a,b){function c(a){for(var b={},c=0;c<a.length;c++)for(var e in a[c])if(\"offset\"!=e&&\"easing\"!=e&&\"composite\"!=e){var g=\n{offset:a[c].offset,easing:a[c].easing,value:a[c][e]};b[e]=b[e]||[];b[e].push(g)}for(var k in b)if(a=b[k],0!=a[0].offset||1!=a[a.length-1].offset)throw{type:DOMException.NOT_SUPPORTED_ERR,name:\"NotSupportedError\",message:\"Partial keyframes are not supported\"};return b}function e(c){var e=[],g;for(g in c)for(var k=c[g],n=0;n<k.length-1;n++){var m=k[n].offset,q=k[n+1].offset,v=k[n].value,B=k[n+1].value,C=k[n].easing;m==q&&(1==q?v=B:B=v);e.push({startTime:m,endTime:q,easing:a.rW(C?C:\"linear\"),property:g,\njN:b.aP(g,v,B)})}return e.sort(function(a,b){return a.startTime-b.startTime}),e}b.tK=function(g){g=a.TB(g);var k=c(g),n=e(k);return function(a,c){if(null!=c)n.filter(function(a){return 0>=c&&0==a.startTime||1<=c&&1==a.endTime||c>=a.startTime&&c<=a.endTime}).forEach(function(e){var g=c-e.startTime,k=e.endTime-e.startTime,g=0==k?0:e.easing(g/k);b.apply(a,e.property,e.jN(g))});else for(var e in k)\"offset\"!=e&&\"easing\"!=e&&\"composite\"!=e&&b.clear(a,e)}}}(c,e,null);(function(a,b){function c(a){return a.replace(/-(.)/g,\nfunction(a,b){return b.toUpperCase()})}function e(a,b,e){for(var g=0;g<e.length;g++){var n=e[g],m=a,q=b,n=c(n);k[n]=k[n]||[];k[n].push([m,q])}}function g(e,g,m){var q=e;/-/.test(e)&&!a.Bo(\"Hyphenated property names\",\"2016-03-22\",\"Use camelCase instead.\",!0)&&(q=c(e));\"initial\"!=g&&\"initial\"!=m||(\"initial\"==g&&(g=n[q]),\"initial\"==m&&(m=n[q]));e=g==m?[]:k[q];for(q=0;e&&q<e.length;q++){var v=e[q][0](g),B=e[q][0](m);if(void 0!==v&&void 0!==B&&(v=e[q][1](v,B))){var C=b.ku.apply(null,v);return function(a){return 0==\na?g:1==a?m:C(a)}}}return b.ku(!1,!0,function(a){return a?m:g})}var k={};b.cg=e;var n={backgroundColor:\"transparent\",backgroundPosition:\"0% 0%\",borderBottomColor:\"currentColor\",borderBottomLeftRadius:\"0px\",borderBottomRightRadius:\"0px\",borderBottomWidth:\"3px\",borderLeftColor:\"currentColor\",borderLeftWidth:\"3px\",borderRightColor:\"currentColor\",borderRightWidth:\"3px\",borderSpacing:\"2px\",borderTopColor:\"currentColor\",borderTopLeftRadius:\"0px\",borderTopRightRadius:\"0px\",borderTopWidth:\"3px\",bottom:\"auto\",\nclip:\"rect(0px, 0px, 0px, 0px)\",color:\"black\",fontSize:\"100%\",fontWeight:\"400\",height:\"auto\",left:\"auto\",letterSpacing:\"normal\",lineHeight:\"120%\",marginBottom:\"0px\",marginLeft:\"0px\",marginRight:\"0px\",marginTop:\"0px\",maxHeight:\"none\",maxWidth:\"none\",minHeight:\"0px\",minWidth:\"0px\",opacity:\"1.0\",outlineColor:\"invert\",n$:\"0px\",outlineWidth:\"3px\",paddingBottom:\"0px\",paddingLeft:\"0px\",paddingRight:\"0px\",paddingTop:\"0px\",right:\"auto\",textIndent:\"0px\",textShadow:\"0px 0px 0px transparent\",top:\"auto\",transform:\"\",\nverticalAlign:\"0px\",visibility:\"visible\",width:\"auto\",wordSpacing:\"normal\",zIndex:\"auto\"};b.aP=g})(c,e,null);(function(a,b){function c(b){var c=a.dk(b),e=function(e){return a.bo(c,e,b)};return e.Xg=b.delay+c+b.endDelay,e.sq=function(e){e=a.$J(c,e,b);return e===PhaseActive||e===PhaseBefore},e}b.KeyframeEffect=function(e,g,k,n){var m,q=c(a.pj(k)),v=b.tK(g);g=function(){v(e,m)};return g.bk=function(a){return m=q(a),null!==m},g.O_=function(){v(e,null)},g.XF=function(a){return e===a},g.sq=q.sq,g.Xg=q.Xg,\ng.Kc=n,g};b.YY=function(a){var b=function(){a&&(a(),a=null)};return b.bk=function(){return null},b.Xg=0,b.sq=function(){return!1},b.XF=function(){return!1},b}})(c,e,null);(function(a){a.apply=function(b,c,e){b.style[a.propertyName(c)]=e};a.clear=function(b,c){b.style[a.propertyName(c)]=\"\"}})(e,null);(function(a){window.Element.prototype.animate=function(b,c){var e=\"\";return c&&c.id&&(e=c.id),a.timeline.Vj(a.KeyframeEffect(this,b,c,e))}})(e);(function(a){function b(a,c,e){if(\"number\"==typeof a&&\"number\"==\ntypeof c)return a*(1-e)+c*e;if(\"boolean\"==typeof a&&\"boolean\"==typeof c)return.5>e?a:c;if(a.length==c.length){for(var g=[],k=0;k<a.length;k++)g.push(b(a[k],c[k],e));return g}throw\"Mismatched interpolation arguments \"+a+\":\"+c;}a.ku=function(a,c,e){return function(g){return e(b(a,c,g))}}})(e,null);(function(a,b){a.sC=0;var c=function(a,b){this.target=a;this.currentTime=b;this.type=\"finish\";this.cancelable=this.bubbles=!1;this.currentTarget=a;this.defaultPrevented=!1;this.eventPhase=Event.AT_TARGET;\nthis.timeStamp=Date.now()};b.Animation=function(b){this.id=\"\";b&&b.Kc&&(this.id=b.Kc);this.Xj=a.sC++;this.Ug=0;this.bg=null;this.ag=!1;this.Dg=1;this.Si=this.qq=!0;this.onfinish=null;this.yn=[];this.kc=b;this.Ui=this.kc.bk(0);this.Bg=!0;this.Oj=!1};b.Animation.prototype={Hv:function(){0>this.playbackRate&&0===this.currentTime?this.Ui=this.kc.bk(-1):this.Ui=this.kc.bk(this.currentTime);this.qq||!this.Ui&&this.Si||(this.qq=!0,b.timeline.sf.push(this))},Dq:function(a,b){a!=this.Ug&&(this.Ug=a,this.Sj&&\n!b&&(this.Ug=0<this.Dg?this.Xg:0),this.Hv())},get currentTime(){return this.Bg||this.Oj?null:this.Ug},set currentTime(a){a=+a;isNaN(a)||(b.restart(),this.ag||null==this.bg||(this.bg=this.$j.currentTime-a/this.Dg),this.Oj=!1,this.Ug!=a&&(this.Dq(a,!0),b.rk()))},get startTime(){return this.bg},set startTime(a){a=+a;isNaN(a)||this.ag||this.Bg||(this.bg=a,this.Dq((this.$j.currentTime-this.bg)*this.playbackRate),b.rk())},get playbackRate(){return this.Dg},set playbackRate(a){if(a!=this.Dg){var b=this.currentTime;\nthis.Dg=a;this.bg=null;\"paused\"!=this.playState&&\"idle\"!=this.playState&&this.play();null!=b&&(this.currentTime=b)}},get Sj(){return!this.Bg&&(0<this.Dg&&this.Ug>=this.Xg||0>this.Dg&&0>=this.Ug)},get Xg(){return this.kc.Xg},get playState(){return this.Bg?\"idle\":null==this.bg&&!this.ag&&0!=this.playbackRate||this.Oj?\"pending\":this.ag?\"paused\":this.Sj?\"finished\":\"running\"},play:function(){this.ag=!1;(this.Sj||this.Bg)&&(this.Ug=0<this.Dg?0:this.Xg,this.bg=null);this.Bg=this.Si=!1;this.Hv();b.rk()},\npause:function(){this.Sj||this.ag||this.Bg||(this.Oj=!0);this.bg=null;this.ag=!0},finish:function(){this.Bg||(this.currentTime=0<this.Dg?this.Xg:0,this.bg=this.Xg-this.currentTime,this.Oj=!1,b.rk())},cancel:function(){this.Ui&&(this.Ui=!1,this.Bg=!0,this.Si=!0,this.currentTime=0,this.bg=null,this.kc.bk(null),b.rk())},reverse:function(){this.playbackRate*=-1;this.play()},addEventListener:function(a,b){\"function\"==typeof b&&\"finish\"==a&&this.yn.push(b)},removeEventListener:function(a,b){\"finish\"==a&&\n(a=this.yn.indexOf(b),0<=a&&this.yn.splice(a,1))},IF:function(a){if(this.Sj){if(!this.Si){var b=new c(this,this.Ug,a),e=this.yn.concat(this.onfinish?[this.onfinish]:[]);setTimeout(function(){e.forEach(function(a){a.call(b.target,b)})},0);this.Si=!0}}else this.Si=!1},$G:function(a,b){this.Bg||this.ag||(null==this.bg?b&&(this.startTime=a-this.Ug/this.playbackRate):this.Sj||this.Dq((a-this.bg)*this.playbackRate));b&&(this.Oj=!1,this.IF(a))},get Uv(){return this.playState in{w$:1,Paa:1}||!this.Si}}})(c,\ne,null);(function(a,b){function c(a){var b=q;q=[];a<aa.currentTime&&(a=aa.currentTime);n(a,!0);b.forEach(function(b){b[1](a)});k()}function e(a,b){return a.Xj-b.Xj}function g(){this.sf=[];this.currentTime=window.performance&&performance.now?performance.now():0}function k(){U.forEach(function(a){a()});U.length=0}function n(a,c){ka=!1;var g=b.timeline;g.currentTime=a;g.sf.sort(e);Q=!1;var k=g.sf;g.sf=[];var n=[],m=[],k=k.filter(function(b){b.$G(a,c);b.Ui?m.push(b.kc):n.push(b.kc);b.Uv&&(Q=!0);var e=\nb.Ui||b.Uv;return b.qq=e,e});U.push.apply(U,n);U.push.apply(U,m);g.sf.push.apply(g.sf,k);Q&&requestAnimationFrame(function(){})}var m=window.requestAnimationFrame,q=[],O=0;window.requestAnimationFrame=function(a){var b=O++;return 0==q.length&&m(c),q.push([b,a]),b};window.cancelAnimationFrame=function(a){q.forEach(function(b){b[0]==a&&(b[1]=function(){})})};g.prototype={Vj:function(c){c.Kf=a.pj(c.timing);c=new b.Animation(c);return c.Bg=!1,c.$j=this,this.sf.push(c),b.restart(),b.rk(),c}};var Q=!1,\nka=!1;b.restart=function(){return Q||(Q=!0,requestAnimationFrame(function(){}),ka=!0),ka};b.rk=function(){n(b.timeline.currentTime,!1);k()};var U=[],aa=new g;b.timeline=aa})(c,e,null);(function(a){function b(a,b){var c=a.exec(b);return c?(c=a.ignoreCase?c[0].toLowerCase():c[0],[c,b.substr(c.length)]):void 0}function c(a,b){b=b.replace(/^\\s*/,\"\");return(a=a(b))?[a[0],a[1].replace(/^\\s*/,\"\")]:void 0}function e(a,e,g){a=c.bind(null,a);for(var k=[];;){var n=a(g);if(!n||(k.push(n[0]),g=n[1],n=b(e,g),!n||\n\"\"==n[1]))return[k,g];g=n[1]}}function g(a,b){for(var c=0,e=0;e<b.length&&(!/\\s|,/.test(b[e])||0!=c);e++)if(\"(\"==b[e])c++;else if(\")\"==b[e]&&(c--,0==c&&e++,0>=c))break;a=a(b.substr(0,e));return void 0==a?void 0:[a,b.substr(e)]}function k(a,b){for(var c=a,e=b;c&&e;)c>e?c%=e:e%=c;return a*b/(c+e)}function n(a){return function(b){b=a(b);return b&&(b[0]=void 0),b}}function m(a,b){return function(c){var e=a(c);return e?e:[b,c]}}function K(b,c){for(var e=[],g=0;g<b.length;g++){c=a.sK(b[g],c);if(!c||\"\"==\nc[0])return;void 0!==c[0]&&e.push(c[0]);c=c[1]}return\"\"==c?e:void 0}function O(a,b,c,e,g){for(var n=[],m=[],q=[],v=k(e.length,g.length),B=0;v>B;B++){var C=b(e[B%e.length],g[B%g.length]);if(!C)return;n.push(C[0]);m.push(C[1]);q.push(C[2])}return[n,m,function(b){b=b.map(function(a,b){return q[b](a)}).join(c);return a?a(b):b}]}function Q(a,b,c){for(var e=[],g=[],k=[],n=0,m=0;m<c.length;m++)if(\"function\"==typeof c[m]){var q=c[m](a[n],b[n++]);e.push(q[0]);g.push(q[1]);k.push(q[2])}else!function(a){e.push(!1);\ng.push(!1);k.push(function(){return c[a]})}(m);return[e,g,function(a){for(var b=\"\",c=0;c<a.length;c++)b+=k[c](a[c]);return b}]}a.Al=b;a.sK=c;a.zl=e;a.kr=g;a.as=n;a.optional=m;a.rK=K;a.ss=O.bind(null,null);a.oO=O;a.G8=Q})(e);(function(a){function b(b){function c(b){var c=a.Al(/^inset/i,b);return c?(e.lj=!0,c):(c=a.ix(b))?(e.fg.push(c[0]),c):(c=a.qK(b))?(e.color=c[0],c):void 0}var e={lj:!1,fg:[],color:null};return(b=a.zl(c,/^/,b))&&b[0].length?[e,b[1]]:void 0}function c(c){return(c=a.zl(b,/^,/,c))&&\n\"\"==c[1]?c[0]:void 0}function e(b,c){for(;b.fg.length<Math.max(b.fg.length,c.fg.length);)b.fg.push({px:0});for(;c.fg.length<Math.max(b.fg.length,c.fg.length);)c.fg.push({px:0});if(b.lj==c.lj&&!!b.color==!!c.color){for(var e,g=[],k=[[],0],n=[[],0],m=0;m<b.fg.length;m++){var q=a.Jo(b.fg[m],c.fg[m],2==m);k[0].push(q[0]);n[0].push(q[1]);g.push(q[2])}b.color&&c.color&&(c=a.mO(b.color,c.color),k[1]=c[0],n[1]=c[1],e=c[2]);return[k,n,function(a){for(var c=b.lj?\"inset \":\" \",k=0;k<g.length;k++)c+=g[k](a[0][k])+\n\" \";return e&&(c+=e(a[1])),c}]}}function g(b,c,e,g){function k(a){return{lj:a,color:[0,0,0,0],fg:[{px:0},{px:0},{px:0},{px:0}]}}for(var n=[],m=[],q=0;q<e.length||q<g.length;q++){var v=e[q]||k(g[q].lj),B=g[q]||k(e[q].lj);n.push(v);m.push(B)}return a.ss(b,c,n,m)}var k=g.bind(null,e,\", \");a.cg(c,k,[\"box-shadow\",\"text-shadow\"])})(e);(function(a){function b(a){return a.toFixed(3).replace(\".000\",\"\")}function c(a,b,c){return Math.min(b,Math.max(a,c))}function e(a){return/^\\s*[-+]?(\\d*\\.)?\\d+\\s*$/.test(a)?\nNumber(a):void 0}function g(a,c){return[a,c,b]}function k(a,b){return 0!=a?m(0,1/0)(a,b):void 0}function n(a,b){return[a,b,function(a){return Math.round(c(1,1/0,a))}]}function m(a,e){return function(g,k){return[g,k,function(g){return b(c(a,e,g))}]}}function K(a,b){return[a,b,Math.round]}a.clamp=c;a.cg(e,m(0,1/0),[\"border-image-width\",\"line-height\"]);a.cg(e,m(0,1),[\"opacity\",\"shape-image-threshold\"]);a.cg(e,k,[\"flex-grow\",\"flex-shrink\"]);a.cg(e,n,[\"orphans\",\"widows\"]);a.cg(e,K,[\"z-index\"]);a.RO=e;\na.nO=g;a.WB=b})(e,null);(function(a){function b(a,b){return\"visible\"==a||\"visible\"==b?[0,1,function(c){return 0>=c?a:1<=c?b:\"visible\"}]:void 0}a.cg(String,b,[\"visibility\"])})(e);(function(a){function b(a){a=a.trim();g.fillStyle=\"#000\";g.fillStyle=a;var b=g.fillStyle;if(g.fillStyle=\"#fff\",g.fillStyle=a,b==g.fillStyle)return g.fillRect(0,0,1,1),a=g.getImageData(0,0,1,1).data,g.clearRect(0,0,1,1),b=a[3]/255,[a[0]*b,a[1]*b,a[2]*b,b]}function c(b,c){return[b,c,function(b){if(b[3])for(var c=0;3>c;c++)b[c]=\nMath.round(Math.max(0,Math.min(255,b[c]/b[3])));return b[3]=a.WB(a.clamp(0,1,b[3])),\"rgba(\"+b.join(\",\")+\")\"}]}var e=document.createElementNS(\"http://www.w3.org/1999/xhtml\",\"canvas\");e.width=e.height=1;var g=e.getContext(\"2d\");a.cg(b,c,\"background-color border-bottom-color border-left-color border-right-color border-top-color color outline-color text-decoration-color\".split(\" \"));a.qK=a.kr.bind(null,b);a.mO=c})(e,null);(function(a){function b(a,b){if(b=b.trim().toLowerCase(),\"0\"==b&&0<=\"px\".search(a))return{px:0};\nif(/^[^(]*$|^calc/.test(b)){b=b.replace(/calc\\(/g,\"(\");var c={};b=b.replace(a,function(a){return c[a]=null,\"U\"+a});a=\"U(\"+a.source+\")\";for(var e=b.replace(/[-+]?(\\d*\\.)?\\d+/g,\"N\").replace(new RegExp(\"N\"+a,\"g\"),\"D\").replace(/\\s[+-]\\s/g,\"O\").replace(/\\s/g,\"\"),g=[/N\\*(D)/g,/(N|D)[*\\/]N/g,/(N|D)O\\1/g,/\\((N|D)\\)/g],k=0;k<g.length;)g[k].test(e)?(e=e.replace(g[k],\"$1\"),k=0):k++;if(\"D\"==e){for(var n in c){e=(0,eval)(b.replace(new RegExp(\"U\"+n,\"g\"),\"\").replace(new RegExp(a,\"g\"),\"*0\"));if(!isFinite(e))return;\nc[n]=e}return c}}}function c(a,b){return e(a,b,!0)}function e(b,c,e){var g,k=[];for(g in b)k.push(g);for(g in c)0>k.indexOf(g)&&k.push(g);return b=k.map(function(a){return b[a]||0}),c=k.map(function(a){return c[a]||0}),[b,c,function(b){var c=b.map(function(c,g){return 1==b.length&&e&&(c=Math.max(c,0)),a.WB(c)+k[g]}).join(\" + \");return 1<b.length?\"calc(\"+c+\")\":c}]}var g=b.bind(null,/px|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc/g),k=b.bind(null,/px|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|%/g),\nn=b.bind(null,/deg|rad|grad|turn/g);a.PO=g;a.QO=k;a.ix=a.kr.bind(null,k);a.OO=n;a.Jo=e;var g=a.kr.bind(null,g),g=a.zl.bind(void 0,g,/^/),m=a.zl.bind(void 0,g,/^,/);a.e4=m;var g=function(a){return(a=m(a))&&\"\"==a[1]?a[0]:void 0},n=a.ss.bind(void 0,c,\" \"),K=a.ss.bind(void 0,n,\",\");a.H8=n;a.cg(g,K,[\"background-size\"]);a.cg(k,c,\"border-bottom-width border-image-width border-left-width border-right-width border-top-width flex-basis font-size height line-height max-height max-width outline-width width\".split(\" \"));\na.cg(k,e,\"border-bottom-left-radius border-bottom-right-radius border-top-left-radius border-top-right-radius bottom left letter-spacing margin-bottom margin-left margin-right margin-top min-height min-width outline-offset padding-bottom padding-left padding-right padding-top perspective right shape-margin text-indent top vertical-align word-spacing\".split(\" \"))})(e,null);(function(a){function b(b){return a.ix(b)||a.Al(/^auto/,b)}function c(c){return(c=a.rK([a.as(a.Al.bind(null,/^rect/)),a.as(a.Al.bind(null,\n/^\\(/)),a.zl.bind(null,b,/^,/),a.as(a.Al.bind(null,/^\\)/))],c))&&4==c[0].length?c[0]:void 0}function e(b,c){return\"auto\"==b||\"auto\"==c?[!0,!1,function(e){e=e?b:c;if(\"auto\"==e)return\"auto\";e=a.Jo(e,e);return e[2](e[0])}]:a.Jo(b,c)}function g(a){return\"rect(\"+a+\")\"}var k=a.oO.bind(null,g,e,\", \");a.t$=c;a.F8=k;a.cg(c,k,[\"clip\"])})(e,null);(function(a){function b(a){return function(b){var c=0;return a.map(function(a){return a===K?b[c++]:a})}}function c(a){return a}function e(b){if(b=b.toLowerCase().trim(),\n\"none\"==b)return[];for(var c,e=/\\s*(\\w+)\\(([^)]*)\\)/g,g=[],k=0;(c=e.exec(b))&&c.index==k;){var k=c.index+c[0].length,n=c[1],m=ka[n];if(!m)break;c=c[2].split(\",\");m=m[0];if(m.length<c.length)break;for(var q=[],v=0;v<m.length;v++){var B,C=c[v],E=m[v];if(B=C?{gp:function(b){return\"0\"==b.trim()?Q:a.OO(b)},pe:a.RO,d_:a.QO,sb:a.PO}[E.toUpperCase()](C):{a:Q,n:q[0],t:O}[E],void 0===B)return;q.push(B)}if(g.push({t:n,d:q}),e.lastIndex==b.length)return g}}function g(a){return a.toFixed(6).replace(\".000000\",\n\"\")}function k(b,c){if(b.sr!==c){b.sr=c;var e=a.JB(b)}if(c.sr!==b){c.sr=b;var k=a.JB(c)}return null==e[0]||null==k[0]?[[!1],[!0],function(a){return a?c[0].d:b[0].d}]:(e[0].push(0),k[0].push(1),[e,k,function(b){var c=a.iaa(e[0][3],k[0][3],b[5]);b=a.K3(b[0],b[1],b[2],c,b[4]);return b=b.map(g).join(\",\")}])}function n(a){return a.replace(/(x|y|z|3d)?$/,\"3d\")}function m(b,c){var e=a.JB&&!0,g=!1;if(!b.length||!c.length){b.length||(g=!0,b=c,c=[]);for(var m=0;m<b.length;m++){var q=b[m].t,v=b[m].d,B=\"scale\"==\nq.substr(0,5)?1:0;c.push({t:q,d:v.map(function(a){if(\"number\"==typeof a)return B;var b={},c;for(c in a)b[c]=B;return b})})}}var v=[],C=[],E=[];if(b.length!=c.length){if(!e)return;var J=k(b,c),v=[J[0]],C=[J[1]],E=[[\"matrix\",[J[2]]]]}else for(m=0;m<b.length;m++){var q=b[m].t,K=c[m].t,O=b[m].d,Q=c[m].d,W=ka[q],U=ka[K];if(\"perspective\"==q&&\"perspective\"==K||!(\"matrix\"!=q&&\"matrix3d\"!=q||\"matrix\"!=K&&\"matrix3d\"!=K)){if(!e)return;J=k([b[m]],[c[m]]);v.push(J[0]);C.push(J[1]);E.push([\"matrix\",[J[2]]])}else{if(q!=\nK)if(W[2]&&U[2]&&q.replace(/[xy]/,\"\")==K.replace(/[xy]/,\"\"))q=q.replace(/[xy]/,\"\"),O=W[2](O),Q=U[2](Q);else{if(!W[1]||!U[1]||n(q)!=n(K)){if(!e)return;J=k(b,c);v=[J[0]];C=[J[1]];E=[[\"matrix\",[J[2]]]];break}q=n(q);O=W[1](O);Q=U[1](Q)}for(var W=[],U=[],K=[],aa=0;aa<O.length;aa++)J=\"number\"==typeof O[aa]?a.nO:a.Jo,J=J(O[aa],Q[aa]),W[aa]=J[0],U[aa]=J[1],K.push(J[2]);v.push(W);C.push(U);E.push([q,K])}}g&&(b=v,v=C,C=b);return[v,C,function(a){return a.map(function(a,b){a=a.map(function(a,c){return E[b][1][c](a)}).join(\",\");\nreturn\"matrix\"==E[b][0]&&16==a.split(\",\").length&&(E[b][0]=\"matrix3d\"),E[b][0]+\"(\"+a+\")\"}).join(\" \")}]}var K=null,O={px:0},Q={V4:0},ka={matrix:[\"NNNNNN\",[K,K,0,0,K,K,0,0,0,0,1,0,K,K,0,1],c],v8:[\"NNNNNNNNNNNNNNNN\",c],rotate:[\"A\"],Laa:[\"A\"],Maa:[\"A\"],Naa:[\"A\"],Kaa:[\"NNNA\"],perspective:[\"L\"],scale:[\"Nn\",b([K,K,1]),c],Vaa:[\"N\",b([K,1,1]),b([K,1])],Waa:[\"N\",b([1,K,1]),b([1,K])],Xaa:[\"N\",b([1,1,K])],Taa:[\"NNN\",c],wba:[\"Aa\",null,c],xba:[\"A\",null,b([K,Q])],yba:[\"A\",null,b([Q,K])],translate:[\"Tt\",b([K,K,O]),\nc],$ca:[\"T\",b([K,O,O]),b([K,O])],ada:[\"T\",b([O,K,O]),b([O,K])],bda:[\"L\",b([O,O,K])],translate3d:[\"TTL\",c]};a.cg(e,m,[\"transform\"])})(e,null);(function(a){function b(a,b){b.concat([a]).forEach(function(b){b in document.documentElement.style&&(c[a]=b)})}var c={};b(\"transform\",[\"webkitTransform\",\"msTransform\"]);b(\"transformOrigin\",[\"webkitTransformOrigin\"]);b(\"perspective\",[\"webkitPerspective\"]);b(\"perspectiveOrigin\",[\"webkitPerspectiveOrigin\"]);a.propertyName=function(a){return c[a]||a}})(e,null)})();\n!function(){if(void 0===document.createElement(\"div\").animate([]).oncancel){var a;a=window.performance&&performance.now?function(){return performance.now()}:function(){return Date.now()};var b=function(a,b){this.target=a;this.currentTime=b;this.type=\"cancel\";this.cancelable=this.bubbles=!1;this.currentTarget=a;this.defaultPrevented=!1;this.eventPhase=Event.AT_TARGET;this.timeStamp=Date.now()},c=window.Element.prototype.animate;window.Element.prototype.animate=function(e,g){e=c.call(this,e,g);e.un=\n[];e.oncancel=null;var k=e.cancel;e.cancel=function(){k.call(this);var c=new b(this,null,a()),e=this.un.concat(this.oncancel?[this.oncancel]:[]);setTimeout(function(){e.forEach(function(a){a.call(c.target,c)})},0)};var n=e.addEventListener;e.addEventListener=function(a,b){\"function\"==typeof b&&\"cancel\"==a?this.un.push(b):n.call(this,a,b)};var m=e.removeEventListener;return e.removeEventListener=function(a,b){\"cancel\"==a?(a=this.un.indexOf(b),0<=a&&this.un.splice(a,1)):m.call(this,a,b)},e}}}();(function(a){var b=\ndocument.documentElement,c=null,e=!1;try{var g=getComputedStyle(b).getPropertyValue(\"opacity\"),g=\"0\"==g?\"1\":\"0\",c=b.animate({opacity:[g,g]},{duration:1});c.currentTime=0;e=getComputedStyle(b).getPropertyValue(\"opacity\")==g}catch(C){}finally{c&&c.cancel()}if(!e){var k=window.Element.prototype.animate;window.Element.prototype.animate=function(b,c){return window.Symbol&&Symbol.iterator&&Array.prototype.from&&b[Symbol.iterator]&&(b=Array.from(b)),Array.isArray(b)||null===b||(b=a.uK(b)),k.call(this,b,\nc)}}})(c);!function(a,b){function c(a){var b=window.document.timeline;b.currentTime=a;b.Ev();0==b.sf.length?g=!1:requestAnimationFrame(c)}var e=window.requestAnimationFrame;window.requestAnimationFrame=function(a){return e(function(b){window.document.timeline.nl();a(b);window.document.timeline.nl()})};b.AnimationTimeline=function(){this.sf=[];this.currentTime=void 0};b.AnimationTimeline.prototype={getAnimations:function(){return this.Ev(),this.sf.slice()},nl:function(){b.Wn=b.Wn.filter(function(a){return a.Vc()})},\nEv:function(){this.nl();this.sf=this.sf.filter(function(a){return\"finished\"!=a.playState&&\"idle\"!=a.playState})},Vj:function(a){a=new b.Animation(a,this);return this.sf.push(a),b.TP(),a.Vc(),a.hb.play(),a.Vc(),a},play:function(a){return a&&a.remove(),this.Vj(a)}};var g=!1;b.TP=function(){g||(g=!0,requestAnimationFrame(c))};var k=new b.AnimationTimeline;b.timeline=k;try{Object.defineProperty(window.document,\"timeline\",{configurable:!0,get:function(){return k}})}catch(C){}try{window.document.timeline=\nk}catch(C){}}(c,g,null);(function(a,b){b.Wn=[];b.Animation=function(b,c){if(this.id=\"\",b&&b.Kc&&(this.id=b.Kc),this.effect=b,b&&(b.hb=this),!c)throw Error(\"Animation with null timeline is not supported\");this.$j=c;this.Xj=a.sC++;this.pq=0;this.Fn=this.ag=!1;this.hb=null;this.Pi=[];this.cl=null;this.Xv=\"idle\";this.hl();this.hb.cancel();this.Vc()};b.Animation.prototype={Vc:function(){var a=this.Xv,b=this.playState;return this.Wj&&b!==a&&(\"idle\"==b?(this.KG(),this.Wj=void 0):\"pending\"==a?this.lw():\"pending\"==\nb&&(this.Wj=void 0)),this.nq&&b!==a&&(\"idle\"==b?(this.h1(),this.nq=void 0):\"finished\"==b?this.l1():\"finished\"==a&&(this.nq=void 0)),this.Xv=this.playState,this.Wj||this.nq},hl:function(){this.Vc();var a,c,e,g,k=!!this.hb;k&&(a=this.playbackRate,c=this.ag,e=this.startTime,g=this.currentTime,this.hb.cancel(),this.hb.Vn=null,this.hb=null);(!this.effect||this.effect instanceof window.KeyframeEffect)&&(this.hb=b.CO(this.effect),b.WJ(this));(this.effect instanceof window.SequenceEffect||this.effect instanceof\nwindow.GroupEffect)&&(this.hb=b.BO(this.effect),b.VJ(this));this.effect&&this.effect.bw&&b.Uw(this);k&&(1!=a&&(this.playbackRate=a),null!==e?this.startTime=e:null!==g?this.currentTime=g:null!==this.pq&&(this.currentTime=this.pq),c&&this.pause());this.Vc()},jH:function(){if(this.effect&&\"idle\"!=this.playState){var a=this.effect.Kf.delay;this.Pi.forEach(function(c){this.sv(c,a);this.effect instanceof window.SequenceEffect&&(a+=b.aB(c.effect))}.bind(this))}},qw:function(a){if(this.effect&&this.Fn)for(var b=\n0;b<this.effect.children.length;b++)this.effect.children[b].hb=a,this.Pi[b].qw(a)},Bv:function(){if(this.effect&&this.Fn){var a=this.effect.Kf.delay;this.il();this.effect.children.forEach(function(c){var e=window.document.timeline.Vj(c);this.Pi.push(e);e.playbackRate=this.playbackRate;this.ag&&e.pause();c.hb=this.effect.hb;this.sv(e,a);this.effect instanceof window.SequenceEffect&&(a+=b.aB(c))}.bind(this))}},sv:function(a,b){null===this.startTime?a.currentTime=this.currentTime-b/this.playbackRate:\na.startTime!==this.startTime+b/this.playbackRate&&(a.startTime=this.startTime+b/this.playbackRate)},get timeline(){return this.$j},get playState(){return this.hb?this.hb.playState:\"idle\"},get ready(){return window.Promise?(this.Wj||(-1==b.Wn.indexOf(this)&&b.Wn.push(this),this.Wj=new Promise(function(a,b){this.lw=function(){a(this)};this.KG=function(){b({type:DOMException.ABORT_ERR,name:\"AbortError\"})}}.bind(this)),\"pending\"!==this.playState&&this.lw()),this.Wj):(console.warn(\"Animation Promises require JavaScript Promise constructor\"),\nnull)},get onfinish(){return this.hb.onfinish},set onfinish(a){\"function\"==typeof a?this.hb.onfinish=function(b){b.target=this;a.call(this,b)}.bind(this):this.hb.onfinish=a},get oncancel(){return this.hb.oncancel},set oncancel(a){\"function\"==typeof a?this.hb.oncancel=function(b){b.target=this;a.call(this,b)}.bind(this):this.hb.oncancel=a},get currentTime(){this.Vc();var a=this.hb.currentTime;return this.Vc(),a},set currentTime(a){this.Vc();this.hb.currentTime=isFinite(a)?a:Math.sign(a)*Number.MAX_VALUE;\nthis.Zh();this.Ti(function(b,c){b.currentTime=a-c});this.Vc()},get startTime(){return this.hb.startTime},set startTime(a){this.Vc();this.hb.startTime=isFinite(a)?a:Math.sign(a)*Number.MAX_VALUE;this.Zh();this.Ti(function(b,c){b.startTime=a+c});this.Vc()},get playbackRate(){return this.hb.playbackRate},set playbackRate(a){this.Vc();var b=this.currentTime;this.hb.playbackRate=a;this.Ti(function(b){b.playbackRate=a});\"paused\"!=this.playState&&\"idle\"!=this.playState&&this.play();null!==b&&(this.currentTime=\nb);this.Vc()},play:function(){this.Vc();this.ag=!1;this.hb.play();-1==this.$j.sf.indexOf(this)&&this.$j.sf.push(this);this.Zh();b.Qw(this);this.Ti(function(a){var b=a.currentTime;a.play();a.currentTime=b});this.Vc()},pause:function(){this.Vc();this.currentTime&&(this.pq=this.currentTime);this.hb.pause();this.Zh();this.Ti(function(a){a.pause()});this.ag=!0;this.Vc()},finish:function(){this.Vc();this.hb.finish();this.Zh();this.Vc()},cancel:function(){this.Vc();this.hb.cancel();this.Zh();this.il();this.Vc()},\nreverse:function(){this.Vc();var a=this.currentTime;this.hb.reverse();this.Ti(function(a){a.reverse()});null!==a&&(this.currentTime=a);this.Vc()},addEventListener:function(a,b){var c=b;\"function\"==typeof b&&(c=function(a){a.target=this;b.call(this,a)}.bind(this),b.Vn=c);this.hb.addEventListener(a,c)},removeEventListener:function(a,b){this.hb.removeEventListener(a,b&&b.Vn||b)},il:function(){for(;this.Pi.length;)this.Pi.pop().cancel()},Ti:function(b){var c=0;if(this.effect.children&&this.Pi.length<\nthis.effect.children.length&&this.Bv(),this.Pi.forEach(function(a){b.call(this,a,c);this.effect instanceof window.SequenceEffect&&(c+=a.effect.rl)}.bind(this)),\"pending\"!=this.playState){var e=this.effect.Kf,g=this.currentTime;null!==g&&(g=a.bo(a.dk(e),g,e));(null==g||isNaN(g))&&this.il()}}};window.Animation=b.Animation})(c,g,null);(function(a,b){function c(b){this.OF=a.TB(b)}function e(){for(var a=!1;E.length;)a=E.shift(),a.jH(),a=!0;return a}var g=function(a){if(a.hb=void 0,a instanceof window.SequenceEffect||\na instanceof window.GroupEffect)for(var b=0;b<a.children.length;b++)g(a.children[b])};b.Ds=function(a){for(var b=[],c=0;c<a.length;c++){var e=a[c];e.Ye?(-1==b.indexOf(e.Ye)&&b.push(e.Ye),e.Ye.children.splice(e.Ye.children.indexOf(e),1),e.Ye=null,g(e)):e.hb&&e.hb.effect==e&&(e.hb.cancel(),e.hb.effect=new KeyframeEffect(null,[]),e.hb.cl&&(e.hb.cl.hb=null),e.hb.hl(),g(e))}for(c=0;c<b.length;c++)b[c].fw()};b.KeyframeEffect=function(b,e,g,k){return this.target=b,this.Ye=null,g=a.ws(g),this.ak=a.io(g),\nthis.Kf=a.pj(g),this.timing=a.KB(g,!1,this),this.timing.kc=this,\"function\"==typeof e?(a.IK(\"Custom KeyframeEffect\",\"2015-06-22\",\"Use KeyframeEffect.onsample instead.\"),this.Xi=e):this.Xi=new c(e),this.tq=e,this.rl=a.dk(this.Kf),this.Kc=k,this};b.KeyframeEffect.prototype={getFrames:function(){return\"function\"==typeof this.Xi?this.Xi:this.Xi.OF},set onsample(a){if(\"function\"==typeof this.getFrames())throw Error(\"Setting onsample on custom effect KeyframeEffect is not supported.\");this.bw=a;this.hb&&\nthis.hb.hl()},get parent(){return this.Ye},clone:function(){if(\"function\"==typeof this.getFrames())throw Error(\"Cloning custom effects is not supported.\");var b=new KeyframeEffect(this.target,[],a.io(this.ak),this.Kc);return b.Xi=this.Xi,b.tq=this.tq,b},remove:function(){b.Ds([this])}};var k=Element.prototype.animate;Element.prototype.animate=function(a,c){var e=\"\";return c&&c.id&&(e=c.id),b.timeline.Vj(new b.KeyframeEffect(this,a,c,e))};var m=document.createElementNS(\"http://www.w3.org/1999/xhtml\",\n\"div\");b.CO=function(a){if(a){var b=a.target||m,c=a.tq;\"function\"==typeof c&&(c=[]);var e=a.ak;e.id=a.Kc}else b=m,c=[],e=0;return k.apply(b,[c,e])};b.WJ=function(a){a.effect&&\"function\"==typeof a.effect.Xi&&b.Uw(a)};var E=[];b.Qw=function(a){null===a.startTime&&a.Fn&&(0==E.length&&requestAnimationFrame(e),E.push(a))};var W=window.getComputedStyle;Object.defineProperty(window,\"getComputedStyle\",{configurable:!0,enumerable:!0,value:function(){window.document.timeline.nl();var a=W.apply(this,arguments);\nreturn e()&&(a=W.apply(this,arguments)),window.document.timeline.nl(),a}});window.KeyframeEffect=b.KeyframeEffect;window.Element.prototype.getAnimations=function(){return document.timeline.getAnimations().filter(function(a){return null!==a.effect&&a.effect.target==this}.bind(this))}})(c,g,null);(function(a,b){function c(a){a.Kn||(a.Kn=!0,k.push(a),m||(m=!0,requestAnimationFrame(e)))}function e(){var a=k;k=[];a.sort(function(a,b){return a.Xj-b.Xj});a=a.filter(function(a){a();var b=a.hb?a.hb.playState:\n\"idle\";return\"running\"!=b&&\"pending\"!=b&&(a.Kn=!1),a.Kn});k.push.apply(k,a);k.length?(m=!0,requestAnimationFrame(e)):m=!1}var g=(document.createElementNS(\"http://www.w3.org/1999/xhtml\",\"div\"),0);b.Uw=function(b){var e,k=b.effect.target,n=\"function\"==typeof b.effect.getFrames();e=n?b.effect.getFrames():b.effect.bw;var m=b.effect.timing,q=null,m=a.pj(m),v=function(){var c=v.hb?v.hb.currentTime:null;null!==c&&(c=a.bo(a.dk(m),c,m),isNaN(c)&&(c=null));c!==q&&(n?e(c,k,b.effect):e(c,b.effect,b.effect.hb));\nq=c};v.hb=b;v.Kn=!1;v.Xj=g++;b.cl=v;c(v)};var k=[],m=!1;b.Animation.prototype.Zh=function(){this.cl&&c(this.cl)}})(c,g,null);(function(a,b){function c(a){return a.Kf.delay+a.rl+a.Kf.endDelay}function e(b,c,e){this.Kc=e;this.Ye=null;this.children=b||[];this.iw(this.children);c=a.ws(c);this.ak=a.io(c);this.Kf=a.pj(c,!0);this.timing=a.KB(c,!0,this);this.timing.kc=this;\"auto\"===this.Kf.duration&&(this.Kf.duration=this.rl)}window.SequenceEffect=function(){e.apply(this,arguments)};window.GroupEffect=function(){e.apply(this,\narguments)};e.prototype={ZF:function(a){for(var b=this;null!==b;){if(b==a)return!0;b=b.Ye}return!1},fw:function(){for(var a=this;a;)\"auto\"===a.timing.duration&&(a.Kf.duration=a.rl),a=a.Ye;this.hb&&this.hb.hl()},iw:function(a){b.Ds(a);for(var c=0;c<a.length;c++)a[c].Ye=this},ew:function(a,b){for(var c=b?\"Cannot append an ancestor or self\":\"Cannot prepend an ancestor or self\",e=0;e<a.length;e++)if(this.ZF(a[e]))throw{type:DOMException.HIERARCHY_REQUEST_ERR,name:\"HierarchyRequestError\",message:c};for(e=\n0;e<a.length;e++)b?this.children.push(a[e]):this.children.unshift(a[e]);this.iw(a);this.fw()},append:function(){this.ew(arguments,!0)},prepend:function(){this.ew(arguments,!1)},get parent(){return this.Ye},get firstChild(){return this.children.length?this.children[0]:null},get lastChild(){return this.children.length?this.children[this.children.length-1]:null},clone:function(){for(var b=a.io(this.ak),c=[],e=0;e<this.children.length;e++)c.push(this.children[e].clone());return this instanceof GroupEffect?\nnew GroupEffect(c,b):new SequenceEffect(c,b)},remove:function(){b.Ds([this])}};window.SequenceEffect.prototype=Object.create(e.prototype);Object.defineProperty(window.SequenceEffect.prototype,\"activeDuration\",{get:function(){var a=0;return this.children.forEach(function(b){a+=c(b)}),Math.max(a,0)}});window.GroupEffect.prototype=Object.create(e.prototype);Object.defineProperty(window.GroupEffect.prototype,\"activeDuration\",{get:function(){var a=0;return this.children.forEach(function(b){a=Math.max(a,\nc(b))}),a}});b.BO=function(c){var e,g=null,k=function(b){var c=e.Vn;return c&&\"pending\"!=c.playState&&c.effect?null==b?void c.il():0==b&&0>c.playbackRate&&(g||(g=a.pj(c.effect.timing)),b=a.bo(a.dk(g),-1,g),isNaN(b)||null==b)?(c.Ti(function(a){a.currentTime=-1}),void c.il()):void 0:void 0};c=new KeyframeEffect(null,[],c.Kf,c.Kc);return c.onsample=k,e=b.timeline.Vj(c)};b.VJ=function(a){a.hb.Vn=a;a.Fn=!0;b.Qw(a);a.Bv();a.qw(a)};b.aB=c})(c,g,null);b[\"true\"]=a}({},function(){return this}())})();\nV.Gi.np={};V.Gi.np.bZ={};Polymer({is:\"opaque-animation\",behaviors:[Polymer.Rh],bj:function(a){var b=a.node;b.style.opacity=\"0\";return this.kc=new KeyframeEffect(b,[{opacity:\"1\"},{opacity:\"1\"}],this.zj(a))},complete:function(a){a.node.style.opacity=\"\"}});V.Gi.Fu={};\nPolymer.Fu={properties:{animationConfig:{type:Object},entryAnimation:{observer:\"f0\",type:String},exitAnimation:{observer:\"g0\",type:String}},f0:function(){this.animationConfig=this.animationConfig||{};this.animationConfig.entry=\"fade-in-animation\"!==this.entryAnimation?[{name:\"opaque-animation\",node:this},{name:this.entryAnimation,node:this}]:[{name:this.entryAnimation,node:this}]},g0:function(){this.animationConfig=this.animationConfig||{};this.animationConfig.exit=[{name:this.exitAnimation,node:this}]},\nCv:function(a,b){for(var c in b)a[c]=b[c]},nF:function(a){var b={pN:!0};this.Cv(b,a);return b},Lv:function(a,b,c){if(this.animationConfig)if(this.animationConfig.value&&\"function\"===typeof this.animationConfig.value)this._warn(this._logf(\"playAnimation\",\"Please put 'animationConfig' inside of your components 'properties' object instead of outside of it.\"));else{var e;e=a?this.animationConfig[a]:this.animationConfig;Array.isArray(e)||(e=[e]);if(e)for(var g,k=0;g=e[k];k++)if(g.HJ)g.HJ.Lv(g.type||a,\nb,c);else if(g.id){var m=b[g.id];m?(m.pN||(b[g.id]=this.nF(m),m=b[g.id]),this.Cv(m,g)):b[g.id]=g}else c.push(g)}},fL:function(a){var b={},c=[];this.Lv(a,b,c);for(var e in b)c.push(b[e]);return c}};V.Gi.Ep={};\nPolymer.aE={properties:{_player:{type:Object}},rF:function(a){var b=[];if(0<a.length)for(var c,e=0;c=a[e];e++){var g=document.createElement(c.name);if(g.zN){var k=g.bj(c);k&&b.push({IJ:g,gx:c,effect:k})}else Polymer.Base._warn(this.is+\":\",c.name,\"not found!\")}return b},OG:function(a){return document.timeline.play(new GroupEffect(a))},pF:function(a){for(var b,c=0;b=a[c];c++)b.IJ.complete(b.gx)},Oo:function(a,b){if(a=this.fL(a)){var c=this.rF(a);a=c.map(function(a){return a.effect});0<a.length?(this._player=\nthis.OG(a),this._player.onfinish=function(){this.pF(c);this._player&&(this._player.cancel(),this._player=null);this.fire(\"neon-animation-finish\",b,{bubbles:!1})}.bind(this)):this.fire(\"neon-animation-finish\",b,{bubbles:!1})}},eo:function(){this._player&&this._player.cancel()}};Polymer.Ep=[Polymer.Fu,Polymer.aE];V.Qh={};V.Qh.ou={};\n(function(){var a=Element.prototype,b=a.matches||a.matchesSelector||a.mozMatchesSelector||a.msMatchesSelector||a.oMatchesSelector||a.webkitMatchesSelector;Polymer.ou={CM:function(a){var b=[];return(a=this.yv(a,b))?this.Bq(b):b},rB:function(a){return b.call(a,\"input, select, textarea, button, object\")?b.call(a,\":not([disabled])\"):b.call(a,\"a[href], area[href], iframe, [tabindex], [contentEditable]\")},R7:function(a){return this.rB(a)&&b.call(a,':not([tabindex\\x3d\"-1\"])')&&this.Ov(a)},oG:function(a){return this.rB(a)?\n(a=a.getAttribute(\"tabindex\")||0,Number(a)):-1},yv:function(a,b){if(a.nodeType!==Node.ELEMENT_NODE||!this.Ov(a))return!1;var c=a,e=this.oG(c);a=0<e;0<=e&&b.push(c);c=\"content\"===c.localName?Polymer.dom(c).getDistributedNodes():Polymer.dom(c.root||c).children;for(e=0;e<c.length;e++){var m=this.yv(c[e],b);a=a||m}return a},Ov:function(a){var b=a.style;return\"hidden\"!==b.visibility&&\"none\"!==b.display?(b=window.getComputedStyle(a),\"hidden\"!==b.visibility&&\"none\"!==b.display):!1},Bq:function(a){var b=\na.length;if(2>b)return a;var c=Math.ceil(b/2),b=this.Bq(a.slice(0,c));a=this.Bq(a.slice(c));return this.kG(b,a)},kG:function(a,b){for(var c=[];0<a.length&&0<b.length;)this.WF(a[0],b[0])?c.push(b.shift()):c.push(a.shift());return c.concat(a,b)},WF:function(a,b){a=Math.max(a.tabIndex,0);b=Math.max(b.tabIndex,0);return 0===a||0===b?b>a:a>b}}})();V.Qh.nY={};\nPolymer({is:\"iron-overlay-backdrop\",properties:{opened:{reflectToAttribute:!0,type:Boolean,value:!1,observer:\"Yh\"}},listeners:{transitionend:\"$0\"},created:function(){this.$k=null},attached:function(){this.opened&&this.Yh(this.opened)},YO:function(){this.opened&&!this.parentNode&&Polymer.dom(document.body).appendChild(this)},open:function(){this.opened=!0},close:function(){this.opened=!1},complete:function(){this.opened||this.parentNode!==document.body||Polymer.dom(this.parentNode).removeChild(this)},\n$0:function(a){a&&a.target===this&&this.complete()},Yh:function(a){a?this.YO():(a=window.getComputedStyle(this),\"0s\"!==a.transitionDuration&&0!=a.opacity||this.complete());this.isAttached&&(this.$k&&(window.cancelAnimationFrame(this.$k),this.$k=null),this.scrollTop=this.scrollTop,this.$k=window.requestAnimationFrame(function(){this.$k=null;this.toggleClass(\"opened\",this.opened)}.bind(this)))}});V.Qh.vu={};\nPolymer.Ap=function(){this.Me=[];this.Hn=101;this.rn=null;Polymer.Gestures.add(document,\"tap\",this.vq.bind(this));document.addEventListener(\"focus\",this.wq.bind(this),!0);document.addEventListener(\"keydown\",this.tG.bind(this),!0)};\nPolymer.Ap.prototype={constructor:Polymer.Ap,get Xn(){this.rn||(this.rn=document.createElement(\"iron-overlay-backdrop\"));return this.rn},get sx(){for(var a=document.activeElement||document.body;a.root&&Polymer.dom(a.root).activeElement;)a=Polymer.dom(a.root).activeElement;return a},jF:function(a){var b=this.Me[a];if(b){var c=this.Me.length-1,e=this.Me[c];e&&this.rw(b,e)&&c--;if(!(a>=c)){e=Math.max(this.AK(),this.Hn);for(this.Pj(b)<=e&&this.$p(b,e);a<c;)this.Me[a]=this.Me[a+1],a++;this.Me[c]=b}}},\nRI:function(a){var b=this.Me.indexOf(a);if(0<=b)this.jF(b);else{var b=this.Me.length,c=this.Me[b-1],e=Math.max(this.Pj(c),this.Hn),g=this.Pj(a);c&&this.rw(a,c)&&(this.$p(c,e),b--,c=this.Me[b-1],e=Math.max(this.Pj(c),this.Hn));g<=e&&this.$p(a,e);this.Me.splice(b,0,a)}this.yt()},gC:function(a){a=this.Me.indexOf(a);-1!==a&&(this.Me.splice(a,1),this.yt())},Cl:function(){var a=this.Me.length-1;return this.Me[a]},AK:function(){return this.Pj(this.Cl())},yt:function(){var a=this.FG();if(a||this.rn)this.Xn.style.zIndex=\nthis.Pj(a)-1,this.Xn.opened=!!a},FG:function(){for(var a=0;a<this.Me.length;a++)if(this.Me[a].withBackdrop)return this.Me[a]},Pj:function(a){var b=this.Hn;a&&(a=Number(a.style.zIndex||window.getComputedStyle(a).zIndex),a===a&&(b=a));return b},UG:function(a,b){a.style.zIndex=b},$p:function(a,b){this.UG(a,b+2)},DG:function(a){a=a||[];for(var b=0;b<a.length;b++)if(a[b]._manager===this)return a[b]},vq:function(a){var b=this.Cl();b&&this.DG(Polymer.dom(a).path)!==b&&b.vq(a)},wq:function(a){var b=this.Cl();\nb&&b.wq(a)},tG:function(a){var b=this.Cl();b&&(Polymer.mg.Ho(a,\"esc\")?b.sG(a):Polymer.mg.Ho(a,\"tab\")&&b.vG(a))},rw:function(a,b){return!a.alwaysOnTop&&b.alwaysOnTop}};Polymer.vu=new Polymer.Ap;V.Xm={};V.Xm.Xm={};\nPolymer.Xm={properties:{sizingTarget:{type:Object,value:function(){return this}},fitInto:{type:Object,value:window},noOverlap:{type:Boolean},positionTarget:{type:Element},horizontalAlign:{type:String},verticalAlign:{type:String},dynamicAlign:{type:Boolean},horizontalOffset:{type:Number,value:0,notify:!0},verticalOffset:{type:Number,value:0,notify:!0},autoFitOnAttach:{type:Boolean,value:!1},_fitInfo:{type:Object}},get k0(){var a;return a=this.fitInto===window?this.fitInto.innerWidth:this.fitInto.getBoundingClientRect().width},\nget h0(){var a;return a=this.fitInto===window?this.fitInto.innerHeight:this.fitInto.getBoundingClientRect().height},get i0(){var a;return a=this.fitInto===window?0:this.fitInto.getBoundingClientRect().left},get j0(){var a;return a=this.fitInto===window?0:this.fitInto.getBoundingClientRect().top},get sF(){var a=Polymer.dom(this).parentNode;a&&a.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&(a=a.host);return a},get gG(){if(this.aG){if(\"right\"===this.horizontalAlign)return\"left\";if(\"left\"===this.horizontalAlign)return\"right\"}return this.horizontalAlign},\nattached:function(){this.aG=\"rtl\"==window.getComputedStyle(this).direction;this.positionTarget=this.positionTarget||this.sF;this.autoFitOnAttach&&(\"none\"===window.getComputedStyle(this).display?setTimeout(function(){this.fit()}.bind(this)):this.fit())},fit:function(){this.position();this.oK();this.center()},jq:function(){if(!this._fitInfo){var a=window.getComputedStyle(this),b=window.getComputedStyle(this.sizingTarget);this._fitInfo={pk:{top:this.style.top||\"\",left:this.style.left||\"\",position:this.style.position||\n\"\"},yC:{maxWidth:this.sizingTarget.style.maxWidth||\"\",maxHeight:this.sizingTarget.style.maxHeight||\"\",boxSizing:this.sizingTarget.style.boxSizing||\"\"},om:{Km:\"auto\"!==a.top?\"top\":\"auto\"!==a.bottom?\"bottom\":null,fm:\"auto\"!==a.left?\"left\":\"auto\"!==a.right?\"right\":null},Zo:{height:\"none\"!==b.maxHeight,width:\"none\"!==b.maxWidth,minWidth:parseInt(b.minWidth,10)||0,minHeight:parseInt(b.minHeight,10)||0},margin:{top:parseInt(a.marginTop,10)||0,right:parseInt(a.marginRight,10)||0,bottom:parseInt(a.marginBottom,\n10)||0,left:parseInt(a.marginLeft,10)||0}};this.verticalOffset&&(this._fitInfo.margin.top=this._fitInfo.margin.bottom=this.verticalOffset,this._fitInfo.pk.marginTop=this.style.marginTop||\"\",this._fitInfo.pk.marginBottom=this.style.marginBottom||\"\",this.style.marginTop=this.style.marginBottom=this.verticalOffset+\"px\");this.horizontalOffset&&(this._fitInfo.margin.left=this._fitInfo.margin.right=this.horizontalOffset,this._fitInfo.pk.marginLeft=this.style.marginLeft||\"\",this._fitInfo.pk.marginRight=\nthis.style.marginRight||\"\",this.style.marginLeft=this.style.marginRight=this.horizontalOffset+\"px\")}},OP:function(){var a=this._fitInfo||{},b;for(b in a.yC)this.sizingTarget.style[b]=a.yC[b];for(b in a.pk)this.style[b]=a.pk[b];this._fitInfo=null},As:function(){var a=this.sizingTarget.scrollLeft,b=this.sizingTarget.scrollTop;this.OP();this.fit();this.sizingTarget.scrollLeft=a;this.sizingTarget.scrollTop=b},position:function(){if(this.horizontalAlign||this.verticalAlign){this.jq();this.style.position=\n\"fixed\";this.sizingTarget.style.boxSizing=\"border-box\";this.style.left=\"0px\";this.style.top=\"0px\";var a=this.getBoundingClientRect(),b=this.qn(this.positionTarget),c=this.qn(this.fitInto),e=this._fitInfo.margin,g={width:a.width+e.left+e.right,height:a.height+e.top+e.bottom},g=this.eF(this.gG,this.verticalAlign,g,b,c),b=g.left+e.left,g=g.top+e.top,k=Math.min(c.right-e.right,b+a.width),c=Math.min(c.bottom-e.bottom,g+a.height),m=this._fitInfo.Zo.minWidth,n=this._fitInfo.Zo.minHeight;b<e.left&&(b=e.left,\nk-b<m&&(b=k-m));g<e.top&&(g=e.top,c-g<n&&(g=c-n));this.sizingTarget.style.maxWidth=k-b+\"px\";this.sizingTarget.style.maxHeight=c-g+\"px\";this.style.left=b-a.left+\"px\";this.style.top=g-a.top+\"px\"}},oK:function(){if(!this.horizontalAlign&&!this.verticalAlign){this.jq();var a=this._fitInfo;a.om.Km||(this.style.position=\"fixed\",this.style.top=\"0px\");a.om.fm||(this.style.position=\"fixed\",this.style.left=\"0px\");this.sizingTarget.style.boxSizing=\"border-box\";var b=this.getBoundingClientRect();a.Zo.height||\nthis.Yp(b,a.om.Km,\"top\",\"bottom\",\"Height\");a.Zo.width||this.Yp(b,a.om.fm,\"left\",\"right\",\"Width\")}},t1:function(a,b,c,e,g){this.Yp(a,b,c,e,g)},Yp:function(a,b,c,e,g){var k=this._fitInfo,m=this.qn(this.fitInto),m=\"Width\"===g?m.width:m.height;a=(b=b===e)?m-a[e]:a[c];c=k.margin[b?c:e];e=\"offset\"+g;e=this[e]-this.sizingTarget[e];this.sizingTarget.style[\"max\"+g]=m-c-a-e+\"px\"},center:function(){if(!this.horizontalAlign&&!this.verticalAlign){this.jq();var a=this._fitInfo.om;if(!a.Km||!a.fm){this.style.position=\n\"fixed\";a.Km||(this.style.top=\"0px\");a.fm||(this.style.left=\"0px\");var b=this.getBoundingClientRect(),c=this.qn(this.fitInto);if(!a.Km){var e=c.top-b.top+(c.height-b.height)/2;this.style.top=e+\"px\"}a.fm||(a=c.left-b.left+(c.width-b.width)/2,this.style.left=a+\"px\")}}},qn:function(a){return a===document.documentElement||a===window?{top:0,left:0,width:window.innerWidth,height:window.innerHeight,right:window.innerWidth,bottom:window.innerHeight}:a.getBoundingClientRect()},dF:function(a,b,c){var e=Math.min(0,\na.top)+Math.min(0,c.bottom-(a.top+b.height));a=Math.min(0,a.left)+Math.min(0,c.right-(a.left+b.width));return Math.abs(e)*b.width+Math.abs(a)*b.height},eF:function(a,b,c,e,g){var k=[{verticalAlign:\"top\",horizontalAlign:\"left\",top:e.top,left:e.left},{verticalAlign:\"top\",horizontalAlign:\"right\",top:e.top,left:e.right-c.width},{verticalAlign:\"bottom\",horizontalAlign:\"left\",top:e.bottom-c.height,left:e.left},{verticalAlign:\"bottom\",horizontalAlign:\"right\",top:e.bottom-c.height,left:e.right-c.width}];\nif(this.noOverlap){for(var m=0,n=k.length;m<n;m++){var q={},v;for(v in k[m])q[v]=k[m][v];k.push(q)}k[0].top=k[1].top+=e.height;k[2].top=k[3].top-=e.height;k[4].left=k[6].left+=e.width;k[5].left=k[7].left-=e.width}b=\"auto\"===b?null:b;a=\"auto\"===a?null:a;for(var B,m=0;m<k.length;m++){e=k[m];if(!this.dynamicAlign&&!this.noOverlap&&e.verticalAlign===b&&e.horizontalAlign===a){B=e;break}n=(!b||e.verticalAlign===b)&&(!a||e.horizontalAlign===a);if(this.dynamicAlign||n){B=B||e;e.or=this.dF(e,c,g);q=e.or-B.or;\nif(0>q||0===q&&n)B=e;if(0===B.or&&n)break}}return B}};V.Qh.Qh={};\nPolymer.Lk={properties:{opened:{observer:\"Yh\",type:Boolean,value:!1,notify:!0},canceled:{observer:\"L_\",readOnly:!0,type:Boolean,value:!1},withBackdrop:{observer:\"H1\",type:Boolean},noAutoFocus:{type:Boolean,value:!1},noCancelOnEscKey:{type:Boolean,value:!1},noCancelOnOutsideClick:{type:Boolean,value:!1},closingReason:{type:Object},restoreFocusOnClose:{type:Boolean,value:!1},alwaysOnTop:{type:Boolean},_manager:{type:Object,value:Polymer.vu},_focusedChild:{type:Object}},listeners:{\"iron-resize\":\"U0\"},\nget Xn(){return this._manager.Xn},get An(){return this._focusedChild||Polymer.dom(this).querySelector(\"[autofocus]\")||this},get LF(){return Polymer.ou.CM(this)},ready:function(){this.Xp=this.Yk=!1;this.al=this.Mi=this.Xk=this.Zk=null;this.CF()},attached:function(){this.opened&&this.Yh(this.opened);this.gl=Polymer.dom(this).observeNodes(this.zG)},detached:function(){Polymer.dom(this).unobserveNodes(this.gl);this.gl=null;this.Mi&&(window.cancelAnimationFrame(this.Mi),this.Mi=null);this._manager.gC(this)},\ntoggle:function(){this._setCanceled(!1);this.opened=!this.opened},open:function(){this._setCanceled(!1);this.opened=!0},close:function(){this._setCanceled(!1);this.opened=!1},cancel:function(a){a=this.fire(\"iron-overlay-canceled\",a,{cancelable:!0});a.defaultPrevented||(this._setCanceled(!0),this.opened=!1)},kN:function(){this.Xk=this.Zk=null},CF:function(){this.EG||(this.EG=!0,this.style.outline=\"none\",this.style.display=\"none\")},Yh:function(a){a?this.removeAttribute(\"aria-hidden\"):this.setAttribute(\"aria-hidden\",\n\"true\");this.isAttached&&(this.Yk=!0,this.jv(this.fF))},L_:function(){this.closingReason=this.closingReason||{};this.closingReason.canceled=this.canceled},H1:function(){this.withBackdrop&&!this.hasAttribute(\"tabindex\")?(this.setAttribute(\"tabindex\",\"-1\"),this.Xp=!0):this.Xp&&(this.removeAttribute(\"tabindex\"),this.Xp=!1);this.opened&&this.isAttached&&this._manager.yt()},HG:function(){this.al=this._manager.sx;this.GG();this.As();this.HF();this.noAutoFocus&&document.activeElement===this.An&&(this.An.blur(),\nthis.al.focus())},Mn:function(){this.mq()},Ln:function(){this.lq()},mq:function(){this.ri();this.Yk=!1;this.fire(\"iron-overlay-opened\")},lq:function(){this.style.display=\"none\";this.style.zIndex=\"\";this.ri();this.Yk=!1;this.fire(\"iron-overlay-closed\",this.closingReason)},GG:function(){this.style.transition=this.style.webkitTransition=\"none\";this.style.transform=this.style.webkitTransform=\"none\";this.style.display=\"\"},HF:function(){this.style.display=\"none\";this.scrollTop=this.scrollTop;this.style.transition=\nthis.style.webkitTransition=\"\";this.style.transform=this.style.webkitTransform=\"\";this.style.display=\"\";this.scrollTop=this.scrollTop},Oi:function(){if(this.opened)this.noAutoFocus||this.An.focus();else{this.An.blur();this._focusedChild=null;this.restoreFocusOnClose&&this.al&&this.al.focus();this.al=null;var a=this._manager.Cl();a&&this!==a&&a.Oi()}},vq:function(a){this.noCancelOnOutsideClick||this.cancel(a)},wq:function(a){if(this.withBackdrop){var b=Polymer.dom(a).path;-1===b.indexOf(this)?(a.stopPropagation(),\nthis.Oi()):this._focusedChild=b[0]}},sG:function(a){this.noCancelOnEscKey||this.cancel(a)},vG:function(a){if(this.withBackdrop){this.cF();var b=a.shiftKey,c=b?this.Xk:this.Zk,b=b?this.Zk:this.Xk;if(c===b)c=!0;else var e=this._manager.sx,c=e===c||e===this;c&&(a.preventDefault(),this._focusedChild=b,this.Oi())}},U0:function(){this.opened&&!this.Yk&&this.jv(this.As)},zG:function(){this.opened&&!this.Yk&&(this.kN(),this.ri())},cF:function(){if(!this.Xk||!this.Zk){var a=this.LF;this.Xk=a[0];this.Zk=a[a.length-\n1]}},fF:function(){this.opened?(this.HG(),this._manager.RI(this),this.Oi(),this.Mn()):(this._manager.gC(this),this.Oi(),this.Ln())},jv:function(a){this.Mi&&window.cancelAnimationFrame(this.Mi);var b=this;this.Mi=window.requestAnimationFrame(function(){b.Mi=null;a.call(b)})}};Polymer.Qh=[Polymer.Xm,Polymer.Jj,Polymer.Lk];V.Qk={};V.Qk.Qk={};\nPolymer.nE={hostAttributes:{role:\"dialog\",tabindex:\"-1\"},properties:{modal:{type:Boolean,value:!1}},observers:[\"F0(modal,_readied)\"],listeners:{tap:\"M0\"},ready:function(){this.lv=this.noCancelOnOutsideClick;this.kv=this.noCancelOnEscKey;this.mv=this.withBackdrop},F0:function(a,b){b&&(a?(this.lv=this.noCancelOnOutsideClick,this.kv=this.noCancelOnEscKey,this.mv=this.withBackdrop,this.withBackdrop=this.noCancelOnEscKey=this.noCancelOnOutsideClick=!0):(this.noCancelOnOutsideClick=this.noCancelOnOutsideClick&&\nthis.lv,this.noCancelOnEscKey=this.noCancelOnEscKey&&this.kv,this.withBackdrop=this.withBackdrop&&this.mv))},kH:function(a){this.closingReason=this.closingReason||{};this.closingReason.c4=a},M0:function(a){for(var b=Polymer.dom(a).path,c=0;c<b.indexOf(this);c++){var e=b[c];if(e.hasAttribute&&(e.hasAttribute(\"dialog-dismiss\")||e.hasAttribute(\"dialog-confirm\"))){this.kH(e.hasAttribute(\"dialog-confirm\"));this.close();a.stopPropagation();break}}}};Polymer.Qk=[Polymer.Qh,Polymer.nE];V.zD={};V.zD.FZ={};\nV.Vf.LE={};V.Qk.lZ={};V.Qu={};V.Qu.Qu={};Polymer({is:\"paper-dialog\",behaviors:[Polymer.Qk,Polymer.Ep],listeners:{\"neon-animation-finish\":\"yG\"},Mn:function(){this.eo();this.Oo(\"entry\")},Ln:function(){this.eo();this.Oo(\"exit\")},yG:function(){this.opened?this.mq():this.lq()}});V.Rk={};V.Rk.mZ={};V.Rk.oZ={};V.Qg={};V.Qg.Qg={};\nPolymer.Qg={properties:{name:{type:String},value:{notify:!0,type:String},required:{type:Boolean,value:!1},_parentForm:{type:Object}},attached:function(){this.fire(\"iron-form-element-register\")},detached:function(){this._parentForm&&this._parentForm.fire(\"iron-form-element-unregister\",{target:this})}};V.Rg={};V.Rg.Rg={};Polymer.Dp=null;\nPolymer.Rg={properties:{validator:{type:String},invalid:{notify:!0,reflectToAttribute:!0,type:Boolean,value:!1},_validatorMeta:{type:Object},validatorType:{type:String,value:\"validator\"},_validator:{type:Object,computed:\"A_(validator)\"}},observers:[\"YF(invalid)\"],registered:function(){Polymer.Dp=new Polymer.Ph({type:\"validator\"})},YF:function(){this.invalid?this.setAttribute(\"aria-invalid\",\"true\"):this.removeAttribute(\"aria-invalid\")},Zr:function(){return null!=this._validator},ah:function(a){this.invalid=\n!this.Cn(a);return!this.invalid},Cn:function(a){return this.Zr()?this._validator.ah(a):!0},A_:function(){return Polymer.Dp&&Polymer.Dp.er(this.validator)}};V.ph={};V.ph.Jp={};Polymer.hn={};Polymer.hn.cE=1;Polymer.hn.bE=1;\nPolymer.oE={properties:{label:{type:String},value:{notify:!0,type:String},disabled:{type:Boolean,value:!1},invalid:{type:Boolean,value:!1,notify:!0},preventInvalidInput:{type:Boolean},allowedPattern:{type:String},type:{type:String},list:{type:String},pattern:{type:String},required:{type:Boolean,value:!1},errorMessage:{type:String},charCounter:{type:Boolean,value:!1},noLabelFloat:{type:Boolean,value:!1},alwaysFloatLabel:{type:Boolean,value:!1},autoValidate:{type:Boolean,value:!1},validator:{type:String},\nautocomplete:{type:String,value:\"off\"},autofocus:{type:Boolean,observer:\"J_\"},inputmode:{type:String},minlength:{type:Number},maxlength:{type:Number},min:{type:String},max:{type:String},step:{type:String},name:{type:String},placeholder:{type:String,value:\"\"},readonly:{type:Boolean,value:!1},size:{type:Number},autocapitalize:{type:String,value:\"none\"},autocorrect:{type:String,value:\"off\"},autosave:{type:String},results:{type:Number},accept:{type:String},multiple:{type:Boolean},_ariaDescribedBy:{type:String,\nvalue:\"\"},_ariaLabelledBy:{type:String,value:\"\"}},listeners:{\"addon-attached\":\"qG\"},$g:{\"shift+tab:keydown\":\"AG\"},hostAttributes:{tabindex:0},get Ig(){return this.$.input},get Bn(){return this.Ig},registered:function(){this.eH=\"date datetime datetime-local month time week file\".split(\" \")},attached:function(){this.iH();this.Ig&&-1!==this.eH.indexOf(this.Ig.type)&&(this.alwaysFloatLabel=!0)},rv:function(a,b){return a=a?a+\" \"+b:b},qG:function(a){a=a.path?a.path[0]:a.target;if(a.id)this._ariaDescribedBy=\nthis.rv(this._ariaDescribedBy,a.id);else{var b=\"paper-input-add-on-\"+Polymer.hn.bE++;a.id=b;this._ariaDescribedBy=this.rv(this._ariaDescribedBy,b)}},ah:function(){return this.Ig.ah()},zn:function(a){Polymer.ng.zn.call(this,a);this.focused&&!this.Yj&&this.Bn.focus()},AG:function(){var a=this.getAttribute(\"tabindex\");this.Yj=!0;this.setAttribute(\"tabindex\",\"-1\");this.async(function(){this.setAttribute(\"tabindex\",a);this.Yj=!1},1)},o0:function(){this.autoValidate&&this.ah()},oda:function(a){try{var b=\nthis.Ig.selectionStart;this.value=a;this.Ig.selectionStart=b;this.Ig.selectionEnd=b}catch(c){this.value=a}},Q_:function(a,b){return b||a},iH:function(){var a=Polymer.dom(this.root).querySelector(\"label\");if(a){var b;a.id?b=a.id:(b=\"paper-input-label-\"+Polymer.hn.cE++,a.id=b);this._ariaLabelledBy=b}else this._ariaLabelledBy=\"\"},J0:function(a){this.shadowRoot&&this.fire(a.type,{sourceEvent:a},{node:this,bubbles:a.bubbles,cancelable:a.cancelable})},J_:function(){if(this.autofocus&&this.Bn){var a=document.activeElement,\nb=a instanceof HTMLElement;(a=b&&a!==document.body&&a!==document.documentElement)||this.Bn.focus()}}};Polymer.Jp=[Polymer.ng,Polymer.mg,Polymer.oE];V.ph.Ip={};Polymer.Ip={hostAttributes:{\"add-on\":\"\"},attached:function(){this.fire(\"addon-attached\")},update:function(){}};V.ph.rZ={};\nPolymer({is:\"paper-input-char-counter\",behaviors:[Polymer.Ip],properties:{_charCounterStr:{type:String,value:\"0\"}},update:function(a){if(a.Ig){a.value=a.value||\"\";var b=a.value.toString().length.toString();a.Ig.hasAttribute(\"maxlength\")&&(b+=\"/\"+a.Ig.getAttribute(\"maxlength\"));this._charCounterStr=b}}});V.ph.sZ={};\nPolymer({is:\"paper-input-container\",properties:{noLabelFloat:{type:Boolean,value:!1},alwaysFloatLabel:{type:Boolean,value:!1},attrForValue:{type:String,value:\"bind-value\"},autoValidate:{type:Boolean,value:!1},invalid:{observer:\"YF\",type:Boolean,value:!1},focused:{readOnly:!0,type:Boolean,value:!1,notify:!0},_addons:{type:Array},_inputHasContent:{type:Boolean,value:!1},_inputSelector:{type:String,value:\"input,textarea,.paper-input-input\"},_boundOnFocus:{type:Function,value:function(){return this.Yv.bind(this)}},\n_boundOnBlur:{type:Function,value:function(){return this.rG.bind(this)}},_boundOnInput:{type:Function,value:function(){return this.In.bind(this)}},_boundValueChanged:{type:Function,value:function(){return this.aw.bind(this)}}},listeners:{\"addon-attached\":\"qG\",\"iron-input-validate\":\"R0\"},get oH(){return this.attrForValue+\"-changed\"},get JG(){return Polymer.CaseMap.dashToCamelCase(this.attrForValue)},get Vh(){return Polymer.dom(this).querySelector(this._inputSelector)},get rq(){return this.Vh[this.JG]||\nthis.Vh.value},ready:function(){this._addons||(this._addons=[]);this.addEventListener(\"focus\",this._boundOnFocus,!0);this.addEventListener(\"blur\",this._boundOnBlur,!0)},attached:function(){this.attrForValue?this.Vh.addEventListener(this.oH,this._boundValueChanged):this.addEventListener(\"input\",this.In);\"\"!=this.rq?this.Dn(this.Vh):this.oq(this.Vh)},qG:function(a){this._addons||(this._addons=[]);a=a.target;-1===this._addons.indexOf(a)&&(this._addons.push(a),this.isAttached&&this.oq(this.Vh))},Yv:function(){this._setFocused(!0)},\nrG:function(){this._setFocused(!1);this.Dn(this.Vh)},In:function(a){this.Dn(a.target)},aw:function(a){this.Dn(a.target)},oq:function(a){var b=this.rq;b||0===b||\"number\"===a.type&&!a.checkValidity()?this._inputHasContent=!0:this._inputHasContent=!1;this.KC({Ig:a,value:b,invalid:this.invalid})},Dn:function(a){if(this.autoValidate){var b;b=a.ah?a.ah(this.rq):a.checkValidity();this.invalid=!b}this.oq(a)},R0:function(){this.invalid=this.Vh.invalid},YF:function(){this._addons&&this.KC({invalid:this.invalid})},\nKC:function(a){for(var b,c=0;b=this._addons[c];c++)b.update(a)},X_:function(a,b,c,e,g){var k=\"input-content\";a?g&&(k+=\" label-is-hidden\"):(a=this.querySelector(\"label\"),b||g?(k+=\" label-is-floating\",this.$.labelAndInputContainer.style.position=\"static\",e?k+=\" is-invalid\":c&&(k+=\" label-is-highlighted\")):a&&(this.$.labelAndInputContainer.style.position=\"relative\"));return k},b0:function(a,b){var c=\"underline\";b?c+=\" is-invalid\":a&&(c+=\" is-highlighted\");return c},P_:function(a,b){var c=\"add-on-content\";\nb?c+=\" is-invalid\":a&&(c+=\" is-highlighted\");return c}});V.ph.tZ={};Polymer({is:\"paper-input-error\",behaviors:[Polymer.Ip],properties:{invalid:{readOnly:!0,reflectToAttribute:!0,type:Boolean}},update:function(a){this._setInvalid(a.invalid)}});V.lg={};V.lg.lg={};Polymer.lg=function(){};\nPolymer.lg=Polymer({is:\"iron-a11y-announcer\",properties:{mode:{type:String,value:\"polite\"},_text:{type:String,value:\"\"}},created:function(){Polymer.lg.im||(Polymer.lg.im=this);document.body.addEventListener(\"iron-announce\",this.wG.bind(this))},JJ:function(a){this._text=\"\";this.async(function(){this._text=a},100)},wG:function(a){a.detail&&a.detail.text&&this.JJ(a.detail.text)}});Polymer.lg.im=null;\nPolymer.lg.LP=function(){Polymer.lg.im||(Polymer.lg.im=document.createElement(\"iron-a11y-announcer\"));document.body.appendChild(Polymer.lg.im)};V.su={};V.su.su={};\nPolymer({is:\"iron-input\",extends:\"input\",behaviors:[Polymer.Rg],properties:{bindValue:{observer:\"iF\",type:String},preventInvalidInput:{type:Boolean},allowedPattern:{type:String,observer:\"E_\"},_previousValidInput:{type:String,value:\"\"},_patternAlreadyChecked:{type:Boolean,value:!1}},listeners:{input:\"In\",keypress:\"W0\"},registered:function(){this.kF()||(this.CG=this.dispatchEvent,this.dispatchEvent=this.wF)},created:function(){Polymer.lg.LP()},kF:function(){var a=document.createElement(\"input\"),b=!1;\na.disabled=!0;a.addEventListener(\"feature-check-dispatch-event\",function(){b=!0});try{a.dispatchEvent(new Event(\"feature-check-dispatch-event\"))}catch(c){}return b},wF:function(){var a=this.disabled;this.disabled=!1;this.CG.apply(this,arguments);this.disabled=a},get cw(){var a;if(this.allowedPattern)a=new RegExp(this.allowedPattern);else switch(this.type){case \"number\":a=/[0-9.,e-]/}return a},ready:function(){this.bindValue=this.value},iF:function(){this.value!==this.bindValue&&(this.value=this.bindValue||\n0===this.bindValue||!1===this.bindValue?this.bindValue:\"\");this.fire(\"bind-value-changed\",{value:this.bindValue})},E_:function(){this.preventInvalidInput=this.allowedPattern?!0:!1},In:function(){if(this.preventInvalidInput&&!this._patternAlreadyChecked){var a=this.mF();a||(this.qv(\"Invalid string of characters not entered.\"),this.value=this._previousValidInput)}this._previousValidInput=this.bindValue=this.value;this._patternAlreadyChecked=!1},$F:function(a){var b=8==a.keyCode||9==a.keyCode||13==a.keyCode||\n27==a.keyCode,c=19==a.keyCode||20==a.keyCode||45==a.keyCode||46==a.keyCode||144==a.keyCode||145==a.keyCode||32<a.keyCode&&41>a.keyCode||111<a.keyCode&&124>a.keyCode;return!b&&!(0==a.charCode&&c)},W0:function(a){if(this.preventInvalidInput||\"number\"===this.type){var b=this.cw;if(b&&!(a.metaKey||a.ctrlKey||a.altKey)){this._patternAlreadyChecked=!0;var c=String.fromCharCode(a.charCode);this.$F(a)&&!b.test(c)&&(a.preventDefault(),this.qv(\"Invalid character \"+c+\" not entered.\"))}}},mF:function(){var a=\nthis.cw;if(!a)return!0;for(var b=0;b<this.value.length;b++)if(!a.test(this.value[b]))return!1;return!0},ah:function(){var a=this.checkValidity();a&&(this.required&&\"\"===this.value?a=!1:this.Zr()&&(a=Polymer.Rg.ah.call(this,this.value)));this.invalid=!a;this.fire(\"iron-input-validate\");return a},qv:function(a){this.fire(\"iron-announce\",{text:a})}});V.ph.ph={};Polymer({is:\"paper-input\",behaviors:[Polymer.Qg,Polymer.Jp]});V.jn={};V.jn.xZ={};\nPolymer({is:\"paper-menu-grow-height-animation\",behaviors:[Polymer.Rh],bj:function(a){var b=a.node,c=b.getBoundingClientRect(),c=c.height;return this.kc=new KeyframeEffect(b,[{height:c/2+\"px\"},{height:c+\"px\"}],this.zj(a))}});Polymer({is:\"paper-menu-grow-width-animation\",behaviors:[Polymer.Rh],bj:function(a){var b=a.node,c=b.getBoundingClientRect(),c=c.width;return this.kc=new KeyframeEffect(b,[{width:c/2+\"px\"},{width:c+\"px\"}],this.zj(a))}});\nPolymer({is:\"paper-menu-shrink-width-animation\",behaviors:[Polymer.Rh],bj:function(a){var b=a.node,c=b.getBoundingClientRect(),c=c.width;return this.kc=new KeyframeEffect(b,[{width:c+\"px\"},{width:c-c/20+\"px\"}],this.zj(a))}});\nPolymer({is:\"paper-menu-shrink-height-animation\",behaviors:[Polymer.Rh],bj:function(a){var b=a.node,c=b.getBoundingClientRect(),c=c.height;this.lU(b,\"transformOrigin\",\"0 0\");return this.kc=new KeyframeEffect(b,[{height:c+\"px\",transform:\"translateY(0)\"},{height:c/2+\"px\",transform:\"translateY(-20px)\"}],this.zj(a))}});V.zp={};V.zp.Wm={};\n(function(){var a={pageX:0,pageY:0},b=null,c=[];Polymer.Wm={get ox(){return this.Xh[this.Xh.length-1]},m5:function(a){var b=this.ox;if(void 0===b)return!1;if(this.UF(a))return!0;if(this.VF(a))return!1;(b=!!b&&b!==a&&!this.zv(b,a))?this.Gn.push(a):this.Rn.push(a);return b},cP:function(a){0<=this.Xh.indexOf(a)||(0===this.Xh.length&&this.hG(),this.Xh.push(a),this.Gn=[],this.Rn=[])},hC:function(a){a=this.Xh.indexOf(a);-1!==a&&(this.Xh.splice(a,1),this.Gn=[],this.Rn=[],0===this.Xh.length&&this.fH())},\nXh:[],Gn:null,Rn:null,UF:function(a){return-1<this.Gn.indexOf(a)},VF:function(a){return-1<this.Rn.indexOf(a)},zv:function(a,b){var c,e,g;if(a.contains(b))return!0;a=Polymer.dom(a).querySelectorAll(\"content\");for(e=0;e<a.length;++e)for(c=Polymer.dom(a[e]).getDistributedNodes(),g=0;g<c.length;++g)if(this.zv(c[g],b))return!0;return!1},QG:function(b){b.cancelable&&this.VG(b)&&b.preventDefault();b.targetTouches&&(b=b.targetTouches[0],a.pageX=b.pageX,a.pageY=b.pageY)},hG:function(){this.Ag=this.Ag||this.QG.bind(this);\ndocument.addEventListener(\"wheel\",this.Ag,!0);document.addEventListener(\"mousewheel\",this.Ag,!0);document.addEventListener(\"DOMMouseScroll\",this.Ag,!0);document.addEventListener(\"touchstart\",this.Ag,!0);document.addEventListener(\"touchmove\",this.Ag,!0)},fH:function(){document.removeEventListener(\"wheel\",this.Ag,!0);document.removeEventListener(\"mousewheel\",this.Ag,!0);document.removeEventListener(\"DOMMouseScroll\",this.Ag,!0);document.removeEventListener(\"touchstart\",this.Ag,!0);document.removeEventListener(\"touchmove\",\nthis.Ag,!0)},VG:function(a){var e=Polymer.dom(a).rootTarget;\"touchmove\"!==a.type&&b!==e&&(b=e,c=this.QF(Polymer.dom(a).path));if(!c.length)return!0;if(\"touchstart\"===a.type)return!1;a=this.PF(a);return!this.RF(c,a.deltaX,a.deltaY)},QF:function(a){for(var b=[],c=a.indexOf(this.ox),e=0;e<=c;e++)if(a[e].nodeType===Node.ELEMENT_NODE){var n=a[e],q=n.style;\"scroll\"!==q.overflow&&\"auto\"!==q.overflow&&(q=window.getComputedStyle(n));\"scroll\"!==q.overflow&&\"auto\"!==q.overflow||b.push(n)}return b},RF:function(a,\nb,c){if(b||c)for(var e=Math.abs(c)>=Math.abs(b),g=0;g<a.length;g++){var k=a[g],v;if(v=e?0>c?0<k.scrollTop:k.scrollTop<k.scrollHeight-k.clientHeight:0>b?0<k.scrollLeft:k.scrollLeft<k.scrollWidth-k.clientWidth)return k}},PF:function(b){var c={deltaX:b.deltaX,deltaY:b.deltaY};\"deltaX\"in b||(\"wheelDeltaX\"in b?(c.deltaX=-b.wheelDeltaX,c.deltaY=-b.wheelDeltaY):\"axis\"in b?(c.deltaX=1===b.axis?b.detail:0,c.deltaY=2===b.axis?b.detail:0):b.targetTouches&&(b=b.targetTouches[0],c.deltaX=a.pageX-b.pageX,c.deltaY=\na.pageY-b.pageY));return c}}})();V.zp.zp={};\nPolymer({is:\"iron-dropdown\",behaviors:[Polymer.ng,Polymer.mg,Polymer.Qh,Polymer.Ep],properties:{horizontalAlign:{type:String,value:\"left\",reflectToAttribute:!0},verticalAlign:{type:String,value:\"top\",reflectToAttribute:!0},openAnimationConfig:{type:Object},closeAnimationConfig:{type:Object},focusTarget:{type:Object},noAnimations:{type:Boolean,value:!1},allowOutsideScroll:{type:Boolean,value:!1},_boundOnCaptureScroll:{type:Function,value:function(){return this.uG.bind(this)}}},listeners:{\"neon-animation-finish\":\"yG\"},\nobservers:[\"D1(positionTarget,verticalAlign,horizontalAlign,verticalOffset,horizontalOffset)\"],get ko(){return Polymer.dom(this.$.content).getDistributedNodes()[0]},get l0(){return this.focusTarget||this.ko},ready:function(){this.jl=this.kl=0;this.yq=null},attached:function(){this.sizingTarget&&this.sizingTarget!==this||(this.sizingTarget=this.ko||this)},detached:function(){this.eo();document.removeEventListener(\"scroll\",this._boundOnCaptureScroll);Polymer.Wm.hC(this)},Yh:function(){this.opened&&\nthis.disabled?this.cancel():(this.eo(),this.hH(),this.PG(),this.opened?(document.addEventListener(\"scroll\",this._boundOnCaptureScroll),!this.allowOutsideScroll&&Polymer.Wm.cP(this)):(document.removeEventListener(\"scroll\",this._boundOnCaptureScroll),Polymer.Wm.hC(this)),Polymer.Lk.Yh.apply(this,arguments))},Mn:function(){!this.noAnimations&&this.animationConfig.open?(this.$.contentWrapper.classList.add(\"animating\"),this.Oo(\"open\")):Polymer.Lk.Mn.apply(this,arguments)},Ln:function(){!this.noAnimations&&\nthis.animationConfig.close?(this.$.contentWrapper.classList.add(\"animating\"),this.Oo(\"close\")):Polymer.Lk.Ln.apply(this,arguments)},yG:function(){this.$.contentWrapper.classList.remove(\"animating\");this.opened?this.mq():this.lq()},uG:function(){this.allowOutsideScroll?(this.yq&&window.cancelAnimationFrame(this.yq),this.yq=window.requestAnimationFrame(this.As.bind(this))):this.NG()},PG:function(){document.scrollingElement?(this.kl=document.scrollingElement.scrollTop,this.jl=document.scrollingElement.scrollLeft):\n(this.kl=Math.max(document.documentElement.scrollTop,document.body.scrollTop),this.jl=Math.max(document.documentElement.scrollLeft,document.body.scrollLeft))},NG:function(){document.scrollingElement?(document.scrollingElement.scrollTop=this.kl,document.scrollingElement.scrollLeft=this.jl):(document.documentElement.scrollTop=this.kl,document.documentElement.scrollLeft=this.jl,document.body.scrollTop=this.kl,document.body.scrollLeft=this.jl)},hH:function(){for(var a=this.ko,b=[].concat(this.openAnimationConfig||\n[]).concat(this.closeAnimationConfig||[]),c=0;c<b.length;c++)b[c].node=a;this.animationConfig={open:this.openAnimationConfig,close:this.closeAnimationConfig}},D1:function(){this.isAttached&&this.ri()},Oi:function(){var a=this.focusTarget||this.ko;a&&this.opened&&!this.noAutoFocus?a.focus():Polymer.Lk.Oi.apply(this,arguments)}});V.Gi.np.SX={};Polymer({is:\"fade-in-animation\",behaviors:[Polymer.Rh],bj:function(a){var b=a.node;return this.kc=new KeyframeEffect(b,[{opacity:\"0\"},{opacity:\"1\"}],this.zj(a))}});\nV.Gi.np.TX={};Polymer({is:\"fade-out-animation\",behaviors:[Polymer.Rh],bj:function(a){var b=a.node;return this.kc=new KeyframeEffect(b,[{opacity:\"1\"},{opacity:\"0\"}],this.zj(a))}});var Lw=function(){};d=Lw.prototype;d.registered=function(){};d.SI=function(){};d.vP=function(){};d.Ho=function(){};d.xv=function(){};d.Jn=function(){};d.Zp=function(){};d.Aq=function(){};d.uq=function(){};d.Gq=function(){};d.$v=function(){};d.ww=function(){};\nd.zn=function(a){if(a.target===this)this._setFocused(\"focus\"===a.type);else if(!this.shadowRoot){var b=Polymer.dom(a).localTarget;this.isLightDescendant(b)||this.fire(a.type,{sourceEvent:a},{node:this,bubbles:a.bubbles,cancelable:a.cancelable})}};d.lF=function(){this.vn&&this.vn()};d._setFocused=function(){};V.jn.jn={};\n(function(){var a={hp:\"cubic-bezier(.3,.95,.5,1)\",IY:400};Lw=Polymer({is:\"paper-menu-button\",behaviors:[Polymer.mg,Polymer.ng],properties:{opened:{type:Boolean,value:!1,notify:!0,observer:\"Yh\"},horizontalAlign:{type:String,value:\"left\",reflectToAttribute:!0},verticalAlign:{type:String,value:\"top\",reflectToAttribute:!0},dynamicAlign:{type:Boolean},horizontalOffset:{type:Number,value:0,notify:!0},verticalOffset:{type:Number,value:0,notify:!0},noOverlap:{type:Boolean},noAnimations:{type:Boolean,value:!1},\nignoreSelect:{type:Boolean,value:!1},closeOnActivate:{type:Boolean,value:!1},openAnimationConfig:{type:Object,value:function(){return[{name:\"fade-in-animation\",timing:{delay:100,duration:200}},{name:\"paper-menu-grow-width-animation\",timing:{delay:100,duration:150,easing:a.hp}},{name:\"paper-menu-grow-height-animation\",timing:{delay:100,duration:275,easing:a.hp}}]}},closeAnimationConfig:{type:Object,value:function(){return[{name:\"fade-out-animation\",timing:{duration:150}},{name:\"paper-menu-shrink-width-animation\",\ntiming:{delay:100,duration:50,easing:a.hp}},{name:\"paper-menu-shrink-height-animation\",timing:{duration:200,easing:\"ease-in\"}}]}},allowOutsideScroll:{type:Boolean,value:!1},restoreFocusOnClose:{type:Boolean,value:!0},_dropdownContent:{type:Object}},hostAttributes:{role:\"group\",\"aria-haspopup\":\"true\"},listeners:{\"iron-activate\":\"Q0\",\"iron-select\":\"Zv\"},get fj(){return Polymer.dom(this.$.content).getDistributedNodes()[0]},toggle:function(){this.opened?this.close():this.open()},open:function(){this.disabled||\nthis.$.dropdown.open()},close:function(){this.$.dropdown.close()},Zv:function(){this.ignoreSelect||this.close()},Q0:function(){this.closeOnActivate&&this.close()},Yh:function(a,c){a?(this._dropdownContent=this.fj,this.fire(\"paper-dropdown-open\")):null!=c&&this.fire(\"paper-dropdown-close\")},iq:function(a){Polymer.ng.iq.apply(this,arguments);a&&this.opened&&this.close()},B_:function(a){var b=a.detail;Polymer.dom(b);var e=this.$.trigger,b=Polymer.dom(b).path;-1<b.indexOf(e)&&a.preventDefault()}});Object.keys(a).forEach(function(b){Lw[b]=\na[b]});Polymer.jn=Lw})();V.Rk.Rk={};\nPolymer({is:\"paper-dropdown-menu\",behaviors:[Polymer.Hj,Polymer.ng,Polymer.Qg,Polymer.Rg],properties:{selectedItemLabel:{type:String,notify:!0,readOnly:!0},selectedItem:{type:Object,notify:!0,readOnly:!0},value:{type:String,notify:!0,readOnly:!0},label:{type:String},placeholder:{type:String},errorMessage:{type:String},opened:{type:Boolean,notify:!0,value:!1,observer:\"Yh\"},allowOutsideScroll:{type:Boolean,value:!1},noLabelFloat:{type:Boolean,value:!1,reflectToAttribute:!0},alwaysFloatLabel:{type:Boolean,\nvalue:!1},noAnimations:{type:Boolean,value:!1},horizontalAlign:{type:String,value:\"right\"},verticalAlign:{type:String,value:\"top\"},dynamicAlign:{type:Boolean},restoreFocusOnClose:{type:Boolean,value:!0}},listeners:{tap:\"BG\"},$g:{\"up down\":\"open\",esc:\"close\"},hostAttributes:{role:\"combobox\",\"aria-autocomplete\":\"none\",\"aria-haspopup\":\"true\"},observers:[\"SG(selectedItem)\"],attached:function(){var a=this.fj;a&&a.selectedItem&&this._setSelectedItem(a.selectedItem)},get fj(){return Polymer.dom(this.$.content).getDistributedNodes()[0]},\nopen:function(){this.$.menuButton.open()},close:function(){this.$.menuButton.close()},Zv:function(a){this._setSelectedItem(a.detail.item)},xG:function(){this._setSelectedItem(null)},BG:function(a){Polymer.Gestures.findOriginalTarget(a)===this&&this.open()},SG:function(a){a=a?a.label||a.getAttribute(\"label\")||a.textContent.trim():\"\";this._setValue(a);this._setSelectedItemLabel(a)},qF:function(a){return a?-4:8},Cn:function(){return this.disabled||!this.required||this.required&&!!this.value},Yh:function(){var a=\nthis.opened?\"true\":\"false\",b=this.fj;b&&b.setAttribute(\"aria-expanded\",a)}});V.Rk.nZ={};\nPolymer({is:\"paper-dropdown-menu-light\",behaviors:[Polymer.Hj,Polymer.ng,Polymer.qh,Polymer.Qg,Polymer.Rg],properties:{selectedItemLabel:{type:String,notify:!0,readOnly:!0},selectedItem:{type:Object,notify:!0,readOnly:!0},value:{type:String,notify:!0,readOnly:!0,observer:\"Iq\"},label:{type:String},placeholder:{type:String},opened:{type:Boolean,notify:!0,value:!1,observer:\"Yh\"},allowOutsideScroll:{type:Boolean,value:!1},noLabelFloat:{type:Boolean,value:!1,reflectToAttribute:!0},alwaysFloatLabel:{type:Boolean,\nvalue:!1},noAnimations:{type:Boolean,value:!1},horizontalAlign:{type:String,value:\"right\"},verticalAlign:{type:String,value:\"top\"},hasContent:{type:Boolean,readOnly:!0}},listeners:{tap:\"BG\"},$g:{\"up down\":\"open\",esc:\"close\"},hostAttributes:{tabindex:0,role:\"combobox\",\"aria-autocomplete\":\"none\",\"aria-haspopup\":\"true\"},observers:[\"SG(selectedItem)\"],attached:function(){var a=this.fj;a&&a.selectedItem&&this._setSelectedItem(a.selectedItem)},get fj(){return Polymer.dom(this.$.content).getDistributedNodes()[0]},\nopen:function(){this.$.menuButton.open()},close:function(){this.$.menuButton.close()},Zv:function(a){this._setSelectedItem(a.detail.item)},xG:function(){this._setSelectedItem(null)},BG:function(a){Polymer.Gestures.findOriginalTarget(a)===this&&this.open()},SG:function(a){a=a?a.label||a.getAttribute(\"label\")||a.textContent.trim():\"\";this._setValue(a);this._setSelectedItemLabel(a)},qF:function(a){return a?-4:8},Cn:function(){return this.disabled||!this.required||this.required&&!!this.value},Yh:function(){var a=\nthis.opened?\"true\":\"false\",b=this.fj;b&&b.setAttribute(\"aria-expanded\",a)},Z_:function(a,b,c){var e=\"\";if(!0===a)return c?\"label-is-hidden\":\"\";if(c||!0===b)e+=\" label-is-floating\";return e},Iq:function(){this.$.input&&this.$.input.textContent!==this.value&&(this.$.input.textContent=this.value);this._setHasContent(!!this.value)}});V.en.gn={};\nPolymer.Ru={observers:[\"MF(receivedFocusFromKeyboard)\"],MF:function(a){a&&this.hj();this.kj()&&(this.Ne.holdDown=a)},Ri:function(){var a=Polymer.qh.Ri();a.id=\"ink\";a.setAttribute(\"center\",\"\");a.classList.add(\"circle\");return a}};Polymer.gn=[Polymer.Hj,Polymer.ng,Polymer.qh,Polymer.Ru];V.Hp={};V.Hp.Hp={};\nPolymer({is:\"paper-icon-button\",hostAttributes:{role:\"button\",tabindex:\"0\"},behaviors:[Polymer.gn],properties:{src:{type:String},icon:{type:String},alt:{type:String,observer:\"F_\"}},F_:function(a,b){var c=this.getAttribute(\"aria-label\");c&&b!=c||this.setAttribute(\"aria-label\",a)}});V.Hp.pZ={};\nPolymer({is:\"paper-icon-button-light\",extends:\"button\",behaviors:[Polymer.qh],listeners:{down:\"m1\",up:\"n1\",focus:\"m1\",blur:\"n1\"},m1:function(){this.Pr().fk()},n1:function(){this.Pr().zk()},hj:function(a){var b=this.Ne;Polymer.qh.hj.apply(this,arguments);this.Ne&&this.Ne!==b&&(this.Ne.center=!0,this.Ne.classList.add(\"circle\"))}});V.lu={};V.lu.lu={};\nPolymer({is:\"iron-autogrow-textarea\",behaviors:[Polymer.Qg,Polymer.Rg,Polymer.ng],properties:{bindValue:{observer:\"iF\",type:String},rows:{type:Number,value:1,observer:\"B1\"},maxRows:{type:Number,value:0,observer:\"B1\"},autocomplete:{type:String,value:\"off\"},autofocus:{type:Boolean,value:!1},inputmode:{type:String},placeholder:{type:String},readonly:{type:String},required:{type:Boolean},maxlength:{type:Number}},listeners:{input:\"In\"},observers:[\"aw(value)\"],get Gm(){return this.$.textarea},get selectionStart(){return this.$.textarea.selectionStart},\nget selectionEnd(){return this.$.textarea.selectionEnd},set selectionStart(a){this.$.textarea.selectionStart=a},set selectionEnd(a){this.$.textarea.selectionEnd=a},ah:function(){if(!this.required&&\"\"==this.value)return this.invalid=!1,!0;var a;this.Zr()?a=Polymer.Rg.ah.call(this,this.value):(a=this.$.textarea.validity.valid,this.invalid=!a);this.fire(\"iron-input-validate\");return a},iF:function(){var a=this.Gm;a&&(a.value!==this.bindValue&&(a.value=this.bindValue||0===this.bindValue?this.bindValue:\n\"\"),this.value=this.bindValue,this.$.mirror.innerHTML=this.pH(),this.fire(\"bind-value-changed\",{value:this.bindValue}))},In:function(a){this.bindValue=a.path?a.path[0].value:a.target.value},Av:function(a){var b;a=a||[\"\"];for(b=0<this.maxRows&&a.length>this.maxRows?a.slice(0,this.maxRows):a.slice(0);0<this.rows&&b.length<this.rows;)b.push(\"\");return b.join(\"\\x3cbr/\\x3e\")+\"\\x26#160;\"},pH:function(){var a=this.Gm;if(a)return this.GC=a&&a.value?a.value.replace(/&/gm,\"\\x26amp;\").replace(/\"/gm,\"\\x26quot;\").replace(/'/gm,\n\"\\x26#39;\").replace(/</gm,\"\\x26lt;\").replace(/>/gm,\"\\x26gt;\").split(\"\\n\"):[\"\"],this.Av(this.GC)},B1:function(){this.$.mirror.innerHTML=this.Av(this.GC)},aw:function(){this.bindValue=this.value}});V.ph.zZ={};\nPolymer({is:\"paper-textarea\",behaviors:[Polymer.Jp,Polymer.Qg],properties:{_ariaLabelledBy:{observer:\"I_\",type:String},_ariaDescribedBy:{observer:\"H_\",type:String},rows:{type:Number,value:1},maxRows:{type:Number,value:0}},I_:function(a){this.$.input.Gm.setAttribute(\"aria-labelledby\",a)},H_:function(a){this.$.input.Gm.setAttribute(\"aria-describedby\",a)},get Bn(){return this.$.input.Gm}});V.ph.WC={};V.Hi={};V.Hi.Kp={};Polymer.pE={hostAttributes:{role:\"option\",tabindex:\"0\"}};\nPolymer.Kp=[Polymer.Hj,Polymer.ng,Polymer.pE];V.Hi.vZ={};V.Hi.qZ={};Polymer({is:\"paper-icon-item\",behaviors:[Polymer.Kp]});V.Hi.uZ={};Polymer({is:\"paper-item-body\"});V.Hi.Hi={};Polymer({is:\"paper-item\",behaviors:[Polymer.Kp]});V.Hi.WC={};V.Cp={};V.Cp.Bp={};Polymer.Bp=function(a){this.selection=[];this.pC=a};\nPolymer.Bp.prototype={get:function(){return this.multi?this.selection.slice():this.selection[0]},clear:function(a){this.selection.slice().forEach(function(b){(!a||0>a.indexOf(b))&&this.wm(b,!1)},this)},isSelected:function(a){return 0<=this.selection.indexOf(a)},wm:function(a,b){if(null!=a&&b!==this.isSelected(a)){if(b)this.selection.push(a);else{var c=this.selection.indexOf(a);0<=c&&this.selection.splice(c,1)}this.pC&&this.pC(a,b)}},select:function(a){this.multi?this.toggle(a):this.get()!==a&&(this.wm(this.get(),\n!1),this.wm(a,!0))},toggle:function(a){this.wm(a,!this.isSelected(a))}};V.Cp.pY={};\nPolymer.Nk={properties:{attrForSelected:{type:String,value:null},selected:{type:String,notify:!0},selectedItem:{type:Object,readOnly:!0,notify:!0},activateEvent:{type:String,value:\"tap\",observer:\"C_\"},selectable:String,selectedClass:{type:String,value:\"iron-selected\"},selectedAttribute:{type:String,value:null},fallbackSelection:{type:String,value:null},items:{type:Array,readOnly:!0,notify:!0,value:function(){return[]}},_excludedLocalNames:{type:Object,value:function(){return{template:1}}}},observers:[\"zw(attrForSelected)\",\n\"Sn(selected)\",\"N_(fallbackSelection)\"],created:function(){this.hF=this.GF.bind(this);this.Jf=new Polymer.Bp(this.aq.bind(this))},attached:function(){this.gl=this.pG(this);this.Hq();this.Zj||this.Sn();this.pv(this.activateEvent)},detached:function(){this.gl&&Polymer.dom(this).unobserveNodes(this.gl);this.hw(this.activateEvent)},indexOf:function(a){return this.items.indexOf(a)},select:function(a){this.selected=a},$aa:function(){var a=this.items.length,a=(Number(this.Jq(this.selected))-1+a)%a;this.selected=\nthis.Rj(a)},Zaa:function(){var a=(Number(this.Jq(this.selected))+1)%this.items.length;this.selected=this.Rj(a)},Yaa:function(a){this.select(this.Rj(a))},f6:function(){this.Hq()},get Zj(){return null!=this.selected},N_:function(){this.Zj&&this.Sn()},pv:function(a){this.listen(this,a,\"ov\")},hw:function(a){this.unlisten(this,a,\"ov\")},C_:function(a,b){this.hw(b);this.pv(a)},Hq:function(){var a=Polymer.dom(this).queryDistributedElements(this.selectable||\"*\"),a=Array.prototype.filter.call(a,this.hF);this._setItems(a)},\nzw:function(){this.Zj&&(this.selected=this.Rj(this.indexOf(this.selectedItem)))},Sn:function(){this.ow(this.selected)},ow:function(){this.Jf.select(this.Un(this.selected));this.fallbackSelection&&this.items.length&&void 0===this.Jf.get()&&(this.selected=this.fallbackSelection)},GF:function(a){return!this._excludedLocalNames[a.localName]},Un:function(a){return null==a?null:this.items[this.Jq(a)]},Jq:function(a){if(this.attrForSelected)for(var b=0,c;c=this.items[b];b++){if(this.Cw(c)==a)return b}else return Number(a)},\nRj:function(a){if(this.attrForSelected){if(a=this.items[a])return this.Cw(a)}else return a},Cw:function(a){var b=a[Polymer.CaseMap.dashToCamelCase(this.attrForSelected)];return void 0!=b?b:a.getAttribute(this.attrForSelected)},aq:function(a,b){this.selectedClass&&this.toggleClass(this.selectedClass,b,a);this.selectedAttribute&&this.toggleAttribute(this.selectedAttribute,b,a);this.pw();this.fire(\"iron-\"+(b?\"select\":\"deselect\"),{item:a})},pw:function(){this._setSelectedItem(this.Jf.get())},pG:function(a){return Polymer.dom(a).observeNodes(function(a){this.Hq();\nthis.Zj&&this.Sn();this.fire(\"iron-items-changed\",a,{bubbles:!1,cancelable:!1})})},ov:function(a){a=a.target;for(var b=this.items;a&&a!=this;){var c=b.indexOf(a);if(0<=c){b=this.Rj(c);this.bG(b,a);break}a=a.parentNode}},bG:function(a,b){this.fire(\"iron-activate\",{selected:a,item:b},{cancelable:!0}).defaultPrevented||this.select(a)}};V.Cp.mY={};\nPolymer.uu={properties:{multi:{type:Boolean,value:!1,observer:\"m9\"},selectedValues:{type:Array,notify:!0},selectedItems:{type:Array,readOnly:!0,notify:!0}},observers:[\"Sn(selectedValues.splices)\"],select:function(a){this.multi?this.selectedValues?this.aH(a):this.selectedValues=[a]:this.selected=a},m9:function(a){this.Jf.multi=a},get Zj(){return null!=this.selected||null!=this.selectedValues&&this.selectedValues.length},zw:function(){this.multi?this.Zj&&(this.selectedValues=this.selectedItems.map(function(a){return this.Rj(this.indexOf(a))},\nthis).filter(function(a){return null!=a},this)):Polymer.Nk.zw.apply(this)},Sn:function(){this.multi?this.RG(this.selectedValues):this.ow(this.selected)},RG:function(a){if(a){a=this.qH(a);this.Jf.clear(a);for(var b=0;b<a.length;b++)this.Jf.wm(a[b],!0);this.fallbackSelection&&this.items.length&&!this.Jf.get().length&&(a=this.Un(this.fallbackSelection))&&(this.selectedValues=[this.fallbackSelection])}else this.Jf.clear()},pw:function(){var a=this.Jf.get();this.multi?this._setSelectedItems(a):(this._setSelectedItems([a]),\nthis._setSelectedItem(a))},aH:function(a){var b=this.selectedValues.indexOf(a),c=0>b;c?this.push(\"selectedValues\",a):this.splice(\"selectedValues\",b,1)},qH:function(a){return null==a?null:a.map(function(a){return this.Un(a)},this)}};Polymer.QD=[Polymer.Nk,Polymer.uu];V.Ym={};V.Ym.Ym={};\nPolymer.Kk={properties:{focusedItem:{observer:\"m0\",readOnly:!0,type:Object},attrForItemTitle:{type:String}},hostAttributes:{role:\"menu\",tabindex:\"0\"},observers:[\"C1(multi)\"],listeners:{focus:\"Yv\",keydown:\"V0\",\"iron-items-changed\":\"S0\"},$g:{up:\"a1\",down:\"N0\",esc:\"P0\",\"shift+tab:keydown\":\"AG\"},attached:function(){this.kw()},select:function(a){this.hq&&(this.cancelAsync(this.hq),this.hq=null);var b=this.Un(a);b&&b.hasAttribute(\"disabled\")||(this._setFocusedItem(b),Polymer.uu.select.apply(this,arguments))},\nkw:function(){var a=this.multi?this.selectedItems&&this.selectedItems[0]:this.selectedItem;this.items.forEach(function(b){b.setAttribute(\"tabindex\",b===a?\"0\":\"-1\")},this)},C1:function(a){a?this.setAttribute(\"aria-multiselectable\",\"true\"):this.removeAttribute(\"aria-multiselectable\")},KF:function(a){for(var b=0,c;c=this.items[b];b++){var e=this.attrForItemTitle||\"textContent\",e=c[e]||c.getAttribute(e);if(!c.hasAttribute(\"disabled\")&&e&&e.trim().charAt(0).toLowerCase()===String.fromCharCode(a.keyCode).toLowerCase()){this._setFocusedItem(c);\nbreak}}},JF:function(){for(var a=this.items.length,b=Number(this.indexOf(this.focusedItem)),c=1;c<a+1;c++){var e=this.items[(b-c+a)%a];if(!e.hasAttribute(\"disabled\")){var g=Polymer.dom(e).getOwnerRoot()||document;this._setFocusedItem(e);if(Polymer.dom(g).activeElement==e)break}}},Kv:function(){for(var a=this.items.length,b=Number(this.indexOf(this.focusedItem)),c=1;c<a+1;c++){var e=this.items[(b+c)%a];if(!e.hasAttribute(\"disabled\")){var g=Polymer.dom(e).getOwnerRoot()||document;this._setFocusedItem(e);\nif(Polymer.dom(g).activeElement==e)break}}},aq:function(a,b){b?a.setAttribute(\"aria-selected\",\"true\"):a.removeAttribute(\"aria-selected\");Polymer.Nk.aq.apply(this,arguments)},m0:function(a,b){b&&b.setAttribute(\"tabindex\",\"-1\");a&&(a.setAttribute(\"tabindex\",\"0\"),a.focus())},S0:function(a){a.detail.addedNodes.length&&this.kw()},AG:function(){var a=this.getAttribute(\"tabindex\");Polymer.Kk.Yj=!0;this._setFocusedItem(null);this.setAttribute(\"tabindex\",\"-1\");this.async(function(){this.setAttribute(\"tabindex\",\na);Polymer.Kk.Yj=!1},1)},Yv:function(a){!Polymer.Kk.Yj&&(a=Polymer.dom(a).rootTarget,a===this||\"undefined\"===typeof a.tabIndex||this.isLightDescendant(a))&&(this.hq=this.async(function(){var a=this.multi?this.selectedItems&&this.selectedItems[0]:this.selectedItem;this._setFocusedItem(null);a?this._setFocusedItem(a):this.items[0]&&this.Kv()}))},a1:function(a){this.JF();a.detail.Go.preventDefault()},N0:function(a){this.Kv();a.detail.Go.preventDefault()},P0:function(){this.focusedItem.blur()},V0:function(a){this.Ho(a,\n\"up down esc\")||this.KF(a);a.stopPropagation()},ov:function(a){Polymer.Nk.ov.call(this,a);a.stopPropagation()}};Polymer.Kk.Yj=!1;Polymer.Ym=[Polymer.QD,Polymer.mg,Polymer.Kk];V.Su={};V.Su.Su={};Polymer({is:\"paper-listbox\",behaviors:[Polymer.Ym],hostAttributes:{role:\"listbox\"}});V.Mk={};V.Mk.Mk={};\nPolymer.Mk={properties:{value:{type:Number,value:0,notify:!0,reflectToAttribute:!0},min:{type:Number,value:0,notify:!0},max:{type:Number,value:100,notify:!0},step:{type:Number,value:1,notify:!0},ratio:{type:Number,value:0,readOnly:!0,notify:!0}},observers:[\"bk(value,min,max,step)\"],Nj:function(a){return(this.Qi(a)-this.min)/(this.max-this.min)},Qi:function(a){return Math.min(this.max,Math.max(this.min,this.fq(a)))},fq:function(a){a=parseFloat(a);return this.step?(Math.round((a+this.min)/this.step)-\nthis.min/this.step)/(1/this.step):a},nH:function(){var a=this.Qi(this.value);this.value=this.oldValue=isNaN(a)?this.oldValue:a;return this.value!==a},bk:function(){this.nH();this._setRatio(100*this.Nj(this.value))}};V.Tu={};V.Tu.Tu={};\nPolymer({is:\"paper-progress\",behaviors:[Polymer.Mk],properties:{secondaryProgress:{type:Number,value:0},secondaryRatio:{type:Number,value:0,readOnly:!0},indeterminate:{type:Boolean,value:!1,observer:\"w1\"},disabled:{type:Boolean,value:!1,reflectToAttribute:!0,observer:\"iq\"}},observers:[\"g1(secondaryProgress,value,min,max)\"],hostAttributes:{role:\"progressbar\"},w1:function(a){this.toggleClass(\"indeterminate\",a,this.$.primaryProgress)},Fq:function(a,b){b=\"scaleX(\"+b/100+\")\";a.style.transform=a.style.webkitTransform=\nb},D0:function(a){this.Fq(this.$.primaryProgress,a)},g1:function(a,b,c,e){a=this.Qi(a);b=this.Qi(b);var g=100*this.Nj(a),k=100*this.Nj(b);this._setSecondaryRatio(g);this.Fq(this.$.secondaryProgress,g);this.Fq(this.$.primaryProgress,k);this.secondaryProgress=a;this.setAttribute(\"aria-valuenow\",b);this.setAttribute(\"aria-valuemin\",c);this.setAttribute(\"aria-valuemax\",e)},iq:function(a){this.setAttribute(\"aria-disabled\",a?\"true\":\"false\")},s0:function(a){return 0===a}});V.Vu={};V.Vu.Vu={};\nPolymer({is:\"paper-slider\",behaviors:[Polymer.mg,Polymer.Qg,Polymer.gn,Polymer.Mk],properties:{snaps:{type:Boolean,value:!1,notify:!0},pin:{type:Boolean,value:!1,notify:!0},secondaryProgress:{type:Number,value:0,notify:!0,observer:\"p1\"},editable:{type:Boolean,value:!1},immediateValue:{type:Number,value:0,readOnly:!0,notify:!0},maxMarkers:{type:Number,value:0,notify:!0,observer:\"E0\"},expand:{type:Boolean,value:!1,readOnly:!0},dragging:{type:Boolean,value:!1,readOnly:!0},transiting:{type:Boolean,value:!1,\nreadOnly:!0},markers:{type:Array,readOnly:!0,value:[]}},observers:[\"lH(value,min,max,snaps,step)\",\"Iq(value)\",\"v0(immediateValue)\"],hostAttributes:{role:\"slider\",tabindex:0},$g:{\"left down pagedown home\":\"d0\",\"right up pageup end\":\"w0\"},ready:function(){this.async(function(){this.lH(this.value)},1)},eN:function(){this.value=this.Qi(this.value+this.step)},GK:function(){this.value=this.Qi(this.value-this.step)},lH:function(a,b,c){this.setAttribute(\"aria-valuemin\",b);this.setAttribute(\"aria-valuemax\",\nc);this.setAttribute(\"aria-valuenow\",a);this.dw(this.Nj(a))},Iq:function(){this.fire(\"value-change\")},v0:function(){this.dragging?this.fire(\"immediate-value-change\"):this.value=this.immediateValue},p1:function(){this.secondaryProgress=this.Qi(this.secondaryProgress)},Iv:function(){this._setExpand(!0)},LG:function(){this.cancelDebouncer(\"expandKnob\");this._setExpand(!1)},dw:function(a){this._setImmediateValue(this.fq(this.tv(a)));this._setRatio(this.Nj(this.immediateValue));this.$.sliderKnob.style.left=\n100*this.ratio+\"%\";this.dragging&&(this.Rv=this.ratio*this.$i,this.translate3d(0,0,0,this.$.sliderKnob))},tv:function(a){return(this.max-this.min)*a+this.min},Z0:function(a){a.stopPropagation();switch(a.detail.state){case \"start\":this.Qn(a);break;case \"track\":this.dH(a);break;case \"end\":this.Eq()}},Qn:function(){this.$i=this.$.sliderBar.offsetWidth;this.Rv=this.On=this.tc=this.ratio*this.$i;this.nG=-this.On;this.iG=this.$i-this.On;this.$.sliderKnob.classList.add(\"dragging\");this._setDragging(!0)},\ndH:function(a){this.dragging||this.Qn(a);a=Math.min(this.iG,Math.max(this.nG,a.detail.dx));this.tc=this.On+a;a=this.fq(this.tv(this.tc/this.$i));this._setImmediateValue(a);a=this.Nj(this.immediateValue)*this.$i-this.Rv;this.translate3d(a+\"px\",0,0,this.$.sliderKnob)},Eq:function(){var a=this.$.sliderKnob.style;this.$.sliderKnob.classList.remove(\"dragging\");this._setDragging(!1);this.LG();this.value=this.immediateValue;a.transform=a.webkitTransform=\"\";this.fire(\"change\")},C0:function(a){this.Iv();a.preventDefault();\nthis.focus()},K_:function(a){this.$i=this.$.sliderBar.offsetWidth;var b=this.$.sliderBar.getBoundingClientRect(),b=(a.detail.x-b.left)/this.$i,c=this.ratio;this._setTransiting(!0);this.dw(b);this.debounce(\"expandKnob\",this.Iv,60);c===this.ratio&&this._setTransiting(!1);this.async(function(){this.fire(\"change\")});a.preventDefault();this.focus()},B0:function(a){a.target===this.$.sliderKnob&&this._setTransiting(!1)},E0:function(a){this.snaps||this._setMarkers([]);var b=Math.round((this.max-this.min)/\nthis.step);b>a&&(b=a);this._setMarkers(Array(b))},jG:function(a){return Object.keys(a).filter(function(b){return a[b]}).join(\" \")},n0:function(){return this.jG({disabled:this.disabled,pin:this.pin,snaps:this.snaps,Iaa:this.immediateValue<=this.min,expand:this.expand,dragging:this.dragging,transiting:this.transiting,editable:this.editable})},w0:function(a){this.disabled||(\"end\"===a.detail.key?this.value=this.max:this.eN(),this.fire(\"change\"))},d0:function(a){this.disabled||(\"home\"===a.detail.key?this.value=\nthis.min:this.GK(),this.fire(\"change\"))},M_:function(a){this.value=a.target.value;this.fire(\"change\")},z0:function(a){a.stopPropagation()},Ri:function(){this._rippleContainer=this.$.sliderKnob;return Polymer.Ru.Ri.call(this)},MF:function(a){a&&this.hj();this.kj()&&(this.Ne.style.display=a?\"\":\"none\",this.Ne.holdDown=a)}});V.Vm={};V.Vm.Vm={};\nPolymer.nu={properties:{checked:{type:Boolean,value:!1,reflectToAttribute:!0,notify:!0,observer:\"vv\"},toggles:{type:Boolean,value:!0,reflectToAttribute:!0},value:{type:String,value:\"on\",observer:\"Iq\"}},observers:[\"j1(required)\"],created:function(){this.p0=!0},Cn:function(){return this.disabled||!this.required||this.required&&this.checked},j1:function(){this.required?this.setAttribute(\"aria-required\",\"true\"):this.removeAttribute(\"aria-required\")},vv:function(){this.active=this.checked;this.fire(\"iron-change\")},\nIq:function(){if(void 0===this.value||null===this.value)this.value=\"on\"}};Polymer.Vm=[Polymer.Qg,Polymer.Rg,Polymer.nu];V.en.Pu={};Polymer.mE={vv:function(){Polymer.nu.vv.call(this);this.kj()&&(this.checked?this.Ne.setAttribute(\"checked\",\"\"):this.Ne.removeAttribute(\"checked\"))},tn:function(){Polymer.qh.tn.call(this);!this.disabled&&this.isAttached&&(this.checked=this.active)}};Polymer.Pu=[Polymer.gn,Polymer.Vm,Polymer.mE];V.Wu={};V.Wu.Wu={};\nPolymer({is:\"paper-toggle-button\",behaviors:[Polymer.Pu],hostAttributes:{role:\"button\",\"aria-pressed\":\"false\",tabindex:0},properties:{},listeners:{track:\"b1\"},attached:function(){Polymer.RenderStatus.afterNextRender(this,function(){this.setScrollDirection(\"y\")})},b1:function(a){a=a.detail;\"start\"===a.state?this.Qn(a):\"track\"===a.state?this.cH(a):\"end\"===a.state&&this.Eq(a)},Qn:function(){this.Kq=this.$.toggleBar.offsetWidth/2;this.bH=this.checked;this.$.toggleButton.classList.add(\"dragging\")},cH:function(a){a=\na.dx;this.tc=Math.min(this.Kq,Math.max(0,this.bH?this.Kq+a:a));this.translate3d(this.tc+\"px\",0,0,this.$.toggleButton);this.Bw(this.tc>this.Kq/2)},Eq:function(){this.$.toggleButton.classList.remove(\"dragging\");this.transform(\"\",this.$.toggleButton)},Ri:function(){this._rippleContainer=this.$.toggleButton;var a=Polymer.qh.Ri();a.id=\"ink\";a.setAttribute(\"recenters\",\"\");a.classList.add(\"circle\",\"toggle-ink\");return a}});D.ob={};D.ob.cZ={};D.ob.yg={Wk:\"unweighted\",pn:\"weighted\",Ai:\"both\"};\nD.ob.hv={Wk:\"Number of slices in bucket\",pn:\"Number of (weighted) examples for slices in bucket\"};D.ob.xg={Zt:\"details\",EMPTY:\"empty\",Hu:\"overview\",uD:\"focus\",KY:\"metric-select\",j_:\"type-select\",VY:\"num-buckets\",zY:\"logarithm-scale\",hE:\"options\",aZ:\"options-toggle\"};D.ob.YD=680;D.ob.ED=200;D.ob.dn=30;D.ob.Iu=120;D.ob.iE=120;D.ob.kE=2;D.ob.jE=600;D.ob.Eu=[1,50];D.ob.iD=10;\nD.ob.Cy=function(a,b){a=a.slice(1);return a.reduce(function(a,e){return{min:Math.min(a.min,e[b]),max:Math.max(a.max,e[b])}},{min:Infinity,max:-Infinity})};\nPolymer({is:\"metrics-histogram\",properties:{data:{type:Object,value:function(){return new D.Jb([],[])}},focusRange:{type:Array,value:[0,1]},detailsData:{type:Object,computed:\"M3(data,metric,focusRange)\",notify:!0},numBuckets:{type:Number,value:D.ob.iD},type:{type:String,value:D.ob.yg.Wk},metric:{type:String,value:\"\"},selectableMetrics_:{type:Array,computed:\"V3(data,weightedExamplesColumn)\",observer:\"aba\"},weightedExamplesColumn:{type:String,value:\"\"},logarithmScale:{type:Boolean,value:!1},selectedFeatures:{type:Array,\nvalue:function(){return[]}},realTimeFocus:{type:Boolean,value:!1},chartPackages_:{type:Array,value:[\"corechart\"]}},listeners:{\"iron-resize\":\"j$\"},behaviors:[Polymer.Jj],observers:[\"saa(data,metric,type,focusRange,weightedExamplesColumn,logarithmScale,numBuckets,selectedFeatures)\"],jB:function(){this.Es()?this.Qo():this.async(this.jB,100)},ready:function(){this.$.loader.load();this.jB()},cp:function(a,b){this.focusRange=[a,b]},Qo:function(){this.Es()&&(this.BP(),this.EP())},Dr:function(){var a=this.getBoundingClientRect().width;\nreturn Math.max(a,D.ob.YD)},Jr:function(){var a=this.Dr();return a-D.ob.Iu-D.ob.iE},EP:function(){var a=D.ei.select(this.$[D.ob.xg.Hu]),b=this.Jr(),c=a.node();c.setAttribute(\"width\",b);c.setAttribute(\"height\",D.ob.dn*(this.type==D.ob.yg.Ai?2:1));c.style.marginLeft=D.ob.Iu+\"px\";var c=D.ob.dn,e=this.data.getColumnRange(this.metric),e=this.YB(this.data,D.ob.jE,e.min,e.max),e=e.pr,g=a.select(\".unweighted\"),k=a.select(\".weighted\");g.selectAll(\"*\").remove();k.selectAll(\"*\").remove();this.type!=D.ob.yg.pn&&\nthis.yx(g,e.map(function(a){return[a[0],a[1]]}),D.ob.Cy(e,1));this.type!=D.ob.yg.Wk&&this.yx(k,e.map(function(a){return[a[0],a[2]]}),D.ob.Cy(e,2));g.select(\"path\").attr(\"class\",\"blue\");k.select(\"path\").attr(\"class\",this.type==D.ob.yg.Ai?\"red\":\"blue\");this.type==D.ob.yg.Ai&&k.attr(\"transform\",\"translate(0,\"+c+\")\");this.xx(this.focusRange[0],this.focusRange[1]);var m=[],c=D.ei.drag(),n,q,e=function(){var c=D.ei.mouse(a.node())[0];void 0==m[0]?m[0]=c:(m[1]=c,n=Math.max(0,Math.min(m[0],m[1])/b),q=Math.min(1,\nMath.max(m[0],m[1])/b),this.xx(n,q),this.realTimeFocus&&this.cp(n,q))}.bind(this),g=function(){void 0!=m[0]&&void 0!=m[1]&&(this.cp(n,q),m=[],this.dispatchEvent(new CustomEvent(D.Event.fv,{detail:{aL:n,bL:q}})))}.bind(this);c.on(\"drag\",e).on(\"end\",g);a.call(c);a.on(D.Event.au,function(){this.PP();this.dispatchEvent(new CustomEvent(D.Event.fv,{detail:{aL:0,bL:1}}))}.bind(this))},BP:function(){var a=this.data.getColumnRange(this.metric),b=(a.max-a.min)*this.focusRange[0]+a.min,a=(a.max-a.min)*this.focusRange[1]+\na.min,b=this.YB(this.detailsData,this.numBuckets,b,a),a=[],c=[0],e=0;this.type!=D.ob.yg.pn&&(a.push({targetAxisIndex:e++}),c.push(1),c.push({calc:\"stringify\",sourceColumn:1,type:\"string\",role:\"annotation\"}));this.type!=D.ob.yg.Wk&&(a.push({targetAxisIndex:e++}),c.push(2),c.push({calc:\"stringify\",sourceColumn:2,type:\"string\",role:\"annotation\"}));var g=this.$[D.ob.xg.EMPTY],e=this.$[D.ob.xg.Zt];g.style.display=b.Zc?\"block\":\"none\";e.style.display=b.Zc?\"none\":\"block\";b.Zc||(g=google.visualization.arrayToDataTable(b.pr),\ng=new google.visualization.DataView(g),g.setColumns(c),c=new google.visualization.ColumnChart(e),c.draw(g,{enableInteractivity:!1,bar:{groupWidth:\"99%\"},hAxis:{ticks:b.dB},vAxis:{ticks:[{v:0,f:\"\"}]},legend:{position:\"top\"},tooltip:{trigger:\"none\"},series:a,width:this.Dr(),height:D.ob.ED}),this.$M(b.eB))},YB:function(a,b,c,e){if(0>=b)throw\"number of buckets must be larger than zero\";var g=a.tf,k=a.ki(this.metric);a=a.getColumnRange(this.metric);var m=[this.metric,D.ob.hv.Wk,D.ob.hv.pn],n=[m];if(c>\ne||a.min>e||a.max<c||!g.length)return{pr:[m],dB:[],eB:[],Zc:!0};0==e-c&&(e=c+Math.pow(.1,D.Nh)*b);var q=(e-c)/b;e=[];for(a=0;a<=b;a++)m=c+a*q,e.push({v:m,f:m.toFixed(D.Nh)});for(a=0;a<b;a++)n.push([c+q*(a+.5),0,0]);var v=this.data.ki(this.weightedExamplesColumn),B={};g.forEach(function(a){var e=a.Bh(),g=e[v],e=e[k],e=Math.floor((e-c)/q),e=Math.min(e,b-1)+1;n[e][1]+=1;n[e][2]+=g;a=a.Ah();-1!=this.selectedFeatures.indexOf(a)&&(B[e-1]=!0,this.type==D.ob.yg.Ai&&(B[e+b-1]=!0))}.bind(this));if(this.logarithmScale)for(a=\n1;a<n.length;a++)n[a][1]=Math.log(n[a][1]+1),n[a][2]=Math.log(n[a][2]+1);return{pr:n,dB:e,Zc:!1,eB:Object.keys(B)}},xx:function(a,b){var c=D.ei.select(this.$[D.ob.xg.Hu]),e=c.select(\"rect#focus\");e.empty()&&(e=c.append(\"rect\").attr(\"id\",D.ob.xg.uD));c=this.Jr();e.attr(\"x\",c*a).attr(\"width\",c*(b-a)).attr(\"height\",D.ob.dn*(this.type==D.ob.yg.Ai?2:1))},yx:function(a,b,c){var e=b.slice(1);if(e.length){b=this.Jr();var g=D.ob.dn,k=[e[0][0],e[e.length-1][0]],m=D.ei.scaleLinear().domain(k).range([0,b]),n=\nD.ei.scaleLinear().domain([c.min,c.max]).range([0,g-D.ob.kE]);c=D.ei.line();var q=0,e=e.map(function(a){q=m(a[0]);return[q,g-n(a[1])]});e.push([q,g]);e.push([m(k[0]),g]);a.append(\"path\").attr(\"d\",c(e));a.append(\"rect\").attr(\"class\",\"overview\").attr(\"height\",g).attr(\"width\",b)}},$M:function(a){for(var b=this.$[D.ob.xg.Zt].getElementsByTagName(\"g\"),c,e=0;e<b.length;e++)if(null!=b[e].getAttribute(\"clip-path\")){c=b[e];break}for(var g=c.children[1],k=c.nextSibling.nextSibling.nextSibling,e=0;e<g.children.length;e++)g.children[e].classList.remove(\"highlighted\"),\nk.children[e].classList.remove(\"highlighted\");a.forEach(function(a){g.children[a].classList.add(\"highlighted\");k.children[a].classList.add(\"highlighted\")})},PP:function(){this.cp(0,1)},Es:function(){return\"undefined\"!=typeof google&&\"undefined\"!=typeof google.visualization&&\"undefined\"!=typeof google.visualization.ColumnChart&&\"\"!==this.metric&&this.numBuckets>=D.ob.Eu[0]&&this.numBuckets<=D.ob.Eu[1]},l$:function(){this.$[D.ob.xg.hE].open()},M3:function(a,b,c){var e=a.ki(b);b=a.getColumnRange(b);\nvar g=b.max-b.min;0==g&&(g=Math.pow(.1,D.Nh));var k=Math.max(b.min,b.min+g*c[0]),m=Math.min(b.max,b.min+g*c[1]);a=a.filter(function(a){a=a.Bh();return a[e]>=k&&a[e]<=m});return this.detailsData&&this.detailsData.ii(a)?this.detailsData:a},V3:function(a,b){a=a.lk();if(!a.length||\"\"===b)return[];a=a.slice();b=a.indexOf(b);if(-1==b)throw\"no data table column found for weighted examples\";a.splice(b,1);return a},aba:function(){this.selectableMetrics_.length&&(this.metric=this.selectableMetrics_[0])},saa:function(){this.Es()&&\nthis.Qo()},ZB:0,j$:function(){var a=this.Dr();a!=this.ZB&&(this.ZB=a,this.Qo())}});\nPolymer({is:\"gviz-table\",properties:{options:{type:Object},data:{type:Object},selection:{type:Array,notify:!0,observer:\"WP\"},chartReady:{type:Boolean,notify:!0},updatingSelection_:{type:Boolean,value:!1},table_:{type:Object},staticState_:{type:Object,value:{r:!1}}},observers:[\"Qo(table_,data,options)\"],ready:function(){var a=this;this.async(function(){a.chartReady=a.staticState_.r},1);this.$.loader.load(function(){return a.hN()})},hN:function(){var a=this,b=new google.visualization.Table(this.$.table);\nthis.table_=b;google.visualization.events.addListener(b,\"select\",function(){return a.zW()});this.chartReady=!0;this.staticState_.r=!0;this.selection&&b.setSelection(this.selection)},zW:function(){this.updatingSelection_=!0;this.selection=this.table_.getSelection();this.updatingSelection_=!1},WP:function(a){this.updatingSelection_||this.table_&&this.table_.setSelection(a)},Qo:function(a,b,c){this.$.loader.Dl(b).then(function(b){a.draw(b,c)})}});\nPolymer({is:\"bounded-value\",properties:{upperBound:{type:Number},lowerBound:{type:Number},value_:{type:String,computed:\"W3(lowerBound,upperBound)\"},range_:{type:String,computed:\"U3(lowerBound,upperBound)\"},data:{type:String,value:\"\",observer:\"F4\"}},F4:function(){if(this.data){var a=JSON.parse(this.data);this.upperBound=a.upperBound;this.lowerBound=a.lowerBound}},U3:function(a,b){return((b-a)/2).toFixed(D.Nh)},W3:function(a,b){return((b+a)/2).toFixed(D.Nh)}});\nPolymer({is:\"precision-at-k\",properties:{data:{type:String},formattedData_:{type:Object,computed:\"g6(data)\"}},g6:function(a){var b;try{b=JSON.parse(a)}catch(c){}if(b&&Array.isArray(b))return b.map(function(a){return{k:a.k||\"\",value:(a.value||0).toFixed(D.Nh),total:a.totalPositives||0}})}});window.Promise||(window.Promise=Mw(Polymer.Base.async));\nPromise.all=Promise.all||function(){var a=Array.prototype.slice.call(1===arguments.length&&Array.isArray(arguments[0])?arguments[0]:arguments);return new Promise(function(b,c){function e(k,n){try{if(n&&(\"object\"===typeof n||\"function\"===typeof n)){var m=n.then;if(\"function\"===typeof m){m.call(n,function(a){e(k,a)},c);return}}a[k]=n;0===--g&&b(a)}catch(v){c(v)}}if(0===a.length)return b([]);for(var g=a.length,k=0;k<a.length;k++)e(k,a[k])})};\nPromise.race=Promise.race||function(a){var b=a;return new Promise(function(a,e){for(var c=0,k=b.length;c<k;c++)b[c].then(a,e)})};\nfunction Mw(a){function b(b){var c=this;null===this.ll?this.xn.push(b):a(function(){var a=c.ll?b.KO:b.LO;if(\"function\"!==typeof a)(c.ll?b.resolve:b.reject)(c.uh);else{var e;try{e=a(c.uh)}catch(C){b.reject(C);return}b.resolve(e)}})}function c(a){try{if(a===this)throw new TypeError;if(a&&(\"object\"===typeof a||\"function\"===typeof a)){var b=a.then;if(\"function\"===typeof b){k(b.bind(a),c.bind(this),e.bind(this));return}}this.ll=!0;this.uh=a;g.call(this)}catch(v){e.call(this,v)}}function e(a){this.ll=!1;\nthis.uh=a;g.call(this)}function g(){for(var a=0,c=this.xn.length;a<c;a++)b.call(this,this.xn[a]);this.xn=null}function k(a,b,c){var e=!1;try{a(function(a){e||(e=!0,b(a))},function(a){e||(e=!0,c(a))})}catch(C){e||(e=!0,c(C))}}var m=function(a){if(\"object\"!==typeof this||\"function\"!==typeof a)throw new TypeError;this.uh=this.ll=null;this.xn=[];k(a,c.bind(this),e.bind(this))};m.prototype[\"catch\"]=function(a){return this.then(null,a)};m.prototype.then=function(a,c){var e=this;return new m(function(g,\nk){b.call(e,{KO:a,LO:c,resolve:g,reject:k})})};m.resolve=function(a){return a&&\"object\"===typeof a&&a.constructor===Promise?a:new m(function(b){b(a)})};m.reject=function(a){return new m(function(b,c){c(a)})};return m}V.yp={};V.yp.oY={};\nPolymer({is:\"iron-request\",hostAttributes:{hidden:!0},properties:{xhr:{type:Object,notify:!0,readOnly:!0,value:function(){return new XMLHttpRequest}},response:{type:Object,notify:!0,readOnly:!0,value:function(){return null}},status:{type:Number,notify:!0,readOnly:!0,value:0},statusText:{type:String,notify:!0,readOnly:!0,value:\"\"},completes:{type:Object,readOnly:!0,notify:!0,value:function(){return new Promise(function(a,b){this.QP=a;this.sm=b}.bind(this))}},progress:{type:Object,notify:!0,readOnly:!0,\nvalue:function(){return{}}},aborted:{type:Boolean,notify:!0,readOnly:!0,value:!1},errored:{type:Boolean,notify:!0,readOnly:!0,value:!1},timedOut:{type:Boolean,notify:!0,readOnly:!0,value:!1}},get lW(){if(this.errored||this.aborted||this.timedOut)return!1;var a=this.xhr.status||0;return 0===a||200<=a&&300>a},send:function(a){var b=this.xhr;if(0<b.readyState)return null;b.addEventListener(\"progress\",function(a){this._setProgress({lengthComputable:a.lengthComputable,loaded:a.loaded,total:a.total})}.bind(this));\nb.addEventListener(\"error\",function(a){this._setErrored(!0);this.Tn();this.sm(a)}.bind(this));b.addEventListener(\"timeout\",function(a){this._setTimedOut(!0);this.Tn();this.sm(a)}.bind(this));b.addEventListener(\"abort\",function(){this.Tn();this.sm(Error(\"Request aborted.\"))}.bind(this));b.addEventListener(\"loadend\",function(){this.Tn();this.lW?(this._setResponse(this.TO()),this.QP(this)):this.sm(Error(\"The request failed with status code: \"+this.xhr.status))}.bind(this));this.url=a.url;b.open(a.method||\n\"GET\",a.url,!1!==a.async);var c={json:\"application/json\",text:\"text/plain\",html:\"text/html\",xml:\"application/xml\",arraybuffer:\"application/octet-stream\"}[a.handleAs],e=a.headers||Object.create(null),g=Object.create(null),k;for(k in e)g[k.toLowerCase()]=e[k];e=g;c&&!e.accept&&(e.accept=c);Object.keys(e).forEach(function(a){/[A-Z]/.test(a)&&console.error(\"Headers must be lower case, got\",a);b.setRequestHeader(a,e[a])},this);if(!1!==a.async){c=a.handleAs;if(a.jsonPrefix||!c)c=\"text\";b.responseType=b.MG=\nc;a.jsonPrefix&&(b.Pv=a.jsonPrefix)}b.withCredentials=!!a.withCredentials;b.timeout=a.timeout;a=this.AF(a.body,e[\"content-type\"]);b.send(a);return this.completes},TO:function(){var a=this.xhr,b=a.responseType||a.MG,c=!this.xhr.responseType,e=a.Pv&&a.Pv.length||0;try{switch(b){case \"json\":if(c||void 0===a.response)try{return JSON.parse(a.responseText)}catch(g){return null}return a.response;case \"xml\":return a.responseXML;case \"blob\":case \"document\":case \"arraybuffer\":return a.response;default:if(e)try{return JSON.parse(a.responseText.substring(e))}catch(g){return null}return a.responseText}}catch(g){this.sm(Error(\"Could not parse response. \"+\ng.message))}},abort:function(){this._setAborted(!0);this.xhr.abort()},AF:function(a,b){if(\"string\"==typeof a)return a;var c=a;switch(b){case \"application/json\":return JSON.stringify(c);case \"application/x-www-form-urlencoded\":return this.rH(c)}return a},rH:function(a){if(!a)return\"\";var b=[];Object.keys(a).forEach(function(c){b.push(this.Dw(c)+\"\\x3d\"+this.Dw(a[c]))},this);return b.join(\"\\x26\")},Dw:function(a){return encodeURIComponent(a.toString().replace(/\\r?\\n/g,\"\\r\\n\")).replace(/%20/g,\"+\")},Tn:function(){this._setStatus(this.xhr.status);\nthis._setStatusText(void 0===this.xhr.statusText?\"\":this.xhr.statusText)}});V.yp.yp={};\nPolymer({is:\"iron-ajax\",hostAttributes:{hidden:!0},properties:{url:{type:String},params:{type:Object,value:function(){return{}}},method:{type:String,value:\"GET\"},headers:{type:Object,value:function(){return{}}},contentType:{type:String,value:null},body:{type:Object,value:null},sync:{type:Boolean,value:!1},handleAs:{type:String,value:\"json\"},withCredentials:{type:Boolean,value:!1},timeout:{type:Number,value:0},auto:{type:Boolean,value:!1},verbose:{type:Boolean,value:!1},lastRequest:{type:Object,notify:!0,\nreadOnly:!0},loading:{type:Boolean,notify:!0,readOnly:!0},lastResponse:{type:Object,notify:!0,readOnly:!0},lastError:{type:Object,notify:!0,readOnly:!0},activeRequests:{type:Array,notify:!0,readOnly:!0,value:function(){return[]}},debounceDuration:{type:Number,value:0,notify:!0},jsonPrefix:{type:String,value:\"\"},bubbles:{type:Boolean,value:!1},_boundHandleResponse:{type:Function,value:function(){return this.TF.bind(this)}}},observers:[\"i1(url,method,params.*,headers,contentType,body,sync,handleAs,jsonPrefix,withCredentials,timeout,auto)\"],\nget dP(){var a=[],b,c;for(b in this.params)if(c=this.params[b],b=window.encodeURIComponent(b),Array.isArray(c))for(var e=0;e<c.length;e++)a.push(b+\"\\x3d\"+window.encodeURIComponent(c[e]));else null!==c?a.push(b+\"\\x3d\"+window.encodeURIComponent(c)):a.push(b);return a.join(\"\\x26\")},get NP(){var a=this.dP;if(a){var b=0<=this.url.indexOf(\"?\")?\"\\x26\":\"?\";return this.url+b+a}return this.url},get MP(){var a={},b=this.contentType;null==b&&\"string\"===typeof this.body&&(b=\"application/x-www-form-urlencoded\");\nb&&(a[\"content-type\"]=b);var c;if(this.headers instanceof Object)for(c in this.headers)a[c]=this.headers[c].toString();return a},qW:function(){return{url:this.NP||\"\",method:this.method,headers:this.MP,body:this.body,async:!this.sync,handleAs:this.handleAs,jsonPrefix:this.jsonPrefix,withCredentials:this.withCredentials,timeout:this.timeout}},generateRequest:function(){var a=document.createElement(\"iron-request\"),b=this.qW();this.activeRequests.push(a);a.completes.then(this._boundHandleResponse).catch(this.SF.bind(this,\na)).then(this.vF.bind(this,a));a.send(b);this._setLastRequest(a);this._setLoading(!0);this.fire(\"request\",{request:a,options:b},{bubbles:this.bubbles});return a},TF:function(a){a===this.lastRequest&&(this._setLastResponse(a.response),this._setLastError(null),this._setLoading(!1));this.fire(\"response\",a,{bubbles:this.bubbles})},SF:function(a,b){this.verbose&&console.error(b);a===this.lastRequest&&(this._setLastError({request:a,error:b}),this._setLastResponse(null),this._setLoading(!1));this.fire(\"error\",\n{request:a,error:b},{bubbles:this.bubbles})},vF:function(a){a=this.activeRequests.indexOf(a);-1<a&&this.activeRequests.splice(a,1)},i1:function(){this.debounce(\"generate-request\",function(){null!=this.url&&this.auto&&this.generateRequest()},this.debounceDuration)}});\nPolymer({is:\"google-chart\",properties:{type:{type:String,value:\"column\",observer:\"xw\"},events:{type:Array,value:function(){return[]}},options:{type:Object},cols:{type:Array,observer:\"o1\"},rows:{type:Array,observer:\"o1\"},data:{type:Object,observer:\"c0\"},view:{type:Object,observer:\"F1\"},selection:{type:Array,notify:!0,observer:\"TG\"},drawn:{type:Boolean,readOnly:!0,value:!1}},observers:[\"xF(Th,el)\",\"u1(options.*)\"],listeners:{\"google-chart-select\":\"E1\",\"google-chart-ready\":\"K0\"},Th:null,el:null,Jf:null,\nxw:function(){this.$.loader.create(this.type,this.$.chartdiv).then(function(a){var b=this.$.loader;Object.keys(this.events.concat([\"select\",\"ready\"]).reduce(function(a,b){a[b]=!0;return a},{})).forEach(function(c){b.YK(a,c)});this._setDrawn(!1);this.Th=a}.bind(this))},u1:function(a){this.options=a.base;this.debounce(\"optionChangeRedraw\",function(){this.redraw()},5)},TG:function(){this.drawn&&this.selection&&this.selection!==this.Jf&&(this.Th.setSelection&&this.Th.setSelection(this.selection),this.Jf=\nthis.selection)},E1:function(){this.selection=this.Jf=this.Th.getSelection()},K0:function(){this._setDrawn(!0);this.Jf=null;this.TG()},redraw:function(){this.Th&&this.el&&this.xF(this.Th,this.el)},xF:function(a,b){try{this._setDrawn(!1),a.draw(b,this.options||{})}catch(c){this.$.chartdiv.innerHTML=c}},get p7(){return this.Th?this.Th.getImageURI():null},F1:function(a){a&&(this.el=a)},o1:function(){var a=this.rows,b=this.cols;a&&b&&this.$.loader.Dl().then(function(c){b.forEach(function(a){c.addColumn(a)});\nc.addRows(a);return c}.bind(this)).then(this.$.loader.no.bind(this.$.loader)).then(function(a){this.el=a}.bind(this)).catch(function(a){this.$.chartdiv.innerHTML=a}.bind(this))},c0:function(a){if(a){if(\"string\"==typeof a||a instanceof String){var b=document.createElement(\"iron-request\");a=b.send({url:a,handleAs:\"json\"}).then(function(a){return a.response})}else a=Promise.resolve(a);a.then(this.$.loader.Dl.bind(this.$.loader)).then(this.$.loader.no.bind(this.$.loader)).then(function(a){this.el=a}.bind(this))}}});\n(function(){var a={area:{ctor:\"AreaChart\"},bar:{ctor:\"BarChart\"},\"md-bar\":{ctor:\"Bar\",Eh:\"bar\"},bubble:{ctor:\"BubbleChart\"},candlestick:{ctor:\"CandlestickChart\"},column:{ctor:\"ColumnChart\"},combo:{ctor:\"ComboChart\"},geo:{ctor:\"GeoChart\"},histogram:{ctor:\"Histogram\"},line:{ctor:\"LineChart\"},\"md-line\":{ctor:\"Line\",Eh:\"line\"},org:{ctor:\"OrgChart\",Eh:\"orgchart\"},pie:{ctor:\"PieChart\"},scatter:{ctor:\"ScatterChart\"},\"md-scatter\":{ctor:\"Scatter\",Eh:\"scatter\"},\"stepped-area\":{ctor:\"SteppedAreaChart\"},table:{ctor:\"Table\",\nEh:\"table\"},timeline:{ctor:\"Timeline\",Eh:\"timeline\"},gauge:{ctor:\"Gauge\",Eh:\"gauge\"},treemap:{ctor:\"TreeMap\",Eh:\"treemap\"},calendar:{ctor:\"Calendar\",Eh:\"calendar\"}},b={},c={},e={};Polymer({is:\"google-chart-loader\",properties:{packages:{type:Array,value:function(){return[]},observer:\"Tv\"},type:{type:String,observer:\"eG\"}},get wn(){return c.corechart?c.corechart:this.Tv([\"corechart\"]).then(function(a){return a[0]})},fG:function(){this.debounce(\"loadPackages\",function(){var a=Object.keys(b);a.length&&\n(b={},google.charts.load(\"current\",{packages:a,language:document.documentElement.lang||\"en\"}),google.charts.setOnLoadCallback(function(){a.forEach(function(a){this.fire(\"loaded\",a);e[a](google.visualization)}.bind(this))}.bind(this)))},100)},Tv:function(a){var g=[];a.forEach(function(a){c[a]||(b[a]=!0,c[a]=new Promise(function(b){e[a]=b}),this.fG());g.push(c[a])}.bind(this));return Promise.all(g)},eG:function(b){var c=a[b];return this.Tv([c.Eh||\"corechart\"]).then(function(){return google[0===b.indexOf(\"md-\")?\n\"charts\":\"visualization\"][c.ctor]})},create:function(a,b){return this.eG(a).then(function(a){return new a(b)})},YK:function(a,b,c){return this.wn.then(function(e){e=c?e.events.addOneTimeListener:e.events.addListener;e(a,b,function(c){this.fire(\"google-chart-\"+b,{r3:a,data:c})}.bind(this))}.bind(this))},Dl:function(a){return this.wn.then(function(b){return null==a?new b.DataTable:a.getNumberOfRows?a:a.cols?new b.DataTable(a):0<a.length?b.arrayToDataTable(a):0===a.length?Promise.reject(\"Data was empty.\"):\nPromise.reject(\"Data format was not recognized.\")})},no:function(a){return this.wn.then(function(b){return new b.DataView(a)})},query:function(a,b){return this.wn.then(function(c){return new c.Query(a,b)})}})})();V.Vf.Ci={};V.Vf.Ci.FE={};V.Vf.Ci.LE={};V.Ij.Ci={};V.Ij.Ci.qY={};console.warn(\"This file is deprecated. Please use `iron-flex-layout/iron-flex-layout-classes.html`, and one of the specific dom-modules instead\");V.Ij.Ci.Ij={};console.warn(\"This file is deprecated. Please use `iron-flex-layout/iron-flex-layout-classes.html`, and one of the specific dom-modules instead\");\nV.Vf.yZ={};V.Vf.Ci.XX={};V.Vf.Ci.VZ={};V.Vf.uX={};V.Vf.Vf={};D.Fi={};D.Fi.IX={TW:\"arrow-asc\",UW:\"arrow-desc\",m_:\"visible-column\"};D.Fi.JY=20;D.Fi.ln=\"gviz-table\";\nPolymer({is:\"metrics-table\",properties:{metrics:{type:Array,value:function(){return[]}},metricFormats:{type:Object,value:function(){return{}}},data:Object,options:{type:Object,value:function(){return{allowHtml:!0,width:\"100%\",page:\"enable\",pageSize:20,pageButtons:\"auto\"}}},selection:{type:Array,observer:\"WP\",notify:!0},selected:{type:String,value:\"\"},tableReady_:{type:Boolean,value:!1},plotData_:{type:Array,computed:\"T3(data,selected,metrics,metricFormats,tableReady_)\"}},ready:function(){var a=this.querySelector(D.Fi.ln);\nthis.tm=!0;var b=function(){a.removeEventListener(\"google-chart-ready\",b);this.tableReady_=!0}.bind(this);a.addEventListener(\"google-chart-ready\",b)},select:function(a){this.qC(a,!0)},clearSelection:function(){this.ax(!0)},X6:function(a){this.qC(a,!1)},x3:function(){this.ax(!1)},qC:function(a,b){for(var c=this.querySelector(D.Fi.ln),e=-1,g=this.plotData_,k=1;k<g.length;k++)if(g[k][0].f==a){e=k-1;break}h.R.assert(-1!=e);this.tm=b;c.selection=[{row:e}];this.tm=!0},ax:function(a){var b=this.querySelector(D.Fi.ln);\nthis.tm=a;b.selection=[];this.tm=!0},WP:function(){if(this.tm){var a=this.querySelector(D.Fi.ln),b=a.selection;b.length?(a=this.plotData_[a.selection[0].row+1][0].f,this.dispatchEvent(new CustomEvent(D.Event.Op,{detail:a}))):this.dispatchEvent(new Event(D.Event.Vt))}},T3:function(a,b,c,e,g){if(!g||!a.zs(b))return[[]];var k=a.Gr(c);b=a.getDataTable(b);var m=a.Fr(e);e=b.map(function(b){return k.map(function(c,e){return D.data.Ua.JP(b[e],a,m[c])})});return[k].concat(e)}});D.Ji={};D.Ji.Xt=\"Slice\";\nD.Ji.XD=680;D.Ji.$C=200;\nPolymer({is:\"slice-overview\",properties:{slices:{type:Object},chart_:{type:Object},metrics_:{type:Array,computed:\"S3(slices)\"},metricsForSorting_:{type:Array,computed:\"Q3(metrics_)\"},metricToShow:{type:String},metricToSort_:{type:String,value:D.Ji.Xt},chartPackages_:{type:Array,value:[\"corechart\"]},displayed:{type:Boolean},dataView_:{type:Object}},observers:[\"A$(displayed,slices,metricToShow,metricToSort_,chart_)\"],S3:function(a){if(!a)return[];var b=a.lk(),c={};a.jk().forEach(function(e){e=a.Hl(e);\ne.forEach(function(a,e){!h.ni(a)&&h.Ch(a)&&(c[b[e]]=!0)})});return b.map(function(a){return{name:a,disabled:!!c[a]}})},Q3:function(a){return[{name:D.Ji.Xt,disabled:!1}].concat(a)},A$:function(a,b,c,e,g){var k=this;if(a&&b&&g&&c&&e){var m=b.ki(c);if(-1!=m){var n=b.ki(e),q=[[\"feature\"].concat(b.lk())],v=-1!=n&&e!=c;b.jk().forEach(function(a){var c=b.Hl(a),g=a;v&&(g={v:a,f:a+\", \"+e+\":\"+c[n].toFixed(D.Nh)});q.push([g].concat(c.map(function(a){return h.ni(a)?a:NaN})))});this.$.loader.Dl(q).then(function(a){-1!=\nn&&a.sort([{column:n+1}]);k.$.loader.no(a).then(function(a){a.setColumns([0,m+1]);k.dataView_=a;k.chart_.draw(a,{bar:{groupWidth:\"75%\"},hAxis:{ticks:[]},legend:{position:\"top\"},width:Math.max(k.getBoundingClientRect().width,D.Ji.XD),height:D.Ji.$C})})})}}},ready:function(){var a=this;this.$.loader.create(\"column\",this.$.chart).then(function(b){return a.chart_=b});this.displayed=0<this.getBoundingClientRect().width}});V.wu={};V.wu.wu={};\nPolymer({is:\"iron-pages\",behaviors:[Polymer.Jj,Polymer.Nk],properties:{activateEvent:{type:String,value:null}},observers:[\"q1(selected)\"],q1:function(){this.async(this.ri)}});D.Ff={};D.Ff.xg={GE:\"table\",FD:\"histogram\",cX:\"chart-type\",ZE:\"weighted-examples-threshold\"};D.Ff.Hk={Pp:0,Bu:1};D.Ff.CE=50;D.Ff.YE=10;\nPolymer({is:\"lantern-browser\",properties:{data:{type:Array,value:function(){return[]}},metrics:{type:Array,value:function(){return[]}},sourceType:{type:String},weightedExamplesColumn:{type:String,value:\"\"},weightedExamplesThreshold:{type:Number,value:0},chartType:{type:String,value:D.Ff.Hk.Bu,observer:\"s3\"},selectedFeatures:{type:Array,value:function(){return[]}},selectedColumn:{type:String,value:\"\"},calibrationPlotUriFn:{type:Object,value:null},lanternData_:{type:Object,computed:\"O3(metrics,data,sourceType)\",\nobserver:\"c8\"},filteredData_:{type:Object,computed:\"N3(lanternData_,weightedExamplesColumn,weightedExamplesThreshold)\",observer:\"Z5\"},focusedData_:{type:Object,value:new D.Jb([],[])},weightedExamplesInfo_:{type:Object,computed:\"X3(lanternData_,weightedExamplesColumn,calibrationPlotUriFn)\"},metricFormats_:{type:Object,computed:\"P3(focusedData_,weightedExamplesColumn,calibrationPlotUriFn)\"},metricsTableData_:{type:Object,computed:\"R3(chartType,filteredData_,focusedData_)\"}},observers:[\"nda(lanternData_)\"],\nready:function(){this.fN();this.gN()},fN:function(){var a=this.$[D.Ff.xg.GE];a.addEventListener(D.Event.Op,function(a){a=a.detail;this.selectedFeatures=[a]}.bind(this))},gN:function(){var a=this.$[D.Ff.xg.ZE],b=a.getElementsByTagName(\"input\")[0],c=a.getElementsByTagName(\"paper-slider\")[0],a=function(a){a=+a.target.value;c.setAttribute(\"value\",a);this.weightedExamplesThreshold=a}.bind(this);b.addEventListener(D.Event.xu,a);c.addEventListener(D.Event.KD,function(a){a=+a.target.getElementsByTagName(\"paper-progress\")[0].getAttribute(\"value\");\nb.value=a});c.addEventListener(D.Event.Ut,function(a){this.weightedExamplesThreshold=a=+a.target.getElementsByTagName(\"paper-progress\")[0].getAttribute(\"value\")}.bind(this))},nda:function(a){a=a.vB()?\"none\":\"\";for(var b=this.getElementsByClassName(\"vis\"),c=0;c<b.length;c++)b[c].style.display=a},O3:function(a,b,c){return D.Jb.Vw(a,b,c)},N3:function(a,b,c){var e=a.ki(b);return a.filter(function(a){a=a.Bh();return a[e]>=c})},X3:function(a,b){b=a.getColumnRange(b);a=Math.min(D.Ff.YE,Math.ceil(b.max/100));\nb=Math.ceil((b.max+1)/a)*a;return{max:b,step:a}},P3:function(a,b,c){var e={};e[b]={type:D.Pk.INT};a.Xr()&&(a=function(a){var b=\"\";a.to()&&c&&(a=a.Ah(),a==D.Pf.Kj&&(a=\"\"),b='\\x3ca href\\x3d\"'+c(a)+'\" target\\x3d\"_blank\" class\\x3d\"links\"\\x3eCalib. Plot\\x3c/a\\x3e');return b}.bind(this),e[D.Pf.yu]={type:D.Pk.GD,transform:{withDataSeries:a}});return e},Z5:function(){this.$[D.Ff.xg.FD].cp(0,1)},s3:function(a){this.querySelector(\"slice-overview\").displayed=a==D.Ff.Hk.Pp},c8:function(a){this.chartType=a&&a.jk().length>\nD.Ff.CE?D.Ff.Hk.Bu:D.Ff.Hk.Pp},R3:function(a,b,c){return a==D.Ff.Hk.Pp?b:c}});\n</script></body></html>\n"
  },
  {
    "path": "datalab/notebook/static/extern/parcoords-LICENSE.txt",
    "content": "Copyright (c) 2012, Kai Chang\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n* Redistributions of source code must retain the above copyright notice, this\n  list of conditions and the following disclaimer.\n\n* Redistributions in binary form must reproduce the above copyright notice,\n  this list of conditions and the following disclaimer in the documentation\n  and/or other materials provided with the distribution.\n\n* The name Kai Chang may not be used to endorse or promote products\n  derived from this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL MICHAEL BOSTOCK BE LIABLE FOR ANY DIRECT,\nINDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\nBUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY\nOF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\nNEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\nEVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "datalab/notebook/static/extern/sylvester-LICENSE.txt",
    "content": "(The MIT License)\n\nCopyright (c) 2007-2015 James Coglan\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "datalab/notebook/static/extern/sylvester.js",
    "content": "// === Sylvester ===\n// Vector and Matrix mathematics modules for JavaScript\n// Copyright (c) 2007 James Coglan\n// \n// Permission is hereby granted, free of charge, to any person obtaining\n// a copy of this software and associated documentation files (the \"Software\"),\n// to deal in the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nvar Sylvester = {\n  version: '0.1.3',\n  precision: 1e-6\n};\n\nfunction Vector() {}\nVector.prototype = {\n\n  // Returns element i of the vector\n  e: function(i) {\n    return (i < 1 || i > this.elements.length) ? null : this.elements[i-1];\n  },\n\n  // Returns the number of elements the vector has\n  dimensions: function() {\n    return this.elements.length;\n  },\n\n  // Returns the modulus ('length') of the vector\n  modulus: function() {\n    return Math.sqrt(this.dot(this));\n  },\n\n  // Returns true iff the vector is equal to the argument\n  eql: function(vector) {\n    var n = this.elements.length;\n    var V = vector.elements || vector;\n    if (n != V.length) { return false; }\n    do {\n      if (Math.abs(this.elements[n-1] - V[n-1]) > Sylvester.precision) { return false; }\n    } while (--n);\n    return true;\n  },\n\n  // Returns a copy of the vector\n  dup: function() {\n    return Vector.create(this.elements);\n  },\n\n  // Maps the vector to another vector according to the given function\n  map: function(fn) {\n    var elements = [];\n    this.each(function(x, i) {\n      elements.push(fn(x, i));\n    });\n    return Vector.create(elements);\n  },\n  \n  // Calls the iterator for each element of the vector in turn\n  each: function(fn) {\n    var n = this.elements.length, k = n, i;\n    do { i = k - n;\n      fn(this.elements[i], i+1);\n    } while (--n);\n  },\n\n  // Returns a new vector created by normalizing the receiver\n  toUnitVector: function() {\n    var r = this.modulus();\n    if (r === 0) { return this.dup(); }\n    return this.map(function(x) { return x/r; });\n  },\n\n  // Returns the angle between the vector and the argument (also a vector)\n  angleFrom: function(vector) {\n    var V = vector.elements || vector;\n    var n = this.elements.length, k = n, i;\n    if (n != V.length) { return null; }\n    var dot = 0, mod1 = 0, mod2 = 0;\n    // Work things out in parallel to save time\n    this.each(function(x, i) {\n      dot += x * V[i-1];\n      mod1 += x * x;\n      mod2 += V[i-1] * V[i-1];\n    });\n    mod1 = Math.sqrt(mod1); mod2 = Math.sqrt(mod2);\n    if (mod1*mod2 === 0) { return null; }\n    var theta = dot / (mod1*mod2);\n    if (theta < -1) { theta = -1; }\n    if (theta > 1) { theta = 1; }\n    return Math.acos(theta);\n  },\n\n  // Returns true iff the vector is parallel to the argument\n  isParallelTo: function(vector) {\n    var angle = this.angleFrom(vector);\n    return (angle === null) ? null : (angle <= Sylvester.precision);\n  },\n\n  // Returns true iff the vector is antiparallel to the argument\n  isAntiparallelTo: function(vector) {\n    var angle = this.angleFrom(vector);\n    return (angle === null) ? null : (Math.abs(angle - Math.PI) <= Sylvester.precision);\n  },\n\n  // Returns true iff the vector is perpendicular to the argument\n  isPerpendicularTo: function(vector) {\n    var dot = this.dot(vector);\n    return (dot === null) ? null : (Math.abs(dot) <= Sylvester.precision);\n  },\n\n  // Returns the result of adding the argument to the vector\n  add: function(vector) {\n    var V = vector.elements || vector;\n    if (this.elements.length != V.length) { return null; }\n    return this.map(function(x, i) { return x + V[i-1]; });\n  },\n\n  // Returns the result of subtracting the argument from the vector\n  subtract: function(vector) {\n    var V = vector.elements || vector;\n    if (this.elements.length != V.length) { return null; }\n    return this.map(function(x, i) { return x - V[i-1]; });\n  },\n\n  // Returns the result of multiplying the elements of the vector by the argument\n  multiply: function(k) {\n    return this.map(function(x) { return x*k; });\n  },\n\n  x: function(k) { return this.multiply(k); },\n\n  // Returns the scalar product of the vector with the argument\n  // Both vectors must have equal dimensionality\n  dot: function(vector) {\n    var V = vector.elements || vector;\n    var i, product = 0, n = this.elements.length;\n    if (n != V.length) { return null; }\n    do { product += this.elements[n-1] * V[n-1]; } while (--n);\n    return product;\n  },\n\n  // Returns the vector product of the vector with the argument\n  // Both vectors must have dimensionality 3\n  cross: function(vector) {\n    var B = vector.elements || vector;\n    if (this.elements.length != 3 || B.length != 3) { return null; }\n    var A = this.elements;\n    return Vector.create([\n      (A[1] * B[2]) - (A[2] * B[1]),\n      (A[2] * B[0]) - (A[0] * B[2]),\n      (A[0] * B[1]) - (A[1] * B[0])\n    ]);\n  },\n\n  // Returns the (absolute) largest element of the vector\n  max: function() {\n    var m = 0, n = this.elements.length, k = n, i;\n    do { i = k - n;\n      if (Math.abs(this.elements[i]) > Math.abs(m)) { m = this.elements[i]; }\n    } while (--n);\n    return m;\n  },\n\n  // Returns the index of the first match found\n  indexOf: function(x) {\n    var index = null, n = this.elements.length, k = n, i;\n    do { i = k - n;\n      if (index === null && this.elements[i] == x) {\n        index = i + 1;\n      }\n    } while (--n);\n    return index;\n  },\n\n  // Returns a diagonal matrix with the vector's elements as its diagonal elements\n  toDiagonalMatrix: function() {\n    return Matrix.Diagonal(this.elements);\n  },\n\n  // Returns the result of rounding the elements of the vector\n  round: function() {\n    return this.map(function(x) { return Math.round(x); });\n  },\n\n  // Returns a copy of the vector with elements set to the given value if they\n  // differ from it by less than Sylvester.precision\n  snapTo: function(x) {\n    return this.map(function(y) {\n      return (Math.abs(y - x) <= Sylvester.precision) ? x : y;\n    });\n  },\n\n  // Returns the vector's distance from the argument, when considered as a point in space\n  distanceFrom: function(obj) {\n    if (obj.anchor) { return obj.distanceFrom(this); }\n    var V = obj.elements || obj;\n    if (V.length != this.elements.length) { return null; }\n    var sum = 0, part;\n    this.each(function(x, i) {\n      part = x - V[i-1];\n      sum += part * part;\n    });\n    return Math.sqrt(sum);\n  },\n\n  // Returns true if the vector is point on the given line\n  liesOn: function(line) {\n    return line.contains(this);\n  },\n\n  // Return true iff the vector is a point in the given plane\n  liesIn: function(plane) {\n    return plane.contains(this);\n  },\n\n  // Rotates the vector about the given object. The object should be a \n  // point if the vector is 2D, and a line if it is 3D. Be careful with line directions!\n  rotate: function(t, obj) {\n    var V, R, x, y, z;\n    switch (this.elements.length) {\n      case 2:\n        V = obj.elements || obj;\n        if (V.length != 2) { return null; }\n        R = Matrix.Rotation(t).elements;\n        x = this.elements[0] - V[0];\n        y = this.elements[1] - V[1];\n        return Vector.create([\n          V[0] + R[0][0] * x + R[0][1] * y,\n          V[1] + R[1][0] * x + R[1][1] * y\n        ]);\n        break;\n      case 3:\n        if (!obj.direction) { return null; }\n        var C = obj.pointClosestTo(this).elements;\n        R = Matrix.Rotation(t, obj.direction).elements;\n        x = this.elements[0] - C[0];\n        y = this.elements[1] - C[1];\n        z = this.elements[2] - C[2];\n        return Vector.create([\n          C[0] + R[0][0] * x + R[0][1] * y + R[0][2] * z,\n          C[1] + R[1][0] * x + R[1][1] * y + R[1][2] * z,\n          C[2] + R[2][0] * x + R[2][1] * y + R[2][2] * z\n        ]);\n        break;\n      default:\n        return null;\n    }\n  },\n\n  // Returns the result of reflecting the point in the given point, line or plane\n  reflectionIn: function(obj) {\n    if (obj.anchor) {\n      // obj is a plane or line\n      var P = this.elements.slice();\n      var C = obj.pointClosestTo(P).elements;\n      return Vector.create([C[0] + (C[0] - P[0]), C[1] + (C[1] - P[1]), C[2] + (C[2] - (P[2] || 0))]);\n    } else {\n      // obj is a point\n      var Q = obj.elements || obj;\n      if (this.elements.length != Q.length) { return null; }\n      return this.map(function(x, i) { return Q[i-1] + (Q[i-1] - x); });\n    }\n  },\n\n  // Utility to make sure vectors are 3D. If they are 2D, a zero z-component is added\n  to3D: function() {\n    var V = this.dup();\n    switch (V.elements.length) {\n      case 3: break;\n      case 2: V.elements.push(0); break;\n      default: return null;\n    }\n    return V;\n  },\n\n  // Returns a string representation of the vector\n  inspect: function() {\n    return '[' + this.elements.join(', ') + ']';\n  },\n\n  // Set vector's elements from an array\n  setElements: function(els) {\n    this.elements = (els.elements || els).slice();\n    return this;\n  }\n};\n  \n// Constructor function\nVector.create = function(elements) {\n  var V = new Vector();\n  return V.setElements(elements);\n};\n\n// i, j, k unit vectors\nVector.i = Vector.create([1,0,0]);\nVector.j = Vector.create([0,1,0]);\nVector.k = Vector.create([0,0,1]);\n\n// Random vector of size n\nVector.Random = function(n) {\n  var elements = [];\n  do { elements.push(Math.random());\n  } while (--n);\n  return Vector.create(elements);\n};\n\n// Vector filled with zeros\nVector.Zero = function(n) {\n  var elements = [];\n  do { elements.push(0);\n  } while (--n);\n  return Vector.create(elements);\n};\n\n\n\nfunction Matrix() {}\nMatrix.prototype = {\n\n  // Returns element (i,j) of the matrix\n  e: function(i,j) {\n    if (i < 1 || i > this.elements.length || j < 1 || j > this.elements[0].length) { return null; }\n    return this.elements[i-1][j-1];\n  },\n\n  // Returns row k of the matrix as a vector\n  row: function(i) {\n    if (i > this.elements.length) { return null; }\n    return Vector.create(this.elements[i-1]);\n  },\n\n  // Returns column k of the matrix as a vector\n  col: function(j) {\n    if (j > this.elements[0].length) { return null; }\n    var col = [], n = this.elements.length, k = n, i;\n    do { i = k - n;\n      col.push(this.elements[i][j-1]);\n    } while (--n);\n    return Vector.create(col);\n  },\n\n  // Returns the number of rows/columns the matrix has\n  dimensions: function() {\n    return {rows: this.elements.length, cols: this.elements[0].length};\n  },\n\n  // Returns the number of rows in the matrix\n  rows: function() {\n    return this.elements.length;\n  },\n\n  // Returns the number of columns in the matrix\n  cols: function() {\n    return this.elements[0].length;\n  },\n\n  // Returns true iff the matrix is equal to the argument. You can supply\n  // a vector as the argument, in which case the receiver must be a\n  // one-column matrix equal to the vector.\n  eql: function(matrix) {\n    var M = matrix.elements || matrix;\n    if (typeof(M[0][0]) == 'undefined') { M = Matrix.create(M).elements; }\n    if (this.elements.length != M.length ||\n        this.elements[0].length != M[0].length) { return false; }\n    var ni = this.elements.length, ki = ni, i, nj, kj = this.elements[0].length, j;\n    do { i = ki - ni;\n      nj = kj;\n      do { j = kj - nj;\n        if (Math.abs(this.elements[i][j] - M[i][j]) > Sylvester.precision) { return false; }\n      } while (--nj);\n    } while (--ni);\n    return true;\n  },\n\n  // Returns a copy of the matrix\n  dup: function() {\n    return Matrix.create(this.elements);\n  },\n\n  // Maps the matrix to another matrix (of the same dimensions) according to the given function\n  map: function(fn) {\n    var els = [], ni = this.elements.length, ki = ni, i, nj, kj = this.elements[0].length, j;\n    do { i = ki - ni;\n      nj = kj;\n      els[i] = [];\n      do { j = kj - nj;\n        els[i][j] = fn(this.elements[i][j], i + 1, j + 1);\n      } while (--nj);\n    } while (--ni);\n    return Matrix.create(els);\n  },\n\n  // Returns true iff the argument has the same dimensions as the matrix\n  isSameSizeAs: function(matrix) {\n    var M = matrix.elements || matrix;\n    if (typeof(M[0][0]) == 'undefined') { M = Matrix.create(M).elements; }\n    return (this.elements.length == M.length &&\n        this.elements[0].length == M[0].length);\n  },\n\n  // Returns the result of adding the argument to the matrix\n  add: function(matrix) {\n    var M = matrix.elements || matrix;\n    if (typeof(M[0][0]) == 'undefined') { M = Matrix.create(M).elements; }\n    if (!this.isSameSizeAs(M)) { return null; }\n    return this.map(function(x, i, j) { return x + M[i-1][j-1]; });\n  },\n\n  // Returns the result of subtracting the argument from the matrix\n  subtract: function(matrix) {\n    var M = matrix.elements || matrix;\n    if (typeof(M[0][0]) == 'undefined') { M = Matrix.create(M).elements; }\n    if (!this.isSameSizeAs(M)) { return null; }\n    return this.map(function(x, i, j) { return x - M[i-1][j-1]; });\n  },\n\n  // Returns true iff the matrix can multiply the argument from the left\n  canMultiplyFromLeft: function(matrix) {\n    var M = matrix.elements || matrix;\n    if (typeof(M[0][0]) == 'undefined') { M = Matrix.create(M).elements; }\n    // this.columns should equal matrix.rows\n    return (this.elements[0].length == M.length);\n  },\n\n  // Returns the result of multiplying the matrix from the right by the argument.\n  // If the argument is a scalar then just multiply all the elements. If the argument is\n  // a vector, a vector is returned, which saves you having to remember calling\n  // col(1) on the result.\n  multiply: function(matrix) {\n    if (!matrix.elements) {\n      return this.map(function(x) { return x * matrix; });\n    }\n    var returnVector = matrix.modulus ? true : false;\n    var M = matrix.elements || matrix;\n    if (typeof(M[0][0]) == 'undefined') { M = Matrix.create(M).elements; }\n    if (!this.canMultiplyFromLeft(M)) { return null; }\n    var ni = this.elements.length, ki = ni, i, nj, kj = M[0].length, j;\n    var cols = this.elements[0].length, elements = [], sum, nc, c;\n    do { i = ki - ni;\n      elements[i] = [];\n      nj = kj;\n      do { j = kj - nj;\n        sum = 0;\n        nc = cols;\n        do { c = cols - nc;\n          sum += this.elements[i][c] * M[c][j];\n        } while (--nc);\n        elements[i][j] = sum;\n      } while (--nj);\n    } while (--ni);\n    var M = Matrix.create(elements);\n    return returnVector ? M.col(1) : M;\n  },\n\n  x: function(matrix) { return this.multiply(matrix); },\n\n  // Returns a submatrix taken from the matrix\n  // Argument order is: start row, start col, nrows, ncols\n  // Element selection wraps if the required index is outside the matrix's bounds, so you could\n  // use this to perform row/column cycling or copy-augmenting.\n  minor: function(a, b, c, d) {\n    var elements = [], ni = c, i, nj, j;\n    var rows = this.elements.length, cols = this.elements[0].length;\n    do { i = c - ni;\n      elements[i] = [];\n      nj = d;\n      do { j = d - nj;\n        elements[i][j] = this.elements[(a+i-1)%rows][(b+j-1)%cols];\n      } while (--nj);\n    } while (--ni);\n    return Matrix.create(elements);\n  },\n\n  // Returns the transpose of the matrix\n  transpose: function() {\n    var rows = this.elements.length, cols = this.elements[0].length;\n    var elements = [], ni = cols, i, nj, j;\n    do { i = cols - ni;\n      elements[i] = [];\n      nj = rows;\n      do { j = rows - nj;\n        elements[i][j] = this.elements[j][i];\n      } while (--nj);\n    } while (--ni);\n    return Matrix.create(elements);\n  },\n\n  // Returns true iff the matrix is square\n  isSquare: function() {\n    return (this.elements.length == this.elements[0].length);\n  },\n\n  // Returns the (absolute) largest element of the matrix\n  max: function() {\n    var m = 0, ni = this.elements.length, ki = ni, i, nj, kj = this.elements[0].length, j;\n    do { i = ki - ni;\n      nj = kj;\n      do { j = kj - nj;\n        if (Math.abs(this.elements[i][j]) > Math.abs(m)) { m = this.elements[i][j]; }\n      } while (--nj);\n    } while (--ni);\n    return m;\n  },\n\n  // Returns the indeces of the first match found by reading row-by-row from left to right\n  indexOf: function(x) {\n    var index = null, ni = this.elements.length, ki = ni, i, nj, kj = this.elements[0].length, j;\n    do { i = ki - ni;\n      nj = kj;\n      do { j = kj - nj;\n        if (this.elements[i][j] == x) { return {i: i+1, j: j+1}; }\n      } while (--nj);\n    } while (--ni);\n    return null;\n  },\n\n  // If the matrix is square, returns the diagonal elements as a vector.\n  // Otherwise, returns null.\n  diagonal: function() {\n    if (!this.isSquare) { return null; }\n    var els = [], n = this.elements.length, k = n, i;\n    do { i = k - n;\n      els.push(this.elements[i][i]);\n    } while (--n);\n    return Vector.create(els);\n  },\n\n  // Make the matrix upper (right) triangular by Gaussian elimination.\n  // This method only adds multiples of rows to other rows. No rows are\n  // scaled up or switched, and the determinant is preserved.\n  toRightTriangular: function() {\n    var M = this.dup(), els;\n    var n = this.elements.length, k = n, i, np, kp = this.elements[0].length, p;\n    do { i = k - n;\n      if (M.elements[i][i] == 0) {\n        for (j = i + 1; j < k; j++) {\n          if (M.elements[j][i] != 0) {\n            els = []; np = kp;\n            do { p = kp - np;\n              els.push(M.elements[i][p] + M.elements[j][p]);\n            } while (--np);\n            M.elements[i] = els;\n            break;\n          }\n        }\n      }\n      if (M.elements[i][i] != 0) {\n        for (j = i + 1; j < k; j++) {\n          var multiplier = M.elements[j][i] / M.elements[i][i];\n          els = []; np = kp;\n          do { p = kp - np;\n            // Elements with column numbers up to an including the number\n            // of the row that we're subtracting can safely be set straight to\n            // zero, since that's the point of this routine and it avoids having\n            // to loop over and correct rounding errors later\n            els.push(p <= i ? 0 : M.elements[j][p] - M.elements[i][p] * multiplier);\n          } while (--np);\n          M.elements[j] = els;\n        }\n      }\n    } while (--n);\n    return M;\n  },\n\n  toUpperTriangular: function() { return this.toRightTriangular(); },\n\n  // Returns the determinant for square matrices\n  determinant: function() {\n    if (!this.isSquare()) { return null; }\n    var M = this.toRightTriangular();\n    var det = M.elements[0][0], n = M.elements.length - 1, k = n, i;\n    do { i = k - n + 1;\n      det = det * M.elements[i][i];\n    } while (--n);\n    return det;\n  },\n\n  det: function() { return this.determinant(); },\n\n  // Returns true iff the matrix is singular\n  isSingular: function() {\n    return (this.isSquare() && this.determinant() === 0);\n  },\n\n  // Returns the trace for square matrices\n  trace: function() {\n    if (!this.isSquare()) { return null; }\n    var tr = this.elements[0][0], n = this.elements.length - 1, k = n, i;\n    do { i = k - n + 1;\n      tr += this.elements[i][i];\n    } while (--n);\n    return tr;\n  },\n\n  tr: function() { return this.trace(); },\n\n  // Returns the rank of the matrix\n  rank: function() {\n    var M = this.toRightTriangular(), rank = 0;\n    var ni = this.elements.length, ki = ni, i, nj, kj = this.elements[0].length, j;\n    do { i = ki - ni;\n      nj = kj;\n      do { j = kj - nj;\n        if (Math.abs(M.elements[i][j]) > Sylvester.precision) { rank++; break; }\n      } while (--nj);\n    } while (--ni);\n    return rank;\n  },\n  \n  rk: function() { return this.rank(); },\n\n  // Returns the result of attaching the given argument to the right-hand side of the matrix\n  augment: function(matrix) {\n    var M = matrix.elements || matrix;\n    if (typeof(M[0][0]) == 'undefined') { M = Matrix.create(M).elements; }\n    var T = this.dup(), cols = T.elements[0].length;\n    var ni = T.elements.length, ki = ni, i, nj, kj = M[0].length, j;\n    if (ni != M.length) { return null; }\n    do { i = ki - ni;\n      nj = kj;\n      do { j = kj - nj;\n        T.elements[i][cols + j] = M[i][j];\n      } while (--nj);\n    } while (--ni);\n    return T;\n  },\n\n  // Returns the inverse (if one exists) using Gauss-Jordan\n  inverse: function() {\n    if (!this.isSquare() || this.isSingular()) { return null; }\n    var ni = this.elements.length, ki = ni, i, j;\n    var M = this.augment(Matrix.I(ni)).toRightTriangular();\n    var np, kp = M.elements[0].length, p, els, divisor;\n    var inverse_elements = [], new_element;\n    // Matrix is non-singular so there will be no zeros on the diagonal\n    // Cycle through rows from last to first\n    do { i = ni - 1;\n      // First, normalise diagonal elements to 1\n      els = []; np = kp;\n      inverse_elements[i] = [];\n      divisor = M.elements[i][i];\n      do { p = kp - np;\n        new_element = M.elements[i][p] / divisor;\n        els.push(new_element);\n        // Shuffle of the current row of the right hand side into the results\n        // array as it will not be modified by later runs through this loop\n        if (p >= ki) { inverse_elements[i].push(new_element); }\n      } while (--np);\n      M.elements[i] = els;\n      // Then, subtract this row from those above it to\n      // give the identity matrix on the left hand side\n      for (j = 0; j < i; j++) {\n        els = []; np = kp;\n        do { p = kp - np;\n          els.push(M.elements[j][p] - M.elements[i][p] * M.elements[j][i]);\n        } while (--np);\n        M.elements[j] = els;\n      }\n    } while (--ni);\n    return Matrix.create(inverse_elements);\n  },\n\n  inv: function() { return this.inverse(); },\n\n  // Returns the result of rounding all the elements\n  round: function() {\n    return this.map(function(x) { return Math.round(x); });\n  },\n\n  // Returns a copy of the matrix with elements set to the given value if they\n  // differ from it by less than Sylvester.precision\n  snapTo: function(x) {\n    return this.map(function(p) {\n      return (Math.abs(p - x) <= Sylvester.precision) ? x : p;\n    });\n  },\n\n  // Returns a string representation of the matrix\n  inspect: function() {\n    var matrix_rows = [];\n    var n = this.elements.length, k = n, i;\n    do { i = k - n;\n      matrix_rows.push(Vector.create(this.elements[i]).inspect());\n    } while (--n);\n    return matrix_rows.join('\\n');\n  },\n\n  // Set the matrix's elements from an array. If the argument passed\n  // is a vector, the resulting matrix will be a single column.\n  setElements: function(els) {\n    var i, elements = els.elements || els;\n    if (typeof(elements[0][0]) != 'undefined') {\n      var ni = elements.length, ki = ni, nj, kj, j;\n      this.elements = [];\n      do { i = ki - ni;\n        nj = elements[i].length; kj = nj;\n        this.elements[i] = [];\n        do { j = kj - nj;\n          this.elements[i][j] = elements[i][j];\n        } while (--nj);\n      } while(--ni);\n      return this;\n    }\n    var n = elements.length, k = n;\n    this.elements = [];\n    do { i = k - n;\n      this.elements.push([elements[i]]);\n    } while (--n);\n    return this;\n  }\n};\n\n// Constructor function\nMatrix.create = function(elements) {\n  var M = new Matrix();\n  return M.setElements(elements);\n};\n\n// Identity matrix of size n\nMatrix.I = function(n) {\n  var els = [], k = n, i, nj, j;\n  do { i = k - n;\n    els[i] = []; nj = k;\n    do { j = k - nj;\n      els[i][j] = (i == j) ? 1 : 0;\n    } while (--nj);\n  } while (--n);\n  return Matrix.create(els);\n};\n\n// Diagonal matrix - all off-diagonal elements are zero\nMatrix.Diagonal = function(elements) {\n  var n = elements.length, k = n, i;\n  var M = Matrix.I(n);\n  do { i = k - n;\n    M.elements[i][i] = elements[i];\n  } while (--n);\n  return M;\n};\n\n// Rotation matrix about some axis. If no axis is\n// supplied, assume we're after a 2D transform\nMatrix.Rotation = function(theta, a) {\n  if (!a) {\n    return Matrix.create([\n      [Math.cos(theta),  -Math.sin(theta)],\n      [Math.sin(theta),   Math.cos(theta)]\n    ]);\n  }\n  var axis = a.dup();\n  if (axis.elements.length != 3) { return null; }\n  var mod = axis.modulus();\n  var x = axis.elements[0]/mod, y = axis.elements[1]/mod, z = axis.elements[2]/mod;\n  var s = Math.sin(theta), c = Math.cos(theta), t = 1 - c;\n  // Formula derived here: http://www.gamedev.net/reference/articles/article1199.asp\n  // That proof rotates the co-ordinate system so theta\n  // becomes -theta and sin becomes -sin here.\n  return Matrix.create([\n    [ t*x*x + c, t*x*y - s*z, t*x*z + s*y ],\n    [ t*x*y + s*z, t*y*y + c, t*y*z - s*x ],\n    [ t*x*z - s*y, t*y*z + s*x, t*z*z + c ]\n  ]);\n};\n\n// Special case rotations\nMatrix.RotationX = function(t) {\n  var c = Math.cos(t), s = Math.sin(t);\n  return Matrix.create([\n    [  1,  0,  0 ],\n    [  0,  c, -s ],\n    [  0,  s,  c ]\n  ]);\n};\nMatrix.RotationY = function(t) {\n  var c = Math.cos(t), s = Math.sin(t);\n  return Matrix.create([\n    [  c,  0,  s ],\n    [  0,  1,  0 ],\n    [ -s,  0,  c ]\n  ]);\n};\nMatrix.RotationZ = function(t) {\n  var c = Math.cos(t), s = Math.sin(t);\n  return Matrix.create([\n    [  c, -s,  0 ],\n    [  s,  c,  0 ],\n    [  0,  0,  1 ]\n  ]);\n};\n\n// Random matrix of n rows, m columns\nMatrix.Random = function(n, m) {\n  return Matrix.Zero(n, m).map(\n    function() { return Math.random(); }\n  );\n};\n\n// Matrix filled with zeros\nMatrix.Zero = function(n, m) {\n  var els = [], ni = n, i, nj, j;\n  do { i = n - ni;\n    els[i] = [];\n    nj = m;\n    do { j = m - nj;\n      els[i][j] = 0;\n    } while (--nj);\n  } while (--ni);\n  return Matrix.create(els);\n};\n\n\n\nfunction Line() {}\nLine.prototype = {\n\n  // Returns true if the argument occupies the same space as the line\n  eql: function(line) {\n    return (this.isParallelTo(line) && this.contains(line.anchor));\n  },\n\n  // Returns a copy of the line\n  dup: function() {\n    return Line.create(this.anchor, this.direction);\n  },\n\n  // Returns the result of translating the line by the given vector/array\n  translate: function(vector) {\n    var V = vector.elements || vector;\n    return Line.create([\n      this.anchor.elements[0] + V[0],\n      this.anchor.elements[1] + V[1],\n      this.anchor.elements[2] + (V[2] || 0)\n    ], this.direction);\n  },\n\n  // Returns true if the line is parallel to the argument. Here, 'parallel to'\n  // means that the argument's direction is either parallel or antiparallel to\n  // the line's own direction. A line is parallel to a plane if the two do not\n  // have a unique intersection.\n  isParallelTo: function(obj) {\n    if (obj.normal) { return obj.isParallelTo(this); }\n    var theta = this.direction.angleFrom(obj.direction);\n    return (Math.abs(theta) <= Sylvester.precision || Math.abs(theta - Math.PI) <= Sylvester.precision);\n  },\n\n  // Returns the line's perpendicular distance from the argument,\n  // which can be a point, a line or a plane\n  distanceFrom: function(obj) {\n    if (obj.normal) { return obj.distanceFrom(this); }\n    if (obj.direction) {\n      // obj is a line\n      if (this.isParallelTo(obj)) { return this.distanceFrom(obj.anchor); }\n      var N = this.direction.cross(obj.direction).toUnitVector().elements;\n      var A = this.anchor.elements, B = obj.anchor.elements;\n      return Math.abs((A[0] - B[0]) * N[0] + (A[1] - B[1]) * N[1] + (A[2] - B[2]) * N[2]);\n    } else {\n      // obj is a point\n      var P = obj.elements || obj;\n      var A = this.anchor.elements, D = this.direction.elements;\n      var PA1 = P[0] - A[0], PA2 = P[1] - A[1], PA3 = (P[2] || 0) - A[2];\n      var modPA = Math.sqrt(PA1*PA1 + PA2*PA2 + PA3*PA3);\n      if (modPA === 0) return 0;\n      // Assumes direction vector is normalized\n      var cosTheta = (PA1 * D[0] + PA2 * D[1] + PA3 * D[2]) / modPA;\n      var sin2 = 1 - cosTheta*cosTheta;\n      return Math.abs(modPA * Math.sqrt(sin2 < 0 ? 0 : sin2));\n    }\n  },\n\n  // Returns true iff the argument is a point on the line\n  contains: function(point) {\n    var dist = this.distanceFrom(point);\n    return (dist !== null && dist <= Sylvester.precision);\n  },\n\n  // Returns true iff the line lies in the given plane\n  liesIn: function(plane) {\n    return plane.contains(this);\n  },\n\n  // Returns true iff the line has a unique point of intersection with the argument\n  intersects: function(obj) {\n    if (obj.normal) { return obj.intersects(this); }\n    return (!this.isParallelTo(obj) && this.distanceFrom(obj) <= Sylvester.precision);\n  },\n\n  // Returns the unique intersection point with the argument, if one exists\n  intersectionWith: function(obj) {\n    if (obj.normal) { return obj.intersectionWith(this); }\n    if (!this.intersects(obj)) { return null; }\n    var P = this.anchor.elements, X = this.direction.elements,\n        Q = obj.anchor.elements, Y = obj.direction.elements;\n    var X1 = X[0], X2 = X[1], X3 = X[2], Y1 = Y[0], Y2 = Y[1], Y3 = Y[2];\n    var PsubQ1 = P[0] - Q[0], PsubQ2 = P[1] - Q[1], PsubQ3 = P[2] - Q[2];\n    var XdotQsubP = - X1*PsubQ1 - X2*PsubQ2 - X3*PsubQ3;\n    var YdotPsubQ = Y1*PsubQ1 + Y2*PsubQ2 + Y3*PsubQ3;\n    var XdotX = X1*X1 + X2*X2 + X3*X3;\n    var YdotY = Y1*Y1 + Y2*Y2 + Y3*Y3;\n    var XdotY = X1*Y1 + X2*Y2 + X3*Y3;\n    var k = (XdotQsubP * YdotY / XdotX + XdotY * YdotPsubQ) / (YdotY - XdotY * XdotY);\n    return Vector.create([P[0] + k*X1, P[1] + k*X2, P[2] + k*X3]);\n  },\n\n  // Returns the point on the line that is closest to the given point or line\n  pointClosestTo: function(obj) {\n    if (obj.direction) {\n      // obj is a line\n      if (this.intersects(obj)) { return this.intersectionWith(obj); }\n      if (this.isParallelTo(obj)) { return null; }\n      var D = this.direction.elements, E = obj.direction.elements;\n      var D1 = D[0], D2 = D[1], D3 = D[2], E1 = E[0], E2 = E[1], E3 = E[2];\n      // Create plane containing obj and the shared normal and intersect this with it\n      // Thank you: http://www.cgafaq.info/wiki/Line-line_distance\n      var x = (D3 * E1 - D1 * E3), y = (D1 * E2 - D2 * E1), z = (D2 * E3 - D3 * E2);\n      var N = Vector.create([x * E3 - y * E2, y * E1 - z * E3, z * E2 - x * E1]);\n      var P = Plane.create(obj.anchor, N);\n      return P.intersectionWith(this);\n    } else {\n      // obj is a point\n      var P = obj.elements || obj;\n      if (this.contains(P)) { return Vector.create(P); }\n      var A = this.anchor.elements, D = this.direction.elements;\n      var D1 = D[0], D2 = D[1], D3 = D[2], A1 = A[0], A2 = A[1], A3 = A[2];\n      var x = D1 * (P[1]-A2) - D2 * (P[0]-A1), y = D2 * ((P[2] || 0) - A3) - D3 * (P[1]-A2),\n          z = D3 * (P[0]-A1) - D1 * ((P[2] || 0) - A3);\n      var V = Vector.create([D2 * x - D3 * z, D3 * y - D1 * x, D1 * z - D2 * y]);\n      var k = this.distanceFrom(P) / V.modulus();\n      return Vector.create([\n        P[0] + V.elements[0] * k,\n        P[1] + V.elements[1] * k,\n        (P[2] || 0) + V.elements[2] * k\n      ]);\n    }\n  },\n\n  // Returns a copy of the line rotated by t radians about the given line. Works by\n  // finding the argument's closest point to this line's anchor point (call this C) and\n  // rotating the anchor about C. Also rotates the line's direction about the argument's.\n  // Be careful with this - the rotation axis' direction affects the outcome!\n  rotate: function(t, line) {\n    // If we're working in 2D\n    if (typeof(line.direction) == 'undefined') { line = Line.create(line.to3D(), Vector.k); }\n    var R = Matrix.Rotation(t, line.direction).elements;\n    var C = line.pointClosestTo(this.anchor).elements;\n    var A = this.anchor.elements, D = this.direction.elements;\n    var C1 = C[0], C2 = C[1], C3 = C[2], A1 = A[0], A2 = A[1], A3 = A[2];\n    var x = A1 - C1, y = A2 - C2, z = A3 - C3;\n    return Line.create([\n      C1 + R[0][0] * x + R[0][1] * y + R[0][2] * z,\n      C2 + R[1][0] * x + R[1][1] * y + R[1][2] * z,\n      C3 + R[2][0] * x + R[2][1] * y + R[2][2] * z\n    ], [\n      R[0][0] * D[0] + R[0][1] * D[1] + R[0][2] * D[2],\n      R[1][0] * D[0] + R[1][1] * D[1] + R[1][2] * D[2],\n      R[2][0] * D[0] + R[2][1] * D[1] + R[2][2] * D[2]\n    ]);\n  },\n\n  // Returns the line's reflection in the given point or line\n  reflectionIn: function(obj) {\n    if (obj.normal) {\n      // obj is a plane\n      var A = this.anchor.elements, D = this.direction.elements;\n      var A1 = A[0], A2 = A[1], A3 = A[2], D1 = D[0], D2 = D[1], D3 = D[2];\n      var newA = this.anchor.reflectionIn(obj).elements;\n      // Add the line's direction vector to its anchor, then mirror that in the plane\n      var AD1 = A1 + D1, AD2 = A2 + D2, AD3 = A3 + D3;\n      var Q = obj.pointClosestTo([AD1, AD2, AD3]).elements;\n      var newD = [Q[0] + (Q[0] - AD1) - newA[0], Q[1] + (Q[1] - AD2) - newA[1], Q[2] + (Q[2] - AD3) - newA[2]];\n      return Line.create(newA, newD);\n    } else if (obj.direction) {\n      // obj is a line - reflection obtained by rotating PI radians about obj\n      return this.rotate(Math.PI, obj);\n    } else {\n      // obj is a point - just reflect the line's anchor in it\n      var P = obj.elements || obj;\n      return Line.create(this.anchor.reflectionIn([P[0], P[1], (P[2] || 0)]), this.direction);\n    }\n  },\n\n  // Set the line's anchor point and direction.\n  setVectors: function(anchor, direction) {\n    // Need to do this so that line's properties are not\n    // references to the arguments passed in\n    anchor = Vector.create(anchor);\n    direction = Vector.create(direction);\n    if (anchor.elements.length == 2) {anchor.elements.push(0); }\n    if (direction.elements.length == 2) { direction.elements.push(0); }\n    if (anchor.elements.length > 3 || direction.elements.length > 3) { return null; }\n    var mod = direction.modulus();\n    if (mod === 0) { return null; }\n    this.anchor = anchor;\n    this.direction = Vector.create([\n      direction.elements[0] / mod,\n      direction.elements[1] / mod,\n      direction.elements[2] / mod\n    ]);\n    return this;\n  }\n};\n\n  \n// Constructor function\nLine.create = function(anchor, direction) {\n  var L = new Line();\n  return L.setVectors(anchor, direction);\n};\n\n// Axes\nLine.X = Line.create(Vector.Zero(3), Vector.i);\nLine.Y = Line.create(Vector.Zero(3), Vector.j);\nLine.Z = Line.create(Vector.Zero(3), Vector.k);\n\n\n\nfunction Plane() {}\nPlane.prototype = {\n\n  // Returns true iff the plane occupies the same space as the argument\n  eql: function(plane) {\n    return (this.contains(plane.anchor) && this.isParallelTo(plane));\n  },\n\n  // Returns a copy of the plane\n  dup: function() {\n    return Plane.create(this.anchor, this.normal);\n  },\n\n  // Returns the result of translating the plane by the given vector\n  translate: function(vector) {\n    var V = vector.elements || vector;\n    return Plane.create([\n      this.anchor.elements[0] + V[0],\n      this.anchor.elements[1] + V[1],\n      this.anchor.elements[2] + (V[2] || 0)\n    ], this.normal);\n  },\n\n  // Returns true iff the plane is parallel to the argument. Will return true\n  // if the planes are equal, or if you give a line and it lies in the plane.\n  isParallelTo: function(obj) {\n    var theta;\n    if (obj.normal) {\n      // obj is a plane\n      theta = this.normal.angleFrom(obj.normal);\n      return (Math.abs(theta) <= Sylvester.precision || Math.abs(Math.PI - theta) <= Sylvester.precision);\n    } else if (obj.direction) {\n      // obj is a line\n      return this.normal.isPerpendicularTo(obj.direction);\n    }\n    return null;\n  },\n  \n  // Returns true iff the receiver is perpendicular to the argument\n  isPerpendicularTo: function(plane) {\n    var theta = this.normal.angleFrom(plane.normal);\n    return (Math.abs(Math.PI/2 - theta) <= Sylvester.precision);\n  },\n\n  // Returns the plane's distance from the given object (point, line or plane)\n  distanceFrom: function(obj) {\n    if (this.intersects(obj) || this.contains(obj)) { return 0; }\n    if (obj.anchor) {\n      // obj is a plane or line\n      var A = this.anchor.elements, B = obj.anchor.elements, N = this.normal.elements;\n      return Math.abs((A[0] - B[0]) * N[0] + (A[1] - B[1]) * N[1] + (A[2] - B[2]) * N[2]);\n    } else {\n      // obj is a point\n      var P = obj.elements || obj;\n      var A = this.anchor.elements, N = this.normal.elements;\n      return Math.abs((A[0] - P[0]) * N[0] + (A[1] - P[1]) * N[1] + (A[2] - (P[2] || 0)) * N[2]);\n    }\n  },\n\n  // Returns true iff the plane contains the given point or line\n  contains: function(obj) {\n    if (obj.normal) { return null; }\n    if (obj.direction) {\n      return (this.contains(obj.anchor) && this.contains(obj.anchor.add(obj.direction)));\n    } else {\n      var P = obj.elements || obj;\n      var A = this.anchor.elements, N = this.normal.elements;\n      var diff = Math.abs(N[0]*(A[0] - P[0]) + N[1]*(A[1] - P[1]) + N[2]*(A[2] - (P[2] || 0)));\n      return (diff <= Sylvester.precision);\n    }\n  },\n\n  // Returns true iff the plane has a unique point/line of intersection with the argument\n  intersects: function(obj) {\n    if (typeof(obj.direction) == 'undefined' && typeof(obj.normal) == 'undefined') { return null; }\n    return !this.isParallelTo(obj);\n  },\n\n  // Returns the unique intersection with the argument, if one exists. The result\n  // will be a vector if a line is supplied, and a line if a plane is supplied.\n  intersectionWith: function(obj) {\n    if (!this.intersects(obj)) { return null; }\n    if (obj.direction) {\n      // obj is a line\n      var A = obj.anchor.elements, D = obj.direction.elements,\n          P = this.anchor.elements, N = this.normal.elements;\n      var multiplier = (N[0]*(P[0]-A[0]) + N[1]*(P[1]-A[1]) + N[2]*(P[2]-A[2])) / (N[0]*D[0] + N[1]*D[1] + N[2]*D[2]);\n      return Vector.create([A[0] + D[0]*multiplier, A[1] + D[1]*multiplier, A[2] + D[2]*multiplier]);\n    } else if (obj.normal) {\n      // obj is a plane\n      var direction = this.normal.cross(obj.normal).toUnitVector();\n      // To find an anchor point, we find one co-ordinate that has a value\n      // of zero somewhere on the intersection, and remember which one we picked\n      var N = this.normal.elements, A = this.anchor.elements,\n          O = obj.normal.elements, B = obj.anchor.elements;\n      var solver = Matrix.Zero(2,2), i = 0;\n      while (solver.isSingular()) {\n        i++;\n        solver = Matrix.create([\n          [ N[i%3], N[(i+1)%3] ],\n          [ O[i%3], O[(i+1)%3]  ]\n        ]);\n      }\n      // Then we solve the simultaneous equations in the remaining dimensions\n      var inverse = solver.inverse().elements;\n      var x = N[0]*A[0] + N[1]*A[1] + N[2]*A[2];\n      var y = O[0]*B[0] + O[1]*B[1] + O[2]*B[2];\n      var intersection = [\n        inverse[0][0] * x + inverse[0][1] * y,\n        inverse[1][0] * x + inverse[1][1] * y\n      ];\n      var anchor = [];\n      for (var j = 1; j <= 3; j++) {\n        // This formula picks the right element from intersection by\n        // cycling depending on which element we set to zero above\n        anchor.push((i == j) ? 0 : intersection[(j + (5 - i)%3)%3]);\n      }\n      return Line.create(anchor, direction);\n    }\n  },\n\n  // Returns the point in the plane closest to the given point\n  pointClosestTo: function(point) {\n    var P = point.elements || point;\n    var A = this.anchor.elements, N = this.normal.elements;\n    var dot = (A[0] - P[0]) * N[0] + (A[1] - P[1]) * N[1] + (A[2] - (P[2] || 0)) * N[2];\n    return Vector.create([P[0] + N[0] * dot, P[1] + N[1] * dot, (P[2] || 0) + N[2] * dot]);\n  },\n\n  // Returns a copy of the plane, rotated by t radians about the given line\n  // See notes on Line#rotate.\n  rotate: function(t, line) {\n    var R = Matrix.Rotation(t, line.direction).elements;\n    var C = line.pointClosestTo(this.anchor).elements;\n    var A = this.anchor.elements, N = this.normal.elements;\n    var C1 = C[0], C2 = C[1], C3 = C[2], A1 = A[0], A2 = A[1], A3 = A[2];\n    var x = A1 - C1, y = A2 - C2, z = A3 - C3;\n    return Plane.create([\n      C1 + R[0][0] * x + R[0][1] * y + R[0][2] * z,\n      C2 + R[1][0] * x + R[1][1] * y + R[1][2] * z,\n      C3 + R[2][0] * x + R[2][1] * y + R[2][2] * z\n    ], [\n      R[0][0] * N[0] + R[0][1] * N[1] + R[0][2] * N[2],\n      R[1][0] * N[0] + R[1][1] * N[1] + R[1][2] * N[2],\n      R[2][0] * N[0] + R[2][1] * N[1] + R[2][2] * N[2]\n    ]);\n  },\n\n  // Returns the reflection of the plane in the given point, line or plane.\n  reflectionIn: function(obj) {\n    if (obj.normal) {\n      // obj is a plane\n      var A = this.anchor.elements, N = this.normal.elements;\n      var A1 = A[0], A2 = A[1], A3 = A[2], N1 = N[0], N2 = N[1], N3 = N[2];\n      var newA = this.anchor.reflectionIn(obj).elements;\n      // Add the plane's normal to its anchor, then mirror that in the other plane\n      var AN1 = A1 + N1, AN2 = A2 + N2, AN3 = A3 + N3;\n      var Q = obj.pointClosestTo([AN1, AN2, AN3]).elements;\n      var newN = [Q[0] + (Q[0] - AN1) - newA[0], Q[1] + (Q[1] - AN2) - newA[1], Q[2] + (Q[2] - AN3) - newA[2]];\n      return Plane.create(newA, newN);\n    } else if (obj.direction) {\n      // obj is a line\n      return this.rotate(Math.PI, obj);\n    } else {\n      // obj is a point\n      var P = obj.elements || obj;\n      return Plane.create(this.anchor.reflectionIn([P[0], P[1], (P[2] || 0)]), this.normal);\n    }\n  },\n\n  // Sets the anchor point and normal to the plane. If three arguments are specified,\n  // the normal is calculated by assuming the three points should lie in the same plane.\n  // If only two are sepcified, the second is taken to be the normal. Normal vector is\n  // normalised before storage.\n  setVectors: function(anchor, v1, v2) {\n    anchor = Vector.create(anchor);\n    anchor = anchor.to3D(); if (anchor === null) { return null; }\n    v1 = Vector.create(v1);\n    v1 = v1.to3D(); if (v1 === null) { return null; }\n    if (typeof(v2) == 'undefined') {\n      v2 = null;\n    } else {\n      v2 = Vector.create(v2);\n      v2 = v2.to3D(); if (v2 === null) { return null; }\n    }\n    var A1 = anchor.elements[0], A2 = anchor.elements[1], A3 = anchor.elements[2];\n    var v11 = v1.elements[0], v12 = v1.elements[1], v13 = v1.elements[2];\n    var normal, mod;\n    if (v2 !== null) {\n      var v21 = v2.elements[0], v22 = v2.elements[1], v23 = v2.elements[2];\n      normal = Vector.create([\n        (v12 - A2) * (v23 - A3) - (v13 - A3) * (v22 - A2),\n        (v13 - A3) * (v21 - A1) - (v11 - A1) * (v23 - A3),\n        (v11 - A1) * (v22 - A2) - (v12 - A2) * (v21 - A1)\n      ]);\n      mod = normal.modulus();\n      if (mod === 0) { return null; }\n      normal = Vector.create([normal.elements[0] / mod, normal.elements[1] / mod, normal.elements[2] / mod]);\n    } else {\n      mod = Math.sqrt(v11*v11 + v12*v12 + v13*v13);\n      if (mod === 0) { return null; }\n      normal = Vector.create([v1.elements[0] / mod, v1.elements[1] / mod, v1.elements[2] / mod]);\n    }\n    this.anchor = anchor;\n    this.normal = normal;\n    return this;\n  }\n};\n\n// Constructor function\nPlane.create = function(anchor, v1, v2) {\n  var P = new Plane();\n  return P.setVectors(anchor, v1, v2);\n};\n\n// X-Y-Z planes\nPlane.XY = Plane.create(Vector.Zero(3), Vector.k);\nPlane.YZ = Plane.create(Vector.Zero(3), Vector.i);\nPlane.ZX = Plane.create(Vector.Zero(3), Vector.j);\nPlane.YX = Plane.XY; Plane.ZY = Plane.YZ; Plane.XZ = Plane.ZX;\n\n// Utility functions\nvar $V = Vector.create;\nvar $M = Matrix.create;\nvar $L = Line.create;\nvar $P = Plane.create;\n"
  },
  {
    "path": "datalab/notebook/static/job.css",
    "content": "/*\n * Copyright 2015 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License. You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under the License\n * is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n * or implied. See the License for the specific language governing permissions and limitations under\n * the License.\n */\n\np.jobfail {\n  color: red;\n}\np.jobsucceed {\n  color: green;\n}\np.jobfooter {\n  font-size: smaller;\n}\n"
  },
  {
    "path": "datalab/notebook/static/job.ts",
    "content": "/*\n * Copyright 2015 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License. You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under the License\n * is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n * or implied. See the License for the specific language governing permissions and limitations under\n * the License.\n */\n\n/// <reference path=\"../../../externs/ts/require/require.d.ts\" />\n\ndeclare var datalab: any;\ndeclare var IPython: any;\n\nmodule Job {\n\n  function refresh(dom: any, job_name: any, job_type: any, interval: any,\n      html_on_running: string, html_on_success: string): any {\n    var code = '%_get_job_status ' + job_name + ' ' + job_type;\n    datalab.session.execute(code, function (error: any, newData: any) {\n      error = error || newData.error;\n      if (error) {\n        dom.innerHTML = '<p class=\"jobfail\">Job failed with error: ' + error\n            + '</p>';\n        return;\n      }\n      if (!newData.exists) {\n        dom.innerHTML = '<p>The job does not exist.</p>';\n      } else if (newData.done) {\n        dom.innerHTML = '<p class=\"jobsucceed\">Job completed successfully.</p><br>' +\n                        html_on_success;\n      } else {\n        dom.innerHTML = 'Running... <p class=\"jobfooter\">Updated at '\n          + new Date().toLocaleTimeString() + '</p>' + html_on_running;\n        setTimeout(function() {\n              refresh(dom, job_name, job_type, interval, html_on_running, html_on_success);\n            }, interval * 1000);\n      }\n    });\n  }\n\n  // Render the job view. This is called from Python generated code.\n  export function render(dom: any, events: any, job_name: string, job_type: string,\n      interval: any, html_on_running: string, html_on_success: string) {\n    if (IPython.notebook.kernel.is_connected()) {\n      refresh(dom, job_name, job_type, interval, html_on_running, html_on_success);\n      return;\n    }\n    // If the kernel is not connected, wait for the event.\n    events.on('kernel_ready.Kernel', function(e: any) {\n      refresh(dom, job_name, job_type, interval, html_on_running, html_on_success);\n    });\n  }\n}\n\n\nexport = Job;\n\n"
  },
  {
    "path": "datalab/notebook/static/parcoords.ts",
    "content": "/*\n * Copyright 2016 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License. You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under the License\n * is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n * or implied. See the License for the specific language governing permissions and limitations under\n * the License.\n */\n\n/// <reference path=\"../../../externs/ts/require/require.d.ts\" />\n\nmodule ParCoords {\n\n  function getCentroids(data: any, graph: any): any {\n      var margins = graph.margin();\n      var graphCentPts: any[] = [];\n\n      data.forEach(function(d: any){\n        var initCenPts = graph.compute_centroids(d).filter(function(d: any, i: number) {return i%2==0;});\n        var cenPts = initCenPts.map(function(d: any){\n        return [d[0] + margins[\"left\"], d[1]+ margins[\"top\"]]; \n      });\n      graphCentPts.push(cenPts);\n    });\n\n    return graphCentPts;\n  }\n\n  function getActiveData(graph: any): any{\n    if (graph.brushed()!=false) return graph.brushed();\n      return graph.data();\n  }\n\n  function findAxes(testPt: any, cenPts: any): number {\n    var x: number = testPt[0];\n    var y: number = testPt[1];\n    if (cenPts[0][0] > x) return 0;\n    if (cenPts[cenPts.length-1][0] < x) return 0;\n    for (var i=0; i<cenPts.length; i++) {\n        if (cenPts[i][0] > x) return i;\n    }\n    return 0;\n  }\n\n  function isOnLine(startPt: any, endPt: any, testPt: any, tol: number){\n    var x0 = testPt[0];\n    var\ty0 = testPt[1];\n    var x1 = startPt[0];\n    var\ty1 = startPt[1];\n    var x2 = endPt[0];\n    var y2 = endPt[1];\n    var Dx = x2 - x1;\n    var Dy = y2 - y1;\n    var delta = Math.abs(Dy*x0 - Dx*y0 - x1*y2+x2*y1)/Math.sqrt(Math.pow(Dx, 2) + Math.pow(Dy, 2)); \n    if (delta <= tol) return true;\n    return false;\n  }\n\n  function getClickedLines(mouseClick: any, graph: any): any {\n    var clicked: any[] = [];\n    var clickedCenPts: any[] = [];\n    // find which data is activated right now\n    var activeData: any = getActiveData(graph);\n\n    // find centriod points\n    var graphCentPts: any = getCentroids(activeData, graph);\n\n    if (graphCentPts.length==0) return false;\n    // find between which axes the point is\n    var axeNum: number = findAxes(mouseClick, graphCentPts[0]);\n    if (!axeNum) return false;\n    graphCentPts.forEach(function(d: any, i: number){\n      if (isOnLine(d[axeNum-1], d[axeNum], mouseClick, 2)) {\n        clicked.push(activeData[i]);\n        clickedCenPts.push(graphCentPts[i]); // for tooltip\n      }\n    });\n    return [clicked, clickedCenPts]\n  }\n\n  function highlightLineOnClick(mouseClick: any, graph: any) {\n    var clicked: any[] = [];\n    var clickedCenPts: any[] = [];\n    var clickedData: any = getClickedLines(mouseClick, graph);\n    if (clickedData && clickedData[0].length!=0){\n      clicked = clickedData[0];\n      clickedCenPts = clickedData[1];\n      // highlight clicked line\n      graph.highlight(clicked);\n    }\n  };\n\n  export function plot(d3: any, color_domain: number[], maximize: boolean, data: any,\n           graph_html_id: string, grid_html_id: string) {\n    var range = [\"green\", \"gray\"];\n    if (maximize) {\n      range = [\"gray\", \"green\"];\n    }\n    var blue_to_brown = d3.scale.linear().domain(color_domain)\n                                         .range(range)\n                                         .interpolate(d3.interpolateLab);\n    var color = function(d: any) { return blue_to_brown(d['Objective']); };\n    var columns_hide: string[] = [\"Trial\", \"Training Step\"];\n    for (var attr in data) {\n      if (attr.lastIndexOf(\"(log)\") > 0) {\n        columns_hide.push(attr.slice(0, -5));\n      }\n    }\n    var data_display: any[] = [];\n    for (var i: number =0; i<data.Trial.length; i++) {\n      var instance: any = {};\n      for (var attr in data) {\n        instance[attr] = data[attr][i];\n      }\n      data_display.push(instance);\n    }\n    var parcoords = d3.parcoords()(\"#\" + graph_html_id).color(color).alpha(0.4);\n    parcoords.data(data_display).hideAxis(columns_hide)\n                                .composite(\"darken\")\n                                .render()\n                                .brushMode(\"1D-axes\");\n\n    var grid = d3.divgrid();\n    d3.select(\"#\" + grid_html_id).datum(data_display)\n        .call(grid)\n        .selectAll(\".row\")\n        .on({\n          \"mouseover\": function(d: any) { parcoords.highlight([d]) },\n          \"mouseout\": parcoords.unhighlight\n        });     \n    // update data table on brush event\n    parcoords.on(\"brush\", function(d: any) {\n        d3.select(\"#\" + grid_html_id).datum(d)\n        .call(grid)\n        .selectAll(\".row\")\n        .on({\n            \"mouseover\": function(d: any) { parcoords.highlight([d]) },\n            \"mouseout\": parcoords.unhighlight\n        });\n    });\n    //add hover event\n    d3.select(\"#\" + graph_html_id + \" svg\").on(\"mousemove\", function() {\n          var mousePosition: any = d3.mouse(this);\t\t\t    \n          highlightLineOnClick(mousePosition, parcoords);\n        })\n        .on(\"mouseout\", function(){\n          parcoords.unhighlight();\n\t});\n  }\n}\n\n\nexport = ParCoords;\n\n"
  },
  {
    "path": "datalab/notebook/static/style.ts",
    "content": "/*\n * Copyright 2015 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License. You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under the License\n * is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n * or implied. See the License for the specific language governing permissions and limitations under\n * the License.\n */\n\n// RequireJS plugin to load stylesheets.\n\n/// <reference path=\"../../../externs/ts/require/require.d.ts\" />\n\nmodule Style {\n\n  'use strict';\n\n  // An object containing the set of loaded stylesheets, so as to avoid reloading.\n  var loadedStyleSheets: any = {};\n\n  // An object containing stylesheets to load, once the DOM is ready.\n  var pendingStyleSheets: Array<string> = null;\n\n  function addStyleSheet(url: string): void {\n    loadedStyleSheets[url] = true;\n\n    var stylesheet = document.createElement('link');\n    stylesheet.type = 'text/css';\n    stylesheet.rel = 'stylesheet';\n    stylesheet.href = url;\n\n    document.getElementsByTagName('head')[0].appendChild(stylesheet);\n  }\n\n  function domReadyCallback(): void {\n    if (pendingStyleSheets) {\n      // Clear out pendingStyleSheets, so any future adds are immediately processed.\n      var styleSheets: Array<string> = pendingStyleSheets;\n      pendingStyleSheets = null;\n\n      styleSheets.forEach(addStyleSheet);\n    }\n  }\n\n  export function load(url: string, req: any, loadCallback: any, config: any): void {\n    if (config.isBuild) {\n      loadCallback(null);\n    }\n    else {\n      // Go ahead and immediately/optimistically resolve this, since the resolved value of a\n      // stylesheet is never interesting.\n      setTimeout(loadCallback, 0);\n\n      // Only load a specified stylesheet once for the lifetime of this page.\n      if (loadedStyleSheets[url]) {\n        return;\n      }\n      loadedStyleSheets[url] = true;\n\n      if (document.readyState == 'loading') {\n        if (!pendingStyleSheets) {\n          pendingStyleSheets = [];\n          document.addEventListener('DOMContentLoaded', domReadyCallback, false);\n        }\n\n        pendingStyleSheets.push(url);\n      }\n      else {\n        addStyleSheet(url);\n      }\n    }\n  }\n}\n\nexport = Style;\n"
  },
  {
    "path": "datalab/notebook/static/visualization.ts",
    "content": "/*\n * Copyright 2015 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License. You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under the License\n * is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n * or implied. See the License for the specific language governing permissions and limitations under\n * the License.\n */\n\n// require.js plugin to allow Google Chart API to be loaded.\n\n/// <reference path=\"../../../externs/ts/require/require.d.ts\" />\n\ndeclare var google: any;\ndeclare var window: any;\n\nmodule Visualization {\n\n  'use strict';\n\n  // Queued packages to load until the google api loader itself has not been loaded.\n  var queue: any = {\n    packages: [],\n    callbacks: []\n  };\n\n  function loadGoogleApiLoader(callback: any): void {\n    // Visualization packages are loaded using the Google loader.\n    // The loader URL itself must contain a callback (by name) that it invokes when its loaded.\n    var callbackName: string = '__googleApiLoaderCallback';\n    window[callbackName] = callback;\n\n    var script = document.createElement('script');\n    script.type = 'text/javascript';\n    script.async = true;\n    script.src = 'https://www.google.com/jsapi?callback=' + callbackName;\n    document.getElementsByTagName('head')[0].appendChild(script);\n  }\n\n  function invokeVisualizationCallback(cb: any) {\n    cb(google.visualization);\n  }\n\n  function loadVisualizationPackages(names: any, callbacks: any): void {\n    if (names.length) {\n      var visualizationOptions = {\n        packages: names,\n        callback: function() { callbacks.forEach(invokeVisualizationCallback); }\n      };\n\n      google.load('visualization', '1', visualizationOptions);\n    }\n  }\n\n  loadGoogleApiLoader(function() {\n    if (queue) {\n      loadVisualizationPackages(queue.packages, queue.callbacks);\n      queue = null;\n    }\n  });\n\n  export function load(name: any, req: any, callback: any, config: any) {\n    if (config.isBuild) {\n      callback(null);\n    }\n    else {\n      if (queue) {\n        // Queue the package and associated callback to load, once the loader has been loaded.\n        queue.packages.push(name);\n        queue.callbacks.push(callback);\n      }\n      else {\n        // Loader has already been loaded, so go ahead and load the specified package.\n        loadVisualizationPackages([ name ], [ callback ]);\n      }\n    }\n  }\n}\n\nexport = Visualization;\n"
  },
  {
    "path": "datalab/stackdriver/__init__.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License.  You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied.  See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Google Cloud Platform library - Stackdriver Functionality.\"\"\"\n"
  },
  {
    "path": "datalab/stackdriver/commands/__init__.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\nfrom __future__ import absolute_import\n\nfrom . import _monitoring\n\n__all__ = ['_monitoring']\n"
  },
  {
    "path": "datalab/stackdriver/commands/_monitoring.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"IPython Functionality for the Google Monitoring API.\"\"\"\nfrom __future__ import absolute_import\n\ntry:\n  import IPython.core.display\n  import IPython.core.magic\nexcept ImportError:\n  raise Exception('This module can only be loaded in ipython.')\n\nimport datalab.stackdriver.monitoring as gcm\nimport datalab.utils.commands\n\n\n@IPython.core.magic.register_line_cell_magic\ndef monitoring(line, cell=None):\n  \"\"\"Implements the monitoring cell magic for ipython notebooks.\n\n  Args:\n    line: the contents of the storage line.\n  Returns:\n    The results of executing the cell.\n  \"\"\"\n  parser = datalab.utils.commands.CommandParser(prog='monitoring', description=(\n      'Execute various Monitoring-related operations. Use \"%monitoring '\n      '<command> -h\" for help on a specific command.'))\n\n  list_parser = parser.subcommand(\n      'list', 'List the metrics or resource types in a monitored project.')\n\n  list_metric_parser = list_parser.subcommand(\n      'metrics',\n      'List the metrics that are available through the Monitoring API.')\n  list_metric_parser.add_argument(\n      '-t', '--type',\n      help='The type of metric(s) to list; can include wildchars.')\n  list_metric_parser.add_argument(\n      '-p', '--project', help='The project on which to execute the request.')\n  list_metric_parser.set_defaults(func=_list_metric_descriptors)\n\n  list_resource_parser = list_parser.subcommand(\n      'resource_types',\n      ('List the monitored resource types that are available through the '\n       'Monitoring API.'))\n  list_resource_parser.add_argument(\n      '-p', '--project', help='The project on which to execute the request.')\n  list_resource_parser.add_argument(\n      '-t', '--type',\n      help='The resource type(s) to list; can include wildchars.')\n  list_resource_parser.set_defaults(func=_list_resource_descriptors)\n\n  list_group_parser = list_parser.subcommand(\n      'groups',\n      ('List the Stackdriver groups in this project.'))\n  list_group_parser.add_argument(\n      '-p', '--project', help='The project on which to execute the request.')\n  list_group_parser.add_argument(\n      '-n', '--name',\n      help='The name of the group(s) to list; can include wildchars.')\n  list_group_parser.set_defaults(func=_list_groups)\n\n  return datalab.utils.commands.handle_magic_line(line, cell, parser)\n\n\ndef _list_metric_descriptors(args, _):\n  \"\"\"Lists the metric descriptors in the project.\"\"\"\n  project_id = args['project']\n  pattern = args['type'] or '*'\n  descriptors = gcm.MetricDescriptors(project_id=project_id)\n  dataframe = descriptors.as_dataframe(pattern=pattern)\n  return _render_dataframe(dataframe)\n\n\ndef _list_resource_descriptors(args, _):\n  \"\"\"Lists the resource descriptors in the project.\"\"\"\n  project_id = args['project']\n  pattern = args['type'] or '*'\n  descriptors = gcm.ResourceDescriptors(project_id=project_id)\n  dataframe = descriptors.as_dataframe(pattern=pattern)\n  return _render_dataframe(dataframe)\n\n\ndef _list_groups(args, _):\n  \"\"\"Lists the groups in the project.\"\"\"\n  project_id = args['project']\n  pattern = args['name'] or '*'\n  groups = gcm.Groups(project_id=project_id)\n  dataframe = groups.as_dataframe(pattern=pattern)\n  return _render_dataframe(dataframe)\n\n\ndef _render_dataframe(dataframe):\n  \"\"\"Helper to render a dataframe as an HTML table.\"\"\"\n  data = dataframe.to_dict(orient='records')\n  fields = dataframe.columns.tolist()\n  return IPython.core.display.HTML(\n      datalab.utils.commands.HtmlBuilder.render_table(data, fields))\n"
  },
  {
    "path": "datalab/stackdriver/monitoring/__init__.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License.  You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied.  See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Google Cloud Platform library - Monitoring Functionality.\"\"\"\n\nfrom __future__ import absolute_import\n\nfrom google.cloud.monitoring import enums\nfrom ._group import Groups\nfrom ._metric import MetricDescriptors\nfrom ._query import Query\nfrom ._query_metadata import QueryMetadata\nfrom ._resource import ResourceDescriptors\n\nAligner = enums.Aggregation.Aligner\nReducer = enums.Aggregation.Reducer\n\n__all__ = ['Aligner', 'Reducer', 'Groups', 'MetricDescriptors', 'Query', 'QueryMetadata',\n           'ResourceDescriptors']\n"
  },
  {
    "path": "datalab/stackdriver/monitoring/_group.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License.  You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied.  See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Groups for the Google Monitoring API.\"\"\"\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom builtins import object\n\nimport collections\nimport fnmatch\n\nimport pandas\n\nimport google.datalab\n\nfrom . import _utils\n\n\nclass Groups(object):\n  \"\"\"Represents a list of Stackdriver groups for a project.\"\"\"\n\n  _DISPLAY_HEADERS = ('Group ID', 'Group name', 'Parent ID', 'Parent name',\n                      'Is cluster', 'Filter')\n\n  def __init__(self, context=None):\n    \"\"\"Initializes the Groups for a Stackdriver project.\n\n    Args:\n      context: An optional Context object to use instead of the global default.\n    \"\"\"\n    self._context = context or google.datalab.Context.default()\n    self._client = _utils.make_client(self._context)\n    self._group_dict = None\n\n  def list(self, pattern='*'):\n    \"\"\"Returns a list of groups that match the filters.\n\n    Args:\n      pattern: An optional pattern to filter the groups based on their display\n          name. This can include Unix shell-style wildcards. E.g.\n          ``\"Production*\"``.\n\n    Returns:\n      A list of Group objects that match the filters.\n    \"\"\"\n    if self._group_dict is None:\n      self._group_dict = collections.OrderedDict(\n          (group.name, group) for group in self._client.list_groups())\n\n    return [group for group in self._group_dict.values()\n            if fnmatch.fnmatch(group.display_name, pattern)]\n\n  def as_dataframe(self, pattern='*', max_rows=None):\n    \"\"\"Creates a pandas dataframe from the groups that match the filters.\n\n    Args:\n      pattern: An optional pattern to further filter the groups. This can\n          include Unix shell-style wildcards. E.g. ``\"Production *\"``,\n          ``\"*-backend\"``.\n      max_rows: The maximum number of groups to return. If None, return all.\n\n    Returns:\n      A pandas dataframe containing matching groups.\n    \"\"\"\n    data = []\n    for i, group in enumerate(self.list(pattern)):\n      if max_rows is not None and i >= max_rows:\n        break\n      parent = self._group_dict.get(group.parent_name)\n      parent_display_name = '' if parent is None else parent.display_name\n      data.append([\n          group.name, group.display_name, group.parent_name,\n          parent_display_name, group.is_cluster, group.filter])\n\n    return pandas.DataFrame(data, columns=self._DISPLAY_HEADERS)\n"
  },
  {
    "path": "datalab/stackdriver/monitoring/_metric.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License.  You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied.  See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Provides the MetricDescriptors in the monitoring API.\"\"\"\n\nfrom __future__ import absolute_import\nfrom builtins import object\n\nfrom google.cloud.monitoring_v3 import enums\n\nimport fnmatch\nimport pandas\n\nfrom . import _utils\n\n\nclass MetricDescriptors(object):\n  \"\"\"MetricDescriptors object for retrieving the metric descriptors.\"\"\"\n\n  _DISPLAY_HEADERS = ('Metric type', 'Display name', 'Kind', 'Value', 'Unit',\n                      'Labels')\n\n  def __init__(self, filter_string=None, type_prefix=None, context=None):\n    \"\"\"Initializes the MetricDescriptors based on the specified filters.\n\n    Args:\n      filter_string: An optional filter expression describing the resource\n          descriptors to be returned.\n      type_prefix: An optional prefix constraining the selected metric types.\n          This adds ``metric.type = starts_with(\"<prefix>\")`` to the filter.\n      context: An optional Context object to use instead of the global default.\n    \"\"\"\n    self._client = _utils.make_client(context)\n    self._filter_string = filter_string\n    self._type_prefix = type_prefix\n    self._descriptors = None\n\n  def list(self, pattern='*'):\n    \"\"\"Returns a list of metric descriptors that match the filters.\n\n    Args:\n      pattern: An optional pattern to further filter the descriptors. This can\n          include Unix shell-style wildcards. E.g. ``\"compute*\"``,\n          ``\"*cpu/load_??m\"``.\n\n    Returns:\n      A list of MetricDescriptor objects that match the filters.\n    \"\"\"\n    if self._descriptors is None:\n      self._descriptors = self._client.list_metric_descriptors(\n          filter_string=self._filter_string, type_prefix=self._type_prefix)\n    return [metric for metric in self._descriptors\n            if fnmatch.fnmatch(metric.type, pattern)]\n\n  def as_dataframe(self, pattern='*', max_rows=None):\n    \"\"\"Creates a pandas dataframe from the descriptors that match the filters.\n\n    Args:\n      pattern: An optional pattern to further filter the descriptors. This can\n          include Unix shell-style wildcards. E.g. ``\"compute*\"``,\n          ``\"*/cpu/load_??m\"``.\n      max_rows: The maximum number of descriptors to return. If None, return\n          all.\n\n    Returns:\n      A pandas dataframe containing matching metric descriptors.\n    \"\"\"\n    data = []\n    for i, metric in enumerate(self.list(pattern)):\n      if max_rows is not None and i >= max_rows:\n        break\n      labels = ', '. join([l.key for l in metric.labels])\n      data.append([\n          metric.type, metric.display_name,\n          enums.MetricDescriptor.MetricKind(metric.metric_kind).name,\n          enums.MetricDescriptor.ValueType(metric.value_type).name,\n          metric.unit, labels])\n\n    return pandas.DataFrame(data, columns=self._DISPLAY_HEADERS)\n"
  },
  {
    "path": "datalab/stackdriver/monitoring/_query.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License.  You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied.  See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Provides access to metric data as pandas dataframes.\"\"\"\n\nfrom __future__ import absolute_import\n\nimport google.cloud.monitoring_v3.query\n\nfrom . import _query_metadata\nfrom . import _utils\n\n\nclass Query(google.cloud.monitoring_v3.query.Query):\n  \"\"\"Query object for retrieving metric data.\"\"\"\n\n  def __init__(self,\n               metric_type=google.cloud.monitoring_v3.query.Query.DEFAULT_METRIC_TYPE,\n               end_time=None, days=0, hours=0, minutes=0, context=None):\n    \"\"\"Initializes the core query parameters.\n\n    The start time (exclusive) is determined by combining the\n    values of ``days``, ``hours``, and ``minutes``, and subtracting\n    the resulting duration from the end time.\n\n    It is also allowed to omit the end time and duration here,\n    in which case :meth:`~google.cloud.monitoring_v3.query.Query.select_interval`\n    must be called before the query is executed.\n\n    Args:\n      metric_type: The metric type name. The default value is\n          :data:`Query.DEFAULT_METRIC_TYPE\n          <google.cloud.monitoring_v3.query.Query.DEFAULT_METRIC_TYPE>`, but\n          please note that this default value is provided only for\n          demonstration purposes and is subject to change.\n      end_time: The end time (inclusive) of the time interval for which\n          results should be returned, as a datetime object. The default\n          is the start of the current minute.\n      days: The number of days in the time interval.\n      hours: The number of hours in the time interval.\n      minutes: The number of minutes in the time interval.\n      context: An optional Context object to use instead of the global default.\n\n    Raises:\n        ValueError: ``end_time`` was specified but ``days``, ``hours``, and\n            ``minutes`` are all zero. If you really want to specify a point in\n            time, use\n            :meth:`~google.cloud.monitoring_v3.query.Query.select_interval`.\n    \"\"\"\n    client = _utils.make_client(context)\n    super(Query, self).__init__(client.metrics_client,\n                                project=client.project,\n                                metric_type=metric_type,\n                                end_time=end_time,\n                                days=days, hours=hours, minutes=minutes)\n\n  def metadata(self):\n    \"\"\"Retrieves the metadata for the query.\"\"\"\n    return _query_metadata.QueryMetadata(self)\n"
  },
  {
    "path": "datalab/stackdriver/monitoring/_query_metadata.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License.  You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied.  See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"QueryMetadata object that shows the metadata in a query's results.\"\"\"\n\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom builtins import object\n\nfrom google.cloud.monitoring_v3 import _dataframe\nfrom google.protobuf.json_format import MessageToDict\nimport pandas\n\n\nclass QueryMetadata(object):\n  \"\"\"QueryMetadata object contains the metadata of a timeseries query.\"\"\"\n\n  def __init__(self, query):\n    \"\"\"Initializes the QueryMetadata given the query object.\n\n    Args:\n      query: A Query object.\n    \"\"\"\n    self._timeseries_list = list(query.iter(headers_only=True))\n\n    # Note: If self._timeseries_list has even one entry, the metric type\n    # can be extracted from there as well.\n    self._metric_type = query.metric_type\n\n  def __iter__(self):\n    for timeseries in self._timeseries_list:\n      yield timeseries\n\n  @property\n  def metric_type(self):\n    \"\"\"Returns the metric type in the underlying query.\"\"\"\n    return self._metric_type\n\n  @property\n  def resource_types(self):\n    \"\"\"Returns a set containing resource types in the query result.\"\"\"\n    return set([ts.resource.type for ts in self._timeseries_list])\n\n  def as_dataframe(self, max_rows=None):\n      \"\"\"Creates a pandas dataframe from the query metadata.\n\n      Args:\n        max_rows: The maximum number of timeseries metadata to return. If None,\n            return all.\n\n      Returns:\n        A pandas dataframe containing the resource type, resource labels and\n        metric labels. Each row in this dataframe corresponds to the metadata\n        from one time series.\n      \"\"\"\n      max_rows = len(self._timeseries_list) if max_rows is None else max_rows\n      headers = [{\n          'resource': MessageToDict(ts.resource),\n          'metric': MessageToDict(ts.metric)\n      } for ts in self._timeseries_list[:max_rows]]\n\n      if not headers:\n        return pandas.DataFrame()\n\n      dataframe = pandas.io.json.json_normalize(headers)\n\n      # Add a 2 level column header.\n      dataframe.columns = pandas.MultiIndex.from_tuples(\n          [(col, '') if col == 'resource.type' else col.rsplit('.', 1)\n           for col in dataframe.columns])\n\n      # Re-order the columns.\n      resource_keys = _dataframe._sorted_resource_labels(\n          dataframe['resource.labels'].columns)\n      sorted_columns = [('resource.type', '')]\n      sorted_columns += [('resource.labels', key) for key in resource_keys]\n      sorted_columns += sorted(col for col in dataframe.columns\n                               if col[0] == 'metric.labels')\n      dataframe = dataframe[sorted_columns]\n\n      # Sort the data, and clean up index values, and NaNs.\n      dataframe = dataframe.sort_values(sorted_columns)\n      dataframe = dataframe.reset_index(drop=True).fillna('')\n      return dataframe\n"
  },
  {
    "path": "datalab/stackdriver/monitoring/_resource.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License.  You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied.  See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Provides the ResourceDescriptors in the monitoring API.\"\"\"\n\nfrom __future__ import absolute_import\nfrom builtins import object\n\nimport fnmatch\nimport pandas\n\nfrom . import _utils\n\n\nclass ResourceDescriptors(object):\n  \"\"\"ResourceDescriptors object for retrieving the resource descriptors.\"\"\"\n\n  _DISPLAY_HEADERS = ('Resource type', 'Display name', 'Labels')\n\n  def __init__(self, filter_string=None, context=None):\n    \"\"\"Initializes the ResourceDescriptors based on the specified filters.\n\n    Args:\n      filter_string: An optional filter expression describing the resource\n          descriptors to be returned.\n      context: An optional Context object to use instead of the global default.\n    \"\"\"\n    self._client = _utils.make_client(context)\n    self._filter_string = filter_string\n    self._descriptors = None\n\n  def list(self, pattern='*'):\n    \"\"\"Returns a list of resource descriptors that match the filters.\n\n    Args:\n      pattern: An optional pattern to further filter the descriptors. This can\n          include Unix shell-style wildcards. E.g. ``\"aws*\"``, ``\"*cluster*\"``.\n\n    Returns:\n      A list of ResourceDescriptor objects that match the filters.\n    \"\"\"\n    if self._descriptors is None:\n      self._descriptors = self._client.list_resource_descriptors(\n          filter_string=self._filter_string)\n    return [resource for resource in self._descriptors\n            if fnmatch.fnmatch(resource.type, pattern)]\n\n  def as_dataframe(self, pattern='*', max_rows=None):\n    \"\"\"Creates a pandas dataframe from the descriptors that match the filters.\n\n    Args:\n      pattern: An optional pattern to further filter the descriptors. This can\n          include Unix shell-style wildcards. E.g. ``\"aws*\"``, ``\"*cluster*\"``.\n      max_rows: The maximum number of descriptors to return. If None, return\n          all.\n\n    Returns:\n      A pandas dataframe containing matching resource descriptors.\n    \"\"\"\n    data = []\n    for i, resource in enumerate(self.list(pattern)):\n      if max_rows is not None and i >= max_rows:\n        break\n      labels = ', '. join([l.key for l in resource.labels])\n      data.append([resource.type, resource.display_name, labels])\n\n    return pandas.DataFrame(data, columns=self._DISPLAY_HEADERS)\n"
  },
  {
    "path": "datalab/stackdriver/monitoring/_utils.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License.  You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied.  See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Provides utility methods for the Monitoring API.\"\"\"\n\nfrom __future__ import absolute_import\n\nfrom google.api_core.gapic_v1.client_info import ClientInfo\nfrom google.cloud.monitoring_v3 import MetricServiceClient\nfrom google.cloud.monitoring_v3 import GroupServiceClient\n\nimport google.datalab\n\n\n# _MonitoringClient holds instances of individual google.cloud.monitoring\n# clients and translates each call from the old signature, since the prior\n# client has been updated and has split into multiple client classes.\nclass _MonitoringClient(object):\n  def __init__(self, context):\n    self.project = context.project_id\n    client_info = ClientInfo(user_agent='pydatalab/v0')\n    self.metrics_client = MetricServiceClient(\n      credentials=context.credentials,\n      client_info=client_info\n    )\n    self.group_client = GroupServiceClient(\n      credentials=context.credentials,\n      client_info=client_info\n    )\n\n  def list_metric_descriptors(self, filter_string=None, type_prefix=None):\n    filters = []\n    if filter_string is not None:\n      filters.append(filter_string)\n\n    if type_prefix is not None:\n      filters.append('metric.type = starts_with(\"{prefix}\")'.format(\n          prefix=type_prefix))\n\n    metric_filter = ' AND '.join(filters)\n    metrics = self.metrics_client.list_metric_descriptors(\n        self.project, filter_=metric_filter)\n    return metrics\n\n  def list_resource_descriptors(self, filter_string=None):\n    resources = self.metrics_client.list_monitored_resource_descriptors(\n        self.project, filter_=filter_string)\n    return resources\n\n  def list_groups(self):\n    groups = self.group_client.list_groups(self.project)\n    return groups\n\n\ndef make_client(context=None):\n  context = context or google.datalab.Context.default()\n  client = _MonitoringClient(context)\n  return client\n"
  },
  {
    "path": "datalab/storage/__init__.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Google Cloud Platform library - Cloud Storage Functionality.\"\"\"\nfrom __future__ import absolute_import\n\nfrom ._bucket import Bucket, Buckets\nfrom ._item import Item, Items\n\n__all__ = ['Bucket', 'Buckets', 'Item', 'Items']\n"
  },
  {
    "path": "datalab/storage/_api.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Implements Storage HTTP API wrapper.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom future import standard_library\nstandard_library.install_aliases()  # noqa\nfrom builtins import object\n\nimport urllib.request\nimport urllib.parse\nimport urllib.error\nimport datalab.context\nimport datalab.utils\n\n\nclass Api(object):\n  \"\"\"A helper class to issue Storage HTTP requests.\"\"\"\n\n  # TODO(nikhilko): Use named placeholders in these string templates.\n  _ENDPOINT = 'https://www.googleapis.com/storage/v1'\n  _DOWNLOAD_ENDPOINT = 'https://www.googleapis.com/download/storage/v1'\n  _UPLOAD_ENDPOINT = 'https://www.googleapis.com/upload/storage/v1'\n  _BUCKET_PATH = '/b/%s'\n  _OBJECT_PATH = '/b/%s/o/%s'\n  _OBJECT_COPY_PATH = '/b/%s/o/%s/copyTo/b/%s/o/%s'\n\n  _MAX_RESULTS = 100\n\n  def __init__(self, context):\n    \"\"\"Initializes the Storage helper with context information.\n\n    Args:\n      context: a Context object providing project_id and credentials.\n    \"\"\"\n    self._credentials = context.credentials\n    self._project_id = context.project_id\n\n  @property\n  def project_id(self):\n    \"\"\"The project_id associated with this API client.\"\"\"\n    return self._project_id\n\n  def buckets_insert(self, bucket, project_id=None):\n    \"\"\"Issues a request to create a new bucket.\n\n    Args:\n      bucket: the name of the bucket.\n      project_id: the project to use when inserting the bucket.\n    Returns:\n      A parsed bucket information dictionary.\n    Raises:\n      Exception if there is an error performing the operation.\n    \"\"\"\n    args = {'project': project_id if project_id else self._project_id}\n    data = {'name': bucket}\n\n    url = Api._ENDPOINT + (Api._BUCKET_PATH % '')\n    return datalab.utils.Http.request(url, args=args, data=data, credentials=self._credentials)\n\n  def buckets_delete(self, bucket):\n    \"\"\"Issues a request to delete a bucket.\n\n    Args:\n      bucket: the name of the bucket.\n    Raises:\n      Exception if there is an error performing the operation.\n    \"\"\"\n    url = Api._ENDPOINT + (Api._BUCKET_PATH % bucket)\n    datalab.utils.Http.request(url, method='DELETE', credentials=self._credentials,\n                               raw_response=True)\n\n  def buckets_get(self, bucket, projection='noAcl'):\n    \"\"\"Issues a request to retrieve information about a bucket.\n\n    Args:\n      bucket: the name of the bucket.\n      projection: the projection of the bucket information to retrieve.\n    Returns:\n      A parsed bucket information dictionary.\n    Raises:\n      Exception if there is an error performing the operation.\n    \"\"\"\n    args = {'projection': projection}\n    url = Api._ENDPOINT + (Api._BUCKET_PATH % bucket)\n    return datalab.utils.Http.request(url, credentials=self._credentials, args=args)\n\n  def buckets_list(self, projection='noAcl', max_results=0, page_token=None, project_id=None):\n    \"\"\"Issues a request to retrieve the list of buckets.\n\n    Args:\n      projection: the projection of the bucket information to retrieve.\n      max_results: an optional maximum number of objects to retrieve.\n      page_token: an optional token to continue the retrieval.\n      project_id: the project whose buckets should be listed.\n    Returns:\n      A parsed list of bucket information dictionaries.\n    Raises:\n      Exception if there is an error performing the operation.\n    \"\"\"\n    if max_results == 0:\n      max_results = Api._MAX_RESULTS\n\n    args = {'project': project_id if project_id else self._project_id, 'maxResults': max_results}\n    if projection is not None:\n      args['projection'] = projection\n    if page_token is not None:\n      args['pageToken'] = page_token\n\n    url = Api._ENDPOINT + (Api._BUCKET_PATH % '')\n    return datalab.utils.Http.request(url, args=args, credentials=self._credentials)\n\n  def object_download(self, bucket, key, start_offset=0, byte_count=None):\n    \"\"\"Reads the contents of an object as text.\n\n    Args:\n      bucket: the name of the bucket containing the object.\n      key: the key of the object to be read.\n      start_offset: the start offset of bytes to read.\n      byte_count: the number of bytes to read. If None, it reads to the end.\n    Returns:\n      The text content within the object.\n    Raises:\n      Exception if the object could not be read from.\n    \"\"\"\n    args = {'alt': 'media'}\n    headers = {}\n    if start_offset > 0 or byte_count is not None:\n      header = 'bytes=%d-' % start_offset\n      if byte_count is not None:\n        header += '%d' % byte_count\n      headers['Range'] = header\n    url = Api._DOWNLOAD_ENDPOINT + (Api._OBJECT_PATH % (bucket, Api._escape_key(key)))\n    return datalab.utils.Http.request(url, args=args, headers=headers,\n                                      credentials=self._credentials, raw_response=True)\n\n  def object_upload(self, bucket, key, content, content_type):\n    \"\"\"Writes text content to the object.\n\n    Args:\n      bucket: the name of the bucket containing the object.\n      key: the key of the object to be written.\n      content: the text content to be written.\n      content_type: the type of text content.\n    Raises:\n      Exception if the object could not be written to.\n    \"\"\"\n    args = {'uploadType': 'media', 'name': key}\n    headers = {'Content-Type': content_type}\n\n    url = Api._UPLOAD_ENDPOINT + (Api._OBJECT_PATH % (bucket, ''))\n    return datalab.utils.Http.request(url, args=args, data=content, headers=headers,\n                                      credentials=self._credentials, raw_response=True)\n\n  def objects_copy(self, source_bucket, source_key, target_bucket, target_key):\n    \"\"\"Updates the metadata associated with an object.\n\n    Args:\n      source_bucket: the name of the bucket containing the source object.\n      source_key: the key of the source object being copied.\n      target_bucket: the name of the bucket that will contain the copied object.\n      target_key: the key of the copied object.\n    Returns:\n      A parsed object information dictionary.\n    Raises:\n      Exception if there is an error performing the operation.\n    \"\"\"\n    url = Api._ENDPOINT + (Api._OBJECT_COPY_PATH % (source_bucket, Api._escape_key(source_key),\n                                                    target_bucket, Api._escape_key(target_key)))\n    return datalab.utils.Http.request(url, method='POST', credentials=self._credentials)\n\n  def objects_delete(self, bucket, key):\n    \"\"\"Deletes the specified object.\n\n    Args:\n      bucket: the name of the bucket.\n      key: the key of the object within the bucket.\n    Raises:\n      Exception if there is an error performing the operation.\n    \"\"\"\n    url = Api._ENDPOINT + (Api._OBJECT_PATH % (bucket, Api._escape_key(key)))\n    datalab.utils.Http.request(url, method='DELETE', credentials=self._credentials,\n                               raw_response=True)\n\n  def objects_get(self, bucket, key, projection='noAcl'):\n    \"\"\"Issues a request to retrieve information about an object.\n\n    Args:\n      bucket: the name of the bucket.\n      key: the key of the object within the bucket.\n      projection: the projection of the object to retrieve.\n    Returns:\n      A parsed object information dictionary.\n    Raises:\n      Exception if there is an error performing the operation.\n    \"\"\"\n    args = {}\n    if projection is not None:\n      args['projection'] = projection\n\n    url = Api._ENDPOINT + (Api._OBJECT_PATH % (bucket, Api._escape_key(key)))\n    return datalab.utils.Http.request(url, args=args, credentials=self._credentials)\n\n  def objects_list(self, bucket, prefix=None, delimiter=None, projection='noAcl', versions=False,\n                   max_results=0, page_token=None):\n    \"\"\"Issues a request to retrieve information about an object.\n\n    Args:\n      bucket: the name of the bucket.\n      prefix: an optional key prefix.\n      delimiter: an optional key delimiter.\n      projection: the projection of the objects to retrieve.\n      versions: whether to list each version of a file as a distinct object.\n      max_results: an optional maximum number of objects to retrieve.\n      page_token: an optional token to continue the retrieval.\n    Returns:\n      A parsed list of object information dictionaries.\n    Raises:\n      Exception if there is an error performing the operation.\n    \"\"\"\n    if max_results == 0:\n      max_results = Api._MAX_RESULTS\n\n    args = {'maxResults': max_results}\n    if prefix is not None:\n      args['prefix'] = prefix\n    if delimiter is not None:\n      args['delimiter'] = delimiter\n    if projection is not None:\n      args['projection'] = projection\n    if versions:\n      args['versions'] = 'true'\n    if page_token is not None:\n      args['pageToken'] = page_token\n\n    url = Api._ENDPOINT + (Api._OBJECT_PATH % (bucket, ''))\n    return datalab.utils.Http.request(url, args=args, credentials=self._credentials)\n\n  def objects_patch(self, bucket, key, info):\n    \"\"\"Updates the metadata associated with an object.\n\n    Args:\n      bucket: the name of the bucket containing the object.\n      key: the key of the object being updated.\n      info: the metadata to update.\n    Returns:\n      A parsed object information dictionary.\n    Raises:\n      Exception if there is an error performing the operation.\n    \"\"\"\n    url = Api._ENDPOINT + (Api._OBJECT_PATH % (bucket, Api._escape_key(key)))\n    return datalab.utils.Http.request(url, method='PATCH', data=info, credentials=self._credentials)\n\n  @staticmethod\n  def _escape_key(key):\n    # Disable the behavior to leave '/' alone by explicitly specifying the safe parameter.\n    return urllib.parse.quote(key, safe='')\n\n  @staticmethod\n  def verify_permitted_to_read(gs_path):\n    \"\"\"Check if the user has permissions to read from the given path.\n\n    Args:\n      gs_path: the GCS path to check if user is permitted to read.\n    Raises:\n      Exception if user has no permissions to read.\n    \"\"\"\n    # TODO(qimingj): Storage APIs need to be modified to allow absence of project\n    #                or credential on Items. When that happens we can move the function\n    #                to Items class.\n    from . import _bucket\n    bucket, prefix = _bucket.parse_name(gs_path)\n    credentials = None\n    if datalab.context.Context.is_signed_in():\n      credentials = datalab.context._utils.get_credentials()\n    args = {\n        'maxResults': Api._MAX_RESULTS,\n        'projection': 'noAcl'\n    }\n    if prefix is not None:\n      args['prefix'] = prefix\n    url = Api._ENDPOINT + (Api._OBJECT_PATH % (bucket, ''))\n    try:\n      datalab.utils.Http.request(url, args=args, credentials=credentials)\n    except datalab.utils.RequestException as e:\n      if e.status == 401:\n        raise Exception('Not permitted to read from specified path. '\n                        'Please sign in and make sure you have read access.')\n      raise e\n"
  },
  {
    "path": "datalab/storage/_bucket.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Implements Bucket-related Cloud Storage APIs.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom builtins import object\n\nimport dateutil.parser\nimport re\n\nimport datalab.context\nimport datalab.utils\n\nfrom . import _api\nfrom . import _item\n\n\n# REs to match bucket names and optionally object names\n_BUCKET_NAME = '[a-z\\d][a-z\\d_\\.\\-]+[a-z\\d]'\n_OBJECT_NAME = '[^\\n\\r]+'\n_STORAGE_NAME = 'gs://(' + _BUCKET_NAME + ')(/' + _OBJECT_NAME + ')?'\n\n\ndef parse_name(name):\n  \"\"\" Parse a gs:// URL into the bucket and item names.\n\n  Args:\n    name: a GCS URL of the form gs://bucket or gs://bucket/item\n  Returns:\n    The bucket name (with no gs:// prefix), and the item name if present. If the name\n    could not be parsed returns None for both.\n  \"\"\"\n  bucket = None\n  item = None\n  m = re.match(_STORAGE_NAME, name)\n  if m:\n    # We want to return the last two groups as first group is the optional 'gs://'\n    bucket = m.group(1)\n    item = m.group(2)\n    if item is not None:\n      item = item[1:]  # Strip '/'\n  else:\n    m = re.match('(' + _OBJECT_NAME + ')', name)\n    if m:\n      item = m.group(1)\n  return bucket, item\n\n\nclass BucketMetadata(object):\n  \"\"\"Represents metadata about a Cloud Storage bucket.\"\"\"\n\n  def __init__(self, info):\n    \"\"\"Initializes an instance of a BucketMetadata object.\n\n    Args:\n      info: a dictionary containing information about an Item.\n    \"\"\"\n    self._info = info\n\n  @property\n  def created_on(self):\n    \"\"\"The created timestamp of the bucket as a datetime.datetime.\"\"\"\n    s = self._info.get('timeCreated', None)\n    return dateutil.parser.parse(s) if s else None\n\n  @property\n  def etag(self):\n    \"\"\"The ETag of the bucket, if any.\"\"\"\n    return self._info.get('etag', None)\n\n  @property\n  def name(self):\n    \"\"\"The name of the bucket.\"\"\"\n    return self._info['name']\n\n\nclass Bucket(object):\n  \"\"\"Represents a Cloud Storage bucket.\"\"\"\n\n  def __init__(self, name, info=None, context=None):\n    \"\"\"Initializes an instance of a Bucket object.\n\n    Args:\n      name: the name of the bucket.\n      info: the information about the bucket if available.\n      context: an optional Context object providing project_id and credentials. If a specific\n          project id or credentials are unspecified, the default ones configured at the global\n          level are used.\n    \"\"\"\n    if context is None:\n      context = datalab.context.Context.default()\n    self._context = context\n    self._api = _api.Api(context)\n    self._name = name\n    self._info = info\n\n  @property\n  def name(self):\n    \"\"\"The name of the bucket.\"\"\"\n    return self._name\n\n  def __repr__(self):\n    \"\"\"Returns a representation for the table for showing in the notebook.\n    \"\"\"\n    return 'Bucket gs://%s' % self._name\n\n  @property\n  def metadata(self):\n    \"\"\"Retrieves metadata about the bucket.\n\n    Returns:\n      A BucketMetadata instance with information about this bucket.\n    Raises:\n      Exception if there was an error requesting the bucket's metadata.\n    \"\"\"\n    if self._info is None:\n      try:\n        self._info = self._api.buckets_get(self._name)\n      except Exception as e:\n        raise e\n\n    return BucketMetadata(self._info) if self._info else None\n\n  def item(self, key):\n    \"\"\"Retrieves an Item object for the specified key in this bucket.\n\n    The item need not exist.\n\n    Args:\n      key: the key of the item within the bucket.\n    Returns:\n      An Item instance representing the specified key.\n    \"\"\"\n    return _item.Item(self._name, key, context=self._context)\n\n  def items(self, prefix=None, delimiter=None):\n    \"\"\"Get an iterator for the items within this bucket.\n\n    Args:\n      prefix: an optional prefix to match items.\n      delimiter: an optional string to simulate directory-like semantics. The returned items\n           will be those whose names do not contain the delimiter after the prefix. For\n           the remaining items, the names will be returned truncated after the delimiter\n           with duplicates removed (i.e. as pseudo-directories).\n    Returns:\n      An iterable list of items within this bucket.\n    \"\"\"\n    return _item.Items(self._name, prefix, delimiter, context=self._context)\n\n  def exists(self):\n    \"\"\" Checks if the bucket exists. \"\"\"\n    try:\n      return self.metadata is not None\n    except Exception:\n      return False\n\n  def create(self, project_id=None):\n    \"\"\"Creates the bucket.\n\n    Args:\n      project_id: the project in which to create the bucket.\n    Returns:\n      The bucket.\n    Raises:\n      Exception if there was an error creating the bucket.\n    \"\"\"\n    if not self.exists():\n      if project_id is None:\n        project_id = self._api.project_id\n      try:\n        self._info = self._api.buckets_insert(self._name, project_id=project_id)\n      except Exception as e:\n        raise e\n    return self\n\n  def delete(self):\n    \"\"\"Deletes the bucket.\n\n    Raises:\n      Exception if there was an error deleting the bucket.\n    \"\"\"\n    if self.exists():\n      try:\n        self._api.buckets_delete(self._name)\n      except Exception as e:\n        raise e\n\n\nclass Buckets(object):\n  \"\"\"Represents a list of Cloud Storage buckets for a project.\"\"\"\n\n  def __init__(self, project_id=None, context=None):\n    \"\"\"Initializes an instance of a BucketList.\n\n    Args:\n      project_id: an optional project whose buckets we want to manipulate. If None this\n          is obtained from the api object.\n      context: an optional Context object providing project_id and credentials. If a specific\n          project id or credentials are unspecified, the default ones configured at the global\n          level are used.\n    \"\"\"\n    if context is None:\n      context = datalab.context.Context.default()\n    self._context = context\n    self._api = _api.Api(context)\n    self._project_id = project_id if project_id else self._api.project_id\n\n  def contains(self, name):\n    \"\"\"Checks if the specified bucket exists.\n\n    Args:\n      name: the name of the bucket to lookup.\n    Returns:\n      True if the bucket exists; False otherwise.\n    Raises:\n      Exception if there was an error requesting information about the bucket.\n    \"\"\"\n    try:\n      self._api.buckets_get(name)\n    except datalab.utils.RequestException as e:\n      if e.status == 404:\n        return False\n      raise e\n    except Exception as e:\n      raise e\n    return True\n\n  def create(self, name):\n    \"\"\"Creates a new bucket.\n\n    Args:\n      name: a unique name for the new bucket.\n    Returns:\n      The newly created bucket.\n    Raises:\n      Exception if there was an error creating the bucket.\n    \"\"\"\n    return Bucket(name, context=self._context).create(self._project_id)\n\n  def _retrieve_buckets(self, page_token, _):\n    try:\n      list_info = self._api.buckets_list(page_token=page_token, project_id=self._project_id)\n    except Exception as e:\n      raise e\n\n    buckets = list_info.get('items', [])\n    if len(buckets):\n      try:\n        buckets = [Bucket(info['name'], info, context=self._context) for info in buckets]\n      except KeyError:\n        raise Exception('Unexpected response from server')\n\n    page_token = list_info.get('nextPageToken', None)\n    return buckets, page_token\n\n  def __iter__(self):\n    return iter(datalab.utils.Iterator(self._retrieve_buckets))\n"
  },
  {
    "path": "datalab/storage/_item.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Implements Object-related Cloud Storage APIs.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom builtins import object\n\nimport dateutil.parser\n\nimport datalab.utils\nimport datalab.context\n\nfrom . import _api\n\n# TODO(nikhilko): Read/write operations don't account for larger files, or non-textual content.\n#                 Use streaming reads into a buffer or StringIO or into a file handle.\n\n\nclass ItemMetadata(object):\n  \"\"\"Represents metadata about a Cloud Storage object.\"\"\"\n\n  def __init__(self, info):\n    \"\"\"Initializes an instance of a ItemMetadata object.\n\n    Args:\n      info: a dictionary containing information about an Item.\n    \"\"\"\n    self._info = info\n\n  @property\n  def content_type(self):\n    \"\"\"The Content-Type associated with the item, if any.\"\"\"\n    return self._info.get('contentType', None)\n\n  @property\n  def etag(self):\n    \"\"\"The ETag of the item, if any.\"\"\"\n    return self._info.get('etag', None)\n\n  @property\n  def name(self):\n    \"\"\"The name of the item.\"\"\"\n    return self._info['name']\n\n  @property\n  def size(self):\n    \"\"\"The size (in bytes) of the item. 0 for items that don't exist.\"\"\"\n    return int(self._info.get('size', 0))\n\n  @property\n  def updated_on(self):\n    \"\"\"The updated timestamp of the item as a datetime.datetime.\"\"\"\n    s = self._info.get('updated', None)\n    return dateutil.parser.parse(s) if s else None\n\n\nclass Item(object):\n  \"\"\"Represents a Cloud Storage object within a bucket.\"\"\"\n\n  def __init__(self, bucket, key, info=None, context=None):\n    \"\"\"Initializes an instance of an Item.\n\n    Args:\n      bucket: the name of the bucket containing the item.\n      key: the key of the item.\n      info: the information about the item if available.\n      context: an optional Context object providing project_id and credentials. If a specific\n          project id or credentials are unspecified, the default ones configured at the global\n          level are used.\n    \"\"\"\n    if context is None:\n      context = datalab.context.Context.default()\n    self._context = context\n    self._api = _api.Api(context)\n    self._bucket = bucket\n    self._key = key\n    self._info = info\n\n  @staticmethod\n  def from_url(url):\n    from . import _bucket\n    bucket, item = _bucket.parse_name(url)\n    return Item(bucket, item)\n\n  @property\n  def key(self):\n    \"\"\"Returns the key of the item.\"\"\"\n    return self._key\n\n  @property\n  def uri(self):\n    \"\"\"Returns the gs:// URI for the item.\n    \"\"\"\n    return 'gs://%s/%s' % (self._bucket, self._key)\n\n  def __repr__(self):\n    \"\"\"Returns a representation for the table for showing in the notebook.\n    \"\"\"\n    return 'Item %s' % self.uri\n\n  def copy_to(self, new_key, bucket=None):\n    \"\"\"Copies this item to the specified new key.\n\n    Args:\n      new_key: the new key to copy this item to.\n      bucket: the bucket of the new item; if None (the default) use the same bucket.\n    Returns:\n      An Item corresponding to new key.\n    Raises:\n      Exception if there was an error copying the item.\n    \"\"\"\n    if bucket is None:\n      bucket = self._bucket\n    try:\n      new_info = self._api.objects_copy(self._bucket, self._key, bucket, new_key)\n    except Exception as e:\n      raise e\n    return Item(bucket, new_key, new_info, context=self._context)\n\n  def exists(self):\n    \"\"\" Checks if the item exists. \"\"\"\n    try:\n      return self.metadata is not None\n    except datalab.utils.RequestException:\n      return False\n    except Exception as e:\n      raise e\n\n  def delete(self):\n    \"\"\"Deletes this item from its bucket.\n\n    Raises:\n      Exception if there was an error deleting the item.\n    \"\"\"\n    if self.exists():\n      try:\n        self._api.objects_delete(self._bucket, self._key)\n      except Exception as e:\n        raise e\n\n  @property\n  def metadata(self):\n    \"\"\"Retrieves metadata about the bucket.\n\n    Returns:\n      A BucketMetadata instance with information about this bucket.\n    Raises:\n      Exception if there was an error requesting the bucket's metadata.\n    \"\"\"\n    if self._info is None:\n      try:\n        self._info = self._api.objects_get(self._bucket, self._key)\n      except Exception as e:\n        raise e\n    return ItemMetadata(self._info) if self._info else None\n\n  def read_from(self, start_offset=0, byte_count=None):\n    \"\"\"Reads the content of this item as text.\n\n    Args:\n      start_offset: the start offset of bytes to read.\n      byte_count: the number of bytes to read. If None, it reads to the end.\n    Returns:\n      The text content within the item.\n    Raises:\n      Exception if there was an error requesting the item's content.\n    \"\"\"\n    try:\n      return self._api.object_download(self._bucket, self._key,\n                                       start_offset=start_offset, byte_count=byte_count)\n    except Exception as e:\n      raise e\n\n  def read_lines(self, max_lines=None):\n    \"\"\"Reads the content of this item as text, and return a list of lines up to some max.\n\n    Args:\n      max_lines: max number of lines to return. If None, return all lines.\n    Returns:\n      The text content of the item as a list of lines.\n    Raises:\n      Exception if there was an error requesting the item's content.\n    \"\"\"\n    if max_lines is None:\n      return self.read_from().split('\\n')\n\n    max_to_read = self.metadata.size\n    bytes_to_read = min(100 * max_lines, self.metadata.size)\n    while True:\n      content = self.read_from(byte_count=bytes_to_read)\n\n      lines = content.split('\\n')\n      if len(lines) > max_lines or bytes_to_read >= max_to_read:\n        break\n      # try 10 times more bytes or max\n      bytes_to_read = min(bytes_to_read * 10, max_to_read)\n\n    # remove the partial line at last\n    del lines[-1]\n    return lines[0:max_lines]\n\n  def write_to(self, content, content_type):\n    \"\"\"Writes text content to this item.\n\n    Args:\n      content: the text content to be written.\n      content_type: the type of text content.\n    Raises:\n      Exception if there was an error requesting the item's content.\n    \"\"\"\n    try:\n      self._api.object_upload(self._bucket, self._key, content, content_type)\n    except Exception as e:\n      raise e\n\n\nclass Items(object):\n  \"\"\"Represents a list of Cloud Storage objects within a bucket.\"\"\"\n\n  def __init__(self, bucket, prefix, delimiter, context=None):\n    \"\"\"Initializes an instance of an ItemList.\n\n    Args:\n      bucket: the name of the bucket containing the items.\n      prefix: an optional prefix to match items.\n      delimiter: an optional string to simulate directory-like semantics. The returned items\n           will be those whose names do not contain the delimiter after the prefix. For\n           the remaining items, the names will be returned truncated after the delimiter\n           with duplicates removed (i.e. as pseudo-directories).\n      context: an optional Context object providing project_id and credentials. If a specific\n          project id or credentials are unspecified, the default ones configured at the global\n          level are used.\n    \"\"\"\n    if context is None:\n      context = datalab.context.Context.default()\n    self._context = context\n    self._api = _api.Api(context)\n    self._bucket = bucket\n    self._prefix = prefix\n    self._delimiter = delimiter\n\n  def contains(self, key):\n    \"\"\"Checks if the specified item exists.\n\n    Args:\n      key: the key of the item to lookup.\n    Returns:\n      True if the item exists; False otherwise.\n    Raises:\n      Exception if there was an error requesting information about the item.\n    \"\"\"\n    try:\n      self._api.objects_get(self._bucket, key)\n    except datalab.utils.RequestException as e:\n      if e.status == 404:\n        return False\n      raise e\n    except Exception as e:\n      raise e\n    return True\n\n  def _retrieve_items(self, page_token, _):\n    try:\n      list_info = self._api.objects_list(self._bucket,\n                                         prefix=self._prefix, delimiter=self._delimiter,\n                                         page_token=page_token)\n    except Exception as e:\n      raise e\n\n    items = list_info.get('items', [])\n    if len(items):\n      try:\n        items = [Item(self._bucket, info['name'], info, context=self._context) for info in items]\n      except KeyError:\n        raise Exception('Unexpected response from server')\n\n    page_token = list_info.get('nextPageToken', None)\n    return items, page_token\n\n  def __iter__(self):\n    return iter(datalab.utils.Iterator(self._retrieve_items))\n"
  },
  {
    "path": "datalab/storage/commands/__init__.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\nfrom __future__ import absolute_import\n\nfrom . import _storage\n\n__all__ = ['_storage']\n"
  },
  {
    "path": "datalab/storage/commands/_storage.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Google Cloud Platform library - BigQuery IPython Functionality.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom builtins import str\nfrom past.builtins import basestring\n\ntry:\n  import IPython\n  import IPython.core.display\n  import IPython.core.magic\nexcept ImportError:\n  raise Exception('This module can only be loaded in ipython.')\n\nimport fnmatch\nimport json\nimport re\n\nimport datalab.storage\nimport datalab.utils.commands\n\n\ndef _extract_storage_api_response_error(message):\n  \"\"\" A helper function to extract user-friendly error messages from service exceptions.\n\n  Args:\n    message: An error message from an exception. If this is from our HTTP client code, it\n        will actually be a tuple.\n\n  Returns:\n    A modified version of the message that is less cryptic.\n  \"\"\"\n  try:\n    if len(message) == 3:\n      # Try treat the last part as JSON\n      data = json.loads(message[2])\n      return data['error']['errors'][0]['message']\n  except Exception:\n    pass\n  return message\n\n\n@IPython.core.magic.register_line_cell_magic\ndef storage(line, cell=None):\n  \"\"\"Implements the storage cell magic for ipython notebooks.\n\n  Args:\n    line: the contents of the storage line.\n  Returns:\n    The results of executing the cell.\n  \"\"\"\n  parser = datalab.utils.commands.CommandParser(prog='storage', description=\"\"\"\nExecute various storage-related operations. Use \"%storage <command> -h\"\nfor help on a specific command.\n\"\"\")\n\n  # TODO(gram): consider adding a move command too. I did try this already using the\n  # objects.patch API to change the object name but that fails with an error:\n  #\n  # Value 'newname' in content does not agree with value 'oldname'. This can happen when a value\n  # set through a parameter is inconsistent with a value set in the request.\n  #\n  # This is despite 'name' being identified as writable in the storage API docs.\n  # The alternative would be to use a copy/delete.\n  copy_parser = parser.subcommand('copy',\n                                  'Copy one or more GCS objects to a different location.')\n  copy_parser.add_argument('-s', '--source', help='The name of the object(s) to copy', nargs='+')\n  copy_parser.add_argument('-d', '--destination', required=True,\n                           help='The copy destination. For multiple source items this must be a '\n                                'bucket.')\n  copy_parser.set_defaults(func=_storage_copy)\n\n  create_parser = parser.subcommand('create', 'Create one or more GCS buckets.')\n  create_parser.add_argument('-p', '--project', help='The project associated with the objects')\n  create_parser.add_argument('-b', '--bucket', help='The name of the bucket(s) to create',\n                             nargs='+')\n  create_parser.set_defaults(func=_storage_create)\n\n  delete_parser = parser.subcommand('delete', 'Delete one or more GCS buckets or objects.')\n  delete_parser.add_argument('-b', '--bucket', nargs='*',\n                             help='The name of the bucket(s) to remove')\n  delete_parser.add_argument('-o', '--object', nargs='*',\n                             help='The name of the object(s) to remove')\n  delete_parser.set_defaults(func=_storage_delete)\n\n  list_parser = parser.subcommand('list', 'List buckets in a project, or contents of a bucket.')\n  list_parser.add_argument('-p', '--project', help='The project associated with the objects')\n  group = list_parser.add_mutually_exclusive_group()\n  group.add_argument('-o', '--object',\n                     help='The name of the objects(s) to list; can include wildchars',\n                     nargs='?')\n  group.add_argument('-b', '--bucket',\n                     help='The name of the buckets(s) to list; can include wildchars',\n                     nargs='?')\n  list_parser.set_defaults(func=_storage_list)\n\n  read_parser = parser.subcommand('read',\n                                  'Read the contents of a storage object into a Python variable.')\n  read_parser.add_argument('-o', '--object', help='The name of the object to read',\n                           required=True)\n  read_parser.add_argument('-v', '--variable', required=True,\n                           help='The name of the Python variable to set')\n  read_parser.set_defaults(func=_storage_read)\n\n  view_parser = parser.subcommand('view', 'View the contents of a storage object.')\n  view_parser.add_argument('-n', '--head', type=int, default=20,\n                           help='The number of initial lines to view')\n  view_parser.add_argument('-t', '--tail', type=int, default=20,\n                           help='The number of lines from end to view')\n  view_parser.add_argument('-o', '--object', help='The name of the object to view',\n                           required=True)\n  view_parser.set_defaults(func=_storage_view)\n\n  write_parser = parser.subcommand('write',\n                                   'Write the value of a Python variable to a storage object.')\n  write_parser.add_argument('-v', '--variable', help='The name of the source Python variable',\n                            required=True)\n  write_parser.add_argument('-o', '--object', required=True,\n                            help='The name of the destination GCS object to write')\n  write_parser.add_argument('-c', '--content_type', help='MIME type', default='text/plain')\n  write_parser.set_defaults(func=_storage_write)\n\n  return datalab.utils.commands.handle_magic_line(line, cell, parser)\n\n\ndef _parser_exit(status=0, message=None):\n  \"\"\" Replacement exit method for argument parser. We want to stop processing args but not\n      call sys.exit(), so we raise an exception here and catch it in the call to parse_args.\n  \"\"\"\n  raise Exception()\n\n\ndef _expand_list(names):\n  \"\"\" Do a wildchar name expansion of object names in a list and return expanded list.\n\n    The items are expected to exist as this is used for copy sources or delete targets.\n    Currently we support wildchars in the key name only.\n  \"\"\"\n\n  if names is None:\n    names = []\n  elif isinstance(names, basestring):\n    names = [names]\n\n  results = []  # The expanded list.\n  items = {}  # Cached contents of buckets; used for matching.\n  for name in names:\n    bucket, key = datalab.storage._bucket.parse_name(name)\n    results_len = len(results)  # If we fail to add any we add name and let caller deal with it.\n    if bucket:\n      if not key:\n        # Just a bucket; add it.\n        results.append('gs://%s' % bucket)\n      elif datalab.storage.Item(bucket, key).exists():\n        results.append('gs://%s/%s' % (bucket, key))\n      else:\n        # Expand possible key values.\n        if bucket not in items and key[:1] == '*':\n          # We need the full list; cache a copy for efficiency.\n          items[bucket] = [item.metadata.name\n                           for item in list(datalab.storage.Bucket(bucket).items())]\n        # If we have a cached copy use it\n        if bucket in items:\n          candidates = items[bucket]\n        # else we have no cached copy but can use prefix matching which is more efficient than\n        # getting the full contents.\n        else:\n          # Get the non-wildchar prefix.\n          match = re.search('\\?|\\*|\\[', key)\n          prefix = key\n          if match:\n            prefix = key[0:match.start()]\n\n          candidates = [item.metadata.name\n                        for item in datalab.storage.Bucket(bucket).items(prefix=prefix)]\n\n        for item in candidates:\n          if fnmatch.fnmatch(item, key):\n            results.append('gs://%s/%s' % (bucket, item))\n\n    # If we added no matches, add the original name and let caller deal with it.\n    if len(results) == results_len:\n      results.append(name)\n\n  return results\n\n\ndef _storage_copy(args, _):\n  target = args['destination']\n  target_bucket, target_key = datalab.storage._bucket.parse_name(target)\n  if target_bucket is None and target_key is None:\n    raise Exception('Invalid copy target name %s' % target)\n\n  sources = _expand_list(args['source'])\n\n  if len(sources) > 1:\n    # Multiple sources; target must be a bucket\n    if target_bucket is None or target_key is not None:\n      raise Exception('More than one source but target %s is not a bucket' % target)\n\n  errs = []\n  for source in sources:\n    source_bucket, source_key = datalab.storage._bucket.parse_name(source)\n    if source_bucket is None or source_key is None:\n      raise Exception('Invalid source object name %s' % source)\n    destination_bucket = target_bucket if target_bucket else source_bucket\n    destination_key = target_key if target_key else source_key\n    try:\n      datalab.storage.Item(source_bucket, source_key).copy_to(destination_key,\n                                                              bucket=destination_bucket)\n    except Exception as e:\n      errs.append(\"Couldn't copy %s to %s: %s\" %\n                  (source, target, _extract_storage_api_response_error(str(e))))\n  if errs:\n    raise Exception('\\n'.join(errs))\n\n\ndef _storage_create(args, _):\n  \"\"\" Create one or more buckets. \"\"\"\n  buckets = datalab.storage.Buckets(project_id=args['project'])\n  errs = []\n  for name in args['bucket']:\n    try:\n      bucket, key = datalab.storage._bucket.parse_name(name)\n      if bucket and not key:\n        buckets.create(bucket)\n      else:\n        raise Exception(\"Invalid bucket name %s\" % name)\n    except Exception as e:\n      errs.append(\"Couldn't create %s: %s\" %\n                  (name, _extract_storage_api_response_error(str(e))))\n  if errs:\n    raise Exception('\\n'.join(errs))\n\n\ndef _storage_delete(args, _):\n  \"\"\" Delete one or more buckets or objects. \"\"\"\n  items = _expand_list(args['bucket'])\n  items.extend(_expand_list(args['object']))\n  errs = []\n  for item in items:\n    try:\n      bucket, key = datalab.storage._bucket.parse_name(item)\n      if bucket and key:\n        gcs_item = datalab.storage.Item(bucket, key)\n        if gcs_item.exists():\n          datalab.storage.Item(bucket, key).delete()\n        else:\n          errs.append(\"%s does not exist\" % item)\n      elif bucket:\n        gcs_bucket = datalab.storage.Bucket(bucket)\n        if gcs_bucket.exists():\n          gcs_bucket.delete()\n        else:\n          errs.append(\"%s does not exist\" % item)\n      else:\n        raise Exception(\"Can't delete item with invalid name %s\" % item)\n    except Exception as e:\n      errs.append(\"Couldn't delete %s: %s\" %\n                  (item, _extract_storage_api_response_error(str(e))))\n  if errs:\n    raise Exception('\\n'.join(errs))\n\n\ndef _storage_list_buckets(project, pattern):\n  \"\"\" List all storage buckets that match a pattern. \"\"\"\n  data = [{'Bucket': 'gs://' + bucket.name, 'Created': bucket.metadata.created_on}\n          for bucket in datalab.storage.Buckets(project_id=project)\n          if fnmatch.fnmatch(bucket.name, pattern)]\n  return datalab.utils.commands.render_dictionary(data, ['Bucket', 'Created'])\n\n\ndef _storage_get_keys(bucket, pattern):\n  \"\"\" Get names of all storage keys in a specified bucket that match a pattern. \"\"\"\n  return [item for item in list(bucket.items()) if fnmatch.fnmatch(item.metadata.name, pattern)]\n\n\ndef _storage_get_key_names(bucket, pattern):\n  \"\"\" Get names of all storage keys in a specified bucket that match a pattern. \"\"\"\n  return [item.metadata.name for item in _storage_get_keys(bucket, pattern)]\n\n\ndef _storage_list_keys(bucket, pattern):\n  \"\"\" List all storage keys in a specified bucket that match a pattern. \"\"\"\n  data = [{'Name': item.metadata.name,\n           'Type': item.metadata.content_type,\n           'Size': item.metadata.size,\n           'Updated': item.metadata.updated_on}\n          for item in _storage_get_keys(bucket, pattern)]\n  return datalab.utils.commands.render_dictionary(data, ['Name', 'Type', 'Size', 'Updated'])\n\n\ndef _storage_list(args, _):\n  \"\"\" List the buckets or the contents of a bucket.\n\n  This command is a bit different in that we allow wildchars in the bucket name and will list\n  the buckets that match.\n  \"\"\"\n  target = args['object'] if args['object'] else args['bucket']\n  project = args['project']\n  if target is None:\n    return _storage_list_buckets(project, '*')  # List all buckets.\n\n  bucket_name, key = datalab.storage._bucket.parse_name(target)\n  if bucket_name is None:\n    raise Exception('Cannot list %s; not a valid bucket name' % target)\n\n  if key or not re.search('\\?|\\*|\\[', target):\n    # List the contents of the bucket\n    if not key:\n      key = '*'\n    if project:\n      # Only list if the bucket is in the project\n      for bucket in datalab.storage.Buckets(project_id=project):\n        if bucket.name == bucket_name:\n          break\n      else:\n        raise Exception('%s does not exist in project %s' % (target, project))\n    else:\n      bucket = datalab.storage.Bucket(bucket_name)\n\n    if bucket.exists():\n      return _storage_list_keys(bucket, key)\n    else:\n      raise Exception('Bucket %s does not exist' % target)\n\n  else:\n    # Treat the bucket name as a pattern and show matches. We don't use bucket_name as that\n    # can strip off wildchars and so we need to strip off gs:// here.\n    return _storage_list_buckets(project, target[5:])\n\n\ndef _get_item_contents(source_name):\n  source_bucket, source_key = datalab.storage._bucket.parse_name(source_name)\n  if source_bucket is None:\n    raise Exception('Invalid source object name %s; no bucket specified.' % source_name)\n  if source_key is None:\n    raise Exception('Invalid source object name %si; source cannot be a bucket.' % source_name)\n  source = datalab.storage.Item(source_bucket, source_key)\n  if not source.exists():\n    raise Exception('Source object %s does not exist' % source_name)\n  return source.read_from()\n\n\ndef _storage_read(args, _):\n  contents = _get_item_contents(args['object'])\n  ipy = IPython.get_ipython()\n  ipy.push({args['variable']: contents})\n\n\ndef _storage_view(args, _):\n  contents = _get_item_contents(args['object'])\n  if not isinstance(contents, basestring):\n    contents = str(contents)\n  lines = contents.split('\\n')\n  head_count = args['head']\n  tail_count = args['tail']\n  if len(lines) > head_count + tail_count:\n    head = '\\n'.join(lines[:head_count])\n    tail = '\\n'.join(lines[-tail_count:])\n    return head + '\\n...\\n' + tail\n  else:\n    return contents\n\n\ndef _storage_write(args, _):\n  target_name = args['object']\n  target_bucket, target_key = datalab.storage._bucket.parse_name(target_name)\n  if target_bucket is None or target_key is None:\n    raise Exception('Invalid target object name %s' % target_name)\n  target = datalab.storage.Item(target_bucket, target_key)\n  ipy = IPython.get_ipython()\n  contents = ipy.user_ns[args['variable']]\n  # TODO(gram): would we want to to do any special handling here; e.g. for DataFrames?\n  target.write_to(str(contents), args['content_type'])\n"
  },
  {
    "path": "datalab/utils/__init__.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Google Cloud Platform library - Internal Helpers.\"\"\"\n\nfrom ._async import async_, async_function, async_method\nfrom ._gcp_job import GCPJob\nfrom ._http import Http, RequestException\nfrom ._iterator import Iterator\nfrom ._job import Job, JobError\nfrom ._json_encoder import JSONEncoder\nfrom ._lru_cache import LRUCache\nfrom ._lambda_job import LambdaJob\nfrom ._dataflow_job import DataflowJob\nfrom ._utils import print_exception_with_last_stack, get_item, compare_datetimes, \\\n    pick_unused_port, is_http_running_on, gcs_copy_file\n\n__all__ = ['async_', 'async_function', 'async_method', 'GCPJob', 'Http', 'RequestException',\n           'Iterator', 'Job', 'JobError', 'JSONEncoder', 'LRUCache', 'LambdaJob', 'DataflowJob',\n           'print_exception_with_last_stack', 'get_item', 'compare_datetimes', 'pick_unused_port',\n           'is_http_running_on', 'gcs_copy_file']\n"
  },
  {
    "path": "datalab/utils/_async.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Decorators for async methods and functions to dispatch on threads and support chained calls.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom builtins import object\n\nimport abc\nimport concurrent.futures\nimport functools\n\nfrom . import _job\nfrom future.utils import with_metaclass\n\n\nclass async_(with_metaclass(abc.ABCMeta, object)):\n  \"\"\" Base class for async_function/async_method. Creates a wrapped function/method that will\n      run the original function/method on a thread pool worker thread and return a Job instance\n      for monitoring the status of the thread.\n  \"\"\"\n  executor = concurrent.futures.ThreadPoolExecutor(max_workers=50)  # Pool for doing the work.\n\n  def __init__(self, function):\n    self._function = function\n    # Make the wrapper get attributes like docstring from wrapped method.\n    functools.update_wrapper(self, function)\n\n  @staticmethod\n  def _preprocess_args(*args):\n    # Pre-process arguments - if any are themselves Futures block until they can be resolved.\n    return [arg.result() if isinstance(arg, concurrent.futures.Future) else arg for arg in args]\n\n  @staticmethod\n  def _preprocess_kwargs(**kwargs):\n    # Pre-process keyword arguments - if any are Futures block until they can be resolved.\n    return {kw: (arg.result() if isinstance(arg, concurrent.futures.Future) else arg)\n            for kw, arg in list(kwargs.items())}\n\n  @abc.abstractmethod\n  def _call(self, *args, **kwargs):\n    return\n\n  def __call__(self, *args, **kwargs):\n    # Queue the call up in the thread pool.\n    return _job.Job(future=self.executor.submit(self._call, *args, **kwargs))\n\n\nclass async_function(async_):\n  \"\"\" This decorator can be applied to any static function that makes blocking calls to create\n      a modified version that creates a Job and returns immediately; the original\n      method will be called on a thread pool worker thread.\n  \"\"\"\n\n  def _call(self, *args, **kwargs):\n    # Call the wrapped method.\n    return self._function(*async_._preprocess_args(*args), **async_._preprocess_kwargs(**kwargs))\n\n\nclass async_method(async_):\n  \"\"\" This decorator can be applied to any class instance method that makes blocking calls to create\n      a modified version that creates a Job and returns immediately; the original method will be\n      called on a thread pool worker thread.\n  \"\"\"\n\n  def _call(self, *args, **kwargs):\n    # Call the wrapped method.\n    return self._function(self.obj, *async_._preprocess_args(*args),\n                          **async_._preprocess_kwargs(**kwargs))\n\n  def __get__(self, instance, owner):\n    # This is important for attribute inheritance and setting self.obj so it can be\n    # passed as first argument to wrapped method.\n    self.cls = owner\n    self.obj = instance\n    return self\n"
  },
  {
    "path": "datalab/utils/_dataflow_job.py",
    "content": "# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Implements DataFlow Job functionality.\"\"\"\n\n\nfrom . import _job\n\n\nclass DataflowJob(_job.Job):\n  \"\"\"Represents a DataFlow Job.\n  \"\"\"\n\n  def __init__(self, runner_results):\n    \"\"\"Initializes an instance of a DataFlow Job.\n\n    Args:\n      runner_results: a DataflowPipelineResult returned from Pipeline.run().\n    \"\"\"\n    super(DataflowJob, self).__init__(runner_results._job.name)\n    self._runner_results = runner_results\n\n  def _refresh_state(self):\n    \"\"\" Refresh the job info. \"\"\"\n\n    # DataFlow's DataflowPipelineResult does not refresh state, so we have to do it ourselves\n    # as a workaround.\n    self._runner_results._job = (\n        self._runner_results._runner.dataflow_client.get_job(self._runner_results.job_id()))\n    self._is_complete = self._runner_results.state in ['STOPPED', 'DONE', 'FAILED', 'CANCELLED']\n    self._fator_error = getattr(self._runner_results._runner, 'last_error_msg', None)\n"
  },
  {
    "path": "datalab/utils/_gcp_job.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Implements GCP Job functionality.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\n\nimport datalab.context\nfrom . import _job\n\n\nclass GCPJob(_job.Job):\n  \"\"\"Represents a BigQuery Job.\n  \"\"\"\n\n  def __init__(self, job_id, context):\n    \"\"\"Initializes an instance of a Job.\n\n    Args:\n      job_id: the BigQuery job ID corresponding to this job.\n      context: a Context object providing project_id and credentials.\n    \"\"\"\n    super(GCPJob, self).__init__(job_id)\n    if context is None:\n      context = datalab.context.Context.default()\n    self._context = context\n    self._api = self._create_api(context)\n\n  def _create_api(self, context):\n    raise Exception('_create_api must be defined in a derived class')\n\n  def __repr__(self):\n    \"\"\"Returns a representation for the job for showing in the notebook.\n    \"\"\"\n    return 'Job %s/%s %s' % (self._context.project_id, self._job_id, self.state)\n"
  },
  {
    "path": "datalab/utils/_http.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Implements HTTP client helper functionality.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom future import standard_library\nstandard_library.install_aliases()  # noqa\nfrom builtins import str\nfrom past.builtins import basestring\nfrom builtins import object\n\nimport copy\nimport datetime\nimport json\nimport urllib.request\nimport urllib.parse\nimport urllib.error\nimport httplib2\nimport google_auth_httplib2\nimport logging\n\n\nlog = logging.getLogger(__name__)\n\n\n# TODO(nikhilko): Start using the requests library instead.\n\n\nclass RequestException(Exception):\n\n  def __init__(self, status, content):\n    self.status = status\n    self.content = content\n    self.message = 'HTTP request failed'\n    # Try extract a message from the body; swallow possible resulting ValueErrors and KeyErrors.\n    try:\n      error = json.loads(content.decode('utf-8'))['error']\n      if 'errors' in error:\n        error = error['errors'][0]\n      self.message += ': ' + error['message']\n    except Exception:\n      lines = content.splitlines() if isinstance(content, basestring) else []\n      if lines:\n        self.message += ': ' + lines[0]\n\n  def __str__(self):\n    return self.message\n\n\nclass Http(object):\n  \"\"\"A helper class for making HTTP requests.\n  \"\"\"\n\n  # Reuse one Http object across requests to take advantage of Keep-Alive, e.g.\n  # for BigQuery queries that requires at least ~5 sequential http requests.\n  #\n  # TODO(nikhilko):\n  # SSL cert validation seemingly fails, and workarounds are not amenable\n  # to implementing in library code. So configure the Http object to skip\n  # doing so, in the interim.\n  http = httplib2.Http()\n  http.disable_ssl_certificate_validation = True\n\n  def __init__(self):\n    pass\n\n  @staticmethod\n  def request(url, args=None, data=None, headers=None, method=None,\n              credentials=None, raw_response=False, stats=None):\n    \"\"\"Issues HTTP requests.\n\n    Args:\n      url: the URL to request.\n      args: optional query string arguments.\n      data: optional data to be sent within the request.\n      headers: optional headers to include in the request.\n      method: optional HTTP method to use. If unspecified this is inferred\n          (GET or POST) based on the existence of request data.\n      credentials: optional set of credentials to authorize the request.\n      raw_response: whether the raw response content should be returned as-is.\n      stats: an optional dictionary that, if provided, will be populated with some\n          useful info about the request, like 'duration' in seconds and 'data_size' in\n          bytes. These may be useful optimizing the access to rate-limited APIs.\n    Returns:\n      The parsed response object.\n    Raises:\n      Exception when the HTTP request fails or the response cannot be processed.\n    \"\"\"\n    if headers is None:\n      headers = {}\n\n    headers['user-agent'] = 'GoogleCloudDataLab/1.0'\n    # Add querystring to the URL if there are any arguments.\n    if args is not None:\n      qs = urllib.parse.urlencode(args)\n      url = url + '?' + qs\n\n    # Setup method to POST if unspecified, and appropriate request headers\n    # if there is data to be sent within the request.\n    if data is not None:\n      if method is None:\n        method = 'POST'\n\n      if data != '':\n        # If there is a content type specified, use it (and the data) as-is.\n        # Otherwise, assume JSON, and serialize the data object.\n        if 'Content-Type' not in headers:\n          data = json.dumps(data)\n          headers['Content-Type'] = 'application/json'\n      headers['Content-Length'] = str(len(data))\n    else:\n      if method == 'POST':\n        headers['Content-Length'] = '0'\n\n    # If the method is still unset, i.e. it was unspecified, and there\n    # was no data to be POSTed, then default to GET request.\n    if method is None:\n      method = 'GET'\n\n    http = Http.http\n\n    # Authorize with credentials if given.\n    if credentials is not None:\n      # Make a copy of the shared http instance before we modify it.\n      http = copy.copy(http)\n      http = google_auth_httplib2.AuthorizedHttp(credentials)\n    if stats is not None:\n      stats['duration'] = datetime.datetime.utcnow()\n\n    response = None\n    try:\n      log.debug('request: method[%(method)s], url[%(url)s], body[%(data)s]' % locals())\n      response, content = http.request(url,\n                                       method=method,\n                                       body=data,\n                                       headers=headers)\n      if 200 <= response.status < 300:\n        if raw_response:\n          return content\n        if type(content) == str:\n          return json.loads(content)\n        else:\n          return json.loads(str(content, encoding='UTF-8'))\n      else:\n        raise RequestException(response.status, content)\n    except ValueError:\n      raise Exception('Failed to process HTTP response.')\n    except httplib2.HttpLib2Error:\n      raise Exception('Failed to send HTTP request.')\n    finally:\n      if stats is not None:\n        stats['data_size'] = len(data)\n        stats['status'] = response.status\n        stats['duration'] = (datetime.datetime.utcnow() - stats['duration']).total_seconds()\n"
  },
  {
    "path": "datalab/utils/_iterator.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Iterator class for iterable cloud lists.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom builtins import object\n\n\nclass Iterator(object):\n  \"\"\"An iterator implementation that handles paging over a cloud list.\"\"\"\n\n  def __init__(self, retriever):\n    \"\"\"Initializes an instance of an Iterator.\n\n    Args:\n      retriever: a function that can retrieve the next page of items.\n    \"\"\"\n    self._page_token = None\n    self._first_page = True\n    self._retriever = retriever\n    self._count = 0\n\n  def __iter__(self):\n    \"\"\"Provides iterator functionality.\"\"\"\n    while self._first_page or (self._page_token is not None):\n      items, next_page_token = self._retriever(self._page_token, self._count)\n\n      self._page_token = next_page_token\n      self._first_page = False\n      if self._count == 0:\n        self._count = len(items)\n\n      for item in items:\n        yield item\n\n  def reset(self):\n    \"\"\"Resets the current iteration.\"\"\"\n    self._page_token = None\n    self._first_page = True\n    self._count = 0\n"
  },
  {
    "path": "datalab/utils/_job.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Implements Job functionality for async tasks.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom builtins import str\nfrom builtins import object\n\nimport concurrent.futures\nimport datetime\nimport time\nimport traceback\nimport uuid\n\n\nclass JobError(Exception):\n  \"\"\" A helper class to capture multiple components of Job errors.  \"\"\"\n\n  def __init__(self, location, message, reason):\n    self.location = location\n    self.message = message\n    self.reason = reason\n\n  def __str__(self):\n    return self.message\n\n\nclass Job(object):\n  \"\"\"A manager object for async operations.\n\n     A Job can have a Future in which case it will be able to monitor its own completion state\n     and result, or it may have no Future in which case it must be a derived class that\n     manages this some other way. We do this instead of having an abstract base class in\n     order to make wait_one/wait_all more efficient; instead of just sleeping and polling\n     we can use more reactive ways of monitoring groups of Jobs.\n  \"\"\"\n\n  _POLL_INTERVAL_SECONDS = 5\n\n  def __init__(self, job_id=None, future=None):\n    \"\"\"Initializes an instance of a Job.\n\n    Args:\n      job_id: a unique ID for the job. If None, a UUID will be generated.\n      future: the Future associated with the Job, if any.\n    \"\"\"\n    self._job_id = str(uuid.uuid4()) if job_id is None else job_id\n    self._future = future\n    self._is_complete = False\n    self._errors = None\n    self._fatal_error = None\n    self._result = None\n    self._start_time = datetime.datetime.utcnow()\n    self._end_time = None\n\n  def __str__(self):\n    return self._job_id\n\n  @property\n  def id(self):\n    \"\"\" Get the Job ID.\n\n    Returns:\n      The ID of the job.\n    \"\"\"\n    return self._job_id\n\n  @property\n  def is_complete(self):\n    \"\"\" Get the completion state of the job.\n\n    Returns:\n      True if the job is complete; False if it is still running.\n    \"\"\"\n    self._refresh_state()\n    return self._is_complete\n\n  @property\n  def failed(self):\n    \"\"\" Get the success state of the job.\n\n    Returns:\n      True if the job failed; False if it is still running or succeeded (possibly with partial\n      failure).\n    \"\"\"\n    self._refresh_state()\n    return self._is_complete and self._fatal_error is not None\n\n  @property\n  def fatal_error(self):\n    \"\"\" Get the job error.\n\n    Returns:\n      None if the job succeeded or is still running, else the error tuple for the failure.\n    \"\"\"\n    self._refresh_state()\n    return self._fatal_error\n\n  @property\n  def errors(self):\n    \"\"\" Get the non-fatal errors in the job.\n\n    Returns:\n      None if the job is still running, else the list of errors that occurred.\n    \"\"\"\n    self._refresh_state()\n    return self._errors\n\n  def result(self):\n    \"\"\" Get the result for a job. This will block if the job is incomplete.\n\n    Returns:\n      The result for the Job.\n\n    Raises:\n      An exception if the Job resulted in an exception.\n\n    \"\"\"\n    self.wait()\n    if self._fatal_error:\n      raise self._fatal_error\n    return self._result\n\n  @property\n  def start_time_utc(self):\n    \"\"\" The UTC start time of the job as a Python datetime. \"\"\"\n    return self._start_time\n\n  @property\n  def end_time_utc(self):\n    \"\"\" The UTC end time of the job (or None if incomplete) as a Python datetime. \"\"\"\n    return self._end_time\n\n  @property\n  def total_time(self):\n    \"\"\" The total time in fractional seconds that the job took, or None if not complete. \"\"\"\n    if self._end_time is None:\n      return None\n    return (self._end_time - self._start_time).total_seconds()\n\n  def _refresh_state(self):\n    \"\"\" Get the state of a job. Must be overridden by derived Job classes\n        for Jobs that don't use a Future.\n    \"\"\"\n    if self._is_complete:\n      return\n\n    if not self._future:\n      raise Exception('Please implement this in the derived class')\n\n    if self._future.done():\n      self._is_complete = True\n      self._end_time = datetime.datetime.utcnow()\n      try:\n        self._result = self._future.result()\n      except Exception as e:\n        message = str(e)\n        self._fatal_error = JobError(location=traceback.format_exc(), message=message,\n                                     reason=str(type(e)))\n\n  def _timeout(self):\n    \"\"\" Helper for raising timeout errors. \"\"\"\n    raise concurrent.futures.TimeoutError('Timed out waiting for Job %s to complete' % self._job_id)\n\n  def wait(self, timeout=None):\n    \"\"\" Wait for the job to complete, or a timeout to happen.\n\n    Args:\n      timeout: how long to wait before giving up (in seconds); default None which means no timeout.\n\n    Returns:\n      The Job\n    \"\"\"\n    if self._future:\n      try:\n        # Future.exception() will return rather than raise any exception so we use it.\n        self._future.exception(timeout)\n      except concurrent.futures.TimeoutError:\n        self._timeout()\n      self._refresh_state()\n    else:\n      # fall back to polling\n      while not self.is_complete:\n        if timeout is not None:\n          if timeout <= 0:\n            self._timeout()\n          timeout -= Job._POLL_INTERVAL_SECONDS\n        time.sleep(Job._POLL_INTERVAL_SECONDS)\n    return self\n\n  @property\n  def state(self):\n    \"\"\" Describe the state of a Job.\n\n    Returns: A string describing the job's state.\n    \"\"\"\n    state = 'in progress'\n    if self.is_complete:\n      if self.failed:\n        state = 'failed with error: %s' % str(self._fatal_error)\n      elif self._errors:\n        state = 'completed with some non-fatal errors'\n      else:\n        state = 'completed'\n    return state\n\n  def __repr__(self):\n    \"\"\" Get the notebook representation for the job. \"\"\"\n    return 'Job %s %s' % (self._job_id, self.state)\n\n  @staticmethod\n  def _wait(jobs, timeout, return_when):\n    # If a single job is passed in, make it an array for consistency\n    if isinstance(jobs, Job):\n      jobs = [jobs]\n    elif len(jobs) == 0:\n      return jobs\n\n    wait_on_one = return_when == concurrent.futures.FIRST_COMPLETED\n    completed = []\n    while True:\n      if timeout is not None:\n        timeout -= Job._POLL_INTERVAL_SECONDS\n\n      done = [job for job in jobs if job.is_complete]\n\n      if len(done):\n        completed.extend(done)\n        for job in done:\n          jobs.remove(job)\n        if wait_on_one or len(jobs) == 0:\n          return completed\n\n      if timeout is not None and timeout < 0:\n        return completed\n\n      # Need to block for some time. Favor using concurrent.futures.wait if possible\n      # as it can return early if a (thread) job is ready; else fall back to time.sleep.\n      futures = [job._future for job in jobs if job._future]\n      if len(futures) == 0:\n        time.sleep(Job._POLL_INTERVAL_SECONDS)\n      else:\n        concurrent.futures.wait(futures, timeout=Job._POLL_INTERVAL_SECONDS,\n                                return_when=return_when)\n\n  @staticmethod\n  def wait_any(jobs, timeout=None):\n    \"\"\" Return when at least one of the specified jobs has completed or timeout expires.\n\n    Args:\n      jobs: a Job or list of Jobs to wait on.\n      timeout: a timeout in seconds to wait for. None (the default) means no timeout.\n    Returns:\n      A list of the jobs that have now completed or None if there were no jobs.\n\n    \"\"\"\n    return Job._wait(jobs, timeout, concurrent.futures.FIRST_COMPLETED)\n\n  @staticmethod\n  def wait_all(jobs, timeout=None):\n    \"\"\" Return when at all of the specified jobs have completed or timeout expires.\n\n    Args:\n      jobs: a Job or list of Jobs to wait on.\n      timeout: a timeout in seconds to wait for. None (the default) means no timeout.\n    Returns:\n      A list of the jobs that have now completed or None if there were no jobs.\n    \"\"\"\n    return Job._wait(jobs, timeout, concurrent.futures.ALL_COMPLETED)\n"
  },
  {
    "path": "datalab/utils/_json_encoder.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\" JSON encoder that can handle Python datetime objects. \"\"\"\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nimport datetime\nimport json\n\n\nclass JSONEncoder(json.JSONEncoder):\n  \"\"\" A JSON encoder that can handle Python datetime objects. \"\"\"\n\n  def default(self, obj):\n    if isinstance(obj, datetime.date) or isinstance(obj, datetime.datetime):\n      return obj.isoformat()\n    elif isinstance(obj, datetime.timedelta):\n      return (datetime.datetime.min + obj).time().isoformat()\n    else:\n      return super(JSONEncoder, self).default(obj)\n"
  },
  {
    "path": "datalab/utils/_lambda_job.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Implements OS shell Job functionality.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\n\nfrom . import _async\nfrom . import _job\n\n\nclass LambdaJob(_job.Job):\n  \"\"\"Represents an lambda function as a Job.\n  \"\"\"\n\n  def __init__(self, fn, job_id, *args, **kwargs):\n    \"\"\"Initializes an instance of a Job.\n\n    Args:\n      fn: the lambda function to execute asyncronously\n      job_id: an optional ID for the job. If None, a UUID will be generated.\n    \"\"\"\n    super(LambdaJob, self).__init__(job_id)\n    self._future = _async.async_.executor.submit(fn, *args, **kwargs)\n\n  def __repr__(self):\n    \"\"\"Returns a representation for the job for showing in the notebook.\n    \"\"\"\n    return 'Job %s %s' % (self._job_id, self.state)\n\n    # TODO: ShellJob, once we need it, should inherit on LambdaJob:\n    #      import subprocess\n    #      LambdaJob(subprocess.check_output, id, command_line, shell=True)\n"
  },
  {
    "path": "datalab/utils/_lru_cache.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"A simple LRU cache.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom builtins import str\nfrom past.builtins import basestring\nfrom builtins import object\n\nimport datetime\n\n\nclass LRUCache(object):\n  \"\"\"A simple LRU cache.\"\"\"\n\n  def __init__(self, cache_size):\n    \"\"\" Initialize the cache with the given size.\n\n    Args:\n      cache_size: the maximum number of items the cache can hold. Attempts to add more\n          items than this will result in the least recently used items being displaced to\n          make room.\n    \"\"\"\n    self._cache = {}\n    self._cache_size = cache_size\n\n  def __getitem__(self, key):\n    \"\"\" Get an item from the cache.\n\n    Args:\n      key: a string used as the lookup key.\n    Returns:\n      The cached item, if any.\n    Raises:\n      Exception if the key is not a string.\n      KeyError if the key is not found.\n    \"\"\"\n    if not isinstance(key, basestring):\n      raise Exception(\"LRU cache can only be indexed by strings (%s has type %s)\" %\n                      (str(key), str(type(key))))\n\n    if key in self._cache:\n      entry = self._cache[key]\n      entry['last_used'] = datetime.datetime.now()\n      return entry['value']\n    else:\n      raise KeyError(key)\n\n  def __delitem__(self, key):\n    \"\"\" Remove an item from the cache.\n\n    Args:\n      key: a string key for retrieving the item.\n    \"\"\"\n    if not isinstance(key, basestring):\n      raise Exception(\"LRU cache can only be indexed by strings\")\n    del self._cache[key]\n\n  def __setitem__(self, key, value):\n    \"\"\" Put an item in the cache.\n\n    Args:\n      key: a string key for retrieving the item.\n      value: the item to cache.\n    Raises:\n      Exception if the key is not a string.\n    \"\"\"\n    if not isinstance(key, basestring):\n      raise Exception(\"LRU cache can only be indexed by strings\")\n\n    if key in self._cache:\n      entry = self._cache[key]\n    elif len(self._cache) < self._cache_size:\n      # Cache is not full; append an new entry\n      self._cache[key] = entry = {}\n    else:\n      # Cache is full; displace an entry\n      entry = min(list(self._cache.values()), key=lambda x: x['last_used'])\n      self._cache.pop(entry['key'])\n      self._cache[key] = entry\n\n    entry['value'] = value\n    entry['key'] = key\n    entry['last_used'] = datetime.datetime.now()\n\n  def __contains__(self, key):\n    return key in self._cache\n\n  def get(self, key, value):\n    if key in self._cache:\n      return self._cache[key]['value']\n    return value\n"
  },
  {
    "path": "datalab/utils/_utils.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Miscellaneous simple utility functions.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import print_function\nfrom __future__ import unicode_literals\nfrom builtins import str\n\ntry:\n    import http.client as httplib\nexcept ImportError:\n    import httplib\n\nimport pytz\nimport subprocess\nimport socket\nimport traceback\nimport types\n\n\ndef print_exception_with_last_stack(e):\n  \"\"\" Print the call stack of the last exception plu sprint the passed exception.\n\n  Args:\n    e: the exception to print.\n  \"\"\"\n  traceback.print_exc()\n  print(str(e))\n\n\ndef get_item(env, name, default=None):\n  \"\"\" Get an item from a dictionary, handling nested lookups with dotted notation.\n\n  Args:\n    env: the environment (dictionary) to use to look up the name.\n    name: the name to look up, in dotted notation.\n    default: the value to return if the name if not found.\n\n  Returns:\n    The result of looking up the name, if found; else the default.\n  \"\"\"\n  # TODO: handle attributes\n  for key in name.split('.'):\n    if isinstance(env, dict) and key in env:\n      env = env[key]\n    elif isinstance(env, types.ModuleType) and key in env.__dict__:\n      env = env.__dict__[key]\n    else:\n      return default\n  return env\n\n\ndef compare_datetimes(d1, d2):\n  \"\"\" Compares two datetimes safely, whether they are timezone-naive or timezone-aware.\n\n  If either datetime is naive it is converted to an aware datetime assuming UTC.\n\n  Args:\n    d1: first datetime.\n    d2: second datetime.\n\n  Returns:\n    -1 if d1 < d2, 0 if they are the same, or +1 is d1 > d2.\n  \"\"\"\n  if d1.tzinfo is None or d1.tzinfo.utcoffset(d1) is None:\n    d1 = d1.replace(tzinfo=pytz.UTC)\n  if d2.tzinfo is None or d2.tzinfo.utcoffset(d2) is None:\n    d2 = d2.replace(tzinfo=pytz.UTC)\n  if d1 < d2:\n    return -1\n  elif d1 > d2:\n    return 1\n  return 0\n\n\ndef pick_unused_port():\n  \"\"\" get an unused port on the VM.\n\n  Returns:\n    An unused port.\n  \"\"\"\n  s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n  s.bind(('localhost', 0))\n  addr, port = s.getsockname()\n  s.close()\n  return port\n\n\ndef is_http_running_on(port):\n  \"\"\" Check if an http server runs on a given port.\n\n  Args:\n    The port to check.\n  Returns:\n    True if it is used by an http server. False otherwise.\n  \"\"\"\n  try:\n    conn = httplib.HTTPConnection('127.0.0.1:' + str(port))\n    conn.connect()\n    conn.close()\n    return True\n  except Exception:\n    return False\n\n\ndef gcs_copy_file(source, dest):\n  \"\"\" Copy file from source to destination. The paths can be GCS or local.\n\n  Args:\n    source: the source file path.\n    dest: the destination file path.\n  \"\"\"\n  subprocess.check_call(['gsutil', '-q', 'cp', source, dest])\n"
  },
  {
    "path": "datalab/utils/commands/__init__.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n# flake8: noqa\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\n\n# Support functions for magics and display help.\nfrom ._commands import CommandParser\nfrom ._html import Html, HtmlBuilder\nfrom ._utils import *\n\n# Magics\nfrom . import _chart\nfrom . import _chart_data\nfrom . import _csv\nfrom . import _extension\nfrom . import _job\nfrom . import _modules\n"
  },
  {
    "path": "datalab/utils/commands/_chart.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Google Cloud Platform library - Chart cell magic.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\n\ntry:\n  import IPython\n  import IPython.core.display\n  import IPython.core.magic\nexcept ImportError:\n  raise Exception('This module can only be loaded in ipython.')\n\nfrom . import _commands\nfrom . import _utils\n\n\n@IPython.core.magic.register_line_cell_magic\ndef chart(line, cell=None):\n  \"\"\" Generate charts with Google Charts. Use %chart --help for more details. \"\"\"\n  parser = _commands.CommandParser(prog='%%chart', description=\"\"\"\nGenerate an inline chart using Google Charts using the data in a Table, Query, dataframe, or list.\nNumerous types of charts are supported. Options for the charts can be specified in the cell body\nusing YAML or JSON.\n\"\"\")\n  for chart_type in ['annotation', 'area', 'bars', 'bubbles', 'calendar', 'candlestick', 'columns',\n                     'combo', 'gauge', 'geo', 'heatmap', 'histogram', 'line', 'map', 'org',\n                     'paged_table', 'pie', 'sankey', 'scatter', 'stepped_area', 'table',\n                     'timeline', 'treemap']:\n    subparser = parser.subcommand(chart_type, 'Generate a %s chart.' % chart_type)\n    subparser.add_argument('-f', '--fields',\n                           help='The field(s) to include in the chart')\n    subparser.add_argument('-d', '--data',\n                           help='The name of the variable referencing the Table or Query to chart',\n                           required=True)\n    subparser.set_defaults(chart=chart_type)\n\n  parser.set_defaults(func=_chart_cell)\n  return _utils.handle_magic_line(line, cell, parser)\n\n\ndef _chart_cell(args, cell):\n  source = args['data']\n  ipy = IPython.get_ipython()\n  chart_options = _utils.parse_config(cell, ipy.user_ns)\n  if chart_options is None:\n    chart_options = {}\n  elif not isinstance(chart_options, dict):\n    raise Exception(\"Could not parse chart options\")\n  chart_type = args['chart']\n  fields = args['fields'] if args['fields'] else '*'\n  return IPython.core.display.HTML(_utils.chart_html('gcharts', chart_type, source=source,\n                                                     chart_options=chart_options, fields=fields))\n"
  },
  {
    "path": "datalab/utils/commands/_chart_data.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Google Cloud Platform library - chart_data cell magic.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import print_function\nfrom __future__ import unicode_literals\n\ntry:\n  import IPython\n  import IPython.core.display\n  import IPython.core.magic\nexcept ImportError:\n  raise Exception('This module can only be loaded in ipython.')\n\nimport json\n\nimport datalab.data\nimport datalab.utils\n\nfrom . import _utils\n\n\n# Disable the magic here because another one with same name is available under\n# google.datalab namespace.\n# @IPython.core.magic.register_cell_magic\ndef _get_chart_data(line, cell_body=''):\n\n  refresh = 0\n  options = {}\n  try:\n    metadata = json.loads(cell_body) if cell_body else {}\n    source_index = metadata.get('source_index', None)\n    fields = metadata.get('fields', '*')\n    first_row = int(metadata.get('first', 0))\n    count = int(metadata.get('count', -1))\n\n    source_index = int(source_index)\n    if source_index >= len(_utils._data_sources):  # Can happen after e.g. kernel restart\n      # TODO(gram): get kernel restart events in charting.js and disable any refresh timers.\n      print('No source %d' % source_index)\n      return IPython.core.display.JSON({'data': {}})\n    source = _utils._data_sources[source_index]\n    schema = None\n\n    controls = metadata['controls'] if 'controls' in metadata else {}\n    data, _ = _utils.get_data(source, fields, controls, first_row, count, schema)\n  except Exception as e:\n    datalab.utils.print_exception_with_last_stack(e)\n    print('Failed with exception %s' % e)\n    data = {}\n\n  # TODO(gram): The old way - commented out below - has the advantage that it worked\n  # for datetimes, but it is strictly wrong. The correct way below may have issues if the\n  # chart has datetimes though so test this.\n  return IPython.core.display.JSON({'data': data, 'refresh_interval': refresh, 'options': options})\n  # return IPython.core.display.JSON(json.dumps({'data': data}, cls=datalab.utils.JSONEncoder))\n"
  },
  {
    "path": "datalab/utils/commands/_commands.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Implementation of command parsing and handling within magics.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import print_function\nfrom __future__ import unicode_literals\n\ntry:\n  import IPython\nexcept ImportError:\n  raise Exception('This module can only be loaded in ipython.')\n\nimport argparse\nimport shlex\n\n\nclass CommandParser(argparse.ArgumentParser):\n  \"\"\"An argument parser to parse commands in line/cell magic declarations. \"\"\"\n\n  def __init__(self, *args, **kwargs):\n    \"\"\"Initializes an instance of a CommandParser. \"\"\"\n    super(CommandParser, self).__init__(*args, **kwargs)\n    self._subcommands = None\n\n  @staticmethod\n  def create(name):\n    \"\"\"Creates a CommandParser for a specific magic. \"\"\"\n    return CommandParser(prog=name)\n\n  def exit(self, status=0, message=None):\n    \"\"\"Overridden exit method to stop parsing without calling sys.exit(). \"\"\"\n    raise Exception(message)\n\n  def format_usage(self):\n    \"\"\"Overridden usage generator to use the full help message. \"\"\"\n    return self.format_help()\n\n  @staticmethod\n  def create_args(line, namespace):\n    \"\"\" Expand any meta-variable references in the argument list. \"\"\"\n    args = []\n    # Using shlex.split handles quotes args and escape characters.\n    for arg in shlex.split(line):\n      if not arg:\n         continue\n      if arg[0] == '$':\n        var_name = arg[1:]\n        if var_name in namespace:\n          args.append((namespace[var_name]))\n        else:\n          raise Exception('Undefined variable referenced in command line: %s' % arg)\n      else:\n        args.append(arg)\n    return args\n\n  def parse(self, line, namespace=None):\n    \"\"\"Parses a line into a dictionary of arguments, expanding meta-variables from a namespace. \"\"\"\n    try:\n      if namespace is None:\n        ipy = IPython.get_ipython()\n        namespace = ipy.user_ns\n      args = CommandParser.create_args(line, namespace)\n      return self.parse_args(args)\n    except Exception as e:\n      print(str(e))\n      return None\n\n  def subcommand(self, name, help):\n    \"\"\"Creates a parser for a sub-command. \"\"\"\n    if self._subcommands is None:\n      self._subcommands = self.add_subparsers(help='commands')\n    return self._subcommands.add_parser(name, description=help, help=help)\n"
  },
  {
    "path": "datalab/utils/commands/_csv.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Implements CSV file exploration\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\n\n\ntry:\n  import IPython\n  import IPython.core.magic\n  import IPython.core.display\nexcept ImportError:\n  raise Exception('This module can only be loaded in ipython.')\n\nimport pandas as pd\n\nimport datalab.data\n\nfrom . import _commands\nfrom . import _utils\n\n\n@IPython.core.magic.register_line_cell_magic\ndef csv(line, cell=None):\n  parser = _commands.CommandParser.create('csv')\n\n  view_parser = parser.subcommand('view',\n                                  'Browse CSV files without providing a schema. ' +\n                                  'Each value is considered string type.')\n  view_parser.add_argument('-i', '--input',\n                           help='Path of the input CSV data', required=True)\n  view_parser.add_argument('-n', '--count',\n                           help='The number of lines to browse from head, default to 5.')\n  view_parser.add_argument('-P', '--profile', action='store_true',\n                           default=False, help='Generate an interactive profile of the data')\n  view_parser.set_defaults(func=_view)\n\n  return _utils.handle_magic_line(line, cell, parser)\n\n\ndef _view(args, cell):\n  csv = datalab.data.Csv(args['input'])\n  num_lines = int(args['count'] or 5)\n  headers = None\n  if cell:\n    ipy = IPython.get_ipython()\n    config = _utils.parse_config(cell, ipy.user_ns)\n    if 'columns' in config:\n      headers = [e.strip() for e in config['columns'].split(',')]\n  df = pd.DataFrame(csv.browse(num_lines, headers))\n  if args['profile']:\n    # TODO(gram): We need to generate a schema and type-convert the columns before this\n    # will be useful for CSV\n    return _utils.profile_df(df)\n  else:\n    return IPython.core.display.HTML(df.to_html(index=False))\n"
  },
  {
    "path": "datalab/utils/commands/_extension.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Google Cloud Platform library - Extension cell magic.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\n\ntry:\n  import IPython\n  import IPython.core.display\n  import IPython.core.magic\nexcept ImportError:\n  raise Exception('This module can only be loaded in ipython.')\n\nfrom . import _commands\nfrom . import _utils\n\n\n@IPython.core.magic.register_line_cell_magic\ndef extension(line, cell=None):\n  \"\"\" Load an extension. Use %extension --help for more details. \"\"\"\n  parser = _commands.CommandParser(prog='%extension', description=\"\"\"\nLoad an extension into Datalab. Currently only mathjax is supported.\n\"\"\")\n  subparser = parser.subcommand('mathjax', 'Enabled MathJaX support in Datalab.')\n  subparser.set_defaults(ext='mathjax')\n  parser.set_defaults(func=_extension)\n  return _utils.handle_magic_line(line, cell, parser)\n\n\ndef _extension(args, cell):\n  ext = args['ext']\n  if ext == 'mathjax':\n    # TODO: remove this with the next version update\n    # MathJax is now loaded by default for all notebooks\n    return\n  raise Exception('Unsupported extension %s' % ext)\n"
  },
  {
    "path": "datalab/utils/commands/_html.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Google Cloud Platform library - IPython HTML display Functionality.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom builtins import str\nfrom builtins import range\nfrom past.builtins import basestring\nfrom builtins import object\n\nimport time\n\n\nclass Html(object):\n  \"\"\"A helper to enable generating an HTML representation as display data in a notebook.\n\n  This object supports the combination of HTML markup and/or associated JavaScript.\n  \"\"\"\n\n  _div_id_counter = 0\n\n  @staticmethod\n  def next_id():\n    \"\"\" Return an ID containing a reproducible part (counter) and unique part (timestamp). \"\"\"\n    Html._div_id_counter += 1\n    return '%d_%d' % (Html._div_id_counter, int(round(time.time() * 100)))\n\n  def __init__(self, markup=None):\n    \"\"\"Initializes an instance of Html.\n    \"\"\"\n    self._id = Html.next_id()\n    Html._div_id_counter += 1\n    self._class_name = ''\n    self._markup = markup\n    self._dependencies = [('element!hh_%d' % self._id, 'dom')]\n    self._script = ''\n    self._class = None\n\n  def add_class(self, class_name):\n    \"\"\"Adds a CSS class to be generated on the output HTML.\n    \"\"\"\n    self._class = class_name\n\n  def add_dependency(self, path, name):\n    \"\"\"Adds a script dependency to be loaded before any script is executed.\n    \"\"\"\n    self._dependencies.append((path, name))\n\n  def add_script(self, script):\n    \"\"\"Adds JavaScript that should be included along-side the HTML.\n    \"\"\"\n    self._script = script\n\n  def _repr_html_(self):\n    \"\"\"Generates the HTML representation.\n    \"\"\"\n    parts = []\n    if self._class:\n      parts.append('<div id=\"hh_%s\" class=\"%s\">%s</div>' % (self._id, self._class, self._markup))\n    else:\n      parts.append('<div id=\"hh_%s\">%s</div>' % (self._id, self._markup))\n\n    if len(self._script) != 0:\n      parts.append('<script>')\n      parts.append('require([')\n      parts.append(','.join(['\"%s\"' % d[0] for d in self._dependencies]))\n      parts.append('], function(')\n      parts.append(','.join([d[1] for d in self._dependencies]))\n      parts.append(') {')\n      parts.append(self._script)\n      parts.append('});')\n      parts.append('</script>')\n\n    return ''.join(parts)\n\n\nclass HtmlBuilder(object):\n  \"\"\"A set of helpers to build HTML representations of objects.\n  \"\"\"\n\n  def __init__(self):\n    \"\"\"Initializes an instance of an HtmlBuilder.\n    \"\"\"\n    self._segments = []\n\n  def _render_objects(self, items, attributes=None, datatype='object'):\n    \"\"\"Renders an HTML table with the specified list of objects.\n\n    Args:\n      items: the iterable collection of objects to render.\n      attributes: the optional list of properties or keys to render.\n      datatype: the type of data; one of 'object' for Python objects, 'dict' for a list\n          of dictionaries, or 'chartdata' for Google chart data.\n    \"\"\"\n    if not items:\n      return\n\n    if datatype == 'chartdata':\n      if not attributes:\n        attributes = [items['cols'][i]['label'] for i in range(0, len(items['cols']))]\n      items = items['rows']\n      indices = {attributes[i]: i for i in range(0, len(attributes))}\n\n    num_segments = len(self._segments)\n    self._segments.append('<table>')\n\n    first = True\n    for o in items:\n      if first:\n        first = False\n        if datatype == 'dict' and not attributes:\n          attributes = list(o.keys())\n\n        if attributes is not None:\n          self._segments.append('<tr>')\n          for attr in attributes:\n            self._segments.append('<th>%s</th>' % attr)\n          self._segments.append('</tr>')\n\n      self._segments.append('<tr>')\n      if attributes is None:\n        self._segments.append('<td>%s</td>' % HtmlBuilder._format(o))\n      else:\n        for attr in attributes:\n          if datatype == 'dict':\n            self._segments.append('<td>%s</td>' % HtmlBuilder._format(o.get(attr, None), nbsp=True))\n          elif datatype == 'chartdata':\n            self._segments.append('<td>%s</td>' % HtmlBuilder._format(o['c'][indices[attr]]['v'],\n                                                                      nbsp=True))\n          else:\n            self._segments.append('<td>%s</td>' % HtmlBuilder._format(o.__getattribute__(attr),\n                                                                      nbsp=True))\n      self._segments.append('</tr>')\n\n    self._segments.append('</table>')\n    if first:\n      # The table was empty; drop it from the segments.\n      self._segments = self._segments[:num_segments]\n\n  def _render_text(self, text, preformatted=False):\n    \"\"\"Renders an HTML formatted text block with the specified text.\n\n    Args:\n      text: the text to render\n      preformatted: whether the text should be rendered as preformatted\n    \"\"\"\n    tag = 'pre' if preformatted else 'div'\n    self._segments.append('<%s>%s</%s>' % (tag, HtmlBuilder._format(text), tag))\n\n  def _render_list(self, items, empty='<pre>&lt;empty&gt;</pre>'):\n    \"\"\"Renders an HTML list with the specified list of strings.\n\n    Args:\n      items: the iterable collection of objects to render.\n      empty: what to render if the list is None or empty.\n    \"\"\"\n    if not items or len(items) == 0:\n      self._segments.append(empty)\n      return\n    self._segments.append('<ul>')\n    for o in items:\n      self._segments.append('<li>')\n      self._segments.append(str(o))\n      self._segments.append('</li>')\n    self._segments.append('</ul>')\n\n  def _to_html(self):\n    \"\"\"Returns the HTML that has been rendered.\n\n    Returns:\n      The HTML string that has been built.\n    \"\"\"\n    return ''.join(self._segments)\n\n  @staticmethod\n  def _format(value, nbsp=False):\n    if value is None:\n      return '&nbsp;' if nbsp else ''\n    elif isinstance(value, basestring):\n      return value.replace('&', '&amp;').replace('<', '&lt;').replace('>', '&gt;')\n    else:\n      return str(value)\n\n  @staticmethod\n  def render_text(text, preformatted=False):\n    \"\"\"Renders an HTML formatted text block with the specified text.\n\n    Args:\n      text: the text to render\n      preformatted: whether the text should be rendered as preformatted\n    Returns:\n      The formatted HTML.\n    \"\"\"\n    builder = HtmlBuilder()\n    builder._render_text(text, preformatted=preformatted)\n    return builder._to_html()\n\n  @staticmethod\n  def render_table(data, headers=None):\n    \"\"\" Return a dictionary list formatted as a HTML table.\n\n    Args:\n      data: a list of dictionaries, one per row.\n      headers: the keys in the dictionary to use as table columns, in order.\n    \"\"\"\n    builder = HtmlBuilder()\n    builder._render_objects(data, headers, datatype='dict')\n    return builder._to_html()\n\n  @staticmethod\n  def render_chart_data(data):\n    \"\"\" Return a dictionary list formatted as a HTML table.\n\n    Args:\n      data: data in the form consumed by Google Charts.\n    \"\"\"\n    builder = HtmlBuilder()\n    builder._render_objects(data, datatype='chartdata')\n    return builder._to_html()\n\n  @staticmethod\n  def render_list(data):\n    \"\"\" Return a list formatted as a HTML list.\n\n    Args:\n      data: a list of strings.\n    \"\"\"\n    builder = HtmlBuilder()\n    builder._render_list(data)\n    return builder._to_html()\n"
  },
  {
    "path": "datalab/utils/commands/_job.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Implements job view\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom builtins import str\n\n\ntry:\n  import IPython\n  import IPython.core.magic\n  import IPython.core.display\nexcept ImportError:\n  raise Exception('This module can only be loaded in ipython.')\n\nimport datalab.utils\n\nfrom . import _html\n\n\n_local_jobs = {}\n\n\ndef html_job_status(job_name, job_type, refresh_interval, html_on_running, html_on_success):\n  \"\"\"create html representation of status of a job (long running operation).\n\n  Args:\n    job_name: the full name of the job.\n    job_type: type of job. Can be 'local' or 'cloud'.\n    refresh_interval: how often should the client refresh status.\n    html_on_running: additional html that the job view needs to include on job running.\n    html_on_success: additional html that the job view needs to include on job success.\n  \"\"\"\n  _HTML_TEMPLATE = \"\"\"\n    <div class=\"jobstatus\" id=\"%s\">\n    </div>\n    <script>\n      require(['datalab/job', 'datalab/element!%s', 'base/js/events',\n          'datalab/style!/nbextensions/datalab/job.css'],\n        function(job, dom, events) {\n          job.render(dom, events, '%s', '%s', %s, '%s', '%s');\n        }\n      );\n    </script>\"\"\"\n  div_id = _html.Html.next_id()\n  return IPython.core.display.HTML(_HTML_TEMPLATE % (div_id, div_id, job_name, job_type,\n                                   refresh_interval, html_on_running, html_on_success))\n\n\n@IPython.core.magic.register_line_magic\ndef _get_job_status(line):\n  \"\"\"magic used as an endpoint for client to get job status.\n\n       %_get_job_status <name>\n\n  Returns:\n    A JSON object of the job status.\n  \"\"\"\n  try:\n    args = line.strip().split()\n    job_name = args[0]\n\n    job = None\n    if job_name in _local_jobs:\n      job = _local_jobs[job_name]\n    else:\n      raise Exception('invalid job %s' % job_name)\n\n    if job is not None:\n      error = '' if job.fatal_error is None else str(job.fatal_error)\n      data = {'exists': True, 'done': job.is_complete, 'error': error}\n    else:\n      data = {'exists': False}\n\n  except Exception as e:\n    datalab.utils.print_exception_with_last_stack(e)\n    data = {'done': True, 'error': str(e)}\n\n  return IPython.core.display.JSON(data)\n"
  },
  {
    "path": "datalab/utils/commands/_modules.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Implementation of various module magics\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\n\ntry:\n  import IPython\n  import IPython.core.magic\nexcept ImportError:\n  raise Exception('This module can only be loaded in ipython.')\n\nimport sys\nimport types\n\nfrom . import _commands\nfrom . import _utils\n\n\n@IPython.core.magic.register_line_cell_magic\ndef pymodule(line, cell=None):\n  \"\"\"Creates and subsequently auto-imports a python module.\n  \"\"\"\n  parser = _commands.CommandParser.create('pymodule')\n  parser.add_argument('-n', '--name',\n                      help='the name of the python module to create and import')\n  parser.set_defaults(func=_pymodule_cell)\n  return _utils.handle_magic_line(line, cell, parser)\n\n\ndef _pymodule_cell(args, cell):\n  if cell is None:\n      raise Exception('The code for the module must be included')\n\n  name = args['name']\n  module = _create_python_module(name, cell)\n\n  # Automatically import the newly created module by assigning it to a variable\n  # named the same name as the module name.\n  ipy = IPython.get_ipython()\n  ipy.push({name: module})\n\n\ndef _create_python_module(name, code):\n  # By convention the module is associated with a file name matching the module name\n  module = types.ModuleType(str(name))\n  module.__file__ = name\n  module.__name__ = name\n\n  exec(code, module.__dict__)\n\n  # Hold on to the module if the code executed successfully\n  sys.modules[name] = module\n  return module\n"
  },
  {
    "path": "datalab/utils/commands/_utils.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Utility functions.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import unicode_literals\nfrom builtins import str\nfrom past.builtins import basestring\n\ntry:\n  import IPython\n  import IPython.core.display\nexcept ImportError:\n  raise Exception('This module can only be loaded in ipython.')\n\nimport json\nimport pandas\ntry:\n  # Pandas profiling is not needed for build/test but will be in the container.\n  import pandas_profiling\nexcept ImportError:\n  pass\nimport sys\nimport types\nimport yaml\n\nimport datalab.data\nimport datalab.bigquery\nimport datalab.storage\nimport datalab.utils\nimport google.datalab.bigquery\nimport google.datalab.utils\n\nfrom . import _html\n\n\ndef notebook_environment():\n  \"\"\" Get the IPython user namespace. \"\"\"\n  ipy = IPython.get_ipython()\n  return ipy.user_ns\n\n\ndef get_notebook_item(name):\n  \"\"\" Get an item from the IPython environment. \"\"\"\n  env = notebook_environment()\n  return datalab.utils.get_item(env, name)\n\n\ndef render_list(data):\n  return IPython.core.display.HTML(_html.HtmlBuilder.render_list(data))\n\n\ndef render_dictionary(data, headers=None):\n  \"\"\" Return a dictionary list formatted as a HTML table.\n\n  Args:\n    data: the dictionary list\n    headers: the keys in the dictionary to use as table columns, in order.\n  \"\"\"\n  return IPython.core.display.HTML(_html.HtmlBuilder.render_table(data, headers))\n\n\ndef render_text(text, preformatted=False):\n  \"\"\" Return text formatted as a HTML\n\n  Args:\n    text: the text to render\n    preformatted: whether the text should be rendered as preformatted\n  \"\"\"\n  return IPython.core.display.HTML(_html.HtmlBuilder.render_text(text, preformatted))\n\n\ndef get_field_list(fields, schema):\n  \"\"\" Convert a field list spec into a real list of field names.\n\n      For tables, we return only the top-level non-RECORD fields as Google charts\n      can't handle nested data.\n  \"\"\"\n  # If the fields weren't supplied get them from the schema.\n  if isinstance(fields, list):\n    return fields\n  if isinstance(fields, basestring) and fields != '*':\n    return fields.split(',')\n  if not schema:\n    return []\n  return [f['name'] for f in schema._bq_schema if f['type'] != 'RECORD']\n\n\ndef _get_cols(fields, schema):\n  \"\"\" Get column metadata for Google Charts based on field list and schema. \"\"\"\n  typemap = {\n    'STRING': 'string',\n    'INT64': 'number',\n    'INTEGER': 'number',\n    'FLOAT': 'number',\n    'FLOAT64': 'number',\n    'BOOL': 'boolean',\n    'BOOLEAN': 'boolean',\n    'DATE': 'date',\n    'TIME': 'timeofday',\n    'DATETIME': 'datetime',\n    'TIMESTAMP': 'datetime'\n  }\n  cols = []\n  for col in fields:\n    if schema:\n      f = schema[col]\n      t = 'string' if f.mode == 'REPEATED' else typemap.get(f.data_type, 'string')\n      cols.append({'id': f.name, 'label': f.name, 'type': t})\n    else:\n      # This will only happen if we had no rows to infer a schema from, so the type\n      # is not really important, except that GCharts will choke if we pass such a schema\n      # to a chart if it is string x string so we default to number.\n      cols.append({'id': col, 'label': col, 'type': 'number'})\n  return cols\n\n\ndef _get_data_from_empty_list(source, fields='*', first_row=0, count=-1, schema=None):\n  \"\"\" Helper function for _get_data that handles empty lists. \"\"\"\n  fields = get_field_list(fields, schema)\n  return {'cols': _get_cols(fields, schema), 'rows': []}, 0\n\n\ndef _get_data_from_list_of_dicts(source, fields='*', first_row=0, count=-1, schema=None):\n  \"\"\" Helper function for _get_data that handles lists of dicts. \"\"\"\n  if schema is None:\n    schema = datalab.bigquery.Schema.from_data(source)\n  fields = get_field_list(fields, schema)\n  gen = source[first_row:first_row + count] if count >= 0 else source\n  rows = [{'c': [{'v': row[c]} if c in row else {} for c in fields]} for row in gen]\n  return {'cols': _get_cols(fields, schema), 'rows': rows}, len(source)\n\n\ndef _get_data_from_list_of_lists(source, fields='*', first_row=0, count=-1, schema=None):\n  \"\"\" Helper function for _get_data that handles lists of lists. \"\"\"\n  if schema is None:\n    schema = datalab.bigquery.Schema.from_data(source)\n  fields = get_field_list(fields, schema)\n  gen = source[first_row:first_row + count] if count >= 0 else source\n  cols = [schema.find(name) for name in fields]\n  rows = [{'c': [{'v': row[i]} for i in cols]} for row in gen]\n  return {'cols': _get_cols(fields, schema), 'rows': rows}, len(source)\n\n\ndef _get_data_from_dataframe(source, fields='*', first_row=0, count=-1, schema=None):\n  \"\"\" Helper function for _get_data that handles Pandas DataFrames. \"\"\"\n  if schema is None:\n    schema = datalab.bigquery.Schema.from_data(source)\n  fields = get_field_list(fields, schema)\n  rows = []\n  if count < 0:\n    count = len(source.index)\n  df_slice = source.reset_index(drop=True)[first_row:first_row + count]\n  for index, data_frame_row in df_slice.iterrows():\n    row = data_frame_row.to_dict()\n    for key in list(row.keys()):\n      val = row[key]\n      if isinstance(val, pandas.Timestamp):\n        row[key] = val.to_pydatetime()\n\n    rows.append({'c': [{'v': row[c]} if c in row else {} for c in fields]})\n  cols = _get_cols(fields, schema)\n  return {'cols': cols, 'rows': rows}, len(source)\n\n\ndef _get_data_from_table(source, fields='*', first_row=0, count=-1, schema=None):\n  \"\"\" Helper function for _get_data that handles BQ Tables. \"\"\"\n  if not source.exists():\n    return _get_data_from_empty_list(source, fields, first_row, count)\n  if schema is None:\n    schema = source.schema\n  fields = get_field_list(fields, schema)\n  gen = source.range(first_row, count) if count >= 0 else source\n  rows = [{'c': [{'v': row[c]} if c in row else {} for c in fields]} for row in gen]\n  return {'cols': _get_cols(fields, schema), 'rows': rows}, source.length\n\n\ndef get_data(source, fields='*', env=None, first_row=0, count=-1, schema=None):\n  \"\"\" A utility function to get a subset of data from a Table, Query, Pandas dataframe or List.\n\n  Args:\n    source: the source of the data. Can be a Table, Pandas DataFrame, List of dictionaries or\n        lists, or a string, in which case it is expected to be the name of a table in BQ.\n    fields: a list of fields that we want to return as a list of strings, comma-separated string,\n        or '*' for all.\n    env: if the data source is a Query module, this is the set of variable overrides for\n        parameterizing the Query.\n    first_row: the index of the first row to return; default 0. Onl;y used if count is non-negative.\n    count: the number or rows to return. If negative (the default), return all rows.\n    schema: the schema of the data. Optional; if supplied this can be used to help do type-coercion.\n\n  Returns:\n    A tuple consisting of a dictionary and a count; the dictionary has two entries: 'cols'\n    which is a list of column metadata entries for Google Charts, and 'rows' which is a list of\n    lists of values. The count is the total number of rows in the source (independent of the\n    first_row/count parameters).\n\n  Raises:\n    Exception if the request could not be fulfilled.\n  \"\"\"\n\n  ipy = IPython.get_ipython()\n  if env is None:\n    env = {}\n  env.update(ipy.user_ns)\n  if isinstance(source, basestring):\n    source = datalab.utils.get_item(ipy.user_ns, source, source)\n    if isinstance(source, basestring):\n      source = datalab.bigquery.Table(source)\n\n  if isinstance(source, types.ModuleType) or isinstance(source, datalab.data.SqlStatement):\n    source = datalab.bigquery.Query(source, values=env)\n\n  if isinstance(source, list):\n    if len(source) == 0:\n      return _get_data_from_empty_list(source, fields, first_row, count, schema)\n    elif isinstance(source[0], dict):\n      return _get_data_from_list_of_dicts(source, fields, first_row, count, schema)\n    elif isinstance(source[0], list):\n      return _get_data_from_list_of_lists(source, fields, first_row, count, schema)\n    else:\n      raise Exception(\"To get tabular data from a list it must contain dictionaries or lists.\")\n  elif isinstance(source, pandas.DataFrame):\n    return _get_data_from_dataframe(source, fields, first_row, count, schema)\n  elif (isinstance(source, google.datalab.bigquery.Query) or\n        isinstance(source, google.datalab.bigquery.Table)):\n    return google.datalab.utils.commands._utils.get_data(\n        source, fields, env, first_row, count, schema)\n  elif isinstance(source, datalab.bigquery.Query):\n    return _get_data_from_table(source.results(), fields, first_row, count, schema)\n  elif isinstance(source, datalab.bigquery.Table):\n    return _get_data_from_table(source, fields, first_row, count, schema)\n  else:\n    raise Exception(\"Cannot chart %s; unsupported object type\" % source)\n\n\ndef handle_magic_line(line, cell, parser, namespace=None):\n  \"\"\" Helper function for handling magic command lines given a parser with handlers set. \"\"\"\n  args = parser.parse(line, namespace)\n  if args:\n    try:\n      return args.func(vars(args), cell)\n    except Exception as e:\n      sys.stderr.write(str(e))\n      sys.stderr.write('\\n')\n      sys.stderr.flush()\n  return None\n\n\ndef expand_var(v, env):\n  \"\"\" If v is a variable reference (for example: '$myvar'), replace it using the supplied\n      env dictionary.\n\n  Args:\n    v: the variable to replace if needed.\n    env: user supplied dictionary.\n\n  Raises:\n    Exception if v is a variable reference but it is not found in env.\n  \"\"\"\n  if len(v) == 0:\n    return v\n  # Using len() and v[0] instead of startswith makes this Unicode-safe.\n  if v[0] == '$':\n    v = v[1:]\n    if len(v) and v[0] != '$':\n      if v in env:\n        v = env[v]\n      else:\n        raise Exception('Cannot expand variable $%s' % v)\n  return v\n\n\ndef replace_vars(config, env):\n  \"\"\" Replace variable references in config using the supplied env dictionary.\n\n  Args:\n    config: the config to parse. Can be a tuple, list or dict.\n    env: user supplied dictionary.\n\n  Raises:\n    Exception if any variable references are not found in env.\n  \"\"\"\n  if isinstance(config, dict):\n    for k, v in list(config.items()):\n      if isinstance(v, dict) or isinstance(v, list) or isinstance(v, tuple):\n        replace_vars(v, env)\n      elif isinstance(v, basestring):\n        config[k] = expand_var(v, env)\n  elif isinstance(config, list):\n    for i, v in enumerate(config):\n      if isinstance(v, dict) or isinstance(v, list) or isinstance(v, tuple):\n        replace_vars(v, env)\n      elif isinstance(v, basestring):\n        config[i] = expand_var(v, env)\n  elif isinstance(config, tuple):\n    # TODO(gram): figure out how to handle these if the tuple elements are scalar\n    for v in config:\n      if isinstance(v, dict) or isinstance(v, list) or isinstance(v, tuple):\n        replace_vars(v, env)\n\n\ndef parse_config(config, env, as_dict=True):\n  \"\"\" Parse a config from a magic cell body. This could be JSON or YAML. We turn it into\n      a Python dictionary then recursively replace any variable references using the supplied\n      env dictionary.\n  \"\"\"\n\n  if config is None:\n    return None\n  stripped = config.strip()\n  if len(stripped) == 0:\n    config = {}\n  elif stripped[0] == '{':\n    config = json.loads(config)\n  else:\n    config = yaml.load(config)\n  if as_dict:\n    config = dict(config)\n\n  # Now we need to walk the config dictionary recursively replacing any '$name' vars.\n  replace_vars(config, env)\n  return config\n\n\ndef validate_config(config, required_keys, optional_keys=None):\n  \"\"\" Validate a config dictionary to make sure it includes all required keys\n      and does not include any unexpected keys.\n\n  Args:\n    config: the config to validate.\n    required_keys: the names of the keys that the config must have.\n    optional_keys: the names of the keys that the config can have.\n\n  Raises:\n    Exception if the config is not a dict or invalid.\n  \"\"\"\n  if optional_keys is None:\n    optional_keys = []\n  if not isinstance(config, dict):\n    raise Exception('config is not dict type')\n  invalid_keys = set(config) - set(required_keys + optional_keys)\n  if len(invalid_keys) > 0:\n    raise Exception('Invalid config with unexpected keys \"%s\"' % ', '.join(e for e in invalid_keys))\n  missing_keys = set(required_keys) - set(config)\n  if len(missing_keys) > 0:\n    raise Exception('Invalid config with missing keys \"%s\"' % ', '.join(missing_keys))\n\n\ndef validate_config_must_have(config, required_keys):\n  \"\"\" Validate a config dictionary to make sure it has all of the specified keys\n\n  Args:\n    config: the config to validate.\n    required_keys: the list of possible keys that config must include.\n\n  Raises:\n    Exception if the config does not have any of them.\n  \"\"\"\n  missing_keys = set(required_keys) - set(config)\n  if len(missing_keys) > 0:\n    raise Exception('Invalid config with missing keys \"%s\"' % ', '.join(missing_keys))\n\n\ndef validate_config_has_one_of(config, one_of_keys):\n  \"\"\" Validate a config dictionary to make sure it has one and only one\n      key in one_of_keys.\n\n  Args:\n    config: the config to validate.\n    one_of_keys: the list of possible keys that config can have one and only one.\n\n  Raises:\n    Exception if the config does not have any of them, or multiple of them.\n  \"\"\"\n  intersection = set(config).intersection(one_of_keys)\n  if len(intersection) > 1:\n    raise Exception('Only one of the values in \"%s\" is needed' % ', '.join(intersection))\n  if len(intersection) == 0:\n    raise Exception('One of the values in \"%s\" is needed' % ', '.join(one_of_keys))\n\n\ndef validate_config_value(value, possible_values):\n  \"\"\" Validate a config value to make sure it is one of the possible values.\n\n  Args:\n    value: the config value to validate.\n    possible_values: the possible values the value can be\n\n  Raises:\n    Exception if the value is not one of possible values.\n  \"\"\"\n  if value not in possible_values:\n    raise Exception('Invalid config value \"%s\". Possible values are '\n                    '%s' % (value, ', '.join(e for e in possible_values)))\n\n\n# For chart and table HTML viewers, we use a list of table names and reference\n# instead the indices in the HTML, so as not to include things like projectID, etc,\n# in the HTML.\n\n_data_sources = []\n\n\ndef get_data_source_index(name):\n  if name not in _data_sources:\n    _data_sources.append(name)\n  return _data_sources.index(name)\n\n\ndef validate_gcs_path(path, require_object):\n  \"\"\" Check whether a given path is a valid GCS path.\n\n  Args:\n    path: the config to check.\n    require_object: if True, the path has to be an object path but not bucket path.\n\n  Raises:\n    Exception if the path is invalid\n  \"\"\"\n  bucket, key = datalab.storage._bucket.parse_name(path)\n  if bucket is None:\n    raise Exception('Invalid GCS path \"%s\"' % path)\n  if require_object and key is None:\n    raise Exception('It appears the GCS path \"%s\" is a bucket path but not an object path' % path)\n\n\ndef parse_control_options(controls, variable_defaults=None):\n  \"\"\" Parse a set of control options.\n\n  Args:\n    controls: The dictionary of control options.\n    variable_defaults: If the controls are for a Query with variables, then this is the\n        default variable values defined in the Query module. The options in the controls\n        parameter can override these but if a variable has no 'value' property then we\n        fall back to these.\n\n  Returns:\n    - the HTML for the controls.\n    - the default values for the controls as a dict.\n    - the list of DIV IDs of the controls.\n\n  \"\"\"\n  controls_html = ''\n  control_defaults = {}\n  control_ids = []\n  div_id = _html.Html.next_id()\n  if variable_defaults is None:\n    variable_defaults = {}\n  for varname, control in list(controls.items()):\n    label = control.get('label', varname)\n    control_id = div_id + '__' + varname\n    control_ids.append(control_id)\n    value = control.get('value', variable_defaults.get(varname, None))\n    # The user should usually specify the type but we will default to 'textbox' for strings\n    # and 'set' for lists.\n    if isinstance(value, basestring):\n      type = 'textbox'\n    elif isinstance(value, list):\n      type = 'set'\n    else:\n      type = None\n    type = control.get('type', type)\n\n    if type == 'picker':\n      choices = control.get('choices', value)\n      if not isinstance(choices, list) or len(choices) == 0:\n        raise Exception('picker control must specify a nonempty set of choices')\n      if value is None:\n        value = choices[0]\n      choices_html = ''\n      for i, choice in enumerate(choices):\n        choices_html += \"<option value=\\\"%s\\\" %s>%s</option>\" % \\\n                        (choice, (\"selected=\\\"selected\\\"\" if choice == value else ''), choice)\n      control_html = \"{label}<select disabled id=\\\"{id}\\\">{choices}</select>\" \\\n          .format(label=label, id=control_id, choices=choices_html)\n    elif type == 'set':  # Multi-picker; implemented as checkboxes.\n      # TODO(gram): consider using \"name\" property of the control to group checkboxes. That\n      # way we can save the code of constructing and parsing control Ids with sequential\n      #  numbers in it. Multiple checkboxes can share the same name.\n      choices = control.get('choices', value)\n      if not isinstance(choices, list) or len(choices) == 0:\n        raise Exception('set control must specify a nonempty set of choices')\n      if value is None:\n        value = choices\n      choices_html = ''\n      control_ids[-1] = '%s:%d' % (control_id, len(choices))  # replace ID to include count.\n      for i, choice in enumerate(choices):\n        checked = choice in value\n        choice_id = '%s:%d' % (control_id, i)\n        # TODO(gram): we may want a 'Submit/Refresh button as we may not want to rerun\n        # query on each checkbox change.\n        choices_html += \"\"\"\n          <div>\n            <label>\n              <input type=\"checkbox\" id=\"{id}\" value=\"{choice}\" {checked} disabled>\n              {choice}\n            </label>\n          </div>\n        \"\"\".format(id=choice_id, choice=choice, checked=\"checked\" if checked else '')\n      control_html = \"{label}<div>{choices}</div>\".format(label=label, choices=choices_html)\n    elif type == 'checkbox':\n      control_html = \"\"\"\n            <label>\n              <input type=\"checkbox\" id=\"{id}\" {checked} disabled>\n              {label}\n            </label>\n        \"\"\".format(label=label, id=control_id, checked=\"checked\" if value else '')\n    elif type == 'slider':\n      min_ = control.get('min', None)\n      max_ = control.get('max', None)\n      if min_ is None or max_ is None:\n        raise Exception('slider control must specify a min and max value')\n      if max_ <= min_:\n        raise Exception('slider control must specify a min value less than max value')\n      step = control.get('step', 1 if isinstance(min_, int) and isinstance(max_, int)\n                         else (float(max_ - min_) / 10.0))\n      if value is None:\n        value = min_\n      control_html = \"\"\"\n        {label}\n        <input type=\"text\" class=\"gchart-slider_value\" id=\"{id}_value\" value=\"{value}\" disabled/>\n        <input type=\"range\" class=\"gchart-slider\" id=\"{id}\" min=\"{min}\" max=\"{max}\" step=\"{step}\"\n            value=\"{value}\" disabled/>\n      \"\"\".format(label=label, id=control_id, value=value, min=min_, max=max_, step=step)\n    elif type == 'textbox':\n      if value is None:\n        value = ''\n      control_html = \"{label}<input type=\\\"text\\\" value=\\\"{value}\\\" id=\\\"{id}\\\" disabled/>\" \\\n          .format(label=label, value=value, id=control_id)\n    else:\n      raise Exception(\n          'Unknown control type %s (expected picker, slider, checkbox, textbox or set)' % type)\n\n    control_defaults[varname] = value\n    controls_html += \"<div class=\\\"gchart-control\\\">{control}</div>\\n\" \\\n        .format(control=control_html)\n\n  controls_html = \"<div class=\\\"gchart-controls\\\">{controls}</div>\".format(controls=controls_html)\n  return controls_html, control_defaults, control_ids\n\n\ndef chart_html(driver_name, chart_type, source, chart_options=None, fields='*', refresh_interval=0,\n               refresh_data=None, control_defaults=None, control_ids=None, schema=None):\n  \"\"\" Return HTML for a chart.\n\n  Args:\n    driver_name: the name of the chart driver. Currently we support 'plotly' or 'gcharts'.\n    chart_type: string specifying type of chart.\n    source: the data source for the chart. Can be actual data (e.g. list) or the name of\n        a data source (e.g. the name of a query module).\n    chart_options: a dictionary of options for the chart. Can contain a 'controls' entry\n        specifying controls. Other entries are passed as JSON to Google Charts.\n    fields: the fields to chart. Can be '*' for all fields (only sensible if the columns are\n        ordered; e.g. a Query or list of lists, but not a list of dictionaries); otherwise a\n        string containing a comma-separated list of field names.\n    refresh_interval: a time in seconds after which the chart data will be refreshed. 0 if the\n        chart should not be refreshed (i.e. the data is static).\n    refresh_data: if the source is a list or other raw data, this is a YAML string containing\n        metadata needed to support calls to refresh (get_chart_data).\n    control_defaults: the default variable values for controls that are shared across charts\n        including this one.\n    control_ids: the DIV IDs for controls that are shared across charts including this one.\n    schema: an optional schema for the data; if not supplied one will be inferred.\n\n  Returns:\n    A string containing the HTML for the chart.\n\n  \"\"\"\n  div_id = _html.Html.next_id()\n  controls_html = ''\n  if control_defaults is None:\n    control_defaults = {}\n  if control_ids is None:\n    control_ids = []\n  if chart_options is not None and 'variables' in chart_options:\n    controls = chart_options['variables']\n    del chart_options['variables']  # Just to make sure GCharts doesn't see them.\n    try:\n      item = get_notebook_item(source)\n      _, variable_defaults = datalab.data.SqlModule.get_sql_statement_with_environment(item, '')\n    except Exception:\n      variable_defaults = {}\n    controls_html, defaults, ids = parse_control_options(controls, variable_defaults)\n    # We augment what we are passed so that in principle we can have controls that are\n    # shared by charts as well as controls that are specific to a chart.\n    control_defaults.update(defaults)\n    control_ids.extend(ids),\n\n  _HTML_TEMPLATE = \"\"\"\n    <div class=\"bqgc-container\">\n      {controls}\n      <div class=\"bqgc {extra_class}\" id=\"{id}\">\n      </div>\n    </div>\n    <script src=\"/static/components/requirejs/require.js\"></script>\n    <script>\n\n      require.config({{\n        paths: {{\n          base: '/static/base',\n          d3: '//cdnjs.cloudflare.com/ajax/libs/d3/3.4.13/d3',\n          plotly: 'https://cdn.plot.ly/plotly-1.5.1.min.js?noext',\n          jquery: '//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min'\n        }},\n        map: {{\n          '*': {{\n            datalab: 'nbextensions/gcpdatalab'\n          }}\n        }},\n        shim: {{\n          plotly: {{\n            deps: ['d3', 'jquery'],\n            exports: 'plotly'\n          }}\n        }}\n      }});\n\n      require(['datalab/charting',\n               'datalab/element!{id}',\n               'base/js/events',\n               'datalab/style!/nbextensions/gcpdatalab/charting.css'\n              ],\n        function(charts, dom, events) {{\n          charts.render(\n              '{driver}',\n              dom,\n              events,\n              '{chart_type}',\n              {control_ids},\n              {data},\n              {options},\n              {refresh_data},\n              {refresh_interval},\n              {total_rows});\n          }}\n        );\n    </script>\n  \"\"\"\n  count = 25 if chart_type == 'paged_table' else -1\n  data, total_count = get_data(source, fields, control_defaults, 0, count, schema)\n  if refresh_data is None:\n    if isinstance(source, basestring):\n      source_index = get_data_source_index(source)\n      refresh_data = {'source_index': source_index, 'name': source_index}\n    else:\n      refresh_data = {'name': 'raw data'}\n  refresh_data['fields'] = fields\n\n  # TODO(gram): check if we need to augment env with user_ns\n  return _HTML_TEMPLATE \\\n      .format(driver=driver_name,\n              controls=controls_html,\n              id=div_id,\n              chart_type=chart_type,\n              extra_class=\" bqgc-controlled\" if len(controls_html) else '',\n              data=json.dumps(data, cls=datalab.utils.JSONEncoder),\n              options=json.dumps(chart_options, cls=datalab.utils.JSONEncoder),\n              refresh_data=json.dumps(refresh_data, cls=datalab.utils.JSONEncoder),\n              refresh_interval=refresh_interval,\n              control_ids=str(control_ids),\n              total_rows=total_count)\n\n\ndef profile_df(df):\n  \"\"\" Generate a profile of data in a dataframe.\n\n  Args:\n    df: the Pandas dataframe.\n  \"\"\"\n  # The bootstrap CSS messes up the Datalab display so we tweak it to not have an effect.\n  # TODO(gram): strip it out rather than this kludge.\n  return IPython.core.display.HTML(\n      pandas_profiling.ProfileReport(df).html.replace('bootstrap', 'nonexistent'))\n"
  },
  {
    "path": "docs/.nojekyll",
    "content": ""
  },
  {
    "path": "docs/Makefile",
    "content": "# Makefile for Sphinx documentation\n#\n\n# You can set these variables from the command line.\nSPHINXOPTS    =\nSPHINXBUILD   = sphinx-build\nPAPER         =\n\n# The buildir is out of the main repo. It is the location of the gh-pages\n# branch of Datalab that contains none of the source but just the HTML\n# output from Sphinx. This is to support GitHub Pages documentation.\nBUILDDIR      = ../../datalab-docs\n\n# User-friendly check for sphinx-build\nifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)\n$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)\nendif\n\n# Internal variables.\nPAPEROPT_a4     = -D latex_paper_size=a4\nPAPEROPT_letter = -D latex_paper_size=letter\nALLSPHINXOPTS   = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .\n# the i18n builder cannot share the environment and doctrees with the others\nI18NSPHINXOPTS  = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .\n\n.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest coverage gettext\n\nhelp:\n\t@echo \"Please use \\`make <target>' where <target> is one of\"\n\t@echo \"  html       to make standalone HTML files\"\n\t@echo \"  dirhtml    to make HTML files named index.html in directories\"\n\t@echo \"  singlehtml to make a single large HTML file\"\n\t@echo \"  pickle     to make pickle files\"\n\t@echo \"  json       to make JSON files\"\n\t@echo \"  htmlhelp   to make HTML files and a HTML help project\"\n\t@echo \"  qthelp     to make HTML files and a qthelp project\"\n\t@echo \"  applehelp  to make an Apple Help Book\"\n\t@echo \"  devhelp    to make HTML files and a Devhelp project\"\n\t@echo \"  epub       to make an epub\"\n\t@echo \"  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter\"\n\t@echo \"  latexpdf   to make LaTeX files and run them through pdflatex\"\n\t@echo \"  latexpdfja to make LaTeX files and run them through platex/dvipdfmx\"\n\t@echo \"  text       to make text files\"\n\t@echo \"  man        to make manual pages\"\n\t@echo \"  texinfo    to make Texinfo files\"\n\t@echo \"  info       to make Texinfo files and run them through makeinfo\"\n\t@echo \"  gettext    to make PO message catalogs\"\n\t@echo \"  changes    to make an overview of all changed/added/deprecated items\"\n\t@echo \"  xml        to make Docutils-native XML files\"\n\t@echo \"  pseudoxml  to make pseudoxml-XML files for display purposes\"\n\t@echo \"  linkcheck  to check all external links for integrity\"\n\t@echo \"  doctest    to run all doctests embedded in the documentation (if enabled)\"\n\t@echo \"  coverage   to run coverage check of the documentation (if enabled)\"\n\nclean:\n\trm -rf $(BUILDDIR)/*\n\npre-build:\n\t@echo \"Generate reST for magic commands:\"\n\tipython gen-magic-rst.ipy\n\nhtml: pre-build\n\t$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html\n\t@echo\n\t@echo \"Build finished. The HTML pages are in $(BUILDDIR)/html.\"\n\ndirhtml: pre-build\n\t$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml\n\t@echo\n\t@echo \"Build finished. The HTML pages are in $(BUILDDIR)/dirhtml.\"\n\nsinglehtml: pre-build\n\t$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml\n\t@echo\n\t@echo \"Build finished. The HTML page is in $(BUILDDIR)/singlehtml.\"\n\npickle: pre-build\n\t$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle\n\t@echo\n\t@echo \"Build finished; now you can process the pickle files.\"\n\njson: pre-build\n\t$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json\n\t@echo\n\t@echo \"Build finished; now you can process the JSON files.\"\n\nhtmlhelp: pre-build\n\t$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp\n\t@echo\n\t@echo \"Build finished; now you can run HTML Help Workshop with the\" \\\n\t      \".hhp project file in $(BUILDDIR)/htmlhelp.\"\n\nqthelp: pre-build\n\t$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp\n\t@echo\n\t@echo \"Build finished; now you can run \"qcollectiongenerator\" with the\" \\\n\t      \".qhcp project file in $(BUILDDIR)/qthelp, like this:\"\n\t@echo \"# qcollectiongenerator $(BUILDDIR)/qthelp/api.qhcp\"\n\t@echo \"To view the help file:\"\n\t@echo \"# assistant -collectionFile $(BUILDDIR)/qthelp/api.qhc\"\n\napplehelp: pre-build\n\t$(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp\n\t@echo\n\t@echo \"Build finished. The help book is in $(BUILDDIR)/applehelp.\"\n\t@echo \"N.B. You won't be able to view it unless you put it in\" \\\n\t      \"~/Library/Documentation/Help or install it in your application\" \\\n\t      \"bundle.\"\n\ndevhelp: pre-build\n\t$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp\n\t@echo\n\t@echo \"Build finished.\"\n\t@echo \"To view the help file:\"\n\t@echo \"# mkdir -p $$HOME/.local/share/devhelp/api\"\n\t@echo \"# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/api\"\n\t@echo \"# devhelp\"\n\nepub: pre-build\n\t$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub\n\t@echo\n\t@echo \"Build finished. The epub file is in $(BUILDDIR)/epub.\"\n\nlatex: pre-build\n\t$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex\n\t@echo\n\t@echo \"Build finished; the LaTeX files are in $(BUILDDIR)/latex.\"\n\t@echo \"Run \\`make' in that directory to run these through (pdf)latex\" \\\n\t      \"(use \\`make latexpdf' here to do that automatically).\"\n\nlatexpdf: pre-build\n\t$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex\n\t@echo \"Running LaTeX files through pdflatex...\"\n\t$(MAKE) -C $(BUILDDIR)/latex all-pdf\n\t@echo \"pdflatex finished; the PDF files are in $(BUILDDIR)/latex.\"\n\nlatexpdfja: pre-build\n\t$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex\n\t@echo \"Running LaTeX files through platex and dvipdfmx...\"\n\t$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja\n\t@echo \"pdflatex finished; the PDF files are in $(BUILDDIR)/latex.\"\n\ntext: pre-build\n\t$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text\n\t@echo\n\t@echo \"Build finished. The text files are in $(BUILDDIR)/text.\"\n\nman: pre-build\n\t$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man\n\t@echo\n\t@echo \"Build finished. The manual pages are in $(BUILDDIR)/man.\"\n\ntexinfo: pre-build\n\t$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo\n\t@echo\n\t@echo \"Build finished. The Texinfo files are in $(BUILDDIR)/texinfo.\"\n\t@echo \"Run \\`make' in that directory to run these through makeinfo\" \\\n\t      \"(use \\`make info' here to do that automatically).\"\n\ninfo: pre-build\n\t$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo\n\t@echo \"Running Texinfo files through makeinfo...\"\n\tmake -C $(BUILDDIR)/texinfo info\n\t@echo \"makeinfo finished; the Info files are in $(BUILDDIR)/texinfo.\"\n\ngettext: pre-build\n\t$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale\n\t@echo\n\t@echo \"Build finished. The message catalogs are in $(BUILDDIR)/locale.\"\n\nchanges: pre-build\n\t$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes\n\t@echo\n\t@echo \"The overview file is in $(BUILDDIR)/changes.\"\n\nlinkcheck: pre-build\n\t$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck\n\t@echo\n\t@echo \"Link check complete; look for any errors in the above output \" \\\n\t      \"or in $(BUILDDIR)/linkcheck/output.txt.\"\n\ndoctest: pre-build\n\t$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest\n\t@echo \"Testing of doctests in the sources finished, look at the \" \\\n\t      \"results in $(BUILDDIR)/doctest/output.txt.\"\n\ncoverage: pre-build\n\t$(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage\n\t@echo \"Testing of coverage in the sources finished, look at the \" \\\n\t      \"results in $(BUILDDIR)/coverage/python.txt.\"\n\nxml: pre-build\n\t$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml\n\t@echo\n\t@echo \"Build finished. The XML files are in $(BUILDDIR)/xml.\"\n\npseudoxml: pre-build\n\t$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml\n\t@echo\n\t@echo \"Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml.\"\n\n# Publishing requires a cloned repo in the ../../datalab/docs directory.\n# You can use the prepublish target for this.\nprepublish:\n\tmkdir -p ../../datalab-docs/html\n\tcd ../../datalab-docs && git clone https://github.com/GoogleCloudPlatform/datalab.git html && \\\n\t\tgit checkout gh-pages\n\npublish: pre-build\n\t$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html\n\tcd ../../datalab-docs/html && git add . && git commit -m \"Updated\" && git push --force origin gh-pages\n\n"
  },
  {
    "path": "docs/README",
    "content": "To use, install the prerequisites and the pydatalab module:\n\n  pip install sphinx sphinx_rtd_theme sphinxcontrib-napoleon\n  pip install .. # from docs directory\n\nthen in the docs directory, do 'make html' (or epub, or text, etc).\n\nOutput will be in $BUILDDIR, defaulting to ../../datalab-docs.\n"
  },
  {
    "path": "docs/conf.py",
    "content": "# -*- coding: utf-8 -*-\n#\n# api documentation build configuration file, created by\n# sphinx-quickstart on Tue Nov  3 12:10:12 2015.\n#\n# This file is execfile()d with the current directory set to its\n# containing dir.\n#\n# Note that not all possible configuration values are present in this\n# autogenerated file.\n#\n# All configuration values have a default; values that are commented out\n# serve to show the default.\n\nimport sys\nimport os\nimport sphinx_rtd_theme\n\n# If extensions (or modules to document with autodoc) are in another directory,\n# add these directories to sys.path here. If the directory is relative to the\n# documentation root, use os.path.abspath to make it absolute, like shown here.\nsys.path.append(os.path.abspath('../'))\n\n# -- General configuration ------------------------------------------------\n\n# If your documentation needs a minimal Sphinx version, state it here.\n#needs_sphinx = '1.0'\n\n# Add any Sphinx extension module names here, as strings. They can be\n# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom\n# ones.\nextensions = [\n    'sphinx.ext.autodoc',\n    'sphinx.ext.todo',\n    'sphinx.ext.viewcode',\n    'sphinxcontrib.napoleon',\n]\n\n# Add any paths that contain templates here, relative to this directory.\ntemplates_path = ['_templates']\n\n# The suffix(es) of source filenames.\n# You can specify multiple suffix as a list of string:\n# source_suffix = ['.rst', '.md']\nsource_suffix = '.rst'\n\n# The encoding of source files.\n#source_encoding = 'utf-8-sig'\n\n# The master toctree document.\nmaster_doc = 'index'\n\n# General information about the project.\nproject = u'Google Cloud Datalab'\ncopyright = u'2015, Google, Inc.'\nauthor = u'Google, Inc.'\n\n# The version info for the project you're documenting, acts as replacement for\n# |version| and |release|, also used in various other places throughout the\n# built documents.\n#\n# The short X.Y version.\nversion = ''\n# The full version, including alpha/beta/rc tags.\nrelease = ''\n\n# The language for content autogenerated by Sphinx. Refer to documentation\n# for a list of supported languages.\n#\n# This is also used if you do content translation via gettext catalogs.\n# Usually you set \"language\" from the command line for these cases.\nlanguage = 'en'\n\n# There are two options for replacing |today|: either, you set today to some\n# non-false value, then it is used:\n#today = ''\n# Else, today_fmt is used as the format for a strftime call.\n#today_fmt = '%B %d, %Y'\n\n# List of patterns, relative to source directory, that match files and\n# directories to ignore when looking for source files.\nexclude_patterns = ['_build']\n\n# The reST default role (used for this markup: `text`) to use for all\n# documents.\n#default_role = None\n\n# If true, '()' will be appended to :func: etc. cross-reference text.\n#add_function_parentheses = True\n\n# If true, the current module name will be prepended to all description\n# unit titles (such as .. function::).\n#add_module_names = True\n\n# If true, sectionauthor and moduleauthor directives will be shown in the\n# output. They are ignored by default.\n#show_authors = False\n\n# The name of the Pygments (syntax highlighting) style to use.\npygments_style = 'sphinx'\n\n# A list of ignored prefixes for module index sorting.\n#modindex_common_prefix = []\n\n# If true, keep warnings as \"system message\" paragraphs in the built documents.\n#keep_warnings = False\n\n# If true, `todo` and `todoList` produce output, else they produce nothing.\ntodo_include_todos = True\n\n# Combine class pydoc with __init__ pydoc\nautoclass_content = 'both'\n\n# -- Options for HTML output ----------------------------------------------\n\n# The theme to use for HTML and HTML Help pages.  See the documentation for\n# a list of builtin themes.\nhtml_theme = 'sphinx_rtd_theme'\nhtml_theme_path = [sphinx_rtd_theme.get_html_theme_path()]\n\n# Theme options are theme-specific and customize the look and feel of a theme\n# further.  For a list of options available for each theme, see the\n# documentation.\n#html_theme_options = {}\n\n# Add any paths that contain custom themes here, relative to this directory.\n#html_theme_path = []\n\n# The name for this set of Sphinx documents.  If None, it defaults to\n# \"<project> v<release> documentation\".\n#html_title = None\n\n# A shorter title for the navigation bar.  Default is the same as html_title.\n#html_short_title = None\n\n# The name of an image file (relative to this directory) to place at the top\n# of the sidebar.\n#html_logo = None\n\n# The name of an image file (within the static path) to use as favicon of the\n# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32\n# pixels large.\n#html_favicon = None\n\n# Add any paths that contain custom static files (such as style sheets) here,\n# relative to this directory. They are copied after the builtin static files,\n# so a file named \"default.css\" will overwrite the builtin \"default.css\".\n#html_static_path = []\n\n# Add any extra paths that contain custom files (such as robots.txt or\n# .htaccess) here, relative to this directory. These files are copied\n# directly to the root of the documentation.\n#html_extra_path = []\n\n# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,\n# using the given strftime format.\n#html_last_updated_fmt = '%b %d, %Y'\n\n# If true, SmartyPants will be used to convert quotes and dashes to\n# typographically correct entities.\n#html_use_smartypants = True\n\n# Custom sidebar templates, maps document names to template names.\n#html_sidebars = {}\n\n# Additional templates that should be rendered to pages, maps page names to\n# template names.\n#html_additional_pages = {}\n\n# If false, no module index is generated.\n#html_domain_indices = True\n\n# If false, no index is generated.\n#html_use_index = True\n\n# If true, the index is split into individual pages for each letter.\n#html_split_index = False\n\n# If true, links to the reST sources are added to the pages.\n#html_show_sourcelink = True\n\n# If true, \"Created using Sphinx\" is shown in the HTML footer. Default is True.\n#html_show_sphinx = True\n\n# If true, \"(C) Copyright ...\" is shown in the HTML footer. Default is True.\n#html_show_copyright = True\n\n# If true, an OpenSearch description file will be output, and all pages will\n# contain a <link> tag referring to it.  The value of this option must be the\n# base URL from which the finished HTML is served.\n#html_use_opensearch = ''\n\n# This is the file name suffix for HTML files (e.g. \".xhtml\").\n#html_file_suffix = None\n\n# Language to be used for generating the HTML full-text search index.\n# Sphinx supports the following languages:\n#   'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja'\n#   'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr'\n#html_search_language = 'en'\n\n# A dictionary with options for the search language support, empty by default.\n# Now only 'ja' uses this config value\n#html_search_options = {'type': 'default'}\n\n# The name of a javascript file (relative to the configuration directory) that\n# implements a search results scorer. If empty, the default will be used.\n#html_search_scorer = 'scorer.js'\n\n# Output file base name for HTML help builder.\nhtmlhelp_basename = 'apidoc'\n\n# -- Options for LaTeX output ---------------------------------------------\n\nlatex_elements = {\n# The paper size ('letterpaper' or 'a4paper').\n#'papersize': 'letterpaper',\n\n# The font size ('10pt', '11pt' or '12pt').\n#'pointsize': '10pt',\n\n# Additional stuff for the LaTeX preamble.\n#'preamble': '',\n\n# Latex figure (float) alignment\n#'figure_align': 'htbp',\n}\n\n# Grouping the document tree into LaTeX files. List of tuples\n# (source start file, target name, title,\n#  author, documentclass [howto, manual, or own class]).\nlatex_documents = [\n  (master_doc, 'api.tex', u'api Documentation',\n   u'Google', 'manual'),\n]\n\n# The name of an image file (relative to this directory) to place at the top of\n# the title page.\n#latex_logo = None\n\n# For \"manual\" documents, if this is true, then toplevel headings are parts,\n# not chapters.\n#latex_use_parts = False\n\n# If true, show page references after internal links.\n#latex_show_pagerefs = False\n\n# If true, show URL addresses after external links.\n#latex_show_urls = False\n\n# Documents to append as an appendix to all manuals.\n#latex_appendices = []\n\n# If false, no module index is generated.\n#latex_domain_indices = True\n\n\n# -- Options for manual page output ---------------------------------------\n\n# One entry per manual page. List of tuples\n# (source start file, name, description, authors, manual section).\nman_pages = [\n    (master_doc, 'api', u'api Documentation',\n     [author], 1)\n]\n\n# If true, show URL addresses after external links.\n#man_show_urls = False\n\n\n# -- Options for Texinfo output -------------------------------------------\n\n# Grouping the document tree into Texinfo files. List of tuples\n# (source start file, target name, title, author,\n#  dir menu entry, description, category)\ntexinfo_documents = [\n  (master_doc, 'api', u'api Documentation',\n   author, 'api', 'One line description of project.',\n   'Miscellaneous'),\n]\n\n# Documents to append as an appendix to all manuals.\n#texinfo_appendices = []\n\n# If false, no module index is generated.\n#texinfo_domain_indices = True\n\n# How to display URL addresses: 'footnote', 'no', or 'inline'.\n#texinfo_show_urls = 'footnote'\n\n# If true, do not generate a @detailmenu in the \"Top\" node's menu.\n#texinfo_no_detailmenu = False\n\n\n# -- Options for Epub output ----------------------------------------------\n\n# Bibliographic Dublin Core info.\nepub_title = project\nepub_author = author\nepub_publisher = author\nepub_copyright = copyright\n\n# The basename for the epub file. It defaults to the project name.\n#epub_basename = project\n\n# The HTML theme for the epub output. Since the default themes are not optimized\n# for small screen space, using the same theme for HTML and epub output is\n# usually not wise. This defaults to 'epub', a theme designed to save visual\n# space.\n#epub_theme = 'epub'\n\n# The language of the text. It defaults to the language option\n# or 'en' if the language is not set.\n#epub_language = ''\n\n# The scheme of the identifier. Typical schemes are ISBN or URL.\n#epub_scheme = ''\n\n# The unique identifier of the text. This can be a ISBN number\n# or the project homepage.\n#epub_identifier = ''\n\n# A unique identification for the text.\n#epub_uid = ''\n\n# A tuple containing the cover image and cover page html template filenames.\n#epub_cover = ()\n\n# A sequence of (type, uri, title) tuples for the guide element of content.opf.\n#epub_guide = ()\n\n# HTML files that should be inserted before the pages created by sphinx.\n# The format is a list of tuples containing the path and title.\n#epub_pre_files = []\n\n# HTML files shat should be inserted after the pages created by sphinx.\n# The format is a list of tuples containing the path and title.\n#epub_post_files = []\n\n# A list of files that should not be packed into the epub file.\nepub_exclude_files = ['search.html']\n\n# The depth of the table of contents in toc.ncx.\n#epub_tocdepth = 3\n\n# Allow duplicate toc entries.\n#epub_tocdup = True\n\n# Choose between 'default' and 'includehidden'.\n#epub_tocscope = 'default'\n\n# Fix unsupported image types using the Pillow.\n#epub_fix_images = False\n\n# Scale large images.\n#epub_max_image_width = 0\n\n# How to display URL addresses: 'footnote', 'no', or 'inline'.\n#epub_show_urls = 'inline'\n\n# If false, no index is generated.\n#epub_use_index = True\n"
  },
  {
    "path": "docs/datalab Commands.rst",
    "content": "datalab Commands\n=======================\n\n.. attribute:: %bigquery\n.. parsed-literal::\n\n  usage: bigquery [-h]\n                  {sample,create,delete,dryrun,udf,execute,pipeline,table,schema,datasets,tables,extract,load}\n                  ...\n  \n  Execute various BigQuery-related operations. Use \"%bigquery <command> -h\" for\n  help on a specific command.\n  \n  positional arguments:\n    {sample,create,delete,dryrun,udf,execute,pipeline,table,schema,datasets,tables,extract,load}\n                          commands\n      sample              Display a sample of the results of a BigQuery SQL\n                          query. The cell can optionally contain arguments for\n                          expanding variables in the query, if -q/--query was\n                          used, or it can contain SQL for a query.\n      create              Create a dataset or table.\n      delete              Delete a dataset or table.\n      dryrun              Execute a dry run of a BigQuery query and display\n                          approximate usage statistics\n      udf                 Create a named Javascript BigQuery UDF\n      execute             Execute a BigQuery SQL query and optionally send the\n                          results to a named table. The cell can optionally\n                          contain arguments for expanding variables in the\n                          query.\n      pipeline            Define a deployable pipeline based on a BigQuery\n                          query. The cell can optionally contain arguments for\n                          expanding variables in the query.\n      table               View a BigQuery table.\n      schema              View a BigQuery table or view schema.\n      datasets            List the datasets in a BigQuery project.\n      tables              List the tables in a BigQuery project or dataset.\n      extract             Extract BigQuery query results or table to GCS.\n      load                Load data from GCS into a BigQuery table.\n  \n  optional arguments:\n    -h, --help            show this help message and exit\n  None\n\n.. attribute:: %extension\n.. parsed-literal::\n\n  usage: %extension [-h] {mathjax} ...\n  \n  Load an extension into Datalab. Currently only mathjax is supported.\n  \n  positional arguments:\n    {mathjax}   commands\n      mathjax   Enabled MathJaX support in Datalab.\n  \n  optional arguments:\n    -h, --help  show this help message and exit\n  None\n\n.. attribute:: %monitoring\n.. parsed-literal::\n\n  usage: monitoring [-h] {list} ...\n  \n  Execute various Monitoring-related operations. Use \"%monitoring <command> -h\"\n  for help on a specific command.\n  \n  positional arguments:\n    {list}      commands\n      list      List the metrics or resource types in a monitored project.\n  \n  optional arguments:\n    -h, --help  show this help message and exit\n  None\n\n.. attribute:: %projects\n.. parsed-literal::\n\n  usage: projects [-h] {list,set} ...\n  \n  positional arguments:\n    {list,set}  commands\n      list      List available projects.\n      set       Set the default project.\n  \n  optional arguments:\n    -h, --help  show this help message and exit\n  None\n\n.. attribute:: %pymodule\n.. parsed-literal::\n\n  usage: pymodule [-h] [-n NAME]\n  \n  optional arguments:\n    -h, --help            show this help message and exit\n    -n NAME, --name NAME  the name of the python module to create and import\n  None\n\n.. attribute:: %sql\n.. parsed-literal::\n\n  usage: %%sql [-h] [-m MODULE] [-d {legacy,standard}] [-b BILLING]\n  \n  Create a named SQL module with one or more queries.\n  \n  The cell body should contain an optional initial part defining the default\n  values for the variables, if any, using Python code, followed by one or more\n  queries.\n  \n  Queries should start with 'DEFINE QUERY <name>' in order to bind them to\n  <module name>.<query name> in the notebook (as datalab.data.SqlStament instances).\n  The final query can optionally omit 'DEFINE QUERY <name>', as using the module\n  name in places where a SqlStatement is expected will resolve to the final query\n  in the module.\n  \n  Queries can refer to variables with '$<name>', as well as refer to other queries\n  within the same module, making it easy to compose nested queries and test their\n  parts.\n  \n  The Python code defining the variable default values can assign scalar or list/tuple values to\n  variables, or one of the special functions 'datestring' and 'source'.\n  \n  When a variable with a 'datestring' default is expanded it will expand to a formatted\n  string based on the current date, while a 'source' default will expand to a table whose\n  name is based on the current date.\n  \n  datestring() takes two named arguments, 'format' and 'offset'. The former is a\n  format string that is the same as for Python's time.strftime function. The latter\n  is a string containing a comma-separated list of expressions such as -1y, +2m,\n  etc; these are offsets from the time of expansion that are applied in order. The\n  suffix (y, m, d, h, M) correspond to units of years, months, days, hours and\n  minutes, while the +n or -n prefix is the number of units to add or subtract from\n  the time of expansion. Three special values 'now', 'today' and 'yesterday' are\n  also supported; 'today' and 'yesterday' will be midnight UTC on the current date\n  or previous days date.\n  \n  source() can take a 'name' argument for a fixed table name, or 'format' and 'offset'\n  arguments similar to datestring(), but unlike datestring() will resolve to a Table\n  with the specified name.\n  \n  optional arguments:\n    -h, --help            show this help message and exit\n    -m MODULE, --module MODULE\n                          The name for this SQL module\n    -d {legacy,standard}, --dialect {legacy,standard}\n                          BigQuery SQL dialect\n    -b BILLING, --billing BILLING\n                          BigQuery billing tier\n\n.. attribute:: %storage\n.. parsed-literal::\n\n  usage: storage [-h] {copy,create,delete,list,read,view,write} ...\n  \n  Execute various storage-related operations. Use \"%storage <command> -h\" for\n  help on a specific command.\n  \n  positional arguments:\n    {copy,create,delete,list,read,view,write}\n                          commands\n      copy                Copy one or more GCS objects to a different location.\n      create              Create one or more GCS buckets.\n      delete              Delete one or more GCS buckets or objects.\n      list                List buckets in a project, or contents of a bucket.\n      read                Read the contents of a storage object into a Python\n                          variable.\n      view                View the contents of a storage object.\n      write               Write the value of a Python variable to a storage\n                          object.\n  \n  optional arguments:\n    -h, --help            show this help message and exit\n  None\n\n"
  },
  {
    "path": "docs/datalab.bigquery.rst",
    "content": "datalab.bigquery Module\n=======================\n\n.. automodule:: datalab.bigquery\n    :members:\n    :undoc-members:\n    :show-inheritance:\n\n.. autoclass:: datalab.bigquery.CSVOptions\n    :members:\n\n.. autoclass:: datalab.bigquery.Dataset\n    :members:\n\n.. autoclass:: datalab.bigquery.DatasetName\n    :members:\n\n.. autoclass:: datalab.bigquery.Datasets\n    :members:\n\n.. autoclass:: datalab.bigquery.FederatedTable\n    :members:\n\n.. autoclass:: datalab.bigquery.Job\n    :members:\n\n.. autoclass:: datalab.bigquery.Query\n    :members:\n\n.. autoclass:: datalab.bigquery.QueryJob\n    :members:\n\n.. autoclass:: datalab.bigquery.QueryResultsTable\n    :members:\n\n.. autoclass:: datalab.bigquery.QueryStats\n    :members:\n\n.. autoclass:: datalab.bigquery.Sampling\n    :members:\n\n.. autoclass:: datalab.bigquery.Schema\n    :members:\n\n.. autoclass:: datalab.bigquery.Table\n    :members:\n\n.. autoclass:: datalab.bigquery.TableMetadata\n    :members:\n\n.. autoclass:: datalab.bigquery.TableName\n    :members:\n\n.. autoclass:: datalab.bigquery.UDF\n    :members:\n\n.. autoclass:: datalab.bigquery.View\n    :members:\n"
  },
  {
    "path": "docs/datalab.context.rst",
    "content": "datalab.context Module\n======================\n\n.. autoclass:: datalab.context.Context\n    :members:\n\n.. autoclass:: datalab.context.Project\n    :members:\n\n.. autoclass:: datalab.context.Projects\n    :members:\n\n"
  },
  {
    "path": "docs/datalab.data.rst",
    "content": "datalab.data Module\n===================\n\n.. automodule:: datalab.data\n    :members:\n    :undoc-members:\n    :show-inheritance:\n\n.. autoclass:: datalab.data.Csv\n    :members:\n\n.. autoclass:: datalab.data.SqlModule\n    :members:\n\n.. autoclass:: datalab.data.SqlStatement\n    :members:\n\n"
  },
  {
    "path": "docs/datalab.stackdriver.monitoring.rst",
    "content": "datalab.stackdriver.monitoring Module\n=====================================\n\n.. autoclass:: datalab.stackdriver.monitoring.Groups\n    :members:\n\n.. autoclass:: datalab.stackdriver.monitoring.MetricDescriptors\n    :members:\n\n.. autoclass:: datalab.stackdriver.monitoring.ResourceDescriptors\n    :members:\n\n.. autoclass:: datalab.stackdriver.monitoring.Query\n    :members:\n\n.. autoclass:: datalab.stackdriver.monitoring.QueryMetadata\n    :members:\n"
  },
  {
    "path": "docs/datalab.storage.rst",
    "content": "datalab.storage Module\n======================\n\n.. automodule:: datalab.storage\n    :members:\n    :undoc-members:\n    :show-inheritance:\n\n.. autoclass:: datalab.storage.Bucket\n    :members:\n\n.. autoclass:: datalab.storage.Buckets\n    :members:\n\n.. autoclass:: datalab.storage.Item\n    :members:\n\n.. autoclass:: datalab.storage.Items\n    :members:\n\n"
  },
  {
    "path": "docs/gen-magic-rst.ipy",
    "content": "import subprocess, pkgutil, importlib, sys\nfrom cStringIO import StringIO\n\n# import submodules\ndatalab_submodules = ['datalab.' + s + '.commands' for _,s,_ in pkgutil.iter_modules(['../datalab'])]\ngoogle_submodules = ['google.datalab.' + s + '.commands' for _,s,_ in pkgutil.iter_modules(['../google/datalab'])]\n\ndef generate_magic_docs(submodules, header, dir, ignored_magics=None):\n  if not ignored_magics:\n    ignored_magics = []\n  for m in submodules:\n    try:\n      importlib.import_module(m)\n    except:\n      sys.stderr.write('WARNING, could not find module ' + m + '. Ignoring..\\n')\n\n  magic_regex = \"find \" + dir + \" -name '*.py' -exec perl -e '$f=join(\\\"\\\",<>); print \\\"$1\\n\\\" if $f=~/register_line_cell_magic\\ndef ([^\\(]+)/m' {} \\;\"\n  magics = subprocess.check_output(magic_regex, shell=True)\n\n  reSTfile = open(header + '.rst', 'w')\n  indent = '\\n  '\n\n  reSTfile.write(header + '\\n')\n  reSTfile.write('=======================\\n\\n')\n\n  for m in sorted(magics.split()):\n    if m in ignored_magics:\n      sys.stderr.write('Ignoring magic ' + m + '\\n')\n    else:\n      print('working on magic: '+ m)\n      reSTfile.write('.. attribute:: %' + m + '\\n')\n      reSTfile.write('.. parsed-literal::\\n')\n      # hijack stdout since the ipython kernel call writes to stdout/err directly\n      # and does not return its output\n      tmpStdout, sys.stdout = sys.stdout, StringIO()\n      get_ipython().magic(m + ' -h')\n      resultout = sys.stdout.getvalue().splitlines()\n      sys.stdout = tmpStdout\n      reSTfile.writelines(indent + indent.join(resultout) + '\\n\\n')\n\n\ngenerate_magic_docs(datalab_submodules, 'datalab Commands', '../datalab', ignored_magics=['chart', 'csv']);\ngenerate_magic_docs(google_submodules, 'google.datalab Commands', '../google');\n\n"
  },
  {
    "path": "docs/google.datalab Commands.rst",
    "content": "google.datalab Commands\n=======================\n\n.. attribute:: %bq\n.. parsed-literal::\n\n  usage: %bq [-h]\n             {datasets,tables,query,execute,extract,sample,dryrun,udf,datasource,load}\n             ...\n  \n  Execute various BigQuery-related operations. Use \"%bq <command> -h\" for help\n  on a specific command.\n  \n  positional arguments:\n    {datasets,tables,query,execute,extract,sample,dryrun,udf,datasource,load}\n                          commands\n      datasets            Operations on BigQuery datasets\n      tables              Operations on BigQuery tables\n      query               Create or execute a BigQuery SQL query object,\n                          optionally using other SQL objects, UDFs, or external\n                          datasources. If a query name is not specified, the\n                          query is executed.\n      execute             Execute a BigQuery SQL query and optionally send the\n                          results to a named table. The cell can optionally\n                          contain arguments for expanding variables in the\n                          query.\n      extract             Extract a query or table into file (local or GCS)\n      sample              Display a sample of the results of a BigQuery SQL\n                          query. The cell can optionally contain arguments for\n                          expanding variables in the query, if -q/--query was\n                          used, or it can contain SQL for a query.\n      dryrun              Execute a dry run of a BigQuery query and display\n                          approximate usage statistics\n      udf                 Create a named Javascript BigQuery UDF\n      datasource          Create a named Javascript BigQuery external data\n                          source\n      load                Load data from GCS into a BigQuery table. If creating\n                          a new table, a schema should be specified in YAML or\n                          JSON in the cell body, otherwise the schema is\n                          inferred from existing table.\n  \n  optional arguments:\n    -h, --help            show this help message and exit\n  None\n\n.. attribute:: %chart\n.. parsed-literal::\n\n  usage: %chart [-h]\n                {annotation,area,bars,bubbles,calendar,candlestick,columns,combo,gauge,geo,heatmap,histogram,line,map,org,paged_table,pie,sankey,scatter,stepped_area,table,timeline,treemap}\n                ...\n  \n  Generate an inline chart using Google Charts using the data in a Table, Query,\n  dataframe, or list. Numerous types of charts are supported. Options for the\n  charts can be specified in the cell body using YAML or JSON.\n  \n  positional arguments:\n    {annotation,area,bars,bubbles,calendar,candlestick,columns,combo,gauge,geo,heatmap,histogram,line,map,org,paged_table,pie,sankey,scatter,stepped_area,table,timeline,treemap}\n                          commands\n      annotation          Generate a annotation chart.\n      area                Generate a area chart.\n      bars                Generate a bars chart.\n      bubbles             Generate a bubbles chart.\n      calendar            Generate a calendar chart.\n      candlestick         Generate a candlestick chart.\n      columns             Generate a columns chart.\n      combo               Generate a combo chart.\n      gauge               Generate a gauge chart.\n      geo                 Generate a geo chart.\n      heatmap             Generate a heatmap chart.\n      histogram           Generate a histogram chart.\n      line                Generate a line chart.\n      map                 Generate a map chart.\n      org                 Generate a org chart.\n      paged_table         Generate a paged_table chart.\n      pie                 Generate a pie chart.\n      sankey              Generate a sankey chart.\n      scatter             Generate a scatter chart.\n      stepped_area        Generate a stepped_area chart.\n      table               Generate a table chart.\n      timeline            Generate a timeline chart.\n      treemap             Generate a treemap chart.\n  \n  optional arguments:\n    -h, --help            show this help message and exit\n  None\n\n.. attribute:: %csv\n.. parsed-literal::\n\n  usage: csv [-h] {view} ...\n  \n  positional arguments:\n    {view}      commands\n      view      Browse CSV files without providing a schema. Each value is\n                considered string type.\n  \n  optional arguments:\n    -h, --help  show this help message and exit\n  None\n\n.. attribute:: %datalab\n.. parsed-literal::\n\n  usage: %datalab [-h] {config,project} ...\n  \n  Execute operations that apply to multiple Datalab APIs. Use \"%datalab\n  <command> -h\" for help on a specific command.\n  \n  positional arguments:\n    {config,project}  commands\n      config          List or set API-specific configurations.\n      project         Get or set the default project ID\n  \n  optional arguments:\n    -h, --help        show this help message and exit\n  None\n\n.. attribute:: %gcs\n.. parsed-literal::\n\n  usage: %gcs [-h] {copy,create,delete,list,read,view,write} ...\n  \n  Execute various Google Cloud Storage related operations. Use \"%gcs <command>\n  -h\" for help on a specific command.\n  \n  positional arguments:\n    {copy,create,delete,list,read,view,write}\n                          commands\n      copy                Copy one or more Google Cloud Storage objects to a\n                          different location.\n      create              Create one or more Google Cloud Storage buckets.\n      delete              Delete one or more Google Cloud Storage buckets or\n                          objects.\n      list                List buckets in a project, or contents of a bucket.\n      read                Read the contents of a Google Cloud Storage object\n                          into a Python variable.\n      view                View the contents of a Google Cloud Storage object.\n      write               Write the value of a Python variable to a Google Cloud\n                          Storage object.\n  \n  optional arguments:\n    -h, --help            show this help message and exit\n  None\n\n.. attribute:: %sd\n.. parsed-literal::\n\n  usage: %sd [-h] {monitoring} ...\n  \n  Execute various Stackdriver related operations. Use \"%sd <stackdriver_product>\n  -h\" for help on a specific Stackdriver product.\n  \n  positional arguments:\n    {monitoring}  commands\n      monitoring  Execute Stackdriver monitoring related operations. Use \"sd\n                  monitoring <command> -h\" for help on a specific command\n  \n  optional arguments:\n    -h, --help    show this help message and exit\n  None\n\n"
  },
  {
    "path": "docs/google.datalab.bigquery.rst",
    "content": "google.datalab.bigquery Module\n==============================\n\n.. automodule:: google.datalab.bigquery\n    :members:\n    :undoc-members:\n    :show-inheritance:\n\n.. autoclass:: google.datalab.bigquery.CSVOptions\n    :members:\n\n.. autoclass:: google.datalab.bigquery.Dataset\n    :members:\n\n.. autoclass:: google.datalab.bigquery.DatasetName\n    :members:\n\n.. autoclass:: google.datalab.bigquery.Datasets\n    :members:\n\n.. autoclass:: google.datalab.bigquery.ExternalDataSource\n    :members:\n\n.. autoclass:: google.datalab.bigquery.Query\n    :members:\n\n.. autoclass:: google.datalab.bigquery.QueryOutput\n    :members:\n\n.. autoclass:: google.datalab.bigquery.QueryResultsTable\n    :members:\n\n.. autoclass:: google.datalab.bigquery.QueryStats\n    :members:\n\n.. autoclass:: google.datalab.bigquery.Sampling\n    :members:\n\n.. autoclass:: google.datalab.bigquery.Schema\n    :members:\n\n.. autoclass:: google.datalab.bigquery.SchemaField\n    :members:\n\n.. autoclass:: google.datalab.bigquery.Table\n    :members:\n\n.. autoclass:: google.datalab.bigquery.TableMetadata\n    :members:\n\n.. autoclass:: google.datalab.bigquery.TableName\n    :members:\n\n.. autoclass:: google.datalab.bigquery.UDF\n    :members:\n\n.. autoclass:: google.datalab.bigquery.View\n    :members:\n"
  },
  {
    "path": "docs/google.datalab.data.rst",
    "content": "google.datalab.data Module\n==========================\n\n.. automodule:: google.datalab.data\n    :members:\n    :undoc-members:\n    :show-inheritance:\n\n.. autoclass:: google.datalab.data.CsvFile\n    :members:\n\n"
  },
  {
    "path": "docs/google.datalab.ml.rst",
    "content": "google.datalab.ml Module\n========================\n\n.. automodule:: google.datalab.ml\n    :members:\n    :undoc-members:\n    :show-inheritance:\n\n.. autoclass:: google.datalab.ml.Job\n    :members:\n\n.. autoclass:: google.datalab.ml.Jobs\n    :members:\n\n.. autoclass:: google.datalab.ml.Summary\n    :members:\n\n.. autoclass:: google.datalab.ml.TensorBoard\n    :members:\n\n.. autoclass:: google.datalab.ml.CsvDataSet\n    :members:\n\n.. autoclass:: google.datalab.ml.BigQueryDataSet\n    :members:\n\n.. autoclass:: google.datalab.ml.Models\n    :members:\n\n.. autoclass:: google.datalab.ml.ModelVersions\n    :members:\n\n.. autoclass:: google.datalab.ml.ConfusionMatrix\n    :members:\n\n.. autoclass:: google.datalab.ml.FeatureSliceView\n    :members:\n\n.. autoclass:: google.datalab.ml.CloudTrainingConfig\n    :members:\n\n"
  },
  {
    "path": "docs/google.datalab.rst",
    "content": "google.datalab Module\n=====================\n\n.. automodule:: google.datalab\n    :members:\n    :undoc-members:\n    :show-inheritance:\n\n.. autoclass:: google.datalab.Context\n    :members:\n\n.. autoclass:: google.datalab.Job\n    :members:\n\n"
  },
  {
    "path": "docs/google.datalab.stackdriver.monitoring.rst",
    "content": "google.datalab.stackdriver.monitoring Module\n============================================\n\n.. autoclass:: google.datalab.stackdriver.monitoring.Groups\n    :members:\n\n.. autoclass:: google.datalab.stackdriver.monitoring.MetricDescriptors\n    :members:\n\n.. autoclass:: google.datalab.stackdriver.monitoring.ResourceDescriptors\n    :members:\n\n.. autoclass:: google.datalab.stackdriver.monitoring.Query\n    :members:\n\n.. autoclass:: google.datalab.stackdriver.monitoring.QueryMetadata\n    :members:\n"
  },
  {
    "path": "docs/google.datalab.storage.rst",
    "content": "google.datalab.storage Module\n=============================\n\n.. automodule:: google.datalab.storage\n    :members:\n    :undoc-members:\n    :show-inheritance:\n\n.. autoclass:: google.datalab.storage.Bucket\n    :members:\n\n.. autoclass:: google.datalab.storage.Buckets\n    :members:\n\n.. autoclass:: google.datalab.storage.Object\n    :members:\n\n.. autoclass:: google.datalab.storage.Objects\n    :members:\n\n"
  },
  {
    "path": "docs/index.rst",
    "content": "Welcome to Cloud Datalab's documentation\n========================================\n\ngoogle.datalab namespace\n########################\n\nContents:\n\n.. toctree::\n   google.datalab\n   google.datalab.bigquery\n   google.datalab.data\n   google.datalab.ml\n   google.datalab.stackdriver.monitoring\n   google.datalab.storage\n   google.datalab Commands\n\nML Toolbox:\n\n.. toctree::\n   mltoolbox.classification.dnn\n   mltoolbox.classification.linear\n   mltoolbox.regression.dnn\n   mltoolbox.regression.linear\n   mltoolbox.image.classification\n\ndatalab namespace\n#################\n\nPlease note, this namespace is planned to be phased out. You are strongly encouraged to move to the new google.datalab namespace above.\n\nContents:\n\n.. toctree::\n   datalab.bigquery\n   datalab.context\n   datalab.data\n   datalab.stackdriver.monitoring\n   datalab.storage\n   datalab Commands\n\n\nIndices and tables\n==================\n\n* :ref:`genindex`\n* :ref:`modindex`\n* :ref:`search`\n\n"
  },
  {
    "path": "docs/make.bat",
    "content": "@ECHO OFF\r\n\r\nREM Command file for Sphinx documentation\r\n\r\nif \"%SPHINXBUILD%\" == \"\" (\r\n\tset SPHINXBUILD=sphinx-build\r\n)\r\nset BUILDDIR=_build\r\nset ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .\r\nset I18NSPHINXOPTS=%SPHINXOPTS% .\r\nif NOT \"%PAPER%\" == \"\" (\r\n\tset ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%\r\n\tset I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%\r\n)\r\n\r\nif \"%1\" == \"\" goto help\r\n\r\nif \"%1\" == \"help\" (\r\n\t:help\r\n\techo.Please use `make ^<target^>` where ^<target^> is one of\r\n\techo.  html       to make standalone HTML files\r\n\techo.  dirhtml    to make HTML files named index.html in directories\r\n\techo.  singlehtml to make a single large HTML file\r\n\techo.  pickle     to make pickle files\r\n\techo.  json       to make JSON files\r\n\techo.  htmlhelp   to make HTML files and a HTML help project\r\n\techo.  qthelp     to make HTML files and a qthelp project\r\n\techo.  devhelp    to make HTML files and a Devhelp project\r\n\techo.  epub       to make an epub\r\n\techo.  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter\r\n\techo.  text       to make text files\r\n\techo.  man        to make manual pages\r\n\techo.  texinfo    to make Texinfo files\r\n\techo.  gettext    to make PO message catalogs\r\n\techo.  changes    to make an overview over all changed/added/deprecated items\r\n\techo.  xml        to make Docutils-native XML files\r\n\techo.  pseudoxml  to make pseudoxml-XML files for display purposes\r\n\techo.  linkcheck  to check all external links for integrity\r\n\techo.  doctest    to run all doctests embedded in the documentation if enabled\r\n\techo.  coverage   to run coverage check of the documentation if enabled\r\n\tgoto end\r\n)\r\n\r\nif \"%1\" == \"clean\" (\r\n\tfor /d %%i in (%BUILDDIR%\\*) do rmdir /q /s %%i\r\n\tdel /q /s %BUILDDIR%\\*\r\n\tgoto end\r\n)\r\n\r\n\r\nREM Check if sphinx-build is available and fallback to Python version if any\r\n%SPHINXBUILD% 2> nul\r\nif errorlevel 9009 goto sphinx_python\r\ngoto sphinx_ok\r\n\r\n:sphinx_python\r\n\r\nset SPHINXBUILD=python -m sphinx.__init__\r\n%SPHINXBUILD% 2> nul\r\nif errorlevel 9009 (\r\n\techo.\r\n\techo.The 'sphinx-build' command was not found. Make sure you have Sphinx\r\n\techo.installed, then set the SPHINXBUILD environment variable to point\r\n\techo.to the full path of the 'sphinx-build' executable. Alternatively you\r\n\techo.may add the Sphinx directory to PATH.\r\n\techo.\r\n\techo.If you don't have Sphinx installed, grab it from\r\n\techo.http://sphinx-doc.org/\r\n\texit /b 1\r\n)\r\n\r\n:sphinx_ok\r\n\r\n\r\nif \"%1\" == \"html\" (\r\n\t%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html\r\n\tif errorlevel 1 exit /b 1\r\n\techo.\r\n\techo.Build finished. The HTML pages are in %BUILDDIR%/html.\r\n\tgoto end\r\n)\r\n\r\nif \"%1\" == \"dirhtml\" (\r\n\t%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml\r\n\tif errorlevel 1 exit /b 1\r\n\techo.\r\n\techo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.\r\n\tgoto end\r\n)\r\n\r\nif \"%1\" == \"singlehtml\" (\r\n\t%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml\r\n\tif errorlevel 1 exit /b 1\r\n\techo.\r\n\techo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.\r\n\tgoto end\r\n)\r\n\r\nif \"%1\" == \"pickle\" (\r\n\t%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle\r\n\tif errorlevel 1 exit /b 1\r\n\techo.\r\n\techo.Build finished; now you can process the pickle files.\r\n\tgoto end\r\n)\r\n\r\nif \"%1\" == \"json\" (\r\n\t%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json\r\n\tif errorlevel 1 exit /b 1\r\n\techo.\r\n\techo.Build finished; now you can process the JSON files.\r\n\tgoto end\r\n)\r\n\r\nif \"%1\" == \"htmlhelp\" (\r\n\t%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp\r\n\tif errorlevel 1 exit /b 1\r\n\techo.\r\n\techo.Build finished; now you can run HTML Help Workshop with the ^\r\n.hhp project file in %BUILDDIR%/htmlhelp.\r\n\tgoto end\r\n)\r\n\r\nif \"%1\" == \"qthelp\" (\r\n\t%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp\r\n\tif errorlevel 1 exit /b 1\r\n\techo.\r\n\techo.Build finished; now you can run \"qcollectiongenerator\" with the ^\r\n.qhcp project file in %BUILDDIR%/qthelp, like this:\r\n\techo.^> qcollectiongenerator %BUILDDIR%\\qthelp\\api.qhcp\r\n\techo.To view the help file:\r\n\techo.^> assistant -collectionFile %BUILDDIR%\\qthelp\\api.ghc\r\n\tgoto end\r\n)\r\n\r\nif \"%1\" == \"devhelp\" (\r\n\t%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp\r\n\tif errorlevel 1 exit /b 1\r\n\techo.\r\n\techo.Build finished.\r\n\tgoto end\r\n)\r\n\r\nif \"%1\" == \"epub\" (\r\n\t%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub\r\n\tif errorlevel 1 exit /b 1\r\n\techo.\r\n\techo.Build finished. The epub file is in %BUILDDIR%/epub.\r\n\tgoto end\r\n)\r\n\r\nif \"%1\" == \"latex\" (\r\n\t%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex\r\n\tif errorlevel 1 exit /b 1\r\n\techo.\r\n\techo.Build finished; the LaTeX files are in %BUILDDIR%/latex.\r\n\tgoto end\r\n)\r\n\r\nif \"%1\" == \"latexpdf\" (\r\n\t%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex\r\n\tcd %BUILDDIR%/latex\r\n\tmake all-pdf\r\n\tcd %~dp0\r\n\techo.\r\n\techo.Build finished; the PDF files are in %BUILDDIR%/latex.\r\n\tgoto end\r\n)\r\n\r\nif \"%1\" == \"latexpdfja\" (\r\n\t%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex\r\n\tcd %BUILDDIR%/latex\r\n\tmake all-pdf-ja\r\n\tcd %~dp0\r\n\techo.\r\n\techo.Build finished; the PDF files are in %BUILDDIR%/latex.\r\n\tgoto end\r\n)\r\n\r\nif \"%1\" == \"text\" (\r\n\t%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text\r\n\tif errorlevel 1 exit /b 1\r\n\techo.\r\n\techo.Build finished. The text files are in %BUILDDIR%/text.\r\n\tgoto end\r\n)\r\n\r\nif \"%1\" == \"man\" (\r\n\t%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man\r\n\tif errorlevel 1 exit /b 1\r\n\techo.\r\n\techo.Build finished. The manual pages are in %BUILDDIR%/man.\r\n\tgoto end\r\n)\r\n\r\nif \"%1\" == \"texinfo\" (\r\n\t%SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo\r\n\tif errorlevel 1 exit /b 1\r\n\techo.\r\n\techo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.\r\n\tgoto end\r\n)\r\n\r\nif \"%1\" == \"gettext\" (\r\n\t%SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale\r\n\tif errorlevel 1 exit /b 1\r\n\techo.\r\n\techo.Build finished. The message catalogs are in %BUILDDIR%/locale.\r\n\tgoto end\r\n)\r\n\r\nif \"%1\" == \"changes\" (\r\n\t%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes\r\n\tif errorlevel 1 exit /b 1\r\n\techo.\r\n\techo.The overview file is in %BUILDDIR%/changes.\r\n\tgoto end\r\n)\r\n\r\nif \"%1\" == \"linkcheck\" (\r\n\t%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck\r\n\tif errorlevel 1 exit /b 1\r\n\techo.\r\n\techo.Link check complete; look for any errors in the above output ^\r\nor in %BUILDDIR%/linkcheck/output.txt.\r\n\tgoto end\r\n)\r\n\r\nif \"%1\" == \"doctest\" (\r\n\t%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest\r\n\tif errorlevel 1 exit /b 1\r\n\techo.\r\n\techo.Testing of doctests in the sources finished, look at the ^\r\nresults in %BUILDDIR%/doctest/output.txt.\r\n\tgoto end\r\n)\r\n\r\nif \"%1\" == \"coverage\" (\r\n\t%SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage\r\n\tif errorlevel 1 exit /b 1\r\n\techo.\r\n\techo.Testing of coverage in the sources finished, look at the ^\r\nresults in %BUILDDIR%/coverage/python.txt.\r\n\tgoto end\r\n)\r\n\r\nif \"%1\" == \"xml\" (\r\n\t%SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml\r\n\tif errorlevel 1 exit /b 1\r\n\techo.\r\n\techo.Build finished. The XML files are in %BUILDDIR%/xml.\r\n\tgoto end\r\n)\r\n\r\nif \"%1\" == \"pseudoxml\" (\r\n\t%SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml\r\n\tif errorlevel 1 exit /b 1\r\n\techo.\r\n\techo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml.\r\n\tgoto end\r\n)\r\n\r\n:end\r\n"
  },
  {
    "path": "docs/mltoolbox.classification.dnn.rst",
    "content": "mltoolbox.classification.dnn\n============================\n\n.. automodule:: mltoolbox.classification.dnn\n    :members:\n    :undoc-members:\n    :show-inheritance:\n\n.. autofunction:: mltoolbox.classification.dnn.analyze\n\n.. autofunction:: mltoolbox.classification.dnn.analyze_async\n\n.. autofunction:: mltoolbox.classification.dnn.batch_predict\n\n.. autofunction:: mltoolbox.classification.dnn.batch_predict_async\n\n.. autofunction:: mltoolbox.classification.dnn.predict\n\n.. autofunction:: mltoolbox.classification.dnn.train\n\n.. autofunction:: mltoolbox.classification.dnn.train_async\n\n"
  },
  {
    "path": "docs/mltoolbox.classification.linear.rst",
    "content": "mltoolbox.classification.linear\n===============================\n\n.. automodule:: mltoolbox.classification.linear\n    :members:\n    :undoc-members:\n    :show-inheritance:\n\n.. autofunction:: mltoolbox.classification.linear.analyze\n\n.. autofunction:: mltoolbox.classification.linear.analyze_async\n\n.. autofunction:: mltoolbox.classification.linear.batch_predict\n\n.. autofunction:: mltoolbox.classification.linear.batch_predict_async\n\n.. autofunction:: mltoolbox.classification.linear.predict\n\n.. autofunction:: mltoolbox.classification.linear.train\n\n.. autofunction:: mltoolbox.classification.linear.train_async\n\n"
  },
  {
    "path": "docs/mltoolbox.image.classification.rst",
    "content": "mltoolbox.image.classification\n==============================\n\n.. automodule:: mltoolbox.image.classification\n    :members:\n    :undoc-members:\n    :show-inheritance:\n\n.. autofunction:: mltoolbox.image.classification.preprocess\n\n.. autofunction:: mltoolbox.image.classification.preprocess_async\n\n.. autofunction:: mltoolbox.image.classification.train\n\n.. autofunction:: mltoolbox.image.classification.train_async\n\n.. autofunction:: mltoolbox.image.classification.predict\n\n.. autofunction:: mltoolbox.image.classification.batch_predict\n\n.. autofunction:: mltoolbox.image.classification.batch_predict_async\n\n"
  },
  {
    "path": "docs/mltoolbox.regression.dnn.rst",
    "content": "mltoolbox.regression.dnn\n========================\n\n.. automodule:: mltoolbox.regression.dnn\n    :members:\n    :undoc-members:\n    :show-inheritance:\n\n.. autofunction:: mltoolbox.regression.dnn.analyze\n\n.. autofunction:: mltoolbox.regression.dnn.analyze_async\n\n.. autofunction:: mltoolbox.regression.dnn.batch_predict\n\n.. autofunction:: mltoolbox.regression.dnn.batch_predict_async\n\n.. autofunction:: mltoolbox.regression.dnn.predict\n\n.. autofunction:: mltoolbox.regression.dnn.train\n\n.. autofunction:: mltoolbox.regression.dnn.train_async\n\n"
  },
  {
    "path": "docs/mltoolbox.regression.linear.rst",
    "content": "mltoolbox.regression.linear\n===========================\n\n.. automodule:: mltoolbox.regression.linear\n    :members:\n    :undoc-members:\n    :show-inheritance:\n\n.. autofunction:: mltoolbox.regression.linear.analyze\n\n.. autofunction:: mltoolbox.regression.linear.analyze_async\n\n.. autofunction:: mltoolbox.regression.linear.batch_predict\n\n.. autofunction:: mltoolbox.regression.linear.batch_predict_async\n\n.. autofunction:: mltoolbox.regression.linear.predict\n\n.. autofunction:: mltoolbox.regression.linear.train\n\n.. autofunction:: mltoolbox.regression.linear.train_async\n\n"
  },
  {
    "path": "externs/ts/require/require.d.ts",
    "content": "// Type definitions for RequireJS 2.1.20\n// Project: http://requirejs.org/\n// Definitions by: Josh Baldwin <https://github.com/jbaldwin/>\n// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped\n\n/*\nrequire-2.1.8.d.ts may be freely distributed under the MIT license.\n\nCopyright (c) 2013 Josh Baldwin https://github.com/jbaldwin/require.d.ts\n\nPermission is hereby granted, free of charge, to any person\nobtaining a copy of this software and associated documentation\nfiles (the \"Software\"), to deal in the Software without\nrestriction, including without limitation the rights to use,\ncopy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the\nSoftware is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\nOF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\nHOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nWHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\nOTHER DEALINGS IN THE SOFTWARE.\n*/\n\ndeclare module 'module' {\n\tvar mod: {\n\t\tconfig: () => any;\n\t\tid: string;\n\t\turi: string;\n\t}\n\texport = mod;\n}\n\ninterface RequireError extends Error {\n\n\t/**\n\t* The error ID that maps to an ID on a web page.\n\t**/\n\trequireType: string;\n\n\t/**\n\t* Required modules.\n\t**/\n\trequireModules: string[];\n\n\t/**\n\t* The original error, if there is one (might be null).\n\t**/\n\toriginalError: Error;\n}\n\ninterface RequireShim {\n\n\t/**\n\t* List of dependencies.\n\t**/\n\tdeps?: string[];\n\n\t/**\n\t* Name the module will be exported as.\n\t**/\n\texports?: string;\n\n\t/**\n\t* Initialize function with all dependcies passed in,\n\t* if the function returns a value then that value is used\n\t* as the module export value instead of the object\n\t* found via the 'exports' string.\n\t* @param dependencies\n\t* @return\n\t**/\n\tinit?: (...dependencies: any[]) => any;\n}\n\ninterface RequireConfig {\n\n\t// The root path to use for all module lookups.\n\tbaseUrl?: string;\n\n\t// Path mappings for module names not found directly under\n\t// baseUrl.\n\tpaths?: { [key: string]: any; };\n\n\n\t// Dictionary of Shim's.\n\t// does not cover case of key->string[]\n\tshim?: { [key: string]: RequireShim; };\n\n\t/**\n\t* For the given module prefix, instead of loading the\n\t* module with the given ID, substitude a different\n\t* module ID.\n\t*\n\t* @example\n\t* requirejs.config({\n\t*\tmap: {\n\t*\t\t'some/newmodule': {\n\t*\t\t\t'foo': 'foo1.2'\n\t*\t\t},\n\t*\t\t'some/oldmodule': {\n\t*\t\t\t'foo': 'foo1.0'\n\t*\t\t}\n\t*\t}\n\t* });\n\t**/\n\tmap?: {\n\t\t[id: string]: {\n\t\t\t[id: string]: string;\n\t\t};\n\t};\n\n\t/**\n\t* Allows pointing multiple module IDs to a module ID that contains a bundle of modules.\n\t*\n\t* @example\n\t* requirejs.config({\n\t*\tbundles: {\n\t*\t\t'primary': ['main', 'util', 'text', 'text!template.html'],\n\t*\t\t'secondary': ['text!secondary.html']\n\t*\t}\n\t* });\n\t**/\n\tbundles?: { [key: string]: string[]; };\n\n\t/**\n\t* AMD configurations, use module.config() to access in\n\t* define() functions\n\t**/\n\tconfig?: { [id: string]: {}; };\n\n\t/**\n\t* Configures loading modules from CommonJS packages.\n\t**/\n\tpackages?: {};\n\n\t/**\n\t* The number of seconds to wait before giving up on loading\n\t* a script.  The default is 7 seconds.\n\t**/\n\twaitSeconds?: number;\n\n\t/**\n\t* A name to give to a loading context.  This allows require.js\n\t* to load multiple versions of modules in a page, as long as\n\t* each top-level require call specifies a unique context string.\n\t**/\n\tcontext?: string;\n\n\t/**\n\t* An array of dependencies to load.\n\t**/\n\tdeps?: string[];\n\n\t/**\n\t* A function to pass to require that should be require after\n\t* deps have been loaded.\n\t* @param modules\n\t**/\n\tcallback?: (...modules: any[]) => void;\n\n\t/**\n\t* If set to true, an error will be thrown if a script loads\n\t* that does not call define() or have shim exports string\n\t* value that can be checked.\n\t**/\n\tenforceDefine?: boolean;\n\n\t/**\n\t* If set to true, document.createElementNS() will be used\n\t* to create script elements.\n\t**/\n\txhtml?: boolean;\n\n\t/**\n\t* Extra query string arguments appended to URLs that RequireJS\n\t* uses to fetch resources.  Most useful to cache bust when\n\t* the browser or server is not configured correctly.\n\t*\n\t* @example\n\t* urlArgs: \"bust= + (new Date()).getTime()\n\t**/\n\turlArgs?: string;\n\n\t/**\n\t* Specify the value for the type=\"\" attribute used for script\n\t* tags inserted into the document by RequireJS.  Default is\n\t* \"text/javascript\".  To use Firefox's JavasScript 1.8\n\t* features, use \"text/javascript;version=1.8\".\n\t**/\n\tscriptType?: string;\n\n\t/**\n\t* If set to true, skips the data-main attribute scanning done\n\t* to start module loading. Useful if RequireJS is embedded in\n\t* a utility library that may interact with other RequireJS\n\t* library on the page, and the embedded version should not do\n\t* data-main loading.\n\t**/\n\tskipDataMain?: boolean;\n\n\t/**\n\t* Allow extending requirejs to support Subresource Integrity\n\t* (SRI).\n\t**/\n\tonNodeCreated?: (node: HTMLScriptElement, config: RequireConfig, moduleName: string, url: string) => void;\n}\n\n// todo: not sure what to do with this guy\ninterface RequireModule {\n\n\t/**\n\t*\n\t**/\n\tconfig(): {};\n\n}\n\n/**\n*\n**/\ninterface RequireMap {\n\n\t/**\n\t*\n\t**/\n\tprefix: string;\n\n\t/**\n\t*\n\t**/\n\tname: string;\n\n\t/**\n\t*\n\t**/\n\tparentMap: RequireMap;\n\n\t/**\n\t*\n\t**/\n\turl: string;\n\n\t/**\n\t*\n\t**/\n\toriginalName: string;\n\n\t/**\n\t*\n\t**/\n\tfullName: string;\n}\n\ninterface Require {\n\n\t/**\n\t* Configure require.js\n\t**/\n\tconfig(config: RequireConfig): Require;\n\n\t/**\n\t* CommonJS require call\n\t* @param module Module to load\n\t* @return The loaded module\n\t*/\n\t(module: string): any;\n\n\t/**\n\t* Start the main app logic.\n\t* Callback is optional.\n\t* Can alternatively use deps and callback.\n\t* @param modules Required modules to load.\n\t**/\n\t(modules: string[]): void;\n\n\t/**\n\t* @see Require()\n\t* @param ready Called when required modules are ready.\n\t**/\n\t(modules: string[], ready: Function): void;\n\n\t/**\n\t* @see http://requirejs.org/docs/api.html#errbacks\n\t* @param ready Called when required modules are ready.\n\t**/\n\t(modules: string[], ready: Function, errback: Function): void;\n\n\t/**\n\t* Generate URLs from require module\n\t* @param module Module to URL\n\t* @return URL string\n\t**/\n\ttoUrl(module: string): string;\n\n\t/**\n\t* Returns true if the module has already been loaded and defined.\n\t* @param module Module to check\n\t**/\n\tdefined(module: string): boolean;\n\n\t/**\n\t* Returns true if the module has already been requested or is in the process of loading and should be available at some point.\n\t* @param module Module to check\n\t**/\n\tspecified(module: string): boolean;\n\n\t/**\n\t* On Error override\n\t* @param err\n\t**/\n\tonError(err: RequireError, errback?: (err: RequireError) => void): void;\n\n\t/**\n\t* Undefine a module\n\t* @param module Module to undefine.\n\t**/\n\tundef(module: string): void;\n\n\t/**\n\t* Semi-private function, overload in special instance of undef()\n\t**/\n\tonResourceLoad(context: Object, map: RequireMap, depArray: RequireMap[]): void;\n}\n\ninterface RequireDefine {\n\n\t/**\n\t* Define Simple Name/Value Pairs\n\t* @param config Dictionary of Named/Value pairs for the config.\n\t**/\n\t(config: { [key: string]: any; }): void;\n\n\t/**\n\t* Define function.\n\t* @param func: The function module.\n\t**/\n\t(func: () => any): void;\n\n\t/**\n\t* Define function with dependencies.\n\t* @param deps List of dependencies module IDs.\n\t* @param ready Callback function when the dependencies are loaded.\n\t*\tcallback param deps module dependencies\n\t*\tcallback return module definition\n\t**/\n    \t(deps: string[], ready: Function): void;\n\n\t/**\n\t*  Define module with simplified CommonJS wrapper.\n\t* @param ready\n\t*\tcallback require requirejs instance\n\t*\tcallback exports exports object\n\t*\tcallback module module\n\t*\tcallback return module definition\n\t**/\n\t(ready: (require: Require, exports: { [key: string]: any; }, module: RequireModule) => any): void;\n\n\t/**\n\t* Define a module with a name and dependencies.\n\t* @param name The name of the module.\n\t* @param deps List of dependencies module IDs.\n\t* @param ready Callback function when the dependencies are loaded.\n\t*\tcallback deps module dependencies\n\t*\tcallback return module definition\n\t**/\n\t(name: string, deps: string[], ready: Function): void;\n\n\t/**\n\t* Define a module with a name.\n\t* @param name The name of the module.\n\t* @param ready Callback function when the dependencies are loaded.\n\t*\tcallback return module definition\n\t**/\n\t(name: string, ready: Function): void;\n\n\t/**\n\t* Used to allow a clear indicator that a global define function (as needed for script src browser loading) conforms\n\t* to the AMD API, any global define function SHOULD have a property called \"amd\" whose value is an object.\n\t* This helps avoid conflict with any other existing JavaScript code that could have defined a define() function\n\t* that does not conform to the AMD API.\n\t* define.amd.jQuery is specific to jQuery and indicates that the loader is able to account for multiple version\n\t* of jQuery being loaded simultaneously.\n\t*/\n\tamd: Object;\n}\n\n// Ambient declarations for 'require' and 'define'\ndeclare var requirejs: Require;\ndeclare var require: Require;\ndeclare var define: RequireDefine;\n\n"
  },
  {
    "path": "google/__init__.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n"
  },
  {
    "path": "google/datalab/__init__.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom google.datalab._context import Context\nfrom google.datalab._job import Job, JobError\nimport warnings\n\n__all__ = ['Context', 'Job', 'JobError']\n\nwarnings.warn(\"Datalab is deprecated. For more information, see https://cloud.google.com/datalab/docs/resources/deprecation.\", DeprecationWarning)"
  },
  {
    "path": "google/datalab/_context.py",
    "content": "# Copyright 2014 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#  http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\"\"\"Implements Context functionality.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom builtins import object\n\nfrom google.datalab.utils import _utils as du\n\n\nclass Context(object):\n  \"\"\"Maintains contextual state for connecting to Cloud APIs.\n  \"\"\"\n\n  _global_context = None\n\n  def __init__(self, project_id, credentials, config=None):\n    \"\"\"Initializes an instance of a Context object.\n\n    Args:\n      project_id: the current cloud project.\n      credentials: the credentials to use to authorize requests.\n      config: key/value configurations for cloud operations\n    \"\"\"\n    self._project_id = project_id\n    self._credentials = credentials\n    self._config = config if config is not None else Context._get_default_config()\n\n  @property\n  def credentials(self):\n    \"\"\"Retrieves the value of the credentials property.\n\n    Returns:\n      The current credentials used in authorizing API requests.\n    \"\"\"\n    return self._credentials\n\n  def set_credentials(self, credentials):\n    \"\"\" Set the credentials for the context. \"\"\"\n    self._credentials = credentials\n\n  @property\n  def project_id(self):\n    \"\"\"Retrieves the value of the project_id property.\n\n    Returns:\n      The current project id to associate with API requests.\n    \"\"\"\n    if not self._project_id:\n      raise Exception('No project ID found. Perhaps you should set one by running'\n                      '\"%datalab project set -p <project-id>\" in a code cell.')\n    return self._project_id\n\n  def set_project_id(self, project_id):\n    \"\"\" Set the project_id for the context. \"\"\"\n    self._project_id = project_id\n    if self == Context._global_context:\n      du.save_project_id(self._project_id)\n\n  @property\n  def config(self):\n    \"\"\" Retrieves the value of the config property.\n\n    Returns:\n      The current config object used in cloud operations\n    \"\"\"\n    return self._config\n\n  def set_config(self, config):\n    \"\"\" Set the config property for the context. \"\"\"\n    self._config = config\n\n  @staticmethod\n  def _is_signed_in():\n    \"\"\" If the user has signed in or it is on GCE VM with default credential.\"\"\"\n    try:\n      du.get_credentials()\n      return True\n    except Exception:\n      return False\n\n  @staticmethod\n  def _get_default_config():\n    \"\"\"Return a default config object\"\"\"\n    return {\n      'bigquery_billing_tier': None\n    }\n\n  @staticmethod\n  def default():\n    \"\"\"Retrieves a default Context object, creating it if necessary.\n\n      The default Context is a global shared instance used every time the default context is\n      retrieved.\n\n      Attempting to use a Context with no project_id will raise an exception, so on first use\n      set_project_id must be called.\n\n    Returns:\n      An initialized and shared instance of a Context object.\n    \"\"\"\n    credentials = du.get_credentials()\n    project = du.get_default_project_id()\n    if Context._global_context is None:\n      config = Context._get_default_config()\n      Context._global_context = Context(project, credentials, config)\n    else:\n      # Always update everything in case the access token is revoked or expired, config changed,\n      # or project changed.\n      Context._global_context.set_credentials(credentials)\n      Context._global_context.set_project_id(project)\n    return Context._global_context\n"
  },
  {
    "path": "google/datalab/_job.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Implements Job functionality for async tasks.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom builtins import str\nfrom builtins import object\n\nimport concurrent.futures\nimport datetime\nimport time\nimport traceback\nimport uuid\n\n\nclass JobError(Exception):\n  \"\"\" A helper class to capture multiple components of Job errors.  \"\"\"\n\n  def __init__(self, location, message, reason):\n    self.location = location\n    self.message = message\n    self.reason = reason\n\n  def __str__(self):\n    return '%s %s %s' % (self.message, self.reason, self.location)\n\n\nclass Job(object):\n  \"\"\"A manager object for async operations.\n\n     A Job can have a Future in which case it will be able to monitor its own completion state\n     and result, or it may have no Future in which case it must be a derived class that\n     manages this some other way. We do this instead of having an abstract base class in\n     order to make wait_one/wait_all more efficient; instead of just sleeping and polling\n     we can use more reactive ways of monitoring groups of Jobs.\n  \"\"\"\n\n  _POLL_INTERVAL_SECONDS = 5\n\n  def __init__(self, job_id=None, future=None):\n    \"\"\"Initializes an instance of a Job.\n\n    Args:\n      job_id: a unique ID for the job. If None, a UUID will be generated.\n      future: the Future associated with the Job, if any.\n    \"\"\"\n    self._job_id = str(uuid.uuid4()) if job_id is None else job_id\n    self._future = future\n    self._is_complete = False\n    self._errors = None\n    self._fatal_error = None\n    self._result = None\n    self._start_time = datetime.datetime.utcnow()\n    self._end_time = None\n\n  def __str__(self):\n    return self._job_id\n\n  @property\n  def id(self):\n    \"\"\" Get the Job ID.\n\n    Returns:\n      The ID of the job.\n    \"\"\"\n    return self._job_id\n\n  @property\n  def is_complete(self):\n    \"\"\" Get the completion state of the job.\n\n    Returns:\n      True if the job is complete; False if it is still running.\n    \"\"\"\n    self._refresh_state()\n    return self._is_complete\n\n  @property\n  def failed(self):\n    \"\"\" Get the success state of the job.\n\n    Returns:\n      True if the job failed; False if it is still running or succeeded (possibly with partial\n      failure).\n    \"\"\"\n    self._refresh_state()\n    return self._is_complete and self._fatal_error is not None\n\n  @property\n  def fatal_error(self):\n    \"\"\" Get the job error.\n\n    Returns:\n      None if the job succeeded or is still running, else the error tuple for the failure.\n    \"\"\"\n    self._refresh_state()\n    return self._fatal_error\n\n  @property\n  def errors(self):\n    \"\"\" Get the non-fatal errors in the job.\n\n    Returns:\n      None if the job is still running, else the list of errors that occurred.\n    \"\"\"\n    self._refresh_state()\n    return self._errors\n\n  def result(self):\n    \"\"\" Get the result for a job. This will block if the job is incomplete.\n\n    Returns:\n      The result for the Job.\n\n    Raises:\n      An exception if the Job resulted in an exception.\n\n    \"\"\"\n    self.wait()\n    if self._fatal_error:\n      raise self._fatal_error\n    return self._result\n\n  @property\n  def start_time_utc(self):\n    \"\"\" The UTC start time of the job as a Python datetime. \"\"\"\n    return self._start_time\n\n  @property\n  def end_time_utc(self):\n    \"\"\" The UTC end time of the job (or None if incomplete) as a Python datetime. \"\"\"\n    return self._end_time\n\n  @property\n  def total_time(self):\n    \"\"\" The total time in fractional seconds that the job took, or None if not complete. \"\"\"\n    if self._end_time is None:\n      return None\n    return (self._end_time - self._start_time).total_seconds()\n\n  def _refresh_state(self):\n    \"\"\" Get the state of a job. Must be overridden by derived Job classes\n        for Jobs that don't use a Future.\n    \"\"\"\n    if self._is_complete:\n      return\n\n    if not self._future:\n      raise Exception('Please implement this in the derived class')\n\n    if self._future.done():\n      self._is_complete = True\n      self._end_time = datetime.datetime.utcnow()\n      try:\n        self._result = self._future.result()\n      except Exception as e:\n        message = str(e)\n        self._fatal_error = JobError(location=traceback.format_exc(), message=message,\n                                     reason=str(type(e)))\n\n  def _timeout(self):\n    \"\"\" Helper for raising timeout errors. \"\"\"\n    raise concurrent.futures.TimeoutError('Timed out waiting for Job %s to complete' % self._job_id)\n\n  def wait(self, timeout=None):\n    \"\"\" Wait for the job to complete, or a timeout to happen.\n\n    Args:\n      timeout: how long to wait before giving up (in seconds); default None which means no timeout.\n\n    Returns:\n      The Job\n    \"\"\"\n    if self._future:\n      try:\n        # Future.exception() will return rather than raise any exception so we use it.\n        self._future.exception(timeout)\n      except concurrent.futures.TimeoutError:\n        self._timeout()\n      self._refresh_state()\n    else:\n      # fall back to polling\n      while not self.is_complete:\n        if timeout is not None:\n          if timeout <= 0:\n            self._timeout()\n          timeout -= Job._POLL_INTERVAL_SECONDS\n        time.sleep(Job._POLL_INTERVAL_SECONDS)\n    return self\n\n  @property\n  def state(self):\n    \"\"\" Describe the state of a Job.\n\n    Returns: A string describing the job's state.\n    \"\"\"\n    state = 'in progress'\n    if self.is_complete:\n      if self.failed:\n        state = 'failed with error: %s' % str(self._fatal_error)\n      elif self._errors:\n        state = 'completed with some non-fatal errors'\n      else:\n        state = 'completed'\n    return state\n\n  def __repr__(self):\n    \"\"\" Get the notebook representation for the job. \"\"\"\n    return 'Job %s %s' % (self._job_id, self.state)\n\n  @staticmethod\n  def _wait(jobs, timeout, return_when):\n    # If a single job is passed in, make it an array for consistency\n    if isinstance(jobs, Job):\n      jobs = [jobs]\n    elif len(jobs) == 0:\n      return jobs\n\n    wait_on_one = return_when == concurrent.futures.FIRST_COMPLETED\n    completed = []\n    while True:\n      if timeout is not None:\n        timeout -= Job._POLL_INTERVAL_SECONDS\n\n      done = [job for job in jobs if job.is_complete]\n\n      if len(done):\n        completed.extend(done)\n        for job in done:\n          jobs.remove(job)\n        if wait_on_one or len(jobs) == 0:\n          return completed\n\n      if timeout is not None and timeout < 0:\n        return completed\n\n      # Need to block for some time. Favor using concurrent.futures.wait if possible\n      # as it can return early if a (thread) job is ready; else fall back to time.sleep.\n      futures = [job._future for job in jobs if job._future]\n      if len(futures) == 0:\n        time.sleep(Job._POLL_INTERVAL_SECONDS)\n      else:\n        concurrent.futures.wait(futures, timeout=Job._POLL_INTERVAL_SECONDS,\n                                return_when=return_when)\n"
  },
  {
    "path": "google/datalab/bigquery/__init__.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Google Cloud Platform library - BigQuery Functionality.\"\"\"\nfrom __future__ import absolute_import\n\nfrom ._csv_options import CSVOptions\nfrom ._dataset import Dataset, Datasets\nfrom ._external_data_source import ExternalDataSource\nfrom ._query import Query\nfrom ._query_output import QueryOutput\nfrom ._query_results_table import QueryResultsTable\nfrom ._query_stats import QueryStats\nfrom ._sampling import Sampling\nfrom ._schema import Schema, SchemaField\nfrom ._table import Table, TableMetadata\nfrom ._udf import UDF\nfrom ._utils import TableName, DatasetName\nfrom ._view import View\n\n__all__ = ['CSVOptions', 'Dataset', 'Datasets', 'ExternalDataSource', 'Query', 'QueryOutput',\n           'QueryResultsTable', 'QueryStats', 'Sampling', 'Schema', 'SchemaField', 'Table',\n           'TableMetadata', 'UDF', 'TableName', 'DatasetName', 'View']\n"
  },
  {
    "path": "google/datalab/bigquery/_api.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Implements BigQuery HTTP API wrapper.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom past.builtins import basestring\nfrom builtins import object\n\nimport google.datalab.utils\nimport google.datalab.bigquery\n\n\nclass Api(object):\n  \"\"\"A helper class to issue BigQuery HTTP requests.\"\"\"\n\n  # TODO(nikhilko): Use named placeholders in these string templates.\n  _ENDPOINT = 'https://www.googleapis.com/bigquery/v2'\n  _JOBS_PATH = '/projects/%s/jobs/%s'\n  _QUERIES_PATH = '/projects/%s/queries/%s'\n  _DATASETS_PATH = '/projects/%s/datasets/%s'\n  _TABLES_PATH = '/projects/%s/datasets/%s/tables/%s%s'\n  _TABLEDATA_PATH = '/projects/%s/datasets/%s/tables/%s%s/data'\n\n  _DEFAULT_TIMEOUT = 60000\n\n  def __init__(self, context):\n    \"\"\"Initializes the BigQuery helper with context information.\n\n    Args:\n      context: a Context object providing project_id and credentials.\n    \"\"\"\n    self._context = context\n\n  @property\n  def project_id(self):\n    \"\"\"The project_id associated with this API client.\"\"\"\n    return self._context.project_id\n\n  @property\n  def credentials(self):\n    \"\"\"The credentials associated with this API client.\"\"\"\n    return self._context.credentials\n\n  @property\n  def bigquery_billing_tier(self):\n    \"\"\"The BigQuery billing tier associated with this API client.\"\"\"\n    return self._context.config.get('bigquery_billing_tier', None)\n\n  def jobs_insert_load(self, source, table_name, append=False, overwrite=False, create=False,\n                       source_format='CSV', field_delimiter=',', allow_jagged_rows=False,\n                       allow_quoted_newlines=False, encoding='UTF-8', ignore_unknown_values=False,\n                       max_bad_records=0, quote='\"', skip_leading_rows=0):\n    \"\"\" Issues a request to load data from GCS to a BQ table\n\n    Args:\n      source: the URL of the source bucket(s). Can include wildcards, and can be a single\n          string argument or a list.\n      table_name: a tuple representing the full name of the destination table.\n      append: if True append onto existing table contents.\n      overwrite: if True overwrite existing table contents.\n      create: if True, create the table if it doesn't exist\n      source_format: the format of the data; default 'CSV'. Other options are DATASTORE_BACKUP\n          or NEWLINE_DELIMITED_JSON.\n      field_delimiter: The separator for fields in a CSV file. BigQuery converts the string to\n          ISO-8859-1 encoding, and then uses the first byte of the encoded string to split the data\n          as raw binary (default ',').\n      allow_jagged_rows: If True, accept rows in CSV files that are missing trailing optional\n          columns; the missing values are treated as nulls (default False).\n      allow_quoted_newlines: If True, allow quoted data sections in CSV files that contain newline\n          characters (default False).\n      encoding: The character encoding of the data, either 'UTF-8' (the default) or 'ISO-8859-1'.\n      ignore_unknown_values: If True, accept rows that contain values that do not match the schema;\n          the unknown values are ignored (default False).\n      max_bad_records: The maximum number of bad records that are allowed (and ignored) before\n          returning an 'invalid' error in the Job result (default 0).\n      quote: The value used to quote data sections in a CSV file; default '\"'. If your data does\n          not contain quoted sections, set the property value to an empty string. If your data\n          contains quoted newline characters, you must also enable allow_quoted_newlines.\n      skip_leading_rows: A number of rows at the top of a CSV file to skip (default 0).\n    Returns:\n      A parsed result object.\n    Raises:\n      Exception if there is an error performing the operation.\n    \"\"\"\n    url = Api._ENDPOINT + (Api._JOBS_PATH % (table_name.project_id, ''))\n    if isinstance(source, basestring):\n      source = [source]\n    write_disposition = 'WRITE_EMPTY'\n    if overwrite:\n      write_disposition = 'WRITE_TRUNCATE'\n    if append:\n      write_disposition = 'WRITE_APPEND'\n    data = {\n        'kind': 'bigquery#job',\n        'configuration': {\n            'load': {\n                'sourceUris': source,\n                'destinationTable': {\n                    'projectId': table_name.project_id,\n                    'datasetId': table_name.dataset_id,\n                    'tableId': table_name.table_id\n                },\n                'createDisposition': 'CREATE_IF_NEEDED' if create else 'CREATE_NEVER',\n                'writeDisposition': write_disposition,\n                'sourceFormat': source_format,\n                'ignoreUnknownValues': ignore_unknown_values,\n                'maxBadRecords': max_bad_records,\n            }\n        }\n    }\n    if source_format == 'CSV':\n      load_config = data['configuration']['load']\n      load_config.update({\n          'fieldDelimiter': field_delimiter,\n          'allowJaggedRows': allow_jagged_rows,\n          'allowQuotedNewlines': allow_quoted_newlines,\n          'quote': quote,\n          'encoding': encoding,\n          'skipLeadingRows': skip_leading_rows\n      })\n\n    return google.datalab.utils.Http.request(url, data=data, credentials=self.credentials)\n\n  def jobs_insert_query(self, sql, table_name=None, append=False,\n                        overwrite=False, dry_run=False, use_cache=True, batch=True,\n                        allow_large_results=False, table_definitions=None, query_params=None):\n    \"\"\"Issues a request to insert a query job.\n\n    Args:\n      sql: the SQL string representing the query to execute.\n      table_name: None for an anonymous table, or a name parts tuple for a long-lived table.\n      append: if True, append to the table if it is non-empty; else the request will fail if table\n          is non-empty unless overwrite is True.\n      overwrite: if the table already exists, truncate it instead of appending or raising an\n          Exception.\n      dry_run: whether to actually execute the query or just dry run it.\n      use_cache: whether to use past query results or ignore cache. Has no effect if destination is\n          specified.\n      batch: whether to run this as a batch job (lower priority) or as an interactive job (high\n          priority, more expensive).\n      allow_large_results: whether to allow large results (slower with some restrictions but\n          can handle big jobs).\n      table_definitions: a dictionary of ExternalDataSource names and objects for any external\n          tables referenced in the query.\n      query_params: a dictionary containing query parameter types and values, passed to BigQuery.\n    Returns:\n      A parsed result object.\n    Raises:\n      Exception if there is an error performing the operation.\n    \"\"\"\n    url = Api._ENDPOINT + (Api._JOBS_PATH % (self.project_id, ''))\n\n    data = {\n        'kind': 'bigquery#job',\n        'configuration': {\n            'query': {\n                'query': sql,\n                'useQueryCache': use_cache,\n                'allowLargeResults': allow_large_results,\n                'useLegacySql': False\n            },\n            'dryRun': dry_run,\n            'priority': 'BATCH' if batch else 'INTERACTIVE',\n        },\n    }\n\n    query_config = data['configuration']['query']\n\n    if table_definitions:\n      expanded_definitions = {}\n      for td in table_definitions:\n        expanded_definitions[td] = table_definitions[td]._to_query_json()\n      query_config['tableDefinitions'] = expanded_definitions\n\n    if table_name:\n      query_config['destinationTable'] = {\n          'projectId': table_name.project_id,\n          'datasetId': table_name.dataset_id,\n          'tableId': table_name.table_id\n      }\n      if append:\n        query_config['writeDisposition'] = \"WRITE_APPEND\"\n      elif overwrite:\n        query_config['writeDisposition'] = \"WRITE_TRUNCATE\"\n\n    if self.bigquery_billing_tier:\n        query_config['maximumBillingTier'] = self.bigquery_billing_tier\n\n    if query_params:\n      query_config['queryParameters'] = query_params\n\n    return google.datalab.utils.Http.request(url, data=data, credentials=self.credentials)\n\n  def jobs_query_results(self, job_id, project_id, page_size, timeout, start_index=0):\n    \"\"\"Issues a request to the jobs/getQueryResults method.\n\n    Args:\n      job_id: the id of job from a previously executed query.\n      project_id: the project id to use to fetch the results; use None for the default project.\n      page_size: limit to the number of rows to fetch.\n      timeout: duration (in milliseconds) to wait for the query to complete.\n      start_index: the index of the row (0-based) at which to start retrieving the page of result\n          rows.\n    Returns:\n      A parsed result object.\n    Raises:\n      Exception if there is an error performing the operation.\n    \"\"\"\n    if timeout is None:\n      timeout = Api._DEFAULT_TIMEOUT\n    if project_id is None:\n      project_id = self.project_id\n\n    args = {\n        'maxResults': page_size,\n        'timeoutMs': timeout,\n        'startIndex': start_index\n    }\n    url = Api._ENDPOINT + (Api._QUERIES_PATH % (project_id, job_id))\n    return google.datalab.utils.Http.request(url, args=args, credentials=self.credentials)\n\n  def jobs_get(self, job_id, project_id=None):\n    \"\"\"Issues a request to retrieve information about a job.\n\n    Args:\n      job_id: the id of the job\n      project_id: the project id to use to fetch the results; use None for the default project.\n    Returns:\n      A parsed result object.\n    Raises:\n      Exception if there is an error performing the operation.\n    \"\"\"\n    if project_id is None:\n      project_id = self.project_id\n    url = Api._ENDPOINT + (Api._JOBS_PATH % (project_id, job_id))\n    return google.datalab.utils.Http.request(url, credentials=self.credentials)\n\n  def datasets_insert(self, dataset_name, friendly_name=None, description=None):\n    \"\"\"Issues a request to create a dataset.\n\n    Args:\n      dataset_name: the name of the dataset to create.\n      friendly_name: (optional) the friendly name for the dataset\n      description: (optional) a description for the dataset\n    Returns:\n      A parsed result object.\n    Raises:\n      Exception if there is an error performing the operation.\n    \"\"\"\n    url = Api._ENDPOINT + (Api._DATASETS_PATH % (dataset_name.project_id, ''))\n    data = {\n        'kind': 'bigquery#dataset',\n        'datasetReference': {\n            'projectId': dataset_name.project_id,\n            'datasetId': dataset_name.dataset_id\n        },\n    }\n    if friendly_name:\n      data['friendlyName'] = friendly_name\n    if description:\n      data['description'] = description\n    return google.datalab.utils.Http.request(url, data=data, credentials=self.credentials)\n\n  def datasets_delete(self, dataset_name, delete_contents):\n    \"\"\"Issues a request to delete a dataset.\n\n    Args:\n      dataset_name: the name of the dataset to delete.\n      delete_contents: if True, any tables in the dataset will be deleted. If False and the\n          dataset is non-empty an exception will be raised.\n    Returns:\n      A parsed result object.\n    Raises:\n      Exception if there is an error performing the operation.\n    \"\"\"\n    url = Api._ENDPOINT + (Api._DATASETS_PATH % dataset_name)\n    args = {}\n    if delete_contents:\n      args['deleteContents'] = True\n    return google.datalab.utils.Http.request(url, method='DELETE', args=args,\n                                             credentials=self.credentials, raw_response=True)\n\n  def datasets_update(self, dataset_name, dataset_info):\n    \"\"\"Updates the Dataset info.\n\n    Args:\n      dataset_name: the name of the dataset to update as a tuple of components.\n      dataset_info: the Dataset resource with updated fields.\n    \"\"\"\n    url = Api._ENDPOINT + (Api._DATASETS_PATH % dataset_name)\n    return google.datalab.utils.Http.request(url, method='PUT', data=dataset_info,\n                                             credentials=self.credentials)\n\n  def datasets_get(self, dataset_name):\n    \"\"\"Issues a request to retrieve information about a dataset.\n\n    Args:\n      dataset_name: the name of the dataset\n    Returns:\n      A parsed result object.\n    Raises:\n      Exception if there is an error performing the operation.\n    \"\"\"\n    url = Api._ENDPOINT + (Api._DATASETS_PATH % dataset_name)\n    return google.datalab.utils.Http.request(url, credentials=self.credentials)\n\n  def datasets_list(self, project_id=None, max_results=0, page_token=None):\n    \"\"\"Issues a request to list the datasets in the project.\n\n    Args:\n      project_id: the project id to use to fetch the results; use None for the default project.\n      max_results: an optional maximum number of tables to retrieve.\n      page_token: an optional token to continue the retrieval.\n    Returns:\n      A parsed result object.\n    Raises:\n      Exception if there is an error performing the operation.\n    \"\"\"\n    if project_id is None:\n      project_id = self.project_id\n    url = Api._ENDPOINT + (Api._DATASETS_PATH % (project_id, ''))\n\n    args = {}\n    if max_results != 0:\n      args['maxResults'] = max_results\n    if page_token is not None:\n      args['pageToken'] = page_token\n\n    return google.datalab.utils.Http.request(url, args=args, credentials=self.credentials)\n\n  def tables_get(self, table_name):\n    \"\"\"Issues a request to retrieve information about a table.\n\n    Args:\n      table_name: a tuple representing the full name of the table.\n    Returns:\n      A parsed result object.\n    Raises:\n      Exception if there is an error performing the operation.\n    \"\"\"\n    url = Api._ENDPOINT + (Api._TABLES_PATH % table_name)\n    return google.datalab.utils.Http.request(url, credentials=self.credentials)\n\n  def tables_list(self, dataset_name, max_results=0, page_token=None):\n    \"\"\"Issues a request to retrieve a list of tables.\n\n    Args:\n      dataset_name: the name of the dataset to enumerate.\n      max_results: an optional maximum number of tables to retrieve.\n      page_token: an optional token to continue the retrieval.\n    Returns:\n      A parsed result object.\n    Raises:\n      Exception if there is an error performing the operation.\n    \"\"\"\n    url = Api._ENDPOINT +\\\n        (Api._TABLES_PATH % (dataset_name.project_id, dataset_name.dataset_id, '', ''))\n\n    args = {}\n    if max_results != 0:\n      args['maxResults'] = max_results\n    if page_token is not None:\n      args['pageToken'] = page_token\n\n    return google.datalab.utils.Http.request(url, args=args, credentials=self.credentials)\n\n  def tables_insert(self, table_name, schema=None, query=None, friendly_name=None,\n                    description=None):\n    \"\"\"Issues a request to create a table or view in the specified dataset with the specified id.\n       A schema must be provided to create a Table, or a query must be provided to create a View.\n\n    Args:\n      table_name: the name of the table as a tuple of components.\n      schema: the schema, if this is a Table creation.\n      query: the query, if this is a View creation.\n      friendly_name: an optional friendly name.\n      description: an optional description.\n    Returns:\n      A parsed result object.\n    Raises:\n      Exception if there is an error performing the operation.\n    \"\"\"\n    url = Api._ENDPOINT + \\\n        (Api._TABLES_PATH % (table_name.project_id, table_name.dataset_id, '', ''))\n\n    data = {\n        'kind': 'bigquery#table',\n        'tableReference': {\n            'projectId': table_name.project_id,\n            'datasetId': table_name.dataset_id,\n            'tableId': table_name.table_id\n        }\n    }\n    if schema:\n      data['schema'] = {'fields': schema}\n    if query:\n      data['view'] = {'query': query}\n    if friendly_name:\n      data['friendlyName'] = friendly_name\n    if description:\n      data['description'] = description\n\n    return google.datalab.utils.Http.request(url, data=data, credentials=self.credentials)\n\n  def tabledata_insert_all(self, table_name, rows):\n    \"\"\"Issues a request to insert data into a table.\n\n    Args:\n      table_name: the name of the table as a tuple of components.\n      rows: the data to populate the table, as a list of dictionaries.\n    Returns:\n      A parsed result object.\n    Raises:\n      Exception if there is an error performing the operation.\n    \"\"\"\n    url = Api._ENDPOINT + (Api._TABLES_PATH % table_name) + \"/insertAll\"\n\n    data = {\n      'kind': 'bigquery#tableDataInsertAllRequest',\n      'rows': rows\n    }\n\n    return google.datalab.utils.Http.request(url, data=data, credentials=self.credentials)\n\n  def tabledata_list(self, table_name, start_index=None, max_results=None, page_token=None):\n    \"\"\" Retrieves the contents of a table.\n\n    Args:\n      table_name: the name of the table as a tuple of components.\n      start_index: the index of the row at which to start retrieval.\n      max_results: an optional maximum number of rows to retrieve.\n      page_token: an optional token to continue the retrieval.\n    Returns:\n      A parsed result object.\n    Raises:\n      Exception if there is an error performing the operation.\n    \"\"\"\n    url = Api._ENDPOINT + (Api._TABLEDATA_PATH % table_name)\n    args = {}\n    if start_index:\n      args['startIndex'] = start_index\n    if max_results:\n      args['maxResults'] = max_results\n    if page_token is not None:\n      args['pageToken'] = page_token\n    return google.datalab.utils.Http.request(url, args=args, credentials=self.credentials)\n\n  def table_delete(self, table_name):\n    \"\"\"Issues a request to delete a table.\n\n    Args:\n      table_name: the name of the table as a tuple of components.\n    Returns:\n      A parsed result object.\n    Raises:\n      Exception if there is an error performing the operation.\n    \"\"\"\n    url = Api._ENDPOINT + (Api._TABLES_PATH % table_name)\n    return google.datalab.utils.Http.request(url, method='DELETE',\n                                             credentials=self.credentials,\n                                             raw_response=True)\n\n  def table_extract(self, table_name, destination, format='CSV', compress=True,\n                    field_delimiter=',', print_header=True):\n    \"\"\"Exports the table to GCS.\n\n    Args:\n      table_name: the name of the table as a tuple of components.\n      destination: the destination URI(s). Can be a single URI or a list.\n      format: the format to use for the exported data; one of CSV, NEWLINE_DELIMITED_JSON or AVRO.\n          Defaults to CSV.\n      compress: whether to compress the data on export. Compression is not supported for\n          AVRO format. Defaults to False.\n      field_delimiter: for CSV exports, the field delimiter to use. Defaults to ','\n      print_header: for CSV exports, whether to include an initial header line. Default true.\n    Returns:\n      A parsed result object.\n    Raises:\n      Exception if there is an error performing the operation.\n    \"\"\"\n    url = Api._ENDPOINT + (Api._JOBS_PATH % (table_name.project_id, ''))\n    if isinstance(destination, basestring):\n      destination = [destination]\n    data = {\n        # 'projectId': table_name.project_id, # Code sample shows this but it is not in job\n        # reference spec. Filed as b/19235843\n        'kind': 'bigquery#job',\n        'configuration': {\n            'extract': {\n                'sourceTable': {\n                    'projectId': table_name.project_id,\n                    'datasetId': table_name.dataset_id,\n                    'tableId': table_name.table_id,\n                },\n                'compression': 'GZIP' if compress else 'NONE',\n                'fieldDelimiter': field_delimiter,\n                'printHeader': print_header,\n                'destinationUris': destination,\n                'destinationFormat': format,\n            }\n        }\n    }\n    return google.datalab.utils.Http.request(url, data=data, credentials=self.credentials)\n\n  def table_update(self, table_name, table_info):\n    \"\"\"Updates the Table info.\n\n    Args:\n      table_name: the name of the table to update as a tuple of components.\n      table_info: the Table resource with updated fields.\n    \"\"\"\n    url = Api._ENDPOINT + (Api._TABLES_PATH % table_name)\n    return google.datalab.utils.Http.request(url, method='PUT', data=table_info,\n                                             credentials=self.credentials)\n"
  },
  {
    "path": "google/datalab/bigquery/_csv_options.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Implements CSV options for External Tables and Table loads from GCS.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom builtins import object\n\n\nclass CSVOptions(object):\n\n  def __init__(self, delimiter=',', skip_leading_rows=0, encoding='utf-8', quote='\"',\n               allow_quoted_newlines=False, allow_jagged_rows=False):\n\n    \"\"\" Initialize an instance of CSV options.\n\n    Args:\n      delimiter: The separator for fields in a CSV file. BigQuery converts the string to\n          ISO-8859-1 encoding, and then uses the first byte of the encoded string to split the data\n          as raw binary (default ',').\n      skip_leading_rows: A number of rows at the top of a CSV file to skip (default 0).\n      encoding: The character encoding of the data, either 'utf-8' (the default) or 'iso-8859-1'.\n      quote: The value used to quote data sections in a CSV file; default '\"'. If your data does\n          not contain quoted sections, set the property value to an empty string. If your data\n          contains quoted newline characters, you must also enable allow_quoted_newlines.\n      allow_quoted_newlines: If True, allow quoted data sections in CSV files that contain newline\n          characters (default False).\n      allow_jagged_rows: If True, accept rows in CSV files that are missing trailing optional\n          columns; the missing values are treated as nulls (default False).\n    \"\"\"\n    encoding_upper = encoding.upper()\n    if encoding_upper != 'UTF-8' and encoding_upper != 'ISO-8859-1':\n      raise Exception(\"Invalid source encoding %s\" % encoding)\n\n    self._delimiter = delimiter\n    self._skip_leading_rows = skip_leading_rows\n    self._encoding = encoding\n    self._quote = quote\n    self._allow_quoted_newlines = allow_quoted_newlines\n    self._allow_jagged_rows = allow_jagged_rows\n\n  @property\n  def delimiter(self):\n    return self._delimiter\n\n  @property\n  def skip_leading_rows(self):\n    return self._skip_leading_rows\n\n  @property\n  def encoding(self):\n    return self._encoding\n\n  @property\n  def quote(self):\n      return self._quote\n\n  @property\n  def allow_quoted_newlines(self):\n    return self._allow_quoted_newlines\n\n  @property\n  def allow_jagged_rows(self):\n    return self._allow_jagged_rows\n\n  def _to_query_json(self):\n    \"\"\" Return the options as a dictionary to be used as JSON in a query job. \"\"\"\n    return {\n      'quote': self._quote,\n      'fieldDelimiter': self._delimiter,\n      'encoding': self._encoding.upper(),\n      'skipLeadingRows': self._skip_leading_rows,\n      'allowQuotedNewlines': self._allow_quoted_newlines,\n      'allowJaggedRows': self._allow_jagged_rows\n    }\n"
  },
  {
    "path": "google/datalab/bigquery/_dataset.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Implements Dataset, and related Dataset BigQuery APIs.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom builtins import object\n\nimport google.datalab\nimport google.datalab.utils\n\nfrom . import _api\nfrom . import _table\nfrom . import _utils\nfrom . import _view\n\n\nclass Dataset(object):\n  \"\"\"Represents a list of BigQuery tables in a dataset.\"\"\"\n\n  def __init__(self, name, context=None):\n    \"\"\"Initializes an instance of a Dataset.\n\n    Args:\n      name: the name of the dataset, as a string or (project_id, dataset_id) tuple.\n      context: an optional Context object providing project_id and credentials. If a specific\n          project id or credentials are unspecified, the default ones configured at the global\n          level are used.\n    Raises:\n      Exception if the name is invalid.\n      \"\"\"\n    if context is None:\n      context = google.datalab.Context.default()\n    self._context = context\n    self._api = _api.Api(context)\n    self._name_parts = _utils.parse_dataset_name(name, self._api.project_id)\n    self._full_name = '%s.%s' % self._name_parts\n    self._info = None\n    try:\n      self._info = self._get_info()\n    except google.datalab.utils.RequestException:\n      pass\n\n  @property\n  def name(self):\n    \"\"\"The DatasetName named tuple (project_id, dataset_id) for the dataset.\"\"\"\n    return self._name_parts\n\n  @property\n  def description(self):\n    \"\"\"The description of the dataset, if any.\n\n    Raises:\n      Exception if the dataset exists but the metadata for the dataset could not be retrieved.\n    \"\"\"\n    self._get_info()\n    return self._info['description'] if self._info else None\n\n  @property\n  def friendly_name(self):\n    \"\"\"The friendly name of the dataset, if any.\n\n    Raises:\n      Exception if the dataset exists but the metadata for the dataset could not be retrieved.\n    \"\"\"\n    self._get_info()\n    return self._info['friendlyName'] if self._info else None\n\n  def _get_info(self):\n    try:\n      if self._info is None:\n        self._info = self._api.datasets_get(self._name_parts)\n      return self._info\n    except google.datalab.utils.RequestException as e:\n      if e.status == 404:\n        return None\n      raise e\n    except Exception as e:\n      raise e\n\n  def exists(self):\n    \"\"\" Checks if the dataset exists.\n\n    Returns:\n      True if the dataset exists; False otherwise.\n    Raises:\n      Exception if the dataset exists but the metadata for the dataset could not be retrieved.\n    \"\"\"\n    self._get_info()\n    return self._info is not None\n\n  def delete(self, delete_contents=False):\n    \"\"\"Issues a request to delete the dataset.\n\n    Args:\n      delete_contents: if True, any tables and views in the dataset will be deleted. If False\n          and the dataset is non-empty an exception will be raised.\n    Returns:\n      None on success.\n    Raises:\n      Exception if the delete fails (including if table was nonexistent).\n    \"\"\"\n    if not self.exists():\n      raise Exception('Cannot delete non-existent dataset %s' % self._full_name)\n    try:\n      self._api.datasets_delete(self._name_parts, delete_contents=delete_contents)\n    except Exception as e:\n      raise e\n    self._info = None\n    return None\n\n  def create(self, friendly_name=None, description=None):\n    \"\"\"Creates the Dataset with the specified friendly name and description.\n\n    Args:\n      friendly_name: (optional) the friendly name for the dataset if it is being created.\n      description: (optional) a description for the dataset if it is being created.\n    Returns:\n      The Dataset.\n    Raises:\n      Exception if the Dataset could not be created.\n    \"\"\"\n    if not self.exists():\n      try:\n        response = self._api.datasets_insert(self._name_parts,\n                                             friendly_name=friendly_name,\n                                             description=description)\n      except Exception as e:\n        raise e\n      if 'selfLink' not in response:\n        raise Exception(\"Could not create dataset %s\" % self._full_name)\n    return self\n\n  def update(self, friendly_name=None, description=None):\n    \"\"\" Selectively updates Dataset information.\n\n    Args:\n      friendly_name: if not None, the new friendly name.\n      description: if not None, the new description.\n\n    Returns:\n    \"\"\"\n    self._get_info()\n\n    if self._info:\n      if friendly_name:\n        self._info['friendlyName'] = friendly_name\n      if description:\n        self._info['description'] = description\n      try:\n        self._api.datasets_update(self._name_parts, self._info)\n      except Exception as e:\n        raise e\n      finally:\n        self._info = None  # need a refresh\n\n  def _retrieve_items(self, page_token, item_type):\n    try:\n      list_info = self._api.tables_list(self._name_parts, page_token=page_token)\n    except Exception as e:\n      raise e\n\n    tables = list_info.get('tables', [])\n    contents = []\n    if len(tables):\n      try:\n        for info in tables:\n          if info['type'] != item_type:\n            continue\n          if info['type'] == 'TABLE':\n            item = _table.Table((info['tableReference']['projectId'],\n                                 info['tableReference']['datasetId'],\n                                 info['tableReference']['tableId']), self._context)\n          else:\n            item = _view.View((info['tableReference']['projectId'],\n                               info['tableReference']['datasetId'],\n                               info['tableReference']['tableId']), self._context)\n          contents.append(item)\n      except KeyError:\n        raise Exception('Unexpected item list response')\n\n    page_token = list_info.get('nextPageToken', None)\n    return contents, page_token\n\n  def _retrieve_tables(self, page_token, _):\n    return self._retrieve_items(page_token=page_token, item_type='TABLE')\n\n  def _retrieve_views(self, page_token, _):\n    return self._retrieve_items(page_token=page_token, item_type='VIEW')\n\n  def tables(self):\n    \"\"\" Returns an iterator for iterating through the Tables in the dataset. \"\"\"\n    return iter(google.datalab.utils.Iterator(self._retrieve_tables))\n\n  def views(self):\n    \"\"\" Returns an iterator for iterating through the Views in the dataset. \"\"\"\n    return iter(google.datalab.utils.Iterator(self._retrieve_views))\n\n  def __iter__(self):\n    \"\"\" Returns an iterator for iterating through the Tables in the dataset. \"\"\"\n    return self.tables()\n\n  def __str__(self):\n    \"\"\"Returns a string representation of the dataset using its specified name.\n\n    Returns:\n      The string representation of this object.\n    \"\"\"\n    return self._full_name\n\n  def __repr__(self):\n    \"\"\"Returns a representation for the dataset for showing in the notebook.\n    \"\"\"\n    return 'Dataset %s' % self._full_name\n\n\nclass Datasets(object):\n  \"\"\" Iterator class for enumerating the datasets in a project. \"\"\"\n\n  def __init__(self, context=None):\n    \"\"\" Initialize the Datasets object.\n\n    Args:\n      context: an optional Context object providing project_id and credentials. If a specific\n          project id or credentials are unspecified, the default ones configured at the global\n          level are used.\n    \"\"\"\n    if context is None:\n      context = google.datalab.Context.default()\n    self._context = context\n    self._api = _api.Api(context)\n    self._project_id = context.project_id if context else self._api.project_id\n    self._page_size = 0\n\n  def _retrieve_datasets(self, page_token, _):\n    try:\n      list_info = self._api.datasets_list(self._project_id, max_results=self._page_size,\n                                          page_token=page_token)\n    except Exception as e:\n      raise e\n\n    datasets = list_info.get('datasets', [])\n    if len(datasets):\n      self._page_size = self._page_size or len(datasets)\n      try:\n        datasets = [Dataset((info['datasetReference']['projectId'],\n                             info['datasetReference']['datasetId']), self._context)\n                    for info in datasets]\n      except KeyError:\n        raise Exception('Unexpected response from server.')\n\n    page_token = list_info.get('nextPageToken', None)\n    return datasets, page_token\n\n  def __iter__(self):\n    \"\"\" Returns an iterator for iterating through the Datasets in the project.\n    \"\"\"\n    return iter(google.datalab.utils.Iterator(self._retrieve_datasets))\n"
  },
  {
    "path": "google/datalab/bigquery/_external_data_source.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Implements External Table functionality.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom builtins import object\n\nfrom . import _csv_options\n\n\nclass ExternalDataSource(object):\n\n  def __init__(self, source, source_format='csv', csv_options=None, ignore_unknown_values=False,\n               max_bad_records=0, compressed=False, schema=None):\n\n    \"\"\" Create an external table for a GCS object.\n\n    Args:\n      source: the URL of the source objects(s). Can include a wildcard '*' at the end of the item\n         name. Can be a single source or a list.\n      source_format: the format of the data, 'csv' or 'json'; default 'csv'.\n      csv_options: For CSV files, the options such as quote character and delimiter.\n      ignore_unknown_values: If True, accept rows that contain values that do not match the schema;\n          the unknown values are ignored (default False).\n      max_bad_records: The maximum number of bad records that are allowed (and ignored) before\n          returning an 'invalid' error in the Job result (default 0).\n      compressed: whether the data is GZ compressed or not (default False). Note that compressed\n          data can be used as an external data source but cannot be loaded into a BQ Table.\n      schema: the schema of the data. This is required for this table to be used as an external\n          data source or to be loaded using a Table object that itself has no schema (default None).\n\n  \"\"\"\n    # Do some sanity checking and concert some params from friendly form to form used by BQ.\n    if source_format == 'csv':\n      self._bq_source_format = 'CSV'\n      if csv_options is None:\n        csv_options = _csv_options.CSVOptions()  # use defaults\n    elif source_format == 'json':\n      if csv_options:\n        raise Exception('CSV options are not support for JSON tables')\n      self._bq_source_format = 'NEWLINE_DELIMITED_JSON'\n    else:\n      raise Exception(\"Invalid source format %s\" % source_format)\n\n    self._source = source if isinstance(source, list) else [source]\n    self._source_format = source_format\n    self._csv_options = csv_options\n    self._ignore_unknown_values = ignore_unknown_values\n    self._max_bad_records = max_bad_records\n    self._compressed = compressed\n    self._schema = schema\n\n  @property\n  def schema(self):\n    return self._schema\n\n  def __repr__(self):\n    return 'BigQuery External Datasource - paths: %s' % (','.join(self._source))\n\n  def _to_query_json(self):\n    \"\"\" Return the table as a dictionary to be used as JSON in a query job. \"\"\"\n    json = {\n      'compression': 'GZIP' if self._compressed else 'NONE',\n      'ignoreUnknownValues': self._ignore_unknown_values,\n      'maxBadRecords': self._max_bad_records,\n      'sourceFormat': self._bq_source_format,\n      'sourceUris': self._source,\n    }\n    if self._source_format == 'csv' and self._csv_options:\n      json['csvOptions'] = {}\n      json['csvOptions'].update(self._csv_options._to_query_json())\n    if self._schema:\n      json['schema'] = {'fields': self._schema._bq_schema}\n    return json\n"
  },
  {
    "path": "google/datalab/bigquery/_job.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Implements BigQuery Job functionality.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom __future__ import division\n\nimport datetime\n\nimport google.datalab\n\nfrom google.datalab.utils._gcp_job import GCPJob\n\nfrom . import _api\n\n\nclass Job(GCPJob):\n  \"\"\"Represents a BigQuery Job.\n  \"\"\"\n\n  def __init__(self, job_id, context):\n    \"\"\"Initializes an instance of a Job.\n\n    Args:\n      job_id: the BigQuery job ID corresponding to this job.\n      context: a Context object providing project_id and credentials.\n    \"\"\"\n    super(Job, self).__init__(job_id, context)\n\n  def _create_api(self, context):\n    return _api.Api(context)\n\n  def _refresh_state(self):\n    \"\"\" Get the state of a job. If the job is complete this does nothing;\n        otherwise it gets a refreshed copy of the job resource.\n    \"\"\"\n    # TODO(gram): should we put a choke on refreshes? E.g. if the last call was less than\n    # a second ago should we return the cached value?\n    if self._is_complete:\n      return\n\n    try:\n      response = self._api.jobs_get(self._job_id)\n    except Exception as e:\n      raise e\n\n    if 'status' in response:\n      status = response['status']\n      if 'state' in status and status['state'] == 'DONE':\n        self._end_time = datetime.datetime.utcnow()\n        self._is_complete = True\n        self._process_job_status(status)\n\n    if 'statistics' in response:\n      statistics = response['statistics']\n      start_time = statistics.get('creationTime', None)\n      end_time = statistics.get('endTime', None)\n      if start_time and end_time and end_time >= start_time:\n        self._start_time = datetime.datetime.fromtimestamp(float(start_time) / 1000.0)\n        self._end_time = datetime.datetime.fromtimestamp(float(end_time) / 1000.0)\n\n  def _process_job_status(self, status):\n    if 'errorResult' in status:\n      error_result = status['errorResult']\n      location = error_result.get('location', None)\n      message = error_result.get('message', None)\n      reason = error_result.get('reason', None)\n      self._fatal_error = google.datalab.JobError(location, message, reason)\n    if 'errors' in status:\n      self._errors = []\n      for error in status['errors']:\n        location = error.get('location', None)\n        message = error.get('message', None)\n        reason = error.get('reason', None)\n        self._errors.append(google.datalab.JobError(location, message, reason))\n"
  },
  {
    "path": "google/datalab/bigquery/_parser.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Implements BigQuery related data parsing helpers.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import unicode_literals\nfrom builtins import zip\nfrom builtins import str\nfrom builtins import object\n\nimport datetime\n\n\nclass Parser(object):\n  \"\"\"A set of helper functions to parse data in BigQuery responses.\"\"\"\n\n  def __init__(self):\n    pass\n\n  @staticmethod\n  def parse_row(schema, data):\n    \"\"\"Parses a row from query results into an equivalent object.\n\n    Args:\n      schema: the array of fields defining the schema of the data.\n      data: the JSON row from a query result.\n    Returns:\n      The parsed row object.\n    \"\"\"\n    def parse_value(data_type, value):\n      \"\"\"Parses a value returned from a BigQuery response.\n\n      Args:\n        data_type: the type of the value as specified by the schema.\n        value: the raw value to return (before casting to data_type).\n\n      Returns:\n        The value cast to the data_type.\n      \"\"\"\n      if value is not None:\n        if value == 'null':\n          value = None\n        elif data_type == 'INTEGER':\n          value = int(value)\n        elif data_type == 'FLOAT':\n          value = float(value)\n        elif data_type == 'TIMESTAMP':\n          value = datetime.datetime.utcfromtimestamp(float(value))\n        elif data_type == 'BOOLEAN':\n          value = value == 'true'\n        elif (type(value) != str):\n          # TODO(gram): Handle nested JSON records\n          value = str(value)\n      return value\n\n    row = {}\n    if data is None:\n      return row\n\n    for i, (field, schema_field) in enumerate(zip(data['f'], schema)):\n      val = field['v']\n      name = schema_field['name']\n      data_type = schema_field['type']\n      repeated = True if 'mode' in schema_field and schema_field['mode'] == 'REPEATED' else False\n\n      if repeated and val is None:\n        row[name] = []\n      elif data_type == 'RECORD':\n        sub_schema = schema_field['fields']\n        if repeated:\n          row[name] = [Parser.parse_row(sub_schema, v['v']) for v in val]\n        else:\n          row[name] = Parser.parse_row(sub_schema, val)\n      elif repeated:\n        row[name] = [parse_value(data_type, v['v']) for v in val]\n      else:\n        row[name] = parse_value(data_type, val)\n\n    return row\n\n  @staticmethod\n  def parse_timestamp(value):\n    \"\"\"Parses a timestamp.\n\n    Args:\n      value: the number of milliseconds since epoch.\n    \"\"\"\n    return datetime.datetime.utcfromtimestamp(float(value) / 1000.0)\n"
  },
  {
    "path": "google/datalab/bigquery/_query.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Implements Query BigQuery API.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom builtins import object\n\nimport datetime\nimport google.datalab\nimport google.datalab.data\nimport google.datalab.utils\nimport six\n\nfrom ._query_output import QueryOutput\nfrom . import _api\nfrom . import _query_job\nfrom . import _udf\nfrom . import _utils\nfrom . import _external_data_source\n\n\nclass Query(object):\n  \"\"\"Represents a Query object that encapsulates a BigQuery SQL query.\n\n  This object can be used to execute SQL queries and retrieve results.\n  \"\"\"\n\n  def __init__(self, sql, env=None, udfs=None, data_sources=None, subqueries=None):\n    \"\"\"Initializes an instance of a Query object.\n\n    Args:\n      sql: the BigQuery SQL query string to execute\n      env: a dictionary containing objects from the query execution context, used to get references\n          to UDFs, subqueries, and external data sources referenced by the query\n      udfs: list of UDFs names referenced in the SQL, or dictionary of names and UDF objects\n      data_sources: list of external data sources names referenced in the SQL, or dictionary of\n          names and data source objects\n      subqueries: list of subqueries names referenced in the SQL, or dictionary of names and\n          Query objects\n\n    Raises:\n      Exception if expansion of any variables failed.\n      \"\"\"\n    self._sql = sql\n    self._udfs = []\n    self._subqueries = []\n    self._data_sources = []\n    self._env = env or {}\n\n    # Validate given list or dictionary of objects that they are of correct type\n    # and add them to the target dictionary\n    def _expand_objects(obj_container, obj_type, target_list):\n      for item in obj_container:\n        # for a list of objects, we should find these objects in the given environment\n        if isinstance(obj_container, list):\n          value = self._env.get(item)\n          if value is None:\n            raise Exception('Cannot find object %s' % item)\n\n        # for a dictionary of objects, each pair must be a string and object of the expected type\n        elif isinstance(obj_container, dict):\n          value = obj_container[item]\n          if not isinstance(value, obj_type):\n            raise Exception('Expected type: %s, found: %s.' % (obj_type, type(value)))\n\n        else:\n          raise Exception('Unexpected container for type %s. Expected a list or dictionary'\n                          % obj_type)\n\n        target_list.append((item, value))\n\n    if subqueries:\n      _expand_objects(subqueries, Query, self._subqueries)\n    if udfs:\n      _expand_objects(udfs, _udf.UDF, self._udfs)\n    if data_sources:\n      _expand_objects(data_sources, _external_data_source.ExternalDataSource, self._data_sources)\n\n    if len(self._data_sources) > 1:\n      raise Exception('Only one temporary external datasource is supported in queries.')\n\n  @staticmethod\n  def from_view(view):\n    \"\"\" Return a Query for the given View object\n\n    Args:\n      view: the View object to construct a Query out of\n\n    Returns:\n      A Query object with the same sql as the given View object\n    \"\"\"\n    return Query('SELECT * FROM %s' % view._repr_sql_())\n\n  @staticmethod\n  def from_table(table, fields=None):\n    \"\"\" Return a Query for the given Table object\n\n    Args:\n      table: the Table object to construct a Query out of\n      fields: the fields to return. If None, all fields will be returned. This can be a string\n          which will be injected into the Query after SELECT, or a list of field names.\n\n    Returns:\n      A Query object that will return the specified fields from the records in the Table.\n    \"\"\"\n    if fields is None:\n      fields = '*'\n    elif isinstance(fields, list):\n      fields = ','.join(fields)\n    return Query('SELECT %s FROM %s' % (fields, table._repr_sql_()))\n\n  def _expanded_sql(self, sampling=None):\n    \"\"\"Get the expanded SQL of this object, including all subqueries, UDFs, and external datasources\n\n    Returns:\n      The expanded SQL string of this object\n    \"\"\"\n\n    # use lists to preserve the order of subqueries, bigquery will not like listing subqueries\n    # out of order if they depend on each other. for example. the following will be rejected:\n    # WITH q2 as (SELECT * FROM q1),\n    #      q1 as (SELECT * FROM mytable),\n    # SELECT * FROM q2\n    # so when we're getting the dependencies, use recursion into a list to maintain the order\n    udfs = []\n    subqueries = []\n    expanded_sql = ''\n\n    def _recurse_subqueries(query):\n      \"\"\"Recursively scan subqueries and add their pieces to global scope udfs and subqueries\n      \"\"\"\n      if query._subqueries:\n        for subquery in query._subqueries:\n          _recurse_subqueries(subquery[1])\n        subqueries.extend([s for s in query._subqueries if s not in subqueries])\n      if query._udfs:\n        # query._udfs is a list of (name, UDF) tuples; we just want the UDF.\n        udfs.extend([u[1] for u in query._udfs if u[1] not in udfs])\n\n    _recurse_subqueries(self)\n\n    if udfs:\n      expanded_sql += '\\n'.join([udf._expanded_sql() for udf in udfs])\n      expanded_sql += '\\n'\n\n    def _indent_query(subquery):\n      return '  ' + subquery._sql.replace('\\n', '\\n  ')\n\n    if subqueries:\n      expanded_sql += 'WITH ' + \\\n                      '\\n),\\n'.join(['%s AS (\\n%s' % (sq[0], _indent_query(sq[1]))\n                                     for sq in subqueries])\n      expanded_sql += '\\n)\\n\\n'\n\n    expanded_sql += sampling(self._sql) if sampling else self._sql\n\n    return expanded_sql\n\n  def _repr_sql_(self):\n    \"\"\"Creates a SQL representation of this object.\n\n    Returns:\n      The SQL representation to use when embedding this object into other SQL.\n    \"\"\"\n    return '(%s)' % self.sql\n\n  def __repr__(self):\n    \"\"\"Creates a friendly representation of this object.\n\n    Returns:\n      The friendly representation of this object (the unmodified SQL).\n    \"\"\"\n    return 'BigQuery Query - %s' % self._sql\n\n  @property\n  def sql(self):\n    \"\"\" Get the SQL for the query. \"\"\"\n    return self._expanded_sql()\n\n  @property\n  def udfs(self):\n    \"\"\" Get a dictionary of UDFs referenced by the query.\"\"\"\n    return dict(self._udfs)\n\n  @property\n  def subqueries(self):\n    \"\"\" Get a dictionary of subqueries referenced by the query.\"\"\"\n    return dict(self._subqueries)\n\n  @property\n  def data_sources(self):\n    \"\"\" Get a dictionary of external data sources referenced by the query.\"\"\"\n    return dict(self._data_sources)\n\n  def dry_run(self, context=None, query_params=None):\n    \"\"\"Dry run a query, to check the validity of the query and return some useful statistics.\n\n    Args:\n      context: an optional Context object providing project_id and credentials. If a specific\n          project id or credentials are unspecified, the default ones configured at the global\n          level are used.\n      query_params: a dictionary containing query parameter types and values, passed to BigQuery.\n\n    Returns:\n      A dict with 'cacheHit' and 'totalBytesProcessed' fields.\n    Raises:\n      An exception if the query was malformed.\n    \"\"\"\n\n    context = context or google.datalab.Context.default()\n    api = _api.Api(context)\n    try:\n      query_result = api.jobs_insert_query(self.sql, dry_run=True,\n                                           table_definitions=self.data_sources,\n                                           query_params=query_params)\n    except Exception as e:\n      raise e\n    return query_result['statistics']['query']\n\n  def execute_async(self, output_options=None, sampling=None, context=None, query_params=None):\n    \"\"\" Initiate the query and return a QueryJob.\n\n    Args:\n      output_options: a QueryOutput object describing how to execute the query\n      sampling: sampling function to use. No sampling is done if None. See bigquery.Sampling\n      context: an optional Context object providing project_id and credentials. If a specific\n          project id or credentials are unspecified, the default ones configured at the global\n          level are used.\n      query_params: a dictionary containing query parameter types and values, passed to BigQuery.\n    Returns:\n      A Job object that can wait on creating a table or exporting to a file\n      If the output is a table, the Job object additionally has run statistics\n      and query results\n    Raises:\n      Exception if query could not be executed.\n    \"\"\"\n\n    # Default behavior is to execute to a table\n    if output_options is None:\n      output_options = QueryOutput.table()\n\n    # First, execute the query into a table, using a temporary one if no name is specified\n    batch = output_options.priority == 'low'\n    append = output_options.table_mode == 'append'\n    overwrite = output_options.table_mode == 'overwrite'\n    table_name = output_options.table_name\n    context = context or google.datalab.Context.default()\n    api = _api.Api(context)\n    if table_name is not None:\n      table_name = _utils.parse_table_name(table_name, api.project_id)\n\n    sql = self._expanded_sql(sampling)\n\n    try:\n      query_result = api.jobs_insert_query(sql, table_name=table_name,\n                                           append=append, overwrite=overwrite, batch=batch,\n                                           use_cache=output_options.use_cache,\n                                           allow_large_results=output_options.allow_large_results,\n                                           table_definitions=self.data_sources,\n                                           query_params=query_params)\n    except Exception as e:\n      raise e\n    if 'jobReference' not in query_result:\n      raise Exception('Unexpected response from server')\n\n    job_id = query_result['jobReference']['jobId']\n    if not table_name:\n      try:\n        destination = query_result['configuration']['query']['destinationTable']\n        table_name = (destination['projectId'], destination['datasetId'], destination['tableId'])\n      except KeyError:\n        # The query was in error\n        raise Exception(_utils.format_query_errors(query_result['status']['errors']))\n\n    execute_job = _query_job.QueryJob(job_id, table_name, sql, context=context)\n\n    # If all we need is to execute the query to a table, we're done\n    if output_options.type == 'table':\n      return execute_job\n    # Otherwise, build an async Job that waits on the query execution then carries out\n    # the specific export operation\n    else:\n      export_args = export_kwargs = None\n      if output_options.type == 'file':\n        if output_options.file_path.startswith('gs://'):\n          export_func = execute_job.result().extract\n          export_args = [output_options.file_path]\n          export_kwargs = {\n            'format': output_options.file_format,\n            'csv_delimiter': output_options.csv_delimiter,\n            'csv_header': output_options.csv_header,\n            'compress': output_options.compress_file\n          }\n        else:\n          export_func = execute_job.result().to_file\n          export_args = [output_options.file_path]\n          export_kwargs = {\n            'format': output_options.file_format,\n            'csv_delimiter': output_options.csv_delimiter,\n            'csv_header': output_options.csv_header\n          }\n      elif output_options.type == 'dataframe':\n        export_func = execute_job.result().to_dataframe\n        export_args = []\n        export_kwargs = {\n          'start_row': output_options.dataframe_start_row,\n          'max_rows': output_options.dataframe_max_rows\n        }\n\n      # Perform the export operation with the specified parameters\n      export_func = google.datalab.utils.async_function(export_func)\n      return export_func(*export_args, **export_kwargs)\n\n  def execute(self, output_options=None, sampling=None, context=None, query_params=None):\n    \"\"\" Initiate the query and return a QueryJob.\n\n    Args:\n      output_options: a QueryOutput object describing how to execute the query\n      sampling: sampling function to use. No sampling is done if None. See bigquery.Sampling\n      context: an optional Context object providing project_id and credentials. If a specific\n          project id or credentials are unspecified, the default ones configured at the global\n          level are used.\n    Returns:\n      A Job object that can be used to get the query results, or export to a file or dataframe\n    Raises:\n      Exception if query could not be executed.\n    \"\"\"\n    return self.execute_async(output_options, sampling=sampling, context=context,\n                              query_params=query_params).wait()\n\n  @staticmethod\n  def get_query_parameters(config_parameters, date_time=datetime.datetime.now()):\n    \"\"\" Merge the given parameters with the airflow macros. Enables macros (like '@_ds') in sql.\n\n    Args:\n      config_parameters: The user-specified list of parameters in the cell-body.\n      date_time: The timestamp at which the parameters need to be evaluated. E.g. when the table\n          is <project-id>.<dataset-id>.logs_%(_ds)s, the '_ds' evaluates to the current date-time.\n\n    Returns:\n      A list of query parameters that are in the format for the BQ service\n    \"\"\"\n    merged_parameters = Query.merge_parameters(config_parameters, date_time=date_time,\n                                               macros=False, types_and_values=True)\n    # We're exposing a simpler schema format than the one actually required by BigQuery to make\n    # magics easier. We need to convert between the two formats\n    parsed_params = []\n    for key, value in merged_parameters.items():\n      parsed_params.append({\n        'name': key,\n        'parameterType': {\n          'type': value['type']\n        },\n        'parameterValue': {\n          'value': value['value']\n        }\n      })\n    return parsed_params\n\n  @staticmethod\n  def resolve_parameters(value, parameters, date_time=datetime.datetime.now(), macros=False):\n    \"\"\" Resolve a format modifier with the corresponding value.\n\n    Args:\n      value: The string (path, table, or any other artifact in a cell_body) which may have format\n          modifiers. E.g. a table name could be <project-id>.<dataset-id>.logs_%(_ds)s\n      parameters: The user-specified list of parameters in the cell-body.\n      date_time: The timestamp at which the parameters need to be evaluated. E.g. when the table\n          is <project-id>.<dataset-id>.logs_%(_ds)s, the '_ds' evaluates to the current date-time.\n      macros: When true, the format modifers in the value are replaced with the corresponding\n          airflow macro equivalents (like '{{ ds }}'. When false, the actual values are used (like\n          '2015-12-12'.\n\n    Returns:\n      The resolved value, i.e. the value with the format modifiers replaced with the corresponding\n          parameter-values. E.g. if value is <project-id>.<dataset-id>.logs_%(_ds)s, the returned\n          value is something like <project-id>.<dataset-id>.logs_2017-12-21\n    \"\"\"\n    merged_parameters = Query.merge_parameters(parameters, date_time=date_time, macros=macros,\n                                               types_and_values=False)\n    return Query._resolve_parameters(value, merged_parameters)\n\n  @staticmethod\n  def _resolve_parameters(operator_param_value, merged_parameters):\n    \"\"\" Resolve a format modifier with the corresponding value.\n\n    Args:\n      operator_param_value: The object with the format-modifiers that need to be evaluated. This\n          could either be a string, or a more complex type like a list or a dict. This function\n          will recursively replace the format-modifiers from all the string values that it can\n          find.\n      merged_parameters: The full set of parameters that include the user-specified list of\n          parameters from the cell-body, and the built-in airflow macros (either the macros or the\n          evaluated-values).\n\n    Returns:\n      The resolved value, i.e. the value with the format modifiers replaced with the corresponding\n          parameter-values. E.g. if value is <project-id>.<dataset-id>.logs_%(_ds)s, the returned\n          value could be <project-id>.<dataset-id>.logs_2017-12-21.\n    \"\"\"\n    if isinstance(operator_param_value, list):\n      return [Query._resolve_parameters(item, merged_parameters)\n              for item in operator_param_value]\n    if isinstance(operator_param_value, dict):\n      return {Query._resolve_parameters(k, merged_parameters): Query._resolve_parameters(\n        v, merged_parameters) for k, v in operator_param_value.items()}\n    if isinstance(operator_param_value, six.string_types) and merged_parameters:\n      return operator_param_value % merged_parameters\n    return operator_param_value\n\n  @staticmethod\n  def _airflow_macro_formats(date_time, macros, types_and_values):\n    \"\"\" Return a mapping from airflow macro names (prefixed with '_') to values\n\n    Args:\n      date_time: The timestamp at which the macro values need to be evaluated. This is only\n          applicable when types_and_values = True\n      macros: If true, the items in the returned dict are the macro strings (like '_ds': '{{ ds }}')\n      types_and_values: If true, the values in the returned dict are dictionaries of the types and\n          the values of the parameters (i.e like '_ds': {'type': STRING, 'value': 2017-12-21})\n    Returns:\n      The resolved value, i.e. the value with the format modifiers replaced with the corresponding\n          parameter-values. E.g. if value is <project-id>.<dataset-id>.logs_%(_ds)s, the returned\n          value could be <project-id>.<dataset-id>.logs_2017-12-21.\n    \"\"\"\n    day = date_time.date()\n    airflow_macros = {\n      # the datetime formatted as YYYY-MM-DD\n      '_ds': {'type': 'STRING', 'value': day.isoformat(), 'macro': '{{ ds }}'},\n      # the full ISO-formatted timestamp YYYY-MM-DDTHH:MM:SS.mmmmmm\n      '_ts': {'type': 'STRING', 'value': date_time.isoformat(), 'macro': '{{ ts }}'},\n      # the datetime formatted as YYYYMMDD (i.e. YYYY-MM-DD with 'no dashes')\n      '_ds_nodash': {'type': 'STRING', 'value': day.strftime('%Y%m%d'),\n                     'macro': '{{ ds_nodash }}'},\n      # the timestamp formatted as YYYYMMDDTHHMMSSmmmmmm (i.e full ISO-formatted timestamp\n      # YYYY-MM-DDTHH:MM:SS.mmmmmm with no dashes or colons).\n      '_ts_nodash': {'type': 'STRING', 'value': date_time.strftime('%Y%m%d%H%M%S%f'),\n                     'macro': '{{ ts_nodash }}'},\n      '_ts_year': {'type': 'STRING', 'value': day.strftime('%Y'),\n                   'macro': \"\"\"{{ '{:04d}'.format(execution_date.year) }}\"\"\"},\n      '_ts_month': {'type': 'STRING', 'value': day.strftime('%m'),\n                    'macro': \"\"\"{{ '{:02d}'.format(execution_date.month) }}\"\"\"},\n      '_ts_day': {'type': 'STRING', 'value': day.strftime('%d'),\n                  'macro': \"\"\"{{ '{:02d}'.format(execution_date.day) }}\"\"\"},\n      '_ts_hour': {'type': 'STRING', 'value': date_time.strftime('%H'),\n                   'macro': \"\"\"{{ '{:02d}'.format(execution_date.hour) }}\"\"\"},\n      '_ts_minute': {'type': 'STRING', 'value': date_time.strftime('%M'),\n                     'macro': \"\"\"{{ '{:02d}'.format(execution_date.minute) }}\"\"\"},\n      '_ts_second': {'type': 'STRING', 'value': date_time.strftime('%S'),\n                     'macro': \"\"\"{{ '{:02d}'.format(execution_date.second) }}\"\"\"},\n    }\n\n    if macros:\n      return {key: value['macro'] for key, value in airflow_macros.items()}\n\n    if types_and_values:\n      return {\n        key: {\n          'type': item['type'],\n          'value': item['value']\n        } for key, item in airflow_macros.items()\n      }\n\n    # By default only return values\n    return {key: value['value'] for key, value in airflow_macros.items()}\n\n  @staticmethod\n  def merge_parameters(parameters, date_time, macros, types_and_values):\n    \"\"\" Merge Return a mapping from airflow macro names (prefixed with '_') to values\n\n    Args:\n      date_time: The timestamp at which the macro values need to be evaluated. This is only\n          applicable when types_and_values = True\n      macros: If true, the values in the returned dict are the macro strings (like '{{ ds }}')\n\n    Returns:\n      The resolved value, i.e. the value with the format modifiers replaced with the corresponding\n          parameter-values. E.g. if value is <project-id>.<dataset-id>.logs_%(_ds)s, the returned\n          value could be <project-id>.<dataset-id>.logs_2017-12-21.\n    \"\"\"\n    merged_parameters = Query._airflow_macro_formats(date_time=date_time, macros=macros,\n                                                     types_and_values=types_and_values)\n    if parameters:\n      if types_and_values:\n        parameters = {\n          item['name']: {'value': item['value'], 'type': item['type']}\n          for item in parameters\n        }\n      else:  # macros = True, or the default (i.e. just values)\n        parameters = {item['name']: item['value'] for item in parameters}\n\n      merged_parameters.update(parameters)\n    return merged_parameters\n"
  },
  {
    "path": "google/datalab/bigquery/_query_job.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Implements BigQuery query job functionality.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom builtins import str\n\nfrom . import _job\nfrom . import _query_results_table\n\n\nclass QueryJob(_job.Job):\n  \"\"\" Represents a BigQuery Query Job. \"\"\"\n\n  def __init__(self, job_id, table_name, sql, context):\n    \"\"\"  Initializes a QueryJob object.\n\n    Args:\n      job_id: the ID of the query job.\n      table_name: the name of the table where the query results will be stored.\n      sql: the SQL statement that was executed for the query.\n      context: the Context object providing project_id and credentials that was used\n          when executing the query.\n    \"\"\"\n    super(QueryJob, self).__init__(job_id, context)\n    self._sql = sql\n    self._table = _query_results_table.QueryResultsTable(table_name, context, self,\n                                                         is_temporary=True)\n    self._bytes_processed = None\n    self._cache_hit = None\n    self._total_rows = None\n\n  @property\n  def bytes_processed(self):\n    \"\"\" The number of bytes processed, or None if the job is not complete. \"\"\"\n    return self._bytes_processed\n\n  @property\n  def total_rows(self):\n    \"\"\" The total number of rows in the result, or None if not complete. \"\"\"\n    return self._total_rows\n\n  @property\n  def cache_hit(self):\n    \"\"\" Whether the query results were obtained from the cache or not, or None if not complete. \"\"\"\n    return self._cache_hit\n\n  @property\n  def sql(self):\n    \"\"\" The SQL statement that was executed for the query. \"\"\"\n    return self._sql\n\n  def wait(self, timeout=None):\n    \"\"\" Wait for the job to complete, or a timeout to happen.\n\n      This is more efficient than the version in the base Job class, in that we can\n      use a call that blocks for the poll duration rather than a sleep. That means we\n      shouldn't block unnecessarily long and can also poll less.\n\n    Args:\n      timeout: how long to wait (in seconds) before giving up; default None which means no timeout.\n\n    Returns:\n      The QueryJob\n    \"\"\"\n    poll = 30\n    while not self._is_complete:\n      try:\n        query_result = self._api.jobs_query_results(self._job_id,\n                                                    project_id=self._context.project_id,\n                                                    page_size=0,\n                                                    timeout=poll * 1000)\n      except Exception as e:\n        raise e\n      if query_result['jobComplete']:\n        if 'totalBytesProcessed' in query_result:\n          self._bytes_processed = int(query_result['totalBytesProcessed'])\n        self._cache_hit = query_result.get('cacheHit', None)\n        if 'totalRows' in query_result:\n          self._total_rows = int(query_result['totalRows'])\n        break\n\n      if timeout is not None:\n        timeout -= poll\n        if timeout <= 0:\n          break\n\n    self._refresh_state()\n    return self\n\n  def result(self):\n    \"\"\" Get the table used for the results of the query. If the query is incomplete, this blocks.\n\n    Raises:\n      Exception if we timed out waiting for results or the query failed.\n    \"\"\"\n    self.wait()\n    if self.failed:\n      raise Exception('Query failed: %s' % str(self.errors))\n    return self._table\n"
  },
  {
    "path": "google/datalab/bigquery/_query_output.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Implements BigQuery output type functionality.\"\"\"\n\n\nclass QueryOutput(object):\n\n  @staticmethod\n  def table(name=None, mode='create', use_cache=True, priority='interactive',\n            allow_large_results=False):\n    \"\"\" Construct a query output object where the result is a table\n\n    Args:\n      name: the result table name as a string or TableName; if None (the default), then a\n          temporary table will be used.\n      table_mode: one of 'create', 'overwrite' or 'append'. If 'create' (the default), the request\n          will fail if the table exists.\n      use_cache: whether to use past query results or ignore cache. Has no effect if destination is\n          specified (default True).\n      priority:one of 'batch' or 'interactive' (default). 'interactive' jobs should be scheduled\n          to run quickly but are subject to rate limits; 'batch' jobs could be delayed by as much\n          as three hours but are not rate-limited.\n      allow_large_results: whether to allow large results; i.e. compressed data over 100MB. This is\n          slower and requires a name to be specified) (default False).\n    \"\"\"\n    output = QueryOutput()\n    output._output_type = 'table'\n    output._table_name = name\n    output._table_mode = mode\n    output._use_cache = use_cache\n    output._priority = priority\n    output._allow_large_results = allow_large_results\n    return output\n\n  @staticmethod\n  def file(path, format='csv', csv_delimiter=',', csv_header=True, compress=False,\n           use_cache=True):\n    \"\"\" Construct a query output object where the result is either a local file or a GCS path\n\n    Note that there are two jobs that may need to be run sequentially, one to run the query,\n    and the second to extract the resulting table. These are wrapped by a single outer Job.\n\n    If the query has already been executed and you would prefer to get a Job just for the\n    extract, you can can call extract[_async] on the QueryResultsTable returned by the query\n\n    Args:\n      path: the destination path. Can either be a local or GCS URI (starting with gs://)\n      format: the format to use for the exported data; one of 'csv', 'json', or 'avro'\n          (default 'csv').\n      csv_delimiter: for CSV exports, the field delimiter to use (default ',').\n      csv_header: for CSV exports, whether to include an initial header line (default True).\n      compress: whether to compress the data on export. Compression is not supported for\n          AVRO format (default False). Applies only to GCS URIs.\n      use_cache: whether to use cached results or not (default True).\n    \"\"\"\n    output = QueryOutput()\n    output._output_type = 'file'\n    output._file_path = path\n    output._file_format = format\n    output._csv_delimiter = csv_delimiter\n    output._csv_header = csv_header\n    output._compress_file = compress\n    return output\n\n  @staticmethod\n  def dataframe(start_row=0, max_rows=None, use_cache=True):\n    \"\"\" Construct a query output object where the result is a dataframe\n\n    Args:\n      start_row: the row of the table at which to start the export (default 0).\n      max_rows: an upper limit on the number of rows to export (default None).\n      use_cache: whether to use cached results or not (default True).\n    \"\"\"\n    output = QueryOutput()\n    output._output_type = 'dataframe'\n    output._dataframe_start_row = start_row\n    output._dataframe_max_rows = max_rows\n    output._use_cache = use_cache\n    return output\n\n  def __init__(self):\n    \"\"\" Create a BigQuery output type object. Do not call this directly; use factory methods. \"\"\"\n    self._output_type = None\n    self._table_name = None\n    self._table_mode = None\n    self._use_cache = None\n    self._priority = None\n    self._allow_large_results = None\n    self._file_path = None\n    self._file_format = None\n    self._csv_delimiter = None\n    self._csv_header = None\n    self._compress_file = None\n    self._dataframe_start_row = None\n    self._dataframe_max_rows = None\n\n  @property\n  def type(self):\n    return self._output_type\n\n  @property\n  def table_name(self):\n    return self._table_name\n\n  @property\n  def table_mode(self):\n    return self._table_mode\n\n  @property\n  def use_cache(self):\n    return self._use_cache\n\n  @property\n  def priority(self):\n    return self._priority\n\n  @property\n  def allow_large_results(self):\n    return self._allow_large_results\n\n  @property\n  def file_path(self):\n    return self._file_path\n\n  @property\n  def file_format(self):\n    return self._file_format\n\n  @property\n  def csv_delimiter(self):\n    return self._csv_delimiter\n\n  @property\n  def csv_header(self):\n    return self._csv_header\n\n  @property\n  def compress_file(self):\n    return self._compress_file\n\n  @property\n  def dataframe_start_row(self):\n    return self._dataframe_start_row\n\n  @property\n  def dataframe_max_rows(self):\n    return self._dataframe_max_rows\n"
  },
  {
    "path": "google/datalab/bigquery/_query_results_table.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Implements BigQuery query job results table functionality.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\n\nfrom . import _table\n\n\nclass QueryResultsTable(_table.Table):\n  \"\"\" A subclass of Table specifically for Query results.\n\n  The primary differences are the additional properties job_id and sql.\n  \"\"\"\n\n  def __init__(self, name, context, job, is_temporary=False):\n    \"\"\"Initializes an instance of a Table object.\n\n    Args:\n      name: the name of the table either as a string or a 3-part tuple (projectid, datasetid, name).\n      context: an optional Context object providing project_id and credentials. If a specific\n        project id or credentials are unspecified, the default ones configured at the global\n        level are used.\n      job: the QueryJob associated with these results.\n      is_temporary: if True, this is a short-lived table for intermediate results (default False).\n    \"\"\"\n    super(QueryResultsTable, self).__init__(name, context)\n    self._job = job\n    self._is_temporary = is_temporary\n\n  def __repr__(self):\n    \"\"\"Returns a representation for the dataset for showing in the notebook.\n    \"\"\"\n    if self._is_temporary:\n      return 'QueryResultsTable %s' % self.job_id\n    else:\n      return super(QueryResultsTable, self).__repr__()\n\n  def insert(self, *args, **kwargs):\n    raise Exception('QueryResultsTable object is immutable')\n\n  @property\n  def job(self):\n    \"\"\" The QueryJob object that caused the table to be populated. \"\"\"\n    return self._job\n\n  @property\n  def job_id(self):\n    \"\"\" The ID of the query job that caused the table to be populated. \"\"\"\n    return self._job.id\n\n  @property\n  def sql(self):\n    \"\"\" The SQL statement for the query that populated the table. \"\"\"\n    return self._job.sql\n\n  @property\n  def is_temporary(self):\n    \"\"\" Whether this is a short-lived table or not. \"\"\"\n    return self._is_temporary\n"
  },
  {
    "path": "google/datalab/bigquery/_query_stats.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\n\"\"\"Implements representation of BigQuery query job dry run results.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom builtins import object\n\n\nclass QueryStats(object):\n  \"\"\"A wrapper for statistics returned by a dry run query. Useful so we can get an HTML\n  representation in a notebook.\n  \"\"\"\n\n  def __init__(self, total_bytes, is_cached):\n    self.total_bytes = float(total_bytes)\n    self.is_cached = is_cached\n\n  def _repr_html_(self):\n    self.total_bytes = QueryStats._size_formatter(self.total_bytes)\n    return \"\"\"\n    <p>Dry run information: %s to process, results %s</p>\n    \"\"\" % (self.total_bytes, \"cached\" if self.is_cached else \"not cached\")\n\n  @staticmethod\n  def _size_formatter(byte_num, suf='B'):\n    for mag in ['', 'K', 'M', 'G', 'T']:\n      if byte_num < 1000.0:\n        if suf == 'B':  # Don't do fractional bytes\n          return \"%5d%s%s\" % (int(byte_num), mag, suf)\n        return \"%3.1f%s%s\" % (byte_num, mag, suf)\n      byte_num /= 1000.0\n    return \"%.1f%s%s\".format(byte_num, 'P', suf)\n"
  },
  {
    "path": "google/datalab/bigquery/_sampling.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Sampling for BigQuery.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import unicode_literals\nfrom builtins import object\n\n\nclass Sampling(object):\n  \"\"\"Provides common sampling strategies.\n\n  Sampling strategies can be used for sampling tables or queries.\n\n  They are implemented as functions that take in a SQL statement representing the table or query\n  that should be sampled, and return a new SQL statement that limits the result set in some manner.\n  \"\"\"\n\n  def __init__(self):\n    pass\n\n  @staticmethod\n  def _create_projection(fields):\n    \"\"\"Creates a projection for use in a SELECT statement.\n\n    Args:\n      fields: the list of fields to be specified.\n    \"\"\"\n    if (fields is None) or (len(fields) == 0):\n      return '*'\n    return ','.join(fields)\n\n  @staticmethod\n  def default(fields=None, count=5):\n    \"\"\"Provides a simple default sampling strategy which limits the result set by a count.\n\n    Args:\n      fields: an optional list of field names to retrieve.\n      count: optional number of rows to limit the sampled results to.\n    Returns:\n      A sampling function that can be applied to get a random sampling.\n    \"\"\"\n    projection = Sampling._create_projection(fields)\n    return lambda sql: 'SELECT %s FROM (%s) LIMIT %d' % (projection, sql, count)\n\n  @staticmethod\n  def sorted(field_name, ascending=True, fields=None, count=5):\n    \"\"\"Provides a sampling strategy that picks from an ordered set of rows.\n\n    Args:\n      field_name: the name of the field to sort the rows by.\n      ascending: whether to sort in ascending direction or not.\n      fields: an optional list of field names to retrieve.\n      count: optional number of rows to limit the sampled results to.\n    Returns:\n      A sampling function that can be applied to get the initial few rows.\n    \"\"\"\n    if field_name is None:\n      raise Exception('Sort field must be specified')\n    direction = '' if ascending else ' DESC'\n    projection = Sampling._create_projection(fields)\n    return lambda sql: 'SELECT %s FROM (%s) ORDER BY %s%s LIMIT %d' % (projection, sql, field_name,\n                                                                       direction, count)\n\n  @staticmethod\n  def hashed(field_name, percent, fields=None, count=0):\n    \"\"\"Provides a sampling strategy based on hashing and selecting a percentage of data.\n\n    Args:\n      field_name: the name of the field to hash.\n      percent: the percentage of the resulting hashes to select.\n      fields: an optional list of field names to retrieve.\n      count: optional maximum count of rows to pick.\n    Returns:\n      A sampling function that can be applied to get a hash-based sampling.\n    \"\"\"\n    if field_name is None:\n      raise Exception('Hash field must be specified')\n\n    def _hashed_sampling(sql):\n      projection = Sampling._create_projection(fields)\n      sql = 'SELECT %s FROM (%s) WHERE MOD(ABS(FARM_FINGERPRINT(CAST(%s AS STRING))), 100) < %d' % \\\n            (projection, sql, field_name, percent)\n      if count != 0:\n        sql = '%s LIMIT %d' % (sql, count)\n      return sql\n    return _hashed_sampling\n\n  @staticmethod\n  def random(percent, fields=None, count=0):\n    \"\"\"Provides a sampling strategy that picks a semi-random set of rows.\n\n    Args:\n      percent: the percentage of the resulting hashes to select.\n      fields: an optional list of field names to retrieve.\n      count: maximum number of rows to limit the sampled results to (default 5).\n    Returns:\n      A sampling function that can be applied to get some random rows. In order for this to\n      provide a good random sample percent should be chosen to be ~count/#rows where #rows\n      is the number of rows in the object (query, view or table) being sampled.\n      The rows will be returned in order; i.e. the order itself is not randomized.\n    \"\"\"\n    def _random_sampling(sql):\n      projection = Sampling._create_projection(fields)\n      sql = 'SELECT %s FROM (%s) WHERE rand() < %f' % (projection, sql, (float(percent) / 100.0))\n      if count != 0:\n        sql = '%s LIMIT %d' % (sql, count)\n      return sql\n    return _random_sampling\n\n  @staticmethod\n  def _auto(method, fields, count, percent, key_field, ascending):\n    \"\"\"Construct a sampling function according to the provided sampling technique, provided all\n    its needed fields are passed as arguments\n\n    Args:\n      method: one of the supported sampling methods: {limit,random,hashed,sorted}\n      fields: an optional list of field names to retrieve.\n      count: maximum number of rows to limit the sampled results to.\n      percent: the percentage of the resulting hashes to select if using hashed sampling\n      key_field: the name of the field to sort the rows by or use for hashing\n      ascending: whether to sort in ascending direction or not.\n    Returns:\n      A sampling function using the provided arguments\n    Raises:\n      Exception if an unsupported mathod name is passed\n    \"\"\"\n    if method == 'limit':\n      return Sampling.default(fields=fields, count=count)\n    elif method == 'random':\n      return Sampling.random(fields=fields, percent=percent, count=count)\n    elif method == 'hashed':\n      return Sampling.hashed(fields=fields, field_name=key_field, percent=percent, count=count)\n    elif method == 'sorted':\n      return Sampling.sorted(fields=fields, field_name=key_field, ascending=ascending, count=count)\n    else:\n      raise Exception('Unsupported sampling method: %s' % method)\n"
  },
  {
    "path": "google/datalab/bigquery/_schema.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Implements Table and View Schema APIs.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom builtins import str\nfrom builtins import range\nfrom past.builtins import basestring\nfrom builtins import object\n\nimport datetime\nimport pandas\nimport pprint\n\n\nclass SchemaField(object):\n  \"\"\" Represents a single field in a Table schema.\n\n  This has the properties:\n\n  - name: the flattened, full-qualified name of the field.\n  - type: the type of the field as a string ('INTEGER', 'BOOLEAN', 'FLOAT', 'STRING'\n     or 'TIMESTAMP').\n  - mode: the mode of the field; 'NULLABLE' by default.\n  - description: a description of the field, if known; empty string by default.\n\n   \"\"\"\n\n  def __init__(self, name, type, mode='NULLABLE', description=''):\n    self.name = name\n    self.type = type\n    self.mode = mode\n    self.description = description\n\n  def _repr_sql_(self):\n    \"\"\"Returns a representation of the field for embedding into a SQL statement.\n\n    Returns:\n      A formatted field name for use within SQL statements.\n    \"\"\"\n    return self.name\n\n  def __eq__(self, other):\n    \"\"\" Compare two schema field objects for equality (ignoring description). \"\"\"\n    return self.name == other.name and self.type == other.type\\\n        and self.mode == other.mode\n\n  def __repr__(self):\n    \"\"\" Returns the schema field as a string form of a dictionary. \"\"\"\n    return 'BigQuery Schema Field:\\n%s' % pprint.pformat(vars(self), width=1)\n\n  def __getitem__(self, item):\n    # TODO(gram): Currently we need this for a Schema object to work with the Parser object.\n    # Eventually if we change Parser to only work with Schema (and not also with the\n    # schema dictionaries in query results) we can remove this.\n\n    if item == 'name':\n      return self.name\n    if item == 'type':\n      return self.type\n    if item == 'mode':\n      return self.mode\n    if item == 'description':\n      return self.description\n\n\nclass Schema(list):\n  \"\"\"Represents the schema of a BigQuery table as a flattened list of objects representing fields.\n\n   Each field object has name, type, mode and description properties. Nested fields\n   get flattened with their full-qualified names. So a Schema that has an object A with nested\n   field B will be represented as [(name: 'A', ...), (name: 'A.b', ...)].\n  \"\"\"\n\n  @staticmethod\n  def _from_dataframe(dataframe, default_type='STRING'):\n    \"\"\"\n      Infer a BigQuery table schema from a Pandas dataframe. Note that if you don't explicitly set\n      the types of the columns in the dataframe, they may be of a type that forces coercion to\n      STRING, so even though the fields in the dataframe themselves may be numeric, the type in the\n      derived schema may not be. Hence it is prudent to make sure the Pandas dataframe is typed\n      correctly.\n    Args:\n      dataframe: The DataFrame.\n      default_type : The default big query type in case the type of the column does not exist in\n          the schema. Defaults to 'STRING'.\n    Returns:\n      A list of dictionaries containing field 'name' and 'type' entries, suitable for use in a\n          BigQuery Tables resource schema.\n    \"\"\"\n\n    type_mapping = {\n      'i': 'INTEGER',\n      'b': 'BOOLEAN',\n      'f': 'FLOAT',\n      'O': 'STRING',\n      'S': 'STRING',\n      'U': 'STRING',\n      'M': 'TIMESTAMP'\n    }\n\n    fields = []\n    for column_name, dtype in dataframe.dtypes.iteritems():\n      fields.append({'name': column_name,\n                     'type': type_mapping.get(dtype.kind, default_type)})\n\n    return fields\n\n  @staticmethod\n  def _get_field_entry(name, value):\n    entry = {'name': name}\n    if isinstance(value, datetime.datetime):\n      _type = 'TIMESTAMP'\n    elif isinstance(value, datetime.date):\n      _type = 'DATE'\n    elif isinstance(value, datetime.time):\n      _type = 'TIME'\n    elif isinstance(value, bool):\n      _type = 'BOOLEAN'\n    elif isinstance(value, float):\n      _type = 'FLOAT'\n    elif isinstance(value, int):\n      _type = 'INTEGER'\n    elif isinstance(value, dict) or isinstance(value, list):\n      _type = 'RECORD'\n      entry['fields'] = Schema._from_record(value)\n    else:\n      _type = 'STRING'\n    entry['type'] = _type\n    return entry\n\n  @staticmethod\n  def _from_dict_record(data):\n    \"\"\"\n    Infer a BigQuery table schema from a dictionary. If the dictionary has entries that\n    are in turn OrderedDicts these will be turned into RECORD types. Ideally this will\n    be an OrderedDict but it is not required.\n\n    Args:\n      data: The dict to infer a schema from.\n    Returns:\n      A list of dictionaries containing field 'name' and 'type' entries, suitable for use in a\n          BigQuery Tables resource schema.\n    \"\"\"\n    return [Schema._get_field_entry(name, value) for name, value in list(data.items())]\n\n  @staticmethod\n  def _from_list_record(data):\n    \"\"\"\n    Infer a BigQuery table schema from a list of values.\n\n    Args:\n      data: The list of values.\n    Returns:\n      A list of dictionaries containing field 'name' and 'type' entries, suitable for use in a\n          BigQuery Tables resource schema.\n    \"\"\"\n    return [Schema._get_field_entry('Column%d' % (i + 1), value) for i, value in enumerate(data)]\n\n  @staticmethod\n  def _from_record(data):\n    \"\"\"\n    Infer a BigQuery table schema from a list of fields or a dictionary. The typeof the elements\n    is used. For a list, the field names are simply 'Column1', 'Column2', etc.\n\n    Args:\n      data: The list of fields or dictionary.\n    Returns:\n      A list of dictionaries containing field 'name' and 'type' entries, suitable for use in a\n          BigQuery Tables resource schema.\n    \"\"\"\n    if isinstance(data, dict):\n      return Schema._from_dict_record(data)\n    elif isinstance(data, list):\n      return Schema._from_list_record(data)\n    else:\n      raise Exception('Cannot create a schema from record %s' % str(data))\n\n  @staticmethod\n  def from_record(source):\n    \"\"\"\n    Infers a table/view schema from a single record that can contain a list of fields or a\n    dictionary of fields. The type of the elements is used for the types in the schema. For a\n    dict, key names are used for column names while for a list, the field names are simply named\n    'Column1', 'Column2', etc. Note that if using a dict you may want to use an OrderedDict\n    to ensure column ordering is deterministic.\n\n    Args:\n      source: The list of field values or dictionary of key/values.\n\n    Returns:\n      A Schema for the data.\n    \"\"\"\n    # TODO(gram): may want to allow an optional second argument which is a list of field\n    # names; could be useful for the record-containing-list case.\n    return Schema(Schema._from_record(source))\n\n  @staticmethod\n  def from_data(source):\n    \"\"\"Infers a table/view schema from its JSON representation, a list of records, or a Pandas\n       dataframe.\n\n    Args:\n      source: the Pandas Dataframe, a dictionary representing a record, a list of heterogeneous\n          data (record) or homogeneous data (list of records) from which to infer the schema, or\n          a definition of the schema as a list of dictionaries with 'name' and 'type' entries\n          and possibly 'mode' and 'description' entries. Only used if no data argument was provided.\n          'mode' can be 'NULLABLE', 'REQUIRED' or 'REPEATED'. For the allowed types, see:\n          https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types\n\n          Note that there is potential ambiguity when passing a list of lists or a list of\n          dicts between whether that should be treated as a list of records or a single record\n          that is a list. The heuristic used is to check the length of the entries in the\n          list; if they are equal then a list of records is assumed. To avoid this ambiguity\n          you can instead use the Schema.from_record method which assumes a single record,\n          in either list of values or dictionary of key-values form.\n\n    Returns:\n      A Schema for the data.\n    \"\"\"\n    if isinstance(source, pandas.DataFrame):\n      bq_schema = Schema._from_dataframe(source)\n    elif isinstance(source, list):\n      if len(source) == 0:\n        bq_schema = source\n      elif all(isinstance(d, dict) for d in source):\n        if all('name' in d and 'type' in d for d in source):\n          # It looks like a bq_schema; use it as-is.\n          bq_schema = source\n        elif all(len(d) == len(source[0]) for d in source):\n          bq_schema = Schema._from_dict_record(source[0])\n        else:\n          raise Exception(('Cannot create a schema from heterogeneous list %s; perhaps you meant ' +\n                          'to use Schema.from_record?') % str(source))\n      elif isinstance(source[0], list) and \\\n              all([isinstance(l, list) and len(l) == len(source[0]) for l in source]):\n        # A list of lists all of the same length; treat first entry as a list record.\n        bq_schema = Schema._from_record(source[0])\n      else:\n        # A heterogeneous list; treat as a record.\n        raise Exception(('Cannot create a schema from heterogeneous list %s; perhaps you meant ' +\n                        'to use Schema.from_record?') % str(source))\n    elif isinstance(source, dict):\n      bq_schema = Schema._from_record(source)\n    else:\n      raise Exception('Cannot create a schema from %s' % str(source))\n    return Schema(bq_schema)\n\n  def __init__(self, definition=None):\n    \"\"\"Initializes a Schema from its raw JSON representation, a Pandas Dataframe, or a list.\n\n    Args:\n      definition: a definition of the schema as a list of dictionaries with 'name' and 'type'\n          entries and possibly 'mode' and 'description' entries. Only used if no data argument was\n          provided. 'mode' can be 'NULLABLE', 'REQUIRED' or 'REPEATED'. For the allowed types, see:\n          https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types\n    \"\"\"\n    super(Schema, self).__init__()\n    self._map = {}\n    self._bq_schema = definition\n    self._populate_fields(definition)\n\n  def __getitem__(self, key):\n    \"\"\"Provides ability to lookup a schema field by position or by name.\n    \"\"\"\n    if isinstance(key, basestring):\n      return self._map.get(key, None)\n    # noinspection PyCallByClass\n    return list.__getitem__(self, key)\n\n  def _add_field(self, name, type, mode='NULLABLE', description=''):\n    field = SchemaField(name, type, mode, description)\n    self.append(field)\n    self._map[name] = field\n\n  def find(self, name):\n    \"\"\" Get the index of a field in the flattened list given its (fully-qualified) name.\n\n    Args:\n      name: the fully-qualified name of the field.\n    Returns:\n      The index of the field, if found; else -1.\n    \"\"\"\n    for i in range(0, len(self)):\n      if self[i].name == name:\n        return i\n    return -1\n\n  def _populate_fields(self, data, prefix=''):\n    for field_data in data:\n      name = prefix + field_data['name']\n      type = field_data['type']\n      self._add_field(name, type, field_data.get('mode', None),\n                      field_data.get('description', None))\n\n      if type == 'RECORD':\n        # Recurse into the nested fields, using this field's name as a prefix.\n        self._populate_fields(field_data.get('fields'), name + '.')\n\n  def __repr__(self):\n    \"\"\" Returns a string representation of the schema for notebooks.\"\"\"\n    return 'BigQuery Schema - Fields:\\n%s' % pprint.pformat(self._bq_schema, width=1)\n\n  def __eq__(self, other):\n    \"\"\" Compares two schema for equality. \"\"\"\n    other_map = other._map\n    if len(self._map) != len(other_map):\n      return False\n    for name in self._map.keys():\n      if name not in other_map:\n        return False\n      if not self._map[name] == other_map[name]:\n        return False\n    return True\n\n  def __ne__(self, other):\n    \"\"\" Compares two schema for inequality. \"\"\"\n    return not(self.__eq__(other))\n"
  },
  {
    "path": "google/datalab/bigquery/_table.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Implements Table, and related Table BigQuery APIs.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import unicode_literals\nfrom builtins import str\nfrom past.utils import old_div\nfrom builtins import object\n\nimport calendar\nimport codecs\nimport csv\nimport datetime\nimport pandas\nimport time\nimport traceback\nimport uuid\nimport sys\n\nimport google.datalab\nimport google.datalab.utils\n\nfrom . import _api\nfrom . import _csv_options\nfrom . import _job\nfrom . import _parser\nfrom . import _schema\nfrom . import _utils\n\n\nclass TableMetadata(object):\n  \"\"\"Represents metadata about a BigQuery table.\"\"\"\n\n  def __init__(self, table, info):\n    \"\"\"Initializes a TableMetadata instance.\n\n    Args:\n      table: the Table object this belongs to.\n      info: The BigQuery information about this table as a Python dictionary.\n    \"\"\"\n    self._table = table\n    self._info = info\n\n  @property\n  def created_on(self):\n    \"\"\"The creation timestamp.\"\"\"\n    timestamp = self._info.get('creationTime')\n    return _parser.Parser.parse_timestamp(timestamp)\n\n  @property\n  def description(self):\n    \"\"\"The description of the table if it exists.\"\"\"\n    return self._info.get('description', '')\n\n  @property\n  def expires_on(self):\n    \"\"\"The timestamp for when the table will expire, or None if unknown.\"\"\"\n    timestamp = self._info.get('expirationTime', None)\n    if timestamp is None:\n      return None\n    return _parser.Parser.parse_timestamp(timestamp)\n\n  @property\n  def friendly_name(self):\n    \"\"\"The friendly name of the table if it exists.\"\"\"\n    return self._info.get('friendlyName', '')\n\n  @property\n  def modified_on(self):\n    \"\"\"The timestamp for when the table was last modified.\"\"\"\n    timestamp = self._info.get('lastModifiedTime')\n    return _parser.Parser.parse_timestamp(timestamp)\n\n  @property\n  def rows(self):\n    \"\"\"The number of rows within the table, or -1 if unknown. \"\"\"\n    return int(self._info['numRows']) if 'numRows' in self._info else -1\n\n  @property\n  def size(self):\n    \"\"\"The size of the table in bytes, or -1 if unknown. \"\"\"\n    return int(self._info['numBytes']) if 'numBytes' in self._info else -1\n\n  def refresh(self):\n    \"\"\" Refresh the metadata. \"\"\"\n    self._info = self._table._load_info()\n\n\nclass Table(object):\n  \"\"\"Represents a Table object referencing a BigQuery table. \"\"\"\n\n  # Allowed characters in a BigQuery table column name\n  _VALID_COLUMN_NAME_CHARACTERS = '_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'\n\n  # When fetching table contents for a range or iteration, use a small page size per request\n  _DEFAULT_PAGE_SIZE = 1024\n  # When fetching the entire table, use the maximum number of rows. The BigQuery service\n  # will always return fewer rows than this if their encoded JSON size is larger than 10MB\n  _MAX_PAGE_SIZE = 100000\n\n  # Milliseconds per week\n  _MSEC_PER_WEEK = 7 * 24 * 3600 * 1000\n\n  def __init__(self, name, context=None):\n    \"\"\"Initializes an instance of a Table object. The Table need not exist yet.\n\n    Args:\n      name: the name of the table either as a string or a 3-part tuple (projectid, datasetid, name).\n        If a string, it must have the form '<project>.<dataset>.<table>' or '<dataset>.<table>'.\n      context: an optional Context object providing project_id and credentials. If a specific\n        project id or credentials are unspecified, the default ones configured at the global\n        level are used.\n    Raises:\n      Exception if the name is invalid.\n    \"\"\"\n    if context is None:\n      context = google.datalab.Context.default()\n    self._context = context\n    self._api = _api.Api(context)\n    self._name_parts = _utils.parse_table_name(name, self._api.project_id)\n    self._full_name = '%s.%s.%s%s' % self._name_parts\n    self._info = None\n    self._cached_page = None\n    self._cached_page_index = 0\n    self._schema = None\n\n  @property\n  def name(self):\n    \"\"\"The TableName named tuple (project_id, dataset_id, table_id, decorator) for the table.\"\"\"\n    return self._name_parts\n\n  @property\n  def full_name(self):\n    \"\"\"The full name of the table in the form of project.dataset.table.\"\"\"\n    return self._full_name\n\n  @property\n  def job(self):\n    \"\"\" For tables resulting from executing queries, the job that created the table.\n\n    Default is None for a Table object; this is overridden by QueryResultsTable.\n    \"\"\"\n    return None\n\n  @property\n  def is_temporary(self):\n    \"\"\" Whether this is a short-lived table or not. Always False for non-QueryResultsTables. \"\"\"\n    return False\n\n  def _load_info(self):\n    \"\"\"Loads metadata about this table.\"\"\"\n    if self._info is None:\n      try:\n        self._info = self._api.tables_get(self._name_parts)\n      except Exception as e:\n        raise e\n\n  @property\n  def metadata(self):\n    \"\"\"Retrieves metadata about the table.\n\n    Returns:\n      A TableMetadata object.\n    Raises\n      Exception if the request could not be executed or the response was malformed.\n    \"\"\"\n    self._load_info()\n    return TableMetadata(self, self._info)\n\n  def exists(self):\n    \"\"\"Checks if the table exists.\n\n    Returns:\n      True if the table exists; False otherwise.\n    Raises:\n      Exception if there was an error requesting information about the table.\n    \"\"\"\n    try:\n      info = self._api.tables_get(self._name_parts)\n    except google.datalab.utils.RequestException as e:\n      if e.status == 404:\n        return False\n      raise e\n    except Exception as e:\n      raise e\n    self._info = info\n    return True\n\n  def is_listable(self):\n    \"\"\" Determine if the table can be listed.\n\n    Returns:\n      True is the Table can be listed; False otherwise.\n    \"\"\"\n    self._load_info()\n    return 'type' not in self._info or 'MODEL' != self._info['type']\n\n  def delete(self):\n    \"\"\" Delete the table.\n\n    Returns:\n      True if the Table no longer exists; False otherwise.\n    \"\"\"\n    try:\n      self._api.table_delete(self._name_parts)\n    except google.datalab.utils.RequestException:\n      # TODO(gram): May want to check the error reasons here and if it is not\n      # because the file didn't exist, return an error.\n      pass\n    except Exception as e:\n      raise e\n    return not self.exists()\n\n  def create(self, schema, overwrite=False):\n    \"\"\" Create the table with the specified schema.\n\n    Args:\n      schema: the schema to use to create the table. Should be a list of dictionaries, each\n          containing at least a pair of entries, 'name' and 'type'.\n          See https://cloud.google.com/bigquery/docs/reference/v2/tables#resource\n      overwrite: if True, delete the table first if it exists. If False and the table exists,\n          creation will fail and raise an Exception.\n    Returns:\n      The Table instance.\n    Raises:\n      Exception if the table couldn't be created or already exists and truncate was False.\n    \"\"\"\n    if overwrite and self.exists():\n      self.delete()\n    if not isinstance(schema, _schema.Schema):\n      # Convert to a Schema object\n      schema = _schema.Schema(schema)\n    try:\n      response = self._api.tables_insert(self._name_parts, schema=schema._bq_schema)\n    except Exception as e:\n      raise e\n    if 'selfLink' in response:\n      self._schema = schema\n      return self\n    raise Exception(\"Table %s could not be created as it already exists\" % self._full_name)\n\n  @staticmethod\n  def _encode_dict_as_row(record, column_name_map):\n    \"\"\" Encode a dictionary representing a table row in a form suitable for streaming to BQ.\n\n      This includes encoding timestamps as ISO-compatible strings and removing invalid\n      characters from column names.\n\n    Args:\n      record: a Python dictionary representing the table row.\n      column_name_map: a dictionary mapping dictionary keys to column names. This is initially\n        empty and built up by this method when it first encounters each column, then used as a\n        cache subsequently.\n    Returns:\n      The sanitized dictionary.\n    \"\"\"\n    for k in list(record.keys()):\n      v = record[k]\n      # If the column is a date, convert to ISO string.\n      if isinstance(v, (pandas.Timestamp, datetime.datetime, datetime.date, datetime.time)):\n        v = record[k] = record[k].isoformat()\n\n      # If k has invalid characters clean it up\n      if k not in column_name_map:\n        column_name_map[k] = ''.join(c for c in k if c in Table._VALID_COLUMN_NAME_CHARACTERS)\n      new_k = column_name_map[k]\n      if k != new_k:\n        record[new_k] = v\n        del record[k]\n    return record\n\n  def insert(self, data, include_index=False, index_name=None):\n    \"\"\" Insert the contents of a Pandas DataFrame or a list of dictionaries into the table.\n\n    The insertion will be performed using at most 500 rows per POST, and at most 10 POSTs per\n    second, as BigQuery has some limits on streaming rates.\n\n    Args:\n      data: the DataFrame or list to insert.\n      include_index: whether to include the DataFrame or list index as a column in the BQ table.\n      index_name: for a list, if include_index is True, this should be the name for the index.\n          If not specified, 'Index' will be used.\n    Returns:\n      The table.\n    Raises:\n      Exception if the table doesn't exist, the table's schema differs from the data's schema,\n      or the insert failed.\n    \"\"\"\n    # TODO(gram): we could create the Table here is it doesn't exist using a schema derived\n    # from the data. IIRC we decided not to but doing so seems less unwieldy that having to\n    # create it first and then validate the schema against it itself.\n\n    # There are BigQuery limits on the streaming API:\n    #\n    # max_rows_per_post = 500\n    # max_bytes_per_row = 20000\n    # max_rows_per_second = 10000\n    # max_bytes_per_post = 1000000\n    # max_bytes_per_second = 10000000\n    #\n    # It is non-trivial to enforce these here, and the max bytes per row is not something we\n    # can really control. As an approximation we enforce the 500 row limit\n    # with a 0.05 sec POST interval (to enforce the 10,000 rows per sec limit).\n    max_rows_per_post = 500\n    post_interval = 0.05\n\n    # TODO(gram): add different exception types for each failure case.\n    if not self.exists():\n      raise Exception('Table %s does not exist.' % self._full_name)\n\n    data_schema = _schema.Schema.from_data(data)\n    if isinstance(data, list):\n      if include_index:\n        if not index_name:\n          index_name = 'Index'\n        data_schema._add_field(index_name, 'INTEGER')\n\n    table_schema = self.schema\n\n    # Do some validation of the two schema to make sure they are compatible.\n    for data_field in data_schema:\n      name = data_field.name\n      table_field = table_schema[name]\n      if table_field is None:\n        raise Exception('Table does not contain field %s' % name)\n      data_type = data_field.type\n      table_type = table_field.type\n      if table_type != data_type:\n        raise Exception('Field %s in data has type %s but in table has type %s' %\n                        (name, data_type, table_type))\n\n    total_rows = len(data)\n    total_pushed = 0\n\n    job_id = uuid.uuid4().hex\n    rows = []\n    column_name_map = {}\n\n    is_dataframe = isinstance(data, pandas.DataFrame)\n    if is_dataframe:\n      # reset_index creates a new dataframe so we don't affect the original. reset_index(drop=True)\n      # drops the original index and uses an integer range.\n      gen = data.reset_index(drop=not include_index).iterrows()\n    else:\n      gen = enumerate(data)\n\n    for index, row in gen:\n      if is_dataframe:\n        row = row.to_dict()\n      elif include_index:\n        row[index_name] = index\n\n      rows.append({\n        'json': self._encode_dict_as_row(row, column_name_map),\n        'insertId': job_id + str(index)\n      })\n\n      total_pushed += 1\n\n      if (total_pushed == total_rows) or (len(rows) == max_rows_per_post):\n        try:\n          response = self._api.tabledata_insert_all(self._name_parts, rows)\n        except Exception as e:\n          raise e\n        if 'insertErrors' in response:\n          raise Exception('insertAll failed: %s' % response['insertErrors'])\n\n        time.sleep(post_interval)  # Streaming API is rate-limited\n        rows = []\n\n    # Block until data is ready\n    while True:\n      self._info = self._api.tables_get(self._name_parts)\n      if 'streamingBuffer' not in self._info or \\\n         'estimatedRows' not in self._info['streamingBuffer'] or \\\n         int(self._info['streamingBuffer']['estimatedRows']) > 0:\n        break\n      time.sleep(2)\n\n    return self\n\n  def _init_job_from_response(self, response):\n    \"\"\" Helper function to create a Job instance from a response. \"\"\"\n    job = None\n    if response and 'jobReference' in response:\n      job = _job.Job(job_id=response['jobReference']['jobId'], context=self._context)\n    return job\n\n  def extract_async(self, destination, format='csv', csv_delimiter=None, csv_header=True,\n                    compress=False):\n    \"\"\"Starts a job to export the table to GCS.\n\n    Args:\n      destination: the destination URI(s). Can be a single URI or a list.\n      format: the format to use for the exported data; one of 'csv', 'json', or 'avro'\n          (default 'csv').\n      csv_delimiter: for CSV exports, the field delimiter to use. Defaults to ','\n      csv_header: for CSV exports, whether to include an initial header line. Default true.\n      compress: whether to compress the data on export. Compression is not supported for\n          AVRO format. Defaults to False.\n    Returns:\n      A Job object for the export Job if it was started successfully; else None.\n    \"\"\"\n    format = format.upper()\n    if format == 'JSON':\n      format = 'NEWLINE_DELIMITED_JSON'\n    if format == 'CSV' and csv_delimiter is None:\n      csv_delimiter = ','\n    try:\n      response = self._api.table_extract(self._name_parts, destination, format, compress,\n                                         csv_delimiter, csv_header)\n      return self._init_job_from_response(response)\n    except Exception as e:\n      raise google.datalab.JobError(location=traceback.format_exc(), message=str(e),\n                                    reason=str(type(e)))\n\n  def extract(self, destination, format='csv', csv_delimiter=None, csv_header=True, compress=False):\n    \"\"\"Exports the table to GCS; blocks until complete.\n\n    Args:\n      destination: the destination URI(s). Can be a single URI or a list.\n      format: the format to use for the exported data; one of 'csv', 'json', or 'avro'\n          (default 'csv').\n      csv_delimiter: for CSV exports, the field delimiter to use. Defaults to ','\n      csv_header: for CSV exports, whether to include an initial header line. Default true.\n      compress: whether to compress the data on export. Compression is not supported for\n          AVRO format. Defaults to False.\n    Returns:\n      A Job object for the completed export Job if it was started successfully; else None.\n    \"\"\"\n    job = self.extract_async(destination, format=format, csv_delimiter=csv_delimiter,\n                             csv_header=csv_header, compress=compress)\n    if job is not None:\n      job.wait()\n    return job\n\n  def load_async(self, source, mode='create', source_format='csv', csv_options=None,\n                 ignore_unknown_values=False, max_bad_records=0):\n    \"\"\" Starts importing a table from GCS and return a Future.\n\n    Args:\n      source: the URL of the source objects(s). Can include a wildcard '*' at the end of the item\n         name. Can be a single source or a list.\n      mode: one of 'create', 'append', or 'overwrite'. 'append' or 'overwrite' will fail if the\n          table does not already exist, while 'create' will fail if it does. The default is\n          'create'. If 'create' the schema will be inferred if necessary.\n      source_format: the format of the data, 'csv' or 'json'; default 'csv'.\n      csv_options: if source format is 'csv', additional options as a CSVOptions object.\n      ignore_unknown_values: If True, accept rows that contain values that do not match the schema;\n          the unknown values are ignored (default False).\n      max_bad_records: the maximum number of bad records that are allowed (and ignored) before\n          returning an 'invalid' error in the Job result (default 0).\n\n    Returns:\n      A Job object for the import if it was started successfully or None if not.\n    Raises:\n      Exception if the load job failed to be started or invalid arguments were supplied.\n    \"\"\"\n    if source_format == 'csv':\n      source_format = 'CSV'\n    elif source_format == 'json':\n      source_format = 'NEWLINE_DELIMITED_JSON'\n    else:\n      raise Exception(\"Invalid source format %s\" % source_format)\n\n    if not(mode == 'create' or mode == 'append' or mode == 'overwrite'):\n      raise Exception(\"Invalid mode %s\" % mode)\n\n    if csv_options is None:\n      csv_options = _csv_options.CSVOptions()\n\n    try:\n      response = self._api.jobs_insert_load(source, self._name_parts,\n                                            append=(mode == 'append'),\n                                            overwrite=(mode == 'overwrite'),\n                                            create=(mode == 'create'),\n                                            source_format=source_format,\n                                            field_delimiter=csv_options.delimiter,\n                                            allow_jagged_rows=csv_options.allow_jagged_rows,\n                                            allow_quoted_newlines=csv_options.allow_quoted_newlines,\n                                            encoding=csv_options.encoding.upper(),\n                                            ignore_unknown_values=ignore_unknown_values,\n                                            max_bad_records=max_bad_records,\n                                            quote=csv_options.quote,\n                                            skip_leading_rows=csv_options.skip_leading_rows)\n    except Exception as e:\n      raise e\n    return self._init_job_from_response(response)\n\n  def load(self, source, mode='create', source_format='csv', csv_options=None,\n           ignore_unknown_values=False, max_bad_records=0):\n    \"\"\" Load the table from GCS.\n\n    Args:\n      source: the URL of the source objects(s). Can include a wildcard '*' at the end of the item\n         name. Can be a single source or a list.\n      mode: one of 'create', 'append', or 'overwrite'. 'append' or 'overwrite' will fail if the\n          table does not already exist, while 'create' will fail if it does. The default is\n          'create'. If 'create' the schema will be inferred if necessary.\n      source_format: the format of the data, 'csv' or 'json'; default 'csv'.\n      csv_options: if source format is 'csv', additional options as a CSVOptions object.\n      ignore_unknown_values: if True, accept rows that contain values that do not match the schema;\n          the unknown values are ignored (default False).\n      max_bad_records: the maximum number of bad records that are allowed (and ignored) before\n          returning an 'invalid' error in the Job result (default 0).\n\n    Returns:\n      A Job object for the completed load Job if it was started successfully; else None.\n    \"\"\"\n    job = self.load_async(source,\n                          mode=mode,\n                          source_format=source_format,\n                          csv_options=csv_options,\n                          ignore_unknown_values=ignore_unknown_values,\n                          max_bad_records=max_bad_records)\n    if job is not None:\n      job.wait()\n    return job\n\n  def _get_row_fetcher(self, start_row=0, max_rows=None, page_size=_DEFAULT_PAGE_SIZE):\n    \"\"\" Get a function that can retrieve a page of rows.\n\n    The function returned is a closure so that it can have a signature suitable for use\n    by Iterator.\n\n    Args:\n      start_row: the row to start fetching from; default 0.\n      max_rows: the maximum number of rows to fetch (across all calls, not per-call). Default\n          is None which means no limit.\n      page_size: the maximum number of results to fetch per page; default 1024.\n    Returns:\n      A function that can be called repeatedly with a page token and running count, and that\n      will return an array of rows and a next page token; when the returned page token is None\n      the fetch is complete.\n    \"\"\"\n    if not start_row:\n      start_row = 0\n    elif start_row < 0:  # We are measuring from the table end\n      if self.length >= 0:\n        start_row += self.length\n      else:\n        raise Exception('Cannot use negative indices for table of unknown length')\n\n    schema = self.schema._bq_schema\n    name_parts = self._name_parts\n\n    def _retrieve_rows(page_token, count):\n\n      page_rows = []\n      if max_rows and count >= max_rows:\n        page_token = None\n      else:\n        if max_rows and page_size > (max_rows - count):\n          max_results = max_rows - count\n        else:\n          max_results = page_size\n\n        try:\n          if page_token:\n            response = self._api.tabledata_list(name_parts, page_token=page_token,\n                                                max_results=max_results)\n          else:\n            response = self._api.tabledata_list(name_parts, start_index=start_row,\n                                                max_results=max_results)\n        except Exception as e:\n          raise e\n        page_token = response['pageToken'] if 'pageToken' in response else None\n        if 'rows' in response:\n          page_rows = response['rows']\n\n      rows = []\n      for row_dict in page_rows:\n        rows.append(_parser.Parser.parse_row(schema, row_dict))\n\n      return rows, page_token\n\n    return _retrieve_rows\n\n  def range(self, start_row=0, max_rows=None):\n    \"\"\" Get an iterator to iterate through a set of table rows.\n\n    Args:\n      start_row: the row of the table at which to start the iteration (default 0)\n      max_rows: an upper limit on the number of rows to iterate through (default None)\n\n    Returns:\n      A row iterator.\n    \"\"\"\n    fetcher = self._get_row_fetcher(start_row=start_row, max_rows=max_rows)\n    return iter(google.datalab.utils.Iterator(fetcher))\n\n  def to_dataframe(self, start_row=0, max_rows=None):\n    \"\"\" Exports the table to a Pandas dataframe.\n\n    Args:\n      start_row: the row of the table at which to start the export (default 0)\n      max_rows: an upper limit on the number of rows to export (default None)\n    Returns:\n      A Pandas dataframe containing the table data.\n    \"\"\"\n    fetcher = self._get_row_fetcher(start_row=start_row,\n                                    max_rows=max_rows,\n                                    page_size=self._MAX_PAGE_SIZE)\n    count = 0\n    page_token = None\n\n    # Collect results of page fetcher in separate dataframe objects, then\n    # concatenate them to reduce the amount of copying\n    df_list = []\n    df = None\n\n    while True:\n      page_rows, page_token = fetcher(page_token, count)\n      if len(page_rows):\n        count += len(page_rows)\n        df_list.append(pandas.DataFrame.from_records(page_rows))\n      if not page_token:\n        break\n    if df_list:\n      df = pandas.concat(df_list, ignore_index=True, copy=False)\n\n    # Need to reorder the dataframe to preserve column ordering\n    ordered_fields = [field.name for field in self.schema]\n    return df[ordered_fields] if df is not None else pandas.DataFrame()\n\n  def to_file(self, destination, format='csv', csv_delimiter=',', csv_header=True):\n    \"\"\"Save the results to a local file in CSV format.\n\n    Args:\n      destination: path on the local filesystem for the saved results.\n      format: the format to use for the exported data; currently only 'csv' is supported.\n      csv_delimiter: for CSV exports, the field delimiter to use. Defaults to ','\n      csv_header: for CSV exports, whether to include an initial header line. Default true.\n    Raises:\n      An Exception if the operation failed.\n    \"\"\"\n    f = codecs.open(destination, 'w', 'utf-8')\n    fieldnames = []\n    for column in self.schema:\n      fieldnames.append(column.name)\n    if sys.version_info[0] == 2:\n      csv_delimiter = csv_delimiter.encode('unicode_escape')\n    writer = csv.DictWriter(f, fieldnames=fieldnames, delimiter=csv_delimiter)\n    if csv_header:\n      writer.writeheader()\n    for row in self:\n      writer.writerow(row)\n    f.close()\n\n  @property\n  def schema(self):\n    \"\"\"Retrieves the schema of the table.\n\n    Returns:\n      A Schema object containing a list of schema fields and associated metadata.\n    Raises\n      Exception if the request could not be executed or the response was malformed.\n    \"\"\"\n    if not self._schema:\n      try:\n        self._load_info()\n        self._schema = _schema.Schema(self._info['schema']['fields'])\n      except KeyError:\n        raise Exception('Unexpected table response: missing schema')\n    return self._schema\n\n  def update(self, friendly_name=None, description=None, expiry=None, schema=None):\n    \"\"\" Selectively updates Table information.\n\n    Any parameters that are omitted or None are not updated.\n\n    Args:\n      friendly_name: if not None, the new friendly name.\n      description: if not None, the new description.\n      expiry: if not None, the new expiry time, either as a DateTime or milliseconds since epoch.\n      schema: if not None, the new schema: either a list of dictionaries or a Schema.\n    \"\"\"\n    self._load_info()\n    if friendly_name is not None:\n      self._info['friendlyName'] = friendly_name\n    if description is not None:\n      self._info['description'] = description\n    if expiry is not None:\n      if isinstance(expiry, datetime.datetime):\n        expiry = calendar.timegm(expiry.utctimetuple()) * 1000\n      self._info['expirationTime'] = expiry\n    if schema is not None:\n      if isinstance(schema, _schema.Schema):\n        schema = schema._bq_schema\n      self._info['schema'] = {'fields': schema}\n    try:\n      self._api.table_update(self._name_parts, self._info)\n    except google.datalab.utils.RequestException:\n      # The cached metadata is out of sync now; abandon it.\n      self._info = None\n    except Exception as e:\n      raise e\n\n  def _repr_sql_(self):\n    \"\"\"Returns a representation of the table for embedding into a SQL statement.\n\n    Returns:\n      A formatted table name for use within SQL statements.\n    \"\"\"\n    return '`' + self._full_name + '`'\n\n  def __repr__(self):\n    \"\"\"Returns a representation for the table for showing in the notebook.\n    \"\"\"\n    return 'BigQuery Table - name: %s' % self._full_name\n\n  @property\n  def length(self):\n    \"\"\" Get the length of the table (number of rows). We don't use __len__ as this may\n        return -1 for 'unknown'.\n    \"\"\"\n    return self.metadata.rows\n\n  def __iter__(self):\n    \"\"\" Get an iterator for the table.\n    \"\"\"\n    return self.range(start_row=0)\n\n  def __getitem__(self, item):\n    \"\"\" Get an item or a slice of items from the table. This uses a small cache\n        to reduce the number of calls to tabledata.list.\n\n        Note: this is a useful function to have, and supports some current usage like\n        query.execute().result()[0], but should be used with care.\n    \"\"\"\n    if isinstance(item, slice):\n      # Just treat this as a set of calls to __getitem__(int)\n      result = []\n      i = item.start\n      step = item.step if item.step else 1\n      while i < item.stop:\n        result.append(self[i])\n        i += step\n      return result\n\n    # Handle the integer index case.\n    if item < 0:\n      if self.length >= 0:\n        item += self.length\n      else:\n        raise Exception('Cannot use negative indices for table of unknown length')\n\n    if not self._cached_page \\\n        or self._cached_page_index > item \\\n            or self._cached_page_index + len(self._cached_page) <= item:\n      # cache a new page. To get the start row we round to the nearest multiple of the page\n      # size.\n      first = old_div(item, self._DEFAULT_PAGE_SIZE) * self._DEFAULT_PAGE_SIZE\n      count = self._DEFAULT_PAGE_SIZE\n\n      if self.length >= 0:\n        remaining = self.length - first\n        if count > remaining:\n          count = remaining\n\n      fetcher = self._get_row_fetcher(start_row=first, max_rows=count, page_size=count)\n      self._cached_page_index = first\n      self._cached_page, _ = fetcher(None, 0)\n\n    return self._cached_page[item - self._cached_page_index]\n\n  @staticmethod\n  def _convert_decorator_time(when):\n    if isinstance(when, datetime.datetime):\n      value = 1000 * (when - datetime.datetime.utcfromtimestamp(0)).total_seconds()\n    elif isinstance(when, datetime.timedelta):\n      value = when.total_seconds() * 1000\n      if value > 0:\n        raise Exception(\"Invalid snapshot relative when argument: %s\" % str(when))\n    else:\n      raise Exception(\"Invalid snapshot when argument type: %s\" % str(when))\n\n    if value < -Table._MSEC_PER_WEEK:\n      raise Exception(\"Invalid snapshot relative when argument: must be within 7 days: %s\"\n                      % str(when))\n\n    if value > 0:\n      now = 1000 * (datetime.datetime.utcnow() -\n                    datetime.datetime.utcfromtimestamp(0)).total_seconds()\n      # Check that an abs value is not more than 7 days in the past and is\n      # not in the future\n      if not ((now - Table._MSEC_PER_WEEK) < value < now):\n        raise Exception(\"Invalid snapshot absolute when argument: %s\" % str(when))\n\n    return int(value)\n\n  def snapshot(self, at):\n    \"\"\" Return a new Table which is a snapshot of this table at the specified time.\n\n    Args:\n      at: the time of the snapshot. This can be a Python datetime (absolute) or timedelta\n          (relative to current time). The result must be after the table was created and no more\n          than seven days in the past. Passing None will get a reference the oldest snapshot.\n\n          Note that using a datetime will get a snapshot at an absolute point in time, while\n          a timedelta will provide a varying snapshot; any queries issued against such a Table\n          will be done against a snapshot that has an age relative to the execution time of the\n          query.\n\n    Returns:\n      A new Table object referencing the snapshot.\n\n    Raises:\n      An exception if this Table is already decorated, or if the time specified is invalid.\n    \"\"\"\n    if self._name_parts.decorator != '':\n      raise Exception(\"Cannot use snapshot() on an already decorated table\")\n\n    value = Table._convert_decorator_time(at)\n    return Table(\"%s@%s\" % (self._full_name, str(value)), context=self._context)\n\n  def window(self, begin, end=None):\n    \"\"\" Return a new Table limited to the rows added to this Table during the specified time range.\n\n    Args:\n      begin: the start time of the window. This can be a Python datetime (absolute) or timedelta\n          (relative to current time). The result must be after the table was created and no more\n          than seven days in the past.\n\n          Note that using a relative value will provide a varying snapshot, not a fixed\n          snapshot; any queries issued against such a Table will be done against a snapshot\n          that has an age relative to the execution time of the query.\n\n      end: the end time of the snapshot; if None, then the current time is used. The types and\n          interpretation of values is as for start.\n\n    Returns:\n      A new Table object referencing the window.\n\n    Raises:\n      An exception if this Table is already decorated, or if the time specified is invalid.\n    \"\"\"\n    if self._name_parts.decorator != '':\n      raise Exception(\"Cannot use window() on an already decorated table\")\n\n    start = Table._convert_decorator_time(begin)\n    if end is None:\n      if isinstance(begin, datetime.timedelta):\n        end = datetime.timedelta(0)\n      else:\n        end = datetime.datetime.utcnow()\n    stop = Table._convert_decorator_time(end)\n\n    # Both values must have the same sign\n    if (start > 0 >= stop) or (stop > 0 >= start):\n      raise Exception(\"window: Between arguments must both be absolute or relative: %s, %s\" %\n                      (str(begin), str(end)))\n\n    # start must be less than stop\n    if start > stop:\n      raise Exception(\"window: Between arguments: begin must be before end: %s, %s\" %\n                      (str(begin), str(end)))\n\n    return Table(\"%s@%s-%s\" % (self._full_name, str(start), str(stop)), context=self._context)\n"
  },
  {
    "path": "google/datalab/bigquery/_udf.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Google Cloud Platform library - BigQuery UDF Functionality.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom past.builtins import basestring\nfrom builtins import object\n\n\nclass UDF(object):\n  \"\"\"Represents a BigQuery UDF declaration.\n  \"\"\"\n\n  @property\n  def name(self):\n    return self._name\n\n  @property\n  def imports(self):\n    return self._imports\n\n  @property\n  def code(self):\n    return self._code\n\n  def __init__(self, name, code, return_type, params=None, language='js', imports=None):\n    \"\"\"Initializes a UDF object from its pieces.\n\n    Args:\n      name: the name of the javascript function\n      code: function body implementing the logic.\n      return_type: BigQuery data type of the function return. See supported data types in\n        the BigQuery docs\n      params: list of parameter tuples: (name, type)\n      language: see list of supported languages in the BigQuery docs\n      imports: a list of GCS paths containing further support code.\n      \"\"\"\n    if not isinstance(return_type, basestring):\n      raise TypeError('Argument return_type should be a string. Instead got: ', type(return_type))\n    if params and not isinstance(params, list):\n      raise TypeError('Argument params should be a list of parameter names and types')\n    if imports and not isinstance(imports, list):\n      raise TypeError('Argument imports should be a list of GCS string paths')\n    if imports and language != 'js':\n      raise Exception('Imports are available for Javascript UDFs only')\n\n    self._name = name\n    self._code = code\n    self._return_type = return_type\n    self._params = params or []\n    self._language = language\n    self._imports = imports or []\n    self._sql = None\n\n  def _expanded_sql(self):\n    \"\"\"Get the expanded BigQuery SQL string of this UDF\n\n    Returns\n      The expanded SQL string of this UDF\n    \"\"\"\n    if not self._sql:\n      self._sql = UDF._build_udf(self._name, self._code, self._return_type, self._params,\n                                 self._language, self._imports)\n    return self._sql\n\n  def _repr_sql_(self):\n    return self._expanded_sql()\n\n  def __repr__(self):\n    return 'BigQuery UDF - code:\\n%s' % self._code\n\n  @staticmethod\n  def _build_udf(name, code, return_type, params, language, imports):\n    \"\"\"Creates the UDF part of a BigQuery query using its pieces\n\n    Args:\n      name: the name of the javascript function\n      code: function body implementing the logic.\n      return_type: BigQuery data type of the function return. See supported data types in\n        the BigQuery docs\n      params: dictionary of parameter names and types\n      language: see list of supported languages in the BigQuery docs\n      imports: a list of GCS paths containing further support code.\n      \"\"\"\n\n    params = ','.join(['%s %s' % named_param for named_param in params])\n    imports = ','.join(['library=\"%s\"' % i for i in imports])\n\n    if language.lower() == 'sql':\n        udf = 'CREATE TEMPORARY FUNCTION {name} ({params})\\n' + \\\n              'RETURNS {return_type}\\n' + \\\n              'AS (\\n' + \\\n              '{code}\\n' + \\\n              ');'\n    else:\n        udf = 'CREATE TEMPORARY FUNCTION {name} ({params})\\n' +\\\n              'RETURNS {return_type}\\n' + \\\n              'LANGUAGE {language}\\n' + \\\n              'AS \"\"\"\\n' +\\\n              '{code}\\n' +\\\n              '\"\"\"\\n' +\\\n              'OPTIONS (\\n' +\\\n              '{imports}\\n' +\\\n              ');'\n    return udf.format(name=name, params=params, return_type=return_type,\n                      language=language, code=code, imports=imports)\n"
  },
  {
    "path": "google/datalab/bigquery/_utils.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Useful common utility functions.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom builtins import str\nfrom past.builtins import basestring\n\nimport collections\nimport re\n\n\nDatasetName = collections.namedtuple('DatasetName', ['project_id', 'dataset_id'])\n\"\"\" A namedtuple for Dataset names.\n\n  Args:\n    project_id: the project id for the dataset.\n    dataset_id: the dataset id for the dataset.\n\"\"\"\n\nTableName = collections.namedtuple('TableName',\n                                   ['project_id', 'dataset_id', 'table_id', 'decorator'])\n\"\"\" A namedtuple for Table names.\n\n  Args:\n    project_id: the project id for the table.\n    dataset_id: the dataset id for the table.\n    table_id: the table id for the table.\n    decorator: the optional decorator for the table (for windowing/snapshot-ing).\n\"\"\"\n\n# Absolute project-qualified name pattern: <project>.<dataset>\n_ABS_DATASET_NAME_PATTERN = r'^([a-z\\d\\-_\\.:]+)\\.(\\w+)$'\n\n# Relative name pattern: <dataset>\n_REL_DATASET_NAME_PATTERN = r'^(\\w+)$'\n\n# Absolute project-qualified name pattern: <project>.<dataset>.<table>\n_ABS_TABLE_NAME_PATTERN = r'^([a-z\\d\\-_\\.:]+)\\.(\\w+)\\.(\\w+)(@[\\d\\-]+)?$'\n\n# Relative name pattern: <dataset>.<table>\n_REL_TABLE_NAME_PATTERN = r'^(\\w+)\\.(\\w+)(@[\\d\\-]+)?$'\n\n# Table-only name pattern: <table>. Includes an optional decorator.\n_TABLE_NAME_PATTERN = r'^(\\w+)(@[\\d\\-]+)$'\n\n\ndef parse_dataset_name(name, project_id=None):\n  \"\"\"Parses a dataset name into its individual parts.\n\n  Args:\n    name: the name to parse, or a tuple, dictionary or array containing the parts.\n    project_id: the expected project ID. If the name does not contain a project ID,\n        this will be used; if the name does contain a project ID and it does not match\n        this, an exception will be thrown.\n  Returns:\n    A DatasetName named tuple for the dataset.\n  Raises:\n    Exception: raised if the name doesn't match the expected formats or a project_id was\n        specified that does not match that in the name.\n  \"\"\"\n  _project_id = _dataset_id = None\n  if isinstance(name, basestring):\n    # Try to parse as absolute name first.\n    m = re.match(_ABS_DATASET_NAME_PATTERN, name, re.IGNORECASE)\n    if m is not None:\n      _project_id, _dataset_id = m.groups()\n    else:\n      # Next try to match as a relative name implicitly scoped within current project.\n      m = re.match(_REL_DATASET_NAME_PATTERN, name)\n      if m is not None:\n        groups = m.groups()\n        _dataset_id = groups[0]\n  elif isinstance(name, dict):\n    try:\n      _dataset_id = name['dataset_id']\n      _project_id = name['project_id']\n    except KeyError:\n      pass\n  else:\n    # Try treat as an array or tuple\n    if len(name) == 2:\n      # Treat as a tuple or array.\n      _project_id, _dataset_id = name\n    elif len(name) == 1:\n      _dataset_id = name[0]\n  if not _dataset_id:\n    raise Exception('Invalid dataset name: ' + str(name))\n  if not _project_id:\n    _project_id = project_id\n\n  return DatasetName(_project_id, _dataset_id)\n\n\ndef parse_table_name(name, project_id=None, dataset_id=None):\n  \"\"\"Parses a table name into its individual parts.\n\n  Args:\n    name: the name to parse, or a tuple, dictionary or array containing the parts.\n    project_id: the expected project ID. If the name does not contain a project ID,\n        this will be used; if the name does contain a project ID and it does not match\n        this, an exception will be thrown.\n    dataset_id: the expected dataset ID. If the name does not contain a dataset ID,\n        this will be used; if the name does contain a dataset ID and it does not match\n        this, an exception will be thrown.\n  Returns:\n    A TableName named tuple consisting of the full name and individual name parts.\n  Raises:\n    Exception: raised if the name doesn't match the expected formats, or a project_id and/or\n        dataset_id was provided that does not match that in the name.\n  \"\"\"\n  _project_id = _dataset_id = _table_id = _decorator = None\n  if isinstance(name, basestring):\n    # Try to parse as absolute name first.\n    m = re.match(_ABS_TABLE_NAME_PATTERN, name, re.IGNORECASE)\n    if m is not None:\n      _project_id, _dataset_id, _table_id, _decorator = m.groups()\n    else:\n      # Next try to match as a relative name implicitly scoped within current project.\n      m = re.match(_REL_TABLE_NAME_PATTERN, name)\n      if m is not None:\n        groups = m.groups()\n        _project_id, _dataset_id, _table_id, _decorator =\\\n            project_id, groups[0], groups[1], groups[2]\n      else:\n        # Finally try to match as a table name only.\n        m = re.match(_TABLE_NAME_PATTERN, name)\n        if m is not None:\n          groups = m.groups()\n          _project_id, _dataset_id, _table_id, _decorator =\\\n              project_id, dataset_id, groups[0], groups[1]\n  elif isinstance(name, dict):\n    try:\n      _table_id = name['table_id']\n      _dataset_id = name['dataset_id']\n      _project_id = name['project_id']\n    except KeyError:\n      pass\n  else:\n    # Try treat as an array or tuple\n    if len(name) == 4:\n      _project_id, _dataset_id, _table_id, _decorator = name\n    elif len(name) == 3:\n      _project_id, _dataset_id, _table_id = name\n    elif len(name) == 2:\n      _dataset_id, _table_id = name\n  if not _table_id:\n    raise Exception('Invalid table name: ' + str(name))\n  if not _project_id:\n    _project_id = project_id\n  if not _dataset_id:\n    _dataset_id = dataset_id\n  if not _decorator:\n    _decorator = ''\n\n  return TableName(_project_id, _dataset_id, _table_id, _decorator)\n\n\ndef format_query_errors(errors):\n  return '\\n'.join(['%s: %s' % (error['reason'], error['message']) for error in errors])\n"
  },
  {
    "path": "google/datalab/bigquery/_view.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Implements BigQuery Views.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom builtins import str\nfrom builtins import object\n\nimport google.datalab\n\nfrom . import _query\nfrom . import _table\n\n# Query import is at end to avoid issues with circular dependencies.\n\n\nclass View(object):\n  \"\"\" An implementation of a BigQuery View. \"\"\"\n\n  # Views in BigQuery are virtual tables, but it is useful to have a mixture of both Table and\n  # Query semantics; our version thus internally has a BaseTable and a Query (for materialization;\n  # not the same as the view query), and exposes a number of the same APIs as Table and Query\n  # through wrapper functions around these.\n\n  def __init__(self, name, context=None):\n    \"\"\"Initializes an instance of a View object.\n\n    Args:\n      name: the name of the view either as a string or a 3-part tuple\n          (projectid, datasetid, name). If a string, it must have the form\n          '<project>.<dataset>.<view>' or '<dataset>.<view>'.\n      context: an optional Context object providing project_id and credentials. If a specific\n          project id or credentials are unspecified, the default ones configured at the global\n          level are used.\n    Raises:\n      Exception if the name is invalid.\n      \"\"\"\n    if context is None:\n      context = google.datalab.Context.default()\n    self._context = context\n    self._table = _table.Table(name, context=context)\n    self._materialization = _query.Query('SELECT * FROM %s' % self._repr_sql_())\n\n  @property\n  def name(self):\n    \"\"\"The name for the view as a named tuple.\"\"\"\n    return self._table.name\n\n  @property\n  def description(self):\n    \"\"\"The description of the view if it exists.\"\"\"\n    return self._table.metadata.description\n\n  @property\n  def friendly_name(self):\n    \"\"\"The friendly name of the view if it exists.\"\"\"\n    return self._table.metadata.friendly_name\n\n  @property\n  def query(self):\n    \"\"\"The Query that defines the view.\"\"\"\n    if not self.exists():\n      return None\n    self._table._load_info()\n    if 'view' in self._table._info and 'query' in self._table._info['view']:\n      return _query.Query(self._table._info['view']['query'])\n    return None\n\n  def exists(self):\n    \"\"\"Whether the view's Query has been executed and the view is available or not.\"\"\"\n    return self._table.exists()\n\n  def delete(self):\n    \"\"\"Removes the view if it exists.\"\"\"\n    self._table.delete()\n\n  def create(self, query):\n    \"\"\" Creates the view with the specified query.\n\n    Args:\n      query: the query to use to for the View; either a string containing a SQL query or\n          a Query object.\n    Returns:\n      The View instance.\n    Raises:\n      Exception if the view couldn't be created or already exists and overwrite was False.\n    \"\"\"\n    if isinstance(query, _query.Query):\n      query = query.sql\n    try:\n      response = self._table._api.tables_insert(self._table.name, query=query)\n    except Exception as e:\n      raise e\n    if 'selfLink' in response:\n      return self\n    raise Exception(\"View %s could not be created as it already exists\" % str(self))\n\n  @property\n  def schema(self):\n    \"\"\"Retrieves the schema of the table.\n\n    Returns:\n      A Schema object containing a list of schema fields and associated metadata.\n    Raises\n      Exception if the request could not be executed or the response was malformed.\n    \"\"\"\n    return self._table.schema\n\n  def update(self, friendly_name=None, description=None, query=None):\n    \"\"\" Selectively updates View information.\n\n    Any parameters that are None (the default) are not applied in the update.\n\n    Args:\n      friendly_name: if not None, the new friendly name.\n      description: if not None, the new description.\n      query: if not None, a new query string for the View.\n    \"\"\"\n    self._table._load_info()\n    if query is not None:\n      if isinstance(query, _query.Query):\n        query = query.sql\n      self._table._info['view'] = {'query': query}\n    self._table.update(friendly_name=friendly_name, description=description)\n\n  def _repr_sql_(self):\n    \"\"\"Returns a representation of the view for embedding into a SQL statement.\n\n    Returns:\n      A formatted table name for use within SQL statements.\n    \"\"\"\n    return self._table._repr_sql_()\n\n  def __repr__(self):\n    \"\"\"Returns a representation for the view for showing in the notebook.\n    \"\"\"\n    return 'BigQuery View - table: %s, sql: %s' % (self._table, self.query)\n"
  },
  {
    "path": "google/datalab/bigquery/commands/__init__.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\nfrom __future__ import absolute_import\n\nfrom . import _bigquery\n\n__all__ = ['_bigquery']\n"
  },
  {
    "path": "google/datalab/bigquery/commands/_bigquery.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Google Cloud Platform library - BigQuery IPython Functionality.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import print_function\nfrom __future__ import unicode_literals\nfrom builtins import str\nfrom past.builtins import basestring\n\ntry:\n  import IPython\n  import IPython.core.display\n  import IPython.core.magic\nexcept ImportError:\n  raise Exception('This module can only be loaded in ipython.')\n\nimport datetime\nimport jsonschema\nimport fnmatch\nimport json\nimport re\n\nimport google.datalab.bigquery as bigquery\nimport google.datalab.data\nimport google.datalab.utils\nimport google.datalab.utils.commands\n\nfrom google.datalab.bigquery._query_output import QueryOutput\nfrom google.datalab.bigquery._sampling import Sampling\n\n\nclass BigQuerySchema(object):\n  \"\"\"A container class for commonly used BQ-related constants.\"\"\"\n\n  DATATYPES = ['STRING', 'BYTES', 'INTEGER', 'INT64', 'FLOAT', 'FLOAT64', 'BOOLEAN', 'BOOL',\n               'TIMESTAMP', 'DATE', 'TIME', 'DATETIME', 'RECORD']\n  DATATYPES_LOWER = [t.lower() for t in DATATYPES]\n  MODES = ['NULLABLE', 'REQUIRED', 'REPEATED']\n  MODES_LOWER = [m.lower() for m in MODES]\n\n  TABLE_SCHEMA_SCHEMA = {\n    'definitions': {\n      'field': {\n        'title': 'field',\n        'type': 'object',\n        'properties': {\n          'name': {'type': 'string'},\n          'type': {'type': 'string', 'enum': DATATYPES + DATATYPES_LOWER},\n          'mode': {'type': 'string', 'enum': MODES + MODES_LOWER},\n          'description': {'type': 'string'},\n          'fields': {\n            'type': 'array',\n            'items': {\n              'allOf': [{'$ref': '#/definitions/field'}]\n            }\n          }\n        },\n        'required': ['name', 'type'],\n        'additionalProperties': False\n      }\n    },\n    'type': 'object',\n    'properties': {\n      'schema': {\n        'type': 'array',\n        'items': {\n          'allOf': [{'$ref': '#/definitions/field'}]\n        }\n      }\n    },\n    'required': ['schema'],\n    'additionalProperties': False\n  }\n\n  QUERY_PARAMS_SCHEMA = {\n    'type': 'object',\n    'properties': {\n      'parameters': {\n        'type': 'array',\n        'items': [\n          {\n            'type': 'object',\n            'properties': {\n              'name': {'type': 'string'},\n              'type': {'type': 'string', 'enum': DATATYPES + DATATYPES_LOWER},\n              'value': {'type': ['string', 'integer', 'number']}\n            },\n            'required': ['name', 'type', 'value'],\n            'additionalProperties': False\n          }\n        ]\n      }\n    },\n    'required': ['parameters'],\n    'additionalProperties': False\n  }\n\n\ndef _create_dataset_subparser(parser):\n  dataset_parser = parser.subcommand('datasets', 'Operations on BigQuery datasets')\n  sub_commands = dataset_parser.add_subparsers(dest='command')\n\n  # %%bq datasets list\n  list_parser = sub_commands.add_parser('list', help='List datasets')\n  list_parser.add_argument('-p', '--project',\n                           help='The project whose datasets should be listed')\n  list_parser.add_argument('-f', '--filter',\n                           help='Optional wildcard filter string used to limit the results')\n\n  # %%bq datasets create\n  create_parser = sub_commands.add_parser('create', help='Create a dataset.')\n  create_parser.add_argument('-n', '--name', help='The name of the dataset to create.',\n                             required=True)\n  create_parser.add_argument('-f', '--friendly', help='The friendly name of the dataset.')\n\n  # %%bq datasets delete\n  delete_dataset_parser = sub_commands.add_parser('delete', help='Delete a dataset.')\n  delete_dataset_parser.add_argument('-n', '--name', help='The name of the dataset to delete.',\n                                     required=True)\n\n  return dataset_parser\n\n\ndef _create_table_subparser(parser):\n  table_parser = parser.subcommand('tables', 'Operations on BigQuery tables')\n  sub_commands = table_parser.add_subparsers(dest='command')\n\n  # %%bq tables list\n  list_parser = sub_commands.add_parser('list',\n                                        help='List the tables in a BigQuery project or dataset.')\n  list_parser.add_argument('-p', '--project', help='The project whose tables should be listed')\n  list_parser.add_argument('-d', '--dataset', help='The dataset to restrict to')\n  list_parser.add_argument('-f', '--filter',\n                           help='Optional wildcard filter string used to limit the results')\n\n  # %%bq tables create\n  create_parser = sub_commands.add_parser('create', help='Create a table.')\n  create_parser.add_argument('-n', '--name', help='The name of the table to create.', required=True)\n  create_parser.add_argument('-o', '--overwrite', help='Overwrite table if it exists.',\n                             action='store_true')\n\n  # %%bq tables describe\n  describe_parser = sub_commands.add_parser('describe', help='View a table\\'s schema')\n  describe_parser.add_argument('-n', '--name', help='Name of table to show', required=True)\n\n  # %%bq tables delete\n  delete_parser = sub_commands.add_parser('delete', help='Delete a table.')\n  delete_parser.add_argument('-n', '--name', help='The name of the table to delete.', required=True)\n\n  # %%bq tables view\n  delete_parser = sub_commands.add_parser('view', help='View a table.')\n  delete_parser.add_argument('-n', '--name', help='The name of the table to view.', required=True)\n\n  return table_parser\n\n\ndef _create_sample_subparser(parser):\n  sample_parser = parser.subcommand('sample',\n                                    help='Display a sample of the results of a BigQuery SQL query. '\n                                         'The cell can optionally contain arguments for expanding '\n                                         'variables in the query, if -q/--query was used, or it '\n                                         'can contain SQL for a query.')\n  group = sample_parser.add_mutually_exclusive_group()\n  group.add_argument('-q', '--query', help='the name of the query object to sample')\n  group.add_argument('-t', '--table', help='the name of the table object to sample')\n  group.add_argument('-v', '--view', help='the name of the view object to sample')\n  sample_parser.add_argument('-nc', '--nocache', help='Don\\'t use previously cached results',\n                             action='store_true')\n  sample_parser.add_argument('-b', '--billing', type=int, help='BigQuery billing tier')\n  sample_parser.add_argument('-m', '--method', help='The type of sampling to use',\n                             choices=['limit', 'random', 'hashed', 'sorted'], default='limit')\n  sample_parser.add_argument('--fields', help='Comma separated field names for projection')\n  sample_parser.add_argument('-c', '--count', type=int, default=10,\n                             help='The number of rows to limit to, if sampling')\n  sample_parser.add_argument('-p', '--percent', type=int, default=1,\n                             help='For random or hashed sampling, what percentage to sample from')\n  sample_parser.add_argument('--key-field',\n                             help='The field to use for sorted or hashed sampling')\n  sample_parser.add_argument('-o', '--order', choices=['ascending', 'descending'],\n                             default='ascending', help='The sort order to use for sorted sampling')\n  sample_parser.add_argument('-P', '--profile', action='store_true',\n                             default=False, help='Generate an interactive profile of the data')\n  sample_parser.add_argument('--verbose',\n                             help='Show the expanded SQL that is being executed',\n                             action='store_true')\n  return sample_parser\n\n\ndef _create_udf_subparser(parser):\n  udf_parser = parser.subcommand('udf', 'Create a named Javascript BigQuery UDF')\n  udf_parser.add_argument('-n', '--name', help='The name for this UDF', required=True)\n  udf_parser.add_argument('-l', '--language', help='The language of the function', required=True,\n                          choices=['sql', 'js'])\n  return udf_parser\n\n\ndef _create_datasource_subparser(parser):\n  datasource_parser = parser.subcommand('datasource',\n                                        'Create a named Javascript BigQuery external data source')\n  datasource_parser.add_argument('-n', '--name', help='The name for this data source',\n                                 required=True)\n  datasource_parser.add_argument('-p', '--paths',\n                                 help='URL(s) of the data objects, can include a wildcard \"*\" at '\n                                      'the end',\n                                 required=True, nargs='+')\n  datasource_parser.add_argument('-f', '--format',\n                                 help='The format of the table\\'s data. CSV or JSON, default CSV',\n                                 default='CSV')\n  datasource_parser.add_argument('-c', '--compressed', help='Whether the data is compressed',\n                                 action='store_true')\n  return datasource_parser\n\n\ndef _create_dryrun_subparser(parser):\n  dryrun_parser = parser.subcommand('dryrun', 'Execute a dry run of a BigQuery query and display '\n                                              'approximate usage statistics')\n  dryrun_parser.add_argument('-q', '--query', help='The name of the query to be dry run')\n  dryrun_parser.add_argument('-b', '--billing', type=int, help='BigQuery billing tier')\n  dryrun_parser.add_argument('-v', '--verbose', help='Show the expanded SQL that is being executed',\n                             action='store_true')\n  return dryrun_parser\n\n\ndef _create_query_subparser(parser):\n  query_parser = parser.subcommand('query', 'Create or execute a BigQuery SQL query object, '\n                                            'optionally using other SQL objects, UDFs, or external '\n                                            'datasources. If a query name is not specified, the '\n                                            'query is executed.')\n  query_parser.add_argument('-n', '--name', help='The name of this SQL query object')\n  query_parser.add_argument('--udfs', help='List of UDFs to reference in the query body', nargs='+')\n  query_parser.add_argument('--datasources',\n                            help='List of external datasources to reference in the query body',\n                            nargs='+')\n  query_parser.add_argument('--subqueries',\n                            help='List of subqueries to reference in the query body',\n                            nargs='+')\n  query_parser.add_argument('-v', '--verbose', help='Show the expanded SQL that is being executed',\n                            action='store_true')\n  return query_parser\n\n\ndef _create_execute_subparser(parser):\n  execute_parser = parser.subcommand('execute', 'Execute a BigQuery SQL query and optionally send '\n                                                'the results to a named table.\\nThe cell can '\n                                                'optionally contain arguments for expanding '\n                                                'variables in the query.')\n  execute_parser.add_argument('-nc', '--nocache', help='Don\\'t use previously cached results',\n                              action='store_true')\n  execute_parser.add_argument('-b', '--billing', type=int, help='BigQuery billing tier')\n  execute_parser.add_argument('-m', '--mode', help='The table creation mode', default='create',\n                              choices=['create', 'append', 'overwrite'])\n  execute_parser.add_argument('-l', '--large', help='Whether to allow large results',\n                              action='store_true')\n  execute_parser.add_argument('-q', '--query', help='The name of query to run', required=True)\n  execute_parser.add_argument('-t', '--table', help='Target table name')\n  execute_parser.add_argument('--to-dataframe', help='Convert the result into a dataframe',\n                              action='store_true')\n  execute_parser.add_argument('--dataframe-start-row', help='Row of the table to start the ' +\n                              'dataframe export')\n  execute_parser.add_argument('--dataframe-max-rows', help='Upper limit on number of rows ' +\n                              'to export to the dataframe', default=None)\n  execute_parser.add_argument('-v', '--verbose',\n                              help='Show the expanded SQL that is being executed',\n                              action='store_true')\n  return execute_parser\n\n\ndef _create_extract_subparser(parser):\n  extract_parser = parser.subcommand('extract', 'Extract a query or table into file (local or GCS)')\n  extract_parser.add_argument('-nc', '--nocache', help='Don\\'t use previously cached results',\n                              action='store_true')\n  extract_parser.add_argument('-f', '--format', choices=['csv', 'json'], default='csv',\n                              help='The format to use for the export')\n  extract_parser.add_argument('-b', '--billing', type=int, help='BigQuery billing tier')\n  extract_parser.add_argument('-c', '--compress', action='store_true',\n                              help='Whether to compress the data')\n  extract_parser.add_argument('-H', '--header', action='store_true',\n                              help='Whether to include a header line (CSV only)')\n  extract_parser.add_argument('-D', '--delimiter', default=',',\n                              help='The field delimiter to use (CSV only)')\n  group = extract_parser.add_mutually_exclusive_group()\n  group.add_argument('-q', '--query', help='The name of query to extract')\n  group.add_argument('-t', '--table', help='The name of the table to extract')\n  group.add_argument('-v', '--view', help='The name of the view to extract')\n  extract_parser.add_argument('-p', '--path', help='The path of the destination')\n  extract_parser.add_argument('--verbose',\n                              help='Show the expanded SQL that is being executed',\n                              action='store_true')\n  return extract_parser\n\n\ndef _create_load_subparser(parser):\n  load_parser = parser.subcommand('load', 'Load data from GCS into a BigQuery table. If creating a '\n                                          'new table, a schema should be specified in YAML or JSON '\n                                          'in the cell body, otherwise the schema is inferred from '\n                                          'existing table.')\n  load_parser.add_argument('-m', '--mode', help='One of create (default), append or overwrite',\n                           choices=['create', 'append', 'overwrite'], default='create')\n  load_parser.add_argument('-f', '--format', help='The source format', choices=['json', 'csv'],\n                           default='csv')\n  load_parser.add_argument('--skip',\n                           help='The number of initial lines to skip; useful for CSV headers',\n                           type=int, default=0)\n  load_parser.add_argument('-s', '--strict', help='Whether to reject bad values and jagged lines',\n                           action='store_true')\n  load_parser.add_argument('-d', '--delimiter', default=',',\n                           help='The inter-field delimiter for CVS (default ,)')\n  load_parser.add_argument('-q', '--quote', default='\"',\n                           help='The quoted field delimiter for CVS (default \")')\n  load_parser.add_argument('-p', '--path', help='The path URL of the GCS source(s)')\n  load_parser.add_argument('-t', '--table', help='The destination table name')\n  return load_parser\n\n\ndef _get_query_argument(args, cell, env):\n  \"\"\" Get a query argument to a cell magic.\n\n  The query is specified with args['query']. We look that up and if it is a BQ query\n  object, just return it. If it is a string, build a query object out of it and return\n  that\n\n  Args:\n    args: the dictionary of magic arguments.\n    cell: the cell contents which can be variable value overrides (if args has a 'query'\n        value) or inline SQL otherwise.\n    env: a dictionary that is used for looking up variable values.\n\n  Returns:\n    A Query object.\n  \"\"\"\n  sql_arg = args.get('query', None)\n  if sql_arg is None:\n    # Assume we have inline SQL in the cell\n    if not isinstance(cell, basestring):\n      raise Exception('Expected a --query argument or inline SQL')\n    return bigquery.Query(cell, env=env)\n\n  item = google.datalab.utils.commands.get_notebook_item(sql_arg)\n  if isinstance(item, bigquery.Query):\n    return item\n  else:\n    raise Exception('Expected a query object, got %s.' % type(item))\n\n\ndef get_query_parameters(args, cell_body, date_time=datetime.datetime.now()):\n  \"\"\"Extract query parameters from cell body if provided\n  Also validates the cell body schema using jsonschema to catch errors before sending the http\n  request. This validation isn't complete, however; it does not validate recursive schemas,\n  but it acts as a good filter against most simple schemas\n\n  Args:\n    args: arguments passed to the magic cell\n    cell_body: body of the magic cell\n    date_time: The timestamp at which the date-time related parameters need to be resolved.\n\n  Returns:\n    Validated object containing query parameters\n  \"\"\"\n\n  env = google.datalab.utils.commands.notebook_environment()\n  config = google.datalab.utils.commands.parse_config(cell_body, env=env, as_dict=False)\n  sql = args['query']\n  if sql is None:\n    raise Exception('Cannot extract query parameters in non-query cell')\n\n  # Validate query_params\n  if config:\n    jsonschema.validate(config, BigQuerySchema.QUERY_PARAMS_SCHEMA)\n\n  config = config or {}\n  config_parameters = config.get('parameters', [])\n  return bigquery.Query.get_query_parameters(config_parameters, date_time=date_time)\n\n\ndef _sample_cell(args, cell_body):\n  \"\"\"Implements the BigQuery sample magic for sampling queries\n  The supported sytanx is:\n    %%bq sample <args>\n     [<inline SQL>]\n  Args:\n    args: the optional arguments following '%%bq sample'.\n    cell_body: optional contents of the cell\n  Returns:\n    The results of executing the sampling query, or a profile of the sample data.\n  \"\"\"\n\n  env = google.datalab.utils.commands.notebook_environment()\n  config = google.datalab.utils.commands.parse_config(cell_body, env, False) or {}\n  parameters = config.get('parameters') or []\n  if parameters:\n    jsonschema.validate({'parameters': parameters}, BigQuerySchema.QUERY_PARAMS_SCHEMA)\n\n  query = None\n  table = None\n  view = None\n  query_params = None\n\n  if args['query']:\n    query = google.datalab.utils.commands.get_notebook_item(args['query'])\n    if query is None:\n      raise Exception('Cannot find query %s.' % args['query'])\n    query_params = get_query_parameters(args, cell_body)\n\n  elif args['table']:\n    table_name = google.datalab.bigquery.Query.resolve_parameters(args['table'], parameters)\n    table = _get_table(table_name)\n    if not table:\n      raise Exception('Could not find table %s' % args['table'])\n  elif args['view']:\n    view = google.datalab.utils.commands.get_notebook_item(args['view'])\n    if not isinstance(view, bigquery.View):\n      raise Exception('Could not find view %s' % args['view'])\n  else:\n    raise Exception('A query, table, or view is neede to sample')\n\n  # parse comma-separated list of fields\n  fields = args['fields'].split(',') if args['fields'] else None\n  count = int(args['count']) if args['count'] else None\n  percent = int(args['percent']) if args['percent'] else None\n  sampling = Sampling._auto(method=args['method'], fields=fields, count=count, percent=percent,\n                            key_field=args['key_field'], ascending=(args['order'] == 'ascending'))\n\n  context = google.datalab.utils._utils._construct_context_for_args(args)\n\n  if view:\n    query = bigquery.Query.from_view(view)\n  elif table:\n    query = bigquery.Query.from_table(table)\n\n  if args['profile']:\n    results = query.execute(QueryOutput.dataframe(), sampling=sampling,\n                            context=context, query_params=query_params).result()\n  else:\n    results = query.execute(QueryOutput.table(), sampling=sampling, context=context,\n                            query_params=query_params).result()\n\n  if args['verbose']:\n    print(query.sql)\n\n  if args['profile']:\n    return google.datalab.utils.commands.profile_df(results)\n  else:\n    return results\n\n\ndef _dryrun_cell(args, cell_body):\n  \"\"\"Implements the BigQuery cell magic used to dry run BQ queries.\n\n   The supported syntax is:\n   %%bq dryrun [-q|--sql <query identifier>]\n   [<YAML or JSON cell_body or inline SQL>]\n\n  Args:\n    args: the argument following '%bq dryrun'.\n    cell_body: optional contents of the cell interpreted as YAML or JSON.\n  Returns:\n    The response wrapped in a DryRunStats object\n  \"\"\"\n  query = _get_query_argument(args, cell_body, google.datalab.utils.commands.notebook_environment())\n\n  if args['verbose']:\n    print(query.sql)\n\n  context = google.datalab.utils._utils._construct_context_for_args(args)\n  result = query.dry_run(context=context)\n  return bigquery._query_stats.QueryStats(\n    total_bytes=result['totalBytesProcessed'], is_cached=result['cacheHit'])\n\n\ndef _udf_cell(args, cell_body):\n  \"\"\"Implements the Bigquery udf cell magic for ipython notebooks.\n\n  The supported syntax is:\n  %%bq udf --name <var> --language <lang>\n  // @param <name> <type>\n  // @returns <type>\n  // @import <gcs_path>\n  <js function>\n\n  Args:\n    args: the optional arguments following '%%bq udf'.\n    cell_body: the UDF declaration (inputs and outputs) and implementation in javascript.\n  \"\"\"\n  udf_name = args['name']\n  if not udf_name:\n    raise Exception('Declaration must be of the form %%bq udf --name <variable name>')\n\n  # Parse out parameters, return type, and imports\n  param_pattern = r'^\\s*\\/\\/\\s*@param\\s+([<>\\w]+)\\s+([<>\\w,\\s]+)\\s*$'\n  returns_pattern = r'^\\s*\\/\\/\\s*@returns\\s+([<>\\w,\\s]+)\\s*$'\n  import_pattern = r'^\\s*\\/\\/\\s*@import\\s+(\\S+)\\s*$'\n\n  params = re.findall(param_pattern, cell_body, re.MULTILINE)\n  return_type = re.findall(returns_pattern, cell_body, re.MULTILINE)\n  imports = re.findall(import_pattern, cell_body, re.MULTILINE)\n\n  if len(return_type) < 1:\n    raise Exception('UDF return type must be defined using // @returns <type>')\n  if len(return_type) > 1:\n    raise Exception('Found more than one return type definition')\n\n  return_type = return_type[0]\n\n  # Finally build the UDF object\n  udf = bigquery.UDF(udf_name, cell_body, return_type, params, args['language'], imports)\n  google.datalab.utils.commands.notebook_environment()[udf_name] = udf\n\n\ndef _datasource_cell(args, cell_body):\n  \"\"\"Implements the BigQuery datasource cell magic for ipython notebooks.\n\n  The supported syntax is\n  %%bq datasource --name <var> --paths <url> [--format <CSV|JSON>]\n  <schema>\n\n  Args:\n    args: the optional arguments following '%%bq datasource'\n    cell_body: the datasource's schema in json/yaml\n  \"\"\"\n  name = args['name']\n  paths = args['paths']\n  data_format = (args['format'] or 'CSV').lower()\n  compressed = args['compressed'] or False\n\n  # Get the source schema from the cell body\n  record = google.datalab.utils.commands.parse_config(\n      cell_body, google.datalab.utils.commands.notebook_environment(), as_dict=False)\n\n  jsonschema.validate(record, BigQuerySchema.TABLE_SCHEMA_SCHEMA)\n  schema = bigquery.Schema(record['schema'])\n\n  # Finally build the datasource object\n  datasource = bigquery.ExternalDataSource(source=paths, source_format=data_format,\n                                           compressed=compressed, schema=schema)\n  google.datalab.utils.commands.notebook_environment()[name] = datasource\n\n\ndef _query_cell(args, cell_body):\n  \"\"\"Implements the BigQuery cell magic for used to build SQL objects.\n\n  The supported syntax is:\n\n      %%bq query <args>\n      [<inline SQL>]\n\n  Args:\n    args: the optional arguments following '%%bql query'.\n    cell_body: the contents of the cell\n  \"\"\"\n  name = args['name']\n  udfs = args['udfs']\n  datasources = args['datasources']\n  subqueries = args['subqueries']\n\n  # Finally build the query object\n  query = bigquery.Query(cell_body, env=IPython.get_ipython().user_ns, udfs=udfs,\n                         data_sources=datasources, subqueries=subqueries)\n\n  # if no name is specified, execute this query instead of defining it\n  if name is None:\n    return query.execute().result()\n  else:\n    google.datalab.utils.commands.notebook_environment()[name] = query\n\n\ndef _execute_cell(args, cell_body):\n  \"\"\"Implements the BigQuery cell magic used to execute BQ queries.\n\n   The supported syntax is:\n     %%bq execute <args>\n     [<inline SQL>]\n\n  Args:\n    args: the optional arguments following '%%bq execute'.\n    cell_body: optional contents of the cell\n  Returns:\n    QueryResultsTable containing query result\n  \"\"\"\n  env = google.datalab.utils.commands.notebook_environment()\n  config = google.datalab.utils.commands.parse_config(cell_body, env, False) or {}\n  parameters = config.get('parameters') or []\n  if parameters:\n    jsonschema.validate({'parameters': parameters}, BigQuerySchema.QUERY_PARAMS_SCHEMA)\n  table_name = google.datalab.bigquery.Query.resolve_parameters(args['table'], parameters)\n\n  query = google.datalab.utils.commands.get_notebook_item(args['query'])\n  if args['verbose']:\n    print(query.sql)\n\n  query_params = get_query_parameters(args, cell_body)\n\n  if args['to_dataframe']:\n    # re-parse the int arguments because they're passed as strings\n    start_row = int(args['dataframe_start_row']) if args['dataframe_start_row'] else None\n    max_rows = int(args['dataframe_max_rows']) if args['dataframe_max_rows'] else None\n    output_options = QueryOutput.dataframe(start_row=start_row, max_rows=max_rows,\n                                           use_cache=not args['nocache'])\n  else:\n    output_options = QueryOutput.table(\n      name=table_name, mode=args['mode'], use_cache=not args['nocache'],\n      allow_large_results=args['large'])\n  context = google.datalab.utils._utils._construct_context_for_args(args)\n  r = query.execute(output_options, context=context, query_params=query_params)\n  return r.result()\n\n\n# An LRU cache for Tables. This is mostly useful so that when we cross page boundaries\n# when paging through a table we don't have to re-fetch the schema.\n_existing_table_cache = google.datalab.utils.LRUCache(10)\n\n\ndef _get_table(name):\n  \"\"\" Given a variable or table name, get a Table if it exists.\n\n  Args:\n    name: the name of the Table or a variable referencing the Table.\n  Returns:\n    The Table, if found.\n  \"\"\"\n  # If name is a variable referencing a table, use that.\n  item = google.datalab.utils.commands.get_notebook_item(name)\n  if isinstance(item, bigquery.Table):\n    return item\n  # Else treat this as a BQ table name and return the (cached) table if it exists.\n  try:\n    return _existing_table_cache[name]\n  except KeyError:\n    table = bigquery.Table(name)\n    if table.exists():\n      _existing_table_cache[name] = table\n      return table\n  return None\n\n\ndef _render_list(data):\n  \"\"\" Helper to render a list of objects as an HTML list object. \"\"\"\n  return IPython.core.display.HTML(google.datalab.utils.commands.HtmlBuilder.render_list(data))\n\n\ndef _dataset_line(args):\n  \"\"\"Implements the BigQuery dataset magic subcommand used to operate on datasets\n\n   The supported syntax is:\n   %bq datasets <command> <args>\n\n  Commands:\n    {list, create, delete}\n\n  Args:\n    args: the optional arguments following '%bq datasets command'.\n  \"\"\"\n  if args['command'] == 'list':\n    filter_ = args['filter'] if args['filter'] else '*'\n    context = google.datalab.Context.default()\n    if args['project']:\n      context = google.datalab.Context(args['project'], context.credentials)\n    return _render_list([str(dataset) for dataset in bigquery.Datasets(context)\n                         if fnmatch.fnmatch(str(dataset), filter_)])\n\n  elif args['command'] == 'create':\n    try:\n      bigquery.Dataset(args['name']).create(friendly_name=args['friendly'])\n    except Exception as e:\n      print('Failed to create dataset %s: %s' % (args['name'], e))\n\n  elif args['command'] == 'delete':\n    try:\n      bigquery.Dataset(args['name']).delete()\n    except Exception as e:\n      print('Failed to delete dataset %s: %s' % (args['name'], e))\n\n\ndef _table_cell(args, cell_body):\n  \"\"\"Implements the BigQuery table magic subcommand used to operate on tables\n\n   The supported syntax is:\n   %%bq tables <command> <args>\n\n  Commands:\n    {list, create, delete, describe, view}\n\n  Args:\n    args: the optional arguments following '%%bq tables command'.\n    cell_body: optional contents of the cell interpreted as SQL, YAML or JSON.\n  Returns:\n    The HTML rendering for the table of datasets.\n  \"\"\"\n  if args['command'] == 'list':\n    filter_ = args['filter'] if args['filter'] else '*'\n    if args['dataset']:\n      if args['project'] is None:\n        datasets = [bigquery.Dataset(args['dataset'])]\n      else:\n        context = google.datalab.Context(args['project'],\n                                         google.datalab.Context.default().credentials)\n        datasets = [bigquery.Dataset(args['dataset'], context)]\n    else:\n      default_context = google.datalab.Context.default()\n      context = google.datalab.Context(default_context.project_id, default_context.credentials)\n      if args['project']:\n        context.set_project_id(args['project'])\n      datasets = bigquery.Datasets(context)\n\n    tables = []\n    for dataset in datasets:\n      tables.extend([table.full_name\n                     for table in dataset if fnmatch.fnmatch(table.full_name, filter_)])\n\n    return _render_list(tables)\n\n  elif args['command'] == 'create':\n    if cell_body is None:\n      print('Failed to create %s: no schema specified' % args['name'])\n    else:\n      try:\n        record = google.datalab.utils.commands.parse_config(\n            cell_body, google.datalab.utils.commands.notebook_environment(), as_dict=False)\n        jsonschema.validate(record, BigQuerySchema.TABLE_SCHEMA_SCHEMA)\n        schema = bigquery.Schema(record['schema'])\n        bigquery.Table(args['name']).create(schema=schema, overwrite=args['overwrite'])\n      except Exception as e:\n        print('Failed to create table %s: %s' % (args['name'], e))\n\n  elif args['command'] == 'describe':\n    name = args['name']\n    table = _get_table(name)\n    if not table:\n      raise Exception('Could not find table %s' % name)\n\n    html = _repr_html_table_schema(table.schema)\n    return IPython.core.display.HTML(html)\n\n  elif args['command'] == 'delete':\n    try:\n      bigquery.Table(args['name']).delete()\n    except Exception as e:\n      print('Failed to delete table %s: %s' % (args['name'], e))\n\n  elif args['command'] == 'view':\n    name = args['name']\n    table = _get_table(name)\n    if not table:\n      raise Exception('Could not find table %s' % name)\n    return table\n\n\ndef _extract_cell(args, cell_body):\n  \"\"\"Implements the BigQuery extract magic used to extract query or table data to GCS.\n\n   The supported syntax is:\n     %bq extract <args>\n\n  Args:\n    args: the arguments following '%bigquery extract'.\n  \"\"\"\n\n  env = google.datalab.utils.commands.notebook_environment()\n  config = google.datalab.utils.commands.parse_config(cell_body, env, False) or {}\n  parameters = config.get('parameters')\n  if args['table']:\n    table = google.datalab.bigquery.Query.resolve_parameters(args['table'], parameters)\n    source = _get_table(table)\n    if not source:\n      raise Exception('Could not find table %s' % table)\n\n    csv_delimiter = args['delimiter'] if args['format'] == 'csv' else None\n    path = google.datalab.bigquery.Query.resolve_parameters(args['path'], parameters)\n    job = source.extract(path, format=args['format'], csv_delimiter=csv_delimiter,\n                         csv_header=args['header'], compress=args['compress'])\n  elif args['query'] or args['view']:\n    source_name = args['view'] or args['query']\n    source = google.datalab.utils.commands.get_notebook_item(source_name)\n    if not source:\n      raise Exception('Could not find ' +\n                      ('view ' + args['view'] if args['view'] else 'query ' + args['query']))\n    query = source if args['query'] else bigquery.Query.from_view(source)\n    query_params = get_query_parameters(args, cell_body) if args['query'] else None\n\n    output_options = QueryOutput.file(path=args['path'], format=args['format'],\n                                      csv_delimiter=args['delimiter'],\n                                      csv_header=args['header'], compress=args['compress'],\n                                      use_cache=not args['nocache'])\n    context = google.datalab.utils._utils._construct_context_for_args(args)\n    job = query.execute(output_options, context=context, query_params=query_params)\n  else:\n    raise Exception('A query, table, or view is needed to extract')\n\n  if job.failed:\n    raise Exception('Extract failed: %s' % str(job.fatal_error))\n  elif job.errors:\n    raise Exception('Extract completed with errors: %s' % str(job.errors))\n  return job.result()\n\n\ndef _load_cell(args, cell_body):\n  \"\"\"Implements the BigQuery load magic used to load data from GCS to a table.\n\n   The supported syntax is:\n\n       %bq load <optional args>\n\n  Args:\n    args: the arguments following '%bq load'.\n    cell_body: optional contents of the cell interpreted as YAML or JSON.\n  Returns:\n    A message about whether the load succeeded or failed.\n  \"\"\"\n  env = google.datalab.utils.commands.notebook_environment()\n  config = google.datalab.utils.commands.parse_config(cell_body, env, False) or {}\n\n  parameters = config.get('parameters') or []\n  if parameters:\n    jsonschema.validate({'parameters': parameters}, BigQuerySchema.QUERY_PARAMS_SCHEMA)\n  name = google.datalab.bigquery.Query.resolve_parameters(args['table'], parameters)\n\n  table = _get_table(name)\n  if not table:\n    table = bigquery.Table(name)\n\n  if args['mode'] == 'create':\n    if table.exists():\n      raise Exception('table %s already exists; use \"append\" or \"overwrite\" as mode.' % name)\n    if not cell_body or 'schema' not in cell_body:\n      raise Exception('Table does not exist, and no schema specified in cell; cannot load.')\n\n    schema = config['schema']\n    # schema can be an instance of bigquery.Schema.\n    # For example, user can run \"my_schema = bigquery.Schema.from_data(df)\" in a previous cell and\n    # specify \"schema: $my_schema\" in cell input.\n    if not isinstance(schema, bigquery.Schema):\n      jsonschema.validate({'schema': schema}, BigQuerySchema.TABLE_SCHEMA_SCHEMA)\n      schema = bigquery.Schema(schema)\n    table.create(schema=schema)\n  elif not table.exists():\n    raise Exception('table %s does not exist; use \"create\" as mode.' % name)\n\n  csv_options = bigquery.CSVOptions(delimiter=args['delimiter'], skip_leading_rows=args['skip'],\n                                    allow_jagged_rows=not args['strict'], quote=args['quote'])\n  path = google.datalab.bigquery.Query.resolve_parameters(args['path'], parameters)\n  job = table.load(path, mode=args['mode'], source_format=args['format'], csv_options=csv_options,\n                   ignore_unknown_values=not args['strict'])\n  if job.failed:\n    raise Exception('Load failed: %s' % str(job.fatal_error))\n  elif job.errors:\n    raise Exception('Load completed with errors: %s' % str(job.errors))\n\n\ndef _create_pipeline_subparser(parser):\n  import argparse\n  pipeline_parser = parser.subcommand(\n    'pipeline',\n    formatter_class=argparse.RawTextHelpFormatter,\n    help=\"\"\"\nCreates a GCS/BigQuery ETL pipeline. The cell-body is specified as follows:\n  input:\n    table | path: <BQ table name or GCS path; both if path->table load is also required>\n    schema: <For syntax, refer '%%bq execute'>\n    format: {csv (default) | json}\n    csv: <This section is relevant only when 'format' is 'csv'>\n      delimiter: <The field delimiter to use; default is ','>\n      skip: <Number of rows at the top of a CSV file to skip; default is 0>\n      strict: <{True | False (default)}; whether to accept rows with missing trailing (or optional) columns>\n      quote: <Value used to quote data sections; default is '\"'>\n    mode: <{append (default) | overwrite}; applicable if path->table load>\n  transformation: <optional; when absent, a direct conversion is done from input (path|table) to output (table|path)>\n    query: <name of BQ query defined via \"%%bq query --name ...\">\n  output:\n    table | path: <BQ table name or GCS path; both if table->path extract is required>\n    mode: <{append | overwrite | create (default)}; applicable only when table is specified.\n    format: <{csv (default) | json}>\n    csv: <This section is relevant only when 'format' is 'csv'>\n      delimiter: <the field delimiter to use. Defaults to ','>\n      header: <{True (default) | False}; Whether to include an initial header line>\n      compress: <{True | False (default) }; Whether to compress the data on export>\n  schedule:\n    start: <formatted as '%%Y-%%m-%%dT%%H:%%M:%%S'; default is 'now'>\n    end:  <formatted as '%%Y-%%m-%%dT%%H:%%M:%%S'; default is 'forever'>\n    interval: <{@once (default) | @hourly | @daily | @weekly | @ monthly | @yearly | <cron ex>}>\n    catchup: <{True | False (default)}; when True, backfill is performed for start and end times.\n    retries: Number of attempts to run the pipeline; default is 0\n    retry_delay_seconds: Number of seconds to wait before retrying the task\n  emails: <comma separated list of emails to notify in case of retries, failures, etc.>\n  parameters: <For syntax, refer '%%bq execute'>\n\"\"\")  # noqa\n\n  pipeline_parser.add_argument('-n', '--name', type=str, help='BigQuery pipeline name',\n                               required=True)\n  pipeline_parser.add_argument('-d', '--gcs_dag_bucket', type=str,\n                               help='The Google Cloud Storage bucket for the Airflow dags.')\n  pipeline_parser.add_argument('-f', '--gcs_dag_file_path', type=str,\n                               help='The file path suffix for the Airflow dags.')\n  pipeline_parser.add_argument('-e', '--environment', type=str,\n                               help='The name of the Google Cloud Composer environment.')\n  pipeline_parser.add_argument('-l', '--location', type=str,\n                               help='The location of the Google Cloud Composer environment. '\n                                    'Refer https://cloud.google.com/about/locations/ for further '\n                                    'details.')\n  pipeline_parser.add_argument('-g', '--debug', type=str,\n                               help='Debug output with the airflow spec.')\n  return pipeline_parser\n\n\ndef _pipeline_cell(args, cell_body):\n    \"\"\"Implements the pipeline subcommand in the %%bq magic.\n    Args:\n      args: the arguments following '%%bq pipeline'.\n      cell_body: Cell contents.\n    \"\"\"\n    name = args.get('name')\n    if name is None:\n        raise Exception('Pipeline name was not specified.')\n\n    import google.datalab.utils as utils\n    bq_pipeline_config = utils.commands.parse_config(\n      cell_body, utils.commands.notebook_environment())\n\n    try:\n      airflow_spec = \\\n        google.datalab.contrib.bigquery.commands.get_airflow_spec_from_config(name,\n                                                                              bq_pipeline_config)\n    except AttributeError:\n      return \"Perhaps you're missing: import google.datalab.contrib.bigquery.commands\"\n\n    # If a gcs_dag_bucket is specified, we deploy to it so that the Airflow VM rsyncs it.\n    error_message = ''\n    gcs_dag_bucket = args.get('gcs_dag_bucket')\n    gcs_dag_file_path = args.get('gcs_dag_file_path')\n    if gcs_dag_bucket:\n      try:\n        airflow = google.datalab.contrib.pipeline.airflow.Airflow(gcs_dag_bucket, gcs_dag_file_path)\n        airflow.deploy(name, airflow_spec)\n        error_message += (\"Airflow pipeline successfully deployed! View dashboard for more \"\n                          \"details.\\n\")\n      except AttributeError:\n        return \"Perhaps you're missing: import google.datalab.contrib.pipeline.airflow\"\n\n    location = args.get('location')\n    environment = args.get('environment')\n\n    if location and environment:\n      try:\n        composer = google.datalab.contrib.pipeline.composer.Composer(location, environment)\n        composer.deploy(name, airflow_spec)\n        error_message += (\"Composer pipeline successfully deployed! View dashboard for more \"\n                          \"details.\\n\")\n      except AttributeError:\n        return \"Perhaps you're missing: import google.datalab.contrib.pipeline.composer\"\n\n    if args.get('debug'):\n      error_message += '\\n\\n' + airflow_spec\n\n    return error_message\n\n\ndef _add_command(parser, subparser_fn, handler, cell_required=False, cell_prohibited=False):\n  \"\"\" Create and initialize a bigquery subcommand handler. \"\"\"\n  sub_parser = subparser_fn(parser)\n  sub_parser.set_defaults(func=lambda args, cell: _dispatch_handler(args, cell, sub_parser, handler,\n                          cell_required=cell_required, cell_prohibited=cell_prohibited))\n\n\ndef _create_bigquery_parser():\n  \"\"\" Create the parser for the %bq magics.\n\n  Note that because we use the func default handler dispatch mechanism of argparse,\n  our handlers can take only one argument which is the parsed args. So we must create closures\n  for the handlers that bind the cell contents and thus must recreate this parser for each\n  cell upon execution.\n  \"\"\"\n  parser = google.datalab.utils.commands.CommandParser(prog='%bq', description=\"\"\"\nExecute various BigQuery-related operations. Use \"%bq <command> -h\"\nfor help on a specific command.\n  \"\"\")\n\n  # This is a bit kludgy because we want to handle some line magics and some cell magics\n  # with the bq command.\n\n  # %bq datasets\n  _add_command(parser, _create_dataset_subparser, _dataset_line, cell_prohibited=True)\n\n  # %bq tables\n  _add_command(parser, _create_table_subparser, _table_cell)\n\n  # %%bq query\n  _add_command(parser, _create_query_subparser, _query_cell)\n\n  # %%bq execute\n  _add_command(parser, _create_execute_subparser, _execute_cell)\n\n  # %bq extract\n  _add_command(parser, _create_extract_subparser, _extract_cell)\n\n  # %%bq sample\n  _add_command(parser, _create_sample_subparser, _sample_cell)\n\n  # %%bq dryrun\n  _add_command(parser, _create_dryrun_subparser, _dryrun_cell)\n\n  # %%bq udf\n  _add_command(parser, _create_udf_subparser, _udf_cell, cell_required=True)\n\n  # %%bq datasource\n  _add_command(parser, _create_datasource_subparser, _datasource_cell, cell_required=True)\n\n  # %bq load\n  _add_command(parser, _create_load_subparser, _load_cell)\n\n  # %bq pipeline\n  _add_command(parser, _create_pipeline_subparser, _pipeline_cell)\n\n  return parser\n\n\n_bigquery_parser = _create_bigquery_parser()\n\n\n@IPython.core.magic.register_line_cell_magic\ndef bq(line, cell=None):\n  \"\"\"Implements the bq cell magic for ipython notebooks.\n\n  The supported syntax is:\n\n    %%bq <command> [<args>]\n    <cell>\n\n  or:\n\n    %bq <command> [<args>]\n\n  Use %bq --help for a list of commands, or %bq <command> --help for help\n  on a specific command.\n  \"\"\"\n  return google.datalab.utils.commands.handle_magic_line(line, cell, _bigquery_parser)\n\n\ndef _dispatch_handler(args, cell, parser, handler, cell_required=False, cell_prohibited=False):\n  \"\"\" Makes sure cell magics include cell and line magics don't, before dispatching to handler.\n\n  Args:\n    args: the parsed arguments from the magic line.\n    cell: the contents of the cell, if any.\n    parser: the argument parser for <cmd>; used for error message.\n    handler: the handler to call if the cell present/absent check passes.\n    cell_required: True for cell magics, False for line magics that can't be cell magics.\n    cell_prohibited: True for line magics, False for cell magics that can't be line magics.\n  Returns:\n    The result of calling the handler.\n  Raises:\n    Exception if the invocation is not valid.\n  \"\"\"\n  if cell_prohibited:\n    if cell and len(cell.strip()):\n      parser.print_help()\n      raise Exception('Additional data is not supported with the %s command.' % parser.prog)\n    return handler(args)\n\n  if cell_required and not cell:\n    parser.print_help()\n    raise Exception('The %s command requires additional data' % parser.prog)\n\n  return handler(args, cell)\n\n\ndef _table_viewer(table, rows_per_page=25, fields=None):\n  \"\"\"  Return a table viewer.\n\n    This includes a static rendering of the first page of the table, that gets replaced\n    by the charting code in environments where Javascript is executable and BQ is available.\n\n  Args:\n    table: the table to view.\n    rows_per_page: how many rows to display at one time.\n    fields: an array of field names to display; default is None which uses the full schema.\n  Returns:\n    A string containing the HTML for the table viewer.\n  \"\"\"\n\n  # TODO(gram): rework this to use google.datalab.utils.commands.chart_html\n\n  if not table.exists():\n    raise Exception('Table %s does not exist' % table.full_name)\n\n  if not table.is_listable():\n    return \"Done\"\n\n  _HTML_TEMPLATE = u\"\"\"\n    <div class=\"bqtv\" id=\"{div_id}\">{static_table}</div>\n    <br />{meta_data}<br />\n    <script src=\"/static/components/requirejs/require.js\"></script>\n    <script>\n      require.config({{\n        paths: {{\n          base: '/static/base',\n          d3: '//cdnjs.cloudflare.com/ajax/libs/d3/3.4.13/d3',\n          plotly: 'https://cdn.plot.ly/plotly-1.5.1.min.js?noext',\n          jquery: '//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min'\n        }},\n        map: {{\n          '*': {{\n            datalab: 'nbextensions/gcpdatalab'\n          }}\n        }},\n        shim: {{\n          plotly: {{\n            deps: ['d3', 'jquery'],\n            exports: 'plotly'\n          }}\n        }}\n      }});\n\n      require(['datalab/charting', 'datalab/element!{div_id}', 'base/js/events',\n          'datalab/style!/nbextensions/gcpdatalab/charting.css'],\n        function(charts, dom, events) {{\n          charts.render('gcharts', dom, events, '{chart_style}', [], {data},\n            {{\n              pageSize: {rows_per_page},\n              cssClassNames:  {{\n                tableRow: 'gchart-table-row',\n                headerRow: 'gchart-table-headerrow',\n                oddTableRow: 'gchart-table-oddrow',\n                selectedTableRow: 'gchart-table-selectedrow',\n                hoverTableRow: 'gchart-table-hoverrow',\n                tableCell: 'gchart-table-cell',\n                headerCell: 'gchart-table-headercell',\n                rowNumberCell: 'gchart-table-rownumcell'\n              }}\n            }},\n            {{source_index: {source_index}, fields: '{fields}'}},\n            0,\n            {total_rows});\n        }}\n      );\n    </script>\n  \"\"\"\n\n  if fields is None:\n    fields = google.datalab.utils.commands.get_field_list(fields, table.schema)\n  div_id = google.datalab.utils.commands.Html.next_id()\n  meta_count = ('rows: %d' % table.length) if table.length >= 0 else ''\n  meta_name = table.full_name if table.job is None else ('job: %s' % table.job.id)\n  if table.job:\n    if table.job.cache_hit:\n      meta_cost = 'cached'\n    else:\n      bytes = bigquery._query_stats.QueryStats._size_formatter(table.job.bytes_processed)\n      meta_cost = '%s processed' % bytes\n    meta_time = 'time: %.1fs' % table.job.total_time\n  else:\n    meta_cost = ''\n    meta_time = ''\n\n  data, total_count = google.datalab.utils.commands.get_data(table, fields, first_row=0,\n                                                             count=rows_per_page)\n\n  if total_count < 0:\n    # The table doesn't have a length metadata property but may still be small if we fetched less\n    # rows than we asked for.\n    fetched_count = len(data['rows'])\n    if fetched_count < rows_per_page:\n      total_count = fetched_count\n\n  chart = 'table' if 0 <= total_count <= rows_per_page else 'paged_table'\n  meta_entries = [meta_count, meta_time, meta_cost, meta_name]\n  meta_data = '(%s)' % (', '.join([entry for entry in meta_entries if len(entry)]))\n\n  return _HTML_TEMPLATE.format(div_id=div_id,\n                               static_table=google.datalab.utils.commands.HtmlBuilder\n                               .render_chart_data(data),\n                               meta_data=meta_data,\n                               chart_style=chart,\n                               source_index=google.datalab.utils.commands\n                               .get_data_source_index(table.full_name),\n                               fields=','.join(fields),\n                               total_rows=total_count,\n                               rows_per_page=rows_per_page,\n                               data=json.dumps(data, cls=google.datalab.utils.JSONEncoder))\n\n\ndef _repr_html_query(query):\n  # TODO(nikhilko): Pretty print the SQL\n  return google.datalab.utils.commands.HtmlBuilder.render_text(query.sql, preformatted=True)\n\n\ndef _repr_html_query_results_table(results):\n  return _table_viewer(results)\n\n\ndef _repr_html_table(results):\n  return _table_viewer(results)\n\n\ndef _repr_html_table_schema(schema):\n  _HTML_TEMPLATE = \"\"\"\n    <div class=\"bqsv\" id=\"%s\"></div>\n    <script src=\"/static/components/requirejs/require.js\"></script>\n    <script>\n      require.config({\n        paths: {\n          base: '/static/base',\n        },\n        map: {\n          '*': {\n            datalab: 'nbextensions/gcpdatalab'\n          }\n        },\n      });\n\n      require(['datalab/bigquery', 'datalab/element!%s',\n          'datalab/style!/nbextensions/gcpdatalab/bigquery.css'],\n        function(bq, dom) {\n          bq.renderSchema(dom, %s);\n        }\n      );\n    </script>\n    \"\"\"\n  id = google.datalab.utils.commands.Html.next_id()\n  return _HTML_TEMPLATE % (id, id, json.dumps(schema._bq_schema))\n\n\ndef _register_html_formatters():\n  try:\n    # The full module paths need to be specified in the type name lookup\n    ipy = IPython.get_ipython()\n    html_formatter = ipy.display_formatter.formatters['text/html']\n\n    html_formatter.for_type_by_name('google.datalab.bigquery._query', 'Query', _repr_html_query)\n    html_formatter.for_type_by_name('google.datalab.bigquery._query_results_table',\n                                    'QueryResultsTable', _repr_html_query_results_table)\n    html_formatter.for_type_by_name('google.datalab.bigquery._table', 'Table', _repr_html_table)\n    html_formatter.for_type_by_name('google.datalab.bigquery._schema', 'Schema',\n                                    _repr_html_table_schema)\n  except TypeError:\n    # For when running unit tests\n    pass\n\n\n_register_html_formatters()\n"
  },
  {
    "path": "google/datalab/commands/__init__.py",
    "content": "# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#  http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\"\"\"This module defines the `datalab` magics\"\"\"\n\nfrom __future__ import absolute_import\n\nfrom . import _datalab\n\n__all__ = ['_datalab']\n"
  },
  {
    "path": "google/datalab/commands/_datalab.py",
    "content": "# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#  http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\"\"\"Google Cloud Platform library - datalab cell magic.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\n\ntry:\n  import IPython\n  import IPython.core.display\n  import IPython.core.magic\nexcept ImportError:\n  raise Exception('This module can only be loaded in ipython.')\n\nimport google.datalab.utils.commands\n\n\n@IPython.core.magic.register_line_cell_magic\ndef datalab(line, cell=None):\n  \"\"\"Implements the datalab cell magic for ipython notebooks.\n\n  Args:\n    line: the contents of the datalab line.\n  Returns:\n    The results of executing the cell.\n  \"\"\"\n  parser = google.datalab.utils.commands.CommandParser(\n      prog='%datalab',\n      description=\"\"\"\nExecute operations that apply to multiple Datalab APIs.\n\nUse \"%datalab <command> -h\" for help on a specific command.\n\"\"\")\n\n  config_parser = parser.subcommand(\n      'config', help='List or set API-specific configurations.')\n  config_sub_commands = config_parser.add_subparsers(dest='command')\n\n  # %%datalab config list\n  config_list_parser = config_sub_commands.add_parser(\n      'list', help='List configurations')\n  config_list_parser.set_defaults(func=_config_list_fn)\n\n  # %%datalab config set -n <NAME> -v <VALUE>\n  config_set_parser = config_sub_commands.add_parser(\n      'set', help='Set configurations')\n  config_set_parser.add_argument(\n      '-n', '--name',\n      help='The name of the configuration value', required=True)\n  config_set_parser.add_argument(\n      '-v', '--value', help='The value to set', required=True)\n  config_set_parser.set_defaults(func=_config_set_fn)\n\n  project_parser = parser.subcommand(\n      'project', help='Get or set the default project ID')\n  project_sub_commands = project_parser.add_subparsers(dest='command')\n\n  # %%datalab project get\n  project_get_parser = project_sub_commands.add_parser(\n      'get', help='Get the default project ID')\n  project_get_parser.set_defaults(func=_project_get_fn)\n\n  # %%datalab project set -p <PROJECT_ID>\n  project_set_parser = project_sub_commands.add_parser(\n      'set', help='Set the default project ID')\n  project_set_parser.add_argument(\n      '-p', '--project', help='The default project ID', required=True)\n  project_set_parser.set_defaults(func=_project_set_fn)\n\n  return google.datalab.utils.commands.handle_magic_line(line, cell, parser)\n\n\ndef _config_list_fn(args, cell):\n  ctx = google.datalab.Context.default()\n  return google.datalab.utils.commands.render_dictionary([ctx.config])\n\n\ndef _config_set_fn(args, cell):\n  name = args['name']\n  value = args['value']\n  ctx = google.datalab.Context.default()\n  ctx.config[name] = value\n  return google.datalab.utils.commands.render_dictionary([ctx.config])\n\n\ndef _project_get_fn(args, cell):\n  ctx = google.datalab.Context.default()\n  return google.datalab.utils.commands.render_text(ctx.project_id)\n\n\ndef _project_set_fn(args, cell):\n  project = args['project']\n  ctx = google.datalab.Context.default()\n  ctx.set_project_id(project)\n  return\n"
  },
  {
    "path": "google/datalab/contrib/__init__.py",
    "content": "# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n"
  },
  {
    "path": "google/datalab/contrib/bigquery/__init__.py",
    "content": "# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n"
  },
  {
    "path": "google/datalab/contrib/bigquery/commands/__init__.py",
    "content": "# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\nfrom ._bigquery import get_airflow_spec_from_config  # noqa\n"
  },
  {
    "path": "google/datalab/contrib/bigquery/commands/_bigquery.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Google Cloud Platform library - BigQuery IPython Functionality.\"\"\"\nimport google\nimport google.datalab.utils as utils\nimport google.datalab.contrib.pipeline._pipeline\n\nimport jsonschema\n\n\ndef get_airflow_spec_from_config(name, bq_pipeline_config):\n  pipeline_spec = google.datalab.contrib.bigquery.commands._bigquery._get_pipeline_spec_from_config(\n    bq_pipeline_config)\n  return google.datalab.contrib.pipeline._pipeline.PipelineGenerator.generate_airflow_spec(\n    name, pipeline_spec)\n\n\ndef _get_pipeline_spec_from_config(bq_pipeline_config):\n  pipeline_spec = {}\n\n  schedule_config = bq_pipeline_config.get('schedule')\n  if schedule_config:\n    pipeline_spec['schedule'] = schedule_config\n\n  email_config = bq_pipeline_config.get('emails')\n  if email_config:\n    pipeline_spec['emails'] = email_config\n\n  input_config = bq_pipeline_config.get('input') or bq_pipeline_config.get('load')\n  transformation_config = bq_pipeline_config.get('transformation')\n  output_config = bq_pipeline_config.get('output') or bq_pipeline_config.get('extract')\n\n  parameters_config = bq_pipeline_config.get('parameters')\n  if parameters_config:\n    jsonschema.validate(\n      {'parameters': parameters_config},\n      google.datalab.bigquery.commands._bigquery.BigQuerySchema.QUERY_PARAMS_SCHEMA)\n  pipeline_spec['parameters'] = parameters_config\n\n  pipeline_spec['tasks'] = {}\n\n  load_task_id = None\n  load_task_config = _get_load_parameters(input_config, transformation_config, output_config)\n  if load_task_config:\n    load_task_id = 'bq_pipeline_load_task'\n    pipeline_spec['tasks'][load_task_id] = load_task_config\n\n  execute_task_config = _get_execute_parameters(load_task_id, input_config, transformation_config,\n                                                output_config, parameters_config)\n  execute_task_id = None\n  if execute_task_config:\n    execute_task_id = 'bq_pipeline_execute_task'\n    pipeline_spec['tasks'][execute_task_id] = execute_task_config\n\n  extract_task_config = _get_extract_parameters(execute_task_id, input_config,\n                                                transformation_config, output_config)\n  if extract_task_config:\n    pipeline_spec['tasks']['bq_pipeline_extract_task'] = extract_task_config\n\n  if not load_task_config and not execute_task_config and not extract_task_config:\n    raise Exception('Pipeline has no tasks to execute.')\n\n  return pipeline_spec\n\n\ndef _get_load_parameters(bq_pipeline_input_config, bq_pipeline_transformation_config,\n                         bq_pipeline_output_config):\n    if bq_pipeline_input_config is None:\n      return None\n\n    load_task_config = {'type': 'pydatalab.bq.load'}\n\n    # The path URL of the GCS load file(s).\n    if 'path' not in bq_pipeline_input_config:\n      return None\n\n    # The path URL of the GCS load file(s), and associated parameters\n    load_task_config['path'] = bq_pipeline_input_config.get('path')\n\n    if 'format' in bq_pipeline_input_config:\n      load_task_config['format'] = bq_pipeline_input_config['format']\n\n    if 'csv' in bq_pipeline_input_config:\n      load_task_config['csv_options'] = bq_pipeline_input_config['csv']\n\n    # The destination BQ table name for loading\n    source_of_table = bq_pipeline_input_config\n    if ('table' not in bq_pipeline_input_config and not bq_pipeline_transformation_config and\n        bq_pipeline_output_config and 'table' in bq_pipeline_output_config and\n            'path' not in bq_pipeline_output_config):\n      # If we're here it means that there was no transformation config, but there was an output\n      # config with only a table (and no path). We assume that the user was just trying to do a\n      # gcs->table (or load) step, so we take that as the input table (and emit a load\n      # operator).\n      source_of_table = bq_pipeline_output_config\n\n    # If a table or path are absent, there is no load to be done so we return None\n    if 'table' not in source_of_table:\n      return None\n\n    load_task_config['table'] = source_of_table.get('table')\n\n    if 'schema' in source_of_table:\n      load_task_config['schema'] = source_of_table['schema']\n\n    if 'mode' in source_of_table:\n      load_task_config['mode'] = source_of_table['mode']\n\n    return load_task_config\n\n\ndef _get_execute_parameters(load_task_id, bq_pipeline_input_config,\n                            bq_pipeline_transformation_config, bq_pipeline_output_config,\n                            bq_pipeline_parameters_config):\n    if bq_pipeline_transformation_config is None:\n      return None\n\n    # The name of query for execution; if absent, we return None as we assume that there is\n    # no query to execute\n    if 'query' not in bq_pipeline_transformation_config:\n      return None\n\n    execute_task_config = {\n      'type': 'pydatalab.bq.execute',\n    }\n\n    if load_task_id:\n      execute_task_config['up_stream'] = [load_task_id]\n\n    # If the input config has a path but no table, we assume that the user has specified an\n    # external data_source either explicitly (i.e. via specifying a \"data_source\" key in the input\n    # config, or implicitly (i.e. by letting us assume that this is called \"input\")\n    if (bq_pipeline_input_config and 'path' in bq_pipeline_input_config and\n            'table' not in bq_pipeline_input_config):\n        execute_task_config['data_source'] = bq_pipeline_input_config.get('data_source', 'input')\n\n        if 'path' in bq_pipeline_input_config:\n            # We format the path since this could contain format modifiers\n            execute_task_config['path'] = bq_pipeline_input_config['path']\n\n        if 'schema' in bq_pipeline_input_config:\n            execute_task_config['schema'] = bq_pipeline_input_config['schema']\n\n        if 'max_bad_records' in bq_pipeline_input_config:\n            execute_task_config['max_bad_records'] = bq_pipeline_input_config['max_bad_records']\n\n        if 'format' in bq_pipeline_input_config:\n          execute_task_config['source_format'] = bq_pipeline_input_config.get('format')\n\n        if 'csv' in bq_pipeline_input_config:\n          execute_task_config['csv_options'] = bq_pipeline_input_config.get('csv')\n\n    query = utils.commands.get_notebook_item(bq_pipeline_transformation_config['query'])\n    # If there is a table in the input config, we allow the user to reference table with the name\n    # 'input' in their sql, i.e. via something like 'SELECT col1 FROM input WHERE ...'. To enable\n    # this, we include the input table as a subquery with the query object. If the user's sql does\n    # not reference an 'input' table, BigQuery will just ignore it. Things get interesting if the\n    # user's sql specifies a subquery named 'input' - that should override the subquery that we use.\n    # TODO(rajivpb): Verify this.\n    if (bq_pipeline_input_config and 'table' in bq_pipeline_input_config):\n      table_name = google.datalab.bigquery.Query.resolve_parameters(\n          bq_pipeline_input_config.get('table'), bq_pipeline_parameters_config, macros=True)\n      input_subquery_sql = 'SELECT * FROM `{0}`'.format(table_name)\n      input_subquery = google.datalab.bigquery.Query(input_subquery_sql)\n      # We artificially create an env with just the 'input' key, and the new input_query value to\n      # fool the Query object into using the subquery correctly.\n      query = google.datalab.bigquery.Query(query.sql, env={'input': input_subquery},\n                                            subqueries=['input'])\n\n    execute_task_config['sql'] = query.sql\n    execute_task_config['parameters'] = bq_pipeline_parameters_config\n\n    if bq_pipeline_output_config:\n      if 'table' in bq_pipeline_output_config:\n        execute_task_config['table'] = bq_pipeline_output_config['table']\n\n      if 'mode' in bq_pipeline_output_config:\n          execute_task_config['mode'] = bq_pipeline_output_config['mode']\n\n    return execute_task_config\n\n\ndef _get_extract_parameters(execute_task_id, bq_pipeline_input_config,\n                            bq_pipeline_transformation_config, bq_pipeline_output_config):\n    if bq_pipeline_output_config is None:\n      return None\n\n    extract_task_config = {\n      'type': 'pydatalab.bq.extract',\n    }\n\n    if execute_task_id:\n      extract_task_config['up_stream'] = [execute_task_id]\n      extract_task_config['table'] = \"\"\"{{{{ ti.xcom_pull(task_ids='{0}_id').get('table') }}}}\"\"\"\\\n          .format(execute_task_id)\n\n    # If a path is not specified, there is no extract to be done, so we return None\n    if 'path' not in bq_pipeline_output_config:\n      return None\n\n    extract_task_config['path'] = bq_pipeline_output_config.get('path')\n\n    if 'format' in bq_pipeline_output_config:\n      extract_task_config['format'] = bq_pipeline_output_config.get('format')\n\n    if 'csv' in bq_pipeline_output_config:\n      extract_task_config['csv_options'] = bq_pipeline_output_config.get('csv')\n\n    # If a temporary table from the bigquery results is being used, this will not be present in the\n    # output section.\n    source_of_table = None\n    if 'table' in bq_pipeline_output_config:\n      source_of_table = bq_pipeline_output_config\n    elif (bq_pipeline_input_config and not bq_pipeline_transformation_config and\n          'table' in bq_pipeline_input_config and 'path' not in bq_pipeline_input_config):\n      # If we're here it means that there was no transformation config, but there was an input\n      # config with only a table and no path. We assume that the user was just trying to do a\n      # table->gcs (or extract) step, so we take that as the input table (and emit an extract\n      # operator).\n      source_of_table = bq_pipeline_input_config\n\n    if source_of_table:\n      extract_task_config['table'] = source_of_table['table']\n\n    return extract_task_config\n"
  },
  {
    "path": "google/datalab/contrib/bigquery/operators/__init__.py",
    "content": "# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n"
  },
  {
    "path": "google/datalab/contrib/bigquery/operators/_bq_execute_operator.py",
    "content": "# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nimport google.datalab.bigquery as bq\nfrom airflow.models import BaseOperator\nfrom airflow.utils.decorators import apply_defaults\n\n\nclass ExecuteOperator(BaseOperator):\n\n  template_fields = ('table', 'parameters', 'path', 'sql')\n\n  @apply_defaults\n  def __init__(self, sql, parameters=None, table=None, mode=None, data_source=None, path=None,\n               format=None, csv_options=None, schema=None, max_bad_records=None, *args, **kwargs):\n    super(ExecuteOperator, self).__init__(*args, **kwargs)\n    self.sql = sql\n    self.table = table\n    self.mode = mode\n    self.parameters = parameters\n    self.data_source = data_source\n    self.path = path\n    self.format = format\n    self.csv_options = csv_options\n    self.schema = schema\n    self.max_bad_records = max_bad_records\n\n  def execute(self, context):\n    if self.data_source:\n      kwargs = {}\n      if self.csv_options:\n        csv_kwargs = {}\n        if 'delimiter' in self.csv_options:\n          csv_kwargs['delimiter'] = self.csv_options['delimiter']\n        if 'skip' in self.csv_options:\n          csv_kwargs['skip_leading_rows'] = self.csv_options['skip']\n        if 'strict' in self.csv_options:\n          csv_kwargs['allow_jagged_rows'] = self.csv_options['strict']\n        if 'quote' in self.csv_options:\n          csv_kwargs['quote'] = self.csv_options['quote']\n        kwargs['csv_options'] = bq.CSVOptions(**csv_kwargs)\n\n      if self.format:\n        kwargs['source_format'] = self.format\n\n      if self.max_bad_records:\n        kwargs['max_bad_records'] = self.max_bad_records\n\n      external_data_source = bq.ExternalDataSource(\n        source=self.path, schema=bq.Schema(self.schema), **kwargs)\n      query = bq.Query(sql=self.sql, data_sources={self.data_source: external_data_source})\n    else:\n      query = bq.Query(sql=self.sql)\n\n    # use_cache is False since this is most likely the case in pipeline scenarios\n    # allow_large_results can be True only if table is specified (i.e. when it's not None)\n    kwargs = {}\n    if self.mode is not None:\n      kwargs['mode'] = self.mode\n    output_options = bq.QueryOutput.table(name=self.table, use_cache=False,\n                                          allow_large_results=self.table is not None,\n                                          **kwargs)\n    query_params = bq.Query.get_query_parameters(self.parameters)\n    job = query.execute(output_options=output_options, query_params=query_params)\n\n    # Returning the table-name here makes it available for downstream task instances.\n    return {\n      'table': job.result().full_name\n    }\n"
  },
  {
    "path": "google/datalab/contrib/bigquery/operators/_bq_extract_operator.py",
    "content": "# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nimport google\nfrom airflow.models import BaseOperator\nfrom airflow.utils.decorators import apply_defaults\n\n\nclass ExtractOperator(BaseOperator):\n\n  template_fields = ('table', 'path')\n\n  @apply_defaults\n  def __init__(self, path, table, format='csv', csv_options=None, *args, **kwargs):\n    super(ExtractOperator, self).__init__(*args, **kwargs)\n    self.table = table\n    self.path = path\n    self.format = format\n    self.csv_options = csv_options or {}\n\n  def execute(self, context):\n    source_table = google.datalab.bigquery.Table(self.table, context=None)\n\n    csv_kwargs = {}\n    if 'delimiter' in self.csv_options:\n      csv_kwargs['csv_delimiter'] = self.csv_options['delimiter']\n    if 'header' in self.csv_options:\n      csv_kwargs['csv_header'] = self.csv_options['header']\n    if 'compress' in self.csv_options:\n      csv_kwargs['compress'] = self.csv_options['compress']\n\n    job = source_table.extract(\n      self.path, format='CSV' if self.format == 'csv' else 'NEWLINE_DELIMITED_JSON', **csv_kwargs)\n\n    if job.failed:\n      raise Exception('Extract failed: %s' % str(job.fatal_error))\n    elif job.errors:\n      raise Exception('Extract completed with errors: %s' % str(job.errors))\n    return {\n      'result': job.result()\n    }\n"
  },
  {
    "path": "google/datalab/contrib/bigquery/operators/_bq_load_operator.py",
    "content": "# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nimport google.datalab.bigquery as bq\nfrom airflow.models import BaseOperator\nfrom airflow.utils.decorators import apply_defaults\n\n\nclass LoadOperator(BaseOperator):\n  \"\"\"Implements the BigQuery load magic used to load data from GCS to a table.\n   The supported syntax is:\n       %bq load <optional args>\n  Args:\n    args: the arguments following '%bq load'.\n    cell_body: optional contents of the cell interpreted as YAML or JSON.\n  Returns:\n    A message about whether the load succeeded or failed.\n  \"\"\"\n\n  template_fields = ('table', 'path')\n\n  @apply_defaults\n  def __init__(self, table, path, mode='append', format='csv', schema=None, csv_options=None, *args,\n               **kwargs):\n    super(LoadOperator, self).__init__(*args, **kwargs)\n    self.table = table\n    self.path = path\n    self.mode = mode\n    self.format = format\n    self.csv_options = csv_options or {}\n    self.schema = schema\n\n  # TODO(rajipb): In schema validation, make sure that mode is either 'append' or 'create'\n  def execute(self, context):\n    table = bq.Table(self.table, context=None)\n    if not table.exists():\n      table.create(schema=self.schema)\n\n    kwargs = {}\n    if 'delimiter' in self.csv_options:\n      kwargs['delimiter'] = self.csv_options['delimiter']\n    if 'skip' in self.csv_options:\n      kwargs['skip_leading_rows'] = self.csv_options['skip']\n    if 'strict' in self.csv_options:\n      kwargs['allow_jagged_rows'] = self.csv_options['strict']\n    if 'quote' in self.csv_options:\n      kwargs['quote'] = self.csv_options['quote']\n    csv_options = bq.CSVOptions(**kwargs)\n\n    job = table.load(self.path, mode=self.mode,\n                     source_format=('csv' if self.format == 'csv' else 'NEWLINE_DELIMITED_JSON'),\n                     csv_options=csv_options,\n                     ignore_unknown_values=not self.csv_options.get('strict'))\n\n    if job.failed:\n      raise Exception('Load failed: %s' % str(job.fatal_error))\n    elif job.errors:\n      raise Exception('Load completed with errors: %s' % str(job.errors))\n\n    return {\n      'result': job.result()\n    }\n"
  },
  {
    "path": "google/datalab/contrib/mlworkbench/__init__.py",
    "content": "# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\nfrom __future__ import absolute_import\n\nfrom ._local_predict import get_prediction_results, get_probs_for_labels, local_batch_predict\nfrom ._prediction_explainer import PredictionExplainer\n\n__all__ = ['get_prediction_results', 'get_probs_for_labels', 'local_batch_predict',\n           'PredictionExplainer']\n"
  },
  {
    "path": "google/datalab/contrib/mlworkbench/_archive.py",
    "content": "# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#  http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\"\"\"Google Cloud Platform library - ml cell magic.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\n\nimport os\nimport shutil\nimport tempfile\nimport tensorflow as tf\n\nimport google.datalab.contrib.mlworkbench._shell_process as _shell_process\n\n\ndef extract_archive(archive_path, dest):\n  \"\"\"Extract a local or GCS archive file to a folder.\n\n  Args:\n    archive_path: local or gcs path to a *.tar.gz or *.tar file\n    dest: local folder the archive will be extracted to\n  \"\"\"\n  # Make the dest folder if it does not exist\n  if not os.path.isdir(dest):\n    os.makedirs(dest)\n\n  try:\n    tmpfolder = None\n\n    if (not tf.gfile.Exists(archive_path)) or tf.gfile.IsDirectory(archive_path):\n      raise ValueError('archive path %s is not a file' % archive_path)\n\n    if archive_path.startswith('gs://'):\n      # Copy the file to a local temp folder\n      tmpfolder = tempfile.mkdtemp()\n      cmd_args = ['gsutil', 'cp', archive_path, tmpfolder]\n      _shell_process.run_and_monitor(cmd_args, os.getpid())\n      archive_path = os.path.join(tmpfolder, os.path.name(archive_path))\n\n    if archive_path.lower().endswith('.tar.gz'):\n      flags = '-xzf'\n    elif archive_path.lower().endswith('.tar'):\n      flags = '-xf'\n    else:\n      raise ValueError('Only tar.gz or tar.Z files are supported.')\n\n    cmd_args = ['tar', flags, archive_path, '-C', dest]\n    _shell_process.run_and_monitor(cmd_args, os.getpid())\n  finally:\n    if tmpfolder:\n      shutil.rmtree(tmpfolder)\n"
  },
  {
    "path": "google/datalab/contrib/mlworkbench/_local_predict.py",
    "content": "# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#  http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\"\"\"Google Cloud Platform library - ml cell magic.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\n\n\nimport base64\nimport collections\nimport copy\nimport csv\nfrom io import BytesIO\nimport json\nimport logging\nimport numpy as np\nimport os\nimport pandas as pd\nfrom PIL import Image\nimport six\nimport tensorflow as tf\nfrom tensorflow.python.lib.io import file_io\nfrom tensorflow.python.saved_model import signature_constants\n\nimport google.datalab.ml as ml\n\n\ndef _tf_load_model(sess, model_dir):\n  \"\"\"Load a tf model from model_dir, and return input/output alias maps.\"\"\"\n\n  meta_graph_pb = tf.saved_model.loader.load(\n      sess=sess,\n      tags=[tf.saved_model.tag_constants.SERVING],\n      export_dir=model_dir)\n\n  signature = meta_graph_pb.signature_def[signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY]\n  input_alias_map = {friendly_name: tensor_info_proto.name\n                     for (friendly_name, tensor_info_proto) in signature.inputs.items()}\n  output_alias_map = {friendly_name: tensor_info_proto.name\n                      for (friendly_name, tensor_info_proto) in signature.outputs.items()}\n\n  return input_alias_map, output_alias_map\n\n\ndef _tf_predict(model_dir, input_csvlines):\n  \"\"\"Prediction with a tf savedmodel.\n\n  Args:\n    model_dir: directory that contains a saved model\n    input_csvlines: list of csv strings\n\n  Returns:\n    Dict in the form tensor_name:prediction_list. Note that the value is always\n        a list, even if there was only 1 row in input_csvlines.\n  \"\"\"\n\n  with tf.Graph().as_default(), tf.Session() as sess:\n    input_alias_map, output_alias_map = _tf_load_model(sess, model_dir)\n    csv_tensor_name = list(input_alias_map.values())[0]\n    results = sess.run(fetches=output_alias_map,\n                       feed_dict={csv_tensor_name: input_csvlines})\n\n  # convert any scalar values to a list. This may happen when there is one\n  # example in input_csvlines and the model uses tf.squeeze on the output\n  # tensor.\n  if len(input_csvlines) == 1:\n    for k, v in six.iteritems(results):\n      if not isinstance(v, (list, np.ndarray)):\n        results[k] = [v]\n\n  # Convert bytes to string. In python3 the results may be bytes.\n  for k, v in six.iteritems(results):\n    if any(isinstance(x, bytes) for x in v):\n      results[k] = [x.decode('utf-8') for x in v]\n\n  return results\n\n\ndef _download_images(data, img_cols):\n  \"\"\"Download images given image columns.\"\"\"\n\n  images = collections.defaultdict(list)\n  for d in data:\n    for img_col in img_cols:\n      if d.get(img_col, None):\n        if isinstance(d[img_col], Image.Image):\n          # If it is already an Image, just copy and continue.\n          images[img_col].append(d[img_col])\n        else:\n          # Otherwise it is image url. Load the image.\n          with file_io.FileIO(d[img_col], 'rb') as fi:\n            im = Image.open(fi)\n          images[img_col].append(im)\n      else:\n        images[img_col].append('')\n\n  return images\n\n\ndef _get_predicton_csv_lines(data, headers, images):\n  \"\"\"Create CSV lines from list-of-dict data.\"\"\"\n\n  if images:\n    data = copy.deepcopy(data)\n    for img_col in images:\n      for d, im in zip(data, images[img_col]):\n        if im == '':\n          continue\n\n        im = im.copy()\n        im.thumbnail((299, 299), Image.ANTIALIAS)\n        buf = BytesIO()\n        im.save(buf, \"JPEG\")\n        content = base64.urlsafe_b64encode(buf.getvalue()).decode('ascii')\n        d[img_col] = content\n\n  csv_lines = []\n  for d in data:\n    buf = six.StringIO()\n    writer = csv.DictWriter(buf, fieldnames=headers, lineterminator='')\n    writer.writerow(d)\n    csv_lines.append(buf.getvalue())\n\n  return csv_lines\n\n\ndef _get_display_data_with_images(data, images):\n  \"\"\"Create display data by converting image urls to base64 strings.\"\"\"\n\n  if not images:\n    return data\n\n  display_data = copy.deepcopy(data)\n  for img_col in images:\n    for d, im in zip(display_data, images[img_col]):\n      if im == '':\n        d[img_col + '_image'] = ''\n      else:\n        im = im.copy()\n        im.thumbnail((128, 128), Image.ANTIALIAS)\n        buf = BytesIO()\n        im.save(buf, \"PNG\")\n        content = base64.b64encode(buf.getvalue()).decode('ascii')\n        d[img_col + '_image'] = content\n\n  return display_data\n\n\ndef get_model_schema_and_features(model_dir):\n  \"\"\"Get a local model's schema and features config.\n\n  Args:\n    model_dir: local or GCS path of a model.\n  Returns:\n    A tuple of schema (list) and features config (dict).\n  \"\"\"\n  schema_file = os.path.join(model_dir, 'assets.extra', 'schema.json')\n  schema = json.loads(file_io.read_file_to_string(schema_file))\n  features_file = os.path.join(model_dir, 'assets.extra', 'features.json')\n  features_config = json.loads(file_io.read_file_to_string(features_file))\n  return schema, features_config\n\n\ndef get_prediction_results(model_dir_or_id, data, headers, img_cols=None,\n                           cloud=False, with_source=True, show_image=True):\n  \"\"\" Predict with a specified model.\n\n  It predicts with the model, join source data with prediction results, and formats\n  the results so they can be displayed nicely in Datalab.\n\n  Args:\n    model_dir_or_id: The model directory if cloud is False, or model.version if cloud is True.\n    data: Can be a list of dictionaries, a list of csv lines, or a Pandas DataFrame. If it is not\n        a list of csv lines, data will be converted to csv lines first, using the orders specified\n        by headers and then send to model. For images, it can be image gs urls or in-memory PIL\n        images. Images will be converted to base64 encoded strings before prediction.\n    headers: the column names of data. It specifies the order of the columns when\n        serializing to csv lines for prediction.\n    img_cols: The image url columns. If specified, the img_urls will be converted to\n        base64 encoded image bytes.\n    with_source: Whether return a joined prediction source and prediction results, or prediction\n        results only.\n    show_image: When displaying prediction source, whether to add a column of image bytes for\n        each image url column.\n\n  Returns:\n    A dataframe of joined prediction source and prediction results, or prediction results only.\n  \"\"\"\n\n  if img_cols is None:\n    img_cols = []\n\n  if isinstance(data, pd.DataFrame):\n    data = list(data.T.to_dict().values())\n  elif isinstance(data[0], six.string_types):\n    data = list(csv.DictReader(data, fieldnames=headers))\n\n  images = _download_images(data, img_cols)\n  predict_data = _get_predicton_csv_lines(data, headers, images)\n\n  if cloud:\n    parts = model_dir_or_id.split('.')\n    if len(parts) != 2:\n      raise ValueError('Invalid model name for cloud prediction. Use \"model.version\".')\n\n    predict_results = ml.ModelVersions(parts[0]).predict(parts[1], predict_data)\n  else:\n    tf_logging_level = logging.getLogger(\"tensorflow\").level\n    logging.getLogger(\"tensorflow\").setLevel(logging.WARNING)\n    try:\n      predict_results = _tf_predict(model_dir_or_id, predict_data)\n    finally:\n      logging.getLogger(\"tensorflow\").setLevel(tf_logging_level)\n\n  df_r = pd.DataFrame(predict_results)\n  if not with_source:\n    return df_r\n\n  display_data = data\n  if show_image:\n    display_data = _get_display_data_with_images(data, images)\n\n  df_s = pd.DataFrame(display_data)\n  df = pd.concat([df_r, df_s], axis=1)\n  # Remove duplicate columns. All 'key' columns are duplicate here.\n  df = df.loc[:, ~df.columns.duplicated()]\n\n  return df\n\n\ndef get_probs_for_labels(labels, prediction_results):\n  \"\"\" Given ML Workbench prediction results, get probs of each label for each instance.\n\n  The prediction results are like:\n  [\n    {'predicted': 'daisy', 'probability': 0.8, 'predicted_2': 'rose', 'probability_2': 0.1},\n    {'predicted': 'sunflower', 'probability': 0.9, 'predicted_2': 'daisy', 'probability_2': 0.01},\n    ...\n  ]\n\n  Each instance is ordered by prob. But in some cases probs are needed for fixed\n  order of labels. For example, given labels = ['daisy', 'rose', 'sunflower'], the\n  results of above is expected to be:\n  [\n    [0.8, 0.1, 0.0],\n    [0.01, 0.0, 0.9],\n    ...\n  ]\n  Note that the sum of each instance may not be always 1. If model's top_n is set to\n  none-zero, and is less than number of labels, then prediction results may not contain\n  probs for all labels.\n\n  Args:\n    labels: a list of labels specifying the order of the labels.\n    prediction_results: a pandas DataFrame containing prediction results, usually returned\n        by get_prediction_results() call.\n\n  Returns:\n    A list of list of probs for each class.\n  \"\"\"\n\n  probs = []\n  if 'probability' in prediction_results:\n    # 'probability' exists so top-n is set to none zero, and results are like\n    # \"predicted, predicted_2,...,probability,probability_2,...\n    for i, r in prediction_results.iterrows():\n      probs_one = [0.0] * len(labels)\n      for k, v in six.iteritems(r):\n        if v in labels and k.startswith('predicted'):\n          if k == 'predict':\n            prob_name = 'probability'\n          else:\n            prob_name = 'probability' + k[9:]\n          probs_one[labels.index(v)] = r[prob_name]\n      probs.append(probs_one)\n    return probs\n  else:\n    # 'probability' does not exist, so top-n is set to zero. Results are like\n    # \"predicted, class_name1, class_name2,...\n    for i, r in prediction_results.iterrows():\n      probs_one = [0.0] * len(labels)\n      for k, v in six.iteritems(r):\n        if k in labels:\n          probs_one[labels.index(k)] = v\n      probs.append(probs_one)\n    return probs\n\n\ndef _batch_csv_reader(csv_file, n):\n  with file_io.FileIO(csv_file, 'r') as f:\n    args = [f] * n\n    return six.moves.zip_longest(*args)\n\n\ndef _get_output_schema(session, output_alias_map):\n  schema = []\n  for name in sorted(six.iterkeys(output_alias_map)):\n    tensor_name = output_alias_map[name]\n    dtype = session.graph.get_tensor_by_name(tensor_name).dtype\n    if dtype == tf.int32 or dtype == tf.int64:\n      schema.append({'name': name, 'type': 'INTEGER'})\n    elif dtype == tf.float32 or dtype == tf.float64:\n      schema.append({'name': name, 'type': 'FLOAT'})\n    else:\n      schema.append({'name': name, 'type': 'STRING'})\n\n  return schema\n\n\ndef _format_results(output_format, output_schema, batched_results):\n  # Convert a dict of list to a list of dict.\n  # Note that results from session.run may contain scaler value instead of lists\n  # if batch size is 1.\n  if (isinstance(next(iter(batched_results.values())), list) or\n     isinstance(next(iter(batched_results.values())), np.ndarray)):\n    batched_results = [dict(zip(batched_results, t)) for t in zip(*batched_results.values())]\n  else:\n    batched_results = [batched_results]\n\n  if output_format == 'csv':\n    results = []\n    for r in batched_results:\n      values = [str(r[schema['name']]) for schema in output_schema]\n      results.append(','.join(values))\n  elif output_format == 'json':\n    # Default json encoder cannot handle numpy types.\n    class _JSONEncoder(json.JSONEncoder):\n\n      def default(self, obj):\n        if isinstance(obj, np.integer):\n            return int(obj)\n        elif isinstance(obj, np.floating):\n            return float(obj)\n        elif isinstance(obj, bytes):\n            return obj.decode('utf-8')\n        elif isinstance(obj, np.ndarray):\n            return obj.tolist()\n        else:\n            return super(_JSONEncoder, self).default(obj)\n\n    results = [json.dumps(x, cls=_JSONEncoder) for x in batched_results]\n  else:\n    raise ValueError('Unknown output_format %s' % output_format)\n\n  return results\n\n\ndef local_batch_predict(model_dir, csv_file_pattern, output_dir, output_format, batch_size=100):\n  \"\"\" Batch Predict with a specified model.\n\n  It does batch prediction, saves results to output files and also creates an output\n  schema file. The output file names are input file names prepended by 'predict_results_'.\n\n  Args:\n    model_dir: The model directory containing a SavedModel (usually saved_model.pb).\n    csv_file_pattern: a pattern of csv files as batch prediction source.\n    output_dir: the path of the output directory.\n    output_format: csv or json.\n    batch_size: Larger batch_size improves performance but may\n        cause more memory usage.\n  \"\"\"\n\n  file_io.recursive_create_dir(output_dir)\n  csv_files = file_io.get_matching_files(csv_file_pattern)\n  if len(csv_files) == 0:\n    raise ValueError('No files found given ' + csv_file_pattern)\n\n  with tf.Graph().as_default(), tf.Session() as sess:\n    input_alias_map, output_alias_map = _tf_load_model(sess, model_dir)\n    csv_tensor_name = list(input_alias_map.values())[0]\n    output_schema = _get_output_schema(sess, output_alias_map)\n    for csv_file in csv_files:\n      output_file = os.path.join(\n          output_dir,\n          'predict_results_' +\n          os.path.splitext(os.path.basename(csv_file))[0] + '.' + output_format)\n      with file_io.FileIO(output_file, 'w') as f:\n        prediction_source = _batch_csv_reader(csv_file, batch_size)\n        for batch in prediction_source:\n          batch = [l.rstrip() for l in batch if l]\n          predict_results = sess.run(fetches=output_alias_map, feed_dict={csv_tensor_name: batch})\n          formatted_results = _format_results(output_format, output_schema, predict_results)\n          f.write('\\n'.join(formatted_results) + '\\n')\n\n  file_io.write_string_to_file(os.path.join(output_dir, 'predict_results_schema.json'),\n                               json.dumps(output_schema, indent=2))\n"
  },
  {
    "path": "google/datalab/contrib/mlworkbench/_prediction_explainer.py",
    "content": "# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#  http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\"\"\"Google Cloud Platform library - ML Workbench Model Prediction Explainer.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\n\nimport base64\nimport csv\nimport io\nimport numpy as np\nimport pandas as pd\nfrom PIL import Image\nimport six\nimport tensorflow as tf\nfrom tensorflow.python.lib.io import file_io\n\nfrom . import _local_predict\n\n\nclass PredictionExplainer(object):\n    \"\"\"An explainer that explains text and image predictions based on LIME.\"\"\"\n\n    def __init__(self, model_dir):\n        \"\"\"\n        Args:\n          model_dir: the directory of the model to use for prediction.\n        \"\"\"\n\n        self._model_dir = model_dir\n        schema, features = _local_predict.get_model_schema_and_features(model_dir)\n        self._headers = [x['name'] for x in schema]\n        self._text_columns, self._image_columns = [], []\n        self._categorical_columns, self._numeric_columns = [], []\n        for k, v in six.iteritems(features):\n            if v['transform'] in ['image_to_vec']:\n                self._image_columns.append(v['source_column'])\n            elif v['transform'] in ['bag_of_words', 'tfidf']:\n                self._text_columns.append(v['source_column'])\n            elif v['transform'] in ['one_hot', 'embedding']:\n                self._categorical_columns.append(v['source_column'])\n            elif v['transform'] in ['identity', 'scale']:\n                self._numeric_columns.append(v['source_column'])\n\n    def _make_text_predict_fn(self, labels, instance, column_to_explain):\n        \"\"\"Create a predict_fn that can be used by LIME text explainer. \"\"\"\n\n        def _predict_fn(perturbed_text):\n            predict_input = []\n            for x in perturbed_text:\n                instance_copy = dict(instance)\n                instance_copy[column_to_explain] = x\n                predict_input.append(instance_copy)\n\n            df = _local_predict.get_prediction_results(self._model_dir, predict_input,\n                                                       self._headers, with_source=False)\n            probs = _local_predict.get_probs_for_labels(labels, df)\n            return np.asarray(probs)\n\n        return _predict_fn\n\n    def _make_image_predict_fn(self, labels, instance, column_to_explain):\n        \"\"\"Create a predict_fn that can be used by LIME image explainer. \"\"\"\n\n        def _predict_fn(perturbed_image):\n\n            predict_input = []\n            for x in perturbed_image:\n                instance_copy = dict(instance)\n                instance_copy[column_to_explain] = Image.fromarray(x)\n                predict_input.append(instance_copy)\n\n            df = _local_predict.get_prediction_results(\n                self._model_dir, predict_input, self._headers,\n                img_cols=self._image_columns, with_source=False)\n            probs = _local_predict.get_probs_for_labels(labels, df)\n            return np.asarray(probs)\n\n        return _predict_fn\n\n    def _get_unique_categories(self, df):\n        \"\"\"Get all categories for each categorical columns from training data.\"\"\"\n\n        categories = []\n        for col in self._categorical_columns:\n            categocial = pd.Categorical(df[col])\n            col_categories = list(map(str, categocial.categories))\n            col_categories.append('_UNKNOWN')\n            categories.append(col_categories)\n        return categories\n\n    def _preprocess_data_for_tabular_explain(self, df, categories):\n        \"\"\"Get preprocessed training set in numpy array, and categorical names from raw training data.\n\n        LIME tabular explainer requires a training set to know the distribution of numeric and\n        categorical values. The training set has to be numpy arrays, with all categorical values\n        converted to indices. It also requires list of names for each category.\n        \"\"\"\n\n        df = df.copy()\n\n        # Remove non tabular columns (text, image).\n        for col in list(df.columns):\n            if col not in (self._categorical_columns + self._numeric_columns):\n                del df[col]\n\n        # Convert categorical values into indices.\n        for col_name, col_categories in zip(self._categorical_columns, categories):\n            df[col_name] = df[col_name].apply(\n                lambda x: col_categories.index(str(x)) if str(x) in col_categories\n                else len(col_categories) - 1)\n\n        # Make sure numeric values are really numeric\n        for numeric_col in self._numeric_columns:\n            df[numeric_col] = df[numeric_col].apply(lambda x: float(x))\n\n        return df.as_matrix(self._categorical_columns + self._numeric_columns)\n\n    def _make_tabular_predict_fn(self, labels, instance, categories):\n        \"\"\"Create a predict_fn that can be used by LIME tabular explainer. \"\"\"\n\n        def _predict_fn(np_instance):\n\n            df = pd.DataFrame(\n                np_instance,\n                columns=(self._categorical_columns + self._numeric_columns))\n\n            # Convert categorical indices back to categories.\n            for col_name, col_categories in zip(self._categorical_columns, categories):\n                df[col_name] = df[col_name].apply(lambda x: col_categories[int(x)])\n\n            # Add columns that do not exist in the perturbed data,\n            # such as key, text, and image data.\n            for col_name in self._headers:\n                if col_name not in (self._categorical_columns + self._numeric_columns):\n                    df[col_name] = instance[col_name]\n\n            r = _local_predict.get_prediction_results(\n                self._model_dir, df, self._headers, with_source=False)\n            probs = _local_predict.get_probs_for_labels(labels, r)\n            probs = np.asarray(probs)\n            return probs\n\n        return _predict_fn\n\n    def explain_tabular(self, trainset, labels, instance, num_features=5, kernel_width=3):\n        \"\"\"Explain categorical and numeric features for a prediction.\n\n        It analyze the prediction by LIME, and returns a report of the most impactful tabular\n        features contributing to certain labels.\n\n        Args:\n          trainset: a DataFrame representing the training features that LIME can use to decide\n              value distributions.\n          labels: a list of labels to explain.\n          instance: the prediction instance. It needs to conform to model's input. Can be a csv\n              line string, or a dict.\n          num_features: maximum number of features to show.\n          kernel_width: Passed to LIME LimeTabularExplainer directly.\n\n        Returns:\n          A LIME's lime.explanation.Explanation.\n        \"\"\"\n        from lime.lime_tabular import LimeTabularExplainer\n\n        if isinstance(instance, six.string_types):\n            instance = next(csv.DictReader([instance], fieldnames=self._headers))\n\n        categories = self._get_unique_categories(trainset)\n        np_trainset = self._preprocess_data_for_tabular_explain(trainset, categories)\n        predict_fn = self._make_tabular_predict_fn(labels, instance, categories)\n        prediction_df = pd.DataFrame([instance])\n        prediction_instance = self._preprocess_data_for_tabular_explain(prediction_df, categories)\n\n        explainer = LimeTabularExplainer(\n            np_trainset,\n            feature_names=(self._categorical_columns + self._numeric_columns),\n            class_names=labels,\n            categorical_features=range(len(categories)),\n            categorical_names={i: v for i, v in enumerate(categories)},\n            kernel_width=kernel_width)\n\n        exp = explainer.explain_instance(\n            prediction_instance[0],\n            predict_fn,\n            num_features=num_features,\n            labels=range(len(labels)))\n        return exp\n\n    def explain_text(self, labels, instance, column_name=None, num_features=10, num_samples=5000):\n        \"\"\"Explain a text field of a prediction.\n\n        It analyze the prediction by LIME, and returns a report of which words are most impactful\n        in contributing to certain labels.\n\n        Args:\n          labels: a list of labels to explain.\n          instance: the prediction instance. It needs to conform to model's input. Can be a csv\n              line string, or a dict.\n          column_name: which text column to explain. Can be None if there is only one text column\n              in the model input.\n          num_features: maximum number of words (features) to analyze. Passed to\n              LIME LimeTextExplainer directly.\n          num_samples: size of the neighborhood to learn the linear model. Passed to\n              LIME LimeTextExplainer directly.\n\n        Returns:\n          A LIME's lime.explanation.Explanation.\n\n        Throws:\n          ValueError if the given text column is not found in model input or column_name is None\n              but there are multiple text columns in model input.\n        \"\"\"\n\n        from lime.lime_text import LimeTextExplainer\n\n        if len(self._text_columns) > 1 and not column_name:\n            raise ValueError('There are multiple text columns in the input of the model. ' +\n                             'Please specify \"column_name\".')\n        elif column_name and column_name not in self._text_columns:\n            raise ValueError('Specified column_name \"%s\" not found in the model input.'\n                             % column_name)\n\n        text_column_name = column_name if column_name else self._text_columns[0]\n        if isinstance(instance, six.string_types):\n            instance = next(csv.DictReader([instance], fieldnames=self._headers))\n\n        predict_fn = self._make_text_predict_fn(labels, instance, text_column_name)\n        explainer = LimeTextExplainer(class_names=labels)\n        exp = explainer.explain_instance(\n            instance[text_column_name], predict_fn, labels=range(len(labels)),\n            num_features=num_features, num_samples=num_samples)\n        return exp\n\n    def explain_image(self, labels, instance, column_name=None, num_features=100000,\n                      num_samples=300, batch_size=200, hide_color=0):\n        \"\"\"Explain an image of a prediction.\n\n        It analyze the prediction by LIME, and returns a report of which words are most impactful\n        in contributing to certain labels.\n\n        Args:\n          labels: a list of labels to explain.\n          instance: the prediction instance. It needs to conform to model's input. Can be a csv\n              line string, or a dict.\n          column_name: which image column to explain. Can be None if there is only one image column\n              in the model input.\n          num_features: maximum number of areas (features) to analyze. Passed to\n              LIME LimeImageExplainer directly.\n          num_samples: size of the neighborhood to learn the linear model. Passed to\n              LIME LimeImageExplainer directly.\n          batch_size: size of batches passed to predict_fn. Passed to\n              LIME LimeImageExplainer directly.\n          hide_color: the color used to perturb images. Passed to\n              LIME LimeImageExplainer directly.\n\n        Returns:\n          A LIME's lime.explanation.Explanation.\n\n        Throws:\n          ValueError if the given image column is not found in model input or column_name is None\n              but there are multiple image columns in model input.\n        \"\"\"\n\n        from lime.lime_image import LimeImageExplainer\n\n        if len(self._image_columns) > 1 and not column_name:\n            raise ValueError('There are multiple image columns in the input of the model. ' +\n                             'Please specify \"column_name\".')\n        elif column_name and column_name not in self._image_columns:\n            raise ValueError('Specified column_name \"%s\" not found in the model input.'\n                             % column_name)\n\n        image_column_name = column_name if column_name else self._image_columns[0]\n        if isinstance(instance, six.string_types):\n            instance = next(csv.DictReader([instance], fieldnames=self._headers))\n\n        predict_fn = self._make_image_predict_fn(labels, instance, image_column_name)\n        explainer = LimeImageExplainer()\n        with file_io.FileIO(instance[image_column_name], 'rb') as fi:\n            im = Image.open(fi)\n        im.thumbnail((299, 299), Image.ANTIALIAS)\n        rgb_im = np.asarray(im.convert('RGB'))\n        exp = explainer.explain_instance(\n            rgb_im, predict_fn, labels=range(len(labels)), top_labels=None,\n            hide_color=hide_color, num_features=num_features,\n            num_samples=num_samples, batch_size=batch_size)\n        return exp\n\n    def _image_gradients(self, input_csvlines, label, image_column_name):\n        \"\"\"Compute gradients from prob of label to image. Used by integrated gradients (probe).\"\"\"\n\n        with tf.Graph().as_default() as g, tf.Session() as sess:\n            logging_level = tf.logging.get_verbosity()\n            try:\n                tf.logging.set_verbosity(tf.logging.ERROR)\n                meta_graph_pb = tf.saved_model.loader.load(\n                    sess=sess,\n                    tags=[tf.saved_model.tag_constants.SERVING],\n                    export_dir=self._model_dir)\n            finally:\n                tf.logging.set_verbosity(logging_level)\n\n            signature = meta_graph_pb.signature_def['serving_default']\n            input_alias_map = {name: tensor_info_proto.name\n                               for (name, tensor_info_proto) in signature.inputs.items()}\n            output_alias_map = {name: tensor_info_proto.name\n                                for (name, tensor_info_proto) in signature.outputs.items()}\n\n            csv_tensor_name = list(input_alias_map.values())[0]\n\n            # The image tensor is already built into ML Workbench graph.\n            float_image = g.get_tensor_by_name(\"import/gradients_%s:0\" % image_column_name)\n            if label not in output_alias_map:\n                raise ValueError('The label \"%s\" does not exist in output map.' % label)\n\n            prob = g.get_tensor_by_name(output_alias_map[label])\n            grads = tf.gradients(prob, float_image)[0]\n            grads_values = sess.run(fetches=grads, feed_dict={csv_tensor_name: input_csvlines})\n\n        return grads_values\n\n    def probe_image(self, labels, instance, column_name=None, num_scaled_images=50,\n                    top_percent=10):\n        \"\"\" Get pixel importance of the image.\n\n        It performs pixel sensitivity analysis by showing only the most important pixels to a\n        certain label in the image. It uses integrated gradients to measure the\n        importance of each pixel.\n\n        Args:\n            labels: labels to compute gradients from.\n            instance: the prediction instance. It needs to conform to model's input. Can be a csv\n              line string, or a dict.\n            img_column_name: the name of the image column to probe. If there is only one image\n                column it can be None.\n            num_scaled_images: Number of scaled images to get grads from. For example, if 10,\n                the image will be scaled by 0.1, 0.2, ..., 0,9, 1.0 and it will produce\n                10 images for grads computation.\n            top_percent: The percentile of pixels to show only. for example, if 10,\n                only top 10% impactful pixels will be shown and rest of the pixels will be black.\n\n        Returns:\n            A tuple. First is the resized original image (299x299x3). Second is a list of\n                the visualization with same size that highlights the most important pixels, one\n                per each label.\n        \"\"\"\n\n        if len(self._image_columns) > 1 and not column_name:\n            raise ValueError('There are multiple image columns in the input of the model. ' +\n                             'Please specify \"column_name\".')\n        elif column_name and column_name not in self._image_columns:\n            raise ValueError('Specified column_name \"%s\" not found in the model input.' %\n                             column_name)\n\n        image_column_name = column_name if column_name else self._image_columns[0]\n        if isinstance(instance, six.string_types):\n            instance = next(csv.DictReader([instance], fieldnames=self._headers))\n\n        image_path = instance[image_column_name]\n\n        with file_io.FileIO(image_path, 'rb') as fi:\n            im = Image.open(fi)\n\n        resized_image = im.resize((299, 299))\n\n        # Produce a list of scaled images, create instances (csv lines) from these images.\n        step = 1. / num_scaled_images\n        scales = np.arange(0.0, 1.0, step) + step\n        csv_lines = []\n        for s in scales:\n            pixels = (np.asarray(resized_image) * s).astype('uint8')\n            scaled_image = Image.fromarray(pixels)\n            buf = io.BytesIO()\n            scaled_image.save(buf, \"JPEG\")\n            encoded_image = base64.urlsafe_b64encode(buf.getvalue()).decode('ascii')\n            instance_copy = dict(instance)\n            instance_copy[image_column_name] = encoded_image\n\n            buf = six.StringIO()\n            writer = csv.DictWriter(buf, fieldnames=self._headers, lineterminator='')\n            writer.writerow(instance_copy)\n            csv_lines.append(buf.getvalue())\n\n        integrated_gradients_images = []\n        for label in labels:\n          # Send to tf model to get gradients.\n          grads = self._image_gradients(csv_lines, label, image_column_name)\n          integrated_grads = resized_image * np.average(grads, axis=0)\n\n          # Gray scale the grads by removing color dimension.\n          # abs() is for getting the most impactful pixels regardless positive or negative.\n          grayed = np.average(abs(integrated_grads), axis=2)\n          grayed = np.transpose([grayed, grayed, grayed], axes=[1, 2, 0])\n\n          # Only show the most impactful pixels.\n          p = np.percentile(grayed, 100 - top_percent)\n          viz_window = np.where(grayed > p, 1, 0)\n          vis = resized_image * viz_window\n          im_vis = Image.fromarray(np.uint8(vis))\n          integrated_gradients_images.append(im_vis)\n\n        return resized_image, integrated_gradients_images\n"
  },
  {
    "path": "google/datalab/contrib/mlworkbench/_shell_process.py",
    "content": "# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#  http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\"\"\"Google Cloud Platform library - ml cell magic.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\n\n\nimport os\nimport psutil\nimport six\nimport subprocess\nimport sys\n\n\ndef _wait_and_kill(pid_to_wait, pids_to_kill):\n  \"\"\" Wait for a process to finish if it exists, and then kill a list of processes.\n\n  Args:\n    pid_to_wait: the process to wait for.\n    pids_to_kill: a list of processes to kill after the process of pid_to_wait finishes.\n  \"\"\"\n  if psutil.pid_exists(pid_to_wait):\n    psutil.Process(pid=pid_to_wait).wait()\n\n  for pid_to_kill in pids_to_kill:\n    if psutil.pid_exists(pid_to_kill):\n      p = psutil.Process(pid=pid_to_kill)\n      p.kill()\n\n\ndef run_and_monitor(args, pid_to_wait, std_out_filter_fn=None, cwd=None):\n  \"\"\" Start a process, and have it depend on another specified process.\n\n  Args:\n    args: the args of the process to start and monitor.\n    pid_to_wait: the process to wait on. If the process ends, also kill the started process.\n    std_out_filter_fn: a filter function which takes a string content from the stdout of the\n        started process, and returns True if the string should be redirected to console stdout.\n    cwd: the current working directory for the process to start.\n  \"\"\"\n\n  monitor_process = None\n  try:\n    p = subprocess.Popen(args,\n                         cwd=cwd,\n                         env=os.environ,\n                         stdout=subprocess.PIPE,\n                         stderr=subprocess.STDOUT)\n\n    pids_to_kill = [p.pid]\n    script = ('import %s;%s._wait_and_kill(%s, %s)' %\n              (__name__, __name__, str(pid_to_wait), str(pids_to_kill)))\n    monitor_process = subprocess.Popen(['python', '-c', script], env=os.environ)\n    while p.poll() is None:\n      line = p.stdout.readline()\n\n      if not six.PY2:\n        line = line.decode()\n\n      if std_out_filter_fn is None or std_out_filter_fn(line):\n        sys.stdout.write(line)\n        # Cannot do sys.stdout.flush(). It appears that too many flush() calls will hang browser.\n  finally:\n    if monitor_process:\n      monitor_process.kill()\n"
  },
  {
    "path": "google/datalab/contrib/mlworkbench/commands/__init__.py",
    "content": "# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\nfrom __future__ import absolute_import\n\nfrom . import _ml\n\n__all__ = ['_ml']\n"
  },
  {
    "path": "google/datalab/contrib/mlworkbench/commands/_ml.py",
    "content": "# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#  http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\"\"\"Google Cloud Platform library - ml cell magic.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\n\ntry:\n  import IPython\n  import IPython.core.display\n  import IPython.core.magic\nexcept ImportError:\n  raise Exception('This module can only be loaded in ipython.')\n\nimport argparse\nimport collections\nimport json\nimport os\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport shutil\nimport six\nfrom skimage.segmentation import mark_boundaries\nimport subprocess\nimport tempfile\nimport textwrap\nimport tensorflow as tf\nfrom tensorflow.python.lib.io import file_io\nimport urllib\n\nimport google.datalab\nfrom google.datalab import Context\nimport google.datalab.ml as datalab_ml\nimport google.datalab.utils.commands\nimport google.datalab.contrib.mlworkbench._local_predict as _local_predict\nimport google.datalab.contrib.mlworkbench._shell_process as _shell_process\nimport google.datalab.contrib.mlworkbench._archive as _archive\nimport google.datalab.contrib.mlworkbench._prediction_explainer as _prediction_explainer\n\n\nDEFAULT_PACKAGE_PATH = '/datalab/lib/pydatalab/solutionbox/ml_workbench/tensorflow/'\n\n\n@IPython.core.magic.register_line_cell_magic\ndef ml(line, cell=None):\n  \"\"\"Implements the datalab cell magic for MLWorkbench operations.\n\n  Args:\n    line: the contents of the ml command line.\n  Returns:\n    The results of executing the cell.\n  \"\"\"\n  parser = google.datalab.utils.commands.CommandParser(\n      prog='%ml',\n      description=textwrap.dedent(\"\"\"\\\n          Execute MLWorkbench operations\n\n          Use \"%ml <command> -h\" for help on a specific command.\n      \"\"\"))\n\n  dataset_parser = parser.subcommand(\n      'dataset',\n      formatter_class=argparse.RawTextHelpFormatter,\n      help='Create or explore datasets.')\n  dataset_sub_commands = dataset_parser.add_subparsers(dest='command')\n  dataset_create_parser = dataset_sub_commands.add_parser(\n      'create', help='Create datasets', formatter_class=argparse.RawTextHelpFormatter,\n      epilog=textwrap.dedent(\"\"\"\\\n          Example usage:\n\n          %%ml dataset\n          name: mydata\n          format: csv\n          train: path/to/train.csv\n          eval: path/to/eval.csv\n          schema:\n            - name: news_label\n              type: STRING\n            - name: text\n              type: STRING\"\"\"))\n\n  dataset_create_parser.add_argument('--name', required=True,\n                                     help='the name of the dataset to define. ')\n  dataset_create_parser.add_argument('--format', required=True,\n                                     choices=['csv', 'bigquery', 'transformed'],\n                                     help='The format of the data.')\n  dataset_create_parser.add_argument('--train', required=True,\n                                     help='The path of the training file pattern if format ' +\n                                          'is csv or transformed, or table name if format ' +\n                                          'is bigquery.')\n  dataset_create_parser.add_argument('--eval', required=True,\n                                     help='The path of the eval file pattern if format ' +\n                                          'is csv or transformed, or table name if format ' +\n                                          'is bigquery.')\n  dataset_create_parser.add_cell_argument('schema',\n                                          help='yaml representation of CSV schema, or path to ' +\n                                          'schema file. Only needed if format is csv.')\n  dataset_create_parser.set_defaults(func=_dataset_create)\n\n  dataset_explore_parser = dataset_sub_commands.add_parser(\n      'explore', help='Explore training data.')\n  dataset_explore_parser.add_argument('--name', required=True,\n                                      help='The name of the dataset to explore.')\n\n  dataset_explore_parser.add_argument('--overview', action='store_true', default=False,\n                                      help='Plot overview of sampled data. Set \"sample_size\" ' +\n                                           'to change the default sample size.')\n  dataset_explore_parser.add_argument('--facets', action='store_true', default=False,\n                                      help='Plot facets view of sampled data. Set ' +\n                                           '\"sample_size\" to change the default sample size.')\n  dataset_explore_parser.add_argument('--sample_size', type=int, default=1000,\n                                      help='sample size for overview or facets view. Only ' +\n                                           'used if either --overview or --facets is set.')\n  dataset_explore_parser.set_defaults(func=_dataset_explore)\n\n  analyze_parser = parser.subcommand(\n      'analyze',\n      formatter_class=argparse.RawTextHelpFormatter,\n      help='Analyze training data and generate stats, such as min/max/mean '\n           'for numeric values, vocabulary for text columns.',\n      epilog=textwrap.dedent(\"\"\"\\\n          Example usage:\n\n          %%ml analyze [--cloud]\n          output: path/to/dir\n          data: $mydataset\n          features:\n            serialId:\n              transform: key\n            num1:\n              transform: scale\n              value: 1\n            num2:\n              transform: identity\n            text1:\n              transform: bag_of_words\n\n          Also supports in-notebook variables, such as:\n          %%ml analyze --output path/to/dir\n          training_data: $my_csv_dataset\n          features: $features_def\"\"\"))\n\n  analyze_parser.add_argument('--output', required=True,\n                              help='path of output directory.')\n  analyze_parser.add_argument('--cloud', action='store_true', default=False,\n                              help='whether to run analysis in cloud or local.')\n  analyze_parser.add_argument('--package', required=False,\n                              help='A local or GCS tarball path to use as the source. '\n                                   'If not set, the default source package will be used.')\n  analyze_parser.add_cell_argument(\n    'data',\n    required=True,\n    help=\"\"\"Training data. A dataset defined by \"%%ml dataset\".\"\"\")\n  analyze_parser.add_cell_argument(\n      'features',\n      required=True,\n      help=textwrap.dedent(\"\"\"\\\n          features config indicating how to transform data into features. The\n          list of supported transforms:\n              \"transform: identity\"\n                   does nothing (for numerical columns).\n              \"transform: scale\n               value: x\"\n                   scale a numerical column to [-a, a]. If value is missing, x\n                   defaults to 1.\n              \"transform: one_hot\"\n                   treats the string column as categorical and makes one-hot\n                   encoding of it.\n              \"transform: embedding\n               embedding_dim: d\"\n                   treats the string column as categorical and makes embeddings of\n                   it with specified dimension size.\n              \"transform: bag_of_words\"\n                   treats the string column as text and make bag of words\n                   transform of it.\n              \"transform: tfidf\"\n                   treats the string column as text and make TFIDF transform of it.\n              \"transform: image_to_vec\n               checkpoint: gs://b/o\"\n                   from image gs url to embeddings. \"checkpoint\" is a inception v3\n                   checkpoint. If absent, a default checkpoint is used.\n              \"transform: target\"\n                   denotes the column is the target. If the schema type of this\n                   column is string, a one_hot encoding is automatically applied.\n                   If numerical, an identity transform is automatically applied.\n              \"transform: key\"\n                   column contains metadata-like information and will be output\n                   as-is in prediction.\"\"\"))\n  analyze_parser.set_defaults(func=_analyze)\n\n  transform_parser = parser.subcommand(\n      'transform',\n      formatter_class=argparse.RawTextHelpFormatter,\n      help='Transform the data into tf.example which is more efficient in training.',\n      epilog=textwrap.dedent(\"\"\"\\\n          Example usage:\n\n          %%ml transform [--cloud] [--shuffle]\n          analysis: path/to/analysis_output_folder\n          output: path/to/dir\n          batch_size: 100\n          data: $mydataset\n          cloud:\n            num_workers: 3\n            worker_machine_type: n1-standard-1\n            project_id: my_project_id\"\"\"))\n  transform_parser.add_argument('--analysis', required=True,\n                                help='path of analysis output directory.')\n  transform_parser.add_argument('--output', required=True,\n                                help='path of output directory.')\n  transform_parser.add_argument('--cloud', action='store_true', default=False,\n                                help='whether to run transform in cloud or local.')\n  transform_parser.add_argument('--shuffle', action='store_true', default=False,\n                                help='whether to shuffle the training data in output.')\n  transform_parser.add_argument('--batch_size', type=int, default=100,\n                                help='number of instances in a batch to process once. '\n                                     'Larger batch is more efficient but may consume more memory.')\n  transform_parser.add_argument('--package', required=False,\n                                help='A local or GCS tarball path to use as the source. '\n                                     'If not set, the default source package will be used.')\n  transform_parser.add_cell_argument(\n      'data',\n      required=True,\n      help=\"\"\"Training data. A dataset defined by \"%%ml dataset\".\"\"\")\n  transform_parser.add_cell_argument(\n      'cloud_config',\n      help=textwrap.dedent(\"\"\"\\\n          A dictionary of cloud config. All of them are optional.\n              num_workers: Dataflow number of workers. If not set, DataFlow\n                  service will determine the number.\n              worker_machine_type: a machine name from\n                  https://cloud.google.com/compute/docs/machine-types\n                  If not given, the service uses the default machine type.\n              project_id: id of the project to use for DataFlow service. If not set,\n                  Datalab's default project (set by %%datalab project set) is used.\n              job_name: Unique name for a Dataflow job to use. If not set, a\n                  random name will be used.\"\"\"))\n  transform_parser.set_defaults(func=_transform)\n\n  train_parser = parser.subcommand(\n      'train',\n      formatter_class=argparse.RawTextHelpFormatter,\n      help='Train a model.',\n      epilog=textwrap.dedent(\"\"\"\\\n          Example usage:\n\n          %%ml train [--cloud]\n          analysis: path/to/analysis_output\n          output: path/to/dir\n          data: $mydataset\n          model_args:\n            model: linear_regression\n          cloud_config:\n            region: us-central1\"\"\"))\n  train_parser.add_argument('--analysis', required=True,\n                            help='path of analysis output directory.')\n  train_parser.add_argument('--output', required=True,\n                            help='path of trained model directory.')\n  train_parser.add_argument('--cloud', action='store_true', default=False,\n                            help='whether to run training in cloud or local.')\n  train_parser.add_argument('--notb', action='store_true', default=False,\n                            help='If set, tensorboard is not automatically started.')\n  train_parser.add_argument('--package', required=False,\n                            help='A local or GCS tarball path to use as the source. '\n                                 'If not set, the default source package will be used.')\n  train_parser.add_cell_argument(\n      'data',\n      required=True,\n      help=\"\"\"Training data. A dataset defined by \"%%ml dataset\".\"\"\")\n\n  package_model_help = subprocess.Popen(\n      ['python', '-m', 'trainer.task', '--datalab-help'],\n      cwd=DEFAULT_PACKAGE_PATH,\n      stdout=subprocess.PIPE).communicate()[0]\n  package_model_help = ('model_args: a dictionary of model specific args, including:\\n\\n' +\n                        package_model_help.decode())\n  train_parser.add_cell_argument('model_args', help=package_model_help)\n\n  train_parser.add_cell_argument(\n      'cloud_config',\n      help=textwrap.dedent(\"\"\"\\\n          A dictionary of cloud training config, including:\n              job_id: the name of the job. If not provided, a default job name is created.\n              region: see {url}\n              runtime_version: see \"region\". Must be a string like '1.2'.\n              scale_tier: see \"region\".\"\"\".format(\n          url='https://cloud.google.com/sdk/gcloud/reference/ml-engine/jobs/submit/training')))\n  train_parser.set_defaults(func=_train)\n\n  predict_parser = parser.subcommand(\n      'predict',\n      formatter_class=argparse.RawTextHelpFormatter,\n      help='Predict with local or deployed models. (Good for small datasets).',\n      epilog=textwrap.dedent(\"\"\"\\\n          Example usage:\n\n          %%ml predict\n          headers: key,num\n          model: path/to/model\n          data:\n            - key1,value1\n            - key2,value2\n\n          Or, in another cell, define a list of dict:\n\n          my_data = [{'key': 1, 'num': 1.2}, {'key': 2, 'num': 2.8}]\n\n          Then:\n\n          %%ml predict\n          headers: key,num\n          model: path/to/model\n          data: $my_data\"\"\"))\n  predict_parser.add_argument('--model', required=True,\n                              help='The model path.')\n  predict_parser.add_argument('--no_show_image', action='store_true', default=False,\n                              help='If not set, add a column of images in output.')\n  predict_parser.add_cell_argument(\n      'data',\n      required=True,\n      help=textwrap.dedent(\"\"\"\\\n          Prediction data can be\n              1) CSV lines in the input cell in yaml format or\n              2) a local variable which is one of\n                a) list of dict\n                b) list of strings of csv lines\n                c) a Pandas DataFrame\"\"\"))\n  predict_parser.set_defaults(func=_predict)\n\n  batch_predict_parser = parser.subcommand(\n      'batch_predict',\n      formatter_class=argparse.RawTextHelpFormatter,\n      help='Batch prediction with local or deployed models. (Good for large datasets)',\n      epilog=textwrap.dedent(\"\"\"\\\n\n      Example usage:\n\n      %%ml batch_predict [--cloud]\n      model: path/to/model\n      output: path/to/output\n      format: csv\n      data:\n        csv: path/to/file_pattern\"\"\"))\n  batch_predict_parser.add_argument('--model', required=True,\n                                    help='The model path if not --cloud, or the id in '\n                                         'the form of model.version if --cloud.')\n  batch_predict_parser.add_argument('--output', required=True,\n                                    help='The path of output directory with prediction results. '\n                                         'If --cloud, it has to be GCS path.')\n  batch_predict_parser.add_argument('--format',\n                                    help='csv or json. For cloud run, '\n                                         'the only supported format is json.')\n  batch_predict_parser.add_argument('--batch_size', type=int, default=100,\n                                    help='number of instances in a batch to process once. '\n                                         'Larger batch is more efficient but may consume '\n                                         'more memory. Only used in local run.')\n  batch_predict_parser.add_argument('--cloud', action='store_true', default=False,\n                                    help='whether to run prediction in cloud or local.')\n  batch_predict_parser.add_cell_argument(\n      'data',\n      required=True,\n      help='Data to predict with. Only csv is supported.')\n  batch_predict_parser.add_cell_argument(\n      'cloud_config',\n      help=textwrap.dedent(\"\"\"\\\n          A dictionary of cloud batch prediction config.\n              job_id: the name of the job. If not provided, a default job name is created.\n              region: see {url}\n              max_worker_count: see reference in \"region\".\"\"\".format(\n                  url='https://cloud.google.com/sdk/gcloud/reference/ml-engine/jobs/submit/prediction')))  # noqa\n  batch_predict_parser.set_defaults(func=_batch_predict)\n\n  explain_parser = parser.subcommand(\n      'explain',\n      formatter_class=argparse.RawTextHelpFormatter,\n      help='Explain a prediction with LIME tool.')\n  explain_parser.add_argument('--type', default='all', choices=['text', 'image', 'tabular', 'all'],\n                              help='the type of column to explain.')\n  explain_parser.add_argument('--algorithm', choices=['lime', 'ig'], default='lime',\n                              help='\"lime\" is the open sourced project for prediction explainer.' +\n                                   '\"ig\" means integrated gradients and currently only applies ' +\n                                   'to image.')\n  explain_parser.add_argument('--model', required=True,\n                              help='path of the model directory used for prediction.')\n  explain_parser.add_argument('--labels', required=True,\n                              help='comma separated labels to explain.')\n  explain_parser.add_argument('--column_name',\n                              help='the name of the column to explain. Optional if text type ' +\n                                   'and there is only one text column, or image type and ' +\n                                   'there is only one image column.')\n  explain_parser.add_cell_argument('data', required=True,\n                                   help='Prediction Data. Can be a csv line, or a dict.')\n  explain_parser.add_cell_argument('training_data',\n                                   help='A csv or bigquery dataset defined by %%ml dataset. ' +\n                                        'Used by tabular explainer only to determine the ' +\n                                        'distribution of numeric and categorical values. ' +\n                                        'Suggest using original training dataset.')\n\n  # options specific for lime\n  explain_parser.add_argument('--num_features', type=int,\n                              help='number of features to analyze. In text, it is number of ' +\n                                   'words. In image, it is number of areas. For lime only.')\n  explain_parser.add_argument('--num_samples', type=int,\n                              help='size of the neighborhood to learn the linear model. ' +\n                                   'For lime only.')\n  explain_parser.add_argument('--hide_color', type=int, default=0,\n                              help='the color to use for perturbed area. If -1, average of ' +\n                                   'each channel is used for each channel. For image only.')\n  explain_parser.add_argument('--include_negative', action='store_true', default=False,\n                              help='whether to show only positive areas. For lime image only.')\n  explain_parser.add_argument('--overview', action='store_true', default=False,\n                              help='whether to show overview instead of details view.' +\n                                   'For lime text and tabular only.')\n  explain_parser.add_argument('--batch_size', type=int, default=100,\n                              help='size of batches passed to prediction. For lime only.')\n\n  # options specific for integrated gradients\n  explain_parser.add_argument('--num_gradients', type=int, default=50,\n                              help='the number of scaled images to get gradients from. Larger ' +\n                                   'number usually produces better results but slower.')\n  explain_parser.add_argument('--percent_show', type=int, default=10,\n                              help='the percentage of top impactful pixels to show.')\n\n  explain_parser.set_defaults(func=_explain)\n\n  tensorboard_parser = parser.subcommand(\n      'tensorboard',\n      formatter_class=argparse.RawTextHelpFormatter,\n      help='Start/stop/list TensorBoard instances.')\n  tensorboard_sub_commands = tensorboard_parser.add_subparsers(dest='command')\n\n  tensorboard_start_parser = tensorboard_sub_commands.add_parser(\n      'start', help='Start a tensorboard instance.')\n  tensorboard_start_parser.add_argument('--logdir', required=True,\n                                        help='The local or GCS logdir path.')\n  tensorboard_start_parser.set_defaults(func=_tensorboard_start)\n\n  tensorboard_stop_parser = tensorboard_sub_commands.add_parser(\n      'stop', help='Stop a tensorboard instance.')\n  tensorboard_stop_parser.add_argument('--pid', required=True, type=int,\n                                       help='The pid of the tensorboard instance.')\n  tensorboard_stop_parser.set_defaults(func=_tensorboard_stop)\n\n  tensorboard_list_parser = tensorboard_sub_commands.add_parser(\n      'list', help='List tensorboard instances.')\n  tensorboard_list_parser.set_defaults(func=_tensorboard_list)\n\n  evaluate_parser = parser.subcommand(\n      'evaluate',\n      formatter_class=argparse.RawTextHelpFormatter,\n      help='Analyze model evaluation results, such as confusion matrix, ROC, RMSE.')\n  evaluate_sub_commands = evaluate_parser.add_subparsers(dest='command')\n\n  def _add_data_params_for_evaluate(parser):\n    parser.add_argument('--csv', help='csv file path patterns.')\n    parser.add_argument('--headers',\n                        help='csv file headers. Required if csv is specified and ' +\n                             'predict_results_schema.json does not exist in the same directory.')\n    parser.add_argument('--bigquery',\n                        help='can be bigquery table, query as a string, or ' +\n                             'a pre-defined query (%%bq query --name).')\n\n  evaluate_cm_parser = evaluate_sub_commands.add_parser(\n      'confusion_matrix', help='Get confusion matrix from evaluation results.')\n  _add_data_params_for_evaluate(evaluate_cm_parser)\n  evaluate_cm_parser.add_argument('--plot', action='store_true', default=False,\n                                  help='Whether to plot confusion matrix as graph.')\n  evaluate_cm_parser.add_argument('--size', type=int, default=10,\n                                  help='The size of the confusion matrix.')\n  evaluate_cm_parser.set_defaults(func=_evaluate_cm)\n\n  evaluate_accuracy_parser = evaluate_sub_commands.add_parser(\n      'accuracy', help='Get accuracy results from classification evaluation results.')\n  _add_data_params_for_evaluate(evaluate_accuracy_parser)\n  evaluate_accuracy_parser.set_defaults(func=_evaluate_accuracy)\n\n  evaluate_pr_parser = evaluate_sub_commands.add_parser(\n      'precision_recall', help='Get precision recall metrics from evaluation results.')\n  _add_data_params_for_evaluate(evaluate_pr_parser)\n  evaluate_pr_parser.add_argument('--plot', action='store_true', default=False,\n                                  help='Whether to plot precision recall as graph.')\n  evaluate_pr_parser.add_argument('--num_thresholds', type=int, default=20,\n                                  help='Number of thresholds which determines how many ' +\n                                       'points in the graph.')\n  evaluate_pr_parser.add_argument('--target_class', required=True,\n                                  help='The target class to determine correctness of ' +\n                                       'a prediction.')\n  evaluate_pr_parser.add_argument('--probability_column',\n                                  help='The name of the column holding the probability ' +\n                                       'value of the target class. If absent, the value ' +\n                                       'of target class is used.')\n  evaluate_pr_parser.set_defaults(func=_evaluate_pr)\n\n  evaluate_roc_parser = evaluate_sub_commands.add_parser(\n      'roc', help='Get ROC metrics from evaluation results.')\n  _add_data_params_for_evaluate(evaluate_roc_parser)\n  evaluate_roc_parser.add_argument('--plot', action='store_true', default=False,\n                                   help='Whether to plot ROC as graph.')\n  evaluate_roc_parser.add_argument('--num_thresholds', type=int, default=20,\n                                   help='Number of thresholds which determines how many ' +\n                                        'points in the graph.')\n  evaluate_roc_parser.add_argument('--target_class', required=True,\n                                   help='The target class to determine correctness of ' +\n                                        'a prediction.')\n  evaluate_roc_parser.add_argument('--probability_column',\n                                   help='The name of the column holding the probability ' +\n                                        'value of the target class. If absent, the value ' +\n                                        'of target class is used.')\n  evaluate_roc_parser.set_defaults(func=_evaluate_roc)\n\n  evaluate_regression_parser = evaluate_sub_commands.add_parser(\n      'regression', help='Get regression metrics from evaluation results.')\n  _add_data_params_for_evaluate(evaluate_regression_parser)\n  evaluate_regression_parser.set_defaults(func=_evaluate_regression)\n\n  model_parser = parser.subcommand(\n      'model',\n      help='Models and versions management such as deployment, deletion, listing.')\n  model_sub_commands = model_parser.add_subparsers(dest='command')\n  model_list_parser = model_sub_commands.add_parser(\n      'list', help='List models and versions.')\n  model_list_parser.add_argument('--name',\n                                 help='If absent, list all models of specified or current ' +\n                                      'project. If provided, list all versions of the ' +\n                                      'model.')\n  model_list_parser.add_argument('--project',\n                                 help='The project to list model(s) or version(s). If absent, ' +\n                                      'use Datalab\\'s default project.')\n  model_list_parser.set_defaults(func=_model_list)\n\n  model_delete_parser = model_sub_commands.add_parser(\n      'delete', help='Delete models or versions.')\n  model_delete_parser.add_argument('--name', required=True,\n                                   help='If no \".\" in the name, try deleting the specified ' +\n                                        'model. If \"model.version\" is provided, try deleting ' +\n                                        'the specified version.')\n  model_delete_parser.add_argument('--project',\n                                   help='The project to delete model or version. If absent, ' +\n                                        'use Datalab\\'s default project.')\n  model_delete_parser.set_defaults(func=_model_delete)\n\n  model_deploy_parser = model_sub_commands.add_parser(\n      'deploy', help='Deploy a model version.')\n  model_deploy_parser.add_argument('--name', required=True,\n                                   help='Must be model.version to indicate the model ' +\n                                        'and version name to deploy.')\n  model_deploy_parser.add_argument('--path', required=True,\n                                   help='The GCS path of the model to be deployed.')\n  model_deploy_parser.add_argument('--runtime_version',\n                                   help='The TensorFlow version to use for this model. ' +\n                                        'For example, \"1.2.1\". If absent, the current ' +\n                                        'TensorFlow version installed in Datalab will be used.')\n  model_deploy_parser.add_argument('--project',\n                                   help='The project to deploy a model version. If absent, ' +\n                                        'use Datalab\\'s default project.')\n  model_deploy_parser.set_defaults(func=_model_deploy)\n\n  return google.datalab.utils.commands.handle_magic_line(line, cell, parser)\n\n\nDataSet = collections.namedtuple('DataSet', ['train', 'eval'])\n\n\ndef _abs_path(path):\n  \"\"\"Convert a non-GCS path to its absolute path.\n\n  path can contain special filepath characters like '..', '*' and '.'.\n\n  Example: If the current folder is /content/datalab/folder1 and path is\n  '../folder2/files*', then this function returns the string\n  '/content/datalab/folder2/files*'.\n\n  This function is needed if using _shell_process.run_and_monitor() as that\n  function runs a command in a different folder.\n\n  Args:\n    path: string.\n  \"\"\"\n  if path.startswith('gs://'):\n    return path\n  return os.path.abspath(path)\n\n\ndef _create_json_file(tmpdir, data, filename):\n  json_file = os.path.join(tmpdir, filename)\n  with file_io.FileIO(json_file, 'w') as f:\n    json.dump(data, f)\n  return json_file\n\n\ndef _show_job_link(job):\n  log_url_query_strings = {\n    'project': Context.default().project_id,\n    'resource': 'ml.googleapis.com/job_id/' + job.info['jobId']\n  }\n  log_url = 'https://console.developers.google.com/logs/viewer?' + \\\n      urllib.urlencode(log_url_query_strings)\n  html = 'Job \"%s\" submitted.' % job.info['jobId']\n  html += '<p>Click <a href=\"%s\" target=\"_blank\">here</a> to view cloud log. <br/>' % log_url\n  IPython.display.display_html(html, raw=True)\n\n\ndef get_dataset_from_arg(dataset_arg):\n  if isinstance(dataset_arg, DataSet):\n    return dataset_arg\n\n  if isinstance(dataset_arg, six.string_types):\n    return google.datalab.utils.commands.notebook_environment()[dataset_arg]\n\n  raise ValueError('Invalid dataset reference \"%s\". ' % dataset_arg +\n                   'Expect a dataset defined with \"%%ml dataset create\".')\n\n\ndef _analyze(args, cell):\n  # For now, always run python2. If needed we can run python3 when the current kernel\n  # is py3. Since now our transform cannot work on py3 anyway, I would rather run\n  # everything with python2.\n  cmd_args = ['python', 'analyze.py', '--output', _abs_path(args['output'])]\n  if args['cloud']:\n    cmd_args.append('--cloud')\n\n  training_data = get_dataset_from_arg(args['data'])\n\n  if args['cloud']:\n    tmpdir = os.path.join(args['output'], 'tmp')\n  else:\n    tmpdir = tempfile.mkdtemp()\n\n  try:\n    if isinstance(training_data.train, datalab_ml.CsvDataSet):\n      csv_data = training_data.train\n      schema_file = _create_json_file(tmpdir, csv_data.schema, 'schema.json')\n      for file_name in csv_data.input_files:\n        cmd_args.append('--csv=' + _abs_path(file_name))\n      cmd_args.extend(['--schema', schema_file])\n    elif isinstance(training_data.train, datalab_ml.BigQueryDataSet):\n      bq_data = training_data.train\n      cmd_args.extend(['--bigquery', bq_data.table])\n    else:\n      raise ValueError('Unexpected training data type. Only csv or bigquery are supported.')\n\n    features = args['features']\n    features_file = _create_json_file(tmpdir, features, 'features.json')\n    cmd_args.extend(['--features', features_file])\n\n    if args['package']:\n      code_path = os.path.join(tmpdir, 'package')\n      _archive.extract_archive(args['package'], code_path)\n    else:\n      code_path = DEFAULT_PACKAGE_PATH\n\n    _shell_process.run_and_monitor(cmd_args, os.getpid(), cwd=code_path)\n  finally:\n    file_io.delete_recursively(tmpdir)\n\n\ndef _transform(args, cell):\n  if args['cloud_config'] and not args['cloud']:\n    raise ValueError('\"cloud_config\" is provided but no \"--cloud\". '\n                     'Do you want local run or cloud run?')\n\n  cmd_args = ['python', 'transform.py',\n              '--output', _abs_path(args['output']),\n              '--analysis', _abs_path(args['analysis'])]\n  if args['cloud']:\n    cmd_args.append('--cloud')\n    cmd_args.append('--async')\n  if args['shuffle']:\n    cmd_args.append('--shuffle')\n  if args['batch_size']:\n    cmd_args.extend(['--batch-size', str(args['batch_size'])])\n\n  cloud_config = args['cloud_config']\n  if cloud_config:\n    google.datalab.utils.commands.validate_config(\n        cloud_config,\n        required_keys=[],\n        optional_keys=['num_workers', 'worker_machine_type', 'project_id', 'job_name'])\n    if 'num_workers' in cloud_config:\n      cmd_args.extend(['--num-workers', str(cloud_config['num_workers'])])\n    if 'worker_machine_type' in cloud_config:\n      cmd_args.extend(['--worker-machine-type', cloud_config['worker_machine_type']])\n    if 'project_id' in cloud_config:\n      cmd_args.extend(['--project-id', cloud_config['project_id']])\n    if 'job_name' in cloud_config:\n      cmd_args.extend(['--job-name', cloud_config['job_name']])\n\n  if args['cloud'] and (not cloud_config or 'project_id' not in cloud_config):\n    cmd_args.extend(['--project-id', google.datalab.Context.default().project_id])\n\n  training_data = get_dataset_from_arg(args['data'])\n  data_names = ('train', 'eval')\n  for name in data_names:\n    cmd_args_copy = list(cmd_args)\n    if isinstance(getattr(training_data, name), datalab_ml.CsvDataSet):\n      for file_name in getattr(training_data, name).input_files:\n        cmd_args_copy.append('--csv=' + _abs_path(file_name))\n    elif isinstance(getattr(training_data, name), datalab_ml.BigQueryDataSet):\n      cmd_args_copy.extend(['--bigquery', getattr(training_data, name).table])\n    else:\n      raise ValueError('Unexpected training data type. Only csv or bigquery are supported.')\n\n    cmd_args_copy.extend(['--prefix', name])\n    try:\n      tmpdir = None\n      if args['package']:\n        tmpdir = tempfile.mkdtemp()\n        code_path = os.path.join(tmpdir, 'package')\n        _archive.extract_archive(args['package'], code_path)\n      else:\n        code_path = DEFAULT_PACKAGE_PATH\n      _shell_process.run_and_monitor(cmd_args_copy, os.getpid(), cwd=code_path)\n    finally:\n      if tmpdir:\n        shutil.rmtree(tmpdir)\n\n\ndef _train(args, cell):\n  if args['cloud_config'] and not args['cloud']:\n    raise ValueError('\"cloud_config\" is provided but no \"--cloud\". '\n                     'Do you want local run or cloud run?')\n\n  job_args = ['--job-dir', _abs_path(args['output']),\n              '--analysis', _abs_path(args['analysis'])]\n\n  training_data = get_dataset_from_arg(args['data'])\n  data_names = ('train', 'eval')\n  for name in data_names:\n    if (isinstance(getattr(training_data, name), datalab_ml.CsvDataSet) or\n       isinstance(getattr(training_data, name), datalab_ml.TransformedDataSet)):\n      for file_name in getattr(training_data, name).input_files:\n        job_args.append('--%s=%s' % (name, _abs_path(file_name)))\n    else:\n      raise ValueError('Unexpected training data type. ' +\n                       'Only csv and transformed type are supported.')\n\n  if isinstance(training_data.train, datalab_ml.CsvDataSet):\n    job_args.append('--transform')\n\n  # TODO(brandondutra) document that any model_args that are file paths must\n  # be given as an absolute path\n  if args['model_args']:\n    for k, v in six.iteritems(args['model_args']):\n      job_args.extend(['--' + k, str(v)])\n\n  try:\n    tmpdir = None\n    if args['package']:\n      tmpdir = tempfile.mkdtemp()\n      code_path = os.path.join(tmpdir, 'package')\n      _archive.extract_archive(args['package'], code_path)\n    else:\n      code_path = DEFAULT_PACKAGE_PATH\n\n    if args['cloud']:\n      cloud_config = args['cloud_config']\n      if not args['output'].startswith('gs://'):\n        raise ValueError('Cloud training requires a GCS (starting with \"gs://\") output.')\n\n      staging_tarball = os.path.join(args['output'], 'staging', 'trainer.tar.gz')\n      datalab_ml.package_and_copy(code_path,\n                                  os.path.join(code_path, 'setup.py'),\n                                  staging_tarball)\n      job_request = {\n          'package_uris': [staging_tarball],\n          'python_module': 'trainer.task',\n          'job_dir': args['output'],\n          'args': job_args,\n      }\n      job_request.update(cloud_config)\n      job_id = cloud_config.get('job_id', None)\n      job = datalab_ml.Job.submit_training(job_request, job_id)\n      _show_job_link(job)\n      if not args['notb']:\n        datalab_ml.TensorBoard.start(args['output'])\n    else:\n      cmd_args = ['python', '-m', 'trainer.task'] + job_args\n      if not args['notb']:\n        datalab_ml.TensorBoard.start(args['output'])\n      _shell_process.run_and_monitor(cmd_args, os.getpid(), cwd=code_path)\n  finally:\n    if tmpdir:\n      shutil.rmtree(tmpdir)\n\n\ndef _predict(args, cell):\n  schema, features = _local_predict.get_model_schema_and_features(args['model'])\n  headers = [x['name'] for x in schema]\n  img_cols = []\n  for k, v in six.iteritems(features):\n    if v['transform'] in ['image_to_vec']:\n      img_cols.append(v['source_column'])\n\n  data = args['data']\n  df = _local_predict.get_prediction_results(\n      args['model'], data, headers, img_cols=img_cols, cloud=False,\n      show_image=not args['no_show_image'])\n\n  def _show_img(img_bytes):\n    return '<img src=\"data:image/png;base64,' + img_bytes + '\" />'\n\n  def _truncate_text(text):\n    return (text[:37] + '...') if isinstance(text, six.string_types) and len(text) > 40 else text\n\n  # Truncate text explicitly here because we will set display.max_colwidth to -1.\n  # This applies to images to but images will be overriden with \"_show_img()\" later.\n  formatters = {x: _truncate_text for x in df.columns if df[x].dtype == np.object}\n  if not args['no_show_image'] and img_cols:\n    formatters.update({x + '_image': _show_img for x in img_cols})\n\n  # Set display.max_colwidth to -1 so we can display images.\n  old_width = pd.get_option('display.max_colwidth')\n  pd.set_option('display.max_colwidth', -1)\n  try:\n    IPython.display.display(IPython.display.HTML(\n        df.to_html(formatters=formatters, escape=False, index=False)))\n  finally:\n    pd.set_option('display.max_colwidth', old_width)\n\n\ndef _batch_predict(args, cell):\n  if args['cloud_config'] and not args['cloud']:\n    raise ValueError('\"cloud_config\" is provided but no \"--cloud\". '\n                     'Do you want local run or cloud run?')\n\n  if args['cloud']:\n    job_request = {\n      'data_format': 'TEXT',\n      'input_paths': file_io.get_matching_files(args['data']['csv']),\n      'output_path': args['output'],\n    }\n    if args['model'].startswith('gs://'):\n      job_request['uri'] = args['model']\n    else:\n      parts = args['model'].split('.')\n      if len(parts) != 2:\n        raise ValueError('Invalid model name for cloud prediction. Use \"model.version\".')\n\n      version_name = ('projects/%s/models/%s/versions/%s' %\n                      (Context.default().project_id, parts[0], parts[1]))\n      job_request['version_name'] = version_name\n\n    cloud_config = args['cloud_config'] or {}\n    job_id = cloud_config.pop('job_id', None)\n    job_request.update(cloud_config)\n    job = datalab_ml.Job.submit_batch_prediction(job_request, job_id)\n    _show_job_link(job)\n  else:\n    print('local prediction...')\n    _local_predict.local_batch_predict(args['model'],\n                                       args['data']['csv'],\n                                       args['output'],\n                                       args['format'],\n                                       args['batch_size'])\n    print('done.')\n\n\n# Helper classes for explainer. Each for is for a combination\n# of algorithm (LIME, IG) and type (text, image, tabular)\n# ===========================================================\nclass _TextLimeExplainerInstance(object):\n\n  def __init__(self, explainer, labels, args):\n    num_features = args['num_features'] if args['num_features'] else 10\n    num_samples = args['num_samples'] if args['num_samples'] else 5000\n    self._exp = explainer.explain_text(\n        labels, args['data'], column_name=args['column_name'],\n        num_features=num_features, num_samples=num_samples)\n    self._col_name = args['column_name'] if args['column_name'] else explainer._text_columns[0]\n    self._show_overview = args['overview']\n\n  def visualize(self, label_index):\n    if self._show_overview:\n      IPython.display.display(\n          IPython.display.HTML('<br/>  Text Column \"<b>%s</b>\"<br/>' % self._col_name))\n      self._exp.show_in_notebook(labels=[label_index])\n    else:\n      fig = self._exp.as_pyplot_figure(label=label_index)\n      # Clear original title set by lime.\n      plt.title('')\n      fig.suptitle('Text Column \"%s\"' % self._col_name, fontsize=16)\n      plt.close(fig)\n      IPython.display.display(fig)\n\n\nclass _ImageLimeExplainerInstance(object):\n\n  def __init__(self, explainer, labels, args):\n    num_samples = args['num_samples'] if args['num_samples'] else 300\n    hide_color = None if args['hide_color'] == -1 else args['hide_color']\n    self._exp = explainer.explain_image(\n        labels, args['data'], column_name=args['column_name'],\n        num_samples=num_samples, batch_size=args['batch_size'], hide_color=hide_color)\n    self._labels = labels\n    self._positive_only = not args['include_negative']\n    self._num_features = args['num_features'] if args['num_features'] else 3\n    self._col_name = args['column_name'] if args['column_name'] else explainer._image_columns[0]\n\n  def visualize(self, label_index):\n    image, mask = self._exp.get_image_and_mask(\n        label_index,\n        positive_only=self._positive_only,\n        num_features=self._num_features, hide_rest=False)\n    fig = plt.figure()\n    fig.suptitle('Image Column \"%s\"' % self._col_name, fontsize=16)\n    plt.grid(False)\n    plt.imshow(mark_boundaries(image, mask))\n    plt.close(fig)\n    IPython.display.display(fig)\n\n\nclass _ImageIgExplainerInstance(object):\n\n  def __init__(self, explainer, labels, args):\n    self._raw_image, self._analysis_images = explainer.probe_image(\n        labels, args['data'], column_name=args['column_name'],\n        num_scaled_images=args['num_gradients'], top_percent=args['percent_show'])\n    self._labels = labels\n    self._col_name = args['column_name'] if args['column_name'] else explainer._image_columns[0]\n\n  def visualize(self, label_index):\n    # Show both resized raw image and analyzed image.\n    fig = plt.figure()\n    fig.suptitle('Image Column \"%s\"' % self._col_name, fontsize=16)\n    plt.grid(False)\n    plt.imshow(self._analysis_images[label_index])\n    plt.close(fig)\n    IPython.display.display(fig)\n\n\nclass _TabularLimeExplainerInstance(object):\n\n  def __init__(self, explainer, labels, args):\n    if not args['training_data']:\n      raise ValueError('tabular explanation requires training_data to determine ' +\n                       'values distribution.')\n\n    training_data = get_dataset_from_arg(args['training_data'])\n    if (not isinstance(training_data.train, datalab_ml.CsvDataSet) and\n       not isinstance(training_data.train, datalab_ml.BigQueryDataSet)):\n      raise ValueError('Require csv or bigquery dataset.')\n\n    sample_size = min(training_data.train.size, 10000)\n    training_df = training_data.train.sample(sample_size)\n    num_features = args['num_features'] if args['num_features'] else 5\n    self._exp = explainer.explain_tabular(training_df, labels, args['data'],\n                                          num_features=num_features)\n    self._show_overview = args['overview']\n\n  def visualize(self, label_index):\n    if self._show_overview:\n      IPython.display.display(\n          IPython.display.HTML('<br/>All Categorical and Numeric Columns<br/>'))\n      self._exp.show_in_notebook(labels=[label_index])\n    else:\n      fig = self._exp.as_pyplot_figure(label=label_index)\n      # Clear original title set by lime.\n      plt.title('')\n      fig.suptitle('  All Categorical and Numeric Columns', fontsize=16)\n      plt.close(fig)\n      IPython.display.display(fig)\n\n# End of Explainer Helper Classes\n# ===================================================\n\n\ndef _explain(args, cell):\n\n  explainer = _prediction_explainer.PredictionExplainer(args['model'])\n  labels = args['labels'].split(',')\n  instances = []\n  if args['type'] == 'all':\n    if explainer._numeric_columns or explainer._categorical_columns:\n      instances.append(_TabularLimeExplainerInstance(explainer, labels, args))\n    for col_name in explainer._text_columns:\n      args['column_name'] = col_name\n      instances.append(_TextLimeExplainerInstance(explainer, labels, args))\n    for col_name in explainer._image_columns:\n      args['column_name'] = col_name\n      if args['algorithm'] == 'lime':\n        instances.append(_ImageLimeExplainerInstance(explainer, labels, args))\n      elif args['algorithm'] == 'ig':\n        instances.append(_ImageIgExplainerInstance(explainer, labels, args))\n\n  elif args['type'] == 'text':\n    instances.append(_TextLimeExplainerInstance(explainer, labels, args))\n  elif args['type'] == 'image' and args['algorithm'] == 'lime':\n    instances.append(_ImageLimeExplainerInstance(explainer, labels, args))\n  elif args['type'] == 'image' and args['algorithm'] == 'ig':\n    instances.append(_ImageIgExplainerInstance(explainer, labels, args))\n  elif args['type'] == 'tabular':\n    instances.append(_TabularLimeExplainerInstance(explainer, labels, args))\n\n  for i, label in enumerate(labels):\n    IPython.display.display(\n        IPython.display.HTML('<br/>Explaining features for label <b>\"%s\"</b><br/>' % label))\n    for instance in instances:\n      instance.visualize(i)\n\n\ndef _tensorboard_start(args, cell):\n  datalab_ml.TensorBoard.start(args['logdir'])\n\n\ndef _tensorboard_stop(args, cell):\n  datalab_ml.TensorBoard.stop(args['pid'])\n\n\ndef _tensorboard_list(args, cell):\n  return datalab_ml.TensorBoard.list()\n\n\ndef _get_evaluation_csv_schema(csv_file):\n  # ML Workbench produces predict_results_schema.json in local batch prediction.\n  schema_file = os.path.join(os.path.dirname(csv_file), 'predict_results_schema.json')\n  if not file_io.file_exists(schema_file):\n    raise ValueError('csv data requires headers.')\n  return schema_file\n\n\ndef _evaluate_cm(args, cell):\n  if args['csv']:\n    if args['headers']:\n      headers = args['headers'].split(',')\n      cm = datalab_ml.ConfusionMatrix.from_csv(args['csv'], headers=headers)\n    else:\n      schema_file = _get_evaluation_csv_schema(args['csv'])\n      cm = datalab_ml.ConfusionMatrix.from_csv(args['csv'], schema_file=schema_file)\n  elif args['bigquery']:\n    cm = datalab_ml.ConfusionMatrix.from_bigquery(args['bigquery'])\n  else:\n    raise ValueError('Either csv or bigquery is needed.')\n\n  if args['plot']:\n    return cm.plot(figsize=(args['size'], args['size']), rotation=90)\n  else:\n    return cm.to_dataframe()\n\n\ndef _create_metrics(args):\n  if args['csv']:\n    if args['headers']:\n      headers = args['headers'].split(',')\n      metrics = datalab_ml.Metrics.from_csv(args['csv'], headers=headers)\n    else:\n      schema_file = _get_evaluation_csv_schema(args['csv'])\n      metrics = datalab_ml.Metrics.from_csv(args['csv'], schema_file=schema_file)\n  elif args['bigquery']:\n    metrics = datalab_ml.Metrics.from_bigquery(args['bigquery'])\n  else:\n    raise ValueError('Either csv or bigquery is needed.')\n\n  return metrics\n\n\ndef _evaluate_accuracy(args, cell):\n  metrics = _create_metrics(args)\n  return metrics.accuracy()\n\n\ndef _evaluate_regression(args, cell):\n  metrics = _create_metrics(args)\n  metrics_dict = []\n  metrics_dict.append({\n      'metric': 'Root Mean Square Error',\n      'value': metrics.rmse()\n  })\n  metrics_dict.append({\n      'metric': 'Mean Absolute Error',\n      'value': metrics.mae()\n  })\n  metrics_dict.append({\n      'metric': '50 Percentile Absolute Error',\n      'value': metrics.percentile_nearest(50)\n  })\n  metrics_dict.append({\n      'metric': '90 Percentile Absolute Error',\n      'value': metrics.percentile_nearest(90)\n  })\n  metrics_dict.append({\n      'metric': '99 Percentile Absolute Error',\n      'value': metrics.percentile_nearest(99)\n  })\n  return pd.DataFrame(metrics_dict)\n\n\ndef _evaluate_pr(args, cell):\n  metrics = _create_metrics(args)\n  df = metrics.precision_recall(args['num_thresholds'], args['target_class'],\n                                probability_column=args['probability_column'])\n  if args['plot']:\n    plt.plot(df['recall'], df['precision'],\n             label='Precision-Recall curve for class ' + args['target_class'])\n    plt.xlabel('Recall')\n    plt.ylabel('Precision')\n    plt.ylim([0.0, 1.05])\n    plt.xlim([0.0, 1.0])\n    plt.title('Precision-Recall')\n    plt.legend(loc=\"lower left\")\n    plt.show()\n  else:\n    return df\n\n\ndef _evaluate_roc(args, cell):\n  metrics = _create_metrics(args)\n  df = metrics.roc(args['num_thresholds'], args['target_class'],\n                   probability_column=args['probability_column'])\n  if args['plot']:\n    plt.plot(df['fpr'], df['tpr'],\n             label='ROC curve for class ' + args['target_class'])\n    plt.xlabel('fpr')\n    plt.ylabel('tpr')\n    plt.ylim([0.0, 1.05])\n    plt.xlim([0.0, 1.0])\n    plt.title('ROC')\n    plt.legend(loc=\"lower left\")\n    plt.show()\n  else:\n    return df\n\n\ndef _model_list(args, cell):\n  if args['name']:\n    # model name provided. List versions of that model.\n    versions = datalab_ml.ModelVersions(args['name'], project_id=args['project'])\n    versions = list(versions.get_iterator())\n    df = pd.DataFrame(versions)\n    df['name'] = df['name'].apply(lambda x: x.split('/')[-1])\n    df = df.replace(np.nan, '', regex=True)\n    return df\n  else:\n    # List all models.\n    models = list(datalab_ml.Models(project_id=args['project']).get_iterator())\n    if len(models) > 0:\n      df = pd.DataFrame(models)\n      df['name'] = df['name'].apply(lambda x: x.split('/')[-1])\n      df['defaultVersion'] = df['defaultVersion'].apply(lambda x: x['name'].split('/')[-1])\n      df = df.replace(np.nan, '', regex=True)\n      return df\n    else:\n      print('No models found.')\n\n\ndef _model_delete(args, cell):\n  parts = args['name'].split('.')\n  if len(parts) == 1:\n    models = datalab_ml.Models(project_id=args['project'])\n    models.delete(parts[0])\n  elif len(parts) == 2:\n    versions = datalab_ml.ModelVersions(parts[0], project_id=args['project'])\n    versions.delete(parts[1])\n  else:\n    raise ValueError('Too many \".\" in name. Use \"model\" or \"model.version\".')\n\n\ndef _model_deploy(args, cell):\n  parts = args['name'].split('.')\n  if len(parts) == 2:\n    model_name, version_name = parts[0], parts[1]\n    model_exists = False\n    try:\n      # If describe() works, the model already exists.\n      datalab_ml.Models(project_id=args['project']).get_model_details(model_name)\n      model_exists = True\n    except:\n      pass\n\n    if not model_exists:\n      datalab_ml.Models(project_id=args['project']).create(model_name)\n\n    versions = datalab_ml.ModelVersions(model_name, project_id=args['project'])\n    runtime_version = args['runtime_version']\n    if not runtime_version:\n      runtime_version = tf.__version__\n    versions.deploy(version_name, args['path'], runtime_version=runtime_version)\n  else:\n    raise ValueError('Name must be like \"model.version\".')\n\n\ndef _dataset_create(args, cell):\n  if args['format'] == 'csv':\n    if not args['schema']:\n      raise ValueError('schema is required if format is csv.')\n\n    schema, schema_file = None, None\n    if isinstance(args['schema'], six.string_types):\n      schema_file = args['schema']\n    elif isinstance(args['schema'], list):\n      schema = args['schema']\n    else:\n      raise ValueError('schema should either be a file path, or a dictionary.')\n\n    train_dataset = datalab_ml.CsvDataSet(args['train'], schema=schema, schema_file=schema_file)\n    eval_dataset = datalab_ml.CsvDataSet(args['eval'], schema=schema, schema_file=schema_file)\n  elif args['format'] == 'bigquery':\n    train_dataset = datalab_ml.BigQueryDataSet(table=args['train'])\n    eval_dataset = datalab_ml.BigQueryDataSet(table=args['eval'])\n  elif args['format'] == 'transformed':\n    train_dataset = datalab_ml.TransformedDataSet(args['train'])\n    eval_dataset = datalab_ml.TransformedDataSet(args['eval'])\n  else:\n    raise ValueError('Invalid data format.')\n\n  dataset = DataSet(train_dataset, eval_dataset)\n  google.datalab.utils.commands.notebook_environment()[args['name']] = dataset\n\n\ndef _dataset_explore(args, cell):\n\n  dataset = get_dataset_from_arg(args['name'])\n  print('train data instances: %d' % dataset.train.size)\n  print('eval data instances: %d' % dataset.eval.size)\n\n  if args['overview'] or args['facets']:\n    if isinstance(dataset.train, datalab_ml.TransformedDataSet):\n      raise ValueError('transformed data does not support overview or facets.')\n\n    print('Sampled %s instances for each.' % args['sample_size'])\n    sample_train_df = dataset.train.sample(args['sample_size'])\n    sample_eval_df = dataset.eval.sample(args['sample_size'])\n    if args['overview']:\n      overview = datalab_ml.FacetsOverview().plot({'train': sample_train_df,\n                                                   'eval': sample_eval_df})\n      IPython.display.display(overview)\n    if args['facets']:\n      sample_train_df['_source'] = pd.Series(['train'] * len(sample_train_df),\n                                             index=sample_train_df.index)\n      sample_eval_df['_source'] = pd.Series(['eval'] * len(sample_eval_df),\n                                            index=sample_eval_df.index)\n      df_merged = pd.concat([sample_train_df, sample_eval_df])\n      diveview = datalab_ml.FacetsDiveview().plot(df_merged)\n      IPython.display.display(diveview)\n"
  },
  {
    "path": "google/datalab/contrib/pipeline/__init__.py",
    "content": "# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n"
  },
  {
    "path": "google/datalab/contrib/pipeline/_pipeline.py",
    "content": "# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nimport datetime\nimport google\nimport google.datalab.bigquery as bigquery\nimport sys\n\n# Any operators need to be imported here. This is required for dynamically getting the list of\n# templated fields from the operators. Static code-analysis will report that this is not\n# necessary, hence the '# noqa' annotations\nfrom google.datalab.contrib.bigquery.operators._bq_load_operator import LoadOperator  # noqa\nfrom google.datalab.contrib.bigquery.operators._bq_execute_operator import ExecuteOperator  # noqa\nfrom google.datalab.contrib.bigquery.operators._bq_extract_operator import ExtractOperator  # noqa\n\n\nclass PipelineGenerator(object):\n  \"\"\" Represents a Pipeline object that encapsulates an Airflow pipeline spec.\n\n  This object can be used to generate the python airflow spec.\n  \"\"\"\n\n  _imports = \"\"\"\nimport datetime\nfrom airflow import DAG\nfrom airflow.operators.bash_operator import BashOperator\nfrom airflow.contrib.operators.bigquery_operator import BigQueryOperator\nfrom airflow.contrib.operators.bigquery_table_delete_operator import BigQueryTableDeleteOperator\nfrom airflow.contrib.operators.bigquery_to_bigquery import BigQueryToBigQueryOperator\nfrom airflow.contrib.operators.bigquery_to_gcs import BigQueryToCloudStorageOperator\nfrom airflow.contrib.operators.gcs_to_bq import GoogleCloudStorageToBigQueryOperator\nfrom google.datalab.contrib.bigquery.operators._bq_load_operator import LoadOperator\nfrom google.datalab.contrib.bigquery.operators._bq_execute_operator import ExecuteOperator\nfrom google.datalab.contrib.bigquery.operators._bq_extract_operator import ExtractOperator\nfrom datetime import timedelta\n\"\"\"\n\n  @staticmethod\n  def generate_airflow_spec(name, pipeline_spec):\n    \"\"\" Gets the airflow python spec for the Pipeline object.\n    \"\"\"\n    task_definitions = ''\n    up_steam_statements = ''\n    parameters = pipeline_spec.get('parameters')\n    for (task_id, task_details) in sorted(pipeline_spec['tasks'].items()):\n      task_def = PipelineGenerator._get_operator_definition(task_id, task_details, parameters)\n      task_definitions = task_definitions + task_def\n      dependency_def = PipelineGenerator._get_dependency_definition(\n        task_id, task_details.get('up_stream', []))\n      up_steam_statements = up_steam_statements + dependency_def\n\n    schedule_config = pipeline_spec.get('schedule', {})\n\n    default_args = PipelineGenerator._get_default_args(schedule_config,\n                                                       pipeline_spec.get('emails', {}))\n    dag_definition = PipelineGenerator._get_dag_definition(\n      name, schedule_config.get('interval', '@once'), schedule_config.get('catchup', False))\n    return PipelineGenerator._imports + default_args + dag_definition + task_definitions + \\\n        up_steam_statements\n\n  @staticmethod\n  def _get_default_args(schedule_config, emails):\n    start_datetime_obj = schedule_config.get('start', datetime.datetime.now())\n    end_datetime_obj = schedule_config.get('end')\n    start_date_str = PipelineGenerator._get_datetime_expr_str(start_datetime_obj)\n    end_date_str = PipelineGenerator._get_datetime_expr_str(end_datetime_obj)\n\n    default_arg_literals = \"\"\"\n    'owner': 'Google Cloud Datalab',\n    'email': {0},\n    'start_date': {1},\n    'end_date': {2},\n\"\"\".format(emails.split(',') if emails else [], start_date_str, end_date_str)\n\n    configurable_keys = ['email_on_retry', 'email_on_failure', 'retries',\n                         'retry_exponential_backoff']\n    for configurable_key in configurable_keys:\n      if configurable_key in schedule_config:\n        default_arg_literals = default_arg_literals + \"\"\"    \\'{0}\\': {1},\n\"\"\".format(configurable_key, schedule_config.get(configurable_key))\n\n    # We deal with these separately as they need to be timedelta literals.\n    retry_delay_keys = ['retry_delay_seconds', 'max_retry_delay_seconds']\n    for retry_delay_key in retry_delay_keys:\n      if retry_delay_key in schedule_config:\n        default_arg_literals = default_arg_literals + \"\"\"    \\'{0}\\': timedelta(seconds={1}),\n\"\"\".format(retry_delay_key[:-8], schedule_config.get(retry_delay_key))\n\n    return \"\"\"\ndefault_args = {{{0}}}\n\n\"\"\".format(default_arg_literals)\n\n  @staticmethod\n  def _get_datetime_expr_str(datetime_obj):\n    if not datetime_obj:\n      return None\n\n    # Apache Airflow assumes that all times are timezone-unaware, and are in UTC:\n    # https: // issues.apache.org / jira / browse / AIRFLOW - 1710\n    # Somewhat conveniently, yaml.load() recognizes and parses strings that look like datetimes\n    # into timezone unaware datetime objects (if the user input specifies the timezone, it's\n    # corrected and the result is assumed to be in UTC).\n    # Here, we serialize this object into the format laid down by ISO 8601, and generate python code\n    # that parses this format into a datetime object for Airflow.\n    datetime_format = '%Y-%m-%dT%H:%M:%S'  # ISO 8601, timezone unaware\n    expr_format = 'datetime.datetime.strptime(\\'{0}\\', \\'{1}\\')'\n    return expr_format.format(datetime_obj.strftime(datetime_format), datetime_format)\n\n  @staticmethod\n  def _get_operator_definition(task_id, task_details, parameters):\n    \"\"\" Internal helper that gets the definition of the airflow operator for the task with the\n      python parameters. All the parameters are also expanded with the airflow macros.\n      :param parameters:\n    \"\"\"\n    operator_type = task_details['type']\n    full_param_string = 'task_id=\\'{0}_id\\''.format(task_id)\n    operator_class_name, module = PipelineGenerator._get_operator_class_name(operator_type)\n    operator_class_instance = getattr(sys.modules[module], operator_class_name, None)\n    templated_fields = operator_class_instance.template_fields if operator_class_instance else ()\n\n    operator_param_values = PipelineGenerator._get_operator_param_name_and_values(\n        operator_class_name, task_details)\n\n    # This loop resolves all the macros and builds up the final string\n    merged_parameters = google.datalab.bigquery.Query.merge_parameters(\n      parameters, date_time=datetime.datetime.now(), macros=True, types_and_values=False)\n    for (operator_param_name, operator_param_value) in sorted(operator_param_values.items()):\n      # We replace modifiers in the parameter values with either the user-defined values, or with\n      # with the airflow macros, as applicable.\n      # An important assumption that this makes is that the operators parameters have the same names\n      # as the templated_fields. TODO(rajivpb): There may be a better way to do this.\n      if operator_param_name in templated_fields:\n        operator_param_value = google.datalab.bigquery.Query._resolve_parameters(\n          operator_param_value, merged_parameters)\n      param_format_string = PipelineGenerator._get_param_format_string(operator_param_value)\n      param_string = param_format_string.format(operator_param_name, operator_param_value)\n      full_param_string = full_param_string + param_string\n\n    return '{0} = {1}({2}, dag=dag)\\n'.format(task_id, operator_class_name, full_param_string)\n\n  @staticmethod\n  def _get_param_format_string(param_value):\n    # If the type is a python non-string (best guess), we don't quote it.\n    if type(param_value) in [int, bool, float, type(None), list, dict]:\n      return ', {0}={1}'\n    return ', {0}=\"\"\"{1}\"\"\"'\n\n  @staticmethod\n  def _get_dag_definition(name, schedule_interval, catchup=False):\n    dag_definition = 'dag = DAG(dag_id=\\'{0}\\', schedule_interval=\\'{1}\\', ' \\\n                     'catchup={2}, default_args=default_args)\\n\\n'.format(name,\n                                                                          schedule_interval,\n                                                                          catchup)\n    return dag_definition\n\n  @staticmethod\n  def _get_dependency_definition(task_id, dependencies):\n    \"\"\" Internal helper collects all the dependencies of the task, and returns\n      the Airflow equivalent python sytax for specifying them.\n    \"\"\"\n    set_upstream_statements = ''\n    for dependency in dependencies:\n      set_upstream_statements = set_upstream_statements + \\\n          '{0}.set_upstream({1})'.format(task_id, dependency) + '\\n'\n    return set_upstream_statements\n\n  @staticmethod\n  def _get_operator_class_name(task_detail_type):\n    \"\"\" Internal helper gets the name of the Airflow operator class. We maintain\n      this in a map, so this method really returns the enum name, concatenated\n      with the string \"Operator\".\n    \"\"\"\n    # TODO(rajivpb): Rename this var correctly.\n    task_type_to_operator_prefix_mapping = {\n      'pydatalab.bq.execute': ('Execute',\n                               'google.datalab.contrib.bigquery.operators._bq_execute_operator'),\n      'pydatalab.bq.extract': ('Extract',\n                               'google.datalab.contrib.bigquery.operators._bq_extract_operator'),\n      'pydatalab.bq.load': ('Load', 'google.datalab.contrib.bigquery.operators._bq_load_operator'),\n      'Bash': ('Bash', 'airflow.operators.bash_operator')\n    }\n    (operator_class_prefix, module) = task_type_to_operator_prefix_mapping.get(\n        task_detail_type, (None, __name__))\n    format_string = '{0}Operator'\n    operator_class_name = format_string.format(operator_class_prefix)\n    if operator_class_prefix is None:\n      return format_string.format(task_detail_type), module\n    return operator_class_name, module\n\n  @staticmethod\n  def _get_operator_param_name_and_values(operator_class_name, task_details):\n    \"\"\" Internal helper gets the name of the python parameter for the Airflow operator class. In\n      some cases, we do not expose the airflow parameter name in its native form, but choose to\n      expose a name that's more standard for Datalab, or one that's more friendly. For example,\n      Airflow's BigQueryOperator uses 'bql' for the query string, but we want %%bq users in Datalab\n      to use 'query'. Hence, a few substitutions that are specific to the Airflow operator need to\n      be made.\n\n      Similarly, we the parameter value could come from the notebook's context. All that happens\n      here.\n\n      Returns:\n        Dict containing _only_ the keys and values that are required in Airflow operator definition.\n      This requires a substituting existing keys in the dictionary with their Airflow equivalents (\n      i.e. by adding new keys, and removing the existing ones).\n    \"\"\"\n\n    # We make a clone and then remove 'type' and 'up_stream' since these aren't needed for the\n    # the operator's parameters.\n    operator_task_details = task_details.copy()\n    if 'type' in operator_task_details.keys():\n      del operator_task_details['type']\n    if 'up_stream' in operator_task_details.keys():\n      del operator_task_details['up_stream']\n\n    # We special-case certain operators if we do some translation of the parameter names. This is\n    # usually the case when we use syntactic sugar to expose the functionality.\n    # TODO(rajivpb): It should be possible to make this a lookup from the modules mapping via\n    # getattr() or equivalent. Avoid hard-coding these class-names here.\n    if (operator_class_name == 'BigQueryOperator'):\n      return PipelineGenerator._get_bq_execute_params(operator_task_details)\n    if (operator_class_name == 'BigQueryToCloudStorageOperator'):\n      return PipelineGenerator._get_bq_extract_params(operator_task_details)\n    if (operator_class_name == 'GoogleCloudStorageToBigQueryOperator'):\n      return PipelineGenerator._get_bq_load_params(operator_task_details)\n    return operator_task_details\n\n  @staticmethod\n  def _get_bq_execute_params(operator_task_details):\n    if 'query' in operator_task_details:\n      operator_task_details['bql'] = operator_task_details['query'].sql\n      del operator_task_details['query']\n\n    if 'parameters' in operator_task_details:\n      operator_task_details['query_params'] = bigquery.Query.get_query_parameters(\n        operator_task_details['parameters'])\n      del operator_task_details['parameters']\n\n    # Add over-rides of Airflow defaults here.\n    if 'use_legacy_sql' not in operator_task_details:\n      operator_task_details['use_legacy_sql'] = False\n\n    return operator_task_details\n\n  @staticmethod\n  def _get_bq_extract_params(operator_task_details):\n    if 'table' in operator_task_details:\n      table = bigquery.commands._bigquery._get_table(operator_task_details['table'])\n      operator_task_details['source_project_dataset_table'] = table.full_name\n      del operator_task_details['table']\n    if 'path' in operator_task_details:\n      operator_task_details['destination_cloud_storage_uris'] = [operator_task_details['path']]\n      del operator_task_details['path']\n    if 'format' in operator_task_details:\n      operator_task_details['export_format'] = 'CSV' if operator_task_details['format'] == 'csv' \\\n        else 'NEWLINE_DELIMITED_JSON'\n      del operator_task_details['format']\n    if 'delimiter' in operator_task_details:\n      operator_task_details['field_delimiter'] = operator_task_details['delimiter']\n      del operator_task_details['delimiter']\n    if 'compress' in operator_task_details:\n      operator_task_details['compression'] = 'GZIP' if operator_task_details['compress'] else 'NONE'\n      del operator_task_details['compress']\n    if 'header' in operator_task_details:\n      operator_task_details['print_header'] = operator_task_details['header']\n      del operator_task_details['header']\n\n    return operator_task_details\n\n  @staticmethod\n  def _get_bq_load_params(operator_task_details):\n    if 'table' in operator_task_details:\n      table = bigquery.commands._bigquery._get_table(operator_task_details['table'])\n      if not table:\n        table = bigquery.Table(operator_task_details['table'])\n        # TODO(rajivpb): Ensure that mode == create here.\n      operator_task_details['destination_project_dataset_table'] = table.full_name\n      del operator_task_details['table']\n\n    if 'format' in operator_task_details:\n      operator_task_details['export_format'] = 'CSV' if operator_task_details['format'] == 'csv' \\\n        else 'NEWLINE_DELIMITED_JSON'\n      del operator_task_details['format']\n\n    if 'delimiter' in operator_task_details:\n      operator_task_details['field_delimiter'] = operator_task_details['delimiter']\n      del operator_task_details['delimiter']\n\n    if 'skip' in operator_task_details:\n      operator_task_details['skip_leading_rows'] = operator_task_details['skip']\n      del operator_task_details['skip']\n\n    if 'path' in operator_task_details:\n      bucket, source_object = PipelineGenerator._get_bucket_and_source_object(\n        operator_task_details['path'])\n      operator_task_details['bucket'] = bucket\n      operator_task_details['source_objects'] = source_object\n      del operator_task_details['path']\n\n    return operator_task_details\n\n  @staticmethod\n  def _get_bucket_and_source_object(gcs_path):\n    return gcs_path.split('/')[2], '/'.join(gcs_path.split('/')[3:])\n"
  },
  {
    "path": "google/datalab/contrib/pipeline/airflow/__init__.py",
    "content": "# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\nfrom ._airflow import Airflow  # noqa\n"
  },
  {
    "path": "google/datalab/contrib/pipeline/airflow/_airflow.py",
    "content": "# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nimport google.datalab.storage as storage\n\n\nclass Airflow(object):\n  \"\"\" Represents a Airflow object that encapsulates a set of functionality relating to the\n  Cloud Airflow service.\n\n  This object can be used to generate the python airflow spec.\n  \"\"\"\n\n  def __init__(self, gcs_dag_bucket, gcs_dag_file_path=None):\n    \"\"\" Initializes an instance of a Airflow object.\n\n    Args:\n      gcs_dag_bucket: Bucket where Airflow expects dag files to be uploaded.\n      gcs_dag_file_path: File path of the Airflow dag files.\n    \"\"\"\n    self._gcs_dag_bucket = gcs_dag_bucket\n    self._gcs_dag_file_path = gcs_dag_file_path or ''\n\n  def deploy(self, name, dag_string):\n    if self._gcs_dag_file_path is not '' and self._gcs_dag_file_path.endswith('/') is False:\n      self._gcs_dag_file_path = self._gcs_dag_file_path + '/'\n    file_name = '{0}{1}.py'.format(self._gcs_dag_file_path, name)\n\n    bucket = storage.Bucket(self._gcs_dag_bucket)\n    file_object = bucket.object(file_name)\n    file_object.write_stream(dag_string, 'text/plain')\n"
  },
  {
    "path": "google/datalab/contrib/pipeline/commands/__init__.py",
    "content": "# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n"
  },
  {
    "path": "google/datalab/contrib/pipeline/commands/_pipeline.py",
    "content": "# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Google Cloud Platform library - Pipeline IPython Functionality.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import print_function\nfrom __future__ import unicode_literals\n\nimport google\n\n\ndef _create_cell(args, cell_body):\n  \"\"\"Implements the pipeline cell create magic used to create Pipeline objects.\n  The supported syntax is:\n      %%pipeline create <args>\n      [<inline YAML>]\n  Args:\n    args: the arguments following '%%pipeline create'.\n    cell_body: the contents of the cell\n  \"\"\"\n  name = args.get('name')\n  if name is None:\n    raise Exception(\"Pipeline name was not specified.\")\n  pipeline_spec = google.datalab.utils.commands.parse_config(\n    cell_body, google.datalab.utils.commands.notebook_environment())\n  airflow_spec = google.datalab.contrib.pipeline._pipeline.PipelineGenerator.generate_airflow_spec(\n      name, pipeline_spec)\n\n  debug = args.get('debug')\n  if debug is True:\n    return airflow_spec\n\n\ndef _create_create_subparser(parser):\n  create_parser = parser.subcommand('create', 'Create and/or execute a '\n                                              'Pipeline object. If a pipeline '\n                                              'name is not specified, the '\n                                              'pipeline is scheduled.')\n  create_parser.add_argument('-n', '--name', type=str,\n                             help='The name of this Pipeline object.')\n  create_parser.add_argument('-d', '--debug', action='store_true',\n                             default=False,\n                             help='Print the airflow python spec.')\n\n  return create_parser\n\n\ndef _add_command(parser, subparser_fn, handler, cell_required=False,\n                 cell_prohibited=False):\n  \"\"\" Create and initialize a pipeline subcommand handler. \"\"\"\n  sub_parser = subparser_fn(parser)\n  sub_parser.set_defaults(func=lambda args, cell: _dispatch_handler(\n      args, cell, sub_parser, handler, cell_required=cell_required,\n      cell_prohibited=cell_prohibited))\n\n\ndef _create_pipeline_parser():\n  \"\"\" Create the parser for the %pipeline magics.\n\n    Note that because we use the func default handler dispatch mechanism of\n    argparse, our handlers can take only one argument which is the parsed args. So\n    we must create closures for the handlers that bind the cell contents and thus\n    must recreate this parser for each cell upon execution.\n  \"\"\"\n  parser = google.datalab.utils.commands.CommandParser(\n      prog='%pipeline', description=\"\"\"\nExecute various pipeline-related operations. Use \"%pipeline <command> -h\"\nfor help on a specific command.\n  \"\"\")\n\n  # %%pipeline create\n  _add_command(parser, _create_create_subparser, _create_cell)\n\n  return parser\n\n\n_pipeline_parser = _create_pipeline_parser()\n\n\n# TODO(rajivpb): Decorate this with '@IPython.core.magic.register_line_cell_magic'\ndef pipeline(line, cell=None):\n  \"\"\"Implements the pipeline cell magic for ipython notebooks.\n\n  The supported syntax is:\n\n    %%pipeline <command> [<args>]\n    <cell>\n\n  or:\n\n    %pipeline <command> [<args>]\n\n  Use %pipeline --help for a list of commands, or %pipeline <command> --help for\n  help on a specific command.\n  \"\"\"\n  return google.datalab.utils.commands.handle_magic_line(line, cell, _pipeline_parser)\n\n\ndef _dispatch_handler(args, cell, parser, handler, cell_required=False,\n                      cell_prohibited=False):\n  \"\"\" Makes sure cell magics include cell and line magics don't, before\n    dispatching to handler.\n\n  Args:\n    args: the parsed arguments from the magic line.\n    cell: the contents of the cell, if any.\n    parser: the argument parser for <cmd>; used for error message.\n    handler: the handler to call if the cell present/absent check passes.\n    cell_required: True for cell magics, False for line magics that can't be\n      cell magics.\n    cell_prohibited: True for line magics, False for cell magics that can't be\n      line magics.\n  Returns:\n    The result of calling the handler.\n  Raises:\n    Exception if the invocation is not valid.\n  \"\"\"\n  if cell_prohibited:\n    if cell and len(cell.strip()):\n      parser.print_help()\n      raise Exception(\n          'Additional data is not supported with the %s command.' % parser.prog)\n    return handler(args)\n\n  if cell_required and not cell:\n    parser.print_help()\n    raise Exception('The %s command requires additional data' % parser.prog)\n\n  return handler(args, cell)\n"
  },
  {
    "path": "google/datalab/contrib/pipeline/composer/__init__.py",
    "content": "# Copyright 2018 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\nfrom ._composer import Composer  # noqa\n"
  },
  {
    "path": "google/datalab/contrib/pipeline/composer/_api.py",
    "content": "# Copyright 2018 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Implements Composer HTTP API wrapper.\"\"\"\nimport google.datalab.utils\n\n\nclass Api(object):\n  \"\"\"A helper class to issue Composer HTTP requests.\"\"\"\n\n  _ENDPOINT = 'https://composer.googleapis.com/v1alpha1'\n  _ENVIRONMENTS_PATH_FORMAT = '/projects/%s/locations/%s/environments/%s'\n\n  @staticmethod\n  def get_environment_details(zone, environment):\n    \"\"\" Issues a request to Composer to get the environment details.\n\n    Args:\n      zone: GCP zone of the composer environment\n      environment: name of the Composer environment\n    Returns:\n      A parsed result object.\n    Raises:\n      Exception if there is an error performing the operation.\n    \"\"\"\n    default_context = google.datalab.Context.default()\n    url = (Api._ENDPOINT + (Api._ENVIRONMENTS_PATH_FORMAT % (default_context.project_id, zone,\n                                                             environment)))\n\n    return google.datalab.utils.Http.request(url, credentials=default_context.credentials)\n"
  },
  {
    "path": "google/datalab/contrib/pipeline/composer/_composer.py",
    "content": "# Copyright 2018 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nimport google.datalab.storage as storage\nfrom google.datalab.contrib.pipeline.composer._api import Api\nimport re\n\n\nclass Composer(object):\n  \"\"\" Represents a Composer object that encapsulates a set of functionality relating to the\n  Cloud Composer service.\n\n  This object can be used to generate the python airflow spec.\n  \"\"\"\n\n  gcs_file_regexp = re.compile('gs://.*')\n\n  def __init__(self, zone, environment):\n    \"\"\" Initializes an instance of a Composer object.\n\n    Args:\n      zone: Zone in which Composer environment has been created.\n      environment: Name of the Composer environment.\n    \"\"\"\n    self._zone = zone\n    self._environment = environment\n    self._gcs_dag_location = None\n\n  def deploy(self, name, dag_string):\n    bucket_name, file_path = self.gcs_dag_location.split('/', 3)[2:]  # setting maxsplit to 3\n    file_name = '{0}{1}.py'.format(file_path, name)\n\n    bucket = storage.Bucket(bucket_name)\n    file_object = bucket.object(file_name)\n    file_object.write_stream(dag_string, 'text/plain')\n\n  @property\n  def gcs_dag_location(self):\n    if not self._gcs_dag_location:\n      environment_details = Api.get_environment_details(self._zone, self._environment)\n\n      if ('config' not in environment_details or\n              'gcsDagLocation' not in environment_details.get('config')):\n        raise ValueError('Dag location unavailable from Composer environment {0}'.format(\n          self._environment))\n      gcs_dag_location = environment_details['config']['gcsDagLocation']\n\n      if gcs_dag_location is None or not self.gcs_file_regexp.match(gcs_dag_location):\n        raise ValueError(\n          'Dag location {0} from Composer environment {1} is in incorrect format'.format(\n            gcs_dag_location, self._environment))\n\n      self._gcs_dag_location = gcs_dag_location\n      if gcs_dag_location.endswith('/') is False:\n        self._gcs_dag_location = self._gcs_dag_location + '/'\n\n    return self._gcs_dag_location\n"
  },
  {
    "path": "google/datalab/data/__init__.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Google Cloud Platform library - Generic SQL Helpers.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\n\nfrom ._csv_file import CsvFile\n\n__all__ = ['CsvFile']\n"
  },
  {
    "path": "google/datalab/data/_csv_file.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Implements usefule CSV utilities.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom builtins import next\nfrom builtins import str as newstr\nfrom builtins import range\nfrom builtins import object\n\n\nimport csv\nimport os\nimport pandas as pd\nimport random\nimport sys\n\ntry:\n    from StringIO import StringIO\nexcept ImportError:\n    from io import StringIO\nimport tempfile\nimport google.datalab.storage\nimport google.datalab.utils\n\n\n_MAX_CSV_BYTES = 10000000\n\n\nclass CsvFile(object):\n  \"\"\"Represents a CSV file in GCS or locally with same schema.\n  \"\"\"\n  def __init__(self, path, delimiter=b','):\n    \"\"\"Initializes an instance of a Csv instance.\n    Args:\n      path: path of the Csv file.\n      delimiter: the separator used to parse a Csv line.\n    \"\"\"\n    self._path = path\n    self._delimiter = delimiter\n\n  @property\n  def path(self):\n    return self._path\n\n  @staticmethod\n  def _read_gcs_lines(path, max_lines=None):\n    return google.datalab.storage.Object.from_url(path).read_lines(max_lines)\n\n  @staticmethod\n  def _read_local_lines(path, max_lines=None):\n    lines = []\n    for line in open(path):\n      if max_lines is not None and len(lines) >= max_lines:\n        break\n      lines.append(line)\n    return lines\n\n  def _is_probably_categorical(self, column):\n    if newstr(column.dtype) != 'object':\n      # only string types (represented in DataFrame as object) can potentially be categorical\n      return False\n    if len(max(column, key=lambda p: len(newstr(p)))) > 100:\n      return False  # value too long to be a category\n    if len(set(column)) > 100:\n      return False  # too many unique values to be a category\n    return True\n\n  def browse(self, max_lines=None, headers=None):\n    \"\"\"Try reading specified number of lines from the CSV object.\n    Args:\n      max_lines: max number of lines to read. If None, the whole file is read\n      headers: a list of strings as column names. If None, it will use \"col0, col1...\"\n    Returns:\n      A pandas DataFrame with the schema inferred from the data.\n    Raises:\n      Exception if the csv object cannot be read or not enough lines to read, or the\n      headers size does not match columns size.\n    \"\"\"\n    if self.path.startswith('gs://'):\n      lines = CsvFile._read_gcs_lines(self.path, max_lines)\n    else:\n      lines = CsvFile._read_local_lines(self.path, max_lines)\n    if len(lines) == 0:\n      return pd.DataFrame(columns=headers)\n    columns_size = len(next(csv.reader([lines[0]], delimiter=self._delimiter)))\n    if headers is None:\n      headers = ['col' + newstr(e) for e in range(columns_size)]\n    if len(headers) != columns_size:\n      raise Exception('Number of columns in CSV do not match number of headers')\n    buf = StringIO()\n    for line in lines:\n      buf.write(line)\n      buf.write('\\n')\n    buf.seek(0)\n    df = pd.read_csv(buf, names=headers, delimiter=self._delimiter)\n    for key, col in df.iteritems():\n      if self._is_probably_categorical(col):\n        df[key] = df[key].astype('category')\n    return df\n\n  def _create_external_data_source(self, skip_header_rows):\n    import google.datalab.bigquery as bq\n    df = self.browse(1, None)\n    # read each column as STRING because we only want to sample rows.\n    schema_train = bq.Schema([{'name': name, 'type': 'STRING'} for name in df.keys()])\n    options = bq.CSVOptions(skip_leading_rows=(1 if skip_header_rows is True else 0))\n    return bq.ExternalDataSource(self.path,\n                                 csv_options=options,\n                                 schema=schema_train,\n                                 max_bad_records=0)\n\n  def _get_gcs_csv_row_count(self, external_data_source):\n    import google.datalab.bigquery as bq\n    results = bq.Query('SELECT count(*) from data',\n                       data_sources={'data': external_data_source}).execute().result()\n    return results[0].values()[0]\n\n  def sample_to(self, count, skip_header_rows, strategy, target):\n    \"\"\"Sample rows from GCS or local file and save results to target file.\n\n    Args:\n      count: number of rows to sample. If strategy is \"BIGQUERY\", it is used as approximate number.\n      skip_header_rows: whether to skip first row when reading from source.\n      strategy: can be \"LOCAL\" or \"BIGQUERY\". If local, the sampling happens in local memory,\n          and number of resulting rows matches count. If BigQuery, sampling is done\n          with BigQuery in cloud, and the number of resulting rows will be approximated to\n          count.\n      target: The target file path, can be GCS or local path.\n    Raises:\n      Exception if strategy is \"BIGQUERY\" but source is not a GCS path.\n    \"\"\"\n\n    if sys.version_info.major > 2:\n      xrange = range  # for python 3 compatibility\n\n    # TODO(qimingj) Add unit test\n    # Read data from source into DataFrame.\n    if strategy == 'BIGQUERY':\n      import google.datalab.bigquery as bq\n      if not self.path.startswith('gs://'):\n        raise Exception('Cannot use BIGQUERY if data is not in GCS')\n      external_data_source = self._create_external_data_source(skip_header_rows)\n      row_count = self._get_gcs_csv_row_count(external_data_source)\n      query = bq.Query('SELECT * from data', data_sources={'data': external_data_source})\n      sampling = bq.Sampling.random(count * 100 / float(row_count))\n      sample = query.sample(sampling=sampling)\n      df = sample.to_dataframe()\n    elif strategy == 'LOCAL':\n      local_file = self.path\n      if self.path.startswith('gs://'):\n        local_file = tempfile.mktemp()\n        google.datalab.utils.gcs_copy_file(self.path, local_file)\n      with open(local_file) as f:\n        row_count = sum(1 for line in f)\n      start_row = 1 if skip_header_rows is True else 0\n      skip_count = row_count - count - 1 if skip_header_rows is True else row_count - count\n      skip = sorted(random.sample(xrange(start_row, row_count), skip_count))\n      header_row = 0 if skip_header_rows is True else None\n      df = pd.read_csv(local_file, skiprows=skip, header=header_row, delimiter=self._delimiter)\n      if self.path.startswith('gs://'):\n        os.remove(local_file)\n    else:\n      raise Exception('strategy must be BIGQUERY or LOCAL')\n    # Write to target.\n    if target.startswith('gs://'):\n      with tempfile.NamedTemporaryFile() as f:\n        df.to_csv(f, header=False, index=False)\n        f.flush()\n        google.datalab.utils.gcs_copy_file(f.name, target)\n    else:\n      with open(target, 'w') as f:\n        df.to_csv(f, header=False, index=False, sep=str(self._delimiter))\n"
  },
  {
    "path": "google/datalab/kernel/__init__.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Google Cloud Datalab - notebook functionality.\"\"\"\n\n\nimport httplib2 as _httplib2\nimport requests as _requests\n\n\ntry:\n  import IPython as _IPython\n  import IPython.core.magic as _magic # noqa\n  import IPython.core.interactiveshell as _shell\n  from IPython import get_ipython # noqa\nexcept ImportError:\n  raise Exception('This package requires an IPython notebook installation')\n\nimport google.datalab\n\n# Import the modules that do cell magics.\nimport google.datalab.bigquery.commands\nimport google.datalab.commands\nimport google.datalab.stackdriver.commands\nimport google.datalab.storage.commands\nimport google.datalab.utils\nimport google.datalab.utils.commands\n\n_orig_request = _httplib2.Http.request\n_orig_init = _requests.Session.__init__\n_orig_run_cell_magic = _shell.InteractiveShell.run_cell_magic\n_orig_run_line_magic = _shell.InteractiveShell.run_line_magic\n\n\ndef load_ipython_extension(shell):\n  \"\"\"\n  Called when the extension is loaded.\n\n  Args:\n      shell - (NotebookWebApplication): handle to the Notebook interactive shell instance.\n  \"\"\"\n\n  # Inject our user agent on all requests by monkey-patching a wrapper around httplib2.Http.request.\n\n  def _request(self, uri, method=\"GET\", body=None, headers=None,\n               redirections=_httplib2.DEFAULT_MAX_REDIRECTS, connection_type=None):\n    if headers is None:\n      headers = {}\n    headers['user-agent'] = 'GoogleCloudDataLab/1.0'\n    return _orig_request(self, uri, method=method, body=body, headers=headers,\n                         redirections=redirections, connection_type=connection_type)\n\n  _httplib2.Http.request = _request\n\n  # Similarly for the requests library.\n\n  def _init_session(self):\n    _orig_init(self)\n    self.headers['User-Agent'] = 'GoogleCloudDataLab/1.0'\n\n  _requests.Session.__init__ = _init_session\n\n  # Be more tolerant with magics. If the user specified a cell magic that doesn't\n  # exist and an empty cell body but a line magic with that name exists, run that\n  # instead. Conversely, if the user specified a line magic that doesn't exist but\n  # a cell magic exists with that name, run the cell magic with an empty body.\n\n  def _run_line_magic(self, magic_name, line):\n    fn = self.find_line_magic(magic_name)\n    if fn is None:\n      cm = self.find_cell_magic(magic_name)\n      if cm:\n        return _run_cell_magic(self, magic_name, line, None)\n    return _orig_run_line_magic(self, magic_name, line)\n\n  def _run_cell_magic(self, magic_name, line, cell):\n    if cell is None or len(cell) == 0 or cell.isspace():\n      fn = self.find_line_magic(magic_name)\n      if fn:\n        return _orig_run_line_magic(self, magic_name, line)\n      # IPython will complain if cell is empty string but not if it is None\n      cell = None\n    return _orig_run_cell_magic(self, magic_name, line, cell)\n\n  _shell.InteractiveShell.run_cell_magic = _run_cell_magic\n  _shell.InteractiveShell.run_line_magic = _run_line_magic\n\n  # Define global 'project_id' and 'set_project_id' functions to manage the default project ID. We\n  # do this conditionally in a try/catch # to avoid the call to Context.default() when running tests\n  # which mock IPython.get_ipython().\n\n  def _get_project_id():\n    try:\n      return google.datalab.Context.default().project_id\n    except Exception:\n      return None\n\n  def _set_project_id(project_id):\n    context = google.datalab.Context.default()\n    context.set_project_id(project_id)\n    try:\n      from datalab.context import Context as _old_context\n      _old_context.default().set_project_id(project_id)\n    except ImportError:\n      # If the old library is not loaded, then we don't have to do anything\n      pass\n\n  try:\n    if 'datalab_project_id' not in _IPython.get_ipython().user_ns:\n      _IPython.get_ipython().user_ns['datalab_project_id'] = _get_project_id\n      _IPython.get_ipython().user_ns['set_datalab_project_id'] = _set_project_id\n  except TypeError:\n    pass\n\n\ndef unload_ipython_extension(shell):\n  _shell.InteractiveShell.run_cell_magic = _orig_run_cell_magic\n  _shell.InteractiveShell.run_line_magic = _orig_run_line_magic\n  _requests.Session.__init__ = _orig_init\n  _httplib2.Http.request = _orig_request\n  try:\n    del _IPython.get_ipython().user_ns['project_id']\n    del _IPython.get_ipython().user_ns['set_project_id']\n  except Exception:\n    pass  # We mock IPython for tests so we need this.\n\n  # TODO(gram): unregister imports/magics/etc.\n"
  },
  {
    "path": "google/datalab/ml/__init__.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n# flake8: noqa\n\n\"\"\"CloudML Helper Library.\"\"\"\n\nfrom __future__ import absolute_import\n\nfrom ._job import Jobs, Job\nfrom ._summary import Summary\nfrom ._tensorboard import TensorBoard\nfrom ._dataset import CsvDataSet, BigQueryDataSet, TransformedDataSet\nfrom ._cloud_models import Models, ModelVersions\nfrom ._confusion_matrix import ConfusionMatrix\nfrom ._feature_slice_view import FeatureSliceView\nfrom ._cloud_training_config import CloudTrainingConfig\nfrom ._fasets import FacetsOverview, FacetsDiveview\nfrom ._metrics import Metrics\nfrom ._util import *\n"
  },
  {
    "path": "google/datalab/ml/_cloud_models.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Implements Cloud ML Model Operations\"\"\"\n\nfrom googleapiclient import discovery\nimport os\nimport yaml\n\nimport google.datalab as datalab\n\nfrom . import _util\n\n\nclass Models(object):\n  \"\"\"Represents a list of Cloud ML models for a project.\"\"\"\n\n  def __init__(self, project_id=None):\n    \"\"\"\n    Args:\n      project_id: project_id of the models. If not provided, default project_id will be used.\n    \"\"\"\n    if project_id is None:\n      project_id = datalab.Context.default().project_id\n    self._project_id = project_id\n    self._credentials = datalab.Context.default().credentials\n    self._api = discovery.build('ml', 'v1', credentials=self._credentials)\n    self._page_size = 0\n\n  def _retrieve_models(self, page_token, _):\n    list_info = self._api.projects().models().list(\n        parent='projects/' + self._project_id, pageToken=page_token,\n        pageSize=self._page_size).execute()\n    models = list_info.get('models', [])\n    self._page_size = self._page_size or len(models)\n    page_token = list_info.get('nextPageToken', None)\n    return models, page_token\n\n  def get_iterator(self):\n    \"\"\"Get iterator of models so it can be used as \"for model in Models().get_iterator()\".\n    \"\"\"\n    return iter(datalab.utils.Iterator(self._retrieve_models))\n\n  def get_model_details(self, model_name):\n    \"\"\"Get details of the specified model from CloudML Service.\n\n    Args:\n      model_name: the name of the model. It can be a model full name\n          (\"projects/[project_id]/models/[model_name]\") or just [model_name].\n      Returns: a dictionary of the model details.\n    \"\"\"\n    full_name = model_name\n    if not model_name.startswith('projects/'):\n      full_name = ('projects/%s/models/%s' % (self._project_id, model_name))\n    return self._api.projects().models().get(name=full_name).execute()\n\n  def create(self, model_name):\n    \"\"\"Create a model.\n\n    Args:\n      model_name: the short name of the model, such as \"iris\".\n    Returns:\n      If successful, returns informaiton of the model, such as\n      {u'regions': [u'us-central1'], u'name': u'projects/myproject/models/mymodel'}\n    Raises:\n      If the model creation failed.\n    \"\"\"\n    body = {'name': model_name}\n    parent = 'projects/' + self._project_id\n    # Model creation is instant. If anything goes wrong, Exception will be thrown.\n    return self._api.projects().models().create(body=body, parent=parent).execute()\n\n  def delete(self, model_name):\n    \"\"\"Delete a model.\n\n    Args:\n      model_name: the name of the model. It can be a model full name\n          (\"projects/[project_id]/models/[model_name]\") or just [model_name].\n    \"\"\"\n    full_name = model_name\n    if not model_name.startswith('projects/'):\n      full_name = ('projects/%s/models/%s' % (self._project_id, model_name))\n    response = self._api.projects().models().delete(name=full_name).execute()\n    if 'name' not in response:\n      raise Exception('Invalid response from service. \"name\" is not found.')\n    _util.wait_for_long_running_operation(response['name'])\n\n  def list(self, count=10):\n    \"\"\"List models under the current project in a table view.\n\n    Args:\n      count: upper limit of the number of models to list.\n    Raises:\n      Exception if it is called in a non-IPython environment.\n    \"\"\"\n    import IPython\n    data = []\n    # Add range(count) to loop so it will stop either it reaches count, or iteration\n    # on self is exhausted. \"self\" is iterable (see __iter__() method).\n    for _, model in zip(range(count), self.get_iterator()):\n      element = {'name': model['name']}\n      if 'defaultVersion' in model:\n        version_short_name = model['defaultVersion']['name'].split('/')[-1]\n        element['defaultVersion'] = version_short_name\n      data.append(element)\n\n    IPython.display.display(\n        datalab.utils.commands.render_dictionary(data, ['name', 'defaultVersion']))\n\n  def describe(self, model_name):\n    \"\"\"Print information of a specified model.\n\n    Args:\n      model_name: the name of the model to print details on.\n    \"\"\"\n    model_yaml = yaml.safe_dump(self.get_model_details(model_name), default_flow_style=False)\n    print(model_yaml)\n\n\nclass ModelVersions(object):\n  \"\"\"Represents a list of versions for a Cloud ML model.\"\"\"\n\n  def __init__(self, model_name, project_id=None):\n    \"\"\"\n    Args:\n      model_name: the name of the model. It can be a model full name\n          (\"projects/[project_id]/models/[model_name]\") or just [model_name].\n      project_id: project_id of the models. If not provided and model_name is not a full name\n          (not including project_id), default project_id will be used.\n    \"\"\"\n    if project_id is None:\n      self._project_id = datalab.Context.default().project_id\n    self._credentials = datalab.Context.default().credentials\n    self._api = discovery.build('ml', 'v1', credentials=self._credentials)\n    if not model_name.startswith('projects/'):\n      model_name = ('projects/%s/models/%s' % (self._project_id, model_name))\n    self._full_model_name = model_name\n    self._model_name = self._full_model_name.split('/')[-1]\n    self._page_size = 0\n\n  def _retrieve_versions(self, page_token, _):\n    parent = self._full_model_name\n    list_info = self._api.projects().models().versions().list(parent=parent,\n                                                              pageToken=page_token,\n                                                              pageSize=self._page_size).execute()\n    versions = list_info.get('versions', [])\n    self._page_size = self._page_size or len(versions)\n    page_token = list_info.get('nextPageToken', None)\n    return versions, page_token\n\n  def get_iterator(self):\n    \"\"\"Get iterator of versions so it can be used as\n       \"for v in ModelVersions(model_name).get_iterator()\".\n    \"\"\"\n    return iter(datalab.utils.Iterator(self._retrieve_versions))\n\n  def get_version_details(self, version_name):\n    \"\"\"Get details of a version.\n\n    Args:\n      version: the name of the version in short form, such as \"v1\".\n    Returns: a dictionary containing the version details.\n    \"\"\"\n    name = ('%s/versions/%s' % (self._full_model_name, version_name))\n    return self._api.projects().models().versions().get(name=name).execute()\n\n  def deploy(self, version_name, path, runtime_version=None):\n    \"\"\"Deploy a model version to the cloud.\n\n    Args:\n      version_name: the name of the version in short form, such as \"v1\".\n      path: the Google Cloud Storage path (gs://...) which contains the model files.\n      runtime_version: the ML Engine runtime version as a string, example '1.2'.\n          See https://cloud.google.com/ml-engine/docs/concepts/runtime-version-list\n          for a list of runtimes. If None, the ML Engine service will pick one.\n\n    Raises: Exception if the path is invalid or does not contain expected files.\n            Exception if the service returns invalid response.\n    \"\"\"\n    if not path.startswith('gs://'):\n      raise Exception('Invalid path. Only Google Cloud Storage path (gs://...) is accepted.')\n\n    # If there is no \"export.meta\" or\"saved_model.pb\" under path but there is\n    # path/model/export.meta or path/model/saved_model.pb, then append /model to the path.\n    if not datalab.storage.Object.from_url(os.path.join(path, 'export.meta')).exists() and not \\\n            datalab.storage.Object.from_url(os.path.join(path, 'saved_model.pb')).exists():\n      if datalab.storage.Object.from_url(os.path.join(path, 'model', 'export.meta')).exists() or \\\n              datalab.storage.Object.from_url(os.path.join(path, 'model',\n                                                           'saved_model.pb')).exists():\n        path = os.path.join(path, 'model')\n      else:\n        print('Cannot find export.meta or saved_model.pb, but continue with deployment anyway.')\n\n    body = {'name': self._model_name}\n    parent = 'projects/' + self._project_id\n    try:\n      self._api.projects().models().create(body=body, parent=parent).execute()\n    except:\n      # Trying to create an already existing model gets an error. Ignore it.\n      pass\n    body = {\n      'name': version_name,\n      'deployment_uri': path,\n    }\n\n    if runtime_version:\n      body['runtime_version'] = runtime_version\n\n    response = self._api.projects().models().versions().create(\n      body=body, parent=self._full_model_name).execute()\n    if 'name' not in response:\n      raise Exception('Invalid response from service. \"name\" is not found.')\n    _util.wait_for_long_running_operation(response['name'])\n\n  def delete(self, version_name):\n    \"\"\"Delete a version of model.\n\n    Args:\n      version_name: the name of the version in short form, such as \"v1\".\n    \"\"\"\n    name = ('%s/versions/%s' % (self._full_model_name, version_name))\n    response = self._api.projects().models().versions().delete(name=name).execute()\n    if 'name' not in response:\n      raise Exception('Invalid response from service. \"name\" is not found.')\n    _util.wait_for_long_running_operation(response['name'])\n\n  def predict(self, version_name, data):\n    \"\"\"Get prediction results from features instances.\n\n    Args:\n      version_name: the name of the version used for prediction.\n      data: typically a list of instance to be submitted for prediction. The format of the\n          instance depends on the model. For example, structured data model may require\n          a csv line for each instance.\n          Note that online prediction only works on models that take one placeholder value,\n          such as a string encoding a csv line.\n    Returns:\n      A list of prediction results for given instances. Each element is a dictionary representing\n          output mapping from the graph.\n      An example:\n        [{\"predictions\": 1, \"score\": [0.00078, 0.71406, 0.28515]},\n         {\"predictions\": 1, \"score\": [0.00244, 0.99634, 0.00121]}]\n    \"\"\"\n    full_version_name = ('%s/versions/%s' % (self._full_model_name, version_name))\n    request = self._api.projects().predict(body={'instances': data},\n                                           name=full_version_name)\n    request.headers['user-agent'] = 'GoogleCloudDataLab/1.0'\n    result = request.execute()\n    if 'predictions' not in result:\n      raise Exception('Invalid response from service. Cannot find \"predictions\" in response.')\n\n    return result['predictions']\n\n  def describe(self, version_name):\n    \"\"\"Print information of a specified model.\n\n    Args:\n      version: the name of the version in short form, such as \"v1\".\n    \"\"\"\n    version_yaml = yaml.safe_dump(self.get_version_details(version_name),\n                                  default_flow_style=False)\n    print(version_yaml)\n\n  def list(self):\n    \"\"\"List versions under the current model in a table view.\n\n    Raises:\n      Exception if it is called in a non-IPython environment.\n    \"\"\"\n    import IPython\n\n    # \"self\" is iterable (see __iter__() method).\n    data = [{'name': version['name'].split()[-1],\n             'deploymentUri': version['deploymentUri'], 'createTime': version['createTime']}\n            for version in self.get_iterator()]\n    IPython.display.display(\n        datalab.utils.commands.render_dictionary(data, ['name', 'deploymentUri', 'createTime']))\n"
  },
  {
    "path": "google/datalab/ml/_cloud_training_config.py",
    "content": "# Copyright 2017 Google Inc. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nfrom collections import namedtuple\n\n_CloudTrainingConfig = namedtuple(\"CloudConfig\",\n                                  ['region', 'scale_tier', 'master_type', 'worker_type',\n                                   'parameter_server_type', 'worker_count',\n                                   'parameter_server_count'])\n_CloudTrainingConfig.__new__.__defaults__ = ('BASIC', None, None, None, None, None)\n\n\nclass CloudTrainingConfig(_CloudTrainingConfig):\n    \"\"\"A config namedtuple containing cloud specific configurations for CloudML training.\n\n    Fields:\n      region: the region of the training job to be submitted. For example, \"us-central1\".\n          Run \"gcloud compute regions list\" to get a list of regions.\n      scale_tier: Specifies the machine types, the number of replicas for workers and\n          parameter servers. For example, \"STANDARD_1\". See\n          https://cloud.google.com/ml/reference/rest/v1beta1/projects.jobs#scaletier\n          for list of accepted values.\n      master_type: specifies the type of virtual machine to use for your training\n          job's master worker. Must set this value when scale_tier is set to CUSTOM.\n          See the link in \"scale_tier\".\n      worker_type: specifies the type of virtual machine to use for your training\n          job's worker nodes. Must set this value when scale_tier is set to CUSTOM.\n      parameter_server_type: specifies the type of virtual machine to use for your training\n          job's parameter server. Must set this value when scale_tier is set to CUSTOM.\n      worker_count: the number of worker replicas to use for the training job. Each\n          replica in the cluster will be of the type specified in \"worker_type\".\n          Must set this value when scale_tier is set to CUSTOM.\n      parameter_server_count: the number of parameter server replicas to use. Each\n          replica in the cluster will be of the type specified in \"parameter_server_type\".\n          Must set this value when scale_tier is set to CUSTOM.\n    \"\"\"\n    pass\n"
  },
  {
    "path": "google/datalab/ml/_confusion_matrix.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\nimport numpy as np\nimport itertools\nimport json\nimport matplotlib.pyplot as plt\nimport pandas as pd\nfrom sklearn.metrics import confusion_matrix\n\n\nimport google.datalab.bigquery as bq\n\nfrom . import _util\n\n\nclass ConfusionMatrix(object):\n  \"\"\"Represents a confusion matrix.\"\"\"\n\n  def __init__(self, cm, labels):\n    \"\"\"\n    Args:\n      cm: a 2-dimensional matrix with row index being target, column index being predicted,\n          and values being count.\n      labels: the labels whose order matches the row/column indexes.\n    \"\"\"\n    self._cm = cm\n    self._labels = labels\n\n  @staticmethod\n  def from_csv(input_csv, headers=None, schema_file=None):\n    \"\"\"Create a ConfusionMatrix from a csv file.\n\n    Args:\n      input_csv: Path to a Csv file (with no header). Can be local or GCS path.\n      headers: Csv headers. If present, it must include 'target' and 'predicted'.\n      schema_file: Path to a JSON file containing BigQuery schema. Used if \"headers\" is None.\n          If present, it must include 'target' and 'predicted' columns.\n    Returns:\n      A ConfusionMatrix that can be plotted.\n    Raises:\n      ValueError if both headers and schema_file are None, or it does not include 'target'\n          or 'predicted' columns.\n    \"\"\"\n\n    if headers is not None:\n      names = headers\n    elif schema_file is not None:\n      with _util.open_local_or_gcs(schema_file, mode='r') as f:\n        schema = json.load(f)\n      names = [x['name'] for x in schema]\n    else:\n      raise ValueError('Either headers or schema_file is needed')\n\n    all_files = _util.glob_files(input_csv)\n    all_df = []\n    for file_name in all_files:\n      with _util.open_local_or_gcs(file_name, mode='r') as f:\n        all_df.append(pd.read_csv(f, names=names))\n    df = pd.concat(all_df, ignore_index=True)\n\n    if 'target' not in df or 'predicted' not in df:\n      raise ValueError('Cannot find \"target\" or \"predicted\" column')\n\n    labels = sorted(set(df['target']) | set(df['predicted']))\n    cm = confusion_matrix(df['target'], df['predicted'], labels=labels)\n    return ConfusionMatrix(cm, labels)\n\n  @staticmethod\n  def from_bigquery(sql):\n    \"\"\"Create a ConfusionMatrix from a BigQuery table or query.\n\n    Args:\n      sql: Can be one of:\n          A SQL query string.\n          A Bigquery table string.\n          A Query object defined with '%%bq query --name [query_name]'.\n      The query results or table must include \"target\", \"predicted\" columns.\n    Returns:\n      A ConfusionMatrix that can be plotted.\n    Raises:\n      ValueError if query results or table does not include 'target' or 'predicted' columns.\n    \"\"\"\n    if isinstance(sql, bq.Query):\n      sql = sql._expanded_sql()\n\n    parts = sql.split('.')\n    if len(parts) == 1 or len(parts) > 3 or any(' ' in x for x in parts):\n      sql = '(' + sql + ')'  # query, not a table name\n    else:\n      sql = '`' + sql + '`'  # table name\n\n    query = bq.Query(\n        'SELECT target, predicted, count(*) as count FROM %s group by target, predicted' % sql)\n    df = query.execute().result().to_dataframe()\n    labels = sorted(set(df['target']) | set(df['predicted']))\n    labels_count = len(labels)\n    df['target'] = [labels.index(x) for x in df['target']]\n    df['predicted'] = [labels.index(x) for x in df['predicted']]\n    cm = [[0] * labels_count for i in range(labels_count)]\n    for index, row in df.iterrows():\n      cm[row['target']][row['predicted']] = row['count']\n    return ConfusionMatrix(cm, labels)\n\n  def to_dataframe(self):\n    \"\"\"Convert the confusion matrix to a dataframe.\n\n    Returns:\n      A DataFrame with \"target\", \"predicted\", \"count\" columns.\n    \"\"\"\n\n    data = []\n    for target_index, target_row in enumerate(self._cm):\n      for predicted_index, count in enumerate(target_row):\n        data.append((self._labels[target_index], self._labels[predicted_index], count))\n\n    return pd.DataFrame(data, columns=['target', 'predicted', 'count'])\n\n  def plot(self, figsize=None, rotation=45):\n    \"\"\"Plot the confusion matrix.\n\n    Args:\n      figsize: tuple (x, y) of ints. Sets the size of the figure\n      rotation: the rotation angle of the labels on the x-axis.\n    \"\"\"\n\n    fig, ax = plt.subplots(figsize=figsize)\n\n    plt.imshow(self._cm, interpolation='nearest', cmap=plt.cm.Blues, aspect='auto')\n    plt.title('Confusion matrix')\n    plt.colorbar()\n    tick_marks = np.arange(len(self._labels))\n    plt.xticks(tick_marks, self._labels, rotation=rotation)\n    plt.yticks(tick_marks, self._labels)\n    if isinstance(self._cm, list):\n      # If cm is created from BigQuery then it is a list.\n      thresh = max(max(self._cm)) / 2.\n      for i, j in itertools.product(range(len(self._labels)), range(len(self._labels))):\n        plt.text(j, i, self._cm[i][j], horizontalalignment=\"center\",\n                 color=\"white\" if self._cm[i][j] > thresh else \"black\")\n    else:\n      # If cm is created from csv then it is a sklearn's confusion_matrix.\n      thresh = self._cm.max() / 2.\n      for i, j in itertools.product(range(len(self._labels)), range(len(self._labels))):\n        plt.text(j, i, self._cm[i, j], horizontalalignment=\"center\",\n                 color=\"white\" if self._cm[i, j] > thresh else \"black\")\n    plt.tight_layout()\n    plt.ylabel('True label')\n    plt.xlabel('Predicted label')\n"
  },
  {
    "path": "google/datalab/ml/_dataset.py",
    "content": "# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\n\"\"\"Implements DataSets that serve two purposes:\n\n1. Recommended way to pass data source to ML packages.\n2. All DataSets can be sampled into dataframe for analysis/visualization.\n\"\"\"\n\nimport json\nimport numpy as np\nimport pandas as pd\nimport random\nimport six\n\nimport google.datalab.bigquery as bq\n\nfrom . import _util\n\n\nclass CsvDataSet(object):\n  \"\"\"DataSet based on CSV files and schema.\"\"\"\n\n  def __init__(self, file_pattern, schema=None, schema_file=None):\n    \"\"\"\n\n    Args:\n      file_pattern: A list of CSV files. or a string. Can contain wildcards in\n        file names. Can be local or GCS path.\n      schema: A google.datalab.bigquery.Schema object, or a json schema in the form of\n        [{'name': 'col1', 'type': 'STRING'},\n        {'name': 'col2', 'type': 'INTEGER'}]\n        or a single string in of the form 'col1:STRING,col2:INTEGER,col3:FLOAT'.\n      schema_file: A JSON serialized schema file. If schema is None, it will try to load from\n        schema_file if not None.\n    Raise:\n      ValueError if both schema and schema_file are None.\n    \"\"\"\n    if schema is None and schema_file is None:\n      raise ValueError('schema and schema_file cannot both be None.')\n\n    if schema is not None:\n      # This check needs to come before list check, because Schema\n      # is a subclass of list\n      if isinstance(schema, bq.Schema):\n        self._schema = schema._bq_schema\n      elif isinstance(schema, list):\n        self._schema = schema\n      else:\n        self._schema = []\n        for x in schema.split(','):\n          parts = x.split(':')\n          if len(parts) != 2:\n            raise ValueError('invalid schema string \"%s\"' % x)\n          self._schema.append({'name': parts[0].strip(), 'type': parts[1].strip()})\n    else:\n      self._schema = json.loads(_util.read_file_to_string(schema_file))\n\n    if isinstance(file_pattern, six.string_types):\n      file_pattern = [file_pattern]\n    self._input_files = file_pattern\n\n    self._glob_files = []\n    self._size = None\n\n  @property\n  def input_files(self):\n    \"\"\"Returns the file list that was given to this class without globing files.\"\"\"\n    return self._input_files\n\n  @property\n  def files(self):\n    if not self._glob_files:\n      for file in self._input_files:\n        # glob_files() returns unicode strings which doesn't make DataFlow happy. So str().\n        self._glob_files += [str(x) for x in _util.glob_files(file)]\n\n    return self._glob_files\n\n  @property\n  def schema(self):\n    return self._schema\n\n  @property\n  def size(self):\n    \"\"\"The size of the schema. If the underlying data source changes, it may be outdated.\n    \"\"\"\n    if self._size is None:\n      self._size = 0\n      for csv_file in self.files:\n        self._size += sum(1 if line else 0 for line in _util.open_local_or_gcs(csv_file, 'r'))\n\n    return self._size\n\n  def sample(self, n):\n    \"\"\" Samples data into a Pandas DataFrame.\n    Args:\n      n: number of sampled counts.\n    Returns:\n      A dataframe containing sampled data.\n    Raises:\n      Exception if n is larger than number of rows.\n    \"\"\"\n\n    row_total_count = 0\n    row_counts = []\n    for file in self.files:\n      with _util.open_local_or_gcs(file, 'r') as f:\n        num_lines = sum(1 for line in f)\n        row_total_count += num_lines\n        row_counts.append(num_lines)\n\n    names = None\n    dtype = None\n    if self._schema:\n      _MAPPINGS = {\n        'FLOAT': np.float64,\n        'INTEGER': np.int64,\n        'TIMESTAMP': np.datetime64,\n        'BOOLEAN': np.bool,\n      }\n      names = [x['name'] for x in self._schema]\n      dtype = {x['name']: _MAPPINGS.get(x['type'], object) for x in self._schema}\n\n    skip_count = row_total_count - n\n    # Get all skipped indexes. These will be distributed into each file.\n    # Note that random.sample will raise Exception if skip_count is greater than rows count.\n    skip_all = sorted(random.sample(range(0, row_total_count), skip_count))\n    dfs = []\n    for file, row_count in zip(self.files, row_counts):\n      skip = [x for x in skip_all if x < row_count]\n      skip_all = [x - row_count for x in skip_all if x >= row_count]\n      with _util.open_local_or_gcs(file, 'r') as f:\n        dfs.append(pd.read_csv(f, skiprows=skip, names=names, dtype=dtype, header=None))\n    return pd.concat(dfs, axis=0, ignore_index=True)\n\n\nclass BigQueryDataSet(object):\n  \"\"\"DataSet based on BigQuery table or query.\"\"\"\n\n  def __init__(self, sql=None, table=None):\n    \"\"\"\n    Args:\n      sql: A SQL query string, or a SQL Query module defined with '%%bq query --name [query_name]'\n      table: A table name in the form of 'dataset.table or project.dataset.table'.\n    Raises:\n      ValueError if both sql and table are set, or both are None.\n    \"\"\"\n    if (sql is None and table is None) or (sql is not None and table is not None):\n      raise ValueError('One and only one of sql and table should be set.')\n\n    self._query = sql._expanded_sql() if isinstance(sql, bq.Query) else sql\n    self._table = table\n    self._schema = None\n    self._size = None\n\n  @property\n  def query(self):\n    return self._query\n\n  @property\n  def table(self):\n    return self._table\n\n  def _get_source(self):\n    if self._query is not None:\n      return '(' + self._query + ')'\n    return '`' + self._table + '`'\n\n  @property\n  def schema(self):\n    if self._schema is None:\n      self._schema = bq.Query('SELECT * FROM %s LIMIT 1' %\n                              self._get_source()).execute().result().schema\n    return self._schema._bq_schema\n\n  @property\n  def size(self):\n    \"\"\"The size of the schema. If the underlying data source changes, it may be outdated.\n    \"\"\"\n    if self._size is None:\n      self._size = bq.Query('SELECT COUNT(*) FROM %s' %\n                            self._get_source()).execute().result()[0].values()[0]\n    return self._size\n\n  def sample(self, n):\n    \"\"\"Samples data into a Pandas DataFrame. Note that it calls BigQuery so it will\n       incur cost.\n\n    Args:\n      n: number of sampled counts. Note that the number of counts returned is approximated.\n    Returns:\n      A dataframe containing sampled data.\n    Raises:\n      Exception if n is larger than number of rows.\n    \"\"\"\n    total = bq.Query('select count(*) from %s' %\n                     self._get_source()).execute().result()[0].values()[0]\n    if n > total:\n      raise ValueError('sample larger than population')\n    sampling = bq.Sampling.random(percent=n * 100.0 / float(total))\n    if self._query is not None:\n      source = self._query\n    else:\n      source = 'SELECT * FROM `%s`' % self._table\n    sample = bq.Query(source).execute(sampling=sampling).result()\n    df = sample.to_dataframe()\n    return df\n\n\nclass TransformedDataSet(object):\n  \"\"\"DataSet based on tf.example.\"\"\"\n\n  def __init__(self, file_pattern):\n    \"\"\"\n\n    Args:\n      file_pattern: A list of gzip TF Example files. or a string. Can contain wildcards in\n          file names. Can be local or GCS path.\n    \"\"\"\n    if isinstance(file_pattern, six.string_types):\n      file_pattern = [file_pattern]\n    self._input_files = file_pattern\n    self._glob_files = []\n    self._size = None\n\n  @property\n  def input_files(self):\n    \"\"\"Returns the file list that was given to this class without globing files.\"\"\"\n    return self._input_files\n\n  @property\n  def files(self):\n    if not self._glob_files:\n      for file in self._input_files:\n        # glob_files() returns unicode strings which doesn't make DataFlow happy. So str().\n        self._glob_files += [str(x) for x in _util.glob_files(file)]\n\n    return self._glob_files\n\n  @property\n  def size(self):\n    \"\"\"The number of instances in the data. If the underlying data source changes,\n       it may be outdated.\n    \"\"\"\n    import tensorflow as tf\n\n    if self._size is None:\n      self._size = 0\n      options = tf.python_io.TFRecordOptions(tf.python_io.TFRecordCompressionType.GZIP)\n      for tfexample_file in self.files:\n        self._size += sum(1 for x\n                          in tf.python_io.tf_record_iterator(tfexample_file, options=options))\n\n    return self._size\n"
  },
  {
    "path": "google/datalab/ml/_fasets.py",
    "content": "# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\nimport base64\nimport google.datalab as datalab\nfrom google.datalab.utils.facets.generic_feature_statistics_generator \\\n    import GenericFeatureStatisticsGenerator\nimport numpy as np\nimport pandas as pd\nimport re\nimport six\n\n\nclass FacetsOverview(object):\n  \"\"\"Represents A facets overview. \"\"\"\n\n  def _remove_nonascii(self, df):\n    \"\"\"Make copy and remove non-ascii characters from it.\"\"\"\n\n    df_copy = df.copy(deep=True)\n    for col in df_copy.columns:\n      if (df_copy[col].dtype == np.dtype('O')):\n        df_copy[col] = df[col].apply(\n          lambda x: re.sub(r'[^\\x00-\\x7f]', r'', x) if isinstance(x, six.string_types) else x)\n\n    return df_copy\n\n  def plot(self, data):\n    \"\"\" Plots an overview in a list of dataframes\n\n    Args:\n      data: a dictionary with key the name, and value the dataframe.\n    \"\"\"\n\n    import IPython\n\n    if not isinstance(data, dict) or not all(isinstance(v, pd.DataFrame) for v in data.values()):\n      raise ValueError('Expect a dictionary where the values are all dataframes.')\n\n    gfsg = GenericFeatureStatisticsGenerator()\n    data = [{'name': k, 'table': self._remove_nonascii(v)} for k, v in six.iteritems(data)]\n    data_proto = gfsg.ProtoFromDataFrames(data)\n    protostr = base64.b64encode(data_proto.SerializeToString()).decode(\"utf-8\")\n    html_id = 'f' + datalab.utils.commands.Html.next_id()\n\n    HTML_TEMPLATE = \"\"\"<link rel=\"import\" href=\"/nbextensions/gcpdatalab/extern/facets-jupyter.html\" >\n        <facets-overview id=\"{html_id}\"></facets-overview>\n        <script>\n          document.querySelector(\"#{html_id}\").protoInput = \"{protostr}\";\n        </script>\"\"\"\n    html = HTML_TEMPLATE.format(html_id=html_id, protostr=protostr)\n    return IPython.core.display.HTML(html)\n\n\nclass FacetsDiveview(object):\n  \"\"\"Represents A facets overview. \"\"\"\n\n  def plot(self, data, height=1000, render_large_data=False):\n    \"\"\" Plots a detail view of data.\n\n    Args:\n      data: a Pandas dataframe.\n      height: the height of the output.\n    \"\"\"\n\n    import IPython\n\n    if not isinstance(data, pd.DataFrame):\n      raise ValueError('Expect a DataFrame.')\n\n    if (len(data) > 10000 and not render_large_data):\n      raise ValueError('Facets dive may not work well with more than 10000 rows. ' +\n                       'Reduce data or set \"render_large_data\" to True.')\n\n    jsonstr = data.to_json(orient='records')\n    html_id = 'f' + datalab.utils.commands.Html.next_id()\n    HTML_TEMPLATE = \"\"\"\n        <link rel=\"import\" href=\"/nbextensions/gcpdatalab/extern/facets-jupyter.html\">\n        <facets-dive id=\"{html_id}\" height=\"{height}\"></facets-dive>\n        <script>\n          var data = {jsonstr};\n          document.querySelector(\"#{html_id}\").data = data;\n        </script>\"\"\"\n    html = HTML_TEMPLATE.format(html_id=html_id, jsonstr=jsonstr, height=height)\n    return IPython.core.display.HTML(html)\n"
  },
  {
    "path": "google/datalab/ml/_feature_slice_view.py",
    "content": "# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nimport json\nimport pandas as pd\nimport sys\n\nimport google.datalab as datalab\nimport google.datalab.bigquery as bq\n\n\nclass FeatureSliceView(object):\n  \"\"\"Represents A feature slice view.\"\"\"\n\n  def _get_lantern_format(self, df):\n    \"\"\" Feature slice view browser expects data in the format of:\n          {\"metricValues\": {\"count\": 12, \"accuracy\": 1.0}, \"feature\": \"species:Iris-setosa\"}\n          {\"metricValues\": {\"count\": 11, \"accuracy\": 0.72}, \"feature\": \"species:Iris-versicolor\"}\n          ...\n        This function converts a DataFrame to such format.\n    \"\"\"\n\n    if ('count' not in df) or ('feature' not in df):\n      raise Exception('No \"count\" or \"feature\" found in data.')\n    if len(df.columns) < 3:\n      raise Exception('Need at least one metrics column.')\n    if len(df) == 0:\n      raise Exception('Data is empty')\n\n    data = []\n    for _, row in df.iterrows():\n      metric_values = dict(row)\n      feature = metric_values.pop('feature')\n      data.append({'feature': feature, 'metricValues': metric_values})\n    return data\n\n  def plot(self, data):\n    \"\"\" Plots a featire slice view on given data.\n\n    Args:\n      data: Can be one of:\n          A string of sql query.\n          A sql query module defined by \"%%sql --module module_name\".\n          A pandas DataFrame.\n        Regardless of data type, it must include the following columns:\n          \"feature\": identifies a slice of features. For example: \"petal_length:4.0-4.2\".\n          \"count\": number of instances in that slice of features.\n        All other columns are viewed as metrics for its feature slice. At least one is required.\n    \"\"\"\n    import IPython\n\n    if ((sys.version_info.major > 2 and isinstance(data, str)) or\n       (sys.version_info.major <= 2 and isinstance(data, basestring))):\n      data = bq.Query(data)\n\n    if isinstance(data, bq.Query):\n      df = data.execute().result().to_dataframe()\n      data = self._get_lantern_format(df)\n    elif isinstance(data, pd.core.frame.DataFrame):\n      data = self._get_lantern_format(data)\n    else:\n      raise Exception('data needs to be a sql query, or a pandas DataFrame.')\n\n    HTML_TEMPLATE = \"\"\"<link rel=\"import\" href=\"/nbextensions/gcpdatalab/extern/lantern-browser.html\" >\n        <lantern-browser id=\"{html_id}\"></lantern-browser>\n        <script>\n        var browser = document.querySelector('#{html_id}');\n        browser.metrics = {metrics};\n        browser.data = {data};\n        browser.sourceType = 'colab';\n        browser.weightedExamplesColumn = 'count';\n        browser.calibrationPlotUriFn = function(s) {{ return '/' + s; }}\n        </script>\"\"\"\n    # Serialize the data and list of metrics names to JSON string.\n    metrics_str = str(map(str, data[0]['metricValues'].keys()))\n    data_str = str([{str(k): json.dumps(v) for k, v in elem.iteritems()} for elem in data])\n    html_id = 'l' + datalab.utils.commands.Html.next_id()\n    html = HTML_TEMPLATE.format(html_id=html_id, metrics=metrics_str, data=data_str)\n    IPython.display.display(IPython.display.HTML(html))\n"
  },
  {
    "path": "google/datalab/ml/_job.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Implements Cloud ML Operation wrapper.\"\"\"\n\n\nimport six\nimport google.datalab as datalab\nfrom googleapiclient import discovery\nimport yaml\nimport datetime\n\n\nclass Job(datalab.Job):\n  \"\"\"Represents a Cloud ML job.\"\"\"\n\n  def __init__(self, name, context=None):\n    \"\"\"Initializes an instance of a CloudML Job.\n\n    Args:\n      name: the name of the job. It can be an operation full name\n          (\"projects/[project_id]/jobs/[operation_name]\") or just [operation_name].\n      context: an optional Context object providing project_id and credentials.\n    \"\"\"\n    super(Job, self).__init__(name)\n    if context is None:\n      context = datalab.Context.default()\n    self._context = context\n    self._api = discovery.build('ml', 'v1', credentials=self._context.credentials)\n    if not name.startswith('projects/'):\n      name = 'projects/' + self._context.project_id + '/jobs/' + name\n    self._name = name\n    self._refresh_state()\n\n  def _refresh_state(self):\n    \"\"\" Refresh the job info. \"\"\"\n    self._info = self._api.projects().jobs().get(name=self._name).execute()\n    self._fatal_error = self._info.get('errorMessage', None)\n    state = str(self._info.get('state'))\n    self._is_complete = (state == 'SUCCEEDED' or state == 'FAILED')\n\n  @property\n  def info(self):\n    self._refresh_state()\n    return self._info\n\n  def describe(self):\n    self._refresh_state()\n    job_yaml = yaml.safe_dump(self._info, default_flow_style=False)\n    print(job_yaml)\n\n  @staticmethod\n  def submit_training(job_request, job_id=None):\n    \"\"\"Submit a training job.\n\n    Args:\n      job_request: the arguments of the training job in a dict. For example,\n          {\n            'package_uris':  'gs://my-bucket/iris/trainer-0.1.tar.gz',\n            'python_module': 'trainer.task',\n            'scale_tier': 'BASIC',\n            'region': 'us-central1',\n            'args': {\n              'train_data_paths': ['gs://mubucket/data/features_train'],\n              'eval_data_paths': ['gs://mubucket/data/features_eval'],\n              'metadata_path': 'gs://mubucket/data/metadata.yaml',\n              'output_path': 'gs://mubucket/data/mymodel/',\n            }\n          }\n          If 'args' is present in job_request and is a dict, it will be expanded to\n          --key value or --key list_item_0 --key list_item_1, ...\n      job_id: id for the training job. If None, an id based on timestamp will be generated.\n    Returns:\n      A Job object representing the cloud training job.\n    \"\"\"\n    new_job_request = dict(job_request)\n    # convert job_args from dict to list as service required.\n    if 'args' in job_request and isinstance(job_request['args'], dict):\n      job_args = job_request['args']\n      args = []\n      for k, v in six.iteritems(job_args):\n        if isinstance(v, list):\n          for item in v:\n            args.append('--' + str(k))\n            args.append(str(item))\n        else:\n          args.append('--' + str(k))\n          args.append(str(v))\n      new_job_request['args'] = args\n\n    if job_id is None:\n      job_id = datetime.datetime.now().strftime('%y%m%d_%H%M%S')\n      if 'python_module' in new_job_request:\n        job_id = new_job_request['python_module'].replace('.', '_') + \\\n            '_' + job_id\n\n    job = {\n        'job_id': job_id,\n        'training_input': new_job_request,\n    }\n    context = datalab.Context.default()\n    cloudml = discovery.build('ml', 'v1', credentials=context.credentials)\n    request = cloudml.projects().jobs().create(body=job,\n                                               parent='projects/' + context.project_id)\n    request.headers['user-agent'] = 'GoogleCloudDataLab/1.0'\n    request.execute()\n    return Job(job_id)\n\n  @staticmethod\n  def submit_batch_prediction(job_request, job_id=None):\n    \"\"\"Submit a batch prediction job.\n\n    Args:\n      job_request: the arguments of the training job in a dict. For example,\n          {\n            'version_name': 'projects/my-project/models/my-model/versions/my-version',\n            'data_format': 'TEXT',\n            'input_paths': ['gs://my_bucket/my_file.csv'],\n            'output_path': 'gs://my_bucket/predict_output',\n            'region': 'us-central1',\n            'max_worker_count': 1,\n          }\n      job_id: id for the training job. If None, an id based on timestamp will be generated.\n\n    Returns:\n      A Job object representing the batch prediction job.\n    \"\"\"\n\n    if job_id is None:\n      job_id = 'prediction_' + datetime.datetime.now().strftime('%y%m%d_%H%M%S')\n\n    job = {\n        'job_id': job_id,\n        'prediction_input': job_request,\n    }\n    context = datalab.Context.default()\n    cloudml = discovery.build('ml', 'v1', credentials=context.credentials)\n    request = cloudml.projects().jobs().create(body=job,\n                                               parent='projects/' + context.project_id)\n    request.headers['user-agent'] = 'GoogleCloudDataLab/1.0'\n    request.execute()\n    return Job(job_id)\n\n\nclass Jobs(object):\n  \"\"\"Represents a list of Cloud ML jobs for a project.\"\"\"\n\n  def __init__(self, filter=None):\n    \"\"\"Initializes an instance of a CloudML Job list that is iteratable (\"for job in jobs()\").\n\n    Args:\n      filter: filter string for retrieving jobs, such as \"state=FAILED\"\n      context: an optional Context object providing project_id and credentials.\n      api: an optional CloudML API client.\n    \"\"\"\n    self._filter = filter\n    self._context = datalab.Context.default()\n    self._api = discovery.build('ml', 'v1', credentials=self._context.credentials)\n    self._page_size = 0\n\n  def _retrieve_jobs(self, page_token, _):\n    list_info = self._api.projects().jobs().list(parent='projects/' + self._context.project_id,\n                                                 pageToken=page_token, pageSize=self._page_size,\n                                                 filter=self._filter).execute()\n    jobs = list_info.get('jobs', [])\n    self._page_size = self._page_size or len(jobs)\n    page_token = list_info.get('nextPageToken', None)\n    return jobs, page_token\n\n  def get_iterator(self):\n    \"\"\"Get iterator of jobs so it can be used as \"for model in Jobs().get_iterator()\".\n    \"\"\"\n    return iter(datalab.utils.Iterator(self._retrieve_jobs))\n\n  def list(self, count=10):\n    import IPython\n    data = [{'Id': job['jobId'], 'State': job.get('state', 'UNKNOWN'),\n             'createTime': job['createTime']}\n            for _, job in zip(range(count), self)]\n    IPython.display.display(\n        datalab.utils.commands.render_dictionary(data, ['Id', 'State', 'createTime']))\n"
  },
  {
    "path": "google/datalab/ml/_metrics.py",
    "content": "# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\nimport json\nimport math\nimport numpy as np\nimport pandas as pd\nfrom sklearn.metrics import mean_squared_error, mean_absolute_error\n\nimport google.datalab.bigquery as bq\n\nfrom . import _util\n\n\nclass Metrics(object):\n  \"\"\"Represents a Metrics object that computes metrics from raw evaluation results.\"\"\"\n\n  def __init__(self, input_csv_pattern=None, headers=None, bigquery=None):\n    \"\"\"\n    Args:\n      input_csv_pattern: Path to Csv file pattern (with no header). Can be local or GCS path.\n      headers: Csv headers. Required if input_csv_pattern is not None.\n      bigquery: Can be one of:\n          A BigQuery query string.\n          A Bigquery table string.\n          A Query object defined with '%%bq query --name [query_name]'.\n\n    Raises:\n      ValueError if input_csv_pattern is provided but both headers and schema_file are None.\n      ValueError if but both input_csv_pattern and bigquery are None.\n    \"\"\"\n\n    self._input_csv_files = None\n    self._bigquery = None\n    if input_csv_pattern:\n      self._input_csv_files = _util.glob_files(input_csv_pattern)\n      if not headers:\n        raise ValueError('csv requires headers.')\n      self._headers = headers\n    elif bigquery:\n      self._bigquery = bigquery\n    else:\n      raise ValueError('Either input_csv_pattern or bigquery needs to be provided.')\n\n  @staticmethod\n  def from_csv(input_csv_pattern, headers=None, schema_file=None):\n    \"\"\"Create a Metrics instance from csv file pattern.\n\n    Args:\n      input_csv_pattern: Path to Csv file pattern (with no header). Can be local or GCS path.\n      headers: Csv headers.\n      schema_file: Path to a JSON file containing BigQuery schema. Used if \"headers\" is None.\n\n    Returns:\n      a Metrics instance.\n\n    Raises:\n      ValueError if both headers and schema_file are None.\n    \"\"\"\n\n    if headers is not None:\n      names = headers\n    elif schema_file is not None:\n      with _util.open_local_or_gcs(schema_file, mode='r') as f:\n        schema = json.load(f)\n      names = [x['name'] for x in schema]\n    else:\n      raise ValueError('Either headers or schema_file is needed')\n\n    metrics = Metrics(input_csv_pattern=input_csv_pattern, headers=names)\n    return metrics\n\n  @staticmethod\n  def from_bigquery(sql):\n    \"\"\"Create a Metrics instance from a bigquery query or table.\n\n    Returns:\n      a Metrics instance.\n\n    Args:\n      sql: A BigQuery table name or a query.\n    \"\"\"\n\n    if isinstance(sql, bq.Query):\n      sql = sql._expanded_sql()\n\n    parts = sql.split('.')\n    if len(parts) == 1 or len(parts) > 3 or any(' ' in x for x in parts):\n      sql = '(' + sql + ')'  # query, not a table name\n    else:\n      sql = '`' + sql + '`'  # table name\n\n    metrics = Metrics(bigquery=sql)\n    return metrics\n\n  def _get_data_from_csv_files(self):\n    \"\"\"Get data from input csv files.\"\"\"\n\n    all_df = []\n    for file_name in self._input_csv_files:\n      with _util.open_local_or_gcs(file_name, mode='r') as f:\n        all_df.append(pd.read_csv(f, names=self._headers))\n    df = pd.concat(all_df, ignore_index=True)\n    return df\n\n  def _get_data_from_bigquery(self, queries):\n    \"\"\"Get data from bigquery table or query.\"\"\"\n\n    all_df = []\n    for query in queries:\n      all_df.append(query.execute().result().to_dataframe())\n    df = pd.concat(all_df, ignore_index=True)\n    return df\n\n  def accuracy(self):\n    \"\"\"Get accuracy numbers for each target and overall.\n\n    Returns:\n      A DataFrame with two columns: 'class' and 'accuracy'. It also contains the overall\n      accuracy with class being '_all'.\n\n    Raises:\n      Exception if the CSV headers do not include 'target' or 'predicted', or BigQuery\n      does not return 'target' or 'predicted' column.\n    \"\"\"\n\n    if self._input_csv_files:\n      df = self._get_data_from_csv_files()\n      if 'target' not in df or 'predicted' not in df:\n        raise ValueError('Cannot find \"target\" or \"predicted\" column')\n\n      labels = sorted(set(df['target']) | set(df['predicted']))\n      accuracy_results = []\n\n      for label in labels:\n        correct_count = len(df[(df['target'] == df['predicted']) & (df['target'] == label)])\n        total_count = len(df[(df['target'] == label)])\n        accuracy_results.append({\n            'target': label,\n            'accuracy': float(correct_count) / total_count if total_count > 0 else 0,\n            'count': total_count\n        })\n\n      total_correct_count = len(df[(df['target'] == df['predicted'])])\n      if len(df) > 0:\n        total_accuracy = float(total_correct_count) / len(df)\n        accuracy_results.append({'target': '_all', 'accuracy': total_accuracy, 'count': len(df)})\n      return pd.DataFrame(accuracy_results)\n    elif self._bigquery:\n      query = bq.Query(\"\"\"\nSELECT\n  target,\n  SUM(CASE WHEN target=predicted THEN 1 ELSE 0 END)/COUNT(*) as accuracy,\n  COUNT(*) as count\nFROM\n  %s\nGROUP BY\n  target\"\"\" % self._bigquery)\n      query_all = bq.Query(\"\"\"\nSELECT\n  \"_all\" as target,\n  SUM(CASE WHEN target=predicted THEN 1 ELSE 0 END)/COUNT(*) as accuracy,\n  COUNT(*) as count\nFROM\n  %s\"\"\" % self._bigquery)\n\n      df = self._get_data_from_bigquery([query, query_all])\n      return df\n\n  def roc(self, num_thresholds, target_class, probability_column=None):\n    \"\"\"Get true positive rate, false positive rate values from evaluation results.\n\n    Args:\n      num_thresholds: an integer. Number of thresholds.\n      target_class: a string indciating the target class, i.e. \"daisy\" in flower classification.\n      probability_column: the name of the probability column. If None, defaults to\n          value of target_class.\n\n    Returns:\n      A DataFrame with columns: 'tpr', 'fpr', 'threshold' with number of rows\n      equal to num_thresholds.\n\n    Raises:\n      Exception if the CSV headers do not include 'target' or probability_column, or BigQuery\n      does not return 'target' or probability_column column.\n    \"\"\"\n\n    if not probability_column:\n      probability_column = target_class\n\n    thresholds = np.linspace(0, 1, num_thresholds + 1)\n    if self._input_csv_files:\n      df = self._get_data_from_csv_files()\n      if 'target' not in df or probability_column not in df:\n        raise ValueError('Cannot find \"target\" or \"%s\" column' % probability_column)\n\n      total_positive = sum(1 for x in df['target'] if x == target_class)\n      total_negative = len(df) - total_positive\n      true_positives, false_positives = [], []\n      for threshold in thresholds:\n        true_positive_count = len(df[(df[probability_column] > threshold) &\n                                  (df['target'] == target_class)])\n        false_positive_count = len(df[(df[probability_column] > threshold) &\n                                   (df['target'] != target_class)])\n        true_positives.append(true_positive_count)\n        false_positives.append(false_positive_count)\n\n      data = []\n      for tp, fp, t in zip(true_positives, false_positives, thresholds):\n        tpr = (float)(tp) / total_positive if total_positive > 0. else 0.\n        fpr = (float)(fp) / total_negative if total_negative > 0. else 0.\n        data.append({'tpr': tpr, 'fpr': fpr, 'threshold': t})\n      return pd.DataFrame(data)\n\n    elif self._bigquery:\n      true_positive_query = bq.Query(\"\"\"\n        SELECT\n          COUNT(*) as true_positive\n        FROM\n          %s\n        CROSS JOIN\n          (SELECT * FROM UNNEST ([%s]) as t)\n        WHERE\n          %s > t AND target = '%s'\n        GROUP BY t\n        ORDER BY t\n      \"\"\" % (self._bigquery, ','.join(map(str, thresholds)), probability_column, target_class))\n\n      false_positive_query = bq.Query(\"\"\"\n        SELECT\n          COUNT(*) as false_positive\n        FROM\n          %s\n        CROSS JOIN\n          (SELECT * FROM UNNEST ([%s]) as t)\n        WHERE\n          %s > t AND target != '%s'\n        GROUP BY t\n        ORDER BY t\n      \"\"\" % (self._bigquery, ','.join(map(str, thresholds)), probability_column, target_class))\n\n      total_positive_query = bq.Query(\"\"\"\n        SELECT\n          COUNT(*) as total_positive\n        FROM\n          %s\n        WHERE\n          target = '%s'\n      \"\"\" % (self._bigquery, target_class))\n\n      total_negative_query = bq.Query(\"\"\"\n        SELECT\n          COUNT(*) as total_negative\n        FROM\n          %s\n        WHERE\n          target != '%s'\n      \"\"\" % (self._bigquery, target_class))\n\n      true_positives = true_positive_query.execute().result()\n      false_positives = false_positive_query.execute().result()\n      total_positive = total_positive_query.execute().result()[0]['total_positive']\n      total_negative = total_negative_query.execute().result()[0]['total_negative']\n      data = []\n      for tp, fp, t in zip(true_positives, false_positives, thresholds):\n        tpr = (float)(tp['true_positive']) / total_positive if total_positive > 0. else 0.\n        fpr = (float)(fp['false_positive']) / total_negative if total_negative > 0. else 0.\n        data.append({'tpr': tpr, 'fpr': fpr, 'threshold': t})\n      data.append({'tpr': 0., 'fpr': 0., 'threshold': 1.0})\n      return pd.DataFrame(data)\n\n  def precision_recall(self, num_thresholds, target_class, probability_column=None):\n    \"\"\"Get precision, recall values from evaluation results.\n\n    Args:\n      num_thresholds: an integer. Number of thresholds.\n      target_class: a string indciating the target class, i.e. \"daisy\" in flower classification.\n      probability_column: the name of the probability column. If None, defaults to\n          value of target_class.\n\n    Returns:\n      A DataFrame with columns: 'threshold', 'precision', 'recall' with number of rows\n      equal to num_thresholds.\n\n    Raises:\n      Exception if the CSV headers do not include 'target' or probability_column, or BigQuery\n      does not return 'target' or probability_column column.\n    \"\"\"\n\n    if not probability_column:\n      probability_column = target_class\n\n    # threshold = 1.0 is excluded.\n    thresholds = np.linspace(0, 1, num_thresholds + 1)[0:-1]\n    if self._input_csv_files:\n      df = self._get_data_from_csv_files()\n      if 'target' not in df or probability_column not in df:\n        raise ValueError('Cannot find \"target\" or \"%s\" column' % probability_column)\n\n      total_target = sum(1 for x in df['target'] if x == target_class)\n      total_predicted = []\n      correct_predicted = []\n      for threshold in thresholds:\n        predicted_count = sum(1 for x in df[probability_column] if x > threshold)\n        total_predicted.append(predicted_count)\n        correct_count = len(df[(df[probability_column] > threshold) &\n                            (df['target'] == target_class)])\n        correct_predicted.append(correct_count)\n\n      data = []\n      for p, c, t in zip(total_predicted, correct_predicted, thresholds):\n        precision = (float)(c) / p if p > 0. else 0.\n        recall = (float)(c) / total_target if total_target > 0. else 0.\n        data.append({'precision': precision, 'recall': recall, 'threshold': t})\n      return pd.DataFrame(data)\n\n    elif self._bigquery:\n      total_predicted_query = bq.Query(\"\"\"\n        SELECT\n          COUNT(*) as total_predicted\n        FROM\n          %s\n        CROSS JOIN\n          (SELECT * FROM UNNEST ([%s]) as t)\n        WHERE\n          %s > t\n        GROUP BY t\n        ORDER BY t\n      \"\"\" % (self._bigquery, ','.join(map(str, thresholds)), probability_column))\n\n      correct_predicted_query = bq.Query(\"\"\"\n        SELECT\n          COUNT(*) as correct_predicted\n        FROM\n          %s\n        CROSS JOIN\n          (SELECT * FROM UNNEST ([%s]) as t)\n        WHERE\n          %s > t AND target='%s'\n        GROUP BY t\n        ORDER BY t\n      \"\"\" % (self._bigquery, ','.join(map(str, thresholds)), probability_column, target_class))\n\n      total_target_query = bq.Query(\"\"\"\n        SELECT\n          COUNT(*) as total_target\n        FROM\n          %s\n        WHERE\n          target='%s'\n      \"\"\" % (self._bigquery, target_class))\n\n      total_predicted = total_predicted_query.execute().result()\n      correct_predicted = correct_predicted_query.execute().result()\n      total_target = total_target_query.execute().result()[0]['total_target']\n      data = []\n      for p, c, t in zip(total_predicted, correct_predicted, thresholds):\n        precision = ((float)(c['correct_predicted']) / p['total_predicted']\n                     if p['total_predicted'] > 0. else 0.)\n        recall = (float)(c['correct_predicted']) / total_target if total_target > 0. else 0.\n        data.append({'precision': precision, 'recall': recall, 'threshold': t})\n      return pd.DataFrame(data)\n\n  def rmse(self):\n    \"\"\"Get RMSE for regression model evaluation results.\n\n    Returns:\n      the RMSE float number.\n\n    Raises:\n      Exception if the CSV headers do not include 'target' or 'predicted', or BigQuery\n      does not return 'target' or 'predicted' column, or if target or predicted is not\n      number.\n    \"\"\"\n\n    if self._input_csv_files:\n      df = self._get_data_from_csv_files()\n      if 'target' not in df or 'predicted' not in df:\n        raise ValueError('Cannot find \"target\" or \"predicted\" column')\n\n      df = df[['target', 'predicted']].apply(pd.to_numeric)\n      # if df is empty or contains non-numeric, scikit learn will raise error.\n      mse = mean_squared_error(df['target'], df['predicted'])\n      return math.sqrt(mse)\n    elif self._bigquery:\n      query = bq.Query(\"\"\"\n        SELECT\n          SQRT(SUM(ABS(predicted-target) * ABS(predicted-target)) / COUNT(*)) as rmse\n        FROM\n          %s\"\"\" % self._bigquery)\n      df = self._get_data_from_bigquery([query])\n      if df.empty:\n        return None\n      return df['rmse'][0]\n\n  def mae(self):\n    \"\"\"Get MAE (Mean Absolute Error) for regression model evaluation results.\n\n    Returns:\n      the MAE float number.\n\n    Raises:\n      Exception if the CSV headers do not include 'target' or 'predicted', or BigQuery\n      does not return 'target' or 'predicted' column, or if target or predicted is not\n      number.\n    \"\"\"\n\n    if self._input_csv_files:\n      df = self._get_data_from_csv_files()\n      if 'target' not in df or 'predicted' not in df:\n        raise ValueError('Cannot find \"target\" or \"predicted\" column')\n\n      df = df[['target', 'predicted']].apply(pd.to_numeric)\n      mae = mean_absolute_error(df['target'], df['predicted'])\n      return mae\n    elif self._bigquery:\n      query = bq.Query(\"\"\"\n        SELECT\n          SUM(ABS(predicted-target)) / COUNT(*) as mae\n        FROM\n          %s\"\"\" % self._bigquery)\n      df = self._get_data_from_bigquery([query])\n      if df.empty:\n        return None\n      return df['mae'][0]\n\n  def percentile_nearest(self, percentile):\n    \"\"\"Get nearest percentile from regression model evaluation results.\n\n    Args:\n      percentile: a 0~100 float number.\n\n    Returns:\n      the percentile float number.\n\n    Raises:\n      Exception if the CSV headers do not include 'target' or 'predicted', or BigQuery\n      does not return 'target' or 'predicted' column, or if target or predicted is not\n      number.\n    \"\"\"\n\n    if self._input_csv_files:\n      df = self._get_data_from_csv_files()\n      if 'target' not in df or 'predicted' not in df:\n        raise ValueError('Cannot find \"target\" or \"predicted\" column')\n\n      df = df[['target', 'predicted']].apply(pd.to_numeric)\n      abs_errors = np.array((df['target'] - df['predicted']).apply(abs))\n      return np.percentile(abs_errors, percentile, interpolation='nearest')\n    elif self._bigquery:\n      query = bq.Query(\"\"\"\n        SELECT\n          PERCENTILE_DISC(ABS(predicted-target), %f) OVER() AS percentile\n        FROM\n          %s\n        LIMIT 1\"\"\" % (float(percentile) / 100, self._bigquery))\n      df = self._get_data_from_bigquery([query])\n      if df.empty:\n        return None\n      return df['percentile'][0]\n"
  },
  {
    "path": "google/datalab/ml/_summary.py",
    "content": "# Copyright 2017 Google Inc. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\nimport collections\nimport datetime\nimport fnmatch\nimport matplotlib.pyplot as plt\nimport os\nimport pandas as pd\nimport six\nimport tensorflow as tf\n\nfrom tensorflow.core.util import event_pb2\nfrom tensorflow.python.lib.io import tf_record\n\n\nclass Summary(object):\n  \"\"\"Represents TensorFlow summary events from files under specified directories.\"\"\"\n\n  def __init__(self, paths):\n    \"\"\"Initializes an instance of a Summary.\n    Args:\n      path: a path or a list of paths to directories which hold TensorFlow events files.\n            Can be local path or GCS paths. Wild cards allowed.\n    \"\"\"\n\n    if isinstance(paths, six.string_types):\n      self._paths = [paths]\n    else:\n      self._paths = paths\n\n  def _glob_events_files(self, paths, recursive):\n    \"\"\"Find all tf events files under a list of paths recursively. \"\"\"\n\n    event_files = []\n    for path in paths:\n      dirs = tf.gfile.Glob(path)\n      dirs = filter(lambda x: tf.gfile.IsDirectory(x), dirs)\n      for dir in dirs:\n        if recursive:\n          dir_files_pair = [(root, filenames) for root, _, filenames in tf.gfile.Walk(dir)]\n        else:\n          dir_files_pair = [(dir, tf.gfile.ListDirectory(dir))]\n\n        for root, filenames in dir_files_pair:\n          file_names = fnmatch.filter(filenames, '*.tfevents.*')\n          file_paths = [os.path.join(root, x) for x in file_names]\n          file_paths = filter(lambda x: not tf.gfile.IsDirectory(x), file_paths)\n          event_files += file_paths\n    return event_files\n\n  def list_events(self):\n    \"\"\"List all scalar events in the directory.\n\n    Returns:\n      A dictionary. Key is the name of a event. Value is a set of dirs that contain that event.\n    \"\"\"\n    event_dir_dict = collections.defaultdict(set)\n\n    for event_file in self._glob_events_files(self._paths, recursive=True):\n      dir = os.path.dirname(event_file)\n      try:\n        for record in tf_record.tf_record_iterator(event_file):\n          event = event_pb2.Event.FromString(record)\n          if event.summary is None or event.summary.value is None:\n            continue\n          for value in event.summary.value:\n            if value.simple_value is None or value.tag is None:\n              continue\n            event_dir_dict[value.tag].add(dir)\n      except tf.errors.DataLossError:\n        # DataLossError seems to happen sometimes for small logs.\n        # We want to show good records regardless.\n        continue\n    return dict(event_dir_dict)\n\n  def get_events(self, event_names):\n    \"\"\"Get all events as pandas DataFrames given a list of names.\n    Args:\n      event_names: A list of events to get.\n    Returns:\n      A list with the same length and order as event_names. Each element is a dictionary\n          {dir1: DataFrame1, dir2: DataFrame2, ...}.\n          Multiple directories may contain events with the same name, but they are different\n          events (i.e. 'loss' under trains_set/, and 'loss' under eval_set/.)\n    \"\"\"\n\n    if isinstance(event_names, six.string_types):\n      event_names = [event_names]\n\n    all_events = self.list_events()\n    dirs_to_look = set()\n    for event, dirs in six.iteritems(all_events):\n      if event in event_names:\n        dirs_to_look.update(dirs)\n\n    ret_events = [collections.defaultdict(lambda: pd.DataFrame(columns=['time', 'step', 'value']))\n                  for i in range(len(event_names))]\n    for event_file in self._glob_events_files(dirs_to_look, recursive=False):\n      try:\n        for record in tf_record.tf_record_iterator(event_file):\n          event = event_pb2.Event.FromString(record)\n          if event.summary is None or event.wall_time is None or event.summary.value is None:\n            continue\n\n          event_time = datetime.datetime.fromtimestamp(event.wall_time)\n          for value in event.summary.value:\n            if value.tag not in event_names or value.simple_value is None:\n              continue\n\n            index = event_names.index(value.tag)\n            dir_event_dict = ret_events[index]\n            dir = os.path.dirname(event_file)\n            # Append a row.\n            df = dir_event_dict[dir]\n            df.loc[len(df)] = [event_time, event.step, value.simple_value]\n      except tf.errors.DataLossError:\n        # DataLossError seems to happen sometimes for small logs.\n        # We want to show good records regardless.\n        continue\n\n    for idx, dir_event_dict in enumerate(ret_events):\n      for df in dir_event_dict.values():\n        df.sort_values(by=['time'], inplace=True)\n      ret_events[idx] = dict(dir_event_dict)\n\n    return ret_events\n\n  def plot(self, event_names, x_axis='step'):\n    \"\"\"Plots a list of events. Each event (a dir+event_name) is represetented as a line\n       in the graph.\n    Args:\n      event_names: A list of events to plot. Each event_name may correspond to multiple events,\n          each in a different directory.\n      x_axis: whether to use step or time as x axis.\n    \"\"\"\n\n    if isinstance(event_names, six.string_types):\n      event_names = [event_names]\n\n    events_list = self.get_events(event_names)\n    for event_name, dir_event_dict in zip(event_names, events_list):\n      for dir, df in six.iteritems(dir_event_dict):\n        label = event_name + ':' + dir\n        x_column = df['step'] if x_axis == 'step' else df['time']\n        plt.plot(x_column, df['value'], label=label)\n    plt.legend(loc='best')\n    plt.show()\n"
  },
  {
    "path": "google/datalab/ml/_tensorboard.py",
    "content": "# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\ntry:\n  import IPython\nexcept ImportError:\n  raise Exception('This module can only be loaded in ipython.')\n\nimport argparse\nimport os\nimport pandas as pd\nimport psutil\nimport subprocess\nimport time\n\nimport google.datalab as datalab\n\n\nclass TensorBoard(object):\n  \"\"\"Start, shutdown, and list TensorBoard instances.\"\"\"\n\n  @staticmethod\n  def list():\n    \"\"\"List running TensorBoard instances.\"\"\"\n\n    running_list = []\n    parser = argparse.ArgumentParser()\n    parser.add_argument('--logdir')\n    parser.add_argument('--port')\n    for p in psutil.process_iter():\n      if p.name() != 'tensorboard' or p.status() == psutil.STATUS_ZOMBIE:\n        continue\n      cmd_args = p.cmdline()\n      del cmd_args[0:2]  # remove 'python' and 'tensorboard'\n      args = parser.parse_args(cmd_args)\n      running_list.append({'pid': p.pid, 'logdir': args.logdir, 'port': args.port})\n    return pd.DataFrame(running_list)\n\n  @staticmethod\n  def start(logdir):\n    \"\"\"Start a TensorBoard instance.\n\n    Args:\n      logdir: the logdir to run TensorBoard on.\n    Raises:\n      Exception if the instance cannot be started.\n    \"\"\"\n    if logdir.startswith('gs://'):\n      # Check user does have access. TensorBoard will start successfully regardless\n      # the user has read permissions or not so we check permissions here to\n      # give user alerts if needed.\n      datalab.storage._api.Api.verify_permitted_to_read(logdir)\n\n    port = datalab.utils.pick_unused_port()\n    args = ['tensorboard', '--logdir=' + logdir, '--port=' + str(port)]\n    p = subprocess.Popen(args)\n    retry = 10\n    while (retry > 0):\n      if datalab.utils.is_http_running_on(port):\n        basepath = os.environ.get('DATALAB_ENDPOINT_URL', '')\n        url = '%s/_proxy/%d/' % (basepath.rstrip('/'), port)\n        html = '<p>TensorBoard was started successfully with pid %d. ' % p.pid\n        html += 'Click <a href=\"%s\" target=\"_blank\">here</a> to access it.</p>' % url\n        IPython.display.display_html(html, raw=True)\n        return p.pid\n      time.sleep(1)\n      retry -= 1\n\n    raise Exception('Cannot start TensorBoard.')\n\n  @staticmethod\n  def stop(pid):\n    \"\"\"Shut down a specific process.\n\n    Args:\n      pid: the pid of the process to shutdown.\n    \"\"\"\n    if psutil.pid_exists(pid):\n      try:\n        p = psutil.Process(pid)\n        p.kill()\n      except Exception:\n        pass\n"
  },
  {
    "path": "google/datalab/ml/_util.py",
    "content": "# Copyright 2017 Google Inc. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\nfrom googleapiclient import discovery\n\nimport os\nimport shutil\nimport subprocess\nimport tempfile\nimport tensorflow as tf\nimport time\n\nimport datalab.context\nimport google.datalab.utils as dlutils\n\n\n# TODO: Create an Operation class.\ndef wait_for_long_running_operation(operation_full_name):\n  print('Waiting for operation \"%s\"' % operation_full_name)\n  api = discovery.build('ml', 'v1', credentials=datalab.context.Context.default().credentials)\n  while True:\n    response = api.projects().operations().get(name=operation_full_name).execute()\n    if 'done' not in response or response['done'] is not True:\n      time.sleep(3)\n    else:\n      if 'error' in response:\n        print(response['error'])\n      else:\n        print('Done.')\n      break\n\n\ndef package_and_copy(package_root_dir, setup_py, output_tar_path):\n  \"\"\"Repackage an CloudML package and copy it to a staging dir.\n\n  Args:\n    package_root_dir: the root dir to install package from. Usually you can get the path\n        from inside your module using a relative path to __file__.\n    setup_py: the path to setup.py.\n    output_tar_path: the GCS path of the output tarball package.\n  Raises:\n    ValueError if output_tar_path is not a GCS path, or setup_py does not exist.\n  \"\"\"\n  if not output_tar_path.startswith('gs://'):\n    raise ValueError('output_tar_path needs to be a GCS path.')\n  if not os.path.isfile(setup_py):\n    raise ValueError('Supplied file \"%s\" does not exist.' % setup_py)\n\n  dest_setup_py = os.path.join(package_root_dir, 'setup.py')\n  if dest_setup_py != setup_py:\n    # setuptools requires a \"setup.py\" in the current dir, so copy setup.py there.\n    # Also check if there is an existing setup.py. If so, back it up.\n    if os.path.isfile(dest_setup_py):\n      os.rename(dest_setup_py, dest_setup_py + '._bak_')\n    shutil.copyfile(setup_py, dest_setup_py)\n\n  tempdir = tempfile.mkdtemp()\n  previous_cwd = os.getcwd()\n  os.chdir(package_root_dir)\n  try:\n    # Repackage.\n    sdist = ['python', dest_setup_py, 'sdist', '--format=gztar', '-d', tempdir]\n    subprocess.check_call(sdist)\n\n    # Copy to GCS.\n    source = os.path.join(tempdir, '*.tar.gz')\n    gscopy = ['gsutil', 'cp', source, output_tar_path]\n    subprocess.check_call(gscopy)\n    return\n  finally:\n    os.chdir(previous_cwd)\n    if dest_setup_py != setup_py:\n      os.remove(dest_setup_py)\n    if os.path.isfile(dest_setup_py + '._bak_'):\n      os.rename(dest_setup_py + '._bak_', dest_setup_py)\n    shutil.rmtree(tempdir)\n\n\ndef read_file_to_string(path):\n  \"\"\"Read a file into a string.\"\"\"\n  bytes_string = tf.gfile.Open(path, 'r').read()\n  return dlutils.python_portable_string(bytes_string)\n\n\ndef open_local_or_gcs(path, mode):\n  \"\"\"Opens the given path.\"\"\"\n  return tf.gfile.Open(path, mode)\n\n\ndef glob_files(path):\n  \"\"\"Glob the given path.\"\"\"\n  return tf.gfile.Glob(path)\n"
  },
  {
    "path": "google/datalab/notebook/__init__.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Google Cloud Datalab - notebook extension functionality.\"\"\"\n\ntry:\n  import IPython as _\nexcept ImportError:\n  raise Exception('This package requires an IPython notebook installation')\n\n__all__ = ['_']\n\n\ndef _jupyter_nbextension_paths():\n  return [dict(section=\"notebook\", src=\"static\", dest=\"gcpdatalab\")]\n"
  },
  {
    "path": "google/datalab/notebook/static/bigquery.css",
    "content": "/*\n * Copyright 2015 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License. You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under the License\n * is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n * or implied. See the License for the specific language governing permissions and limitations under\n * the License.\n */\n\ntable.bqsv {\n  font-family: inherit;\n  font-size: smaller;\n}\ntable.bqsv th, table.bqsv td {\n  border: solid 1px #cfcfcf;\n}\nth.bqsv_expanded, th.bqsv_collapsed {\n  background-color: #f7f7f7;\n}\nth.bqsv_colheader {\n  font-weight: bold;\n  background-color: #e7e7e7;\n}\ntbody.bqsv_hidden {\n  display: none;\n}\nth.bqsv_expanded:before {\n  content: '\\25be  '\n}\nth.bqsv_collapsed:before {\n  content: '\\25b8  '\n}\n"
  },
  {
    "path": "google/datalab/notebook/static/bigquery.ts",
    "content": "/*\n * Copyright 2015 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License. You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under the License\n * is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n * or implied. See the License for the specific language governing permissions and limitations under\n * the License.\n */\n\n/// <reference path=\"../../../../externs/ts/require/require.d.ts\" />\n\nmodule BigQuery {\n\n  // Event handler to toggle visibility of a nested schema table.\n  function _toggleNode(e: any): void {\n    var node = e.target;\n    var expand = node.className == 'bqsv_collapsed';\n    node.className = expand ? 'bqsv_expanded' : 'bqsv_collapsed';\n    var tgroup = node.parentNode.nextSibling;\n    tgroup.className = expand ? 'bqsv_visible' : 'bqsv_hidden';\n  }\n\n  // Helper function to recursively render a table schema.\n  function _renderSchema(table: any, schema: any, title: string,\n     includeColumnHeaders: boolean, columns: any): void {\n\n    // Create a tbody element to hold the entities for this level. We group them so\n    // we can easily collapse/expand the level.\n    var tbody = document.createElement('tbody');\n\n    for (var i = 0; i < schema.length; i++) {\n      if (i == 0) {\n        if (title.length > 0) {\n          // title.length > 0 implies we are in a nested table. Create a title header row\n          // for this nested table with a click handler and hide the tbody.\n\n          tbody.className = 'bqsv_hidden';\n\n          var th = document.createElement('th');\n          th.colSpan = columns.length;\n          th.className = 'bqsv_collapsed';\n          th.textContent = title.substring(1);  // skip the leading '.'\n          th.addEventListener('click', _toggleNode);\n\n          var tr = document.createElement('tr');\n          tr.appendChild(th);\n          table.appendChild(tr);\n        } else {\n          // We are in the top-level table; add a header row with the column labels.\n          tbody.className = 'bqsv_visible';\n          if (includeColumnHeaders) {\n            // First line; show column headers.\n            var tr = document.createElement('tr');\n            for (var j = 0; j < columns.length; j++) {\n              var th = document.createElement('th');\n              th.textContent = columns[j];\n              th.className = 'bqsv_colheader';\n              tr.appendChild(th);\n            }\n            table.appendChild(tr);\n          }\n        }\n      }\n\n      // Add the details for the current row to the tbody.\n      var field = schema[i];\n      var tr = document.createElement('tr');\n      for (var j = 0; j < columns.length; j++) {\n        var td = document.createElement('td');\n        var v = field[columns[j]];\n        td.textContent = v == undefined ? '' : v;\n        tr.appendChild(td);\n      }\n      tbody.appendChild(tr);\n    }\n\n    // Add the tbody with all the rows to the table.\n    table.appendChild(tbody);\n\n    // Recurse into any nested tables.\n    for (var i = 0; i < schema.length; i++) {\n      var field = schema[i];\n      if (field.type == 'RECORD') {\n        _renderSchema(table, field.fields, title + '.' + field.name, false, columns);\n      }\n    }\n  }\n\n  // Top-level public function for schema rendering.\n  export function renderSchema(dom: any, schema: any) {\n    var columns = ['name', 'type', 'mode', 'description'];\n    var table = document.createElement('table');\n    table.className = 'bqsv';\n    _renderSchema(table, schema, '', /*includeColumnHeaders*/ true, columns);\n    dom.appendChild(table);\n  }\n}\n\nexport = BigQuery;\n"
  },
  {
    "path": "google/datalab/notebook/static/charting.css",
    "content": "/*\n * Copyright 2015 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License. You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under the License\n * is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n * or implied. See the License for the specific language governing permissions and limitations under\n * the License.\n */\n\ntable.google-visualization-table-table, table.dataframe {\n  font-family: inherit;\n  font-size: smaller;\n}\ntr.gchart-table-row {\n}\ntr.gchart-table-headerrow, table.dataframe thead th {\n  font-weight: bold;\n  background-color: #e7e7e7;\n}\ntr.gchart-table-oddrow, table.dataframe tr:nth-child(odd) {\n  background-color: #f7f7f7;\n}\ntr.gchart-table-selectedTableRow {\n  background-color: #e3f2fd;\n}\ntr.gchart-table-hoverrow, table.dataframe tr:hover {\n  background-color: #bbdefb;\n}\ntd.gchart-table-cell, table.dataframe td {\n  border: solid 1px #cfcfcf;\n}\ntd.gchart-table-rownumcell, table.dataframe tr th {\n  border: solid 1px #cfcfcf;\n  color: #999;\n}\nth.gchart-table-headercell, table.dataframe th {\n  border: solid 1px #cfcfcf;\n}\ndiv.bqgc {\n  display: flex;\n  justify-content: center;\n}\ndiv.bqgc img {\n  max-width: none; // Fix the conflict with maps and Bootstrap that messes up zoom controls.\n}\n.gchart-slider {\n  width: 80%;\n  float: left;\n}\n.gchart-slider-value {\n  text-align: center;\n  float: left;\n  width: 20%;\n}\n.gchart-control {\n  padding-top: 10px;\n  padding-bottom: 10px;\n}\n.gchart-controls {\n  font-size: 14px;\n  color: #333333;\t \n  background: #f4f4f4;\n  padding: 10px;\n  width: 180px;\n  float: left;\n}\n.bqgc {\n  padding: 0;\n  max-width: 100%;\n}\n.bqgc-controlled {\n  display: flex;\n  flex-direction: row;\n  justify-content:space-between;\n}\n.bqgc-container {\n  display: block;\n}\n.bqgc-ml-metrics {\n  display: flex;\n  flex-direction: row;\n  justify-content:left;\n}\n"
  },
  {
    "path": "google/datalab/notebook/static/charting.ts",
    "content": "/*\n * Copyright 2015 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License. You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under the License\n * is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n * or implied. See the License for the specific language governing permissions and limitations under\n * the License.\n */\n\n/// <reference path=\"../../../../externs/ts/require/require.d.ts\" />\n\nmodule Charting {\n  declare var IPython:any;\n  declare var datalab:any;\n\n// Wrappers for Plotly.js and Google Charts\n\n  abstract class ChartLibraryDriver {\n\n    chartModule:any;\n\n    constructor(protected dom:HTMLElement, protected chartStyle:string) {\n    }\n\n    abstract requires(url: string, chartStyle:string):Array<string>;\n\n    init(chartModule:any):void {\n      this.chartModule = chartModule;\n    }\n\n    abstract draw(data:any, options:any):void;\n\n    abstract getStaticImage(callback:Function):void;\n\n    abstract addChartReadyHandler(handler:Function):void;\n\n    addPageChangedHandler(handler:Function):void {\n    }\n\n    error(message:string):void {\n    }\n  }\n\n  class PlotlyDriver extends ChartLibraryDriver {\n    readyHandler:any;\n\n    constructor(dom:HTMLElement, chartStyle:string) {\n      super(dom, chartStyle)\n    }\n\n    requires(url: string, chartStyle:string):Array<string> {\n      return ['d3', 'plotly'];\n    }\n\n    public draw(data:any, options:any):void {\n      /*\n       * TODO(gram): if we start moving more chart types over to Plotly.js we should change the\n       * shape of the data we pass to render so we don't need to reshape it here. Also, a fair\n       * amount of the computation done here could be moved to Python code. We should just be\n       * passing in the mostly complete layout object in JSON, for example.\n       */\n      var xlabels: Array<string> = [];\n      var points: Array<any> = [];\n      var layout: any = {\n        xaxis: {},\n        yaxis: {},\n        height: 300,\n        margin: {\n          b: 60,\n          t: 60,\n          l: 60,\n          r: 60\n        }\n      };\n      if (options.title) {\n        layout.title = options.title;\n      }\n      var minX: number = undefined;\n      var maxX: number = undefined;\n      if ('hAxis' in options) {\n        if ('minValue' in options.hAxis) {\n          minX = options.hAxis.minValue;\n        }\n        if ('maxValue' in options.hAxis) {\n          maxX = options.hAxis.maxValue;\n        }\n        if (minX != undefined || maxX != undefined) {\n          layout.xaxis.range = [minX, maxX];\n        }\n      }\n      var minY: number = undefined;\n      var maxY: number = undefined;\n      if ('vAxis' in options) {\n        if ('minValue' in options.vAxis) {\n          minY = options.vAxis.minValue;\n        } else if ('minValues' in options.vAxis) {\n          minY = options.vAxis.minValues[0];\n        }\n        if ('maxValue' in options.vAxis) {\n          maxY = options.vAxis.maxValue;\n        } else if ('maxValues' in options.vAxis) {\n          maxY = options.vAxis.maxValues[0];\n        }\n        if (minY != undefined || maxY != undefined) {\n          layout.yaxis.range = [minY, maxY];\n        }\n        if ('minValues' in options.vAxis) {\n          minY = options.vAxis.minValues[1]; // for second axis below\n        }\n        if ('maxValues' in options.vAxis) {\n          maxY = options.vAxis.maxValues[1]; // for second axis below\n        }\n      }\n      if (options.xAxisTitle) {\n        layout.xaxis.title = options.xAxisTitle;\n      }\n      if (options.xAxisSide) {\n        layout.xaxis.side = options.xAxisSide;\n      }\n      if (options.yAxisTitle) {\n        layout.yaxis.title = options.yAxisTitle;\n      }\n      if (options.yAxesTitles) {\n        layout.yaxis.title = options.yAxesTitles[0];\n        layout.yaxis2 = {\n          title: options.yAxesTitles[1],\n          side: 'right',\n          overlaying: 'y'\n        };\n        if (minY != undefined || maxY != undefined) {\n          layout.yaxis2.range = [minY, maxY];\n        }\n      }\n      if ('width' in options) {\n        layout.width = options.width;\n      }\n      if ('height' in options) {\n        layout.height = options.height;\n        if ('width' in options) {\n          layout.autosize = false;\n        }\n      }\n      var pdata: Array<any> = [];\n\n      if (this.chartStyle == 'line' || this.chartStyle == 'scatter') {\n        var hoverCol: number = 0;\n        var x: Array<any> = [];\n        // First col is X, other cols are Y's and optional hover text only column\n        var y: Array<any> = [];\n        var hover: Array<any> = [];\n        for (var c = 1; c < data.cols.length; c++) {\n          x[c - 1] = [];\n          y[c - 1] = [];\n          var line:any = {\n            x: x[c - 1],\n            y: y[c - 1],\n            name: data.cols[c].label,\n            type: 'scatter',\n            mode: this.chartStyle == 'scatter' ? 'markers' : 'lines'\n          };\n          if (options.hoverOnly) {\n            hover[c - 1] = [];\n            line.text = hover[c - 1];\n            line.hoverinfo = 'text';\n          }\n          if (options.yAxesTitles && (c % 2) == 0) {\n            line.yaxis = 'y2';\n          }\n          pdata.push(line);\n        }\n        for (var c = 1; c < data.cols.length; c++) {\n          if (c == hoverCol) {\n            continue;\n          }\n          for (var r = 0; r < data.rows.length; r++) {\n            var entry:Array<any> = data.rows[r].c;\n            if ('v' in entry[c]) {\n              var xVal = entry[0].v;\n              var yVal = entry[c].v;\n              if (options.hoverOnly) {\n                // Each column is a dict with two values, one for y and one for\n                // hover. Extract these.\n                var hoverVal:any;\n                var yDict:any  = yVal;\n                for (var prop in yDict) {\n                  var val = yDict[prop];\n                  if (prop == options.hoverOnly) {\n                    hoverVal = val;\n                  } else {\n                    yVal = val;\n                  }\n                }\n                // TODO(gram): we may want to add explicit hover text this even without hoverOnly.\n                var xlabel:any = options.xAxisTitle || data.cols[0].label;\n                var ylabel:any  = options.yAxisTitle || data.cols[c].label;\n                var prefix = '';\n                if (options.yAxisTitle) {\n                  prefix += data.cols[c].label + ': ';\n                }\n                hover[c - 1].push(prefix +\n                    options.hoverOnly + '=' + hoverVal + ', ' +\n                    xlabel + '=' + xVal + ', ' +\n                    ylabel + '=' + yVal);\n              }\n              x[c - 1].push(xVal);\n              y[c - 1].push(yVal);\n            }\n          }\n        }\n      } else if (this.chartStyle == 'heatmap') {\n        var size:number = 200 + data.cols.length * 50;\n        if (size > 800) size = 800;\n        layout.height = size;\n        layout.width = size;\n        layout.autosize = false;\n\n        for (var i = 0; i < data.cols.length; i++) {\n          xlabels[i] = data.cols[i].label;\n        }\n        var ylabels = [].concat(xlabels);\n\n        // Plotly draws the first row at the bottom, not the top, so we need\n        // to reverse the y and z array ordering.\n        // We will need to tweak this a bit if we later support non-square maps.\n        ylabels.reverse();\n\n        var hovertext: Array<Array<string>> = [];\n        var hoverx:string = options.xAxisTitle || 'x';\n        var hovery = options.yAxisTitle || 'y';\n\n        for (var i = 0; i < data.rows.length; i++) {\n          var entry:Array<any> = data.rows[i].c;\n          var row:Array<number> = [];\n          var hoverrow:Array<string> = [];\n          for (var j = 0; j < data.cols.length; j++) {\n            row[j] = entry[j].v;\n            hoverrow[j] = hoverx + '= ' + xlabels[j] + ', ' + hovery + '= ' +\n                ylabels[i] + ': ' + row[j];\n          }\n          points[i] = row;\n          hovertext[i] = hoverrow;\n        }\n        points.reverse();\n        layout.hovermode = 'closest';\n\n        pdata = [{\n          x: xlabels,\n          y: ylabels,\n          z: points,\n          type: 'heatmap',\n          text: hovertext,\n          hoverinfo: 'text'\n        }];\n        if (options.colorScale) {\n          pdata[0].colorscale = [\n            [0, options.colorScale.min],\n            [1, options.colorScale.max]\n          ];\n        } else {\n          pdata[0].colorscale = [\n            [0, 'red'],\n            [0.5, 'gray'],\n            [1, 'blue']\n          ];\n        }\n        if (options.hideScale) {\n          pdata[0].showscale = false;\n        }\n        if (options.annotate) {\n          layout.annotations = [];\n          for (var i = 0; i < pdata[0].y.length; i++) {\n            for (var j = 0; j < pdata[0].x.length; j++) {\n              var currentValue = pdata[0].z[i][j];\n              var textColor = (currentValue == 0.0) ? 'black' : 'white';\n              var result = {\n                xref: 'x1',\n                yref: 'y1',\n                x: pdata[0].x[j],\n                y: pdata[0].y[i],\n                text: pdata[0].z[i][j].toPrecision(3),\n                showarrow: false,\n                font: {\n                  color: textColor\n                }\n              };\n              layout.annotations.push(result);\n            }\n          }\n        }\n      }\n      this.chartModule.newPlot(this.dom.id, pdata, layout, {displayModeBar: false});\n      if (this.readyHandler) {\n        this.readyHandler();\n      }\n    }\n\n    getStaticImage(callback:Function):void {\n      this.chartModule.Snapshot.toImage(document.getElementById(this.dom.id),\n          {format: 'png'}).once('success', function (url:string) {\n        callback(this.model, url);\n      });\n    }\n\n    addChartReadyHandler(handler:Function):void {\n      this.readyHandler = handler;\n    }\n  }\n\n  interface IStringMap {\n    [key: string]: string;\n  }\n\n  class GChartsDriver extends ChartLibraryDriver {\n\n    chart:any;\n\n    nameMap: IStringMap = {\n      annotation: 'AnnotationChart',\n      area: 'AreaChart',\n      columns: 'ColumnChart',\n      bars: 'BarChart',\n      bubbles: 'BubbleChart',\n      calendar: 'Calendar',\n      candlestick: 'CandlestickChart',\n      combo: 'ComboChart',\n      gauge: 'Gauge',\n      geo: 'GeoChart',\n      histogram: 'Histogram',\n      line: 'LineChart',\n      map: 'Map',\n      org: 'OrgChart',\n      paged_table: 'Table',\n      pie: 'PieChart',\n      sankey: 'Sankey',\n      scatter: 'ScatterChart',\n      stepped_area: 'SteppedAreaChart',\n      table: 'Table',\n      timeline: 'Timeline',\n      treemap: 'TreeMap',\n    };\n\n    scriptMap: IStringMap = {\n      annotation: 'annotationchart',\n      calendar: 'calendar',\n      gauge: 'gauge',\n      geo: 'geochart',\n      map: 'map',\n      org: 'orgchart',\n      paged_table: 'table',\n      sankey: 'sankey',\n      table: 'table',\n      timeline: 'timeline',\n      treemap: 'treemap'\n    };\n\n    constructor(dom:HTMLElement, chartStyle:string) {\n      super(dom, chartStyle);\n    }\n\n    requires(url: string, chartStyle:string):Array<string> {\n      var chartScript:string = 'corechart';\n      if (chartStyle in this.scriptMap) {\n        chartScript = this.scriptMap[chartStyle];\n      }\n      return [url + 'visualization!' + chartScript];\n    }\n\n    init(chartModule:any):void {\n      super.init(chartModule);\n      var constructor:Function = this.chartModule[this.nameMap[this.chartStyle]];\n      this.chart = new (<any>constructor)(this.dom);\n    }\n\n    error(message:string):void {\n      this.chartModule.errors.addError(this.dom, 'Unable to render the chart', message,\n          {showInTooltip: false});\n    }\n\n    draw(data:any, options:any):void {\n      console.log('Drawing with options ' + JSON.stringify(options));\n      this.chart.draw(new this.chartModule.DataTable(data), options);\n    }\n\n    getStaticImage(callback:Function):void {\n      if (this.chart.getImageURI) {\n        callback(this.chart.getImageURI());\n      }\n    }\n\n    addChartReadyHandler(handler:Function) {\n      this.chartModule.events.addListener(this.chart, 'ready', handler);\n    }\n\n    addPageChangedHandler(handler:Function) {\n      this.chartModule.events.addListener(this.chart, 'page', function (e:any) {\n        handler(e.page);\n      });\n    }\n  }\n\n  class Chart {\n    dataCache:any;  // TODO: add interface types for the caches.\n    optionsCache:any;\n    hasIPython:boolean;\n    cellElement:HTMLElement;\n    totalRows:number;\n\n    constructor(protected driver:ChartLibraryDriver,\n                protected dom:Element,\n                protected controlIds:Array<string>,\n                protected base_options:any,\n                protected refreshData:any,\n                protected refreshInterval:number,\n                totalRows:number) {\n      this.totalRows = totalRows || -1; // Total rows in all (server-side) data.\n      this.dataCache = {};\n      this.optionsCache = {};\n      this.hasIPython = false;\n      try {\n        if (IPython && IPython.notebook) {\n          this.hasIPython = true;\n        }\n      } catch (e) {\n      }\n      (<HTMLElement>this.dom).innerHTML = '';\n      this.removeStaticChart();\n      this.addControls();\n      // Generate and add a new static chart once chart is ready.\n      var _this = this;\n      this.driver.addChartReadyHandler(function () {\n        _this.addStaticChart();\n      });\n    }\n\n    // Convert any string fields that are date type to JS Dates.\n    public convertDates(data:any):void {\n\n      // Format timestamps in the same way as in dataframes.\n      const timestampFormatter = new this.driver.chartModule.DateFormat({\n        'pattern' : 'yyyy-MM-dd HH:mm:ss',\n        'valueType' : 'datetime',\n        'timeZone' : -new Date().getTimezoneOffset() / 60,\n      });\n      // Timestamp formatter with fractional seconds.\n      // BQ and python store time down to the microsecond, but javascript Date\n      // only stores it to the millisecond.\n      const timestampWithFractionalSecondsFormatter = new this.driver.chartModule.DateFormat({\n        'pattern' : 'yyyy-MM-dd HH:mm:ss.SSS',\n        'valueType' : 'datetime',\n        'timeZone' : -new Date().getTimezoneOffset() / 60,\n      });\n\n      // Javascript has terrible support for timezones. When Date objects get converted to\n      // strings, it always applies the local timezone. But we want dates and times to be\n      // printed in UTC so that they match the output of dataframes and other conversions that\n      // are happening in the kernel, which we assume is running in UTC in a docker container.\n      // In order to make this work, we add an offset to our Date objects in an amount equal\n      // to the local timezone offset from UTC so that when those Dates get output as a local\n      // time they will appear as the right UTC time. This is made more confusing by the fact\n      // that date, datetime, and timeofday data types are civil time for which timezone\n      // should not even apply - but since we are passing them along as Date objects, we\n      // pull the same trick with them. We add the 'f' field, for use by Google Charts when\n      // displaying tables, to ensure we have the right string there, but when doing things\n      // like line graphs, that field is not used, so we have to use the Date-offset trick\n      // in order to get dates and times to display correctly as UTC in graphs.\n\n      function dateAsUtc(localDate:Date):Date {\n        const year    = localDate.getUTCFullYear();\n        const month   = localDate.getUTCMonth();\n        const day     = localDate.getUTCDate();\n        const hours   = localDate.getUTCHours();\n        const minutes = localDate.getUTCMinutes();\n        const seconds = localDate.getUTCSeconds();\n        const millis  = localDate.getUTCMilliseconds();\n        return new Date(year, month, day, hours, minutes, seconds, millis);\n      }\n\n      const rows = data.rows;\n      for (let col = 0; col < data.cols.length; col++) {\n        // date, datetime, and timeofday are civil times that are independent of timezone\n        if (data.cols[col].type == 'date' || data.cols[col].type == 'datetime') {\n          for (let row = 0; row < rows.length; row++) {\n            const v = rows[row].c[col].v;\n            rows[row].c[col].v = dateAsUtc(new Date(v));\n            rows[row].c[col].f = v;   // Display the string as-is to avoid timezone problems.\n          }\n        } else if (data.cols[col].type == 'timeofday') {\n          for (let row = 0; row < rows.length; row++) {\n            const v = rows[row].c[col].v;\n            rows[row].c[col].f = v;  // Display the string as-is to avoid timezone problems.\n            const timeInSeconds = v.split('.')[0];\n            rows[row].c[col].v = timeInSeconds.split(':').map(\n              function(n:string) {\n                return parseInt(n, 10);\n              });\n          }\n        } else if (data.cols[col].type == 'timestamp') {\n          data.cols[col].type = 'datetime';\n          // Run through all the dates to determine how to format them.\n          let formatter = timestampFormatter;\n          for (let row = 0; row < rows.length; row++) {\n            const v = new Date(rows[row].c[col].v);\n            if (v.getTime() % 1000 != 0) {\n              formatter = timestampWithFractionalSecondsFormatter;\n              break;\n            }\n          }\n          for (let row = 0; row < rows.length; row++) {\n            const v = new Date(rows[row].c[col].v);   // Timestamp is sent back as UTC time string.\n            rows[row].c[col].f = formatter.formatValue(v);\n            rows[row].c[col].v = dateAsUtc(v);\n          }\n        }\n      }\n    }\n\n    // Extend the properties in a 'base' object with the changes in an 'update' object.\n    // We can add properties or override properties but not delete yet.\n    private static extend(base:any, update:any):void {\n      for (var p in update) {\n        if (typeof base[p] !== 'object' || !base.hasOwnProperty(p)) {\n          base[p] = update[p];\n        } else {\n          this.extend(base[p], update[p]);\n        }\n      }\n    }\n\n    // Get the IPython cell associated with this chart.\n    private getCell() {\n      if (!this.hasIPython) {\n        return undefined;\n      }\n      var cells = IPython.notebook.get_cells();\n      for (var cellIndex in cells) {\n        var cell = cells[cellIndex];\n        if (cell.element && cell.element.length) {\n          var element = cell.element[0];\n          var chartDivs = element.getElementsByClassName('bqgc');\n          if (chartDivs && chartDivs.length) {\n            for (var i = 0; i < chartDivs.length; i++) {\n              if (chartDivs[i].id == this.dom.id) {\n                return cell;\n              }\n            }\n          }\n        }\n      }\n      return undefined;\n    }\n\n    protected getRefreshHandler(useCache:boolean):Function {\n      var _this = this;\n      return function () {\n        _this.refresh(useCache);\n      };\n    }\n\n    // Bind event handlers to the chart controls, if any.\n    private addControls():void {\n      if (!this.controlIds) {\n        return;\n      }\n      var controlHandler = this.getRefreshHandler(true);\n      for (var i = 0; i < this.controlIds.length; i++) {\n        var id = this.controlIds[i];\n        var split = id.indexOf(':');\n        var control:HTMLInputElement;\n        if (split >= 0) {\n          // Checkbox group.\n          var count = parseInt(id.substring(split + 1));\n          var base = id.substring(0, split + 1);\n          for (var j = 0; j < count; j++) {\n            control = <HTMLInputElement>document.getElementById(base + j);\n            control.disabled = !this.hasIPython;\n            control.addEventListener('change', function() {\n              controlHandler();\n            });\n          }\n          continue;\n        }\n        // See if we have an associated control that needs dual binding.\n        control = <HTMLInputElement>document.getElementById(id);\n        if (!control) {\n          // Kernel restart?\n          return;\n        }\n        control.disabled = !this.hasIPython;\n        var textControl = <HTMLInputElement>document.getElementById(id + '_value');\n        if (textControl) {\n          textControl.disabled = !this.hasIPython;\n          textControl.addEventListener('change', function () {\n            if (control.value != textControl.value) {\n              control.value = textControl.value;\n              controlHandler();\n            }\n          });\n          control.addEventListener('change', function () {\n            textControl.value = control.value;\n            controlHandler();\n          });\n        } else {\n          control.addEventListener('change', function() {\n            controlHandler();\n          });\n        }\n      }\n    }\n\n    // Iterate through any widget controls and build up a JSON representation\n    // of their values that can be passed to the Python kernel as part of the\n    // magic to fetch data (also used as part of the cache key).\n    protected getControlSettings():any {\n      var env:any = {};\n      if (this.controlIds) {\n        for (var i = 0; i < this.controlIds.length; i++) {\n          var id = this.controlIds[i];\n          var parts = id.split('__');\n          var varName = parts[1];\n          var splitPoint = varName.indexOf(':');\n          if (splitPoint >= 0) { // this is a checkbox group\n            var count = parseInt(varName.substring(splitPoint + 1));\n            varName = varName.substring(0, splitPoint);\n            var cbBaseId = parts[0] + '__' + varName + ':';\n            var list:Array<string> = [];\n            env[varName] = list;\n            for (var j = 0; j < count; j++) {\n              var cb = <HTMLInputElement>document.getElementById(cbBaseId + j);\n              if (!cb) {\n                // Stale refresh; user re-executed cell.\n                return undefined;\n              }\n              if (cb.checked) {\n                list.push(cb.value);\n              }\n            }\n          } else {\n            var e = <HTMLInputElement>document.getElementById(id);\n            if (!e) {\n              // Stale refresh; user re-executed cell.\n              return undefined;\n            }\n            if (e && e.type == 'checkbox') {\n              // boolean\n              env[varName] = e.checked;\n            } else {\n              // picker/slider/text\n              env[varName] = e.value;\n            }\n          }\n        }\n      }\n      return env;\n    }\n\n    // Get a string representation of the current environment - i.e. control settings and\n    // refresh data. This is used as a cache key.\n    private getEnvironment():string {\n      var controls:any = this.getControlSettings();\n      if (controls == undefined) {\n        // This means the user has re-executed the cell and our controls are gone.\n        return undefined;\n      }\n      var env:any = {controls: controls};\n      Chart.extend(env, this.refreshData);\n      return JSON.stringify(env);\n    }\n\n    protected refresh(useCache:boolean):void {\n      // TODO(gram): remember last cache key and don't redraw chart if cache\n      // key is the same unless this is an ML key and the number of data points has changed.\n      this.removeStaticChart();\n      var env:string = this.getEnvironment();\n      if (env == undefined) {\n        // This means the user has re-executed the cell and our controls are gone.\n        console.log('No chart control environment; abandoning refresh');\n        return;\n      }\n      if (useCache && env in this.dataCache) {\n        this.draw(this.dataCache[env], this.optionsCache[env]);\n        return;\n      }\n      var code = '%_get_chart_data\\n' + env;\n\n      // TODO: hook into the notebook UI to enable/disable 'Running...' while we fetch more data.\n      if (!this.cellElement) {\n        var cell = this.getCell();\n        if (cell && cell.element && cell.element.length == 1) {\n          this.cellElement = cell.element[0];\n        }\n      }\n      // Start the cell spinner in the notebook UI.\n      if (this.cellElement) {\n        this.cellElement.classList.remove('completed');\n      }\n      var _this = this;\n      datalab.session.execute(code, function (error:string, response:any) {\n        _this.handleNewData(env, error, response);\n      });\n    }\n\n    private handleNewData(env: any, error:any, response: any) {\n      var data = response.data;\n\n      // Stop the cell spinner in the notebook UI.\n      if (this.cellElement) {\n        this.cellElement.classList.add('completed');\n      }\n\n      if (data == undefined || data.cols == undefined) {\n        error = 'No data';\n      }\n\n      if (error) {\n        this.driver.error(error);\n        return;\n      }\n\n      this.refreshInterval = response.refresh_interval;\n      if (this.refreshInterval == 0) {\n        console.log('No more refreshes for ' + this.refreshData.name);\n      }\n\n      this.convertDates(data);\n      var options = this.base_options;\n      if (response.options) {\n        // update any options. We need to make a copy so we don't break the base options.\n        options = JSON.parse(JSON.stringify(options));\n        Chart.extend(options, response.options);\n      }\n\n      // Don't update or keep refreshing this if control settings have changed.\n      var newEnv = this.getEnvironment();\n      if (env == newEnv) {\n        console.log('Got refresh for ' + this.refreshData.name + ', ' + env);\n        this.draw(data, options);\n      } else {\n        console.log('Stopping refresh for ' + env + ' as controls are now ' + newEnv)\n      }\n    }\n\n    // Remove a static chart (PNG) from the notebook and the DOM.\n    protected removeStaticChart():void {\n      var cell = this.getCell();\n      if (cell) {\n        var pngDivs = <NodeListOf<HTMLDivElement>>\n            cell.element[0].getElementsByClassName('output_png');\n        if (pngDivs) {\n          for (var i = 0; i < pngDivs.length; i++) {\n            pngDivs[i].innerHTML = '';\n          }\n        }\n        var cell_outputs = cell.output_area.outputs;\n        var changed = true;\n        while (changed) {\n          changed = false;\n          for (var outputIndex in cell_outputs) {\n            var output = cell_outputs[outputIndex];\n            if (output.output_type == 'display_data' && output.metadata.source_id == this.dom.id) {\n              cell_outputs.splice(outputIndex, 1);\n              changed = true;\n              break;\n            }\n          }\n        }\n      } else {\n        // Not running under IPython; use a different approach and just clear the DOM.\n        // Iterate through the IPython outputs...\n        var outputDivs = document.getElementsByClassName('output_wrapper');\n        if (outputDivs) {\n          for (var i = 0; i < outputDivs.length; i++) {\n            // ...and any chart outputs in each...\n            var outputDiv = <HTMLDivElement>outputDivs[i];\n            var chartDivs = outputDiv.getElementsByClassName('bqgc');\n            if (chartDivs) {\n              for (var j = 0; j < chartDivs.length; j++) {\n                // ...until we find the chart div ID we want...\n                if (chartDivs[j].id == this.dom.id) {\n                  // ...then get any PNG outputs in that same output group...\n                  var pngDivs = <NodeListOf<HTMLDivElement>>outputDiv.\n                      getElementsByClassName('output_png');\n                  if (pngDivs) {\n                    for (var k = 0; k < pngDivs.length; k++) {\n                      // ... and clear their contents.\n                      pngDivs[k].innerHTML = '';\n                    }\n                  }\n                  return;\n                }\n              }\n            }\n          }\n        }\n      }\n    }\n\n    // Add a static chart (PNG) to the notebook. The notebook will in turn add it to the DOM when\n    // the notebook is opened.\n    private addStaticChart():void {\n      var _this = this;\n      this.driver.getStaticImage(function (img:string) {\n        _this.handleStaticChart(img);\n      });\n    }\n\n    private handleStaticChart(img: string) {\n      if (img) {\n        var cell = this.getCell();\n        if (cell) {\n          var encoding = img.substr(img.indexOf(',') + 1);  // strip leading base64 etc.\n          var static_output = {\n            metadata: {\n              source_id: this.dom.id\n            },\n            data: {\n              'image/png': encoding\n            },\n            output_type: 'display_data'\n          };\n          cell.output_area.outputs.push(static_output);\n        }\n      }\n    }\n\n    // Set up a refresh callback if we have a non-zero interval and the DOM element still exists\n    // (i.e. output hasn't been cleared).\n    private configureRefresh(refreshInterval:number):void {\n      if (refreshInterval > 0 && document.getElementById(this.dom.id)) {\n        window.setTimeout(this.getRefreshHandler(false), 1000 * refreshInterval);\n      }\n    }\n\n    // Cache the current data and options and draw the chart.\n    public draw(data:any, options:any):void {\n      var env:string = this.getEnvironment();\n      this.dataCache[env] = data;\n      this.optionsCache[env] = options;\n      if ('cols' in data) {\n        this.driver.draw(data, options);\n      }\n      this.configureRefresh(this.refreshInterval);\n    }\n  }\n\n  //-----------------------------------------------------------\n  // A special version of Chart for supporting paginated data.\n\n  class PagedTable extends Chart {\n    firstRow:number;\n    pageSize:number;\n\n    constructor(driver:ChartLibraryDriver,\n                dom:HTMLElement,\n                controlIds:Array<string>,\n                base_options:any,\n                refreshData:any,\n                refreshInterval:number,\n                totalRows:number) {\n      super(driver, dom, controlIds, base_options, refreshData, refreshInterval, totalRows);\n      this.firstRow = 0;  // Index of first row being displayed in page.\n      this.pageSize = base_options.pageSize || 25;\n      if (this.base_options.showRowNumber == undefined) {\n        this.base_options.showRowNumber = true;\n      }\n      this.base_options.sort = 'disable';\n      var __this = this;\n      this.driver.addPageChangedHandler(function (page:number) {\n        __this.handlePageEvent(page);\n      });\n    }\n\n    // Get control settings for cache key. For paged table we add the first row offset of the table.\n    protected getControlSettings():any {\n      var env = super.getControlSettings();\n      if (env) {\n        env.first = this.firstRow;\n      }\n      return env;\n    }\n\n    public draw(data:any, options:any):void {\n      var count = this.pageSize;\n      options.firstRowNumber = this.firstRow + 1;\n      options.page = 'event';\n      if (this.totalRows < 0) {\n        // We don't know where the end is, so we should have 'next' button.\n        options.pagingButtonsConfiguration = this.firstRow > 0 ? 'both' : 'next';\n      } else {\n        count = this.totalRows - this.firstRow;\n        if (count > this.pageSize) {\n          count = this.pageSize;\n        }\n        if (this.firstRow + count < this.totalRows) {\n          // We are not on last page, so we should have 'next' button.\n          options.pagingButtonsConfiguration = this.firstRow > 0 ? 'both' : 'next';\n        } else {\n          // We are on last page\n          if (this.firstRow == 0) {\n            options.pagingButtonsConfiguration = 'none';\n            options.page = 'disable';\n          } else {\n            options.pagingButtonsConfiguration = 'prev';\n          }\n        }\n      }\n      super.draw(data, options);\n    }\n\n    // Handle page forward/back events. Page will only be 0 or 1.\n    handlePageEvent(page:number):void {\n      var offset = (page == 0) ? -1 : 1;\n      this.firstRow += offset * this.pageSize;\n      this.refreshData.first = this.firstRow;\n      this.refreshData.count = this.pageSize;\n      this.refresh(true);\n    }\n  }\n\n  function convertListToDataTable(data:any):any {\n    if (!data || !data.length) {\n      return {cols: [], rows: []};\n    }\n\n    var firstItem = data[0];\n    var names = Object.keys(firstItem);\n\n    var columns = names.map(function (name) {\n      return {id: name, label: name, type: typeof firstItem[name]}\n    });\n\n    var rows = data.map(function (item:any) {\n      var cells = names.map(function (name) {\n        return {v: item[name]};\n      });\n      return {c: cells};\n    });\n\n    return {cols: columns, rows: rows};\n  }\n\n  // The main render method, called from render() wrapper below. dom is the DOM element\n  // for the chart, model is a set of parameters from Python, and options is a JSON\n  // set of options provided by the user in the cell magic body, which takes precedence over\n  // model. An initial set of data can be passed in as a final optional parameter.\n\n  function _render(driver:ChartLibraryDriver,\n                   dom:HTMLElement,\n                   chartStyle:string,\n                   controlIds:Array<string>,\n                   data:any,\n                   options:any,\n                   refreshData:any,\n                   refreshInterval:number,\n                   totalRows:number):void {\n    require([\"base/js/namespace\"], function(Jupyter: any) {\n      var url = \"datalab/\";\n      require(driver.requires(url, chartStyle), function (/* ... */) {\n        // chart module should be last dependency in require() call...\n        var chartModule = arguments[arguments.length - 1];  // See if it needs to be a member.\n        driver.init(chartModule);\n        options = options || {};\n\n        var chart:Chart;\n        if (chartStyle == 'paged_table') {\n          chart = new PagedTable(driver, dom, controlIds, options, refreshData, refreshInterval, totalRows);\n        } else {\n          chart = new Chart(driver, dom, controlIds, options, refreshData, refreshInterval, totalRows);\n        }\n        chart.convertDates(data);\n        chart.draw(data, options);\n        // Do we need to do anything to prevent it getting GCed?\n      });\n    });\n  }\n\n  export function render(driverName:string,\n                         dom:HTMLElement,\n                         events:any,\n                         chartStyle:string,\n                         controlIds:Array<string>,\n                         data:any,\n                         options:any,\n                         refreshData:any,\n                         refreshInterval:number,\n                         totalRows:number):void {\n\n    // If this is HTML from nbconvert we can't support paging so add some text making this clear.\n    if (chartStyle == 'paged_table' && document.hasOwnProperty('_in_nbconverted')) {\n      chartStyle = 'table';\n      var p = document.createElement(\"div\");\n      p.innerHTML = '<br>(Truncated to first page of results)';\n      dom.parentNode.insertBefore(p, dom.nextSibling);\n    }\n\n    // Allocate an appropriate driver.\n    var driver:ChartLibraryDriver;\n    if (driverName == 'plotly') {\n      driver = new PlotlyDriver(dom, chartStyle);\n    } else if (driverName == 'gcharts') {\n      driver = new GChartsDriver(dom, chartStyle);\n    } else {\n      throw new Error('Unsupported chart driver ' + driverName);\n    }\n\n    // Get data in form needed for GCharts.\n    // We shouldn't need this; should be handled by caller.\n    if (!data.cols && !data.rows) {\n      data = this.convertListToDataTable(data);\n    }\n\n    // If there is no IPython instance, assume that this is being executed in a sandboxed output\n    // environment and render immediately.\n    // If we have a datalab session, we can go ahead and draw the chart; if not, add code to do the\n    // drawing to an event handler for when the kernel is ready.\n    if (!this.hasIPython || IPython.notebook.kernel.is_connected()) {\n      _render(driver, dom, chartStyle, controlIds, data, options, refreshData, refreshInterval,\n          totalRows)\n    } else {\n      // If the kernel is not connected, wait for the event.\n      events.on('kernel_ready.Kernel', function (e:any) {\n        _render(driver, dom, chartStyle, controlIds, data, options, refreshData, refreshInterval,\n            totalRows)\n      });\n    }\n  }\n}\n\nexport = Charting;\n\n\n"
  },
  {
    "path": "google/datalab/notebook/static/element.ts",
    "content": "/*\n * Copyright 2015 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License. You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under the License\n * is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n * or implied. See the License for the specific language governing permissions and limitations under\n * the License.\n */\n\n/// <reference path=\"../../../../externs/ts/require/require.d.ts\" />\n\nmodule Element {\n\n// RequireJS plugin to resolve DOM elements.\n\n  'use strict';\n\n  var pendingCallbacks: any = null;\n\n  function resolve(cbInfo: any): void {\n    cbInfo.cb(document.getElementById(cbInfo.name));\n  }\n  \n  function domReadyCallback(): void {\n    if (pendingCallbacks) {\n      // Clear out pendingCallbacks, so any future requests are immediately resolved.\n      var callbacks = pendingCallbacks;\n      pendingCallbacks = null;\n\n      callbacks.forEach(resolve);\n    }\n  }\n\n  export function load(name: any, req: any, loadCallback: any, config: any): void {\n    if (config.isBuild) {\n      loadCallback(null);\n    }\n    else {\n      var cbInfo = { name: name, cb: loadCallback };\n\n      if (document.readyState == 'loading') {\n        if (!pendingCallbacks) {\n          pendingCallbacks = [];\n          document.addEventListener('DOMContentLoaded', domReadyCallback, false);\n        }\n\n        pendingCallbacks.push(cbInfo);\n      }\n      else {\n        resolve(cbInfo);\n      }\n    }\n  }\n}\n\nexport = Element;\n\n"
  },
  {
    "path": "google/datalab/notebook/static/extern/d3.parcoords.css",
    "content": ".parcoords > svg, .parcoords > canvas {\n  /*font: 14px sans-serif;*/\n  position: absolute;\n}\n.parcoords > canvas {\n  pointer-events: none;\n}\n.parcoords rect.background {\n  fill: transparent;\n}\n.parcoords rect.background:hover {\n  fill: rgba(120,120,120,0.2);\n}\n.parcoords .resize rect {\n  fill: rgba(0,0,0,0.1);\n}\n.parcoords rect.extent {\n  fill: rgba(255,255,255,0.25);\n  stroke: rgba(0,0,0,0.6);\n}\n.parcoords .axis line, .parcoords .axis path {\n  fill: none;\n  stroke: #222;\n  shape-rendering: crispEdges;\n}\n.parcoords canvas {\n  opacity: 1;\n  -moz-transition: opacity 0.3s;\n  -webkit-transition: opacity 0.3s;\n  -o-transition: opacity 0.3s;\n}\n.parcoords canvas.faded {\n  opacity: 0.25;\n}\n.parcoords_grid { text-align: center; }\n.parcoords_grid .row, .header { clear: left; font-size: 16px; line-height: 18px; height: 18px; }\n.parcoords_grid .row:nth-child(odd) { background: rgba(0,0,0,0.05); }\n.parcoords_grid .row:hover { background: green; }\n.parcoords_grid .header { font-weight: bold; }\n.parcoords_grid .cell { float: left; overflow: hidden; white-space: nowrap; width: 120px; height: 18px; }\n.parcoords_grid .col-0 { width: 110px; }\n"
  },
  {
    "path": "google/datalab/notebook/static/extern/d3.parcoords.js",
    "content": "d3.parcoords = function(config) {\n  var __ = {\n    data: [],\n    highlighted: [],\n    dimensions: [],\n    dimensionTitles: {},\n    dimensionTitleRotation: 0,\n    types: {},\n    brushed: false,\n    mode: \"default\",\n    rate: 20,\n    width: 600,\n    height: 300,\n    margin: { top: 30, right: 0, bottom: 12, left: 0 },\n    color: \"#069\",\n    composite: \"source-over\",\n    alpha: 0.7,\n    bundlingStrength: 0.5,\n    bundleDimension: null,\n    smoothness: 0.25,\n    showControlPoints: false,\n    hideAxis : []\n  };\n\n  extend(__, config);\nvar pc = function(selection) {\n  selection = pc.selection = d3.select(selection);\n\n  __.width = selection[0][0].clientWidth;\n  __.height = selection[0][0].clientHeight;\n\n  // canvas data layers\n  [\"shadows\", \"marks\", \"foreground\", \"highlight\"].forEach(function(layer) {\n    canvas[layer] = selection\n      .append(\"canvas\")\n      .attr(\"class\", layer)[0][0];\n    ctx[layer] = canvas[layer].getContext(\"2d\");\n  });\n\n  // svg tick and brush layers\n  pc.svg = selection\n    .append(\"svg\")\n      .attr(\"width\", __.width)\n      .attr(\"height\", __.height)\n    .append(\"svg:g\")\n      .attr(\"transform\", \"translate(\" + __.margin.left + \",\" + __.margin.top + \")\");\n\n  return pc;\n};\nvar events = d3.dispatch.apply(this,[\"render\", \"resize\", \"highlight\", \"brush\", \"brushend\", \"axesreorder\"].concat(d3.keys(__))),\n    w = function() { return __.width - __.margin.right - __.margin.left; },\n    h = function() { return __.height - __.margin.top - __.margin.bottom; },\n    flags = {\n      brushable: false,\n      reorderable: false,\n      axes: false,\n      interactive: false,\n      shadows: false,\n      debug: false\n    },\n    xscale = d3.scale.ordinal(),\n    yscale = {},\n    dragging = {},\n    line = d3.svg.line(),\n    axis = d3.svg.axis().orient(\"left\").ticks(5),\n    g, // groups for axes, brushes\n    ctx = {},\n    canvas = {},\n    clusterCentroids = [];\n\n// side effects for setters\nvar side_effects = d3.dispatch.apply(this,d3.keys(__))\n  .on(\"composite\", function(d) { ctx.foreground.globalCompositeOperation = d.value; })\n  .on(\"alpha\", function(d) { ctx.foreground.globalAlpha = d.value; })\n  .on(\"width\", function(d) { pc.resize(); })\n  .on(\"height\", function(d) { pc.resize(); })\n  .on(\"margin\", function(d) { pc.resize(); })\n  .on(\"rate\", function(d) { rqueue.rate(d.value); })\n  .on(\"data\", function(d) {\n    if (flags.shadows){paths(__.data, ctx.shadows);}\n  })\n  .on(\"dimensions\", function(d) {\n    xscale.domain(__.dimensions);\n    if (flags.interactive){pc.render().updateAxes();}\n  })\n  .on(\"bundleDimension\", function(d) {\n\t  if (!__.dimensions.length) pc.detectDimensions();\n\t  if (!(__.dimensions[0] in yscale)) pc.autoscale();\n\t  if (typeof d.value === \"number\") {\n\t\t  if (d.value < __.dimensions.length) {\n\t\t\t  __.bundleDimension = __.dimensions[d.value];\n\t\t  } else if (d.value < __.hideAxis.length) {\n\t\t\t  __.bundleDimension = __.hideAxis[d.value];\n\t\t  }\n\t  } else {\n\t\t  __.bundleDimension = d.value;\n\t  }\n\n\t  __.clusterCentroids = compute_cluster_centroids(__.bundleDimension);\n  })\n  .on(\"hideAxis\", function(d) {\n\t  if (!__.dimensions.length) pc.detectDimensions();\n\t  pc.dimensions(without(__.dimensions, d.value));\n  });\n\n// expose the state of the chart\npc.state = __;\npc.flags = flags;\n\n// create getter/setters\ngetset(pc, __, events);\n\n// expose events\nd3.rebind(pc, events, \"on\");\n\n// tick formatting\nd3.rebind(pc, axis, \"ticks\", \"orient\", \"tickValues\", \"tickSubdivide\", \"tickSize\", \"tickPadding\", \"tickFormat\");\n\n// getter/setter with event firing\nfunction getset(obj,state,events)  {\n  d3.keys(state).forEach(function(key) {\n    obj[key] = function(x) {\n      if (!arguments.length) {\n\t\treturn state[key];\n\t}\n      var old = state[key];\n      state[key] = x;\n      side_effects[key].call(pc,{\"value\": x, \"previous\": old});\n      events[key].call(pc,{\"value\": x, \"previous\": old});\n      return obj;\n    };\n  });\n};\n\nfunction extend(target, source) {\n  for (key in source) {\n    target[key] = source[key];\n  }\n  return target;\n};\n\nfunction without(arr, item) {\n  return arr.filter(function(elem) { return item.indexOf(elem) === -1; })\n};\npc.autoscale = function() {\n  // yscale\n  var defaultScales = {\n    \"date\": function(k) {\n      return d3.time.scale()\n        .domain(d3.extent(__.data, function(d) {\n          return d[k] ? d[k].getTime() : null;\n        }))\n        .range([h()+1, 1]);\n    },\n    \"number\": function(k) {\n      return d3.scale.linear()\n        .domain(d3.extent(__.data, function(d) { return +d[k]; }))\n        .range([h()+1, 1]);\n    },\n    \"string\": function(k) {\n      var counts = {},\n          domain = [];\n\n      // Let's get the count for each value so that we can sort the domain based\n      // on the number of items for each value.\n      __.data.map(function(p) {\n        if (counts[p[k]] === undefined) {\n          counts[p[k]] = 1;\n        } else {\n          counts[p[k]] = counts[p[k]] + 1;\n        }\n      });\n\n      domain = Object.getOwnPropertyNames(counts).sort(function(a, b) {\n        return counts[a] - counts[b];\n      });\n\n      return d3.scale.ordinal()\n        .domain(domain)\n        .rangePoints([h()+1, 1]);\n    }\n  };\n\n  __.dimensions.forEach(function(k) {\n    yscale[k] = defaultScales[__.types[k]](k);\n  });\n\n  __.hideAxis.forEach(function(k) {\n    yscale[k] = defaultScales[__.types[k]](k);\n  });\n\n  // hack to remove ordinal dimensions with many values\n  pc.dimensions(pc.dimensions().filter(function(p,i) {\n    var uniques = yscale[p].domain().length;\n    if (__.types[p] == \"string\" && (uniques > 60 || uniques < 2)) {\n      return false;\n    }\n    return true;\n  }));\n\n  // xscale\n  xscale.rangePoints([0, w()], 1);\n\n  // canvas sizes\n  pc.selection.selectAll(\"canvas\")\n      .style(\"margin-top\", __.margin.top + \"px\")\n      .style(\"margin-left\", __.margin.left + \"px\")\n      .attr(\"width\", w()+2)\n      .attr(\"height\", h()+2);\n\n  // default styles, needs to be set when canvas width changes\n  ctx.foreground.strokeStyle = __.color;\n  ctx.foreground.lineWidth = 1.4;\n  ctx.foreground.globalCompositeOperation = __.composite;\n  ctx.foreground.globalAlpha = __.alpha;\n  ctx.highlight.lineWidth = 3;\n  ctx.shadows.strokeStyle = \"#dadada\";\n\n  return this;\n};\n\npc.scale = function(d, domain) {\n\tyscale[d].domain(domain);\n\n\treturn this;\n};\n\npc.flip = function(d) {\n\t//yscale[d].domain().reverse();\t\t\t\t\t// does not work\n\tyscale[d].domain(yscale[d].domain().reverse()); // works\n\n\treturn this;\n};\n\npc.commonScale = function(global, type) {\n\tvar t = type || \"number\";\n\tif (typeof global === 'undefined') {\n\t\tglobal = true;\n\t}\n\n\t// scales of the same type\n\tvar scales = __.dimensions.concat(__.hideAxis).filter(function(p) {\n\t\treturn __.types[p] == t;\n\t});\n\n\tif (global) {\n\t\tvar extent = d3.extent(scales.map(function(p,i) {\n\t\t\t\treturn yscale[p].domain();\n\t\t\t}).reduce(function(a,b) {\n\t\t\t\treturn a.concat(b);\n\t\t\t}));\n\n\t\tscales.forEach(function(d) {\n\t\t\tyscale[d].domain(extent);\n\t\t});\n\n\t} else {\n\t\tscales.forEach(function(k) {\n\t\t\tyscale[k].domain(d3.extent(__.data, function(d) { return +d[k]; }));\n\t\t});\n\t}\n\n\t// update centroids\n\tif (__.bundleDimension !== null) {\n\t\tpc.bundleDimension(__.bundleDimension);\n\t}\n\n\treturn this;\n};pc.detectDimensions = function() {\n  pc.types(pc.detectDimensionTypes(__.data));\n  pc.dimensions(d3.keys(pc.types()));\n  return this;\n};\n\n// a better \"typeof\" from this post: http://stackoverflow.com/questions/7390426/better-way-to-get-type-of-a-javascript-variable\npc.toType = function(v) {\n  return ({}).toString.call(v).match(/\\s([a-zA-Z]+)/)[1].toLowerCase();\n};\n\n// try to coerce to number before returning type\npc.toTypeCoerceNumbers = function(v) {\n  if ((parseFloat(v) == v) && (v != null)) {\n\treturn \"number\";\n}\n  return pc.toType(v);\n};\n\n// attempt to determine types of each dimension based on first row of data\npc.detectDimensionTypes = function(data) {\n  var types = {};\n  d3.keys(data[0])\n    .forEach(function(col) {\n      types[col] = pc.toTypeCoerceNumbers(data[0][col]);\n    });\n  return types;\n};\npc.render = function() {\n  // try to autodetect dimensions and create scales\n  if (!__.dimensions.length) pc.detectDimensions();\n  if (!(__.dimensions[0] in yscale)) pc.autoscale();\n\n  pc.render[__.mode]();\n\n  events.render.call(this);\n  return this;\n};\n\npc.render['default'] = function() {\n  pc.clear('foreground');\n  if (__.brushed) {\n    __.brushed.forEach(path_foreground);\n    __.highlighted.forEach(path_highlight);\n  } else {\n    __.data.forEach(path_foreground);\n    __.highlighted.forEach(path_highlight);\n  }\n};\n\nvar rqueue = d3.renderQueue(path_foreground)\n  .rate(50)\n  .clear(function() {\n    pc.clear('foreground');\n    pc.clear('highlight');\n  });\n\npc.render.queue = function() {\n  if (__.brushed) {\n    rqueue(__.brushed);\n    __.highlighted.forEach(path_highlight);\n  } else {\n    rqueue(__.data);\n    __.highlighted.forEach(path_highlight);\n  }\n};\nfunction compute_cluster_centroids(d) {\n\n\tvar clusterCentroids = d3.map();\n\tvar clusterCounts = d3.map();\n\t// determine clusterCounts\n\t__.data.forEach(function(row) {\n\t\tvar scaled = yscale[d](row[d]);\n\t\tif (!clusterCounts.has(scaled)) {\n\t\t\tclusterCounts.set(scaled, 0);\n\t\t}\n\t\tvar count = clusterCounts.get(scaled);\n\t\tclusterCounts.set(scaled, count + 1);\n\t});\n\n\t__.data.forEach(function(row) {\n\t\t__.dimensions.map(function(p, i) {\n\t\t\tvar scaled = yscale[d](row[d]);\n\t\t\tif (!clusterCentroids.has(scaled)) {\n\t\t\t\tvar map = d3.map();\n\t\t\t\tclusterCentroids.set(scaled, map);\n\t\t\t}\n\t\t\tif (!clusterCentroids.get(scaled).has(p)) {\n\t\t\t\tclusterCentroids.get(scaled).set(p, 0);\n\t\t\t}\n\t\t\tvar value = clusterCentroids.get(scaled).get(p);\n\t\t\tvalue += yscale[p](row[p]) / clusterCounts.get(scaled);\n\t\t\tclusterCentroids.get(scaled).set(p, value);\n\t\t});\n\t});\n\n\treturn clusterCentroids;\n\n}\n\nfunction compute_centroids(row) {\n\tvar centroids = [];\n\n\tvar p = __.dimensions;\n\tvar cols = p.length;\n\tvar a = 0.5;\t\t\t// center between axes\n\tfor (var i = 0; i < cols; ++i) {\n\t\t// centroids on 'real' axes\n\t\tvar x = position(p[i]);\n\t\tvar y = yscale[p[i]](row[p[i]]);\n    centroids.push([x, y]);\n\t\t//centroids.push($V([x, y]));\n\n\t\t// centroids on 'virtual' axes\n\t\tif (i < cols - 1) {\n\t\t\tvar cx = x + a * (position(p[i+1]) - x);\n\t\t\tvar cy = y + a * (yscale[p[i+1]](row[p[i+1]]) - y);\n\t\t\tif (__.bundleDimension !== null) {\n\t\t\t\tvar leftCentroid = __.clusterCentroids.get(yscale[__.bundleDimension](row[__.bundleDimension])).get(p[i]);\n\t\t\t\tvar rightCentroid = __.clusterCentroids.get(yscale[__.bundleDimension](row[__.bundleDimension])).get(p[i+1]);\n\t\t\t\tvar centroid = 0.5 * (leftCentroid + rightCentroid);\n\t\t\t\tcy = centroid + (1 - __.bundlingStrength) * (cy - centroid);\n\t\t\t}\n      centroids.push([cx, cy]);\n\t\t\t//centroids.push($V([cx, cy]));\n\t\t}\n\t}\n\n\treturn centroids;\n}\n\npc.compute_centroids = compute_centroids;\n\nfunction compute_control_points(centroids) {\n\n\tvar cols = centroids.length;\n\tvar a = __.smoothness;\n\tvar cps = [];\n\n\tcps.push(centroids[0]);\n\tcps.push($V([centroids[0].e(1) + a*2*(centroids[1].e(1)-centroids[0].e(1)), centroids[0].e(2)]));\n\tfor (var col = 1; col < cols - 1; ++col) {\n\t\tvar mid = centroids[col];\n\t\tvar left = centroids[col - 1];\n\t\tvar right = centroids[col + 1];\n\n\t\tvar diff = left.subtract(right);\n\t\tcps.push(mid.add(diff.x(a)));\n\t\tcps.push(mid);\n\t\tcps.push(mid.subtract(diff.x(a)));\n\t}\n\tcps.push($V([centroids[cols-1].e(1) + a*2*(centroids[cols-2].e(1)-centroids[cols-1].e(1)), centroids[cols-1].e(2)]));\n\tcps.push(centroids[cols - 1]);\n\n\treturn cps;\n\n};pc.shadows = function() {\n\tflags.shadows = true;\n\tif (__.data.length > 0) {\n\t\tpaths(__.data, ctx.shadows);\n\t}\n\treturn this;\n};\n\n// draw little dots on the axis line where data intersects\npc.axisDots = function() {\n\tvar ctx = pc.ctx.marks;\n\tctx.globalAlpha = d3.min([ 1 / Math.pow(data.length, 1 / 2), 1 ]);\n\t__.data.forEach(function(d) {\n\t\t__.dimensions.map(function(p, i) {\n\t\t\tctx.fillRect(position(p) - 0.75, yscale[p](d[p]) - 0.75, 1.5, 1.5);\n\t\t});\n\t});\n\treturn this;\n};\n\n// draw single cubic bezier curve\nfunction single_curve(d, ctx) {\n\n\tvar centroids = compute_centroids(d);\n\tvar cps = compute_control_points(centroids);\n\n\tctx.moveTo(cps[0].e(1), cps[0].e(2));\n\tfor (var i = 1; i < cps.length; i += 3) {\n\t\tif (__.showControlPoints) {\n\t\t\tfor (var j = 0; j < 3; j++) {\n\t\t\t\tctx.fillRect(cps[i+j].e(1), cps[i+j].e(2), 2, 2);\n\t\t\t}\n\t\t}\n\t\tctx.bezierCurveTo(cps[i].e(1), cps[i].e(2), cps[i+1].e(1), cps[i+1].e(2), cps[i+2].e(1), cps[i+2].e(2));\n\t}\n};\n\n// draw single polyline\nfunction color_path(d, i, ctx) {\n\tctx.strokeStyle = d3.functor(__.color)(d, i);\n\tctx.beginPath();\n\tif (__.bundleDimension === null || (__.bundlingStrength === 0 && __.smoothness == 0)) {\n\t\tsingle_path(d, ctx);\n\t} else {\n\t\tsingle_curve(d, ctx);\n\t}\n\tctx.stroke();\n};\n\n// draw many polylines of the same color\nfunction paths(data, ctx) {\n\tctx.clearRect(-1, -1, w() + 2, h() + 2);\n\tctx.beginPath();\n\tdata.forEach(function(d) {\n\t\tif (__.bundleDimension === null || (__.bundlingStrength === 0 && __.smoothness == 0)) {\n\t\t\tsingle_path(d, ctx);\n\t\t} else {\n\t\t\tsingle_curve(d, ctx);\n\t\t}\n\t});\n\tctx.stroke();\n};\n\nfunction single_path(d, ctx) {\n\t__.dimensions.map(function(p, i) {\n\t\tif (i == 0) {\n\t\t\tctx.moveTo(position(p), yscale[p](d[p]));\n\t\t} else {\n\t\t\tctx.lineTo(position(p), yscale[p](d[p]));\n\t\t}\n\t});\n}\n\nfunction path_foreground(d, i) {\n\treturn color_path(d, i, ctx.foreground);\n};\n\nfunction path_highlight(d, i) {\n\treturn color_path(d, i, ctx.highlight);\n};\npc.clear = function(layer) {\n  ctx[layer].clearRect(0,0,w()+2,h()+2);\n  return this;\n};\nfunction flipAxisAndUpdatePCP(dimension, i) {\n  var g = pc.svg.selectAll(\".dimension\");\n\n  pc.flip(dimension);\n  d3.select(g[0][i])\n    .transition()\n      .duration(1100)\n      .call(axis.scale(yscale[dimension]));\n\n  pc.render();\n  if (flags.shadows) paths(__.data, ctx.shadows);\n}\n\nfunction rotateLabels() {\n  var delta = d3.event.deltaY;\n  delta = delta < 0 ? -5 : delta;\n  delta = delta > 0 ? 5 : delta;\n\n  __.dimensionTitleRotation += delta;\n  pc.svg.selectAll(\"text.label\")\n    .attr(\"transform\", \"translate(0,-5) rotate(\" + __.dimensionTitleRotation + \")\");\n  d3.event.preventDefault();\n}\n\npc.createAxes = function() {\n  if (g) pc.removeAxes();\n\n  // Add a group element for each dimension.\n  g = pc.svg.selectAll(\".dimension\")\n      .data(__.dimensions, function(d) { return d; })\n    .enter().append(\"svg:g\")\n      .attr(\"class\", \"dimension\")\n      .attr(\"transform\", function(d) { return \"translate(\" + xscale(d) + \")\"; });\n\n  // Add an axis and title.\n  g.append(\"svg:g\")\n      .attr(\"class\", \"axis\")\n      .attr(\"transform\", \"translate(0,0)\")\n      .each(function(d) { d3.select(this).call(axis.scale(yscale[d])); })\n    .append(\"svg:text\")\n      .attr({\n        \"text-anchor\": \"middle\",\n        \"y\": 0,\n        \"transform\": \"translate(0,-5) rotate(\" + __.dimensionTitleRotation + \")\",\n        \"x\": 0,\n        \"class\": \"label\"\n      })\n      .text(function(d) {\n        return d in __.dimensionTitles ? __.dimensionTitles[d] : d;  // dimension display names\n      })\n      .on(\"dblclick\", flipAxisAndUpdatePCP)\n      .on(\"wheel\", rotateLabels);\n\n  flags.axes= true;\n  return this;\n};\n\npc.removeAxes = function() {\n  g.remove();\n  return this;\n};\n\npc.updateAxes = function() {\n  var g_data = pc.svg.selectAll(\".dimension\").data(__.dimensions);\n\n  // Enter\n  g_data.enter().append(\"svg:g\")\n      .attr(\"class\", \"dimension\")\n      .attr(\"transform\", function(p) { return \"translate(\" + position(p) + \")\"; })\n      .style(\"opacity\", 0)\n    .append(\"svg:g\")\n      .attr(\"class\", \"axis\")\n      .attr(\"transform\", \"translate(0,0)\")\n      .each(function(d) { d3.select(this).call(axis.scale(yscale[d])); })\n    .append(\"svg:text\")\n      .attr({\n        \"text-anchor\": \"middle\",\n        \"y\": 0,\n        \"transform\": \"translate(0,-5) rotate(\" + __.dimensionTitleRotation + \")\",\n        \"x\": 0,\n        \"class\": \"label\"\n      })\n      .text(String)\n      .on(\"dblclick\", flipAxisAndUpdatePCP)\n      .on(\"wheel\", rotateLabels);\n\n  // Update\n  g_data.attr(\"opacity\", 0);\n  g_data.select(\".axis\")\n    .transition()\n      .duration(1100)\n      .each(function(d) {\n        d3.select(this).call(axis.scale(yscale[d]));\n      });\n  g_data.select(\".label\")\n    .transition()\n      .duration(1100)\n      .text(String)\n      .attr(\"transform\", \"translate(0,-5) rotate(\" + __.dimensionTitleRotation + \")\");\n\n  // Exit\n  g_data.exit().remove();\n\n  g = pc.svg.selectAll(\".dimension\");\n  g.transition().duration(1100)\n    .attr(\"transform\", function(p) { return \"translate(\" + position(p) + \")\"; })\n    .style(\"opacity\", 1);\n\n  pc.svg.selectAll(\".axis\")\n    .transition()\n      .duration(1100)\n      .each(function(d) { d3.select(this).call(axis.scale(yscale[d])); });\n\n  if (flags.shadows) paths(__.data, ctx.shadows);\n  if (flags.brushable) pc.brushable();\n  if (flags.reorderable) pc.reorderable();\n  if (pc.brushMode() !== \"None\") {\n    var mode = pc.brushMode();\n    pc.brushMode(\"None\");\n    pc.brushMode(mode);\n  }\n  return this;\n};\n\n// Jason Davies, http://bl.ocks.org/1341281\npc.reorderable = function() {\n  if (!g) pc.createAxes();\n\n  // Keep track of the order of the axes to verify if the order has actually\n  // changed after a drag ends. Changed order might have consequence (e.g.\n  // strums that need to be reset).\n  var dimsAtDragstart;\n\n  g.style(\"cursor\", \"move\")\n    .call(d3.behavior.drag()\n      .on(\"dragstart\", function(d) {\n        dragging[d] = this.__origin__ = xscale(d);\n        dimsAtDragstart = __.dimensions.slice();\n      })\n      .on(\"drag\", function(d) {\n        dragging[d] = Math.min(w(), Math.max(0, this.__origin__ += d3.event.dx));\n        __.dimensions.sort(function(a, b) { return position(a) - position(b); });\n        xscale.domain(__.dimensions);\n        pc.render();\n        g.attr(\"transform\", function(d) { return \"translate(\" + position(d) + \")\"; });\n      })\n      .on(\"dragend\", function(d, i) {\n        // Let's see if the order has changed and send out an event if so.\n        var j = __.dimensions.indexOf(d),\n            parent = this.parentElement;\n\n        if (i !== j) {\n          events.axesreorder.call(pc, __.dimensions);\n          // We now also want to reorder the actual dom elements that represent\n          // the axes. That is, the g.dimension elements. If we don't do this,\n          // we get a weird and confusing transition when updateAxes is called.\n          // This is due to the fact that, initially the nth g.dimension element\n          // represents the nth axis. However, after a manual reordering,\n          // without reordering the dom elements, the nth dom elements no longer\n          // necessarily represents the nth axis.\n          //\n          // i is the original index of the dom element\n          // j is the new index of the dom element\n          parent.insertBefore(this, parent.children[j + 1])\n        }\n\n        delete this.__origin__;\n        delete dragging[d];\n        d3.select(this).transition().attr(\"transform\", \"translate(\" + xscale(d) + \")\");\n        pc.render();\n        if (flags.shadows) paths(__.data, ctx.shadows);\n      }));\n  flags.reorderable = true;\n  return this;\n};\n\n// pairs of adjacent dimensions\npc.adjacent_pairs = function(arr) {\n  var ret = [];\n  for (var i = 0; i < arr.length-1; i++) {\n    ret.push([arr[i],arr[i+1]]);\n  };\n  return ret;\n};\n\nvar brush = {\n  modes: {\n    \"None\": {\n      install: function(pc) {},           // Nothing to be done.\n      uninstall: function(pc) {},         // Nothing to be done.\n      selected: function() { return []; } // Nothing to return\n    }\n  },\n  mode: \"None\",\n  predicate: \"AND\",\n  currentMode: function() {\n    return this.modes[this.mode];\n  }\n};\n\n// This function can be used for 'live' updates of brushes. That is, during the\n// specification of a brush, this method can be called to update the view.\n//\n// @param newSelection - The new set of data items that is currently contained\n//                       by the brushes\nfunction brushUpdated(newSelection) {\n  __.brushed = newSelection;\n  events.brush.call(pc,__.brushed);\n  pc.render();\n}\n\nfunction brushPredicate(predicate) {\n  if (!arguments.length) { return brush.predicate; }\n\n  predicate = String(predicate).toUpperCase();\n  if (predicate !== \"AND\" && predicate !== \"OR\") {\n    throw \"Invalid predicate \" + predicate;\n  }\n\n  brush.predicate = predicate;\n  __.brushed = brush.currentMode().selected();\n  pc.render();\n  return pc;\n}\n\npc.brushModes = function() {\n  return Object.getOwnPropertyNames(brush.modes);\n};\n\npc.brushMode = function(mode) {\n  if (arguments.length === 0) {\n    return brush.mode;\n  }\n\n  if (pc.brushModes().indexOf(mode) === -1) {\n    throw \"pc.brushmode: Unsupported brush mode: \" + mode;\n  }\n\n  // Make sure that we don't trigger unnecessary events by checking if the mode\n  // actually changes.\n  if (mode !== brush.mode) {\n    // When changing brush modes, the first thing we need to do is clearing any\n    // brushes from the current mode, if any.\n    if (brush.mode !== \"None\") {\n      pc.brushReset();\n    }\n\n    // Next, we need to 'uninstall' the current brushMode.\n    brush.modes[brush.mode].uninstall(pc);\n    // Finally, we can install the requested one.\n    brush.mode = mode;\n    brush.modes[brush.mode].install();\n    if (mode === \"None\") {\n      delete pc.brushPredicate;\n    } else {\n      pc.brushPredicate = brushPredicate;\n    }\n  }\n\n  return pc;\n};\n\n// brush mode: 1D-Axes\n\n(function() {\n  var brushes = {};\n\n  function is_brushed(p) {\n    return !brushes[p].empty();\n  }\n\n  // data within extents\n  function selected() {\n    var actives = __.dimensions.filter(is_brushed),\n        extents = actives.map(function(p) { return brushes[p].extent(); });\n\n    // We don't want to return the full data set when there are no axes brushed.\n    // Actually, when there are no axes brushed, by definition, no items are\n    // selected. So, let's avoid the filtering and just return false.\n    //if (actives.length === 0) return false;\n\n    // Resolves broken examples for now. They expect to get the full dataset back from empty brushes\n    if (actives.length === 0) return __.data;\n\n    // test if within range\n    var within = {\n      \"date\": function(d,p,dimension) {\n        return extents[dimension][0] <= d[p] && d[p] <= extents[dimension][1]\n      },\n      \"number\": function(d,p,dimension) {\n        return extents[dimension][0] <= d[p] && d[p] <= extents[dimension][1]\n      },\n      \"string\": function(d,p,dimension) {\n        return extents[dimension][0] <= yscale[p](d[p]) && yscale[p](d[p]) <= extents[dimension][1]\n      }\n    };\n\n    return __.data\n      .filter(function(d) {\n        switch(brush.predicate) {\n        case \"AND\":\n          return actives.every(function(p, dimension) {\n            return within[__.types[p]](d,p,dimension);\n          });\n        case \"OR\":\n          return actives.some(function(p, dimension) {\n            return within[__.types[p]](d,p,dimension);\n          });\n        default:\n          throw \"Unknown brush predicate \" + __.brushPredicate;\n        }\n      });\n  };\n\n  function brushExtents() {\n    var extents = {};\n    __.dimensions.forEach(function(d) {\n      var brush = brushes[d];\n      if (!brush.empty()) {\n        var extent = brush.extent();\n        extent.sort(d3.ascending);\n        extents[d] = extent;\n      }\n    });\n    return extents;\n  }\n\n  function brushFor(axis) {\n    var brush = d3.svg.brush();\n\n    brush\n      .y(yscale[axis])\n      .on(\"brushstart\", function() { d3.event.sourceEvent.stopPropagation() })\n      .on(\"brush\", function() {\n        brushUpdated(selected());\n      })\n      .on(\"brushend\", function() {\n        events.brushend.call(pc, __.brushed);\n      });\n\n    brushes[axis] = brush;\n    return brush;\n  }\n\n  function brushReset(dimension) {\n    __.brushed = false;\n    if (g) {\n      g.selectAll('.brush')\n        .each(function(d) {\n          d3.select(this).call(\n            brushes[d].clear()\n          );\n        });\n      pc.render();\n    }\n    return this;\n  };\n\n  function install() {\n    if (!g) pc.createAxes();\n\n    // Add and store a brush for each axis.\n    g.append(\"svg:g\")\n      .attr(\"class\", \"brush\")\n      .each(function(d) {\n        d3.select(this).call(brushFor(d));\n      })\n      .selectAll(\"rect\")\n        .style(\"visibility\", null)\n        .attr(\"x\", -15)\n        .attr(\"width\", 30);\n\n    pc.brushExtents = brushExtents;\n    pc.brushReset = brushReset;\n    return pc;\n  }\n\n  brush.modes[\"1D-axes\"] = {\n    install: install,\n    uninstall: function() {\n      g.selectAll(\".brush\").remove();\n      brushes = {};\n      delete pc.brushExtents;\n      delete pc.brushReset;\n    },\n    selected: selected\n  }\n})();\n// brush mode: 2D-strums\n// bl.ocks.org/syntagmatic/5441022\n\n(function() {\n  var strums = {},\n      strumRect;\n\n  function drawStrum(strum, activePoint) {\n    var svg = pc.selection.select(\"svg\").select(\"g#strums\"),\n        id = strum.dims.i,\n        points = [strum.p1, strum.p2],\n        line = svg.selectAll(\"line#strum-\" + id).data([strum]),\n        circles = svg.selectAll(\"circle#strum-\" + id).data(points),\n        drag = d3.behavior.drag();\n\n    line.enter()\n      .append(\"line\")\n      .attr(\"id\", \"strum-\" + id)\n      .attr(\"class\", \"strum\");\n\n    line\n      .attr(\"x1\", function(d) { return d.p1[0]; })\n      .attr(\"y1\", function(d) { return d.p1[1]; })\n      .attr(\"x2\", function(d) { return d.p2[0]; })\n      .attr(\"y2\", function(d) { return d.p2[1]; })\n      .attr(\"stroke\", \"black\")\n      .attr(\"stroke-width\", 2);\n\n    drag\n      .on(\"drag\", function(d, i) { \n        var ev = d3.event;\n        i = i + 1;\n        strum[\"p\" + i][0] = Math.min(Math.max(strum.minX + 1, ev.x), strum.maxX);\n        strum[\"p\" + i][1] = Math.min(Math.max(strum.minY, ev.y), strum.maxY);\n        drawStrum(strum, i - 1);\n      })\n      .on(\"dragend\", onDragEnd());\n\n    circles.enter()\n      .append(\"circle\")\n      .attr(\"id\", \"strum-\" + id)\n      .attr(\"class\", \"strum\");\n\n    circles\n      .attr(\"cx\", function(d) { return d[0]; })\n      .attr(\"cy\", function(d) { return d[1]; })\n      .attr(\"r\", 5)\n      .style(\"opacity\", function(d, i) {\n        return (activePoint !== undefined && i === activePoint) ? 0.8 : 0;\n      })\n      .on(\"mouseover\", function() {\n        d3.select(this).style(\"opacity\", 0.8);\n      })\n      .on(\"mouseout\", function() {\n        d3.select(this).style(\"opacity\", 0);\n      })\n      .call(drag);\n  }\n\n  function dimensionsForPoint(p) {\n    var dims = { i: -1, left: undefined, right: undefined };\n    __.dimensions.some(function(dim, i) {\n      if (xscale(dim) < p[0]) {\n        var next = __.dimensions[i + 1];\n        dims.i = i;\n        dims.left = dim;\n        dims.right = next;\n        return false;\n      }\n      return true;\n    });\n\n    if (dims.left === undefined) {\n      // Event on the left side of the first axis.\n      dims.i = 0;\n      dims.left = __.dimensions[0];\n      dims.right = __.dimensions[1];\n    } else if (dims.right === undefined) {\n      // Event on the right side of the last axis\n      dims.i = __.dimensions.length - 1;\n      dims.right = dims.left;\n      dims.left = __.dimensions[__.dimensions.length - 2];\n    }\n\n    return dims;\n  }\n\n  function onDragStart() {\n    // First we need to determine between which two axes the sturm was started.\n    // This will determine the freedom of movement, because a strum can\n    // logically only happen between two axes, so no movement outside these axes\n    // should be allowed.\n    return function() {\n      var p = d3.mouse(strumRect[0][0]),\n          dims = dimensionsForPoint(p),\n          strum = {\n            p1: p,\n            dims: dims,\n            minX: xscale(dims.left),\n            maxX: xscale(dims.right),\n            minY: 0,\n            maxY: h()\n          };\n\n      strums[dims.i] = strum;\n      strums.active = dims.i;\n\n      // Make sure that the point is within the bounds\n      strum.p1[0] = Math.min(Math.max(strum.minX, p[0]), strum.maxX);\n      strum.p1[1] = p[1] - __.margin.top;\n      strum.p2 = strum.p1.slice();\n    };\n  }\n\n  function onDrag() {\n    return function() {\n      var ev = d3.event,\n          strum = strums[strums.active];\n\n      // Make sure that the point is within the bounds\n      strum.p2[0] = Math.min(Math.max(strum.minX + 1, ev.x), strum.maxX);\n      strum.p2[1] = Math.min(Math.max(strum.minY, ev.y - __.margin.top), strum.maxY);\n      drawStrum(strum, 1);\n    };\n  }\n\n  function containmentTest(strum, width) {\n    var p1 = [strum.p1[0] - strum.minX, strum.p1[1] - strum.minX],\n        p2 = [strum.p2[0] - strum.minX, strum.p2[1] - strum.minX],\n        m1 = 1 - width / p1[0],\n        b1 = p1[1] * (1 - m1),\n        m2 = 1 - width / p2[0],\n        b2 = p2[1] * (1 - m2);\n\n    // test if point falls between lines\n    return function(p) {\n      var x = p[0],\n          y = p[1],\n          y1 = m1 * x + b1,\n          y2 = m2 * x + b2;\n\n      if (y > Math.min(y1, y2) && y < Math.max(y1, y2)) {\n        return true;\n      }\n\n      return false;\n    };\n  }\n\n  function selected() {\n    var ids = Object.getOwnPropertyNames(strums),\n        brushed = __.data;\n\n    // Get the ids of the currently active strums.\n    ids = ids.filter(function(d) {\n      return !isNaN(d);\n    });\n\n    function crossesStrum(d, id) {\n      var strum = strums[id],\n          test = containmentTest(strum, strums.width(id)),\n          d1 = strum.dims.left,\n          d2 = strum.dims.right,\n          y1 = yscale[d1],\n          y2 = yscale[d2],\n          point = [y1(d[d1]) - strum.minX, y2(d[d2]) - strum.minX];\n      return test(point);\n    }\n\n    if (ids.length === 0) { return brushed; }\n\n    return brushed.filter(function(d) {\n      switch(brush.predicate) {\n      case \"AND\":\n        return ids.every(function(id) { return crossesStrum(d, id); });\n      case \"OR\":\n        return ids.some(function(id) { return crossesStrum(d, id); });\n      default:\n        throw \"Unknown brush predicate \" + __.brushPredicate;\n      }\n    });\n  }\n\n  function removeStrum() {\n    var strum = strums[strums.active],\n        svg = pc.selection.select(\"svg\").select(\"g#strums\");\n\n    delete strums[strums.active];\n    strums.active = undefined;\n    svg.selectAll(\"line#strum-\" + strum.dims.i).remove();\n    svg.selectAll(\"circle#strum-\" + strum.dims.i).remove();\n  }\n\n  function onDragEnd() {\n    return function() {\n      var brushed = __.data,\n          strum = strums[strums.active];\n\n      // Okay, somewhat unexpected, but not totally unsurprising, a mousclick is\n      // considered a drag without move. So we have to deal with that case\n      if (strum && strum.p1[0] === strum.p2[0] && strum.p1[1] === strum.p2[1]) {\n        removeStrum(strums);\n      }\n\n      brushed = selected(strums);\n      strums.active = undefined;\n      __.brushed = brushed;\n      pc.render();\n      events.brushend.call(pc, __.brushed);\n    };\n  }\n\n  function brushReset(strums) {\n    return function() {\n      var ids = Object.getOwnPropertyNames(strums).filter(function(d) {\n        return !isNaN(d);\n      });\n\n      ids.forEach(function(d) {\n        strums.active = d;\n        removeStrum(strums);\n      });\n      onDragEnd(strums)();\n    };\n  }\n\n  function install() {\n    var drag = d3.behavior.drag();\n\n    // Map of current strums. Strums are stored per segment of the PC. A segment,\n    // being the area between two axes. The left most area is indexed at 0.\n    strums.active = undefined;\n    // Returns the width of the PC segment where currently a strum is being\n    // placed. NOTE: even though they are evenly spaced in our current\n    // implementation, we keep for when non-even spaced segments are supported as\n    // well.\n    strums.width = function(id) {\n      var strum = strums[id];\n\n      if (strum === undefined) {\n        return undefined;\n      }\n\n      return strum.maxX - strum.minX;\n    };\n\n    pc.on(\"axesreorder.strums\", function() {\n      var ids = Object.getOwnPropertyNames(strums).filter(function(d) {\n        return !isNaN(d);\n      });\n\n      // Checks if the first dimension is directly left of the second dimension.\n      function consecutive(first, second) {\n        var length = __.dimensions.length;\n        return __.dimensions.some(function(d, i) {\n          return (d === first)\n            ? i + i < length && __.dimensions[i + 1] === second\n            : false;\n        });\n      }\n\n      if (ids.length > 0) { // We have some strums, which might need to be removed.\n        ids.forEach(function(d) {\n          var dims = strums[d].dims;\n          strums.active = d;\n          // If the two dimensions of the current strum are not next to each other\n          // any more, than we'll need to remove the strum. Otherwise we keep it.\n          if (!consecutive(dims.left, dims.right)) {\n            removeStrum(strums);\n          }\n        });\n        onDragEnd(strums)();\n      }\n    });\n\n    // Add a new svg group in which we draw the strums.\n    pc.selection.select(\"svg\").append(\"g\")\n      .attr(\"id\", \"strums\")\n      .attr(\"transform\", \"translate(\" + __.margin.left + \",\" + __.margin.top + \")\");\n\n    // Install the required brushReset function\n    pc.brushReset = brushReset(strums);\n\n    drag\n      .on(\"dragstart\", onDragStart(strums))\n      .on(\"drag\", onDrag(strums))\n      .on(\"dragend\", onDragEnd(strums));\n\n    // NOTE: The styling needs to be done here and not in the css. This is because\n    //       for 1D brushing, the canvas layers should not listen to\n    //       pointer-events.\n    strumRect = pc.selection.select(\"svg\").insert(\"rect\", \"g#strums\")\n      .attr(\"id\", \"strum-events\")\n      .attr(\"x\", __.margin.left)\n      .attr(\"y\", __.margin.top)\n      .attr(\"width\", w())\n      .attr(\"height\", h() + 2)\n      .style(\"opacity\", 0)\n      .call(drag);\n  }\n\n  brush.modes[\"2D-strums\"] = {\n    install: install,\n    uninstall: function() {\n      pc.selection.select(\"svg\").select(\"g#strums\").remove();\n      pc.selection.select(\"svg\").select(\"rect#strum-events\").remove();\n      pc.on(\"axesreorder.strums\", undefined);\n      delete pc.brushReset;\n\n      strumRect = undefined;\n    },\n    selected: selected\n  };\n\n}());\n\npc.interactive = function() {\n  flags.interactive = true;\n  return this;\n};\n\n// expose a few objects\npc.xscale = xscale;\npc.yscale = yscale;\npc.ctx = ctx;\npc.canvas = canvas;\npc.g = function() { return g; };\n\n// rescale for height, width and margins\n// TODO currently assumes chart is brushable, and destroys old brushes\npc.resize = function() {\n  // selection size\n  pc.selection.select(\"svg\")\n    .attr(\"width\", __.width)\n    .attr(\"height\", __.height)\n  pc.svg.attr(\"transform\", \"translate(\" + __.margin.left + \",\" + __.margin.top + \")\");\n\n  // FIXME: the current brush state should pass through\n  if (flags.brushable) pc.brushReset();\n\n  // scales\n  pc.autoscale();\n\n  // axes, destroys old brushes.\n  if (g) pc.createAxes();\n  if (flags.shadows) paths(__.data, ctx.shadows);\n  if (flags.brushable) pc.brushable();\n  if (flags.reorderable) pc.reorderable();\n\n  events.resize.call(this, {width: __.width, height: __.height, margin: __.margin});\n  return this;\n};\n\n// highlight an array of data\npc.highlight = function(data) {\n  if (arguments.length === 0) {\n    return __.highlighted;\n  }\n\n  __.highlighted = data;\n  pc.clear(\"highlight\");\n  d3.select(canvas.foreground).classed(\"faded\", true);\n  data.forEach(path_highlight);\n  events.highlight.call(this, data);\n  return this;\n};\n\n// clear highlighting\npc.unhighlight = function() {\n  __.highlighted = [];\n  pc.clear(\"highlight\");\n  d3.select(canvas.foreground).classed(\"faded\", false);\n  return this;\n};\n\n// calculate 2d intersection of line a->b with line c->d\n// points are objects with x and y properties\npc.intersection =  function(a, b, c, d) {\n  return {\n    x: ((a.x * b.y - a.y * b.x) * (c.x - d.x) - (a.x - b.x) * (c.x * d.y - c.y * d.x)) / ((a.x - b.x) * (c.y - d.y) - (a.y - b.y) * (c.x - d.x)),\n    y: ((a.x * b.y - a.y * b.x) * (c.y - d.y) - (a.y - b.y) * (c.x * d.y - c.y * d.x)) / ((a.x - b.x) * (c.y - d.y) - (a.y - b.y) * (c.x - d.x))\n  };\n};\n\nfunction position(d) {\n  var v = dragging[d];\n  return v == null ? xscale(d) : v;\n}\npc.version = \"0.5.0\";\n  // this descriptive text should live with other introspective methods\n  pc.toString = function() { return \"Parallel Coordinates: \" + __.dimensions.length + \" dimensions (\" + d3.keys(__.data[0]).length + \" total) , \" + __.data.length + \" rows\"; };\n\n  return pc;\n};\n\nd3.renderQueue = (function(func) {\n  var _queue = [],                  // data to be rendered\n      _rate = 10,                   // number of calls per frame\n      _clear = function() {},       // clearing function\n      _i = 0;                       // current iteration\n\n  var rq = function(data) {\n    if (data) rq.data(data);\n    rq.invalidate();\n    _clear();\n    rq.render();\n  };\n\n  rq.render = function() {\n    _i = 0;\n    var valid = true;\n    rq.invalidate = function() { valid = false; };\n\n    function doFrame() {\n      if (!valid) return true;\n      if (_i > _queue.length) return true;\n\n      // Typical d3 behavior is to pass a data item *and* its index. As the\n      // render queue splits the original data set, we'll have to be slightly\n      // more carefull about passing the correct index with the data item.\n      var end = Math.min(_i + _rate, _queue.length);\n      for (var i = _i; i < end; i++) {\n        func(_queue[i], i);\n      }\n      _i += _rate;\n    }\n\n    d3.timer(doFrame);\n  };\n\n  rq.data = function(data) {\n    rq.invalidate();\n    _queue = data.slice(0);\n    return rq;\n  };\n\n  rq.rate = function(value) {\n    if (!arguments.length) return _rate;\n    _rate = value;\n    return rq;\n  };\n\n  rq.remaining = function() {\n    return _queue.length - _i;\n  };\n\n  // clear the canvas\n  rq.clear = function(func) {\n    if (!arguments.length) {\n      _clear();\n      return rq;\n    }\n    _clear = func;\n    return rq;\n  };\n\n  rq.invalidate = function() {};\n\n  return rq;\n});\n\nd3.divgrid = function(config) {\n  var columns = [];\n\n  var dg = function(selection) {\n    if (columns.length == 0) {\n      columns = d3.keys(selection.data()[0][0]);\n      columns = columns.filter( function(item) {\n        return (item.substr(item.length - 5) != \"(log)\");\n      });\n    }\n\n    // header\n    selection.selectAll(\".header\")\n        .data([true])\n      .enter().append(\"div\")\n        .attr(\"class\", \"header\")\n\n    var header = selection.select(\".header\")\n      .selectAll(\".cell\")\n      .data(columns);\n\n    header.enter().append(\"div\")\n      .attr(\"class\", function(d,i) { return \"col-\" + i; })\n      .classed(\"cell\", true)\n\n    selection.selectAll(\".header .cell\")\n      .text(function(d) { return d; });\n\n    header.exit().remove();\n\n    // rows\n    var rows = selection.selectAll(\".row\")\n        .data(function(d) { return d; })\n\n    rows.enter().append(\"div\")\n        .attr(\"class\", \"row\")\n\n    rows.exit().remove();\n\n    var cells = selection.selectAll(\".row\").selectAll(\".cell\")\n        .data(function(d) { return columns.map(function(col){return d[col];}) })\n\n    // cells\n    cells.enter().append(\"div\")\n      .attr(\"class\", function(d,i) { return \"col-\" + i; })\n      .classed(\"cell\", true)\n\n    cells.exit().remove();\n\n    selection.selectAll(\".cell\")\n      .text(function(d) { return d; });\n\n    return dg;\n  };\n\n  dg.columns = function(_) {\n    if (!arguments.length) return columns;\n    columns = _;\n    return this;\n  };\n\n  return dg;\n};\n"
  },
  {
    "path": "google/datalab/notebook/static/extern/facets-jupyter.html",
    "content": "<!doctype html><script>define=undefined</script><!--\n@license\nCopyright 2017 Google Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n\n@license\nCopyright (c) 2015 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n\n@license\nCopyright (c) 2014 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n\n@license\nCopyright (c) 2016 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n\n@license\nCopyright 2016 The TensorFlow Authors. All Rights Reserved.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n\n@license\nd3\nCopyright 2010-2017 Mike Bostock\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without modification,\nare permitted provided that the following conditions are met:\n\n* Redistributions of source code must retain the above copyright notice, this\n  list of conditions and the following disclaimer.\n\n* Redistributions in binary form must reproduce the above copyright notice,\n  this list of conditions and the following disclaimer in the documentation\n  and/or other materials provided with the distribution.\n\n* Neither the name of the author nor the names of contributors may be used to\n  endorse or promote products derived from this software without specific prior\n  written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\nANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR\nANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON\nANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n@license\nPlottable.js\nCopyright (c) 2014-2017 Palantir Technologies, Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n@license\nthree.js\nCopyright (c) 2010-2013 three.js authors\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n@license\nCopyright (c) 2017 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n--><script>// Copyright 2014 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n//     You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n//     See the License for the specific language governing permissions and\n// limitations under the License.\n\n!function(a,b){var c={},d={},e={},f=null;!function(a,b){function c(a){if(\"number\"==typeof a)return a;var b={};for(var c in a)b[c]=a[c];return b}function d(){this._delay=0,this._endDelay=0,this._fill=\"none\",this._iterationStart=0,this._iterations=1,this._duration=0,this._playbackRate=1,this._direction=\"normal\",this._easing=\"linear\",this._easingFunction=w}function e(){return a.isDeprecated(\"Invalid timing inputs\",\"2016-03-02\",\"TypeError exceptions will be thrown instead.\",!0)}function f(b,c,e){var f=new d;return c&&(f.fill=\"both\",f.duration=\"auto\"),\"number\"!=typeof b||isNaN(b)?void 0!==b&&Object.getOwnPropertyNames(b).forEach(function(c){if(\"auto\"!=b[c]){if((\"number\"==typeof f[c]||\"duration\"==c)&&(\"number\"!=typeof b[c]||isNaN(b[c])))return;if(\"fill\"==c&&-1==u.indexOf(b[c]))return;if(\"direction\"==c&&-1==v.indexOf(b[c]))return;if(\"playbackRate\"==c&&1!==b[c]&&a.isDeprecated(\"AnimationEffectTiming.playbackRate\",\"2014-11-28\",\"Use Animation.playbackRate instead.\"))return;f[c]=b[c]}}):f.duration=b,f}function g(a){return\"number\"==typeof a&&(a=isNaN(a)?{duration:0}:{duration:a}),a}function h(b,c){return b=a.numericTimingToObject(b),f(b,c)}function i(a,b,c,d){return 0>a||a>1||0>c||c>1?w:function(e){function f(a,b,c){return 3*a*(1-c)*(1-c)*c+3*b*(1-c)*c*c+c*c*c}if(0==e||1==e)return e;for(var g=0,h=1;;){var i=(g+h)/2,j=f(a,c,i);if(Math.abs(e-j)<1e-4)return f(b,d,i);e>j?g=i:h=i}}}function j(a,b){return function(c){if(c>=1)return 1;var d=1/a;return c+=b*d,c-c%d}}function k(a){B||(B=document.createElement(\"div\").style),B.animationTimingFunction=\"\",B.animationTimingFunction=a;var b=B.animationTimingFunction;if(\"\"==b&&e())throw new TypeError(a+\" is not a valid value for easing\");var c=D.exec(b);if(c)return i.apply(this,c.slice(1).map(Number));var d=E.exec(b);if(d)return j(Number(d[1]),{start:x,middle:y,end:z}[d[2]]);var f=A[b];return f?f:w}function l(a){return Math.abs(m(a)/a.playbackRate)}function m(a){return a.duration*a.iterations}function n(a,b,c){return null==b?F:b<c.delay?G:b>=c.delay+a?H:I}function o(a,b,c,d,e){switch(d){case G:return\"backwards\"==b||\"both\"==b?0:null;case I:return c-e;case H:return\"forwards\"==b||\"both\"==b?a:null;case F:return null}}function p(a,b,c,d){return(d.playbackRate<0?b-a:b)*d.playbackRate+c}function q(a,b,c,d,e){return c===1/0||c===-(1/0)||c-d==b&&e.iterations&&(e.iterations+e.iterationStart)%1==0?a:c%a}function r(a,b,c,d){return 0===c?0:b==a?d.iterationStart+d.iterations-1:Math.floor(c/a)}function s(a,b,c,d){var e=a%2>=1,f=\"normal\"==d.direction||d.direction==(e?\"alternate-reverse\":\"alternate\"),g=f?c:b-c,h=g/b;return b*d._easingFunction(h)}function t(a,b,c){var d=n(a,b,c),e=o(a,c.fill,b,d,c.delay);if(null===e)return null;if(0===a)return d===G?0:1;var f=c.iterationStart*c.duration,g=p(a,e,f,c),h=q(c.duration,m(c),g,f,c),i=r(c.duration,h,g,c);return s(i,c.duration,h,c)/c.duration}var u=\"backwards|forwards|both|none\".split(\"|\"),v=\"reverse|alternate|alternate-reverse\".split(\"|\"),w=function(a){return a};d.prototype={_setMember:function(b,c){this[\"_\"+b]=c,this._effect&&(this._effect._timingInput[b]=c,this._effect._timing=a.normalizeTimingInput(this._effect._timingInput),this._effect.activeDuration=a.calculateActiveDuration(this._effect._timing),this._effect._animation&&this._effect._animation._rebuildUnderlyingAnimation())},get playbackRate(){return this._playbackRate},set delay(a){this._setMember(\"delay\",a)},get delay(){return this._delay},set endDelay(a){this._setMember(\"endDelay\",a)},get endDelay(){return this._endDelay},set fill(a){this._setMember(\"fill\",a)},get fill(){return this._fill},set iterationStart(a){if((isNaN(a)||0>a)&&e())throw new TypeError(\"iterationStart must be a non-negative number, received: \"+timing.iterationStart);this._setMember(\"iterationStart\",a)},get iterationStart(){return this._iterationStart},set duration(a){if(\"auto\"!=a&&(isNaN(a)||0>a)&&e())throw new TypeError(\"duration must be non-negative or auto, received: \"+a);this._setMember(\"duration\",a)},get duration(){return this._duration},set direction(a){this._setMember(\"direction\",a)},get direction(){return this._direction},set easing(a){this._easingFunction=k(a),this._setMember(\"easing\",a)},get easing(){return this._easing},set iterations(a){if((isNaN(a)||0>a)&&e())throw new TypeError(\"iterations must be non-negative, received: \"+a);this._setMember(\"iterations\",a)},get iterations(){return this._iterations}};var x=1,y=.5,z=0,A={ease:i(.25,.1,.25,1),\"ease-in\":i(.42,0,1,1),\"ease-out\":i(0,0,.58,1),\"ease-in-out\":i(.42,0,.58,1),\"step-start\":j(1,x),\"step-middle\":j(1,y),\"step-end\":j(1,z)},B=null,C=\"\\\\s*(-?\\\\d+\\\\.?\\\\d*|-?\\\\.\\\\d+)\\\\s*\",D=new RegExp(\"cubic-bezier\\\\(\"+C+\",\"+C+\",\"+C+\",\"+C+\"\\\\)\"),E=/steps\\(\\s*(\\d+)\\s*,\\s*(start|middle|end)\\s*\\)/,F=0,G=1,H=2,I=3;a.cloneTimingInput=c,a.makeTiming=f,a.numericTimingToObject=g,a.normalizeTimingInput=h,a.calculateActiveDuration=l,a.calculateTimeFraction=t,a.calculatePhase=n,a.toTimingFunction=k}(c,f),function(a,b){function c(a,b){return a in j?j[a][b]||b:b}function d(a,b,d){var e=g[a];if(e){h.style[a]=b;for(var f in e){var i=e[f],j=h.style[i];d[i]=c(i,j)}}else d[a]=c(a,b)}function e(a){var b=[];for(var c in a)if(!(c in[\"easing\",\"offset\",\"composite\"])){var d=a[c];Array.isArray(d)||(d=[d]);for(var e,f=d.length,g=0;f>g;g++)e={},\"offset\"in a?e.offset=a.offset:1==f?e.offset=1:e.offset=g/(f-1),\"easing\"in a&&(e.easing=a.easing),\"composite\"in a&&(e.composite=a.composite),e[c]=d[g],b.push(e)}return b.sort(function(a,b){return a.offset-b.offset}),b}function f(a){function b(){var a=c.length;null==c[a-1].offset&&(c[a-1].offset=1),a>1&&null==c[0].offset&&(c[0].offset=0);for(var b=0,d=c[0].offset,e=1;a>e;e++){var f=c[e].offset;if(null!=f){for(var g=1;e-b>g;g++)c[b+g].offset=d+(f-d)*g/(e-b);b=e,d=f}}}if(null==a)return[];window.Symbol&&Symbol.iterator&&Array.prototype.from&&a[Symbol.iterator]&&(a=Array.from(a)),Array.isArray(a)||(a=e(a));for(var c=a.map(function(a){var b={};for(var c in a){var e=a[c];if(\"offset\"==c){if(null!=e&&(e=Number(e),!isFinite(e)))throw new TypeError(\"keyframe offsets must be numbers.\")}else{if(\"composite\"==c)throw{type:DOMException.NOT_SUPPORTED_ERR,name:\"NotSupportedError\",message:\"add compositing is not supported\"};e=\"\"+e}d(c,e,b)}return void 0==b.offset&&(b.offset=null),b}),f=!0,g=-(1/0),h=0;h<c.length;h++){var i=c[h].offset;if(null!=i){if(g>i)throw{code:DOMException.INVALID_MODIFICATION_ERR,name:\"InvalidModificationError\",message:\"Keyframes are not loosely sorted by offset. Sort or specify offsets.\"};g=i}else f=!1}return c=c.filter(function(a){return a.offset>=0&&a.offset<=1}),f||b(),c}var g={background:[\"backgroundImage\",\"backgroundPosition\",\"backgroundSize\",\"backgroundRepeat\",\"backgroundAttachment\",\"backgroundOrigin\",\"backgroundClip\",\"backgroundColor\"],border:[\"borderTopColor\",\"borderTopStyle\",\"borderTopWidth\",\"borderRightColor\",\"borderRightStyle\",\"borderRightWidth\",\"borderBottomColor\",\"borderBottomStyle\",\"borderBottomWidth\",\"borderLeftColor\",\"borderLeftStyle\",\"borderLeftWidth\"],borderBottom:[\"borderBottomWidth\",\"borderBottomStyle\",\"borderBottomColor\"],borderColor:[\"borderTopColor\",\"borderRightColor\",\"borderBottomColor\",\"borderLeftColor\"],borderLeft:[\"borderLeftWidth\",\"borderLeftStyle\",\"borderLeftColor\"],borderRadius:[\"borderTopLeftRadius\",\"borderTopRightRadius\",\"borderBottomRightRadius\",\"borderBottomLeftRadius\"],borderRight:[\"borderRightWidth\",\"borderRightStyle\",\"borderRightColor\"],borderTop:[\"borderTopWidth\",\"borderTopStyle\",\"borderTopColor\"],borderWidth:[\"borderTopWidth\",\"borderRightWidth\",\"borderBottomWidth\",\"borderLeftWidth\"],flex:[\"flexGrow\",\"flexShrink\",\"flexBasis\"],font:[\"fontFamily\",\"fontSize\",\"fontStyle\",\"fontVariant\",\"fontWeight\",\"lineHeight\"],margin:[\"marginTop\",\"marginRight\",\"marginBottom\",\"marginLeft\"],outline:[\"outlineColor\",\"outlineStyle\",\"outlineWidth\"],padding:[\"paddingTop\",\"paddingRight\",\"paddingBottom\",\"paddingLeft\"]},h=document.createElementNS(\"http://www.w3.org/1999/xhtml\",\"div\"),i={thin:\"1px\",medium:\"3px\",thick:\"5px\"},j={borderBottomWidth:i,borderLeftWidth:i,borderRightWidth:i,borderTopWidth:i,fontSize:{\"xx-small\":\"60%\",\"x-small\":\"75%\",small:\"89%\",medium:\"100%\",large:\"120%\",\"x-large\":\"150%\",\"xx-large\":\"200%\"},fontWeight:{normal:\"400\",bold:\"700\"},outlineWidth:i,textShadow:{none:\"0px 0px 0px transparent\"},boxShadow:{none:\"0px 0px 0px 0px transparent\"}};a.convertToArrayForm=e,a.normalizeKeyframes=f}(c,f),function(a){var b={};a.isDeprecated=function(a,c,d,e){var f=e?\"are\":\"is\",g=new Date,h=new Date(c);return h.setMonth(h.getMonth()+3),h>g?(a in b||console.warn(\"Web Animations: \"+a+\" \"+f+\" deprecated and will stop working on \"+h.toDateString()+\". \"+d),b[a]=!0,!1):!0},a.deprecated=function(b,c,d,e){var f=e?\"are\":\"is\";if(a.isDeprecated(b,c,d,e))throw new Error(b+\" \"+f+\" no longer supported. \"+d)}}(c),function(){if(document.documentElement.animate){var a=document.documentElement.animate([],0),b=!0;if(a&&(b=!1,\"play|currentTime|pause|reverse|playbackRate|cancel|finish|startTime|playState\".split(\"|\").forEach(function(c){void 0===a[c]&&(b=!0)})),!b)return}!function(a,b,c){function d(a){for(var b={},c=0;c<a.length;c++)for(var d in a[c])if(\"offset\"!=d&&\"easing\"!=d&&\"composite\"!=d){var e={offset:a[c].offset,easing:a[c].easing,value:a[c][d]};b[d]=b[d]||[],b[d].push(e)}for(var f in b){var g=b[f];if(0!=g[0].offset||1!=g[g.length-1].offset)throw{type:DOMException.NOT_SUPPORTED_ERR,name:\"NotSupportedError\",message:\"Partial keyframes are not supported\"}}return b}function e(c){var d=[];for(var e in c)for(var f=c[e],g=0;g<f.length-1;g++){var h=f[g].offset,i=f[g+1].offset,j=f[g].value,k=f[g+1].value,l=f[g].easing;h==i&&(1==i?j=k:k=j),d.push({startTime:h,endTime:i,easing:a.toTimingFunction(l?l:\"linear\"),property:e,interpolation:b.propertyInterpolation(e,j,k)})}return d.sort(function(a,b){return a.startTime-b.startTime}),d}b.convertEffectInput=function(c){var f=a.normalizeKeyframes(c),g=d(f),h=e(g);return function(a,c){if(null!=c)h.filter(function(a){return 0>=c&&0==a.startTime||c>=1&&1==a.endTime||c>=a.startTime&&c<=a.endTime}).forEach(function(d){var e=c-d.startTime,f=d.endTime-d.startTime,g=0==f?0:d.easing(e/f);b.apply(a,d.property,d.interpolation(g))});else for(var d in g)\"offset\"!=d&&\"easing\"!=d&&\"composite\"!=d&&b.clear(a,d)}}}(c,d,f),function(a,b,c){function d(a){return a.replace(/-(.)/g,function(a,b){return b.toUpperCase()})}function e(a,b,c){h[c]=h[c]||[],h[c].push([a,b])}function f(a,b,c){for(var f=0;f<c.length;f++){var g=c[f];e(a,b,d(g))}}function g(c,e,f){var g=c;/-/.test(c)&&!a.isDeprecated(\"Hyphenated property names\",\"2016-03-22\",\"Use camelCase instead.\",!0)&&(g=d(c)),\"initial\"!=e&&\"initial\"!=f||(\"initial\"==e&&(e=i[g]),\"initial\"==f&&(f=i[g]));for(var j=e==f?[]:h[g],k=0;j&&k<j.length;k++){var l=j[k][0](e),m=j[k][0](f);if(void 0!==l&&void 0!==m){var n=j[k][1](l,m);if(n){var o=b.Interpolation.apply(null,n);return function(a){return 0==a?e:1==a?f:o(a)}}}}return b.Interpolation(!1,!0,function(a){return a?f:e})}var h={};b.addPropertiesHandler=f;var i={backgroundColor:\"transparent\",backgroundPosition:\"0% 0%\",borderBottomColor:\"currentColor\",borderBottomLeftRadius:\"0px\",borderBottomRightRadius:\"0px\",borderBottomWidth:\"3px\",borderLeftColor:\"currentColor\",borderLeftWidth:\"3px\",borderRightColor:\"currentColor\",borderRightWidth:\"3px\",borderSpacing:\"2px\",borderTopColor:\"currentColor\",borderTopLeftRadius:\"0px\",borderTopRightRadius:\"0px\",borderTopWidth:\"3px\",bottom:\"auto\",clip:\"rect(0px, 0px, 0px, 0px)\",color:\"black\",fontSize:\"100%\",fontWeight:\"400\",height:\"auto\",left:\"auto\",letterSpacing:\"normal\",lineHeight:\"120%\",marginBottom:\"0px\",marginLeft:\"0px\",marginRight:\"0px\",marginTop:\"0px\",maxHeight:\"none\",maxWidth:\"none\",minHeight:\"0px\",minWidth:\"0px\",opacity:\"1.0\",outlineColor:\"invert\",outlineOffset:\"0px\",outlineWidth:\"3px\",paddingBottom:\"0px\",paddingLeft:\"0px\",paddingRight:\"0px\",paddingTop:\"0px\",right:\"auto\",textIndent:\"0px\",textShadow:\"0px 0px 0px transparent\",top:\"auto\",transform:\"\",verticalAlign:\"0px\",visibility:\"visible\",width:\"auto\",wordSpacing:\"normal\",zIndex:\"auto\"};b.propertyInterpolation=g}(c,d,f),function(a,b,c){function d(b){var c=a.calculateActiveDuration(b),d=function(d){return a.calculateTimeFraction(c,d,b)};return d._totalDuration=b.delay+c+b.endDelay,d._isCurrent=function(d){var e=a.calculatePhase(c,d,b);return e===PhaseActive||e===PhaseBefore},d}b.KeyframeEffect=function(c,e,f,g){var h,i=d(a.normalizeTimingInput(f)),j=b.convertEffectInput(e),k=function(){j(c,h)};return k._update=function(a){return h=i(a),null!==h},k._clear=function(){j(c,null)},k._hasSameTarget=function(a){return c===a},k._isCurrent=i._isCurrent,k._totalDuration=i._totalDuration,k._id=g,k},b.NullEffect=function(a){var b=function(){a&&(a(),a=null)};return b._update=function(){return null},b._totalDuration=0,b._isCurrent=function(){return!1},b._hasSameTarget=function(){return!1},b}}(c,d,f),function(a,b){a.apply=function(b,c,d){b.style[a.propertyName(c)]=d},a.clear=function(b,c){b.style[a.propertyName(c)]=\"\"}}(d,f),function(a){window.Element.prototype.animate=function(b,c){var d=\"\";return c&&c.id&&(d=c.id),a.timeline._play(a.KeyframeEffect(this,b,c,d))}}(d),function(a,b){function c(a,b,d){if(\"number\"==typeof a&&\"number\"==typeof b)return a*(1-d)+b*d;if(\"boolean\"==typeof a&&\"boolean\"==typeof b)return.5>d?a:b;if(a.length==b.length){for(var e=[],f=0;f<a.length;f++)e.push(c(a[f],b[f],d));return e}throw\"Mismatched interpolation arguments \"+a+\":\"+b}a.Interpolation=function(a,b,d){return function(e){return d(c(a,b,e))}}}(d,f),function(a,b,c){a.sequenceNumber=0;var d=function(a,b,c){this.target=a,this.currentTime=b,this.timelineTime=c,this.type=\"finish\",this.bubbles=!1,this.cancelable=!1,this.currentTarget=a,this.defaultPrevented=!1,this.eventPhase=Event.AT_TARGET,this.timeStamp=Date.now()};b.Animation=function(b){this.id=\"\",b&&b._id&&(this.id=b._id),this._sequenceNumber=a.sequenceNumber++,this._currentTime=0,this._startTime=null,this._paused=!1,this._playbackRate=1,this._inTimeline=!0,this._finishedFlag=!0,this.onfinish=null,this._finishHandlers=[],this._effect=b,this._inEffect=this._effect._update(0),this._idle=!0,this._currentTimePending=!1},b.Animation.prototype={_ensureAlive:function(){this.playbackRate<0&&0===this.currentTime?this._inEffect=this._effect._update(-1):this._inEffect=this._effect._update(this.currentTime),this._inTimeline||!this._inEffect&&this._finishedFlag||(this._inTimeline=!0,b.timeline._animations.push(this))},_tickCurrentTime:function(a,b){a!=this._currentTime&&(this._currentTime=a,this._isFinished&&!b&&(this._currentTime=this._playbackRate>0?this._totalDuration:0),this._ensureAlive())},get currentTime(){return this._idle||this._currentTimePending?null:this._currentTime},set currentTime(a){a=+a,isNaN(a)||(b.restart(),this._paused||null==this._startTime||(this._startTime=this._timeline.currentTime-a/this._playbackRate),this._currentTimePending=!1,this._currentTime!=a&&(this._tickCurrentTime(a,!0),b.invalidateEffects()))},get startTime(){return this._startTime},set startTime(a){a=+a,isNaN(a)||this._paused||this._idle||(this._startTime=a,this._tickCurrentTime((this._timeline.currentTime-this._startTime)*this.playbackRate),b.invalidateEffects())},get playbackRate(){return this._playbackRate},set playbackRate(a){if(a!=this._playbackRate){var b=this.currentTime;this._playbackRate=a,this._startTime=null,\"paused\"!=this.playState&&\"idle\"!=this.playState&&this.play(),null!=b&&(this.currentTime=b)}},get _isFinished(){return!this._idle&&(this._playbackRate>0&&this._currentTime>=this._totalDuration||this._playbackRate<0&&this._currentTime<=0)},get _totalDuration(){return this._effect._totalDuration},get playState(){return this._idle?\"idle\":null==this._startTime&&!this._paused&&0!=this.playbackRate||this._currentTimePending?\"pending\":this._paused?\"paused\":this._isFinished?\"finished\":\"running\"},play:function(){this._paused=!1,(this._isFinished||this._idle)&&(this._currentTime=this._playbackRate>0?0:this._totalDuration,this._startTime=null),this._finishedFlag=!1,this._idle=!1,this._ensureAlive(),b.invalidateEffects()},pause:function(){this._isFinished||this._paused||this._idle||(this._currentTimePending=!0),this._startTime=null,this._paused=!0},finish:function(){this._idle||(this.currentTime=this._playbackRate>0?this._totalDuration:0,this._startTime=this._totalDuration-this.currentTime,this._currentTimePending=!1,b.invalidateEffects())},cancel:function(){this._inEffect&&(this._inEffect=!1,this._idle=!0,this._finishedFlag=!0,this.currentTime=0,this._startTime=null,this._effect._update(null),b.invalidateEffects())},reverse:function(){this.playbackRate*=-1,this.play()},addEventListener:function(a,b){\"function\"==typeof b&&\"finish\"==a&&this._finishHandlers.push(b)},removeEventListener:function(a,b){if(\"finish\"==a){var c=this._finishHandlers.indexOf(b);c>=0&&this._finishHandlers.splice(c,1)}},_fireEvents:function(a){if(this._isFinished){if(!this._finishedFlag){var b=new d(this,this._currentTime,a),c=this._finishHandlers.concat(this.onfinish?[this.onfinish]:[]);setTimeout(function(){c.forEach(function(a){a.call(b.target,b)})},0),this._finishedFlag=!0}}else this._finishedFlag=!1},_tick:function(a,b){this._idle||this._paused||(null==this._startTime?b&&(this.startTime=a-this._currentTime/this.playbackRate):this._isFinished||this._tickCurrentTime((a-this._startTime)*this.playbackRate)),b&&(this._currentTimePending=!1,this._fireEvents(a))},get _needsTick(){return this.playState in{pending:1,running:1}||!this._finishedFlag}}}(c,d,f),function(a,b,c){function d(a){var b=j;j=[],a<p.currentTime&&(a=p.currentTime),h(a,!0),b.forEach(function(b){b[1](a)}),g(),l=void 0}function e(a,b){return a._sequenceNumber-b._sequenceNumber}function f(){this._animations=[],this.currentTime=window.performance&&performance.now?performance.now():0}function g(){o.forEach(function(a){a()}),o.length=0}function h(a,c){n=!1;var d=b.timeline;d.currentTime=a,d._animations.sort(e),m=!1;var f=d._animations;d._animations=[];var g=[],h=[];f=f.filter(function(b){b._tick(a,c),b._inEffect?h.push(b._effect):g.push(b._effect),b._needsTick&&(m=!0);var d=b._inEffect||b._needsTick;return b._inTimeline=d,d}),o.push.apply(o,g),o.push.apply(o,h),d._animations.push.apply(d._animations,f),m&&requestAnimationFrame(function(){})}var i=window.requestAnimationFrame,j=[],k=0;window.requestAnimationFrame=function(a){var b=k++;return 0==j.length&&i(d),j.push([b,a]),b},window.cancelAnimationFrame=function(a){j.forEach(function(b){b[0]==a&&(b[1]=function(){})})},f.prototype={_play:function(c){c._timing=a.normalizeTimingInput(c.timing);var d=new b.Animation(c);return d._idle=!1,d._timeline=this,this._animations.push(d),b.restart(),b.invalidateEffects(),d}};var l=void 0,m=!1,n=!1;b.restart=function(){return m||(m=!0,requestAnimationFrame(function(){}),n=!0),n},b.invalidateEffects=function(){h(b.timeline.currentTime,!1),g()};var o=[],p=new f;b.timeline=p}(c,d,f),function(a){function b(a,b){var c=a.exec(b);return c?(c=a.ignoreCase?c[0].toLowerCase():c[0],[c,b.substr(c.length)]):void 0}function c(a,b){b=b.replace(/^\\s*/,\"\");var c=a(b);return c?[c[0],c[1].replace(/^\\s*/,\"\")]:void 0}function d(a,d,e){a=c.bind(null,a);for(var f=[];;){var g=a(e);if(!g)return[f,e];if(f.push(g[0]),e=g[1],g=b(d,e),!g||\"\"==g[1])return[f,e];e=g[1]}}function e(a,b){for(var c=0,d=0;d<b.length&&(!/\\s|,/.test(b[d])||0!=c);d++)if(\"(\"==b[d])c++;else if(\")\"==b[d]&&(c--,0==c&&d++,0>=c))break;var e=a(b.substr(0,d));return void 0==e?void 0:[e,b.substr(d)]}function f(a,b){for(var c=a,d=b;c&&d;)c>d?c%=d:d%=c;return c=a*b/(c+d)}function g(a){return function(b){var c=a(b);return c&&(c[0]=void 0),c}}function h(a,b){return function(c){var d=a(c);return d?d:[b,c]}}function i(b,c){for(var d=[],e=0;e<b.length;e++){var f=a.consumeTrimmed(b[e],c);if(!f||\"\"==f[0])return;void 0!==f[0]&&d.push(f[0]),c=f[1]}return\"\"==c?d:void 0}function j(a,b,c,d,e){for(var g=[],h=[],i=[],j=f(d.length,e.length),k=0;j>k;k++){var l=b(d[k%d.length],e[k%e.length]);if(!l)return;g.push(l[0]),h.push(l[1]),i.push(l[2])}return[g,h,function(b){var d=b.map(function(a,b){return i[b](a)}).join(c);return a?a(d):d}]}function k(a,b,c){for(var d=[],e=[],f=[],g=0,h=0;h<c.length;h++)if(\"function\"==typeof c[h]){var i=c[h](a[g],b[g++]);d.push(i[0]),e.push(i[1]),f.push(i[2])}else!function(a){d.push(!1),e.push(!1),f.push(function(){return c[a]})}(h);return[d,e,function(a){for(var b=\"\",c=0;c<a.length;c++)b+=f[c](a[c]);return b}]}a.consumeToken=b,a.consumeTrimmed=c,a.consumeRepeated=d,a.consumeParenthesised=e,a.ignore=g,a.optional=h,a.consumeList=i,a.mergeNestedRepeated=j.bind(null,null),a.mergeWrappedNestedRepeated=j,a.mergeList=k}(d),function(a){function b(b){function c(b){var c=a.consumeToken(/^inset/i,b);if(c)return d.inset=!0,c;var c=a.consumeLengthOrPercent(b);if(c)return d.lengths.push(c[0]),c;var c=a.consumeColor(b);return c?(d.color=c[0],c):void 0}var d={inset:!1,lengths:[],color:null},e=a.consumeRepeated(c,/^/,b);return e&&e[0].length?[d,e[1]]:void 0}function c(c){var d=a.consumeRepeated(b,/^,/,c);return d&&\"\"==d[1]?d[0]:void 0}function d(b,c){for(;b.lengths.length<Math.max(b.lengths.length,c.lengths.length);)b.lengths.push({px:0});for(;c.lengths.length<Math.max(b.lengths.length,c.lengths.length);)c.lengths.push({px:0});if(b.inset==c.inset&&!!b.color==!!c.color){for(var d,e=[],f=[[],0],g=[[],0],h=0;h<b.lengths.length;h++){var i=a.mergeDimensions(b.lengths[h],c.lengths[h],2==h);f[0].push(i[0]),g[0].push(i[1]),e.push(i[2])}if(b.color&&c.color){var j=a.mergeColors(b.color,c.color);f[1]=j[0],g[1]=j[1],d=j[2]}return[f,g,function(a){for(var c=b.inset?\"inset \":\" \",f=0;f<e.length;f++)c+=e[f](a[0][f])+\" \";return d&&(c+=d(a[1])),c}]}}function e(b,c,d,e){function f(a){return{inset:a,color:[0,0,0,0],lengths:[{px:0},{px:0},{px:0},{px:0}]}}for(var g=[],h=[],i=0;i<d.length||i<e.length;i++){var j=d[i]||f(e[i].inset),k=e[i]||f(d[i].inset);g.push(j),h.push(k)}return a.mergeNestedRepeated(b,c,g,h)}var f=e.bind(null,d,\", \");a.addPropertiesHandler(c,f,[\"box-shadow\",\"text-shadow\"])}(d),function(a,b){function c(a){return a.toFixed(3).replace(\".000\",\"\")}function d(a,b,c){return Math.min(b,Math.max(a,c))}function e(a){return/^\\s*[-+]?(\\d*\\.)?\\d+\\s*$/.test(a)?Number(a):void 0}function f(a,b){return[a,b,c]}function g(a,b){return 0!=a?i(0,1/0)(a,b):void 0}function h(a,b){return[a,b,function(a){return Math.round(d(1,1/0,a))}]}function i(a,b){return function(e,f){return[e,f,function(e){return c(d(a,b,e))}]}}function j(a,b){return[a,b,Math.round]}a.clamp=d,a.addPropertiesHandler(e,i(0,1/0),[\"border-image-width\",\"line-height\"]),a.addPropertiesHandler(e,i(0,1),[\"opacity\",\"shape-image-threshold\"]),a.addPropertiesHandler(e,g,[\"flex-grow\",\"flex-shrink\"]),a.addPropertiesHandler(e,h,[\"orphans\",\"widows\"]),a.addPropertiesHandler(e,j,[\"z-index\"]),a.parseNumber=e,a.mergeNumbers=f,a.numberToString=c}(d,f),function(a,b){function c(a,b){return\"visible\"==a||\"visible\"==b?[0,1,function(c){return 0>=c?a:c>=1?b:\"visible\"}]:void 0}a.addPropertiesHandler(String,c,[\"visibility\"])}(d),function(a,b){function c(a){a=a.trim(),f.fillStyle=\"#000\",f.fillStyle=a;var b=f.fillStyle;if(f.fillStyle=\"#fff\",f.fillStyle=a,b==f.fillStyle){f.fillRect(0,0,1,1);var c=f.getImageData(0,0,1,1).data;f.clearRect(0,0,1,1);var d=c[3]/255;return[c[0]*d,c[1]*d,c[2]*d,d]}}function d(b,c){return[b,c,function(b){function c(a){return Math.max(0,Math.min(255,a))}if(b[3])for(var d=0;3>d;d++)b[d]=Math.round(c(b[d]/b[3]));return b[3]=a.numberToString(a.clamp(0,1,b[3])),\"rgba(\"+b.join(\",\")+\")\"}]}var e=document.createElementNS(\"http://www.w3.org/1999/xhtml\",\"canvas\");e.width=e.height=1;var f=e.getContext(\"2d\");a.addPropertiesHandler(c,d,[\"background-color\",\"border-bottom-color\",\"border-left-color\",\"border-right-color\",\"border-top-color\",\"color\",\"outline-color\",\"text-decoration-color\"]),a.consumeColor=a.consumeParenthesised.bind(null,c),a.mergeColors=d}(d,f),function(a,b){function c(a,b){if(b=b.trim().toLowerCase(),\"0\"==b&&\"px\".search(a)>=0)return{px:0};if(/^[^(]*$|^calc/.test(b)){b=b.replace(/calc\\(/g,\"(\");var c={};b=b.replace(a,function(a){return c[a]=null,\"U\"+a});for(var d=\"U(\"+a.source+\")\",e=b.replace(/[-+]?(\\d*\\.)?\\d+/g,\"N\").replace(new RegExp(\"N\"+d,\"g\"),\"D\").replace(/\\s[+-]\\s/g,\"O\").replace(/\\s/g,\"\"),f=[/N\\*(D)/g,/(N|D)[*\\/]N/g,/(N|D)O\\1/g,/\\((N|D)\\)/g],g=0;g<f.length;)f[g].test(e)?(e=e.replace(f[g],\"$1\"),g=0):g++;if(\"D\"==e){for(var h in c){var i=eval(b.replace(new RegExp(\"U\"+h,\"g\"),\"\").replace(new RegExp(d,\"g\"),\"*0\"));if(!isFinite(i))return;c[h]=i}return c}}}function d(a,b){return e(a,b,!0)}function e(b,c,d){var e,f=[];for(e in b)f.push(e);for(e in c)f.indexOf(e)<0&&f.push(e);return b=f.map(function(a){return b[a]||0}),c=f.map(function(a){return c[a]||0}),[b,c,function(b){var c=b.map(function(c,e){return 1==b.length&&d&&(c=Math.max(c,0)),a.numberToString(c)+f[e]}).join(\" + \");return b.length>1?\"calc(\"+c+\")\":c}]}var f=\"px|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc\",g=c.bind(null,new RegExp(f,\"g\")),h=c.bind(null,new RegExp(f+\"|%\",\"g\")),i=c.bind(null,/deg|rad|grad|turn/g);a.parseLength=g,a.parseLengthOrPercent=h,a.consumeLengthOrPercent=a.consumeParenthesised.bind(null,h),a.parseAngle=i,a.mergeDimensions=e;var j=a.consumeParenthesised.bind(null,g),k=a.consumeRepeated.bind(void 0,j,/^/),l=a.consumeRepeated.bind(void 0,k,/^,/);a.consumeSizePairList=l;var m=function(a){var b=l(a);return b&&\"\"==b[1]?b[0]:void 0},n=a.mergeNestedRepeated.bind(void 0,d,\" \"),o=a.mergeNestedRepeated.bind(void 0,n,\",\");a.mergeNonNegativeSizePair=n,a.addPropertiesHandler(m,o,[\"background-size\"]),a.addPropertiesHandler(h,d,[\"border-bottom-width\",\"border-image-width\",\"border-left-width\",\"border-right-width\",\"border-top-width\",\"flex-basis\",\"font-size\",\"height\",\"line-height\",\"max-height\",\"max-width\",\"outline-width\",\"width\"]),a.addPropertiesHandler(h,e,[\"border-bottom-left-radius\",\"border-bottom-right-radius\",\"border-top-left-radius\",\"border-top-right-radius\",\"bottom\",\"left\",\"letter-spacing\",\"margin-bottom\",\"margin-left\",\"margin-right\",\"margin-top\",\"min-height\",\"min-width\",\"outline-offset\",\"padding-bottom\",\"padding-left\",\"padding-right\",\"padding-top\",\"perspective\",\"right\",\"shape-margin\",\"text-indent\",\"top\",\"vertical-align\",\"word-spacing\"])}(d,f),function(a,b){function c(b){return a.consumeLengthOrPercent(b)||a.consumeToken(/^auto/,b)}function d(b){var d=a.consumeList([a.ignore(a.consumeToken.bind(null,/^rect/)),a.ignore(a.consumeToken.bind(null,/^\\(/)),a.consumeRepeated.bind(null,c,/^,/),a.ignore(a.consumeToken.bind(null,/^\\)/))],b);return d&&4==d[0].length?d[0]:void 0}function e(b,c){return\"auto\"==b||\"auto\"==c?[!0,!1,function(d){var e=d?b:c;if(\"auto\"==e)return\"auto\";var f=a.mergeDimensions(e,e);return f[2](f[0])}]:a.mergeDimensions(b,c)}function f(a){return\"rect(\"+a+\")\"}var g=a.mergeWrappedNestedRepeated.bind(null,f,e,\", \");a.parseBox=d,a.mergeBoxes=g,a.addPropertiesHandler(d,g,[\"clip\"])}(d,f),function(a,b){function c(a){return function(b){var c=0;return a.map(function(a){return a===k?b[c++]:a})}}function d(a){return a}function e(b){if(b=b.toLowerCase().trim(),\"none\"==b)return[];for(var c,d=/\\s*(\\w+)\\(([^)]*)\\)/g,e=[],f=0;c=d.exec(b);){if(c.index!=f)return;f=c.index+c[0].length;var g=c[1],h=n[g];if(!h)return;var i=c[2].split(\",\"),j=h[0];if(j.length<i.length)return;for(var k=[],o=0;o<j.length;o++){var p,q=i[o],r=j[o];if(p=q?{A:function(b){return\"0\"==b.trim()?m:a.parseAngle(b)},N:a.parseNumber,T:a.parseLengthOrPercent,L:a.parseLength}[r.toUpperCase()](q):{a:m,n:k[0],t:l}[r],void 0===p)return;k.push(p)}if(e.push({t:g,d:k}),d.lastIndex==b.length)return e}}function f(a){return a.toFixed(6).replace(\".000000\",\"\")}function g(b,c){if(b.decompositionPair!==c){b.decompositionPair=c;var d=a.makeMatrixDecomposition(b)}if(c.decompositionPair!==b){c.decompositionPair=b;var e=a.makeMatrixDecomposition(c)}return null==d[0]||null==e[0]?[[!1],[!0],function(a){return a?c[0].d:b[0].d}]:(d[0].push(0),e[0].push(1),[d,e,function(b){var c=a.quat(d[0][3],e[0][3],b[5]),g=a.composeMatrix(b[0],b[1],b[2],c,b[4]),h=g.map(f).join(\",\");return h}])}function h(a){return a.replace(/[xy]/,\"\")}function i(a){return a.replace(/(x|y|z|3d)?$/,\"3d\")}function j(b,c){var d=a.makeMatrixDecomposition&&!0,e=!1;if(!b.length||!c.length){b.length||(e=!0,b=c,c=[]);for(var f=0;f<b.length;f++){var j=b[f].t,k=b[f].d,l=\"scale\"==j.substr(0,5)?1:0;c.push({t:j,d:k.map(function(a){if(\"number\"==typeof a)return l;var b={};for(var c in a)b[c]=l;return b})})}}var m=function(a,b){return\"perspective\"==a&&\"perspective\"==b||(\"matrix\"==a||\"matrix3d\"==a)&&(\"matrix\"==b||\"matrix3d\"==b)},o=[],p=[],q=[];if(b.length!=c.length){if(!d)return;var r=g(b,c);o=[r[0]],p=[r[1]],q=[[\"matrix\",[r[2]]]]}else for(var f=0;f<b.length;f++){var j,s=b[f].t,t=c[f].t,u=b[f].d,v=c[f].d,w=n[s],x=n[t];if(m(s,t)){if(!d)return;var r=g([b[f]],[c[f]]);o.push(r[0]),p.push(r[1]),q.push([\"matrix\",[r[2]]])}else{if(s==t)j=s;else if(w[2]&&x[2]&&h(s)==h(t))j=h(s),u=w[2](u),v=x[2](v);else{if(!w[1]||!x[1]||i(s)!=i(t)){if(!d)return;var r=g(b,c);o=[r[0]],p=[r[1]],q=[[\"matrix\",[r[2]]]];break}j=i(s),u=w[1](u),v=x[1](v)}for(var y=[],z=[],A=[],B=0;B<u.length;B++){var C=\"number\"==typeof u[B]?a.mergeNumbers:a.mergeDimensions,r=C(u[B],v[B]);y[B]=r[0],z[B]=r[1],A.push(r[2])}o.push(y),p.push(z),q.push([j,A])}}if(e){var D=o;o=p,p=D}return[o,p,function(a){return a.map(function(a,b){var c=a.map(function(a,c){return q[b][1][c](a)}).join(\",\");return\"matrix\"==q[b][0]&&16==c.split(\",\").length&&(q[b][0]=\"matrix3d\"),q[b][0]+\"(\"+c+\")\"}).join(\" \")}]}var k=null,l={px:0},m={deg:0},n={matrix:[\"NNNNNN\",[k,k,0,0,k,k,0,0,0,0,1,0,k,k,0,1],d],matrix3d:[\"NNNNNNNNNNNNNNNN\",d],rotate:[\"A\"],rotatex:[\"A\"],rotatey:[\"A\"],rotatez:[\"A\"],rotate3d:[\"NNNA\"],perspective:[\"L\"],scale:[\"Nn\",c([k,k,1]),d],scalex:[\"N\",c([k,1,1]),c([k,1])],scaley:[\"N\",c([1,k,1]),c([1,k])],scalez:[\"N\",c([1,1,k])],scale3d:[\"NNN\",d],skew:[\"Aa\",null,d],skewx:[\"A\",null,c([k,m])],skewy:[\"A\",null,c([m,k])],translate:[\"Tt\",c([k,k,l]),d],translatex:[\"T\",c([k,l,l]),c([k,l])],translatey:[\"T\",c([l,k,l]),c([l,k])],translatez:[\"L\",c([l,l,k])],translate3d:[\"TTL\",d]};a.addPropertiesHandler(e,j,[\"transform\"])}(d,f),function(a,b){function c(a,b){b.concat([a]).forEach(function(b){b in document.documentElement.style&&(d[a]=b)})}var d={};c(\"transform\",[\"webkitTransform\",\"msTransform\"]),c(\"transformOrigin\",[\"webkitTransformOrigin\"]),c(\"perspective\",[\"webkitPerspective\"]),c(\"perspectiveOrigin\",[\"webkitPerspectiveOrigin\"]),a.propertyName=function(a){return d[a]||a}}(d,f)}(),!function(){if(void 0===document.createElement(\"div\").animate([]).oncancel){var a;if(window.performance&&performance.now)var a=function(){return performance.now()};else var a=function(){return Date.now()};var b=function(a,b,c){this.target=a,this.currentTime=b,this.timelineTime=c,this.type=\"cancel\",this.bubbles=!1,this.cancelable=!1,this.currentTarget=a,this.defaultPrevented=!1,this.eventPhase=Event.AT_TARGET,this.timeStamp=Date.now()},c=window.Element.prototype.animate;window.Element.prototype.animate=function(d,e){var f=c.call(this,d,e);f._cancelHandlers=[],f.oncancel=null;var g=f.cancel;f.cancel=function(){g.call(this);var c=new b(this,null,a()),d=this._cancelHandlers.concat(this.oncancel?[this.oncancel]:[]);setTimeout(function(){d.forEach(function(a){a.call(c.target,c)})},0)};var h=f.addEventListener;f.addEventListener=function(a,b){\"function\"==typeof b&&\"cancel\"==a?this._cancelHandlers.push(b):h.call(this,a,b)};var i=f.removeEventListener;return f.removeEventListener=function(a,b){if(\"cancel\"==a){var c=this._cancelHandlers.indexOf(b);c>=0&&this._cancelHandlers.splice(c,1)}else i.call(this,a,b)},f}}}(),function(a){var b=document.documentElement,c=null,d=!1;try{var e=getComputedStyle(b).getPropertyValue(\"opacity\"),f=\"0\"==e?\"1\":\"0\";c=b.animate({opacity:[f,f]},{duration:1}),c.currentTime=0,d=getComputedStyle(b).getPropertyValue(\"opacity\")==f}catch(g){}finally{c&&c.cancel()}if(!d){var h=window.Element.prototype.animate;window.Element.prototype.animate=function(b,c){return window.Symbol&&Symbol.iterator&&Array.prototype.from&&b[Symbol.iterator]&&(b=Array.from(b)),Array.isArray(b)||null===b||(b=a.convertToArrayForm(b)),h.call(this,b,c)}}}(c),!function(a,b,c){function d(a){var b=window.document.timeline;b.currentTime=a,b._discardAnimations(),0==b._animations.length?f=!1:requestAnimationFrame(d);\n}var e=window.requestAnimationFrame;window.requestAnimationFrame=function(a){return e(function(b){window.document.timeline._updateAnimationsPromises(),a(b),window.document.timeline._updateAnimationsPromises()})},b.AnimationTimeline=function(){this._animations=[],this.currentTime=void 0},b.AnimationTimeline.prototype={getAnimations:function(){return this._discardAnimations(),this._animations.slice()},_updateAnimationsPromises:function(){b.animationsWithPromises=b.animationsWithPromises.filter(function(a){return a._updatePromises()})},_discardAnimations:function(){this._updateAnimationsPromises(),this._animations=this._animations.filter(function(a){return\"finished\"!=a.playState&&\"idle\"!=a.playState})},_play:function(a){var c=new b.Animation(a,this);return this._animations.push(c),b.restartWebAnimationsNextTick(),c._updatePromises(),c._animation.play(),c._updatePromises(),c},play:function(a){return a&&a.remove(),this._play(a)}};var f=!1;b.restartWebAnimationsNextTick=function(){f||(f=!0,requestAnimationFrame(d))};var g=new b.AnimationTimeline;b.timeline=g;try{Object.defineProperty(window.document,\"timeline\",{configurable:!0,get:function(){return g}})}catch(h){}try{window.document.timeline=g}catch(h){}}(c,e,f),function(a,b,c){b.animationsWithPromises=[],b.Animation=function(b,c){if(this.id=\"\",b&&b._id&&(this.id=b._id),this.effect=b,b&&(b._animation=this),!c)throw new Error(\"Animation with null timeline is not supported\");this._timeline=c,this._sequenceNumber=a.sequenceNumber++,this._holdTime=0,this._paused=!1,this._isGroup=!1,this._animation=null,this._childAnimations=[],this._callback=null,this._oldPlayState=\"idle\",this._rebuildUnderlyingAnimation(),this._animation.cancel(),this._updatePromises()},b.Animation.prototype={_updatePromises:function(){var a=this._oldPlayState,b=this.playState;return this._readyPromise&&b!==a&&(\"idle\"==b?(this._rejectReadyPromise(),this._readyPromise=void 0):\"pending\"==a?this._resolveReadyPromise():\"pending\"==b&&(this._readyPromise=void 0)),this._finishedPromise&&b!==a&&(\"idle\"==b?(this._rejectFinishedPromise(),this._finishedPromise=void 0):\"finished\"==b?this._resolveFinishedPromise():\"finished\"==a&&(this._finishedPromise=void 0)),this._oldPlayState=this.playState,this._readyPromise||this._finishedPromise},_rebuildUnderlyingAnimation:function(){this._updatePromises();var a,c,d,e,f=!!this._animation;f&&(a=this.playbackRate,c=this._paused,d=this.startTime,e=this.currentTime,this._animation.cancel(),this._animation._wrapper=null,this._animation=null),(!this.effect||this.effect instanceof window.KeyframeEffect)&&(this._animation=b.newUnderlyingAnimationForKeyframeEffect(this.effect),b.bindAnimationForKeyframeEffect(this)),(this.effect instanceof window.SequenceEffect||this.effect instanceof window.GroupEffect)&&(this._animation=b.newUnderlyingAnimationForGroup(this.effect),b.bindAnimationForGroup(this)),this.effect&&this.effect._onsample&&b.bindAnimationForCustomEffect(this),f&&(1!=a&&(this.playbackRate=a),null!==d?this.startTime=d:null!==e?this.currentTime=e:null!==this._holdTime&&(this.currentTime=this._holdTime),c&&this.pause()),this._updatePromises()},_updateChildren:function(){if(this.effect&&\"idle\"!=this.playState){var a=this.effect._timing.delay;this._childAnimations.forEach(function(c){this._arrangeChildren(c,a),this.effect instanceof window.SequenceEffect&&(a+=b.groupChildDuration(c.effect))}.bind(this))}},_setExternalAnimation:function(a){if(this.effect&&this._isGroup)for(var b=0;b<this.effect.children.length;b++)this.effect.children[b]._animation=a,this._childAnimations[b]._setExternalAnimation(a)},_constructChildAnimations:function(){if(this.effect&&this._isGroup){var a=this.effect._timing.delay;this._removeChildAnimations(),this.effect.children.forEach(function(c){var d=window.document.timeline._play(c);this._childAnimations.push(d),d.playbackRate=this.playbackRate,this._paused&&d.pause(),c._animation=this.effect._animation,this._arrangeChildren(d,a),this.effect instanceof window.SequenceEffect&&(a+=b.groupChildDuration(c))}.bind(this))}},_arrangeChildren:function(a,b){null===this.startTime?a.currentTime=this.currentTime-b/this.playbackRate:a.startTime!==this.startTime+b/this.playbackRate&&(a.startTime=this.startTime+b/this.playbackRate)},get timeline(){return this._timeline},get playState(){return this._animation?this._animation.playState:\"idle\"},get finished(){return window.Promise?(this._finishedPromise||(-1==b.animationsWithPromises.indexOf(this)&&b.animationsWithPromises.push(this),this._finishedPromise=new Promise(function(a,b){this._resolveFinishedPromise=function(){a(this)},this._rejectFinishedPromise=function(){b({type:DOMException.ABORT_ERR,name:\"AbortError\"})}}.bind(this)),\"finished\"==this.playState&&this._resolveFinishedPromise()),this._finishedPromise):(console.warn(\"Animation Promises require JavaScript Promise constructor\"),null)},get ready(){return window.Promise?(this._readyPromise||(-1==b.animationsWithPromises.indexOf(this)&&b.animationsWithPromises.push(this),this._readyPromise=new Promise(function(a,b){this._resolveReadyPromise=function(){a(this)},this._rejectReadyPromise=function(){b({type:DOMException.ABORT_ERR,name:\"AbortError\"})}}.bind(this)),\"pending\"!==this.playState&&this._resolveReadyPromise()),this._readyPromise):(console.warn(\"Animation Promises require JavaScript Promise constructor\"),null)},get onfinish(){return this._animation.onfinish},set onfinish(a){\"function\"==typeof a?this._animation.onfinish=function(b){b.target=this,a.call(this,b)}.bind(this):this._animation.onfinish=a},get oncancel(){return this._animation.oncancel},set oncancel(a){\"function\"==typeof a?this._animation.oncancel=function(b){b.target=this,a.call(this,b)}.bind(this):this._animation.oncancel=a},get currentTime(){this._updatePromises();var a=this._animation.currentTime;return this._updatePromises(),a},set currentTime(a){this._updatePromises(),this._animation.currentTime=isFinite(a)?a:Math.sign(a)*Number.MAX_VALUE,this._register(),this._forEachChild(function(b,c){b.currentTime=a-c}),this._updatePromises()},get startTime(){return this._animation.startTime},set startTime(a){this._updatePromises(),this._animation.startTime=isFinite(a)?a:Math.sign(a)*Number.MAX_VALUE,this._register(),this._forEachChild(function(b,c){b.startTime=a+c}),this._updatePromises()},get playbackRate(){return this._animation.playbackRate},set playbackRate(a){this._updatePromises();var b=this.currentTime;this._animation.playbackRate=a,this._forEachChild(function(b){b.playbackRate=a}),\"paused\"!=this.playState&&\"idle\"!=this.playState&&this.play(),null!==b&&(this.currentTime=b),this._updatePromises()},play:function(){this._updatePromises(),this._paused=!1,this._animation.play(),-1==this._timeline._animations.indexOf(this)&&this._timeline._animations.push(this),this._register(),b.awaitStartTime(this),this._forEachChild(function(a){var b=a.currentTime;a.play(),a.currentTime=b}),this._updatePromises()},pause:function(){this._updatePromises(),this.currentTime&&(this._holdTime=this.currentTime),this._animation.pause(),this._register(),this._forEachChild(function(a){a.pause()}),this._paused=!0,this._updatePromises()},finish:function(){this._updatePromises(),this._animation.finish(),this._register(),this._updatePromises()},cancel:function(){this._updatePromises(),this._animation.cancel(),this._register(),this._removeChildAnimations(),this._updatePromises()},reverse:function(){this._updatePromises();var a=this.currentTime;this._animation.reverse(),this._forEachChild(function(a){a.reverse()}),null!==a&&(this.currentTime=a),this._updatePromises()},addEventListener:function(a,b){var c=b;\"function\"==typeof b&&(c=function(a){a.target=this,b.call(this,a)}.bind(this),b._wrapper=c),this._animation.addEventListener(a,c)},removeEventListener:function(a,b){this._animation.removeEventListener(a,b&&b._wrapper||b)},_removeChildAnimations:function(){for(;this._childAnimations.length;)this._childAnimations.pop().cancel()},_forEachChild:function(b){var c=0;if(this.effect.children&&this._childAnimations.length<this.effect.children.length&&this._constructChildAnimations(),this._childAnimations.forEach(function(a){b.call(this,a,c),this.effect instanceof window.SequenceEffect&&(c+=a.effect.activeDuration)}.bind(this)),\"pending\"!=this.playState){var d=this.effect._timing,e=this.currentTime;null!==e&&(e=a.calculateTimeFraction(a.calculateActiveDuration(d),e,d)),(null==e||isNaN(e))&&this._removeChildAnimations()}}},window.Animation=b.Animation}(c,e,f),function(a,b,c){function d(b){this._frames=a.normalizeKeyframes(b)}function e(){for(var a=!1;i.length;){var b=i.shift();b._updateChildren(),a=!0}return a}var f=function(a){if(a._animation=void 0,a instanceof window.SequenceEffect||a instanceof window.GroupEffect)for(var b=0;b<a.children.length;b++)f(a.children[b])};b.removeMulti=function(a){for(var b=[],c=0;c<a.length;c++){var d=a[c];d._parent?(-1==b.indexOf(d._parent)&&b.push(d._parent),d._parent.children.splice(d._parent.children.indexOf(d),1),d._parent=null,f(d)):d._animation&&d._animation.effect==d&&(d._animation.cancel(),d._animation.effect=new KeyframeEffect(null,[]),d._animation._callback&&(d._animation._callback._animation=null),d._animation._rebuildUnderlyingAnimation(),f(d))}for(c=0;c<b.length;c++)b[c]._rebuild()},b.KeyframeEffect=function(b,c,e,f){return this.target=b,this._parent=null,e=a.numericTimingToObject(e),this._timingInput=a.cloneTimingInput(e),this._timing=a.normalizeTimingInput(e),this.timing=a.makeTiming(e,!1,this),this.timing._effect=this,\"function\"==typeof c?(a.deprecated(\"Custom KeyframeEffect\",\"2015-06-22\",\"Use KeyframeEffect.onsample instead.\"),this._normalizedKeyframes=c):this._normalizedKeyframes=new d(c),this._keyframes=c,this.activeDuration=a.calculateActiveDuration(this._timing),this._id=f,this},b.KeyframeEffect.prototype={getFrames:function(){return\"function\"==typeof this._normalizedKeyframes?this._normalizedKeyframes:this._normalizedKeyframes._frames},set onsample(a){if(\"function\"==typeof this.getFrames())throw new Error(\"Setting onsample on custom effect KeyframeEffect is not supported.\");this._onsample=a,this._animation&&this._animation._rebuildUnderlyingAnimation()},get parent(){return this._parent},clone:function(){if(\"function\"==typeof this.getFrames())throw new Error(\"Cloning custom effects is not supported.\");var b=new KeyframeEffect(this.target,[],a.cloneTimingInput(this._timingInput),this._id);return b._normalizedKeyframes=this._normalizedKeyframes,b._keyframes=this._keyframes,b},remove:function(){b.removeMulti([this])}};var g=Element.prototype.animate;Element.prototype.animate=function(a,c){var d=\"\";return c&&c.id&&(d=c.id),b.timeline._play(new b.KeyframeEffect(this,a,c,d))};var h=document.createElementNS(\"http://www.w3.org/1999/xhtml\",\"div\");b.newUnderlyingAnimationForKeyframeEffect=function(a){if(a){var b=a.target||h,c=a._keyframes;\"function\"==typeof c&&(c=[]);var d=a._timingInput;d.id=a._id}else var b=h,c=[],d=0;return g.apply(b,[c,d])},b.bindAnimationForKeyframeEffect=function(a){a.effect&&\"function\"==typeof a.effect._normalizedKeyframes&&b.bindAnimationForCustomEffect(a)};var i=[];b.awaitStartTime=function(a){null===a.startTime&&a._isGroup&&(0==i.length&&requestAnimationFrame(e),i.push(a))};var j=window.getComputedStyle;Object.defineProperty(window,\"getComputedStyle\",{configurable:!0,enumerable:!0,value:function(){window.document.timeline._updateAnimationsPromises();var a=j.apply(this,arguments);return e()&&(a=j.apply(this,arguments)),window.document.timeline._updateAnimationsPromises(),a}}),window.KeyframeEffect=b.KeyframeEffect,window.Element.prototype.getAnimations=function(){return document.timeline.getAnimations().filter(function(a){return null!==a.effect&&a.effect.target==this}.bind(this))}}(c,e,f),function(a,b,c){function d(a){a._registered||(a._registered=!0,g.push(a),h||(h=!0,requestAnimationFrame(e)))}function e(a){var b=g;g=[],b.sort(function(a,b){return a._sequenceNumber-b._sequenceNumber}),b=b.filter(function(a){a();var b=a._animation?a._animation.playState:\"idle\";return\"running\"!=b&&\"pending\"!=b&&(a._registered=!1),a._registered}),g.push.apply(g,b),g.length?(h=!0,requestAnimationFrame(e)):h=!1}var f=(document.createElementNS(\"http://www.w3.org/1999/xhtml\",\"div\"),0);b.bindAnimationForCustomEffect=function(b){var c,e=b.effect.target,g=\"function\"==typeof b.effect.getFrames();c=g?b.effect.getFrames():b.effect._onsample;var h=b.effect.timing,i=null;h=a.normalizeTimingInput(h);var j=function(){var d=j._animation?j._animation.currentTime:null;null!==d&&(d=a.calculateTimeFraction(a.calculateActiveDuration(h),d,h),isNaN(d)&&(d=null)),d!==i&&(g?c(d,e,b.effect):c(d,b.effect,b.effect._animation)),i=d};j._animation=b,j._registered=!1,j._sequenceNumber=f++,b._callback=j,d(j)};var g=[],h=!1;b.Animation.prototype._register=function(){this._callback&&d(this._callback)}}(c,e,f),function(a,b,c){function d(a){return a._timing.delay+a.activeDuration+a._timing.endDelay}function e(b,c,d){this._id=d,this._parent=null,this.children=b||[],this._reparent(this.children),c=a.numericTimingToObject(c),this._timingInput=a.cloneTimingInput(c),this._timing=a.normalizeTimingInput(c,!0),this.timing=a.makeTiming(c,!0,this),this.timing._effect=this,\"auto\"===this._timing.duration&&(this._timing.duration=this.activeDuration)}window.SequenceEffect=function(){e.apply(this,arguments)},window.GroupEffect=function(){e.apply(this,arguments)},e.prototype={_isAncestor:function(a){for(var b=this;null!==b;){if(b==a)return!0;b=b._parent}return!1},_rebuild:function(){for(var a=this;a;)\"auto\"===a.timing.duration&&(a._timing.duration=a.activeDuration),a=a._parent;this._animation&&this._animation._rebuildUnderlyingAnimation()},_reparent:function(a){b.removeMulti(a);for(var c=0;c<a.length;c++)a[c]._parent=this},_putChild:function(a,b){for(var c=b?\"Cannot append an ancestor or self\":\"Cannot prepend an ancestor or self\",d=0;d<a.length;d++)if(this._isAncestor(a[d]))throw{type:DOMException.HIERARCHY_REQUEST_ERR,name:\"HierarchyRequestError\",message:c};for(var d=0;d<a.length;d++)b?this.children.push(a[d]):this.children.unshift(a[d]);this._reparent(a),this._rebuild()},append:function(){this._putChild(arguments,!0)},prepend:function(){this._putChild(arguments,!1)},get parent(){return this._parent},get firstChild(){return this.children.length?this.children[0]:null},get lastChild(){return this.children.length?this.children[this.children.length-1]:null},clone:function(){for(var b=a.cloneTimingInput(this._timingInput),c=[],d=0;d<this.children.length;d++)c.push(this.children[d].clone());return this instanceof GroupEffect?new GroupEffect(c,b):new SequenceEffect(c,b)},remove:function(){b.removeMulti([this])}},window.SequenceEffect.prototype=Object.create(e.prototype),Object.defineProperty(window.SequenceEffect.prototype,\"activeDuration\",{get:function(){var a=0;return this.children.forEach(function(b){a+=d(b)}),Math.max(a,0)}}),window.GroupEffect.prototype=Object.create(e.prototype),Object.defineProperty(window.GroupEffect.prototype,\"activeDuration\",{get:function(){var a=0;return this.children.forEach(function(b){a=Math.max(a,d(b))}),a}}),b.newUnderlyingAnimationForGroup=function(c){var d,e=null,f=function(b){var c=d._wrapper;return c&&\"pending\"!=c.playState&&c.effect?null==b?void c._removeChildAnimations():0==b&&c.playbackRate<0&&(e||(e=a.normalizeTimingInput(c.effect.timing)),b=a.calculateTimeFraction(a.calculateActiveDuration(e),-1,e),isNaN(b)||null==b)?(c._forEachChild(function(a){a.currentTime=-1}),void c._removeChildAnimations()):void 0:void 0},g=new KeyframeEffect(null,[],c._timing,c._id);return g.onsample=f,d=b.timeline._play(g)},b.bindAnimationForGroup=function(a){a._animation._wrapper=a,a._isGroup=!0,b.awaitStartTime(a),a._constructChildAnimations(),a._setExternalAnimation(a)},b.groupChildDuration=d}(c,e,f),b[\"true\"]=a}({},function(){return this}());\n//# sourceMappingURL=web-animations-next-lite.min.js.map</script><script>// https://d3js.org Version 4.9.1. Copyright 2017 Mike Bostock.\n(function(t,n){\"object\"==typeof exports&&\"undefined\"!=typeof module?n(exports):\"function\"==typeof define&&define.amd?define([\"exports\"],n):n(t.d3=t.d3||{})})(this,function(t){\"use strict\";function n(t){return function(n,e){return js(t(n),e)}}function e(t,n){return[t,n]}function r(t,n,e){var r=(n-t)/Math.max(0,e),i=Math.floor(Math.log(r)/Math.LN10),o=r/Math.pow(10,i);return i>=0?(o>=sf?10:o>=ff?5:o>=lf?2:1)*Math.pow(10,i):-Math.pow(10,-i)/(o>=sf?10:o>=ff?5:o>=lf?2:1)}function i(t,n,e){var r=Math.abs(n-t)/Math.max(0,e),i=Math.pow(10,Math.floor(Math.log(r)/Math.LN10)),o=r/i;return o>=sf?i*=10:o>=ff?i*=5:o>=lf&&(i*=2),n<t?-i:i}function o(t){return t.length}function u(t){return\"translate(\"+(t+.5)+\",0)\"}function a(t){return\"translate(0,\"+(t+.5)+\")\"}function c(t){var n=Math.max(0,t.bandwidth()-1)/2;return t.round()&&(n=Math.round(n)),function(e){return t(e)+n}}function s(){return!this.__axis}function f(t,n){function e(e){var u=null==i?n.ticks?n.ticks.apply(n,r):n.domain():i,a=null==o?n.tickFormat?n.tickFormat.apply(n,r):Cf:o,_=Math.max(f,0)+h,y=n.range(),g=y[0]+.5,m=y[y.length-1]+.5,x=(n.bandwidth?c:Cf)(n.copy()),b=e.selection?e.selection():e,w=b.selectAll(\".domain\").data([null]),M=b.selectAll(\".tick\").data(u,n).order(),T=M.exit(),k=M.enter().append(\"g\").attr(\"class\",\"tick\"),N=M.select(\"line\"),S=M.select(\"text\");w=w.merge(w.enter().insert(\"path\",\".tick\").attr(\"class\",\"domain\").attr(\"stroke\",\"#000\")),M=M.merge(k),N=N.merge(k.append(\"line\").attr(\"stroke\",\"#000\").attr(d+\"2\",p*f)),S=S.merge(k.append(\"text\").attr(\"fill\",\"#000\").attr(d,p*_).attr(\"dy\",t===zf?\"0em\":t===Lf?\"0.71em\":\"0.32em\")),e!==b&&(w=w.transition(e),M=M.transition(e),N=N.transition(e),S=S.transition(e),T=T.transition(e).attr(\"opacity\",qf).attr(\"transform\",function(t){return isFinite(t=x(t))?v(t):this.getAttribute(\"transform\")}),k.attr(\"opacity\",qf).attr(\"transform\",function(t){var n=this.parentNode.__axis;return v(n&&isFinite(n=n(t))?n:x(t))})),T.remove(),w.attr(\"d\",t===Rf||t==Pf?\"M\"+p*l+\",\"+g+\"H0.5V\"+m+\"H\"+p*l:\"M\"+g+\",\"+p*l+\"V0.5H\"+m+\"V\"+p*l),M.attr(\"opacity\",1).attr(\"transform\",function(t){return v(x(t))}),N.attr(d+\"2\",p*f),S.attr(d,p*_).text(a),b.filter(s).attr(\"fill\",\"none\").attr(\"font-size\",10).attr(\"font-family\",\"sans-serif\").attr(\"text-anchor\",t===Pf?\"start\":t===Rf?\"end\":\"middle\"),b.each(function(){this.__axis=x})}var r=[],i=null,o=null,f=6,l=6,h=3,p=t===zf||t===Rf?-1:1,d=t===Rf||t===Pf?\"x\":\"y\",v=t===zf||t===Lf?u:a;return e.scale=function(t){return arguments.length?(n=t,e):n},e.ticks=function(){return r=Af.call(arguments),e},e.tickArguments=function(t){return arguments.length?(r=null==t?[]:Af.call(t),e):r.slice()},e.tickValues=function(t){return arguments.length?(i=null==t?null:Af.call(t),e):i&&i.slice()},e.tickFormat=function(t){return arguments.length?(o=t,e):o},e.tickSize=function(t){return arguments.length?(f=l=+t,e):f},e.tickSizeInner=function(t){return arguments.length?(f=+t,e):f},e.tickSizeOuter=function(t){return arguments.length?(l=+t,e):l},e.tickPadding=function(t){return arguments.length?(h=+t,e):h},e}function l(t){return f(zf,t)}function h(t){return f(Pf,t)}function p(t){return f(Lf,t)}function d(t){return f(Rf,t)}function v(){for(var t,n=0,e=arguments.length,r={};n<e;++n){if(!(t=arguments[n]+\"\")||t in r)throw new Error(\"illegal type: \"+t);r[t]=[]}return new _(r)}function _(t){this._=t}function y(t,n){return t.trim().split(/^|\\s+/).map(function(t){var e=\"\",r=t.indexOf(\".\");if(r>=0&&(e=t.slice(r+1),t=t.slice(0,r)),t&&!n.hasOwnProperty(t))throw new Error(\"unknown type: \"+t);return{type:t,name:e}})}function g(t,n){for(var e,r=0,i=t.length;r<i;++r)if((e=t[r]).name===n)return e.value}function m(t,n,e){for(var r=0,i=t.length;r<i;++r)if(t[r].name===n){t[r]=Uf,t=t.slice(0,r).concat(t.slice(r+1));break}return null!=e&&t.push({name:n,value:e}),t}function x(t){return function(){var n=this.ownerDocument,e=this.namespaceURI;return e===Df&&n.documentElement.namespaceURI===Df?n.createElement(t):n.createElementNS(e,t)}}function b(t){return function(){return this.ownerDocument.createElementNS(t.space,t.local)}}function w(){return new M}function M(){this._=\"@\"+(++Yf).toString(36)}function T(t,n,e){return t=k(t,n,e),function(n){var e=n.relatedTarget;e&&(e===this||8&e.compareDocumentPosition(this))||t.call(this,n)}}function k(n,e,r){return function(i){var o=t.event;t.event=i;try{n.call(this,this.__data__,e,r)}finally{t.event=o}}}function N(t){return t.trim().split(/^|\\s+/).map(function(t){var n=\"\",e=t.indexOf(\".\");return e>=0&&(n=t.slice(e+1),t=t.slice(0,e)),{type:t,name:n}})}function S(t){return function(){var n=this.__on;if(n){for(var e,r=0,i=-1,o=n.length;r<o;++r)e=n[r],t.type&&e.type!==t.type||e.name!==t.name?n[++i]=e:this.removeEventListener(e.type,e.listener,e.capture);++i?n.length=i:delete this.__on}}}function E(t,n,e){var r=$f.hasOwnProperty(t.type)?T:k;return function(i,o,u){var a,c=this.__on,s=r(n,o,u);if(c)for(var f=0,l=c.length;f<l;++f)if((a=c[f]).type===t.type&&a.name===t.name)return this.removeEventListener(a.type,a.listener,a.capture),this.addEventListener(a.type,a.listener=s,a.capture=e),void(a.value=n);this.addEventListener(t.type,s,e),a={type:t.type,name:t.name,value:n,listener:s,capture:e},c?c.push(a):this.__on=[a]}}function A(n,e,r,i){var o=t.event;n.sourceEvent=t.event,t.event=n;try{return e.apply(r,i)}finally{t.event=o}}function C(){}function z(){return[]}function P(t,n){this.ownerDocument=t.ownerDocument,this.namespaceURI=t.namespaceURI,this._next=null,this._parent=t,this.__data__=n}function L(t,n,e,r,i,o){for(var u,a=0,c=n.length,s=o.length;a<s;++a)(u=n[a])?(u.__data__=o[a],r[a]=u):e[a]=new P(t,o[a]);for(;a<c;++a)(u=n[a])&&(i[a]=u)}function R(t,n,e,r,i,o,u){var a,c,s,f={},l=n.length,h=o.length,p=new Array(l);for(a=0;a<l;++a)(c=n[a])&&(p[a]=s=ol+u.call(c,c.__data__,a,n),s in f?i[a]=c:f[s]=c);for(a=0;a<h;++a)s=ol+u.call(t,o[a],a,o),(c=f[s])?(r[a]=c,c.__data__=o[a],f[s]=null):e[a]=new P(t,o[a]);for(a=0;a<l;++a)(c=n[a])&&f[p[a]]===c&&(i[a]=c)}function q(t,n){return t<n?-1:t>n?1:t>=n?0:NaN}function U(t){return function(){this.removeAttribute(t)}}function D(t){return function(){this.removeAttributeNS(t.space,t.local)}}function O(t,n){return function(){this.setAttribute(t,n)}}function F(t,n){return function(){this.setAttributeNS(t.space,t.local,n)}}function I(t,n){return function(){var e=n.apply(this,arguments);null==e?this.removeAttribute(t):this.setAttribute(t,e)}}function Y(t,n){return function(){var e=n.apply(this,arguments);null==e?this.removeAttributeNS(t.space,t.local):this.setAttributeNS(t.space,t.local,e)}}function B(t){return function(){this.style.removeProperty(t)}}function H(t,n,e){return function(){this.style.setProperty(t,n,e)}}function j(t,n,e){return function(){var r=n.apply(this,arguments);null==r?this.style.removeProperty(t):this.style.setProperty(t,r,e)}}function X(t,n){return t.style.getPropertyValue(n)||gl(t).getComputedStyle(t,null).getPropertyValue(n)}function $(t){return function(){delete this[t]}}function V(t,n){return function(){this[t]=n}}function W(t,n){return function(){var e=n.apply(this,arguments);null==e?delete this[t]:this[t]=e}}function Z(t){return t.trim().split(/^|\\s+/)}function G(t){return t.classList||new J(t)}function J(t){this._node=t,this._names=Z(t.getAttribute(\"class\")||\"\")}function Q(t,n){for(var e=G(t),r=-1,i=n.length;++r<i;)e.add(n[r])}function K(t,n){for(var e=G(t),r=-1,i=n.length;++r<i;)e.remove(n[r])}function tt(t){return function(){Q(this,t)}}function nt(t){return function(){K(this,t)}}function et(t,n){return function(){(n.apply(this,arguments)?Q:K)(this,t)}}function rt(){this.textContent=\"\"}function it(t){return function(){this.textContent=t}}function ot(t){return function(){var n=t.apply(this,arguments);this.textContent=null==n?\"\":n}}function ut(){this.innerHTML=\"\"}function at(t){return function(){this.innerHTML=t}}function ct(t){return function(){var n=t.apply(this,arguments);this.innerHTML=null==n?\"\":n}}function st(){this.nextSibling&&this.parentNode.appendChild(this)}function ft(){this.previousSibling&&this.parentNode.insertBefore(this,this.parentNode.firstChild)}function lt(){return null}function ht(){var t=this.parentNode;t&&t.removeChild(this)}function pt(t,n,e){var r=gl(t),i=r.CustomEvent;\"function\"==typeof i?i=new i(n,e):(i=r.document.createEvent(\"Event\"),e?(i.initEvent(n,e.bubbles,e.cancelable),i.detail=e.detail):i.initEvent(n,!1,!1)),t.dispatchEvent(i)}function dt(t,n){return function(){return pt(this,t,n)}}function vt(t,n){return function(){return pt(this,t,n.apply(this,arguments))}}function _t(t,n){this._groups=t,this._parents=n}function yt(){return new _t([[document.documentElement]],zl)}function gt(){t.event.stopImmediatePropagation()}function mt(t,n){var e=t.document.documentElement,r=Pl(t).on(\"dragstart.drag\",null);n&&(r.on(\"click.drag\",Ul,!0),setTimeout(function(){r.on(\"click.drag\",null)},0)),\"onselectstart\"in e?r.on(\"selectstart.drag\",null):(e.style.MozUserSelect=e.__noselect,delete e.__noselect)}function xt(t,n,e,r,i,o,u,a,c,s){this.target=t,this.type=n,this.subject=e,this.identifier=r,this.active=i,this.x=o,this.y=u,this.dx=a,this.dy=c,this._=s}function bt(){return!t.event.button}function wt(){return this.parentNode}function Mt(n){return null==n?{x:t.event.x,y:t.event.y}:n}function Tt(t,n){var e=Object.create(t.prototype);for(var r in n)e[r]=n[r];return e}function kt(){}function Nt(t){var n;return t=(t+\"\").trim().toLowerCase(),(n=jl.exec(t))?(n=parseInt(n[1],16),new zt(n>>8&15|n>>4&240,n>>4&15|240&n,(15&n)<<4|15&n,1)):(n=Xl.exec(t))?St(parseInt(n[1],16)):(n=$l.exec(t))?new zt(n[1],n[2],n[3],1):(n=Vl.exec(t))?new zt(255*n[1]/100,255*n[2]/100,255*n[3]/100,1):(n=Wl.exec(t))?Et(n[1],n[2],n[3],n[4]):(n=Zl.exec(t))?Et(255*n[1]/100,255*n[2]/100,255*n[3]/100,n[4]):(n=Gl.exec(t))?Pt(n[1],n[2]/100,n[3]/100,1):(n=Jl.exec(t))?Pt(n[1],n[2]/100,n[3]/100,n[4]):Ql.hasOwnProperty(t)?St(Ql[t]):\"transparent\"===t?new zt(NaN,NaN,NaN,0):null}function St(t){return new zt(t>>16&255,t>>8&255,255&t,1)}function Et(t,n,e,r){return r<=0&&(t=n=e=NaN),new zt(t,n,e,r)}function At(t){return t instanceof kt||(t=Nt(t)),t?(t=t.rgb(),new zt(t.r,t.g,t.b,t.opacity)):new zt}function Ct(t,n,e,r){return 1===arguments.length?At(t):new zt(t,n,e,null==r?1:r)}function zt(t,n,e,r){this.r=+t,this.g=+n,this.b=+e,this.opacity=+r}function Pt(t,n,e,r){return r<=0?t=n=e=NaN:e<=0||e>=1?t=n=NaN:n<=0&&(t=NaN),new qt(t,n,e,r)}function Lt(t){if(t instanceof qt)return new qt(t.h,t.s,t.l,t.opacity);if(t instanceof kt||(t=Nt(t)),!t)return new qt;if(t instanceof qt)return t;t=t.rgb();var n=t.r/255,e=t.g/255,r=t.b/255,i=Math.min(n,e,r),o=Math.max(n,e,r),u=NaN,a=o-i,c=(o+i)/2;return a?(u=n===o?(e-r)/a+6*(e<r):e===o?(r-n)/a+2:(n-e)/a+4,a/=c<.5?o+i:2-o-i,u*=60):a=c>0&&c<1?0:u,new qt(u,a,c,t.opacity)}function Rt(t,n,e,r){return 1===arguments.length?Lt(t):new qt(t,n,e,null==r?1:r)}function qt(t,n,e,r){this.h=+t,this.s=+n,this.l=+e,this.opacity=+r}function Ut(t,n,e){return 255*(t<60?n+(e-n)*t/60:t<180?e:t<240?n+(e-n)*(240-t)/60:n)}function Dt(t){if(t instanceof Ft)return new Ft(t.l,t.a,t.b,t.opacity);if(t instanceof $t){var n=t.h*Kl;return new Ft(t.l,Math.cos(n)*t.c,Math.sin(n)*t.c,t.opacity)}t instanceof zt||(t=At(t));var e=Ht(t.r),r=Ht(t.g),i=Ht(t.b),o=It((.4124564*e+.3575761*r+.1804375*i)/nh),u=It((.2126729*e+.7151522*r+.072175*i)/eh);return new Ft(116*u-16,500*(o-u),200*(u-It((.0193339*e+.119192*r+.9503041*i)/rh)),t.opacity)}function Ot(t,n,e,r){return 1===arguments.length?Dt(t):new Ft(t,n,e,null==r?1:r)}function Ft(t,n,e,r){this.l=+t,this.a=+n,this.b=+e,this.opacity=+r}function It(t){return t>ah?Math.pow(t,1/3):t/uh+ih}function Yt(t){return t>oh?t*t*t:uh*(t-ih)}function Bt(t){return 255*(t<=.0031308?12.92*t:1.055*Math.pow(t,1/2.4)-.055)}function Ht(t){return(t/=255)<=.04045?t/12.92:Math.pow((t+.055)/1.055,2.4)}function jt(t){if(t instanceof $t)return new $t(t.h,t.c,t.l,t.opacity);t instanceof Ft||(t=Dt(t));var n=Math.atan2(t.b,t.a)*th;return new $t(n<0?n+360:n,Math.sqrt(t.a*t.a+t.b*t.b),t.l,t.opacity)}function Xt(t,n,e,r){return 1===arguments.length?jt(t):new $t(t,n,e,null==r?1:r)}function $t(t,n,e,r){this.h=+t,this.c=+n,this.l=+e,this.opacity=+r}function Vt(t){if(t instanceof Zt)return new Zt(t.h,t.s,t.l,t.opacity);t instanceof zt||(t=At(t));var n=t.r/255,e=t.g/255,r=t.b/255,i=(vh*r+ph*n-dh*e)/(vh+ph-dh),o=r-i,u=(hh*(e-i)-fh*o)/lh,a=Math.sqrt(u*u+o*o)/(hh*i*(1-i)),c=a?Math.atan2(u,o)*th-120:NaN;return new Zt(c<0?c+360:c,a,i,t.opacity)}function Wt(t,n,e,r){return 1===arguments.length?Vt(t):new Zt(t,n,e,null==r?1:r)}function Zt(t,n,e,r){this.h=+t,this.s=+n,this.l=+e,this.opacity=+r}function Gt(t,n,e,r,i){var o=t*t,u=o*t;return((1-3*t+3*o-u)*n+(4-6*o+3*u)*e+(1+3*t+3*o-3*u)*r+u*i)/6}function Jt(t,n){return function(e){return t+e*n}}function Qt(t,n,e){return t=Math.pow(t,e),n=Math.pow(n,e)-t,e=1/e,function(r){return Math.pow(t+r*n,e)}}function Kt(t,n){var e=n-t;return e?Jt(t,e>180||e<-180?e-360*Math.round(e/360):e):Th(isNaN(t)?n:t)}function tn(t){return 1==(t=+t)?nn:function(n,e){return e-n?Qt(n,e,t):Th(isNaN(n)?e:n)}}function nn(t,n){var e=n-t;return e?Jt(t,e):Th(isNaN(t)?n:t)}function en(t){return function(n){var e,r,i=n.length,o=new Array(i),u=new Array(i),a=new Array(i);for(e=0;e<i;++e)r=Ct(n[e]),o[e]=r.r||0,u[e]=r.g||0,a[e]=r.b||0;return o=t(o),u=t(u),a=t(a),r.opacity=1,function(t){return r.r=o(t),r.g=u(t),r.b=a(t),r+\"\"}}}function rn(t){return function(){return t}}function on(t){return function(n){return t(n)+\"\"}}function un(t){return\"none\"===t?Oh:(_h||(_h=document.createElement(\"DIV\"),yh=document.documentElement,gh=document.defaultView),_h.style.transform=t,t=gh.getComputedStyle(yh.appendChild(_h),null).getPropertyValue(\"transform\"),yh.removeChild(_h),t=t.slice(7,-1).split(\",\"),Fh(+t[0],+t[1],+t[2],+t[3],+t[4],+t[5]))}function an(t){return null==t?Oh:(mh||(mh=document.createElementNS(\"http://www.w3.org/2000/svg\",\"g\")),mh.setAttribute(\"transform\",t),(t=mh.transform.baseVal.consolidate())?(t=t.matrix,Fh(t.a,t.b,t.c,t.d,t.e,t.f)):Oh)}function cn(t,n,e,r){function i(t){return t.length?t.pop()+\" \":\"\"}function o(t,r,i,o,u,a){if(t!==i||r!==o){var c=u.push(\"translate(\",null,n,null,e);a.push({i:c-4,x:Ch(t,i)},{i:c-2,x:Ch(r,o)})}else(i||o)&&u.push(\"translate(\"+i+n+o+e)}function u(t,n,e,o){t!==n?(t-n>180?n+=360:n-t>180&&(t+=360),o.push({i:e.push(i(e)+\"rotate(\",null,r)-2,x:Ch(t,n)})):n&&e.push(i(e)+\"rotate(\"+n+r)}function a(t,n,e,o){t!==n?o.push({i:e.push(i(e)+\"skewX(\",null,r)-2,x:Ch(t,n)}):n&&e.push(i(e)+\"skewX(\"+n+r)}function c(t,n,e,r,o,u){if(t!==e||n!==r){var a=o.push(i(o)+\"scale(\",null,\",\",null,\")\");u.push({i:a-4,x:Ch(t,e)},{i:a-2,x:Ch(n,r)})}else 1===e&&1===r||o.push(i(o)+\"scale(\"+e+\",\"+r+\")\")}return function(n,e){var r=[],i=[];return n=t(n),e=t(e),o(n.translateX,n.translateY,e.translateX,e.translateY,r,i),u(n.rotate,e.rotate,r,i),a(n.skewX,e.skewX,r,i),c(n.scaleX,n.scaleY,e.scaleX,e.scaleY,r,i),n=e=null,function(t){for(var n,e=-1,o=i.length;++e<o;)r[(n=i[e]).i]=n.x(t);return r.join(\"\")}}}function sn(t){return((t=Math.exp(t))+1/t)/2}function fn(t){return((t=Math.exp(t))-1/t)/2}function ln(t){return((t=Math.exp(2*t))-1)/(t+1)}function hn(t){return function(n,e){var r=t((n=Rt(n)).h,(e=Rt(e)).h),i=nn(n.s,e.s),o=nn(n.l,e.l),u=nn(n.opacity,e.opacity);return function(t){return n.h=r(t),n.s=i(t),n.l=o(t),n.opacity=u(t),n+\"\"}}}function pn(t,n){var e=nn((t=Ot(t)).l,(n=Ot(n)).l),r=nn(t.a,n.a),i=nn(t.b,n.b),o=nn(t.opacity,n.opacity);return function(n){return t.l=e(n),t.a=r(n),t.b=i(n),t.opacity=o(n),t+\"\"}}function dn(t){return function(n,e){var r=t((n=Xt(n)).h,(e=Xt(e)).h),i=nn(n.c,e.c),o=nn(n.l,e.l),u=nn(n.opacity,e.opacity);return function(t){return n.h=r(t),n.c=i(t),n.l=o(t),n.opacity=u(t),n+\"\"}}}function vn(t){return function n(e){function r(n,r){var i=t((n=Wt(n)).h,(r=Wt(r)).h),o=nn(n.s,r.s),u=nn(n.l,r.l),a=nn(n.opacity,r.opacity);return function(t){return n.h=i(t),n.s=o(t),n.l=u(Math.pow(t,e)),n.opacity=a(t),n+\"\"}}return e=+e,r.gamma=n,r}(1)}function _n(){return ep||(op(yn),ep=ip.now()+rp)}function yn(){ep=0}function gn(){this._call=this._time=this._next=null}function mn(t,n,e){var r=new gn;return r.restart(t,n,e),r}function xn(){_n(),++Jh;for(var t,n=xh;n;)(t=ep-n._time)>=0&&n._call.call(null,t),n=n._next;--Jh}function bn(){ep=(np=ip.now())+rp,Jh=Qh=0;try{xn()}finally{Jh=0,Mn(),ep=0}}function wn(){var t=ip.now(),n=t-np;n>tp&&(rp-=n,np=t)}function Mn(){for(var t,n,e=xh,r=1/0;e;)e._call?(r>e._time&&(r=e._time),t=e,e=e._next):(n=e._next,e._next=null,e=t?t._next=n:xh=n);bh=t,Tn(r)}function Tn(t){if(!Jh){Qh&&(Qh=clearTimeout(Qh));var n=t-ep;n>24?(t<1/0&&(Qh=setTimeout(bn,n)),Kh&&(Kh=clearInterval(Kh))):(Kh||(np=ep,Kh=setInterval(wn,tp)),Jh=1,op(bn))}}function kn(t,n){var e=t.__transition;if(!e||!(e=e[n])||e.state>fp)throw new Error(\"too late\");return e}function Nn(t,n){var e=t.__transition;if(!e||!(e=e[n])||e.state>hp)throw new Error(\"too late\");return e}function Sn(t,n){var e=t.__transition;if(!e||!(e=e[n]))throw new Error(\"too late\");return e}function En(t,n,e){function r(t){e.state=lp,e.timer.restart(i,e.delay,e.time),e.delay<=t&&i(t-e.delay)}function i(r){var s,f,l,h;if(e.state!==lp)return u();for(s in c)if(h=c[s],h.name===e.name){if(h.state===pp)return up(i);h.state===dp?(h.state=_p,h.timer.stop(),h.on.call(\"interrupt\",t,t.__data__,h.index,h.group),delete c[s]):+s<n&&(h.state=_p,h.timer.stop(),delete c[s])}if(up(function(){e.state===pp&&(e.state=dp,e.timer.restart(o,e.delay,e.time),o(r))}),e.state=hp,e.on.call(\"start\",t,t.__data__,e.index,e.group),e.state===hp){for(e.state=pp,a=new Array(l=e.tween.length),s=0,f=-1;s<l;++s)(h=e.tween[s].value.call(t,t.__data__,e.index,e.group))&&(a[++f]=h);a.length=f+1}}function o(n){for(var r=n<e.duration?e.ease.call(null,n/e.duration):(e.timer.restart(u),e.state=vp,1),i=-1,o=a.length;++i<o;)a[i].call(null,r);e.state===vp&&(e.on.call(\"end\",t,t.__data__,e.index,e.group),u())}function u(){e.state=_p,e.timer.stop(),delete c[n];for(var r in c)return;delete t.__transition}var a,c=t.__transition;c[n]=e,e.timer=mn(r,0,e.time)}function An(t,n){var e,r;return function(){var i=Nn(this,t),o=i.tween;if(o!==e){r=e=o;for(var u=0,a=r.length;u<a;++u)if(r[u].name===n){r=r.slice(),r.splice(u,1);break}}i.tween=r}}function Cn(t,n,e){var r,i;if(\"function\"!=typeof e)throw new Error;return function(){var o=Nn(this,t),u=o.tween;if(u!==r){i=(r=u).slice();for(var a={name:n,value:e},c=0,s=i.length;c<s;++c)if(i[c].name===n){i[c]=a;break}c===s&&i.push(a)}o.tween=i}}function zn(t,n,e){var r=t._id;return t.each(function(){var t=Nn(this,r);(t.value||(t.value={}))[n]=e.apply(this,arguments)}),function(t){return Sn(t,r).value[n]}}function Pn(t){return function(){this.removeAttribute(t)}}function Ln(t){return function(){this.removeAttributeNS(t.space,t.local)}}function Rn(t,n,e){var r,i;return function(){var o=this.getAttribute(t);return o===e?null:o===r?i:i=n(r=o,e)}}function qn(t,n,e){var r,i;return function(){var o=this.getAttributeNS(t.space,t.local);return o===e?null:o===r?i:i=n(r=o,e)}}function Un(t,n,e){var r,i,o;return function(){var u,a=e(this);return null==a?void this.removeAttribute(t):(u=this.getAttribute(t),u===a?null:u===r&&a===i?o:o=n(r=u,i=a))}}function Dn(t,n,e){var r,i,o;return function(){var u,a=e(this);return null==a?void this.removeAttributeNS(t.space,t.local):(u=this.getAttributeNS(t.space,t.local),u===a?null:u===r&&a===i?o:o=n(r=u,i=a))}}function On(t,n){function e(){var e=this,r=n.apply(e,arguments);return r&&function(n){e.setAttributeNS(t.space,t.local,r(n))}}return e._value=n,e}function Fn(t,n){function e(){var e=this,r=n.apply(e,arguments);return r&&function(n){e.setAttribute(t,r(n))}}return e._value=n,e}function In(t,n){return function(){kn(this,t).delay=+n.apply(this,arguments)}}function Yn(t,n){return n=+n,function(){kn(this,t).delay=n}}function Bn(t,n){return function(){Nn(this,t).duration=+n.apply(this,arguments)}}function Hn(t,n){return n=+n,function(){Nn(this,t).duration=n}}function jn(t,n){if(\"function\"!=typeof n)throw new Error;return function(){Nn(this,t).ease=n}}function Xn(t){return(t+\"\").trim().split(/^|\\s+/).every(function(t){var n=t.indexOf(\".\");return n>=0&&(t=t.slice(0,n)),!t||\"start\"===t})}function $n(t,n,e){var r,i,o=Xn(n)?kn:Nn;return function(){var u=o(this,t),a=u.on;a!==r&&(i=(r=a).copy()).on(n,e),u.on=i}}function Vn(t){return function(){var n=this.parentNode;for(var e in this.__transition)if(+e!==t)return;n&&n.removeChild(this)}}function Wn(t,n){var e,r,i;return function(){var o=X(this,t),u=(this.style.removeProperty(t),X(this,t));return o===u?null:o===e&&u===r?i:i=n(e=o,r=u)}}function Zn(t){return function(){this.style.removeProperty(t)}}function Gn(t,n,e){var r,i;return function(){var o=X(this,t);return o===e?null:o===r?i:i=n(r=o,e)}}function Jn(t,n,e){var r,i,o;return function(){var u=X(this,t),a=e(this);return null==a&&(this.style.removeProperty(t),a=X(this,t)),u===a?null:u===r&&a===i?o:o=n(r=u,i=a)}}function Qn(t,n,e){function r(){var r=this,i=n.apply(r,arguments);return i&&function(n){r.style.setProperty(t,i(n),e)}}return r._value=n,r}function Kn(t){return function(){this.textContent=t}}function te(t){return function(){var n=t(this);this.textContent=null==n?\"\":n}}function ne(t,n,e,r){this._groups=t,this._parents=n,this._name=e,this._id=r}function ee(t){return yt().transition(t)}function re(){return++Fp}function ie(t){return+t}function oe(t){return t*t}function ue(t){return t*(2-t)}function ae(t){return((t*=2)<=1?t*t:--t*(2-t)+1)/2}function ce(t){return t*t*t}function se(t){return--t*t*t+1}function fe(t){return((t*=2)<=1?t*t*t:(t-=2)*t*t+2)/2}function le(t){return 1-Math.cos(t*Xp)}function he(t){return Math.sin(t*Xp)}function pe(t){return(1-Math.cos(jp*t))/2}function de(t){return Math.pow(2,10*t-10)}function ve(t){return 1-Math.pow(2,-10*t)}function _e(t){return((t*=2)<=1?Math.pow(2,10*t-10):2-Math.pow(2,10-10*t))/2}function ye(t){return 1-Math.sqrt(1-t*t)}function ge(t){return Math.sqrt(1- --t*t)}function me(t){return((t*=2)<=1?1-Math.sqrt(1-t*t):Math.sqrt(1-(t-=2)*t)+1)/2}function xe(t){return 1-be(1-t)}function be(t){return(t=+t)<$p?nd*t*t:t<Wp?nd*(t-=Vp)*t+Zp:t<Jp?nd*(t-=Gp)*t+Qp:nd*(t-=Kp)*t+td}function we(t){return((t*=2)<=1?1-be(1-t):be(t-1)+1)/2}function Me(t,n){for(var e;!(e=t.__transition)||!(e=e[n]);)if(!(t=t.parentNode))return sd.time=_n(),sd;return e}function Te(){t.event.stopImmediatePropagation()}function ke(t){return{type:t}}function Ne(){return!t.event.button}function Se(){var t=this.ownerSVGElement||this;return[[0,0],[t.width.baseVal.value,t.height.baseVal.value]]}function Ee(t){for(;!t.__brush;)if(!(t=t.parentNode))return;return t.__brush}function Ae(t){return t[0][0]===t[1][0]||t[0][1]===t[1][1]}function Ce(t){var n=t.__brush;return n?n.dim.output(n.selection):null}function ze(){return Le(xd)}function Pe(){return Le(bd)}function Le(n){function e(t){var e=t.property(\"__brush\",a).selectAll(\".overlay\").data([ke(\"overlay\")]);e.enter().append(\"rect\").attr(\"class\",\"overlay\").attr(\"pointer-events\",\"all\").attr(\"cursor\",Md.overlay).merge(e).each(function(){var t=Ee(this).extent;Pl(this).attr(\"x\",t[0][0]).attr(\"y\",t[0][1]).attr(\"width\",t[1][0]-t[0][0]).attr(\"height\",t[1][1]-t[0][1])}),t.selectAll(\".selection\").data([ke(\"selection\")]).enter().append(\"rect\").attr(\"class\",\"selection\").attr(\"cursor\",Md.selection).attr(\"fill\",\"#777\").attr(\"fill-opacity\",.3).attr(\"stroke\",\"#fff\").attr(\"shape-rendering\",\"crispEdges\");var i=t.selectAll(\".handle\").data(n.handles,function(t){return t.type});i.exit().remove(),i.enter().append(\"rect\").attr(\"class\",function(t){return\"handle handle--\"+t.type}).attr(\"cursor\",function(t){return Md[t.type]}),t.each(r).attr(\"fill\",\"none\").attr(\"pointer-events\",\"all\").style(\"-webkit-tap-highlight-color\",\"rgba(0,0,0,0)\").on(\"mousedown.brush touchstart.brush\",u)}function r(){var t=Pl(this),n=Ee(this).selection;n?(t.selectAll(\".selection\").style(\"display\",null).attr(\"x\",n[0][0]).attr(\"y\",n[0][1]).attr(\"width\",n[1][0]-n[0][0]).attr(\"height\",n[1][1]-n[0][1]),t.selectAll(\".handle\").style(\"display\",null).attr(\"x\",function(t){return\"e\"===t.type[t.type.length-1]?n[1][0]-h/2:n[0][0]-h/2}).attr(\"y\",function(t){return\"s\"===t.type[0]?n[1][1]-h/2:n[0][1]-h/2}).attr(\"width\",function(t){return\"n\"===t.type||\"s\"===t.type?n[1][0]-n[0][0]+h:h}).attr(\"height\",function(t){return\"e\"===t.type||\"w\"===t.type?n[1][1]-n[0][1]+h:h})):t.selectAll(\".selection,.handle\").style(\"display\",\"none\").attr(\"x\",null).attr(\"y\",null).attr(\"width\",null).attr(\"height\",null)}function i(t,n){return t.__brush.emitter||new o(t,n)}function o(t,n){this.that=t,this.args=n,this.state=t.__brush,this.active=0}function u(){function e(){var t=Gf(T);!U||w||M||(Math.abs(t[0]-O[0])>Math.abs(t[1]-O[1])?M=!0:w=!0),O=t,b=!0,vd(),o()}function o(){var t;switch(m=O[0]-D[0],x=O[1]-D[1],N){case yd:case _d:S&&(m=Math.max(P-l,Math.min(R-v,m)),h=l+m,_=v+m),E&&(x=Math.max(L-p,Math.min(q-y,x)),d=p+x,g=y+x);break;case gd:S<0?(m=Math.max(P-l,Math.min(R-l,m)),h=l+m,_=v):S>0&&(m=Math.max(P-v,Math.min(R-v,m)),h=l,_=v+m),E<0?(x=Math.max(L-p,Math.min(q-p,x)),d=p+x,g=y):E>0&&(x=Math.max(L-y,Math.min(q-y,x)),d=p,g=y+x);break;case md:S&&(h=Math.max(P,Math.min(R,l-m*S)),_=Math.max(P,Math.min(R,v+m*S))),E&&(d=Math.max(L,Math.min(q,p-x*E)),g=Math.max(L,Math.min(q,y+x*E)))}_<h&&(S*=-1,t=l,l=v,v=t,t=h,h=_,_=t,k in Td&&Y.attr(\"cursor\",Md[k=Td[k]])),g<d&&(E*=-1,t=p,p=y,y=t,t=d,d=g,g=t,k in kd&&Y.attr(\"cursor\",Md[k=kd[k]])),A.selection&&(z=A.selection),w&&(h=z[0][0],_=z[1][0]),M&&(d=z[0][1],g=z[1][1]),z[0][0]===h&&z[0][1]===d&&z[1][0]===_&&z[1][1]===g||(A.selection=[[h,d],[_,g]],r.call(T),F.brush())}function u(){if(Te(),t.event.touches){if(t.event.touches.length)return;c&&clearTimeout(c),c=setTimeout(function(){c=null},500),I.on(\"touchmove.brush touchend.brush touchcancel.brush\",null)}else mt(t.event.view,b),B.on(\"keydown.brush keyup.brush mousemove.brush mouseup.brush\",null);I.attr(\"pointer-events\",\"all\"),Y.attr(\"cursor\",Md.overlay),A.selection&&(z=A.selection),Ae(z)&&(A.selection=null,r.call(T)),F.end()}function a(){switch(t.event.keyCode){case 16:U=S&&E;break;case 18:N===gd&&(S&&(v=_-m*S,l=h+m*S),E&&(y=g-x*E,p=d+x*E),N=md,o());break;case 32:N!==gd&&N!==md||(S<0?v=_-m:S>0&&(l=h-m),E<0?y=g-x:E>0&&(p=d-x),N=yd,Y.attr(\"cursor\",Md.selection),o());break;default:return}vd()}function s(){switch(t.event.keyCode){case 16:U&&(w=M=U=!1,o());break;case 18:N===md&&(S<0?v=_:S>0&&(l=h),E<0?y=g:E>0&&(p=d),N=gd,o());break;case 32:N===yd&&(t.event.altKey?(S&&(v=_-m*S,l=h+m*S),E&&(y=g-x*E,p=d+x*E),N=md):(S<0?v=_:S>0&&(l=h),E<0?y=g:E>0&&(p=d),N=gd),Y.attr(\"cursor\",Md[k]),o());break;default:return}vd()}if(t.event.touches){if(t.event.changedTouches.length<t.event.touches.length)return vd()}else if(c)return;if(f.apply(this,arguments)){var l,h,p,d,v,_,y,g,m,x,b,w,M,T=this,k=t.event.target.__data__.type,N=\"selection\"===(t.event.metaKey?k=\"overlay\":k)?_d:t.event.altKey?md:gd,S=n===bd?null:Nd[k],E=n===xd?null:Sd[k],A=Ee(T),C=A.extent,z=A.selection,P=C[0][0],L=C[0][1],R=C[1][0],q=C[1][1],U=S&&E&&t.event.shiftKey,D=Gf(T),O=D,F=i(T,arguments).beforestart();\"overlay\"===k?A.selection=z=[[l=n===bd?P:D[0],p=n===xd?L:D[1]],[v=n===bd?R:l,y=n===xd?q:p]]:(l=z[0][0],p=z[0][1],v=z[1][0],y=z[1][1]),h=l,d=p,_=v,g=y;var I=Pl(T).attr(\"pointer-events\",\"none\"),Y=I.selectAll(\".overlay\").attr(\"cursor\",Md[k]);if(t.event.touches)I.on(\"touchmove.brush\",e,!0).on(\"touchend.brush touchcancel.brush\",u,!0);else{var B=Pl(t.event.view).on(\"keydown.brush\",a,!0).on(\"keyup.brush\",s,!0).on(\"mousemove.brush\",e,!0).on(\"mouseup.brush\",u,!0);Dl(t.event.view)}Te(),gp(T),r.call(T),F.start()}}function a(){var t=this.__brush||{selection:null};return t.extent=s.apply(this,arguments),t.dim=n,t}var c,s=Se,f=Ne,l=v(e,\"start\",\"brush\",\"end\"),h=6;return e.move=function(t,e){t.selection?t.on(\"start.brush\",function(){i(this,arguments).beforestart().start()}).on(\"interrupt.brush end.brush\",function(){i(this,arguments).end()}).tween(\"brush\",function(){function t(t){u.selection=1===t&&Ae(s)?null:f(t),r.call(o),a.brush()}var o=this,u=o.__brush,a=i(o,arguments),c=u.selection,s=n.input(\"function\"==typeof e?e.apply(this,arguments):e,u.extent),f=qh(c,s);return c&&s?t:t(1)}):t.each(function(){var t=this,o=arguments,u=t.__brush,a=n.input(\"function\"==typeof e?e.apply(t,o):e,u.extent),c=i(t,o).beforestart();gp(t),u.selection=null==a||Ae(a)?null:a,r.call(t),c.start().brush().end()})},o.prototype={beforestart:function(){return 1==++this.active&&(this.state.emitter=this,this.starting=!0),this},start:function(){return this.starting&&(this.starting=!1,this.emit(\"start\")),this},brush:function(){return this.emit(\"brush\"),this},end:function(){return 0==--this.active&&(delete this.state.emitter,this.emit(\"end\")),this},emit:function(t){A(new dd(e,t,n.output(this.state.selection)),l.apply,l,[t,this.that,this.args])}},e.extent=function(t){return arguments.length?(s=\"function\"==typeof t?t:pd([[+t[0][0],+t[0][1]],[+t[1][0],+t[1][1]]]),e):s},e.filter=function(t){return arguments.length?(f=\"function\"==typeof t?t:pd(!!t),e):f},e.handleSize=function(t){return arguments.length?(h=+t,e):h},e.on=function(){var t=l.on.apply(l,arguments);return t===l?e:t},e}function Re(t){return function(n,e){return t(n.source.value+n.target.value,e.source.value+e.target.value)}}function qe(){this._x0=this._y0=this._x1=this._y1=null,this._=\"\"}function Ue(){return new qe}function De(t){return t.source}function Oe(t){return t.target}function Fe(t){return t.radius}function Ie(t){return t.startAngle}function Ye(t){return t.endAngle}function Be(){}function He(t,n){var e=new Be;if(t instanceof Be)t.each(function(t,n){e.set(n,t)});else if(Array.isArray(t)){var r,i=-1,o=t.length;if(null==n)for(;++i<o;)e.set(i,t[i]);else for(;++i<o;)e.set(n(r=t[i],i,t),r)}else if(t)for(var u in t)e.set(u,t[u]);return e}function je(){return{}}function Xe(t,n,e){t[n]=e}function $e(){return He()}function Ve(t,n,e){t.set(n,e)}function We(){}function Ze(t,n){var e=new We;if(t instanceof We)t.each(function(t){e.add(t)});else if(t){var r=-1,i=t.length;if(null==n)for(;++r<i;)e.add(t[r]);else for(;++r<i;)e.add(n(t[r],r,t))}return e}function Ge(t){return new Function(\"d\",\"return {\"+t.map(function(t,n){return JSON.stringify(t)+\": d[\"+n+\"]\"}).join(\",\")+\"}\")}function Je(t,n){var e=Ge(t);return function(r,i){return n(e(r),i,t)}}function Qe(t){var n=Object.create(null),e=[];return t.forEach(function(t){for(var r in t)r in n||e.push(n[r]=r)}),e}function Ke(t,n,e,r){if(isNaN(n)||isNaN(e))return t;var i,o,u,a,c,s,f,l,h,p=t._root,d={data:r},v=t._x0,_=t._y0,y=t._x1,g=t._y1;if(!p)return t._root=d,t;for(;p.length;)if((s=n>=(o=(v+y)/2))?v=o:y=o,(f=e>=(u=(_+g)/2))?_=u:g=u,i=p,!(p=p[l=f<<1|s]))return i[l]=d,t;if(a=+t._x.call(null,p.data),c=+t._y.call(null,p.data),n===a&&e===c)return d.next=p,i?i[l]=d:t._root=d,t;do{i=i?i[l]=new Array(4):t._root=new Array(4),(s=n>=(o=(v+y)/2))?v=o:y=o,(f=e>=(u=(_+g)/2))?_=u:g=u}while((l=f<<1|s)==(h=(c>=u)<<1|a>=o));return i[h]=p,i[l]=d,t}function tr(t){var n,e,r,i,o=t.length,u=new Array(o),a=new Array(o),c=1/0,s=1/0,f=-1/0,l=-1/0;for(e=0;e<o;++e)isNaN(r=+this._x.call(null,n=t[e]))||isNaN(i=+this._y.call(null,n))||(u[e]=r,a[e]=i,r<c&&(c=r),r>f&&(f=r),i<s&&(s=i),i>l&&(l=i));for(f<c&&(c=this._x0,f=this._x1),l<s&&(s=this._y0,l=this._y1),this.cover(c,s).cover(f,l),e=0;e<o;++e)Ke(this,u[e],a[e],t[e]);return this}function nr(t){for(var n=0,e=t.length;n<e;++n)this.remove(t[n]);return this}function er(t){return t[0]}function rr(t){return t[1]}function ir(t,n,e){var r=new or(null==n?er:n,null==e?rr:e,NaN,NaN,NaN,NaN);return null==t?r:r.addAll(t)}function or(t,n,e,r,i,o){this._x=t,this._y=n,this._x0=e,this._y0=r,this._x1=i,this._y1=o,this._root=void 0}function ur(t){for(var n={data:t.data},e=n;t=t.next;)e=e.next={data:t.data};return n}function ar(t){return t.x+t.vx}function cr(t){return t.y+t.vy}function sr(t){return t.index}function fr(t,n){var e=t.get(n);if(!e)throw new Error(\"missing: \"+n);return e}function lr(t){return t.x}function hr(t){return t.y}function pr(t){return new dr(t)}function dr(t){if(!(n=Ov.exec(t)))throw new Error(\"invalid format: \"+t);var n,e=n[1]||\" \",r=n[2]||\">\",i=n[3]||\"-\",o=n[4]||\"\",u=!!n[5],a=n[6]&&+n[6],c=!!n[7],s=n[8]&&+n[8].slice(1),f=n[9]||\"\";\"n\"===f?(c=!0,f=\"g\"):Dv[f]||(f=\"\"),(u||\"0\"===e&&\"=\"===r)&&(u=!0,e=\"0\",r=\"=\"),this.fill=e,this.align=r,\nthis.sign=i,this.symbol=o,this.zero=u,this.width=a,this.comma=c,this.precision=s,this.type=f}function vr(n){return Fv=Bv(n),t.format=Fv.format,t.formatPrefix=Fv.formatPrefix,Fv}function _r(){this.reset()}function yr(t,n,e){var r=t.s=n+e,i=r-n,o=r-i;t.t=n-o+(e-i)}function gr(t){return t>1?0:t<-1?N_:Math.acos(t)}function mr(t){return t>1?S_:t<-1?-S_:Math.asin(t)}function xr(t){return(t=I_(t/2))*t}function br(){}function wr(t,n){t&&X_.hasOwnProperty(t.type)&&X_[t.type](t,n)}function Mr(t,n,e){var r,i=-1,o=t.length-e;for(n.lineStart();++i<o;)r=t[i],n.point(r[0],r[1],r[2]);n.lineEnd()}function Tr(t,n){var e=-1,r=t.length;for(n.polygonStart();++e<r;)Mr(t[e],n,1);n.polygonEnd()}function kr(){Z_.point=Sr}function Nr(){Er(Vv,Wv)}function Sr(t,n){Z_.point=Er,Vv=t,Wv=n,t*=z_,n*=z_,Zv=t,Gv=q_(n=n/2+E_),Jv=I_(n)}function Er(t,n){t*=z_,n*=z_,n=n/2+E_;var e=t-Zv,r=e>=0?1:-1,i=r*e,o=q_(n),u=I_(n),a=Jv*u,c=Gv*o+a*q_(i),s=a*r*I_(i);V_.add(R_(s,c)),Zv=t,Gv=o,Jv=u}function Ar(t){return[R_(t[1],t[0]),mr(t[2])]}function Cr(t){var n=t[0],e=t[1],r=q_(e);return[r*q_(n),r*I_(n),I_(e)]}function zr(t,n){return t[0]*n[0]+t[1]*n[1]+t[2]*n[2]}function Pr(t,n){return[t[1]*n[2]-t[2]*n[1],t[2]*n[0]-t[0]*n[2],t[0]*n[1]-t[1]*n[0]]}function Lr(t,n){t[0]+=n[0],t[1]+=n[1],t[2]+=n[2]}function Rr(t,n){return[t[0]*n,t[1]*n,t[2]*n]}function qr(t){var n=B_(t[0]*t[0]+t[1]*t[1]+t[2]*t[2]);t[0]/=n,t[1]/=n,t[2]/=n}function Ur(t,n){u_.push(a_=[Qv=t,t_=t]),n<Kv&&(Kv=n),n>n_&&(n_=n)}function Dr(t,n){var e=Cr([t*z_,n*z_]);if(o_){var r=Pr(o_,e),i=[r[1],-r[0],0],o=Pr(i,r);qr(o),o=Ar(o);var u,a=t-e_,c=a>0?1:-1,s=o[0]*C_*c,f=P_(a)>180;f^(c*e_<s&&s<c*t)?(u=o[1]*C_)>n_&&(n_=u):(s=(s+360)%360-180,f^(c*e_<s&&s<c*t)?(u=-o[1]*C_)<Kv&&(Kv=u):(n<Kv&&(Kv=n),n>n_&&(n_=n))),f?t<e_?Hr(Qv,t)>Hr(Qv,t_)&&(t_=t):Hr(t,t_)>Hr(Qv,t_)&&(Qv=t):t_>=Qv?(t<Qv&&(Qv=t),t>t_&&(t_=t)):t>e_?Hr(Qv,t)>Hr(Qv,t_)&&(t_=t):Hr(t,t_)>Hr(Qv,t_)&&(Qv=t)}else u_.push(a_=[Qv=t,t_=t]);n<Kv&&(Kv=n),n>n_&&(n_=n),o_=e,e_=t}function Or(){Q_.point=Dr}function Fr(){a_[0]=Qv,a_[1]=t_,Q_.point=Ur,o_=null}function Ir(t,n){if(o_){var e=t-e_;J_.add(P_(e)>180?e+(e>0?360:-360):e)}else r_=t,i_=n;Z_.point(t,n),Dr(t,n)}function Yr(){Z_.lineStart()}function Br(){Ir(r_,i_),Z_.lineEnd(),P_(J_)>k_&&(Qv=-(t_=180)),a_[0]=Qv,a_[1]=t_,o_=null}function Hr(t,n){return(n-=t)<0?n+360:n}function jr(t,n){return t[0]-n[0]}function Xr(t,n){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:n<t[0]||t[1]<n}function $r(t,n){t*=z_,n*=z_;var e=q_(n);Vr(e*q_(t),e*I_(t),I_(n))}function Vr(t,n,e){++c_,f_+=(t-f_)/c_,l_+=(n-l_)/c_,h_+=(e-h_)/c_}function Wr(){ty.point=Zr}function Zr(t,n){t*=z_,n*=z_;var e=q_(n);b_=e*q_(t),w_=e*I_(t),M_=I_(n),ty.point=Gr,Vr(b_,w_,M_)}function Gr(t,n){t*=z_,n*=z_;var e=q_(n),r=e*q_(t),i=e*I_(t),o=I_(n),u=R_(B_((u=w_*o-M_*i)*u+(u=M_*r-b_*o)*u+(u=b_*i-w_*r)*u),b_*r+w_*i+M_*o);s_+=u,p_+=u*(b_+(b_=r)),d_+=u*(w_+(w_=i)),v_+=u*(M_+(M_=o)),Vr(b_,w_,M_)}function Jr(){ty.point=$r}function Qr(){ty.point=ti}function Kr(){ni(m_,x_),ty.point=$r}function ti(t,n){m_=t,x_=n,t*=z_,n*=z_,ty.point=ni;var e=q_(n);b_=e*q_(t),w_=e*I_(t),M_=I_(n),Vr(b_,w_,M_)}function ni(t,n){t*=z_,n*=z_;var e=q_(n),r=e*q_(t),i=e*I_(t),o=I_(n),u=w_*o-M_*i,a=M_*r-b_*o,c=b_*i-w_*r,s=B_(u*u+a*a+c*c),f=mr(s),l=s&&-f/s;__+=l*u,y_+=l*a,g_+=l*c,s_+=f,p_+=f*(b_+(b_=r)),d_+=f*(w_+(w_=i)),v_+=f*(M_+(M_=o)),Vr(b_,w_,M_)}function ei(t,n){return[t>N_?t-A_:t<-N_?t+A_:t,n]}function ri(t,n,e){return(t%=A_)?n||e?ry(oi(t),ui(n,e)):oi(t):n||e?ui(n,e):ei}function ii(t){return function(n,e){return n+=t,[n>N_?n-A_:n<-N_?n+A_:n,e]}}function oi(t){var n=ii(t);return n.invert=ii(-t),n}function ui(t,n){function e(t,n){var e=q_(n),a=q_(t)*e,c=I_(t)*e,s=I_(n),f=s*r+a*i;return[R_(c*o-f*u,a*r-s*i),mr(f*o+c*u)]}var r=q_(t),i=I_(t),o=q_(n),u=I_(n);return e.invert=function(t,n){var e=q_(n),a=q_(t)*e,c=I_(t)*e,s=I_(n),f=s*o-c*u;return[R_(c*o+s*u,a*r+f*i),mr(f*r-a*i)]},e}function ai(t,n,e,r,i,o){if(e){var u=q_(n),a=I_(n),c=r*e;null==i?(i=n+r*A_,o=n-c/2):(i=ci(u,i),o=ci(u,o),(r>0?i<o:i>o)&&(i+=r*A_));for(var s,f=i;r>0?f>o:f<o;f-=c)s=Ar([u,-a*q_(f),-a*I_(f)]),t.point(s[0],s[1])}}function ci(t,n){n=Cr(n),n[0]-=t,qr(n);var e=gr(-n[1]);return((-n[2]<0?-e:e)+A_-k_)%A_}function si(t,n,e,r){this.x=t,this.z=n,this.o=e,this.e=r,this.v=!1,this.n=this.p=null}function fi(t){if(n=t.length){for(var n,e,r=0,i=t[0];++r<n;)i.n=e=t[r],e.p=i,i=e;i.n=e=t[0],e.p=i}}function li(t,n,e,r){function i(i,o){return t<=i&&i<=e&&n<=o&&o<=r}function o(i,o,a,s){var f=0,l=0;if(null==i||(f=u(i,a))!==(l=u(o,a))||c(i,o)<0^a>0)do{s.point(0===f||3===f?t:e,f>1?r:n)}while((f=(f+a+4)%4)!==l);else s.point(o[0],o[1])}function u(r,i){return P_(r[0]-t)<k_?i>0?0:3:P_(r[0]-e)<k_?i>0?2:1:P_(r[1]-n)<k_?i>0?1:0:i>0?3:2}function a(t,n){return c(t.x,n.x)}function c(t,n){var e=u(t,1),r=u(n,1);return e!==r?e-r:0===e?n[1]-t[1]:1===e?t[0]-n[0]:2===e?t[1]-n[1]:n[0]-t[0]}return function(u){function c(t,n){i(t,n)&&N.point(t,n)}function s(){for(var n=0,e=0,i=_.length;e<i;++e)for(var o,u,a=_[e],c=1,s=a.length,f=a[0],l=f[0],h=f[1];c<s;++c)o=l,u=h,f=a[c],l=f[0],h=f[1],u<=r?h>r&&(l-o)*(r-u)>(h-u)*(t-o)&&++n:h<=r&&(l-o)*(r-u)<(h-u)*(t-o)&&--n;return n}function f(){N=S,v=[],_=[],k=!0}function l(){var t=s(),n=k&&t,e=(v=bf(v)).length;(n||e)&&(u.polygonStart(),n&&(u.lineStart(),o(null,null,1,u),u.lineEnd()),e&&xy(v,a,t,o,u),u.polygonEnd()),N=u,v=_=y=null}function h(){E.point=d,_&&_.push(y=[]),T=!0,M=!1,b=w=NaN}function p(){v&&(d(g,m),x&&M&&S.rejoin(),v.push(S.result())),E.point=c,M&&N.lineEnd()}function d(o,u){var a=i(o,u);if(_&&y.push([o,u]),T)g=o,m=u,x=a,T=!1,a&&(N.lineStart(),N.point(o,u));else if(a&&M)N.point(o,u);else{var c=[b=Math.max(wy,Math.min(by,b)),w=Math.max(wy,Math.min(by,w))],s=[o=Math.max(wy,Math.min(by,o)),u=Math.max(wy,Math.min(by,u))];gy(c,s,t,n,e,r)?(M||(N.lineStart(),N.point(c[0],c[1])),N.point(s[0],s[1]),a||N.lineEnd(),k=!1):a&&(N.lineStart(),N.point(o,u),k=!1)}b=o,w=u,M=a}var v,_,y,g,m,x,b,w,M,T,k,N=u,S=yy(),E={point:c,lineStart:h,lineEnd:p,polygonStart:f,polygonEnd:l};return E}}function hi(){Sy.point=di,Sy.lineEnd=pi}function pi(){Sy.point=Sy.lineEnd=br}function di(t,n){t*=z_,n*=z_,iy=t,oy=I_(n),uy=q_(n),Sy.point=vi}function vi(t,n){t*=z_,n*=z_;var e=I_(n),r=q_(n),i=P_(t-iy),o=q_(i),u=I_(i),a=r*u,c=uy*e-oy*r*o,s=oy*e+uy*r*o;Ny.add(R_(B_(a*a+c*c),s)),iy=t,oy=e,uy=r}function _i(t,n){return!(!t||!Ly.hasOwnProperty(t.type))&&Ly[t.type](t,n)}function yi(t,n){return 0===zy(t,n)}function gi(t,n){var e=zy(t[0],t[1]);return zy(t[0],n)+zy(n,t[1])<=e+k_}function mi(t,n){return!!ky(t.map(xi),bi(n))}function xi(t){return t=t.map(bi),t.pop(),t}function bi(t){return[t[0]*z_,t[1]*z_]}function wi(t,n,e){var r=cf(t,n-k_,e).concat(n);return function(t){return r.map(function(n){return[t,n]})}}function Mi(t,n,e){var r=cf(t,n-k_,e).concat(n);return function(t){return r.map(function(n){return[n,t]})}}function Ti(){function t(){return{type:\"MultiLineString\",coordinates:n()}}function n(){return cf(U_(o/_)*_,i,_).map(h).concat(cf(U_(s/y)*y,c,y).map(p)).concat(cf(U_(r/d)*d,e,d).filter(function(t){return P_(t%_)>k_}).map(f)).concat(cf(U_(a/v)*v,u,v).filter(function(t){return P_(t%y)>k_}).map(l))}var e,r,i,o,u,a,c,s,f,l,h,p,d=10,v=d,_=90,y=360,g=2.5;return t.lines=function(){return n().map(function(t){return{type:\"LineString\",coordinates:t}})},t.outline=function(){return{type:\"Polygon\",coordinates:[h(o).concat(p(c).slice(1),h(i).reverse().slice(1),p(s).reverse().slice(1))]}},t.extent=function(n){return arguments.length?t.extentMajor(n).extentMinor(n):t.extentMinor()},t.extentMajor=function(n){return arguments.length?(o=+n[0][0],i=+n[1][0],s=+n[0][1],c=+n[1][1],o>i&&(n=o,o=i,i=n),s>c&&(n=s,s=c,c=n),t.precision(g)):[[o,s],[i,c]]},t.extentMinor=function(n){return arguments.length?(r=+n[0][0],e=+n[1][0],a=+n[0][1],u=+n[1][1],r>e&&(n=r,r=e,e=n),a>u&&(n=a,a=u,u=n),t.precision(g)):[[r,a],[e,u]]},t.step=function(n){return arguments.length?t.stepMajor(n).stepMinor(n):t.stepMinor()},t.stepMajor=function(n){return arguments.length?(_=+n[0],y=+n[1],t):[_,y]},t.stepMinor=function(n){return arguments.length?(d=+n[0],v=+n[1],t):[d,v]},t.precision=function(n){return arguments.length?(g=+n,f=wi(a,u,90),l=Mi(r,e,g),h=wi(s,c,90),p=Mi(o,i,g),t):g},t.extentMajor([[-180,-90+k_],[180,90-k_]]).extentMinor([[-180,-80-k_],[180,80+k_]])}function ki(){return Ti()()}function Ni(){Fy.point=Si}function Si(t,n){Fy.point=Ei,ay=sy=t,cy=fy=n}function Ei(t,n){Oy.add(fy*t-sy*n),sy=t,fy=n}function Ai(){Ei(ay,cy)}function Ci(t,n){t<Iy&&(Iy=t),t>By&&(By=t),n<Yy&&(Yy=n),n>Hy&&(Hy=n)}function zi(t,n){Xy+=t,$y+=n,++Vy}function Pi(){tg.point=Li}function Li(t,n){tg.point=Ri,zi(py=t,dy=n)}function Ri(t,n){var e=t-py,r=n-dy,i=B_(e*e+r*r);Wy+=i*(py+t)/2,Zy+=i*(dy+n)/2,Gy+=i,zi(py=t,dy=n)}function qi(){tg.point=zi}function Ui(){tg.point=Oi}function Di(){Fi(ly,hy)}function Oi(t,n){tg.point=Fi,zi(ly=py=t,hy=dy=n)}function Fi(t,n){var e=t-py,r=n-dy,i=B_(e*e+r*r);Wy+=i*(py+t)/2,Zy+=i*(dy+n)/2,Gy+=i,i=dy*t-py*n,Jy+=i*(py+t),Qy+=i*(dy+n),Ky+=3*i,zi(py=t,dy=n)}function Ii(t){this._context=t}function Yi(t,n){ag.point=Bi,eg=ig=t,rg=og=n}function Bi(t,n){ig-=t,og-=n,ug.add(B_(ig*ig+og*og)),ig=t,og=n}function Hi(){this._string=[]}function ji(t){return\"m0,\"+t+\"a\"+t+\",\"+t+\" 0 1,1 0,\"+-2*t+\"a\"+t+\",\"+t+\" 0 1,1 0,\"+2*t+\"z\"}function Xi(t){return t.length>1}function $i(t,n){return((t=t.x)[0]<0?t[1]-S_-k_:S_-t[1])-((n=n.x)[0]<0?n[1]-S_-k_:S_-n[1])}function Vi(t){var n,e=NaN,r=NaN,i=NaN;return{lineStart:function(){t.lineStart(),n=1},point:function(o,u){var a=o>0?N_:-N_,c=P_(o-e);P_(c-N_)<k_?(t.point(e,r=(r+u)/2>0?S_:-S_),t.point(i,r),t.lineEnd(),t.lineStart(),t.point(a,r),t.point(o,r),n=0):i!==a&&c>=N_&&(P_(e-i)<k_&&(e-=i*k_),P_(o-a)<k_&&(o-=a*k_),r=Wi(e,r,o,u),t.point(i,r),t.lineEnd(),t.lineStart(),t.point(a,r),n=0),t.point(e=o,r=u),i=a},lineEnd:function(){t.lineEnd(),e=r=NaN},clean:function(){return 2-n}}}function Wi(t,n,e,r){var i,o,u=I_(t-e);return P_(u)>k_?L_((I_(n)*(o=q_(r))*I_(e)-I_(r)*(i=q_(n))*I_(t))/(i*o*u)):(n+r)/2}function Zi(t,n,e,r){var i;if(null==t)i=e*S_,r.point(-N_,i),r.point(0,i),r.point(N_,i),r.point(N_,0),r.point(N_,-i),r.point(0,-i),r.point(-N_,-i),r.point(-N_,0),r.point(-N_,i);else if(P_(t[0]-n[0])>k_){var o=t[0]<n[0]?N_:-N_;i=e*o/2,r.point(-o,i),r.point(0,i),r.point(o,i)}else r.point(n[0],n[1])}function Gi(t){return function(n){var e=new Ji;for(var r in t)e[r]=t[r];return e.stream=n,e}}function Ji(){}function Qi(t,n,e){var r=n[1][0]-n[0][0],i=n[1][1]-n[0][1],o=t.clipExtent&&t.clipExtent();t.scale(150).translate([0,0]),null!=o&&t.clipExtent(null),$_(e,t.stream(jy));var u=jy.result(),a=Math.min(r/(u[1][0]-u[0][0]),i/(u[1][1]-u[0][1])),c=+n[0][0]+(r-a*(u[1][0]+u[0][0]))/2,s=+n[0][1]+(i-a*(u[1][1]+u[0][1]))/2;return null!=o&&t.clipExtent(o),t.scale(150*a).translate([c,s])}function Ki(t,n,e){return Qi(t,[[0,0],n],e)}function to(t){return Gi({point:function(n,e){n=t(n,e),this.stream.point(n[0],n[1])}})}function no(t,n){function e(r,i,o,u,a,c,s,f,l,h,p,d,v,_){var y=s-r,g=f-i,m=y*y+g*g;if(m>4*n&&v--){var x=u+h,b=a+p,w=c+d,M=B_(x*x+b*b+w*w),T=mr(w/=M),k=P_(P_(w)-1)<k_||P_(o-l)<k_?(o+l)/2:R_(b,x),N=t(k,T),S=N[0],E=N[1],A=S-r,C=E-i,z=g*A-y*C;(z*z/m>n||P_((y*A+g*C)/m-.5)>.3||u*h+a*p+c*d<dg)&&(e(r,i,o,u,a,c,S,E,k,x/=M,b/=M,w,v,_),_.point(S,E),e(S,E,k,x,b,w,s,f,l,h,p,d,v,_))}}return function(n){function r(e,r){e=t(e,r),n.point(e[0],e[1])}function i(){y=NaN,w.point=o,n.lineStart()}function o(r,i){var o=Cr([r,i]),u=t(r,i);e(y,g,_,m,x,b,y=u[0],g=u[1],_=r,m=o[0],x=o[1],b=o[2],pg,n),n.point(y,g)}function u(){w.point=r,n.lineEnd()}function a(){i(),w.point=c,w.lineEnd=s}function c(t,n){o(f=t,n),l=y,h=g,p=m,d=x,v=b,w.point=o}function s(){e(y,g,_,m,x,b,l,h,f,p,d,v,pg,n),w.lineEnd=u,u()}var f,l,h,p,d,v,_,y,g,m,x,b,w={point:r,lineStart:i,lineEnd:u,polygonStart:function(){n.polygonStart(),w.lineStart=a},polygonEnd:function(){n.polygonEnd(),w.lineStart=i}};return w}}function eo(t){return ro(function(){return t})()}function ro(t){function n(t){return t=f(t[0]*z_,t[1]*z_),[t[0]*_+a,c-t[1]*_]}function e(t){return(t=f.invert((t[0]-a)/_,(c-t[1])/_))&&[t[0]*C_,t[1]*C_]}function r(t,n){return t=u(t,n),[t[0]*_+a,c-t[1]*_]}function i(){f=ry(s=ri(b,w,M),u);var t=u(m,x);return a=y-t[0]*_,c=g+t[1]*_,o()}function o(){return d=v=null,n}var u,a,c,s,f,l,h,p,d,v,_=150,y=480,g=250,m=0,x=0,b=0,w=0,M=0,T=null,k=fg,N=null,S=Uy,E=.5,A=vg(r,E);return n.stream=function(t){return d&&v===t?d:d=_g(k(s,A(S(v=t))))},n.clipAngle=function(t){return arguments.length?(k=+t?lg(T=t*z_,6*z_):(T=null,fg),o()):T*C_},n.clipExtent=function(t){return arguments.length?(S=null==t?(N=l=h=p=null,Uy):li(N=+t[0][0],l=+t[0][1],h=+t[1][0],p=+t[1][1]),o()):null==N?null:[[N,l],[h,p]]},n.scale=function(t){return arguments.length?(_=+t,i()):_},n.translate=function(t){return arguments.length?(y=+t[0],g=+t[1],i()):[y,g]},n.center=function(t){return arguments.length?(m=t[0]%360*z_,x=t[1]%360*z_,i()):[m*C_,x*C_]},n.rotate=function(t){return arguments.length?(b=t[0]%360*z_,w=t[1]%360*z_,M=t.length>2?t[2]%360*z_:0,i()):[b*C_,w*C_,M*C_]},n.precision=function(t){return arguments.length?(A=vg(r,E=t*t),o()):B_(E)},n.fitExtent=function(t,e){return Qi(n,t,e)},n.fitSize=function(t,e){return Ki(n,t,e)},function(){return u=t.apply(this,arguments),n.invert=u.invert&&e,i()}}function io(t){var n=0,e=N_/3,r=ro(t),i=r(n,e);return i.parallels=function(t){return arguments.length?r(n=t[0]*z_,e=t[1]*z_):[n*C_,e*C_]},i}function oo(t){function n(t,n){return[t*e,I_(n)/e]}var e=q_(t);return n.invert=function(t,n){return[t/e,mr(n*e)]},n}function uo(t,n){function e(t,n){var e=B_(o-2*i*I_(n))/i;return[e*I_(t*=i),u-e*q_(t)]}var r=I_(t),i=(r+I_(n))/2;if(P_(i)<k_)return oo(t);var o=1+r*(2*i-r),u=B_(o)/i;return e.invert=function(t,n){var e=u-n;return[R_(t,P_(e))/i*Y_(e),mr((o-(t*t+e*e)*i*i)/(2*i))]},e}function ao(t){var n=t.length;return{point:function(e,r){for(var i=-1;++i<n;)t[i].point(e,r)},sphere:function(){for(var e=-1;++e<n;)t[e].sphere()},lineStart:function(){for(var e=-1;++e<n;)t[e].lineStart()},lineEnd:function(){for(var e=-1;++e<n;)t[e].lineEnd()},polygonStart:function(){for(var e=-1;++e<n;)t[e].polygonStart()},polygonEnd:function(){for(var e=-1;++e<n;)t[e].polygonEnd()}}}function co(t){return function(n,e){var r=q_(n),i=q_(e),o=t(r*i);return[o*i*I_(n),o*I_(e)]}}function so(t){return function(n,e){var r=B_(n*n+e*e),i=t(r),o=I_(i),u=q_(i);return[R_(n*o,r*u),mr(r&&e*o/r)]}}function fo(t,n){return[t,O_(H_((S_+n)/2))]}function lo(t){function n(){var n=N_*a(),u=o(vy(o.rotate()).invert([0,0]));return s(null==f?[[u[0]-n,u[1]-n],[u[0]+n,u[1]+n]]:t===fo?[[Math.max(u[0]-n,f),e],[Math.min(u[0]+n,r),i]]:[[f,Math.max(u[1]-n,e)],[r,Math.min(u[1]+n,i)]])}var e,r,i,o=eo(t),u=o.center,a=o.scale,c=o.translate,s=o.clipExtent,f=null;return o.scale=function(t){return arguments.length?(a(t),n()):a()},o.translate=function(t){return arguments.length?(c(t),n()):c()},o.center=function(t){return arguments.length?(u(t),n()):u()},o.clipExtent=function(t){return arguments.length?(null==t?f=e=r=i=null:(f=+t[0][0],e=+t[0][1],r=+t[1][0],i=+t[1][1]),n()):null==f?null:[[f,e],[r,i]]},n()}function ho(t){return H_((S_+t)/2)}function po(t,n){function e(t,n){o>0?n<-S_+k_&&(n=-S_+k_):n>S_-k_&&(n=S_-k_);var e=o/F_(ho(n),i);return[e*I_(i*t),o-e*q_(i*t)]}var r=q_(t),i=t===n?I_(t):O_(r/q_(n))/O_(ho(n)/ho(t)),o=r*F_(ho(t),i)/i;return i?(e.invert=function(t,n){var e=o-n,r=Y_(i)*B_(t*t+e*e);return[R_(t,P_(e))/i*Y_(e),2*L_(F_(o/r,1/i))-S_]},e):fo}function vo(t,n){return[t,n]}function _o(t,n){function e(t,n){var e=o-n,r=i*t;return[e*I_(r),o-e*q_(r)]}var r=q_(t),i=t===n?I_(t):(r-q_(n))/(n-t),o=r/i+t;return P_(i)<k_?vo:(e.invert=function(t,n){var e=o-n;return[R_(t,P_(e))/i*Y_(e),o-Y_(i)*B_(t*t+e*e)]},e)}function yo(t,n){var e=q_(n),r=q_(t)*e;return[e*I_(t)/r,I_(n)/r]}function go(t,n,e,r){return 1===t&&1===n&&0===e&&0===r?Uy:Gi({point:function(i,o){this.stream.point(i*t+e,o*n+r)}})}function mo(t,n){return[q_(n)*I_(t),I_(n)]}function xo(t,n){var e=q_(n),r=1+q_(t)*e;return[e*I_(t)/r,I_(n)/r]}function bo(t,n){return[O_(H_((S_+n)/2)),-t]}function wo(t,n){return t.parent===n.parent?1:2}function Mo(t){return t.reduce(To,0)/t.length}function To(t,n){return t+n.x}function ko(t){return 1+t.reduce(No,0)}function No(t,n){return Math.max(t,n.y)}function So(t){for(var n;n=t.children;)t=n[0];return t}function Eo(t){for(var n;n=t.children;)t=n[n.length-1];return t}function Ao(t){var n=0,e=t.children,r=e&&e.length;if(r)for(;--r>=0;)n+=e[r].value;else n=1;t.value=n}function Co(t,n){if(t===n)return t;var e=t.ancestors(),r=n.ancestors(),i=null;for(t=e.pop(),n=r.pop();t===n;)i=t,t=e.pop(),n=r.pop();return i}function zo(t,n){var e,r,i,o,u,a=new Uo(t),c=+t.value&&(a.value=t.value),s=[a];for(null==n&&(n=Lo);e=s.pop();)if(c&&(e.value=+e.data.value),(i=n(e.data))&&(u=i.length))for(e.children=new Array(u),o=u-1;o>=0;--o)s.push(r=e.children[o]=new Uo(i[o])),r.parent=e,r.depth=e.depth+1;return a.eachBefore(qo)}function Po(){return zo(this).eachBefore(Ro)}function Lo(t){return t.children}function Ro(t){t.data=t.data.data}function qo(t){var n=0;do{t.height=n}while((t=t.parent)&&t.height<++n)}function Uo(t){this.data=t,this.depth=this.height=0,this.parent=null}function Do(t){this._=t,this.next=null}function Oo(t,n){var e=n.x-t.x,r=n.y-t.y,i=t.r-n.r;return i*i+1e-6>e*e+r*r}function Fo(t,n){var e,r,i,o=null,u=t.head;switch(n.length){case 1:e=Io(n[0]);break;case 2:e=Yo(n[0],n[1]);break;case 3:e=Bo(n[0],n[1],n[2])}for(;u;)i=u._,r=u.next,e&&Oo(e,i)?o=u:(o?(t.tail=o,o.next=null):t.head=t.tail=null,n.push(i),e=Fo(t,n),n.pop(),t.head?(u.next=t.head,t.head=u):(u.next=null,t.head=t.tail=u),o=t.tail,o.next=r),u=r;return t.tail=o,e}function Io(t){return{x:t.x,y:t.y,r:t.r}}function Yo(t,n){var e=t.x,r=t.y,i=t.r,o=n.x,u=n.y,a=n.r,c=o-e,s=u-r,f=a-i,l=Math.sqrt(c*c+s*s);return{x:(e+o+c/l*f)/2,y:(r+u+s/l*f)/2,r:(l+i+a)/2}}function Bo(t,n,e){var r=t.x,i=t.y,o=t.r,u=n.x,a=n.y,c=n.r,s=e.x,f=e.y,l=e.r,h=2*(r-u),p=2*(i-a),d=2*(c-o),v=r*r+i*i-o*o-u*u-a*a+c*c,_=2*(r-s),y=2*(i-f),g=2*(l-o),m=r*r+i*i-o*o-s*s-f*f+l*l,x=_*p-h*y,b=(p*m-y*v)/x-r,w=(y*d-p*g)/x,M=(_*v-h*m)/x-i,T=(h*g-_*d)/x,k=w*w+T*T-1,N=2*(b*w+M*T+o),S=b*b+M*M-o*o,E=(-N-Math.sqrt(N*N-4*k*S))/(2*k);return{x:b+w*E+r,y:M+T*E+i,r:E}}function Ho(t,n,e){var r=t.x,i=t.y,o=n.r+e.r,u=t.r+e.r,a=n.x-r,c=n.y-i,s=a*a+c*c;if(s){var f=.5+((u*=u)-(o*=o))/(2*s),l=Math.sqrt(Math.max(0,2*o*(u+s)-(u-=s)*u-o*o))/(2*s);e.x=r+f*a+l*c,e.y=i+f*c-l*a}else e.x=r+u,e.y=i}function jo(t,n){var e=n.x-t.x,r=n.y-t.y,i=t.r+n.r;return i*i-1e-6>e*e+r*r}function Xo(t,n,e){var r=t._,i=t.next._,o=r.r+i.r,u=(r.x*i.r+i.x*r.r)/o-n,a=(r.y*i.r+i.y*r.r)/o-e;return u*u+a*a}function $o(t){this._=t,this.next=null,this.previous=null}function Vo(t){if(!(i=t.length))return 0;var n,e,r,i;if(n=t[0],n.x=0,n.y=0,!(i>1))return n.r;if(e=t[1],n.x=-e.r,e.x=n.r,e.y=0,!(i>2))return n.r+e.r;Ho(e,n,r=t[2]);var o,u,a,c,s,f,l,h=n.r*n.r,p=e.r*e.r,d=r.r*r.r,v=h+p+d,_=h*n.x+p*e.x+d*r.x,y=h*n.y+p*e.y+d*r.y;n=new $o(n),e=new $o(e),r=new $o(r),n.next=r.previous=e,e.next=n.previous=r,r.next=e.previous=n;t:for(a=3;a<i;++a){Ho(n._,e._,r=t[a]),r=new $o(r),c=e.next,s=n.previous,f=e._.r,l=n._.r;do{if(f<=l){if(jo(c._,r._)){e=c,n.next=e,e.previous=n,--a;continue t}f+=c._.r,c=c.next}else{if(jo(s._,r._)){n=s,n.next=e,e.previous=n,--a;continue t}l+=s._.r,s=s.previous}}while(c!==s.next);for(r.previous=n,r.next=e,n.next=e.previous=e=r,v+=d=r._.r*r._.r,_+=d*r._.x,y+=d*r._.y,h=Xo(n,o=_/v,u=y/v);(r=r.next)!==e;)(d=Xo(r,o,u))<h&&(n=r,h=d);e=n.next}for(n=[e._],r=e;(r=r.next)!==e;)n.push(r._);for(r=$g(n),a=0;a<i;++a)n=t[a],n.x-=r.x,n.y-=r.y;return r.r}function Wo(t){return null==t?null:Zo(t)}function Zo(t){if(\"function\"!=typeof t)throw new Error;return t}function Go(){return 0}function Jo(t){return Math.sqrt(t.value)}function Qo(t){return function(n){n.children||(n.r=Math.max(0,+t(n)||0))}}function Ko(t,n){return function(e){if(r=e.children){var r,i,o,u=r.length,a=t(e)*n||0;if(a)for(i=0;i<u;++i)r[i].r+=a;if(o=Vo(r),a)for(i=0;i<u;++i)r[i].r-=a;e.r=o+a}}}function tu(t){return function(n){var e=n.parent;n.r*=t,e&&(n.x=e.x+t*n.x,n.y=e.y+t*n.y)}}function nu(t){return t.id}function eu(t){return t.parentId}function ru(t,n){return t.parent===n.parent?1:2}function iu(t){var n=t.children;return n?n[0]:t.t}function ou(t){var n=t.children;return n?n[n.length-1]:t.t}function uu(t,n,e){var r=e/(n.i-t.i);n.c-=r,n.s+=e,t.c+=r,n.z+=e,n.m+=e}function au(t){for(var n,e=0,r=0,i=t.children,o=i.length;--o>=0;)n=i[o],n.z+=e,n.m+=e,e+=n.s+(r+=n.c)}function cu(t,n,e){return t.a.parent===n.parent?t.a:e}function su(t,n){this._=t,this.parent=null,this.children=null,this.A=null,this.a=this,this.z=0,this.m=0,this.c=0,this.s=0,this.t=null,this.i=n}function fu(t){for(var n,e,r,i,o,u=new su(t,0),a=[u];n=a.pop();)if(r=n._.children)for(n.children=new Array(o=r.length),i=o-1;i>=0;--i)a.push(e=n.children[i]=new su(r[i],i)),e.parent=n;return(u.parent=new su(null,0)).children=[u],u}function lu(t,n,e,r,i,o){for(var u,a,c,s,f,l,h,p,d,v,_,y=[],g=n.children,m=0,x=0,b=g.length,w=n.value;m<b;){c=i-e,s=o-r;do{f=g[x++].value}while(!f&&x<b);for(l=h=f,v=Math.max(s/c,c/s)/(w*t),_=f*f*v,d=Math.max(h/_,_/l);x<b;++x){if(f+=a=g[x].value,a<l&&(l=a),a>h&&(h=a),_=f*f*v,(p=Math.max(h/_,_/l))>d){f-=a;break}d=p}y.push(u={value:f,dice:c<s,children:g.slice(m,x)}),u.dice?Jg(u,e,r,i,w?r+=s*f/w:o):im(u,e,r,w?e+=c*f/w:i,o),w-=f,m=x}return y}function hu(t,n){return t[0]-n[0]||t[1]-n[1]}function pu(t){for(var n=t.length,e=[0,1],r=2,i=2;i<n;++i){for(;r>1&&pm(t[e[r-2]],t[e[r-1]],t[i])<=0;)--r;e[r++]=i}return e.slice(0,r)}function du(t){this._size=t,this._call=this._error=null,this._tasks=[],this._data=[],this._waiting=this._active=this._ended=this._start=0}function vu(t){if(!t._start)try{_u(t)}catch(n){if(t._tasks[t._ended+t._active-1])gu(t,n);else if(!t._data)throw n}}function _u(t){for(;t._start=t._waiting&&t._active<t._size;){var n=t._ended+t._active,e=t._tasks[n],r=e.length-1,i=e[r];e[r]=yu(t,n),--t._waiting,++t._active,e=i.apply(null,e),t._tasks[n]&&(t._tasks[n]=e||gm)}}function yu(t,n){return function(e,r){t._tasks[n]&&(--t._active,++t._ended,t._tasks[n]=null,null==t._error&&(null!=e?gu(t,e):(t._data[n]=r,t._waiting?vu(t):mu(t))))}}function gu(t,n){var e,r=t._tasks.length;for(t._error=n,t._data=void 0,t._waiting=NaN;--r>=0;)if((e=t._tasks[r])&&(t._tasks[r]=null,e.abort))try{e.abort()}catch(n){}t._active=NaN,mu(t)}function mu(t){if(!t._active&&t._call){var n=t._data;t._data=void 0,t._call(t._error,n)}}function xu(t){if(null==t)t=1/0;else if(!((t=+t)>=1))throw new Error(\"invalid concurrency\");return new du(t)}function bu(t){return function(n,e){t(null==n?e:null)}}function wu(t){var n=t.responseType;return n&&\"text\"!==n?t.response:t.responseText}function Mu(t,n){return function(e){return t(e.responseText,n)}}function Tu(t){function n(n){var o=n+\"\",u=e.get(o);if(!u){if(i!==Om)return i;e.set(o,u=r.push(n))}return t[(u-1)%t.length]}var e=He(),r=[],i=Om;return t=null==t?[]:Dm.call(t),n.domain=function(t){if(!arguments.length)return r.slice();r=[],e=He();for(var i,o,u=-1,a=t.length;++u<a;)e.has(o=(i=t[u])+\"\")||e.set(o,r.push(i));return n},n.range=function(e){return arguments.length?(t=Dm.call(e),n):t.slice()},n.unknown=function(t){return arguments.length?(i=t,n):i},n.copy=function(){return Tu().domain(r).range(t).unknown(i)},n}function ku(){function t(){var t=i().length,r=u[1]<u[0],l=u[r-0],h=u[1-r];n=(h-l)/Math.max(1,t-c+2*s),a&&(n=Math.floor(n)),l+=(h-l-n*(t-c))*f,e=n*(1-c),a&&(l=Math.round(l),e=Math.round(e));var p=cf(t).map(function(t){return l+n*t});return o(r?p.reverse():p)}var n,e,r=Tu().unknown(void 0),i=r.domain,o=r.range,u=[0,1],a=!1,c=0,s=0,f=.5;return delete r.unknown,r.domain=function(n){return arguments.length?(i(n),t()):i()},r.range=function(n){return arguments.length?(u=[+n[0],+n[1]],t()):u.slice()},r.rangeRound=function(n){return u=[+n[0],+n[1]],a=!0,t()},r.bandwidth=function(){return e},r.step=function(){return n},r.round=function(n){return arguments.length?(a=!!n,t()):a},r.padding=function(n){return arguments.length?(c=s=Math.max(0,Math.min(1,n)),t()):c},r.paddingInner=function(n){return arguments.length?(c=Math.max(0,Math.min(1,n)),t()):c},r.paddingOuter=function(n){return arguments.length?(s=Math.max(0,Math.min(1,n)),t()):s},r.align=function(n){return arguments.length?(f=Math.max(0,Math.min(1,n)),t()):f},r.copy=function(){return ku().domain(i()).range(u).round(a).paddingInner(c).paddingOuter(s).align(f)},t()}function Nu(t){var n=t.copy;return t.padding=t.paddingOuter,delete t.paddingInner,delete t.paddingOuter,t.copy=function(){return Nu(n())},t}function Su(){return Nu(ku().paddingInner(1))}function Eu(t,n){return(n-=t=+t)?function(e){return(e-t)/n}:Fm(n)}function Au(t){return function(n,e){var r=t(n=+n,e=+e);return function(t){return t<=n?0:t>=e?1:r(t)}}}function Cu(t){return function(n,e){var r=t(n=+n,e=+e);return function(t){return t<=0?n:t>=1?e:r(t)}}}function zu(t,n,e,r){var i=t[0],o=t[1],u=n[0],a=n[1];return o<i?(i=e(o,i),u=r(a,u)):(i=e(i,o),u=r(u,a)),function(t){return u(i(t))}}function Pu(t,n,e,r){var i=Math.min(t.length,n.length)-1,o=new Array(i),u=new Array(i),a=-1;for(t[i]<t[0]&&(t=t.slice().reverse(),n=n.slice().reverse());++a<i;)o[a]=e(t[a],t[a+1]),u[a]=r(n[a],n[a+1]);return function(n){var e=Vs(t,n,1,i)-1;return u[e](o[e](n))}}function Lu(t,n){return n.domain(t.domain()).range(t.range()).interpolate(t.interpolate()).clamp(t.clamp())}function Ru(t,n){function e(){return i=Math.min(a.length,c.length)>2?Pu:zu,o=u=null,r}function r(n){return(o||(o=i(a,c,f?Au(t):t,s)))(+n)}var i,o,u,a=Ym,c=Ym,s=qh,f=!1;return r.invert=function(t){return(u||(u=i(c,a,Eu,f?Cu(n):n)))(+t)},r.domain=function(t){return arguments.length?(a=Um.call(t,Im),e()):a.slice()},r.range=function(t){return arguments.length?(c=Dm.call(t),e()):c.slice()},r.rangeRound=function(t){return c=Dm.call(t),s=Uh,e()},r.clamp=function(t){return arguments.length?(f=!!t,e()):f},r.interpolate=function(t){return arguments.length?(s=t,e()):s},e()}function qu(t){var n=t.domain;return t.ticks=function(t){var e=n();return hf(e[0],e[e.length-1],null==t?10:t)},t.tickFormat=function(t,e){return Bm(n(),t,e)},t.nice=function(e){null==e&&(e=10);var i,o=n(),u=0,a=o.length-1,c=o[u],s=o[a];return s<c&&(i=c,c=s,s=i,i=u,u=a,a=i),i=r(c,s,e),i>0?(c=Math.floor(c/i)*i,s=Math.ceil(s/i)*i,i=r(c,s,e)):i<0&&(c=Math.ceil(c*i)/i,s=Math.floor(s*i)/i,i=r(c,s,e)),i>0?(o[u]=Math.floor(c/i)*i,o[a]=Math.ceil(s/i)*i,n(o)):i<0&&(o[u]=Math.ceil(c*i)/i,o[a]=Math.floor(s*i)/i,n(o)),t},t}function Uu(){var t=Ru(Eu,Ch);return t.copy=function(){return Lu(t,Uu())},qu(t)}function Du(){function t(t){return+t}var n=[0,1];return t.invert=t,t.domain=t.range=function(e){return arguments.length?(n=Um.call(e,Im),t):n.slice()},t.copy=function(){return Du().domain(n)},qu(t)}function Ou(t,n){return(n=Math.log(n/t))?function(e){return Math.log(e/t)/n}:Fm(n)}function Fu(t,n){return t<0?function(e){return-Math.pow(-n,e)*Math.pow(-t,1-e)}:function(e){return Math.pow(n,e)*Math.pow(t,1-e)}}function Iu(t){return isFinite(t)?+(\"1e\"+t):t<0?0:t}function Yu(t){return 10===t?Iu:t===Math.E?Math.exp:function(n){return Math.pow(t,n)}}function Bu(t){return t===Math.E?Math.log:10===t&&Math.log10||2===t&&Math.log2||(t=Math.log(t),function(n){return Math.log(n)/t})}function Hu(t){return function(n){return-t(-n)}}function ju(){function n(){return o=Bu(i),u=Yu(i),r()[0]<0&&(o=Hu(o),u=Hu(u)),e}var e=Ru(Ou,Fu).domain([1,10]),r=e.domain,i=10,o=Bu(10),u=Yu(10);return e.base=function(t){return arguments.length?(i=+t,n()):i},e.domain=function(t){return arguments.length?(r(t),n()):r()},e.ticks=function(t){var n,e=r(),a=e[0],c=e[e.length-1];(n=c<a)&&(h=a,a=c,c=h);var s,f,l,h=o(a),p=o(c),d=null==t?10:+t,v=[];if(!(i%1)&&p-h<d){if(h=Math.round(h)-1,p=Math.round(p)+1,a>0){for(;h<p;++h)for(f=1,s=u(h);f<i;++f)if(!((l=s*f)<a)){if(l>c)break;v.push(l)}}else for(;h<p;++h)for(f=i-1,s=u(h);f>=1;--f)if(!((l=s*f)<a)){if(l>c)break;v.push(l)}}else v=hf(h,p,Math.min(p-h,d)).map(u);return n?v.reverse():v},e.tickFormat=function(n,r){if(null==r&&(r=10===i?\".0e\":\",\"),\"function\"!=typeof r&&(r=t.format(r)),n===1/0)return r;null==n&&(n=10);var a=Math.max(1,i*n/e.ticks().length);return function(t){var n=t/u(Math.round(o(t)));return n*i<i-.5&&(n*=i),n<=a?r(t):\"\"}},e.nice=function(){return r(Hm(r(),{floor:function(t){return u(Math.floor(o(t)))},ceil:function(t){return u(Math.ceil(o(t)))}}))},e.copy=function(){return Lu(e,ju().base(i))},e}function Xu(t,n){return t<0?-Math.pow(-t,n):Math.pow(t,n)}function $u(){function t(t,n){return(n=Xu(n,e)-(t=Xu(t,e)))?function(r){return(Xu(r,e)-t)/n}:Fm(n)}function n(t,n){return n=Xu(n,e)-(t=Xu(t,e)),function(r){return Xu(t+n*r,1/e)}}var e=1,r=Ru(t,n),i=r.domain;return r.exponent=function(t){return arguments.length?(e=+t,i(i())):e},r.copy=function(){return Lu(r,$u().exponent(e))},qu(r)}function Vu(){return $u().exponent(.5)}function Wu(){function t(){var t=0,o=Math.max(1,r.length);for(i=new Array(o-1);++t<o;)i[t-1]=vf(e,t/o);return n}function n(t){if(!isNaN(t=+t))return r[Vs(i,t)]}var e=[],r=[],i=[];return n.invertExtent=function(t){var n=r.indexOf(t);return n<0?[NaN,NaN]:[n>0?i[n-1]:e[0],n<i.length?i[n]:e[e.length-1]]},n.domain=function(n){if(!arguments.length)return e.slice();e=[];for(var r,i=0,o=n.length;i<o;++i)null==(r=n[i])||isNaN(r=+r)||e.push(r);return e.sort(js),t()},n.range=function(n){return arguments.length?(r=Dm.call(n),t()):r.slice()},n.quantiles=function(){return i.slice()},n.copy=function(){return Wu().domain(e).range(r)},n}function Zu(){function t(t){if(t<=t)return u[Vs(o,t,0,i)]}function n(){var n=-1;for(o=new Array(i);++n<i;)o[n]=((n+1)*r-(n-i)*e)/(i+1);return t}var e=0,r=1,i=1,o=[.5],u=[0,1];return t.domain=function(t){return arguments.length?(e=+t[0],r=+t[1],n()):[e,r]},t.range=function(t){return arguments.length?(i=(u=Dm.call(t)).length-1,n()):u.slice()},t.invertExtent=function(t){var n=u.indexOf(t);return n<0?[NaN,NaN]:n<1?[e,o[0]]:n>=i?[o[i-1],r]:[o[n-1],o[n]]},t.copy=function(){return Zu().domain([e,r]).range(u)},qu(t)}function Gu(){function t(t){if(t<=t)return e[Vs(n,t,0,r)]}var n=[.5],e=[0,1],r=1;return t.domain=function(i){return arguments.length?(n=Dm.call(i),r=Math.min(n.length,e.length-1),t):n.slice()},t.range=function(i){return arguments.length?(e=Dm.call(i),r=Math.min(n.length,e.length-1),t):e.slice()},t.invertExtent=function(t){var r=e.indexOf(t);return[n[r-1],n[r]]},t.copy=function(){return Gu().domain(n).range(e)},t}function Ju(t,n,e,r){function i(n){return t(n=new Date(+n)),n}return i.floor=i,i.ceil=function(e){return t(e=new Date(e-1)),n(e,1),t(e),e},i.round=function(t){var n=i(t),e=i.ceil(t);return t-n<e-t?n:e},i.offset=function(t,e){return n(t=new Date(+t),null==e?1:Math.floor(e)),t},i.range=function(e,r,o){var u=[];if(e=i.ceil(e),o=null==o?1:Math.floor(o),!(e<r&&o>0))return u;do{u.push(new Date(+e))}while(n(e,o),t(e),e<r);return u},i.filter=function(e){return Ju(function(n){if(n>=n)for(;t(n),!e(n);)n.setTime(n-1)},function(t,r){if(t>=t)for(;--r>=0;)for(;n(t,1),!e(t););})},e&&(i.count=function(n,r){return jm.setTime(+n),Xm.setTime(+r),t(jm),t(Xm),Math.floor(e(jm,Xm))},i.every=function(t){return t=Math.floor(t),isFinite(t)&&t>0?t>1?i.filter(r?function(n){return r(n)%t==0}:function(n){return i.count(0,n)%t==0}):i:null}),i}function Qu(t){return Ju(function(n){n.setDate(n.getDate()-(n.getDay()+7-t)%7),n.setHours(0,0,0,0)},function(t,n){t.setDate(t.getDate()+7*n)},function(t,n){return(n-t-(n.getTimezoneOffset()-t.getTimezoneOffset())*Wm)/Zm})}function Ku(t){return Ju(function(n){n.setUTCDate(n.getUTCDate()-(n.getUTCDay()+7-t)%7),n.setUTCHours(0,0,0,0)},function(t,n){t.setUTCDate(t.getUTCDate()+7*n)},function(t,n){return(n-t)/Zm})}function ta(t){if(0<=t.y&&t.y<100){var n=new Date(-1,t.m,t.d,t.H,t.M,t.S,t.L);return n.setFullYear(t.y),n}return new Date(t.y,t.m,t.d,t.H,t.M,t.S,t.L)}function na(t){if(0<=t.y&&t.y<100){var n=new Date(Date.UTC(-1,t.m,t.d,t.H,t.M,t.S,t.L));return n.setUTCFullYear(t.y),n}return new Date(Date.UTC(t.y,t.m,t.d,t.H,t.M,t.S,t.L))}function ea(t){return{y:t,m:0,d:1,H:0,M:0,S:0,L:0}}function ra(t){function n(t,n){return function(e){var r,i,o,u=[],a=-1,c=0,s=t.length;for(e instanceof Date||(e=new Date(+e));++a<s;)37===t.charCodeAt(a)&&(u.push(t.slice(c,a)),null!=(i=Vx[r=t.charAt(++a)])?r=t.charAt(++a):i=\"e\"===r?\" \":\"0\",(o=n[r])&&(r=o(e,i)),\nu.push(r),c=a+1);return u.push(t.slice(c,a)),u.join(\"\")}}function e(t,n){return function(e){var i=ea(1900);if(r(i,t,e+=\"\",0)!=e.length)return null;if(\"p\"in i&&(i.H=i.H%12+12*i.p),\"W\"in i||\"U\"in i){\"w\"in i||(i.w=\"W\"in i?1:0);var o=\"Z\"in i?na(ea(i.y)).getUTCDay():n(ea(i.y)).getDay();i.m=0,i.d=\"W\"in i?(i.w+6)%7+7*i.W-(o+5)%7:i.w+7*i.U-(o+6)%7}return\"Z\"in i?(i.H+=i.Z/100|0,i.M+=i.Z%100,na(i)):n(i)}}function r(t,n,e,r){for(var i,o,u=0,a=n.length,c=e.length;u<a;){if(r>=c)return-1;if(37===(i=n.charCodeAt(u++))){if(i=n.charAt(u++),!(o=B[i in Vx?n.charAt(u++):i])||(r=o(t,e,r))<0)return-1}else if(i!=e.charCodeAt(r++))return-1}return r}function i(t,n,e){var r=C.exec(n.slice(e));return r?(t.p=z[r[0].toLowerCase()],e+r[0].length):-1}function o(t,n,e){var r=R.exec(n.slice(e));return r?(t.w=q[r[0].toLowerCase()],e+r[0].length):-1}function u(t,n,e){var r=P.exec(n.slice(e));return r?(t.w=L[r[0].toLowerCase()],e+r[0].length):-1}function a(t,n,e){var r=O.exec(n.slice(e));return r?(t.m=F[r[0].toLowerCase()],e+r[0].length):-1}function c(t,n,e){var r=U.exec(n.slice(e));return r?(t.m=D[r[0].toLowerCase()],e+r[0].length):-1}function s(t,n,e){return r(t,w,n,e)}function f(t,n,e){return r(t,M,n,e)}function l(t,n,e){return r(t,T,n,e)}function h(t){return S[t.getDay()]}function p(t){return N[t.getDay()]}function d(t){return A[t.getMonth()]}function v(t){return E[t.getMonth()]}function _(t){return k[+(t.getHours()>=12)]}function y(t){return S[t.getUTCDay()]}function g(t){return N[t.getUTCDay()]}function m(t){return A[t.getUTCMonth()]}function x(t){return E[t.getUTCMonth()]}function b(t){return k[+(t.getUTCHours()>=12)]}var w=t.dateTime,M=t.date,T=t.time,k=t.periods,N=t.days,S=t.shortDays,E=t.months,A=t.shortMonths,C=ua(k),z=aa(k),P=ua(N),L=aa(N),R=ua(S),q=aa(S),U=ua(E),D=aa(E),O=ua(A),F=aa(A),I={a:h,A:p,b:d,B:v,c:null,d:wa,e:wa,H:Ma,I:Ta,j:ka,L:Na,m:Sa,M:Ea,p:_,S:Aa,U:Ca,w:za,W:Pa,x:null,X:null,y:La,Y:Ra,Z:qa,\"%\":Ga},Y={a:y,A:g,b:m,B:x,c:null,d:Ua,e:Ua,H:Da,I:Oa,j:Fa,L:Ia,m:Ya,M:Ba,p:b,S:Ha,U:ja,w:Xa,W:$a,x:null,X:null,y:Va,Y:Wa,Z:Za,\"%\":Ga},B={a:o,A:u,b:a,B:c,c:s,d:va,e:va,H:ya,I:ya,j:_a,L:xa,m:da,M:ga,p:i,S:ma,U:sa,w:ca,W:fa,x:f,X:l,y:ha,Y:la,Z:pa,\"%\":ba};return I.x=n(M,I),I.X=n(T,I),I.c=n(w,I),Y.x=n(M,Y),Y.X=n(T,Y),Y.c=n(w,Y),{format:function(t){var e=n(t+=\"\",I);return e.toString=function(){return t},e},parse:function(t){var n=e(t+=\"\",ta);return n.toString=function(){return t},n},utcFormat:function(t){var e=n(t+=\"\",Y);return e.toString=function(){return t},e},utcParse:function(t){var n=e(t,na);return n.toString=function(){return t},n}}}function ia(t,n,e){var r=t<0?\"-\":\"\",i=(r?-t:t)+\"\",o=i.length;return r+(o<e?new Array(e-o+1).join(n)+i:i)}function oa(t){return t.replace(Gx,\"\\\\$&\")}function ua(t){return new RegExp(\"^(?:\"+t.map(oa).join(\"|\")+\")\",\"i\")}function aa(t){for(var n={},e=-1,r=t.length;++e<r;)n[t[e].toLowerCase()]=e;return n}function ca(t,n,e){var r=Wx.exec(n.slice(e,e+1));return r?(t.w=+r[0],e+r[0].length):-1}function sa(t,n,e){var r=Wx.exec(n.slice(e));return r?(t.U=+r[0],e+r[0].length):-1}function fa(t,n,e){var r=Wx.exec(n.slice(e));return r?(t.W=+r[0],e+r[0].length):-1}function la(t,n,e){var r=Wx.exec(n.slice(e,e+4));return r?(t.y=+r[0],e+r[0].length):-1}function ha(t,n,e){var r=Wx.exec(n.slice(e,e+2));return r?(t.y=+r[0]+(+r[0]>68?1900:2e3),e+r[0].length):-1}function pa(t,n,e){var r=/^(Z)|([+-]\\d\\d)(?:\\:?(\\d\\d))?/.exec(n.slice(e,e+6));return r?(t.Z=r[1]?0:-(r[2]+(r[3]||\"00\")),e+r[0].length):-1}function da(t,n,e){var r=Wx.exec(n.slice(e,e+2));return r?(t.m=r[0]-1,e+r[0].length):-1}function va(t,n,e){var r=Wx.exec(n.slice(e,e+2));return r?(t.d=+r[0],e+r[0].length):-1}function _a(t,n,e){var r=Wx.exec(n.slice(e,e+3));return r?(t.m=0,t.d=+r[0],e+r[0].length):-1}function ya(t,n,e){var r=Wx.exec(n.slice(e,e+2));return r?(t.H=+r[0],e+r[0].length):-1}function ga(t,n,e){var r=Wx.exec(n.slice(e,e+2));return r?(t.M=+r[0],e+r[0].length):-1}function ma(t,n,e){var r=Wx.exec(n.slice(e,e+2));return r?(t.S=+r[0],e+r[0].length):-1}function xa(t,n,e){var r=Wx.exec(n.slice(e,e+3));return r?(t.L=+r[0],e+r[0].length):-1}function ba(t,n,e){var r=Zx.exec(n.slice(e,e+1));return r?e+r[0].length:-1}function wa(t,n){return ia(t.getDate(),n,2)}function Ma(t,n){return ia(t.getHours(),n,2)}function Ta(t,n){return ia(t.getHours()%12||12,n,2)}function ka(t,n){return ia(1+ex.count(xx(t),t),n,3)}function Na(t,n){return ia(t.getMilliseconds(),n,3)}function Sa(t,n){return ia(t.getMonth()+1,n,2)}function Ea(t,n){return ia(t.getMinutes(),n,2)}function Aa(t,n){return ia(t.getSeconds(),n,2)}function Ca(t,n){return ia(ix.count(xx(t),t),n,2)}function za(t){return t.getDay()}function Pa(t,n){return ia(ox.count(xx(t),t),n,2)}function La(t,n){return ia(t.getFullYear()%100,n,2)}function Ra(t,n){return ia(t.getFullYear()%1e4,n,4)}function qa(t){var n=t.getTimezoneOffset();return(n>0?\"-\":(n*=-1,\"+\"))+ia(n/60|0,\"0\",2)+ia(n%60,\"0\",2)}function Ua(t,n){return ia(t.getUTCDate(),n,2)}function Da(t,n){return ia(t.getUTCHours(),n,2)}function Oa(t,n){return ia(t.getUTCHours()%12||12,n,2)}function Fa(t,n){return ia(1+Nx.count(jx(t),t),n,3)}function Ia(t,n){return ia(t.getUTCMilliseconds(),n,3)}function Ya(t,n){return ia(t.getUTCMonth()+1,n,2)}function Ba(t,n){return ia(t.getUTCMinutes(),n,2)}function Ha(t,n){return ia(t.getUTCSeconds(),n,2)}function ja(t,n){return ia(Ex.count(jx(t),t),n,2)}function Xa(t){return t.getUTCDay()}function $a(t,n){return ia(Ax.count(jx(t),t),n,2)}function Va(t,n){return ia(t.getUTCFullYear()%100,n,2)}function Wa(t,n){return ia(t.getUTCFullYear()%1e4,n,4)}function Za(){return\"+0000\"}function Ga(){return\"%\"}function Ja(n){return Xx=ra(n),t.timeFormat=Xx.format,t.timeParse=Xx.parse,t.utcFormat=Xx.utcFormat,t.utcParse=Xx.utcParse,Xx}function Qa(t){return t.toISOString()}function Ka(t){var n=new Date(t);return isNaN(n)?null:n}function tc(t){return new Date(t)}function nc(t){return t instanceof Date?+t:+new Date(+t)}function ec(t,n,e,r,o,u,a,c,s){function f(i){return(a(i)<i?v:u(i)<i?_:o(i)<i?y:r(i)<i?g:n(i)<i?e(i)<i?m:x:t(i)<i?b:w)(i)}function l(n,e,r,o){if(null==n&&(n=10),\"number\"==typeof n){var u=Math.abs(r-e)/n,a=Xs(function(t){return t[2]}).right(M,u);a===M.length?(o=i(e/ob,r/ob,n),n=t):a?(a=M[u/M[a-1][2]<M[a][2]/u?a-1:a],o=a[1],n=a[0]):(o=i(e,r,n),n=c)}return null==o?n:n.every(o)}var h=Ru(Eu,Ch),p=h.invert,d=h.domain,v=s(\".%L\"),_=s(\":%S\"),y=s(\"%I:%M\"),g=s(\"%I %p\"),m=s(\"%a %d\"),x=s(\"%b %d\"),b=s(\"%B\"),w=s(\"%Y\"),M=[[a,1,Kx],[a,5,5*Kx],[a,15,15*Kx],[a,30,30*Kx],[u,1,tb],[u,5,5*tb],[u,15,15*tb],[u,30,30*tb],[o,1,nb],[o,3,3*nb],[o,6,6*nb],[o,12,12*nb],[r,1,eb],[r,2,2*eb],[e,1,rb],[n,1,ib],[n,3,3*ib],[t,1,ob]];return h.invert=function(t){return new Date(p(t))},h.domain=function(t){return arguments.length?d(Um.call(t,nc)):d().map(tc)},h.ticks=function(t,n){var e,r=d(),i=r[0],o=r[r.length-1],u=o<i;return u&&(e=i,i=o,o=e),e=l(t,i,o,n),e=e?e.range(i,o+1):[],u?e.reverse():e},h.tickFormat=function(t,n){return null==n?f:s(n)},h.nice=function(t,n){var e=d();return(t=l(t,e[0],e[e.length-1],n))?d(Hm(e,t)):h},h.copy=function(){return Lu(h,ec(t,n,e,r,o,u,a,c,s))},h}function rc(t){var n=t.length;return function(e){return t[Math.max(0,Math.min(n-1,Math.floor(e*n)))]}}function ic(t){function n(n){var o=(n-e)/(r-e);return t(i?Math.max(0,Math.min(1,o)):o)}var e=0,r=1,i=!1;return n.domain=function(t){return arguments.length?(e=+t[0],r=+t[1],n):[e,r]},n.clamp=function(t){return arguments.length?(i=!!t,n):i},n.interpolator=function(e){return arguments.length?(t=e,n):t},n.copy=function(){return ic(t).domain([e,r]).clamp(i)},qu(n)}function oc(t){return t>1?0:t<-1?zb:Math.acos(t)}function uc(t){return t>=1?Pb:t<=-1?-Pb:Math.asin(t)}function ac(t){return t.innerRadius}function cc(t){return t.outerRadius}function sc(t){return t.startAngle}function fc(t){return t.endAngle}function lc(t){return t&&t.padAngle}function hc(t,n,e,r,i,o,u,a){var c=e-t,s=r-n,f=u-i,l=a-o,h=(f*(n-o)-l*(t-i))/(l*c-f*s);return[t+h*c,n+h*s]}function pc(t,n,e,r,i,o,u){var a=t-e,c=n-r,s=(u?o:-o)/Ab(a*a+c*c),f=s*c,l=-s*a,h=t+f,p=n+l,d=e+f,v=r+l,_=(h+d)/2,y=(p+v)/2,g=d-h,m=v-p,x=g*g+m*m,b=i-o,w=h*v-d*p,M=(m<0?-1:1)*Ab(Nb(0,b*b*x-w*w)),T=(w*m-g*M)/x,k=(-w*g-m*M)/x,N=(w*m+g*M)/x,S=(-w*g+m*M)/x,E=T-_,A=k-y,C=N-_,z=S-y;return E*E+A*A>C*C+z*z&&(T=N,k=S),{cx:T,cy:k,x01:-f,y01:-l,x11:T*(i/b-1),y11:k*(i/b-1)}}function dc(t){this._context=t}function vc(t){return t[0]}function _c(t){return t[1]}function yc(t){this._curve=t}function gc(t){function n(n){return new yc(t(n))}return n._curve=t,n}function mc(t){var n=t.curve;return t.angle=t.x,delete t.x,t.radius=t.y,delete t.y,t.curve=function(t){return arguments.length?n(gc(t)):n()._curve},t}function xc(t){return t.source}function bc(t){return t.target}function wc(t){function n(){var n,a=jb.call(arguments),c=e.apply(this,a),s=r.apply(this,a);if(u||(u=n=Ue()),t(u,+i.apply(this,(a[0]=c,a)),+o.apply(this,a),+i.apply(this,(a[0]=s,a)),+o.apply(this,a)),n)return u=null,n+\"\"||null}var e=xc,r=bc,i=vc,o=_c,u=null;return n.source=function(t){return arguments.length?(e=t,n):e},n.target=function(t){return arguments.length?(r=t,n):r},n.x=function(t){return arguments.length?(i=\"function\"==typeof t?t:wb(+t),n):i},n.y=function(t){return arguments.length?(o=\"function\"==typeof t?t:wb(+t),n):o},n.context=function(t){return arguments.length?(u=null==t?null:t,n):u},n}function Mc(t,n,e,r,i){t.moveTo(n,e),t.bezierCurveTo(n=(n+r)/2,e,n,i,r,i)}function Tc(t,n,e,r,i){t.moveTo(n,e),t.bezierCurveTo(n,e=(e+i)/2,r,e,r,i)}function kc(t,n,e,r,i){var o=Xb(n,e),u=Xb(n,e=(e+i)/2),a=Xb(r,e),c=Xb(r,i);t.moveTo(o[0],o[1]),t.bezierCurveTo(u[0],u[1],a[0],a[1],c[0],c[1])}function Nc(){return wc(Mc)}function Sc(){return wc(Tc)}function Ec(){var t=wc(kc);return t.angle=t.x,delete t.x,t.radius=t.y,delete t.y,t}function Ac(t,n,e){t._context.bezierCurveTo((2*t._x0+t._x1)/3,(2*t._y0+t._y1)/3,(t._x0+2*t._x1)/3,(t._y0+2*t._y1)/3,(t._x0+4*t._x1+n)/6,(t._y0+4*t._y1+e)/6)}function Cc(t){this._context=t}function zc(t){this._context=t}function Pc(t){this._context=t}function Lc(t,n){this._basis=new Cc(t),this._beta=n}function Rc(t,n,e){t._context.bezierCurveTo(t._x1+t._k*(t._x2-t._x0),t._y1+t._k*(t._y2-t._y0),t._x2+t._k*(t._x1-n),t._y2+t._k*(t._y1-e),t._x2,t._y2)}function qc(t,n){this._context=t,this._k=(1-n)/6}function Uc(t,n){this._context=t,this._k=(1-n)/6}function Dc(t,n){this._context=t,this._k=(1-n)/6}function Oc(t,n,e){var r=t._x1,i=t._y1,o=t._x2,u=t._y2;if(t._l01_a>Cb){var a=2*t._l01_2a+3*t._l01_a*t._l12_a+t._l12_2a,c=3*t._l01_a*(t._l01_a+t._l12_a);r=(r*a-t._x0*t._l12_2a+t._x2*t._l01_2a)/c,i=(i*a-t._y0*t._l12_2a+t._y2*t._l01_2a)/c}if(t._l23_a>Cb){var s=2*t._l23_2a+3*t._l23_a*t._l12_a+t._l12_2a,f=3*t._l23_a*(t._l23_a+t._l12_a);o=(o*s+t._x1*t._l23_2a-n*t._l12_2a)/f,u=(u*s+t._y1*t._l23_2a-e*t._l12_2a)/f}t._context.bezierCurveTo(r,i,o,u,t._x2,t._y2)}function Fc(t,n){this._context=t,this._alpha=n}function Ic(t,n){this._context=t,this._alpha=n}function Yc(t,n){this._context=t,this._alpha=n}function Bc(t){this._context=t}function Hc(t){return t<0?-1:1}function jc(t,n,e){var r=t._x1-t._x0,i=n-t._x1,o=(t._y1-t._y0)/(r||i<0&&-0),u=(e-t._y1)/(i||r<0&&-0),a=(o*i+u*r)/(r+i);return(Hc(o)+Hc(u))*Math.min(Math.abs(o),Math.abs(u),.5*Math.abs(a))||0}function Xc(t,n){var e=t._x1-t._x0;return e?(3*(t._y1-t._y0)/e-n)/2:n}function $c(t,n,e){var r=t._x0,i=t._y0,o=t._x1,u=t._y1,a=(o-r)/3;t._context.bezierCurveTo(r+a,i+a*n,o-a,u-a*e,o,u)}function Vc(t){this._context=t}function Wc(t){this._context=new Zc(t)}function Zc(t){this._context=t}function Gc(t){return new Vc(t)}function Jc(t){return new Wc(t)}function Qc(t){this._context=t}function Kc(t){var n,e,r=t.length-1,i=new Array(r),o=new Array(r),u=new Array(r);for(i[0]=0,o[0]=2,u[0]=t[0]+2*t[1],n=1;n<r-1;++n)i[n]=1,o[n]=4,u[n]=4*t[n]+2*t[n+1];for(i[r-1]=2,o[r-1]=7,u[r-1]=8*t[r-1]+t[r],n=1;n<r;++n)e=i[n]/o[n-1],o[n]-=e,u[n]-=e*u[n-1];for(i[r-1]=u[r-1]/o[r-1],n=r-2;n>=0;--n)i[n]=(u[n]-i[n+1])/o[n];for(o[r-1]=(t[r]+i[r-1])/2,n=0;n<r-1;++n)o[n]=2*t[n+1]-i[n+1];return[i,o]}function ts(t,n){this._context=t,this._t=n}function ns(t){return new ts(t,0)}function es(t){return new ts(t,1)}function rs(t,n){return t[n]}function is(t){for(var n,e=0,r=-1,i=t.length;++r<i;)(n=+t[r][1])&&(e+=n);return e}function os(t){return t[0]}function us(t){return t[1]}function as(){this._=null}function cs(t){t.U=t.C=t.L=t.R=t.P=t.N=null}function ss(t,n){var e=n,r=n.R,i=e.U;i?i.L===e?i.L=r:i.R=r:t._=r,r.U=i,e.U=r,e.R=r.L,e.R&&(e.R.U=e),r.L=e}function fs(t,n){var e=n,r=n.L,i=e.U;i?i.L===e?i.L=r:i.R=r:t._=r,r.U=i,e.U=r,e.L=r.R,e.L&&(e.L.U=e),r.R=e}function ls(t){for(;t.L;)t=t.L;return t}function hs(t,n,e,r){var i=[null,null],o=Yw.push(i)-1;return i.left=t,i.right=n,e&&ds(i,t,n,e),r&&ds(i,n,t,r),Fw[t.index].halfedges.push(o),Fw[n.index].halfedges.push(o),i}function ps(t,n,e){var r=[n,e];return r.left=t,r}function ds(t,n,e,r){t[0]||t[1]?t.left===e?t[1]=r:t[0]=r:(t[0]=r,t.left=n,t.right=e)}function vs(t,n,e,r,i){var o,u=t[0],a=t[1],c=u[0],s=u[1],f=a[0],l=a[1],h=0,p=1,d=f-c,v=l-s;if(o=n-c,d||!(o>0)){if(o/=d,d<0){if(o<h)return;o<p&&(p=o)}else if(d>0){if(o>p)return;o>h&&(h=o)}if(o=r-c,d||!(o<0)){if(o/=d,d<0){if(o>p)return;o>h&&(h=o)}else if(d>0){if(o<h)return;o<p&&(p=o)}if(o=e-s,v||!(o>0)){if(o/=v,v<0){if(o<h)return;o<p&&(p=o)}else if(v>0){if(o>p)return;o>h&&(h=o)}if(o=i-s,v||!(o<0)){if(o/=v,v<0){if(o>p)return;o>h&&(h=o)}else if(v>0){if(o<h)return;o<p&&(p=o)}return!(h>0||p<1)||(h>0&&(t[0]=[c+h*d,s+h*v]),p<1&&(t[1]=[c+p*d,s+p*v]),!0)}}}}}function _s(t,n,e,r,i){var o=t[1];if(o)return!0;var u,a,c=t[0],s=t.left,f=t.right,l=s[0],h=s[1],p=f[0],d=f[1],v=(l+p)/2,_=(h+d)/2;if(d===h){if(v<n||v>=r)return;if(l>p){if(c){if(c[1]>=i)return}else c=[v,e];o=[v,i]}else{if(c){if(c[1]<e)return}else c=[v,i];o=[v,e]}}else if(u=(l-p)/(d-h),a=_-u*v,u<-1||u>1)if(l>p){if(c){if(c[1]>=i)return}else c=[(e-a)/u,e];o=[(i-a)/u,i]}else{if(c){if(c[1]<e)return}else c=[(i-a)/u,i];o=[(e-a)/u,e]}else if(h<d){if(c){if(c[0]>=r)return}else c=[n,u*n+a];o=[r,u*r+a]}else{if(c){if(c[0]<n)return}else c=[r,u*r+a];o=[n,u*n+a]}return t[0]=c,t[1]=o,!0}function ys(t,n,e,r){for(var i,o=Yw.length;o--;)_s(i=Yw[o],t,n,e,r)&&vs(i,t,n,e,r)&&(Math.abs(i[0][0]-i[1][0])>jw||Math.abs(i[0][1]-i[1][1])>jw)||delete Yw[o]}function gs(t){return Fw[t.index]={site:t,halfedges:[]}}function ms(t,n){var e=t.site,r=n.left,i=n.right;return e===i&&(i=r,r=e),i?Math.atan2(i[1]-r[1],i[0]-r[0]):(e===r?(r=n[1],i=n[0]):(r=n[0],i=n[1]),Math.atan2(r[0]-i[0],i[1]-r[1]))}function xs(t,n){return n[+(n.left!==t.site)]}function bs(t,n){return n[+(n.left===t.site)]}function ws(){for(var t,n,e,r,i=0,o=Fw.length;i<o;++i)if((t=Fw[i])&&(r=(n=t.halfedges).length)){var u=new Array(r),a=new Array(r);for(e=0;e<r;++e)u[e]=e,a[e]=ms(t,Yw[n[e]]);for(u.sort(function(t,n){return a[n]-a[t]}),e=0;e<r;++e)a[e]=n[u[e]];for(e=0;e<r;++e)n[e]=a[e]}}function Ms(t,n,e,r){var i,o,u,a,c,s,f,l,h,p,d,v,_=Fw.length,y=!0;for(i=0;i<_;++i)if(o=Fw[i]){for(u=o.site,c=o.halfedges,a=c.length;a--;)Yw[c[a]]||c.splice(a,1);for(a=0,s=c.length;a<s;)p=bs(o,Yw[c[a]]),d=p[0],v=p[1],f=xs(o,Yw[c[++a%s]]),l=f[0],h=f[1],(Math.abs(d-l)>jw||Math.abs(v-h)>jw)&&(c.splice(a,0,Yw.push(ps(u,p,Math.abs(d-t)<jw&&r-v>jw?[t,Math.abs(l-t)<jw?h:r]:Math.abs(v-r)<jw&&e-d>jw?[Math.abs(h-r)<jw?l:e,r]:Math.abs(d-e)<jw&&v-n>jw?[e,Math.abs(l-e)<jw?h:n]:Math.abs(v-n)<jw&&d-t>jw?[Math.abs(h-n)<jw?l:t,n]:null))-1),++s);s&&(y=!1)}if(y){var g,m,x,b=1/0;for(i=0,y=null;i<_;++i)(o=Fw[i])&&(u=o.site,g=u[0]-t,m=u[1]-n,(x=g*g+m*m)<b&&(b=x,y=o));if(y){var w=[t,n],M=[t,r],T=[e,r],k=[e,n];y.halfedges.push(Yw.push(ps(u=y.site,w,M))-1,Yw.push(ps(u,M,T))-1,Yw.push(ps(u,T,k))-1,Yw.push(ps(u,k,w))-1)}}for(i=0;i<_;++i)(o=Fw[i])&&(o.halfedges.length||delete Fw[i])}function Ts(){cs(this),this.x=this.y=this.arc=this.site=this.cy=null}function ks(t){var n=t.P,e=t.N;if(n&&e){var r=n.site,i=t.site,o=e.site;if(r!==o){var u=i[0],a=i[1],c=r[0]-u,s=r[1]-a,f=o[0]-u,l=o[1]-a,h=2*(c*l-s*f);if(!(h>=-Xw)){var p=c*c+s*s,d=f*f+l*l,v=(l*p-s*d)/h,_=(c*d-f*p)/h,y=Bw.pop()||new Ts;y.arc=t,y.site=i,y.x=v+u,y.y=(y.cy=_+a)+Math.sqrt(v*v+_*_),t.circle=y;for(var g=null,m=Iw._;m;)if(y.y<m.y||y.y===m.y&&y.x<=m.x){if(!m.L){g=m.P;break}m=m.L}else{if(!m.R){g=m;break}m=m.R}Iw.insert(g,y),g||(Dw=y)}}}}function Ns(t){var n=t.circle;n&&(n.P||(Dw=n.N),Iw.remove(n),Bw.push(n),cs(n),t.circle=null)}function Ss(){cs(this),this.edge=this.site=this.circle=null}function Es(t){var n=Hw.pop()||new Ss;return n.site=t,n}function As(t){Ns(t),Ow.remove(t),Hw.push(t),cs(t)}function Cs(t){var n=t.circle,e=n.x,r=n.cy,i=[e,r],o=t.P,u=t.N,a=[t];As(t);for(var c=o;c.circle&&Math.abs(e-c.circle.x)<jw&&Math.abs(r-c.circle.cy)<jw;)o=c.P,a.unshift(c),As(c),c=o;a.unshift(c),Ns(c);for(var s=u;s.circle&&Math.abs(e-s.circle.x)<jw&&Math.abs(r-s.circle.cy)<jw;)u=s.N,a.push(s),As(s),s=u;a.push(s),Ns(s);var f,l=a.length;for(f=1;f<l;++f)s=a[f],c=a[f-1],ds(s.edge,c.site,s.site,i);c=a[0],s=a[l-1],s.edge=hs(c.site,s.site,null,i),ks(c),ks(s)}function zs(t){for(var n,e,r,i,o=t[0],u=t[1],a=Ow._;a;)if((r=Ps(a,u)-o)>jw)a=a.L;else{if(!((i=o-Ls(a,u))>jw)){r>-jw?(n=a.P,e=a):i>-jw?(n=a,e=a.N):n=e=a;break}if(!a.R){n=a;break}a=a.R}gs(t);var c=Es(t);if(Ow.insert(n,c),n||e){if(n===e)return Ns(n),e=Es(n.site),Ow.insert(c,e),c.edge=e.edge=hs(n.site,c.site),ks(n),void ks(e);if(!e)return void(c.edge=hs(n.site,c.site));Ns(n),Ns(e);var s=n.site,f=s[0],l=s[1],h=t[0]-f,p=t[1]-l,d=e.site,v=d[0]-f,_=d[1]-l,y=2*(h*_-p*v),g=h*h+p*p,m=v*v+_*_,x=[(_*g-p*m)/y+f,(h*m-v*g)/y+l];ds(e.edge,s,d,x),c.edge=hs(s,t,null,x),e.edge=hs(t,d,null,x),ks(n),ks(e)}}function Ps(t,n){var e=t.site,r=e[0],i=e[1],o=i-n;if(!o)return r;var u=t.P;if(!u)return-1/0;e=u.site;var a=e[0],c=e[1],s=c-n;if(!s)return a;var f=a-r,l=1/o-1/s,h=f/s;return l?(-h+Math.sqrt(h*h-2*l*(f*f/(-2*s)-c+s/2+i-o/2)))/l+r:(r+a)/2}function Ls(t,n){var e=t.N;if(e)return Ps(e,n);var r=t.site;return r[1]===n?r[0]:1/0}function Rs(t,n,e){return(t[0]-e[0])*(n[1]-t[1])-(t[0]-n[0])*(e[1]-t[1])}function qs(t,n){return n[1]-t[1]||n[0]-t[0]}function Us(t,n){var e,r,i,o=t.sort(qs).pop();for(Yw=[],Fw=new Array(t.length),Ow=new as,Iw=new as;;)if(i=Dw,o&&(!i||o[1]<i.y||o[1]===i.y&&o[0]<i.x))o[0]===e&&o[1]===r||(zs(o),e=o[0],r=o[1]),o=t.pop();else{if(!i)break;Cs(i.arc)}if(ws(),n){var u=+n[0][0],a=+n[0][1],c=+n[1][0],s=+n[1][1];ys(u,a,c,s),Ms(u,a,c,s)}this.edges=Yw,this.cells=Fw,Ow=Iw=Yw=Fw=null}function Ds(t,n,e){this.target=t,this.type=n,this.transform=e}function Os(t,n,e){this.k=t,this.x=n,this.y=e}function Fs(t){return t.__zoom||Ww}function Is(){t.event.stopImmediatePropagation()}function Ys(){return!t.event.button}function Bs(){var t,n,e=this;return e instanceof SVGElement?(e=e.ownerSVGElement||e,t=e.width.baseVal.value,n=e.height.baseVal.value):(t=e.clientWidth,n=e.clientHeight),[[0,0],[t,n]]}function Hs(){return this.__zoom||Ww}var js=function(t,n){return t<n?-1:t>n?1:t>=n?0:NaN},Xs=function(t){return 1===t.length&&(t=n(t)),{left:function(n,e,r,i){for(null==r&&(r=0),null==i&&(i=n.length);r<i;){var o=r+i>>>1;t(n[o],e)<0?r=o+1:i=o}return r},right:function(n,e,r,i){for(null==r&&(r=0),null==i&&(i=n.length);r<i;){var o=r+i>>>1;t(n[o],e)>0?i=o:r=o+1}return r}}},$s=Xs(js),Vs=$s.right,Ws=$s.left,Zs=function(t,n){null==n&&(n=e);for(var r=0,i=t.length-1,o=t[0],u=new Array(i<0?0:i);r<i;)u[r]=n(o,o=t[++r]);return u},Gs=function(t,n,r){var i,o,u,a,c=t.length,s=n.length,f=new Array(c*s);for(null==r&&(r=e),i=u=0;i<c;++i)for(a=t[i],o=0;o<s;++o,++u)f[u]=r(a,n[o]);return f},Js=function(t,n){return n<t?-1:n>t?1:n>=t?0:NaN},Qs=function(t){return null===t?NaN:+t},Ks=function(t,n){var e,r,i=t.length,o=0,u=-1,a=0,c=0;if(null==n)for(;++u<i;)isNaN(e=Qs(t[u]))||(r=e-a,a+=r/++o,c+=r*(e-a));else for(;++u<i;)isNaN(e=Qs(n(t[u],u,t)))||(r=e-a,a+=r/++o,c+=r*(e-a));if(o>1)return c/(o-1)},tf=function(t,n){var e=Ks(t,n);return e?Math.sqrt(e):e},nf=function(t,n){var e,r,i,o=t.length,u=-1;if(null==n){for(;++u<o;)if(null!=(e=t[u])&&e>=e)for(r=i=e;++u<o;)null!=(e=t[u])&&(r>e&&(r=e),i<e&&(i=e))}else for(;++u<o;)if(null!=(e=n(t[u],u,t))&&e>=e)for(r=i=e;++u<o;)null!=(e=n(t[u],u,t))&&(r>e&&(r=e),i<e&&(i=e));return[r,i]},ef=Array.prototype,rf=ef.slice,of=ef.map,uf=function(t){return function(){return t}},af=function(t){return t},cf=function(t,n,e){t=+t,n=+n,e=(i=arguments.length)<2?(n=t,t=0,1):i<3?1:+e;for(var r=-1,i=0|Math.max(0,Math.ceil((n-t)/e)),o=new Array(i);++r<i;)o[r]=t+r*e;return o},sf=Math.sqrt(50),ff=Math.sqrt(10),lf=Math.sqrt(2),hf=function(t,n,e){var i,o,u,a=n<t,c=-1;if(a&&(i=t,t=n,n=i),0===(u=r(t,n,e))||!isFinite(u))return[];if(u>0)for(t=Math.ceil(t/u),n=Math.floor(n/u),o=new Array(i=Math.ceil(n-t+1));++c<i;)o[c]=(t+c)*u;else for(t=Math.floor(t*u),n=Math.ceil(n*u),o=new Array(i=Math.ceil(t-n+1));++c<i;)o[c]=(t-c)/u;return a&&o.reverse(),o},pf=function(t){return Math.ceil(Math.log(t.length)/Math.LN2)+1},df=function(){function t(t){var o,u,a=t.length,c=new Array(a);for(o=0;o<a;++o)c[o]=n(t[o],o,t);var s=e(c),f=s[0],l=s[1],h=r(c,f,l);Array.isArray(h)||(h=i(f,l,h),h=cf(Math.ceil(f/h)*h,Math.floor(l/h)*h,h));for(var p=h.length;h[0]<=f;)h.shift(),--p;for(;h[p-1]>l;)h.pop(),--p;var d,v=new Array(p+1);for(o=0;o<=p;++o)d=v[o]=[],d.x0=o>0?h[o-1]:f,d.x1=o<p?h[o]:l;for(o=0;o<a;++o)u=c[o],f<=u&&u<=l&&v[Vs(h,u,0,p)].push(t[o]);return v}var n=af,e=nf,r=pf;return t.value=function(e){return arguments.length?(n=\"function\"==typeof e?e:uf(e),t):n},t.domain=function(n){return arguments.length?(e=\"function\"==typeof n?n:uf([n[0],n[1]]),t):e},t.thresholds=function(n){return arguments.length?(r=\"function\"==typeof n?n:uf(Array.isArray(n)?rf.call(n):n),t):r},t},vf=function(t,n,e){if(null==e&&(e=Qs),r=t.length){if((n=+n)<=0||r<2)return+e(t[0],0,t);if(n>=1)return+e(t[r-1],r-1,t);var r,i=(r-1)*n,o=Math.floor(i),u=+e(t[o],o,t);return u+(+e(t[o+1],o+1,t)-u)*(i-o)}},_f=function(t,n,e){return t=of.call(t,Qs).sort(js),Math.ceil((e-n)/(2*(vf(t,.75)-vf(t,.25))*Math.pow(t.length,-1/3)))},yf=function(t,n,e){return Math.ceil((e-n)/(3.5*tf(t)*Math.pow(t.length,-1/3)))},gf=function(t,n){var e,r,i=t.length,o=-1;if(null==n){for(;++o<i;)if(null!=(e=t[o])&&e>=e)for(r=e;++o<i;)null!=(e=t[o])&&e>r&&(r=e)}else for(;++o<i;)if(null!=(e=n(t[o],o,t))&&e>=e)for(r=e;++o<i;)null!=(e=n(t[o],o,t))&&e>r&&(r=e);return r},mf=function(t,n){var e,r=t.length,i=r,o=-1,u=0;if(null==n)for(;++o<r;)isNaN(e=Qs(t[o]))?--i:u+=e;else for(;++o<r;)isNaN(e=Qs(n(t[o],o,t)))?--i:u+=e;if(i)return u/i},xf=function(t,n){var e,r=t.length,i=-1,o=[];if(null==n)for(;++i<r;)isNaN(e=Qs(t[i]))||o.push(e);else for(;++i<r;)isNaN(e=Qs(n(t[i],i,t)))||o.push(e);return vf(o.sort(js),.5)},bf=function(t){for(var n,e,r,i=t.length,o=-1,u=0;++o<i;)u+=t[o].length;for(e=new Array(u);--i>=0;)for(r=t[i],n=r.length;--n>=0;)e[--u]=r[n];return e},wf=function(t,n){var e,r,i=t.length,o=-1;if(null==n){for(;++o<i;)if(null!=(e=t[o])&&e>=e)for(r=e;++o<i;)null!=(e=t[o])&&r>e&&(r=e)}else for(;++o<i;)if(null!=(e=n(t[o],o,t))&&e>=e)for(r=e;++o<i;)null!=(e=n(t[o],o,t))&&r>e&&(r=e);return r},Mf=function(t,n){for(var e=n.length,r=new Array(e);e--;)r[e]=t[n[e]];return r},Tf=function(t,n){if(e=t.length){var e,r,i=0,o=0,u=t[o];for(null==n&&(n=js);++i<e;)(n(r=t[i],u)<0||0!==n(u,u))&&(u=r,o=i);return 0===n(u,u)?o:void 0}},kf=function(t,n,e){for(var r,i,o=(null==e?t.length:e)-(n=null==n?0:+n);o;)i=Math.random()*o--|0,r=t[o+n],t[o+n]=t[i+n],t[i+n]=r;return t},Nf=function(t,n){var e,r=t.length,i=-1,o=0;if(null==n)for(;++i<r;)(e=+t[i])&&(o+=e);else for(;++i<r;)(e=+n(t[i],i,t))&&(o+=e);return o},Sf=function(t){if(!(i=t.length))return[];for(var n=-1,e=wf(t,o),r=new Array(e);++n<e;)for(var i,u=-1,a=r[n]=new Array(i);++u<i;)a[u]=t[u][n];return r},Ef=function(){return Sf(arguments)},Af=Array.prototype.slice,Cf=function(t){return t},zf=1,Pf=2,Lf=3,Rf=4,qf=1e-6,Uf={value:function(){}};_.prototype=v.prototype={constructor:_,on:function(t,n){var e,r=this._,i=y(t+\"\",r),o=-1,u=i.length;{if(!(arguments.length<2)){if(null!=n&&\"function\"!=typeof n)throw new Error(\"invalid callback: \"+n);for(;++o<u;)if(e=(t=i[o]).type)r[e]=m(r[e],t.name,n);else if(null==n)for(e in r)r[e]=m(r[e],t.name,null);return this}for(;++o<u;)if((e=(t=i[o]).type)&&(e=g(r[e],t.name)))return e}},copy:function(){var t={},n=this._;for(var e in n)t[e]=n[e].slice();return new _(t)},call:function(t,n){if((e=arguments.length-2)>0)for(var e,r,i=new Array(e),o=0;o<e;++o)i[o]=arguments[o+2];if(!this._.hasOwnProperty(t))throw new Error(\"unknown type: \"+t);for(r=this._[t],o=0,e=r.length;o<e;++o)r[o].value.apply(n,i)},apply:function(t,n,e){if(!this._.hasOwnProperty(t))throw new Error(\"unknown type: \"+t);for(var r=this._[t],i=0,o=r.length;i<o;++i)r[i].value.apply(n,e)}};var Df=\"http://www.w3.org/1999/xhtml\",Of={svg:\"http://www.w3.org/2000/svg\",xhtml:Df,xlink:\"http://www.w3.org/1999/xlink\",xml:\"http://www.w3.org/XML/1998/namespace\",xmlns:\"http://www.w3.org/2000/xmlns/\"},Ff=function(t){var n=t+=\"\",e=n.indexOf(\":\");return e>=0&&\"xmlns\"!==(n=t.slice(0,e))&&(t=t.slice(e+1)),Of.hasOwnProperty(n)?{space:Of[n],local:t}:t},If=function(t){var n=Ff(t);return(n.local?b:x)(n)},Yf=0;M.prototype=w.prototype={constructor:M,get:function(t){for(var n=this._;!(n in t);)if(!(t=t.parentNode))return;return t[n]},set:function(t,n){return t[this._]=n},remove:function(t){return this._ in t&&delete t[this._]},toString:function(){return this._}};var Bf=function(t){return function(){return this.matches(t)}};if(\"undefined\"!=typeof document){var Hf=document.documentElement;if(!Hf.matches){var jf=Hf.webkitMatchesSelector||Hf.msMatchesSelector||Hf.mozMatchesSelector||Hf.oMatchesSelector;Bf=function(t){return function(){return jf.call(this,t)}}}}var Xf=Bf,$f={};if(t.event=null,\"undefined\"!=typeof document){\"onmouseenter\"in document.documentElement||($f={mouseenter:\"mouseover\",mouseleave:\"mouseout\"})}var Vf=function(t,n,e){var r,i,o=N(t+\"\"),u=o.length;{if(!(arguments.length<2)){for(a=n?E:S,null==e&&(e=!1),r=0;r<u;++r)this.each(a(o[r],n,e));return this}var a=this.node().__on;if(a)for(var c,s=0,f=a.length;s<f;++s)for(r=0,c=a[s];r<u;++r)if((i=o[r]).type===c.type&&i.name===c.name)return c.value}},Wf=function(){for(var n,e=t.event;n=e.sourceEvent;)e=n;return e},Zf=function(t,n){var e=t.ownerSVGElement||t;if(e.createSVGPoint){var r=e.createSVGPoint();return r.x=n.clientX,r.y=n.clientY,r=r.matrixTransform(t.getScreenCTM().inverse()),[r.x,r.y]}var i=t.getBoundingClientRect();return[n.clientX-i.left-t.clientLeft,n.clientY-i.top-t.clientTop]},Gf=function(t){var n=Wf();return n.changedTouches&&(n=n.changedTouches[0]),Zf(t,n)},Jf=function(t){return null==t?C:function(){return this.querySelector(t)}},Qf=function(t){\"function\"!=typeof t&&(t=Jf(t));for(var n=this._groups,e=n.length,r=new Array(e),i=0;i<e;++i)for(var o,u,a=n[i],c=a.length,s=r[i]=new Array(c),f=0;f<c;++f)(o=a[f])&&(u=t.call(o,o.__data__,f,a))&&(\"__data__\"in o&&(u.__data__=o.__data__),s[f]=u);return new _t(r,this._parents)},Kf=function(t){return null==t?z:function(){return this.querySelectorAll(t)}},tl=function(t){\"function\"!=typeof t&&(t=Kf(t));for(var n=this._groups,e=n.length,r=[],i=[],o=0;o<e;++o)for(var u,a=n[o],c=a.length,s=0;s<c;++s)(u=a[s])&&(r.push(t.call(u,u.__data__,s,a)),i.push(u));return new _t(r,i)},nl=function(t){\"function\"!=typeof t&&(t=Xf(t));for(var n=this._groups,e=n.length,r=new Array(e),i=0;i<e;++i)for(var o,u=n[i],a=u.length,c=r[i]=[],s=0;s<a;++s)(o=u[s])&&t.call(o,o.__data__,s,u)&&c.push(o);return new _t(r,this._parents)},el=function(t){return new Array(t.length)},rl=function(){return new _t(this._enter||this._groups.map(el),this._parents)};P.prototype={constructor:P,appendChild:function(t){return this._parent.insertBefore(t,this._next)},insertBefore:function(t,n){return this._parent.insertBefore(t,n)},querySelector:function(t){return this._parent.querySelector(t)},querySelectorAll:function(t){return this._parent.querySelectorAll(t)}};var il=function(t){return function(){return t}},ol=\"$\",ul=function(t,n){if(!t)return p=new Array(this.size()),s=-1,this.each(function(t){p[++s]=t}),p;var e=n?R:L,r=this._parents,i=this._groups;\"function\"!=typeof t&&(t=il(t));for(var o=i.length,u=new Array(o),a=new Array(o),c=new Array(o),s=0;s<o;++s){var f=r[s],l=i[s],h=l.length,p=t.call(f,f&&f.__data__,s,r),d=p.length,v=a[s]=new Array(d),_=u[s]=new Array(d);e(f,l,v,_,c[s]=new Array(h),p,n);for(var y,g,m=0,x=0;m<d;++m)if(y=v[m]){for(m>=x&&(x=m+1);!(g=_[x])&&++x<d;);y._next=g||null}}return u=new _t(u,r),u._enter=a,u._exit=c,u},al=function(){return new _t(this._exit||this._groups.map(el),this._parents)},cl=function(t){for(var n=this._groups,e=t._groups,r=n.length,i=e.length,o=Math.min(r,i),u=new Array(r),a=0;a<o;++a)for(var c,s=n[a],f=e[a],l=s.length,h=u[a]=new Array(l),p=0;p<l;++p)(c=s[p]||f[p])&&(h[p]=c);for(;a<r;++a)u[a]=n[a];return new _t(u,this._parents)},sl=function(){for(var t=this._groups,n=-1,e=t.length;++n<e;)for(var r,i=t[n],o=i.length-1,u=i[o];--o>=0;)(r=i[o])&&(u&&u!==r.nextSibling&&u.parentNode.insertBefore(r,u),u=r);return this},fl=function(t){function n(n,e){return n&&e?t(n.__data__,e.__data__):!n-!e}t||(t=q);for(var e=this._groups,r=e.length,i=new Array(r),o=0;o<r;++o){for(var u,a=e[o],c=a.length,s=i[o]=new Array(c),f=0;f<c;++f)(u=a[f])&&(s[f]=u);s.sort(n)}return new _t(i,this._parents).order()},ll=function(){var t=arguments[0];return arguments[0]=this,t.apply(null,arguments),this},hl=function(){var t=new Array(this.size()),n=-1;return this.each(function(){t[++n]=this}),t},pl=function(){for(var t=this._groups,n=0,e=t.length;n<e;++n)for(var r=t[n],i=0,o=r.length;i<o;++i){var u=r[i];if(u)return u}return null},dl=function(){var t=0;return this.each(function(){++t}),t},vl=function(){return!this.node()},_l=function(t){for(var n=this._groups,e=0,r=n.length;e<r;++e)for(var i,o=n[e],u=0,a=o.length;u<a;++u)(i=o[u])&&t.call(i,i.__data__,u,o);return this},yl=function(t,n){var e=Ff(t);if(arguments.length<2){var r=this.node();return e.local?r.getAttributeNS(e.space,e.local):r.getAttribute(e)}return this.each((null==n?e.local?D:U:\"function\"==typeof n?e.local?Y:I:e.local?F:O)(e,n))},gl=function(t){return t.ownerDocument&&t.ownerDocument.defaultView||t.document&&t||t.defaultView},ml=function(t,n,e){return arguments.length>1?this.each((null==n?B:\"function\"==typeof n?j:H)(t,n,null==e?\"\":e)):X(this.node(),t)},xl=function(t,n){return arguments.length>1?this.each((null==n?$:\"function\"==typeof n?W:V)(t,n)):this.node()[t]};J.prototype={add:function(t){this._names.indexOf(t)<0&&(this._names.push(t),this._node.setAttribute(\"class\",this._names.join(\" \")))},remove:function(t){var n=this._names.indexOf(t);n>=0&&(this._names.splice(n,1),this._node.setAttribute(\"class\",this._names.join(\" \")))},contains:function(t){return this._names.indexOf(t)>=0}};var bl=function(t,n){var e=Z(t+\"\");if(arguments.length<2){for(var r=G(this.node()),i=-1,o=e.length;++i<o;)if(!r.contains(e[i]))return!1;return!0}return this.each((\"function\"==typeof n?et:n?tt:nt)(e,n))},wl=function(t){return arguments.length?this.each(null==t?rt:(\"function\"==typeof t?ot:it)(t)):this.node().textContent},Ml=function(t){return arguments.length?this.each(null==t?ut:(\"function\"==typeof t?ct:at)(t)):this.node().innerHTML},Tl=function(){return this.each(st)},kl=function(){return this.each(ft)},Nl=function(t){var n=\"function\"==typeof t?t:If(t);return this.select(function(){return this.appendChild(n.apply(this,arguments))})},Sl=function(t,n){var e=\"function\"==typeof t?t:If(t),r=null==n?lt:\"function\"==typeof n?n:Jf(n);return this.select(function(){return this.insertBefore(e.apply(this,arguments),r.apply(this,arguments)||null)})},El=function(){return this.each(ht)},Al=function(t){return arguments.length?this.property(\"__data__\",t):this.node().__data__},Cl=function(t,n){return this.each((\"function\"==typeof n?vt:dt)(t,n))},zl=[null];_t.prototype=yt.prototype={constructor:_t,select:Qf,selectAll:tl,filter:nl,data:ul,enter:rl,exit:al,merge:cl,order:sl,sort:fl,call:ll,nodes:hl,node:pl,size:dl,empty:vl,each:_l,attr:yl,style:ml,property:xl,classed:bl,text:wl,html:Ml,raise:Tl,lower:kl,append:Nl,insert:Sl,remove:El,datum:Al,on:Vf,dispatch:Cl};var Pl=function(t){return\"string\"==typeof t?new _t([[document.querySelector(t)]],[document.documentElement]):new _t([[t]],zl)},Ll=function(t){return\"string\"==typeof t?new _t([document.querySelectorAll(t)],[document.documentElement]):new _t([null==t?[]:t],zl)\n},Rl=function(t,n,e){arguments.length<3&&(e=n,n=Wf().changedTouches);for(var r,i=0,o=n?n.length:0;i<o;++i)if((r=n[i]).identifier===e)return Zf(t,r);return null},ql=function(t,n){null==n&&(n=Wf().touches);for(var e=0,r=n?n.length:0,i=new Array(r);e<r;++e)i[e]=Zf(t,n[e]);return i},Ul=function(){t.event.preventDefault(),t.event.stopImmediatePropagation()},Dl=function(t){var n=t.document.documentElement,e=Pl(t).on(\"dragstart.drag\",Ul,!0);\"onselectstart\"in n?e.on(\"selectstart.drag\",Ul,!0):(n.__noselect=n.style.MozUserSelect,n.style.MozUserSelect=\"none\")},Ol=function(t){return function(){return t}};xt.prototype.on=function(){var t=this._.on.apply(this._,arguments);return t===this._?this:t};var Fl=function(){function n(t){t.on(\"mousedown.drag\",e).on(\"touchstart.drag\",o).on(\"touchmove.drag\",u).on(\"touchend.drag touchcancel.drag\",a).style(\"-webkit-tap-highlight-color\",\"rgba(0,0,0,0)\")}function e(){if(!h&&p.apply(this,arguments)){var n=c(\"mouse\",d.apply(this,arguments),Gf,this,arguments);n&&(Pl(t.event.view).on(\"mousemove.drag\",r,!0).on(\"mouseup.drag\",i,!0),Dl(t.event.view),gt(),l=!1,s=t.event.clientX,f=t.event.clientY,n(\"start\"))}}function r(){if(Ul(),!l){var n=t.event.clientX-s,e=t.event.clientY-f;l=n*n+e*e>x}y.mouse(\"drag\")}function i(){Pl(t.event.view).on(\"mousemove.drag mouseup.drag\",null),mt(t.event.view,l),Ul(),y.mouse(\"end\")}function o(){if(p.apply(this,arguments)){var n,e,r=t.event.changedTouches,i=d.apply(this,arguments),o=r.length;for(n=0;n<o;++n)(e=c(r[n].identifier,i,Rl,this,arguments))&&(gt(),e(\"start\"))}}function u(){var n,e,r=t.event.changedTouches,i=r.length;for(n=0;n<i;++n)(e=y[r[n].identifier])&&(Ul(),e(\"drag\"))}function a(){var n,e,r=t.event.changedTouches,i=r.length;for(h&&clearTimeout(h),h=setTimeout(function(){h=null},500),n=0;n<i;++n)(e=y[r[n].identifier])&&(gt(),e(\"end\"))}function c(e,r,i,o,u){var a,c,s,f=i(r,e),l=g.copy();if(A(new xt(n,\"beforestart\",a,e,m,f[0],f[1],0,0,l),function(){return null!=(t.event.subject=a=_.apply(o,u))&&(c=a.x-f[0]||0,s=a.y-f[1]||0,!0)}))return function t(h){var p,d=f;switch(h){case\"start\":y[e]=t,p=m++;break;case\"end\":delete y[e],--m;case\"drag\":f=i(r,e),p=m}A(new xt(n,h,a,e,p,f[0]+c,f[1]+s,f[0]-d[0],f[1]-d[1],l),l.apply,l,[h,o,u])}}var s,f,l,h,p=bt,d=wt,_=Mt,y={},g=v(\"start\",\"drag\",\"end\"),m=0,x=0;return n.filter=function(t){return arguments.length?(p=\"function\"==typeof t?t:Ol(!!t),n):p},n.container=function(t){return arguments.length?(d=\"function\"==typeof t?t:Ol(t),n):d},n.subject=function(t){return arguments.length?(_=\"function\"==typeof t?t:Ol(t),n):_},n.on=function(){var t=g.on.apply(g,arguments);return t===g?n:t},n.clickDistance=function(t){return arguments.length?(x=(t=+t)*t,n):Math.sqrt(x)},n},Il=function(t,n,e){t.prototype=n.prototype=e,e.constructor=t},Yl=\"\\\\s*([+-]?\\\\d+)\\\\s*\",Bl=\"\\\\s*([+-]?\\\\d*\\\\.?\\\\d+(?:[eE][+-]?\\\\d+)?)\\\\s*\",Hl=\"\\\\s*([+-]?\\\\d*\\\\.?\\\\d+(?:[eE][+-]?\\\\d+)?)%\\\\s*\",jl=/^#([0-9a-f]{3})$/,Xl=/^#([0-9a-f]{6})$/,$l=new RegExp(\"^rgb\\\\(\"+[Yl,Yl,Yl]+\"\\\\)$\"),Vl=new RegExp(\"^rgb\\\\(\"+[Hl,Hl,Hl]+\"\\\\)$\"),Wl=new RegExp(\"^rgba\\\\(\"+[Yl,Yl,Yl,Bl]+\"\\\\)$\"),Zl=new RegExp(\"^rgba\\\\(\"+[Hl,Hl,Hl,Bl]+\"\\\\)$\"),Gl=new RegExp(\"^hsl\\\\(\"+[Bl,Hl,Hl]+\"\\\\)$\"),Jl=new RegExp(\"^hsla\\\\(\"+[Bl,Hl,Hl,Bl]+\"\\\\)$\"),Ql={aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074};Il(kt,Nt,{displayable:function(){return this.rgb().displayable()},toString:function(){return this.rgb()+\"\"}}),Il(zt,Ct,Tt(kt,{brighter:function(t){return t=null==t?1/.7:Math.pow(1/.7,t),new zt(this.r*t,this.g*t,this.b*t,this.opacity)},darker:function(t){return t=null==t?.7:Math.pow(.7,t),new zt(this.r*t,this.g*t,this.b*t,this.opacity)},rgb:function(){return this},displayable:function(){return 0<=this.r&&this.r<=255&&0<=this.g&&this.g<=255&&0<=this.b&&this.b<=255&&0<=this.opacity&&this.opacity<=1},toString:function(){var t=this.opacity;return t=isNaN(t)?1:Math.max(0,Math.min(1,t)),(1===t?\"rgb(\":\"rgba(\")+Math.max(0,Math.min(255,Math.round(this.r)||0))+\", \"+Math.max(0,Math.min(255,Math.round(this.g)||0))+\", \"+Math.max(0,Math.min(255,Math.round(this.b)||0))+(1===t?\")\":\", \"+t+\")\")}})),Il(qt,Rt,Tt(kt,{brighter:function(t){return t=null==t?1/.7:Math.pow(1/.7,t),new qt(this.h,this.s,this.l*t,this.opacity)},darker:function(t){return t=null==t?.7:Math.pow(.7,t),new qt(this.h,this.s,this.l*t,this.opacity)},rgb:function(){var t=this.h%360+360*(this.h<0),n=isNaN(t)||isNaN(this.s)?0:this.s,e=this.l,r=e+(e<.5?e:1-e)*n,i=2*e-r;return new zt(Ut(t>=240?t-240:t+120,i,r),Ut(t,i,r),Ut(t<120?t+240:t-120,i,r),this.opacity)},displayable:function(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1}}));var Kl=Math.PI/180,th=180/Math.PI,nh=.95047,eh=1,rh=1.08883,ih=4/29,oh=6/29,uh=3*oh*oh,ah=oh*oh*oh;Il(Ft,Ot,Tt(kt,{brighter:function(t){return new Ft(this.l+18*(null==t?1:t),this.a,this.b,this.opacity)},darker:function(t){return new Ft(this.l-18*(null==t?1:t),this.a,this.b,this.opacity)},rgb:function(){var t=(this.l+16)/116,n=isNaN(this.a)?t:t+this.a/500,e=isNaN(this.b)?t:t-this.b/200;return t=eh*Yt(t),n=nh*Yt(n),e=rh*Yt(e),new zt(Bt(3.2404542*n-1.5371385*t-.4985314*e),Bt(-.969266*n+1.8760108*t+.041556*e),Bt(.0556434*n-.2040259*t+1.0572252*e),this.opacity)}})),Il($t,Xt,Tt(kt,{brighter:function(t){return new $t(this.h,this.c,this.l+18*(null==t?1:t),this.opacity)},darker:function(t){return new $t(this.h,this.c,this.l-18*(null==t?1:t),this.opacity)},rgb:function(){return Dt(this).rgb()}}));var ch=-.14861,sh=1.78277,fh=-.29227,lh=-.90649,hh=1.97294,ph=hh*lh,dh=hh*sh,vh=sh*fh-lh*ch;Il(Zt,Wt,Tt(kt,{brighter:function(t){return t=null==t?1/.7:Math.pow(1/.7,t),new Zt(this.h,this.s,this.l*t,this.opacity)},darker:function(t){return t=null==t?.7:Math.pow(.7,t),new Zt(this.h,this.s,this.l*t,this.opacity)},rgb:function(){var t=isNaN(this.h)?0:(this.h+120)*Kl,n=+this.l,e=isNaN(this.s)?0:this.s*n*(1-n),r=Math.cos(t),i=Math.sin(t);return new zt(255*(n+e*(ch*r+sh*i)),255*(n+e*(fh*r+lh*i)),255*(n+e*(hh*r)),this.opacity)}}));var _h,yh,gh,mh,xh,bh,wh=function(t){var n=t.length-1;return function(e){var r=e<=0?e=0:e>=1?(e=1,n-1):Math.floor(e*n),i=t[r],o=t[r+1],u=r>0?t[r-1]:2*i-o,a=r<n-1?t[r+2]:2*o-i;return Gt((e-r/n)*n,u,i,o,a)}},Mh=function(t){var n=t.length;return function(e){var r=Math.floor(((e%=1)<0?++e:e)*n),i=t[(r+n-1)%n],o=t[r%n],u=t[(r+1)%n],a=t[(r+2)%n];return Gt((e-r/n)*n,i,o,u,a)}},Th=function(t){return function(){return t}},kh=function t(n){function e(t,n){var e=r((t=Ct(t)).r,(n=Ct(n)).r),i=r(t.g,n.g),o=r(t.b,n.b),u=nn(t.opacity,n.opacity);return function(n){return t.r=e(n),t.g=i(n),t.b=o(n),t.opacity=u(n),t+\"\"}}var r=tn(n);return e.gamma=t,e}(1),Nh=en(wh),Sh=en(Mh),Eh=function(t,n){var e,r=n?n.length:0,i=t?Math.min(r,t.length):0,o=new Array(r),u=new Array(r);for(e=0;e<i;++e)o[e]=qh(t[e],n[e]);for(;e<r;++e)u[e]=n[e];return function(t){for(e=0;e<i;++e)u[e]=o[e](t);return u}},Ah=function(t,n){var e=new Date;return t=+t,n-=t,function(r){return e.setTime(t+n*r),e}},Ch=function(t,n){return t=+t,n-=t,function(e){return t+n*e}},zh=function(t,n){var e,r={},i={};null!==t&&\"object\"==typeof t||(t={}),null!==n&&\"object\"==typeof n||(n={});for(e in n)e in t?r[e]=qh(t[e],n[e]):i[e]=n[e];return function(t){for(e in r)i[e]=r[e](t);return i}},Ph=/[-+]?(?:\\d+\\.?\\d*|\\.?\\d+)(?:[eE][-+]?\\d+)?/g,Lh=new RegExp(Ph.source,\"g\"),Rh=function(t,n){var e,r,i,o=Ph.lastIndex=Lh.lastIndex=0,u=-1,a=[],c=[];for(t+=\"\",n+=\"\";(e=Ph.exec(t))&&(r=Lh.exec(n));)(i=r.index)>o&&(i=n.slice(o,i),a[u]?a[u]+=i:a[++u]=i),(e=e[0])===(r=r[0])?a[u]?a[u]+=r:a[++u]=r:(a[++u]=null,c.push({i:u,x:Ch(e,r)})),o=Lh.lastIndex;return o<n.length&&(i=n.slice(o),a[u]?a[u]+=i:a[++u]=i),a.length<2?c[0]?on(c[0].x):rn(n):(n=c.length,function(t){for(var e,r=0;r<n;++r)a[(e=c[r]).i]=e.x(t);return a.join(\"\")})},qh=function(t,n){var e,r=typeof n;return null==n||\"boolean\"===r?Th(n):(\"number\"===r?Ch:\"string\"===r?(e=Nt(n))?(n=e,kh):Rh:n instanceof Nt?kh:n instanceof Date?Ah:Array.isArray(n)?Eh:\"function\"!=typeof n.valueOf&&\"function\"!=typeof n.toString||isNaN(n)?zh:Ch)(t,n)},Uh=function(t,n){return t=+t,n-=t,function(e){return Math.round(t+n*e)}},Dh=180/Math.PI,Oh={translateX:0,translateY:0,rotate:0,skewX:0,scaleX:1,scaleY:1},Fh=function(t,n,e,r,i,o){var u,a,c;return(u=Math.sqrt(t*t+n*n))&&(t/=u,n/=u),(c=t*e+n*r)&&(e-=t*c,r-=n*c),(a=Math.sqrt(e*e+r*r))&&(e/=a,r/=a,c/=a),t*r<n*e&&(t=-t,n=-n,c=-c,u=-u),{translateX:i,translateY:o,rotate:Math.atan2(n,t)*Dh,skewX:Math.atan(c)*Dh,scaleX:u,scaleY:a}},Ih=cn(un,\"px, \",\"px)\",\"deg)\"),Yh=cn(an,\", \",\")\",\")\"),Bh=Math.SQRT2,Hh=function(t,n){var e,r,i=t[0],o=t[1],u=t[2],a=n[0],c=n[1],s=n[2],f=a-i,l=c-o,h=f*f+l*l;if(h<1e-12)r=Math.log(s/u)/Bh,e=function(t){return[i+t*f,o+t*l,u*Math.exp(Bh*t*r)]};else{var p=Math.sqrt(h),d=(s*s-u*u+4*h)/(2*u*2*p),v=(s*s-u*u-4*h)/(2*s*2*p),_=Math.log(Math.sqrt(d*d+1)-d),y=Math.log(Math.sqrt(v*v+1)-v);r=(y-_)/Bh,e=function(t){var n=t*r,e=sn(_),a=u/(2*p)*(e*ln(Bh*n+_)-fn(_));return[i+a*f,o+a*l,u*e/sn(Bh*n+_)]}}return e.duration=1e3*r,e},jh=hn(Kt),Xh=hn(nn),$h=dn(Kt),Vh=dn(nn),Wh=vn(Kt),Zh=vn(nn),Gh=function(t,n){for(var e=new Array(n),r=0;r<n;++r)e[r]=t(r/(n-1));return e},Jh=0,Qh=0,Kh=0,tp=1e3,np=0,ep=0,rp=0,ip=\"object\"==typeof performance&&performance.now?performance:Date,op=\"function\"==typeof requestAnimationFrame?requestAnimationFrame:function(t){setTimeout(t,17)};gn.prototype=mn.prototype={constructor:gn,restart:function(t,n,e){if(\"function\"!=typeof t)throw new TypeError(\"callback is not a function\");e=(null==e?_n():+e)+(null==n?0:+n),this._next||bh===this||(bh?bh._next=this:xh=this,bh=this),this._call=t,this._time=e,Tn()},stop:function(){this._call&&(this._call=null,this._time=1/0,Tn())}};var up=function(t,n,e){var r=new gn;return n=null==n?0:+n,r.restart(function(e){r.stop(),t(e+n)},n,e),r},ap=function(t,n,e){var r=new gn,i=n;return null==n?(r.restart(t,n,e),r):(n=+n,e=null==e?_n():+e,r.restart(function o(u){u+=i,r.restart(o,i+=n,e),t(u)},n,e),r)},cp=v(\"start\",\"end\",\"interrupt\"),sp=[],fp=0,lp=1,hp=2,pp=3,dp=4,vp=5,_p=6,yp=function(t,n,e,r,i,o){var u=t.__transition;if(u){if(e in u)return}else t.__transition={};En(t,e,{name:n,index:r,group:i,on:cp,tween:sp,time:o.time,delay:o.delay,duration:o.duration,ease:o.ease,timer:null,state:fp})},gp=function(t,n){var e,r,i,o=t.__transition,u=!0;if(o){n=null==n?null:n+\"\";for(i in o)(e=o[i]).name===n?(r=e.state>hp&&e.state<vp,e.state=_p,e.timer.stop(),r&&e.on.call(\"interrupt\",t,t.__data__,e.index,e.group),delete o[i]):u=!1;u&&delete t.__transition}},mp=function(t){return this.each(function(){gp(this,t)})},xp=function(t,n){var e=this._id;if(t+=\"\",arguments.length<2){for(var r,i=Sn(this.node(),e).tween,o=0,u=i.length;o<u;++o)if((r=i[o]).name===t)return r.value;return null}return this.each((null==n?An:Cn)(e,t,n))},bp=function(t,n){var e;return(\"number\"==typeof n?Ch:n instanceof Nt?kh:(e=Nt(n))?(n=e,kh):Rh)(t,n)},wp=function(t,n){var e=Ff(t),r=\"transform\"===e?Yh:bp;return this.attrTween(t,\"function\"==typeof n?(e.local?Dn:Un)(e,r,zn(this,\"attr.\"+t,n)):null==n?(e.local?Ln:Pn)(e):(e.local?qn:Rn)(e,r,n+\"\"))},Mp=function(t,n){var e=\"attr.\"+t;if(arguments.length<2)return(e=this.tween(e))&&e._value;if(null==n)return this.tween(e,null);if(\"function\"!=typeof n)throw new Error;var r=Ff(t);return this.tween(e,(r.local?On:Fn)(r,n))},Tp=function(t){var n=this._id;return arguments.length?this.each((\"function\"==typeof t?In:Yn)(n,t)):Sn(this.node(),n).delay},kp=function(t){var n=this._id;return arguments.length?this.each((\"function\"==typeof t?Bn:Hn)(n,t)):Sn(this.node(),n).duration},Np=function(t){var n=this._id;return arguments.length?this.each(jn(n,t)):Sn(this.node(),n).ease},Sp=function(t){\"function\"!=typeof t&&(t=Xf(t));for(var n=this._groups,e=n.length,r=new Array(e),i=0;i<e;++i)for(var o,u=n[i],a=u.length,c=r[i]=[],s=0;s<a;++s)(o=u[s])&&t.call(o,o.__data__,s,u)&&c.push(o);return new ne(r,this._parents,this._name,this._id)},Ep=function(t){if(t._id!==this._id)throw new Error;for(var n=this._groups,e=t._groups,r=n.length,i=e.length,o=Math.min(r,i),u=new Array(r),a=0;a<o;++a)for(var c,s=n[a],f=e[a],l=s.length,h=u[a]=new Array(l),p=0;p<l;++p)(c=s[p]||f[p])&&(h[p]=c);for(;a<r;++a)u[a]=n[a];return new ne(u,this._parents,this._name,this._id)},Ap=function(t,n){var e=this._id;return arguments.length<2?Sn(this.node(),e).on.on(t):this.each($n(e,t,n))},Cp=function(){return this.on(\"end.remove\",Vn(this._id))},zp=function(t){var n=this._name,e=this._id;\"function\"!=typeof t&&(t=Jf(t));for(var r=this._groups,i=r.length,o=new Array(i),u=0;u<i;++u)for(var a,c,s=r[u],f=s.length,l=o[u]=new Array(f),h=0;h<f;++h)(a=s[h])&&(c=t.call(a,a.__data__,h,s))&&(\"__data__\"in a&&(c.__data__=a.__data__),l[h]=c,yp(l[h],n,e,h,l,Sn(a,e)));return new ne(o,this._parents,n,e)},Pp=function(t){var n=this._name,e=this._id;\"function\"!=typeof t&&(t=Kf(t));for(var r=this._groups,i=r.length,o=[],u=[],a=0;a<i;++a)for(var c,s=r[a],f=s.length,l=0;l<f;++l)if(c=s[l]){for(var h,p=t.call(c,c.__data__,l,s),d=Sn(c,e),v=0,_=p.length;v<_;++v)(h=p[v])&&yp(h,n,e,v,p,d);o.push(p),u.push(c)}return new ne(o,u,n,e)},Lp=yt.prototype.constructor,Rp=function(){return new Lp(this._groups,this._parents)},qp=function(t,n,e){var r=\"transform\"==(t+=\"\")?Ih:bp;return null==n?this.styleTween(t,Wn(t,r)).on(\"end.style.\"+t,Zn(t)):this.styleTween(t,\"function\"==typeof n?Jn(t,r,zn(this,\"style.\"+t,n)):Gn(t,r,n+\"\"),e)},Up=function(t,n,e){var r=\"style.\"+(t+=\"\");if(arguments.length<2)return(r=this.tween(r))&&r._value;if(null==n)return this.tween(r,null);if(\"function\"!=typeof n)throw new Error;return this.tween(r,Qn(t,n,null==e?\"\":e))},Dp=function(t){return this.tween(\"text\",\"function\"==typeof t?te(zn(this,\"text\",t)):Kn(null==t?\"\":t+\"\"))},Op=function(){for(var t=this._name,n=this._id,e=re(),r=this._groups,i=r.length,o=0;o<i;++o)for(var u,a=r[o],c=a.length,s=0;s<c;++s)if(u=a[s]){var f=Sn(u,n);yp(u,t,e,s,a,{time:f.time+f.delay+f.duration,delay:0,duration:f.duration,ease:f.ease})}return new ne(r,this._parents,t,e)},Fp=0,Ip=yt.prototype;ne.prototype=ee.prototype={constructor:ne,select:zp,selectAll:Pp,filter:Sp,merge:Ep,selection:Rp,transition:Op,call:Ip.call,nodes:Ip.nodes,node:Ip.node,size:Ip.size,empty:Ip.empty,each:Ip.each,on:Ap,attr:wp,attrTween:Mp,style:qp,styleTween:Up,text:Dp,remove:Cp,tween:xp,delay:Tp,duration:kp,ease:Np};var Yp=function t(n){function e(t){return Math.pow(t,n)}return n=+n,e.exponent=t,e}(3),Bp=function t(n){function e(t){return 1-Math.pow(1-t,n)}return n=+n,e.exponent=t,e}(3),Hp=function t(n){function e(t){return((t*=2)<=1?Math.pow(t,n):2-Math.pow(2-t,n))/2}return n=+n,e.exponent=t,e}(3),jp=Math.PI,Xp=jp/2,$p=4/11,Vp=6/11,Wp=8/11,Zp=.75,Gp=9/11,Jp=10/11,Qp=.9375,Kp=21/22,td=63/64,nd=1/$p/$p,ed=function t(n){function e(t){return t*t*((n+1)*t-n)}return n=+n,e.overshoot=t,e}(1.70158),rd=function t(n){function e(t){return--t*t*((n+1)*t+n)+1}return n=+n,e.overshoot=t,e}(1.70158),id=function t(n){function e(t){return((t*=2)<1?t*t*((n+1)*t-n):(t-=2)*t*((n+1)*t+n)+2)/2}return n=+n,e.overshoot=t,e}(1.70158),od=2*Math.PI,ud=function t(n,e){function r(t){return n*Math.pow(2,10*--t)*Math.sin((i-t)/e)}var i=Math.asin(1/(n=Math.max(1,n)))*(e/=od);return r.amplitude=function(n){return t(n,e*od)},r.period=function(e){return t(n,e)},r}(1,.3),ad=function t(n,e){function r(t){return 1-n*Math.pow(2,-10*(t=+t))*Math.sin((t+i)/e)}var i=Math.asin(1/(n=Math.max(1,n)))*(e/=od);return r.amplitude=function(n){return t(n,e*od)},r.period=function(e){return t(n,e)},r}(1,.3),cd=function t(n,e){function r(t){return((t=2*t-1)<0?n*Math.pow(2,10*t)*Math.sin((i-t)/e):2-n*Math.pow(2,-10*t)*Math.sin((i+t)/e))/2}var i=Math.asin(1/(n=Math.max(1,n)))*(e/=od);return r.amplitude=function(n){return t(n,e*od)},r.period=function(e){return t(n,e)},r}(1,.3),sd={time:null,delay:0,duration:250,ease:fe},fd=function(t){var n,e;t instanceof ne?(n=t._id,t=t._name):(n=re(),(e=sd).time=_n(),t=null==t?null:t+\"\");for(var r=this._groups,i=r.length,o=0;o<i;++o)for(var u,a=r[o],c=a.length,s=0;s<c;++s)(u=a[s])&&yp(u,t,n,s,a,e||Me(u,n));return new ne(r,this._parents,t,n)};yt.prototype.interrupt=mp,yt.prototype.transition=fd;var ld=[null],hd=function(t,n){var e,r,i=t.__transition;if(i){n=null==n?null:n+\"\";for(r in i)if((e=i[r]).state>lp&&e.name===n)return new ne([[t]],ld,n,+r)}return null},pd=function(t){return function(){return t}},dd=function(t,n,e){this.target=t,this.type=n,this.selection=e},vd=function(){t.event.preventDefault(),t.event.stopImmediatePropagation()},_d={name:\"drag\"},yd={name:\"space\"},gd={name:\"handle\"},md={name:\"center\"},xd={name:\"x\",handles:[\"e\",\"w\"].map(ke),input:function(t,n){return t&&[[t[0],n[0][1]],[t[1],n[1][1]]]},output:function(t){return t&&[t[0][0],t[1][0]]}},bd={name:\"y\",handles:[\"n\",\"s\"].map(ke),input:function(t,n){return t&&[[n[0][0],t[0]],[n[1][0],t[1]]]},output:function(t){return t&&[t[0][1],t[1][1]]}},wd={name:\"xy\",handles:[\"n\",\"e\",\"s\",\"w\",\"nw\",\"ne\",\"se\",\"sw\"].map(ke),input:function(t){return t},output:function(t){return t}},Md={overlay:\"crosshair\",selection:\"move\",n:\"ns-resize\",e:\"ew-resize\",s:\"ns-resize\",w:\"ew-resize\",nw:\"nwse-resize\",ne:\"nesw-resize\",se:\"nwse-resize\",sw:\"nesw-resize\"},Td={e:\"w\",w:\"e\",nw:\"ne\",ne:\"nw\",se:\"sw\",sw:\"se\"},kd={n:\"s\",s:\"n\",nw:\"sw\",ne:\"se\",se:\"ne\",sw:\"nw\"},Nd={overlay:1,selection:1,n:null,e:1,s:null,w:-1,nw:-1,ne:1,se:1,sw:-1},Sd={overlay:1,selection:1,n:-1,e:null,s:1,w:null,nw:-1,ne:-1,se:1,sw:1},Ed=function(){return Le(wd)},Ad=Math.cos,Cd=Math.sin,zd=Math.PI,Pd=zd/2,Ld=2*zd,Rd=Math.max,qd=function(){function t(t){var o,u,a,c,s,f,l=t.length,h=[],p=cf(l),d=[],v=[],_=v.groups=new Array(l),y=new Array(l*l);for(o=0,s=-1;++s<l;){for(u=0,f=-1;++f<l;)u+=t[s][f];h.push(u),d.push(cf(l)),o+=u}for(e&&p.sort(function(t,n){return e(h[t],h[n])}),r&&d.forEach(function(n,e){n.sort(function(n,i){return r(t[e][n],t[e][i])})}),o=Rd(0,Ld-n*l)/o,c=o?n:Ld/l,u=0,s=-1;++s<l;){for(a=u,f=-1;++f<l;){var g=p[s],m=d[g][f],x=t[g][m],b=u,w=u+=x*o;y[m*l+g]={index:g,subindex:m,startAngle:b,endAngle:w,value:x}}_[g]={index:g,startAngle:a,endAngle:u,value:h[g]},u+=c}for(s=-1;++s<l;)for(f=s-1;++f<l;){var M=y[f*l+s],T=y[s*l+f];(M.value||T.value)&&v.push(M.value<T.value?{source:T,target:M}:{source:M,target:T})}return i?v.sort(i):v}var n=0,e=null,r=null,i=null;return t.padAngle=function(e){return arguments.length?(n=Rd(0,e),t):n},t.sortGroups=function(n){return arguments.length?(e=n,t):e},t.sortSubgroups=function(n){return arguments.length?(r=n,t):r},t.sortChords=function(n){return arguments.length?(null==n?i=null:(i=Re(n))._=n,t):i&&i._},t},Ud=Array.prototype.slice,Dd=function(t){return function(){return t}},Od=Math.PI,Fd=2*Od,Id=Fd-1e-6;qe.prototype=Ue.prototype={constructor:qe,moveTo:function(t,n){this._+=\"M\"+(this._x0=this._x1=+t)+\",\"+(this._y0=this._y1=+n)},closePath:function(){null!==this._x1&&(this._x1=this._x0,this._y1=this._y0,this._+=\"Z\")},lineTo:function(t,n){this._+=\"L\"+(this._x1=+t)+\",\"+(this._y1=+n)},quadraticCurveTo:function(t,n,e,r){this._+=\"Q\"+ +t+\",\"+ +n+\",\"+(this._x1=+e)+\",\"+(this._y1=+r)},bezierCurveTo:function(t,n,e,r,i,o){this._+=\"C\"+ +t+\",\"+ +n+\",\"+ +e+\",\"+ +r+\",\"+(this._x1=+i)+\",\"+(this._y1=+o)},arcTo:function(t,n,e,r,i){t=+t,n=+n,e=+e,r=+r,i=+i;var o=this._x1,u=this._y1,a=e-t,c=r-n,s=o-t,f=u-n,l=s*s+f*f;if(i<0)throw new Error(\"negative radius: \"+i);if(null===this._x1)this._+=\"M\"+(this._x1=t)+\",\"+(this._y1=n);else if(l>1e-6)if(Math.abs(f*a-c*s)>1e-6&&i){var h=e-o,p=r-u,d=a*a+c*c,v=h*h+p*p,_=Math.sqrt(d),y=Math.sqrt(l),g=i*Math.tan((Od-Math.acos((d+l-v)/(2*_*y)))/2),m=g/y,x=g/_;Math.abs(m-1)>1e-6&&(this._+=\"L\"+(t+m*s)+\",\"+(n+m*f)),this._+=\"A\"+i+\",\"+i+\",0,0,\"+ +(f*h>s*p)+\",\"+(this._x1=t+x*a)+\",\"+(this._y1=n+x*c)}else this._+=\"L\"+(this._x1=t)+\",\"+(this._y1=n);else;},arc:function(t,n,e,r,i,o){t=+t,n=+n,e=+e;var u=e*Math.cos(r),a=e*Math.sin(r),c=t+u,s=n+a,f=1^o,l=o?r-i:i-r;if(e<0)throw new Error(\"negative radius: \"+e);null===this._x1?this._+=\"M\"+c+\",\"+s:(Math.abs(this._x1-c)>1e-6||Math.abs(this._y1-s)>1e-6)&&(this._+=\"L\"+c+\",\"+s),e&&(l<0&&(l=l%Fd+Fd),l>Id?this._+=\"A\"+e+\",\"+e+\",0,1,\"+f+\",\"+(t-u)+\",\"+(n-a)+\"A\"+e+\",\"+e+\",0,1,\"+f+\",\"+(this._x1=c)+\",\"+(this._y1=s):l>1e-6&&(this._+=\"A\"+e+\",\"+e+\",0,\"+ +(l>=Od)+\",\"+f+\",\"+(this._x1=t+e*Math.cos(i))+\",\"+(this._y1=n+e*Math.sin(i))))},rect:function(t,n,e,r){this._+=\"M\"+(this._x0=this._x1=+t)+\",\"+(this._y0=this._y1=+n)+\"h\"+ +e+\"v\"+ +r+\"h\"+-e+\"Z\"},toString:function(){return this._}};var Yd=function(){function t(){var t,a=Ud.call(arguments),c=n.apply(this,a),s=e.apply(this,a),f=+r.apply(this,(a[0]=c,a)),l=i.apply(this,a)-Pd,h=o.apply(this,a)-Pd,p=f*Ad(l),d=f*Cd(l),v=+r.apply(this,(a[0]=s,a)),_=i.apply(this,a)-Pd,y=o.apply(this,a)-Pd;if(u||(u=t=Ue()),u.moveTo(p,d),u.arc(0,0,f,l,h),l===_&&h===y||(u.quadraticCurveTo(0,0,v*Ad(_),v*Cd(_)),u.arc(0,0,v,_,y)),u.quadraticCurveTo(0,0,p,d),u.closePath(),t)return u=null,t+\"\"||null}var n=De,e=Oe,r=Fe,i=Ie,o=Ye,u=null;return t.radius=function(n){return arguments.length?(r=\"function\"==typeof n?n:Dd(+n),t):r},t.startAngle=function(n){return arguments.length?(i=\"function\"==typeof n?n:Dd(+n),t):i},t.endAngle=function(n){return arguments.length?(o=\"function\"==typeof n?n:Dd(+n),t):o},t.source=function(e){return arguments.length?(n=e,t):n},t.target=function(n){return arguments.length?(e=n,t):e},t.context=function(n){return arguments.length?(u=null==n?null:n,t):u},t};Be.prototype=He.prototype={constructor:Be,has:function(t){return\"$\"+t in this},get:function(t){return this[\"$\"+t]},set:function(t,n){return this[\"$\"+t]=n,this},remove:function(t){var n=\"$\"+t;return n in this&&delete this[n]},clear:function(){for(var t in this)\"$\"===t[0]&&delete this[t]},keys:function(){var t=[];for(var n in this)\"$\"===n[0]&&t.push(n.slice(1));return t},values:function(){var t=[];for(var n in this)\"$\"===n[0]&&t.push(this[n]);return t},entries:function(){var t=[];for(var n in this)\"$\"===n[0]&&t.push({key:n.slice(1),value:this[n]});return t},size:function(){var t=0;for(var n in this)\"$\"===n[0]&&++t;return t},empty:function(){for(var t in this)if(\"$\"===t[0])return!1;return!0},each:function(t){for(var n in this)\"$\"===n[0]&&t(this[n],n.slice(1),this)}};var Bd=function(){function t(n,i,u,a){if(i>=o.length)return null!=r?r(n):null!=e?n.sort(e):n;for(var c,s,f,l=-1,h=n.length,p=o[i++],d=He(),v=u();++l<h;)(f=d.get(c=p(s=n[l])+\"\"))?f.push(s):d.set(c,[s]);return d.each(function(n,e){a(v,e,t(n,i,u,a))}),v}function n(t,e){if(++e>o.length)return t;var i,a=u[e-1];return null!=r&&e>=o.length?i=t.entries():(i=[],t.each(function(t,r){i.push({key:r,values:n(t,e)})})),null!=a?i.sort(function(t,n){return a(t.key,n.key)}):i}var e,r,i,o=[],u=[];return i={object:function(n){return t(n,0,je,Xe)},map:function(n){return t(n,0,$e,Ve)},entries:function(e){return n(t(e,0,$e,Ve),0)},key:function(t){return o.push(t),i},sortKeys:function(t){return u[o.length-1]=t,i},sortValues:function(t){return e=t,i},rollup:function(t){return r=t,i}}},Hd=He.prototype;We.prototype=Ze.prototype={constructor:We,has:Hd.has,add:function(t){return t+=\"\",this[\"$\"+t]=t,this},remove:Hd.remove,clear:Hd.clear,values:Hd.keys,size:Hd.size,empty:Hd.empty,each:Hd.each};var jd=function(t){var n=[];for(var e in t)n.push(e);return n},Xd=function(t){var n=[];for(var e in t)n.push(t[e]);return n},$d=function(t){var n=[];for(var e in t)n.push({key:e,value:t[e]});return n},Vd=function(t){function n(t,n){var r,i,o=e(t,function(t,e){if(r)return r(t,e-1);i=t,r=n?Je(t,n):Ge(t)});return o.columns=i,o}function e(t,n){function e(){if(f>=s)return u;if(i)return i=!1,o;var n,e=f;if(34===t.charCodeAt(e)){for(var r=e;r++<s;)if(34===t.charCodeAt(r)){if(34!==t.charCodeAt(r+1))break;++r}return f=r+2,n=t.charCodeAt(r+1),13===n?(i=!0,10===t.charCodeAt(r+2)&&++f):10===n&&(i=!0),t.slice(e+1,r).replace(/\"\"/g,'\"')}for(;f<s;){var a=1;if(10===(n=t.charCodeAt(f++)))i=!0;else if(13===n)i=!0,10===t.charCodeAt(f)&&(++f,++a);else if(n!==c)continue;return t.slice(e,f-a)}return t.slice(e)}for(var r,i,o={},u={},a=[],s=t.length,f=0,l=0;(r=e())!==u;){for(var h=[];r!==o&&r!==u;)h.push(r),r=e();n&&null==(h=n(h,l++))||a.push(h)}return a}function r(n,e){return null==e&&(e=Qe(n)),[e.map(u).join(t)].concat(n.map(function(n){return e.map(function(t){return u(n[t])}).join(t)})).join(\"\\n\")}function i(t){return t.map(o).join(\"\\n\")}function o(n){return n.map(u).join(t)}function u(t){return null==t?\"\":a.test(t+=\"\")?'\"'+t.replace(/\\\"/g,'\"\"')+'\"':t}var a=new RegExp('[\"'+t+\"\\n\\r]\"),c=t.charCodeAt(0);return{parse:n,parseRows:e,format:r,formatRows:i}},Wd=Vd(\",\"),Zd=Wd.parse,Gd=Wd.parseRows,Jd=Wd.format,Qd=Wd.formatRows,Kd=Vd(\"\\t\"),tv=Kd.parse,nv=Kd.parseRows,ev=Kd.format,rv=Kd.formatRows,iv=function(t,n){function e(){var e,i,o=r.length,u=0,a=0;for(e=0;e<o;++e)i=r[e],u+=i.x,a+=i.y;for(u=u/o-t,a=a/o-n,e=0;e<o;++e)i=r[e],i.x-=u,i.y-=a}var r;return null==t&&(t=0),null==n&&(n=0),e.initialize=function(t){r=t},e.x=function(n){return arguments.length?(t=+n,e):t},e.y=function(t){return arguments.length?(n=+t,e):n},e},ov=function(t){return function(){return t}},uv=function(){return 1e-6*(Math.random()-.5)},av=function(t){var n=+this._x.call(null,t),e=+this._y.call(null,t);return Ke(this.cover(n,e),n,e,t)},cv=function(t,n){if(isNaN(t=+t)||isNaN(n=+n))return this;var e=this._x0,r=this._y0,i=this._x1,o=this._y1;if(isNaN(e))i=(e=Math.floor(t))+1,o=(r=Math.floor(n))+1;else{if(!(e>t||t>i||r>n||n>o))return this;var u,a,c=i-e,s=this._root;switch(a=(n<(r+o)/2)<<1|t<(e+i)/2){case 0:do{u=new Array(4),u[a]=s,s=u}while(c*=2,i=e+c,o=r+c,t>i||n>o);break;case 1:do{u=new Array(4),u[a]=s,s=u}while(c*=2,e=i-c,o=r+c,e>t||n>o);break;case 2:do{u=new Array(4),u[a]=s,s=u}while(c*=2,i=e+c,r=o-c,t>i||r>n);break;case 3:do{u=new Array(4),u[a]=s,s=u}while(c*=2,e=i-c,r=o-c,e>t||r>n)}this._root&&this._root.length&&(this._root=s)}return this._x0=e,this._y0=r,this._x1=i,this._y1=o,this},sv=function(){var t=[];return this.visit(function(n){if(!n.length)do{t.push(n.data)}while(n=n.next)}),t},fv=function(t){return arguments.length?this.cover(+t[0][0],+t[0][1]).cover(+t[1][0],+t[1][1]):isNaN(this._x0)?void 0:[[this._x0,this._y0],[this._x1,this._y1]]},lv=function(t,n,e,r,i){this.node=t,this.x0=n,this.y0=e,this.x1=r,this.y1=i},hv=function(t,n,e){var r,i,o,u,a,c,s,f=this._x0,l=this._y0,h=this._x1,p=this._y1,d=[],v=this._root;for(v&&d.push(new lv(v,f,l,h,p)),null==e?e=1/0:(f=t-e,l=n-e,h=t+e,p=n+e,e*=e);c=d.pop();)if(!(!(v=c.node)||(i=c.x0)>h||(o=c.y0)>p||(u=c.x1)<f||(a=c.y1)<l))if(v.length){var _=(i+u)/2,y=(o+a)/2;d.push(new lv(v[3],_,y,u,a),new lv(v[2],i,y,_,a),new lv(v[1],_,o,u,y),new lv(v[0],i,o,_,y)),(s=(n>=y)<<1|t>=_)&&(c=d[d.length-1],d[d.length-1]=d[d.length-1-s],d[d.length-1-s]=c)}else{var g=t-+this._x.call(null,v.data),m=n-+this._y.call(null,v.data),x=g*g+m*m;if(x<e){var b=Math.sqrt(e=x);f=t-b,l=n-b,h=t+b,p=n+b,r=v.data}}return r},pv=function(t){if(isNaN(o=+this._x.call(null,t))||isNaN(u=+this._y.call(null,t)))return this;var n,e,r,i,o,u,a,c,s,f,l,h,p=this._root,d=this._x0,v=this._y0,_=this._x1,y=this._y1;if(!p)return this;if(p.length)for(;;){if((s=o>=(a=(d+_)/2))?d=a:_=a,(f=u>=(c=(v+y)/2))?v=c:y=c,n=p,!(p=p[l=f<<1|s]))return this;if(!p.length)break;(n[l+1&3]||n[l+2&3]||n[l+3&3])&&(e=n,h=l)}for(;p.data!==t;)if(r=p,!(p=p.next))return this;return(i=p.next)&&delete p.next,r?(i?r.next=i:delete r.next,this):n?(i?n[l]=i:delete n[l],(p=n[0]||n[1]||n[2]||n[3])&&p===(n[3]||n[2]||n[1]||n[0])&&!p.length&&(e?e[h]=p:this._root=p),this):(this._root=i,this)},dv=function(){return this._root},vv=function(){var t=0;return this.visit(function(n){if(!n.length)do{++t}while(n=n.next)}),t},_v=function(t){var n,e,r,i,o,u,a=[],c=this._root;for(c&&a.push(new lv(c,this._x0,this._y0,this._x1,this._y1));n=a.pop();)if(!t(c=n.node,r=n.x0,i=n.y0,o=n.x1,u=n.y1)&&c.length){var s=(r+o)/2,f=(i+u)/2;(e=c[3])&&a.push(new lv(e,s,f,o,u)),(e=c[2])&&a.push(new lv(e,r,f,s,u)),(e=c[1])&&a.push(new lv(e,s,i,o,f)),(e=c[0])&&a.push(new lv(e,r,i,s,f))}return this},yv=function(t){var n,e=[],r=[];for(this._root&&e.push(new lv(this._root,this._x0,this._y0,this._x1,this._y1));n=e.pop();){var i=n.node;if(i.length){var o,u=n.x0,a=n.y0,c=n.x1,s=n.y1,f=(u+c)/2,l=(a+s)/2;(o=i[0])&&e.push(new lv(o,u,a,f,l)),(o=i[1])&&e.push(new lv(o,f,a,c,l)),(o=i[2])&&e.push(new lv(o,u,l,f,s)),(o=i[3])&&e.push(new lv(o,f,l,c,s))}r.push(n)}for(;n=r.pop();)t(n.node,n.x0,n.y0,n.x1,n.y1);return this},gv=function(t){return arguments.length?(this._x=t,this):this._x},mv=function(t){return arguments.length?(this._y=t,this):this._y},xv=ir.prototype=or.prototype;xv.copy=function(){var t,n,e=new or(this._x,this._y,this._x0,this._y0,this._x1,this._y1),r=this._root;if(!r)return e;if(!r.length)return e._root=ur(r),e;for(t=[{source:r,target:e._root=new Array(4)}];r=t.pop();)for(var i=0;i<4;++i)(n=r.source[i])&&(n.length?t.push({source:n,target:r.target[i]=new Array(4)}):r.target[i]=ur(n));return e},xv.add=av,xv.addAll=tr,xv.cover=cv,xv.data=sv,xv.extent=fv,xv.find=hv,xv.remove=pv,xv.removeAll=nr,xv.root=dv,xv.size=vv,xv.visit=_v,xv.visitAfter=yv,xv.x=gv,xv.y=mv;var bv,wv=function(t){function n(){function t(t,n,e,r,i){var o=t.data,a=t.r,p=l+a;{if(!o)return n>s+p||r<s-p||e>f+p||i<f-p;if(o.index>c.index){var d=s-o.x-o.vx,v=f-o.y-o.vy,_=d*d+v*v;_<p*p&&(0===d&&(d=uv(),_+=d*d),0===v&&(v=uv(),_+=v*v),_=(p-(_=Math.sqrt(_)))/_*u,c.vx+=(d*=_)*(p=(a*=a)/(h+a)),c.vy+=(v*=_)*p,o.vx-=d*(p=1-p),o.vy-=v*p)}}}for(var n,r,c,s,f,l,h,p=i.length,d=0;d<a;++d)for(r=ir(i,ar,cr).visitAfter(e),n=0;n<p;++n)c=i[n],l=o[c.index],h=l*l,s=c.x+c.vx,f=c.y+c.vy,r.visit(t)}function e(t){if(t.data)return t.r=o[t.data.index];for(var n=t.r=0;n<4;++n)t[n]&&t[n].r>t.r&&(t.r=t[n].r)}function r(){if(i){var n,e,r=i.length;for(o=new Array(r),n=0;n<r;++n)e=i[n],o[e.index]=+t(e,n,i)}}var i,o,u=1,a=1\n;return\"function\"!=typeof t&&(t=ov(null==t?1:+t)),n.initialize=function(t){i=t,r()},n.iterations=function(t){return arguments.length?(a=+t,n):a},n.strength=function(t){return arguments.length?(u=+t,n):u},n.radius=function(e){return arguments.length?(t=\"function\"==typeof e?e:ov(+e),r(),n):t},n},Mv=function(t){function n(t){return 1/Math.min(s[t.source.index],s[t.target.index])}function e(n){for(var e=0,r=t.length;e<d;++e)for(var i,o,c,s,l,h,p,v=0;v<r;++v)i=t[v],o=i.source,c=i.target,s=c.x+c.vx-o.x-o.vx||uv(),l=c.y+c.vy-o.y-o.vy||uv(),h=Math.sqrt(s*s+l*l),h=(h-a[v])/h*n*u[v],s*=h,l*=h,c.vx-=s*(p=f[v]),c.vy-=l*p,o.vx+=s*(p=1-p),o.vy+=l*p}function r(){if(c){var n,e,r=c.length,h=t.length,p=He(c,l);for(n=0,s=new Array(r);n<h;++n)e=t[n],e.index=n,\"object\"!=typeof e.source&&(e.source=fr(p,e.source)),\"object\"!=typeof e.target&&(e.target=fr(p,e.target)),s[e.source.index]=(s[e.source.index]||0)+1,s[e.target.index]=(s[e.target.index]||0)+1;for(n=0,f=new Array(h);n<h;++n)e=t[n],f[n]=s[e.source.index]/(s[e.source.index]+s[e.target.index]);u=new Array(h),i(),a=new Array(h),o()}}function i(){if(c)for(var n=0,e=t.length;n<e;++n)u[n]=+h(t[n],n,t)}function o(){if(c)for(var n=0,e=t.length;n<e;++n)a[n]=+p(t[n],n,t)}var u,a,c,s,f,l=sr,h=n,p=ov(30),d=1;return null==t&&(t=[]),e.initialize=function(t){c=t,r()},e.links=function(n){return arguments.length?(t=n,r(),e):t},e.id=function(t){return arguments.length?(l=t,e):l},e.iterations=function(t){return arguments.length?(d=+t,e):d},e.strength=function(t){return arguments.length?(h=\"function\"==typeof t?t:ov(+t),i(),e):h},e.distance=function(t){return arguments.length?(p=\"function\"==typeof t?t:ov(+t),o(),e):p},e},Tv=10,kv=Math.PI*(3-Math.sqrt(5)),Nv=function(t){function n(){e(),p.call(\"tick\",o),u<a&&(h.stop(),p.call(\"end\",o))}function e(){var n,e,r=t.length;for(u+=(s-u)*c,l.each(function(t){t(u)}),n=0;n<r;++n)e=t[n],null==e.fx?e.x+=e.vx*=f:(e.x=e.fx,e.vx=0),null==e.fy?e.y+=e.vy*=f:(e.y=e.fy,e.vy=0)}function r(){for(var n,e=0,r=t.length;e<r;++e){if(n=t[e],n.index=e,isNaN(n.x)||isNaN(n.y)){var i=Tv*Math.sqrt(e),o=e*kv;n.x=i*Math.cos(o),n.y=i*Math.sin(o)}(isNaN(n.vx)||isNaN(n.vy))&&(n.vx=n.vy=0)}}function i(n){return n.initialize&&n.initialize(t),n}var o,u=1,a=.001,c=1-Math.pow(a,1/300),s=0,f=.6,l=He(),h=mn(n),p=v(\"tick\",\"end\");return null==t&&(t=[]),r(),o={tick:e,restart:function(){return h.restart(n),o},stop:function(){return h.stop(),o},nodes:function(n){return arguments.length?(t=n,r(),l.each(i),o):t},alpha:function(t){return arguments.length?(u=+t,o):u},alphaMin:function(t){return arguments.length?(a=+t,o):a},alphaDecay:function(t){return arguments.length?(c=+t,o):+c},alphaTarget:function(t){return arguments.length?(s=+t,o):s},velocityDecay:function(t){return arguments.length?(f=1-t,o):1-f},force:function(t,n){return arguments.length>1?(null==n?l.remove(t):l.set(t,i(n)),o):l.get(t)},find:function(n,e,r){var i,o,u,a,c,s=0,f=t.length;for(null==r?r=1/0:r*=r,s=0;s<f;++s)a=t[s],i=n-a.x,o=e-a.y,(u=i*i+o*o)<r&&(c=a,r=u);return c},on:function(t,n){return arguments.length>1?(p.on(t,n),o):p.on(t)}}},Sv=function(){function t(t){var n,a=i.length,c=ir(i,lr,hr).visitAfter(e);for(u=t,n=0;n<a;++n)o=i[n],c.visit(r)}function n(){if(i){var t,n,e=i.length;for(a=new Array(e),t=0;t<e;++t)n=i[t],a[n.index]=+c(n,t,i)}}function e(t){var n,e,r,i,o,u=0;if(t.length){for(r=i=o=0;o<4;++o)(n=t[o])&&(e=n.value)&&(u+=e,r+=e*n.x,i+=e*n.y);t.x=r/u,t.y=i/u}else{n=t,n.x=n.data.x,n.y=n.data.y;do{u+=a[n.data.index]}while(n=n.next)}t.value=u}function r(t,n,e,r){if(!t.value)return!0;var i=t.x-o.x,c=t.y-o.y,h=r-n,p=i*i+c*c;if(h*h/l<p)return p<f&&(0===i&&(i=uv(),p+=i*i),0===c&&(c=uv(),p+=c*c),p<s&&(p=Math.sqrt(s*p)),o.vx+=i*t.value*u/p,o.vy+=c*t.value*u/p),!0;if(!(t.length||p>=f)){(t.data!==o||t.next)&&(0===i&&(i=uv(),p+=i*i),0===c&&(c=uv(),p+=c*c),p<s&&(p=Math.sqrt(s*p)));do{t.data!==o&&(h=a[t.data.index]*u/p,o.vx+=i*h,o.vy+=c*h)}while(t=t.next)}}var i,o,u,a,c=ov(-30),s=1,f=1/0,l=.81;return t.initialize=function(t){i=t,n()},t.strength=function(e){return arguments.length?(c=\"function\"==typeof e?e:ov(+e),n(),t):c},t.distanceMin=function(n){return arguments.length?(s=n*n,t):Math.sqrt(s)},t.distanceMax=function(n){return arguments.length?(f=n*n,t):Math.sqrt(f)},t.theta=function(n){return arguments.length?(l=n*n,t):Math.sqrt(l)},t},Ev=function(t){function n(t){for(var n,e=0,u=r.length;e<u;++e)n=r[e],n.vx+=(o[e]-n.x)*i[e]*t}function e(){if(r){var n,e=r.length;for(i=new Array(e),o=new Array(e),n=0;n<e;++n)i[n]=isNaN(o[n]=+t(r[n],n,r))?0:+u(r[n],n,r)}}var r,i,o,u=ov(.1);return\"function\"!=typeof t&&(t=ov(null==t?0:+t)),n.initialize=function(t){r=t,e()},n.strength=function(t){return arguments.length?(u=\"function\"==typeof t?t:ov(+t),e(),n):u},n.x=function(r){return arguments.length?(t=\"function\"==typeof r?r:ov(+r),e(),n):t},n},Av=function(t){function n(t){for(var n,e=0,u=r.length;e<u;++e)n=r[e],n.vy+=(o[e]-n.y)*i[e]*t}function e(){if(r){var n,e=r.length;for(i=new Array(e),o=new Array(e),n=0;n<e;++n)i[n]=isNaN(o[n]=+t(r[n],n,r))?0:+u(r[n],n,r)}}var r,i,o,u=ov(.1);return\"function\"!=typeof t&&(t=ov(null==t?0:+t)),n.initialize=function(t){r=t,e()},n.strength=function(t){return arguments.length?(u=\"function\"==typeof t?t:ov(+t),e(),n):u},n.y=function(r){return arguments.length?(t=\"function\"==typeof r?r:ov(+r),e(),n):t},n},Cv=function(t,n){if((e=(t=n?t.toExponential(n-1):t.toExponential()).indexOf(\"e\"))<0)return null;var e,r=t.slice(0,e);return[r.length>1?r[0]+r.slice(2):r,+t.slice(e+1)]},zv=function(t){return t=Cv(Math.abs(t)),t?t[1]:NaN},Pv=function(t,n){return function(e,r){for(var i=e.length,o=[],u=0,a=t[0],c=0;i>0&&a>0&&(c+a+1>r&&(a=Math.max(1,r-c)),o.push(e.substring(i-=a,i+a)),!((c+=a+1)>r));)a=t[u=(u+1)%t.length];return o.reverse().join(n)}},Lv=function(t){return function(n){return n.replace(/[0-9]/g,function(n){return t[+n]})}},Rv=function(t,n){t=t.toPrecision(n);t:for(var e,r=t.length,i=1,o=-1;i<r;++i)switch(t[i]){case\".\":o=e=i;break;case\"0\":0===o&&(o=i),e=i;break;case\"e\":break t;default:o>0&&(o=0)}return o>0?t.slice(0,o)+t.slice(e+1):t},qv=function(t,n){var e=Cv(t,n);if(!e)return t+\"\";var r=e[0],i=e[1],o=i-(bv=3*Math.max(-8,Math.min(8,Math.floor(i/3))))+1,u=r.length;return o===u?r:o>u?r+new Array(o-u+1).join(\"0\"):o>0?r.slice(0,o)+\".\"+r.slice(o):\"0.\"+new Array(1-o).join(\"0\")+Cv(t,Math.max(0,n+o-1))[0]},Uv=function(t,n){var e=Cv(t,n);if(!e)return t+\"\";var r=e[0],i=e[1];return i<0?\"0.\"+new Array(-i).join(\"0\")+r:r.length>i+1?r.slice(0,i+1)+\".\"+r.slice(i+1):r+new Array(i-r.length+2).join(\"0\")},Dv={\"\":Rv,\"%\":function(t,n){return(100*t).toFixed(n)},b:function(t){return Math.round(t).toString(2)},c:function(t){return t+\"\"},d:function(t){return Math.round(t).toString(10)},e:function(t,n){return t.toExponential(n)},f:function(t,n){return t.toFixed(n)},g:function(t,n){return t.toPrecision(n)},o:function(t){return Math.round(t).toString(8)},p:function(t,n){return Uv(100*t,n)},r:Uv,s:qv,X:function(t){return Math.round(t).toString(16).toUpperCase()},x:function(t){return Math.round(t).toString(16)}},Ov=/^(?:(.)?([<>=^]))?([+\\-\\( ])?([$#])?(0)?(\\d+)?(,)?(\\.\\d+)?([a-z%])?$/i;pr.prototype=dr.prototype,dr.prototype.toString=function(){return this.fill+this.align+this.sign+this.symbol+(this.zero?\"0\":\"\")+(null==this.width?\"\":Math.max(1,0|this.width))+(this.comma?\",\":\"\")+(null==this.precision?\"\":\".\"+Math.max(0,0|this.precision))+this.type};var Fv,Iv=function(t){return t},Yv=[\"y\",\"z\",\"a\",\"f\",\"p\",\"n\",\"µ\",\"m\",\"\",\"k\",\"M\",\"G\",\"T\",\"P\",\"E\",\"Z\",\"Y\"],Bv=function(t){function n(t){function n(t){var n,i,a,f=_,x=y;if(\"c\"===v)x=g(t)+x,t=\"\";else{t=+t;var b=t<0;if(t=g(Math.abs(t),d),b&&0==+t&&(b=!1),f=(b?\"(\"===s?s:\"-\":\"-\"===s||\"(\"===s?\"\":s)+f,x=x+(\"s\"===v?Yv[8+bv/3]:\"\")+(b&&\"(\"===s?\")\":\"\"),m)for(n=-1,i=t.length;++n<i;)if(48>(a=t.charCodeAt(n))||a>57){x=(46===a?o+t.slice(n+1):t.slice(n))+x,t=t.slice(0,n);break}}p&&!l&&(t=r(t,1/0));var w=f.length+t.length+x.length,M=w<h?new Array(h-w+1).join(e):\"\";switch(p&&l&&(t=r(M+t,M.length?h-x.length:1/0),M=\"\"),c){case\"<\":t=f+t+x+M;break;case\"=\":t=f+M+t+x;break;case\"^\":t=M.slice(0,w=M.length>>1)+f+t+x+M.slice(w);break;default:t=M+f+t+x}return u(t)}t=pr(t);var e=t.fill,c=t.align,s=t.sign,f=t.symbol,l=t.zero,h=t.width,p=t.comma,d=t.precision,v=t.type,_=\"$\"===f?i[0]:\"#\"===f&&/[boxX]/.test(v)?\"0\"+v.toLowerCase():\"\",y=\"$\"===f?i[1]:/[%p]/.test(v)?a:\"\",g=Dv[v],m=!v||/[defgprs%]/.test(v);return d=null==d?v?6:12:/[gprs]/.test(v)?Math.max(1,Math.min(21,d)):Math.max(0,Math.min(20,d)),n.toString=function(){return t+\"\"},n}function e(t,e){var r=n((t=pr(t),t.type=\"f\",t)),i=3*Math.max(-8,Math.min(8,Math.floor(zv(e)/3))),o=Math.pow(10,-i),u=Yv[8+i/3];return function(t){return r(o*t)+u}}var r=t.grouping&&t.thousands?Pv(t.grouping,t.thousands):Iv,i=t.currency,o=t.decimal,u=t.numerals?Lv(t.numerals):Iv,a=t.percent||\"%\";return{format:n,formatPrefix:e}};vr({decimal:\".\",thousands:\",\",grouping:[3],currency:[\"$\",\"\"]});var Hv=function(t){return Math.max(0,-zv(Math.abs(t)))},jv=function(t,n){return Math.max(0,3*Math.max(-8,Math.min(8,Math.floor(zv(n)/3)))-zv(Math.abs(t)))},Xv=function(t,n){return t=Math.abs(t),n=Math.abs(n)-t,Math.max(0,zv(n)-zv(t))+1},$v=function(){return new _r};_r.prototype={constructor:_r,reset:function(){this.s=this.t=0},add:function(t){yr(T_,t,this.t),yr(this,T_.s,this.s),this.s?this.t+=T_.t:this.s=T_.t},valueOf:function(){return this.s}};var Vv,Wv,Zv,Gv,Jv,Qv,Kv,t_,n_,e_,r_,i_,o_,u_,a_,c_,s_,f_,l_,h_,p_,d_,v_,__,y_,g_,m_,x_,b_,w_,M_,T_=new _r,k_=1e-6,N_=Math.PI,S_=N_/2,E_=N_/4,A_=2*N_,C_=180/N_,z_=N_/180,P_=Math.abs,L_=Math.atan,R_=Math.atan2,q_=Math.cos,U_=Math.ceil,D_=Math.exp,O_=Math.log,F_=Math.pow,I_=Math.sin,Y_=Math.sign||function(t){return t>0?1:t<0?-1:0},B_=Math.sqrt,H_=Math.tan,j_={Feature:function(t,n){wr(t.geometry,n)},FeatureCollection:function(t,n){for(var e=t.features,r=-1,i=e.length;++r<i;)wr(e[r].geometry,n)}},X_={Sphere:function(t,n){n.sphere()},Point:function(t,n){t=t.coordinates,n.point(t[0],t[1],t[2])},MultiPoint:function(t,n){for(var e=t.coordinates,r=-1,i=e.length;++r<i;)t=e[r],n.point(t[0],t[1],t[2])},LineString:function(t,n){Mr(t.coordinates,n,0)},MultiLineString:function(t,n){for(var e=t.coordinates,r=-1,i=e.length;++r<i;)Mr(e[r],n,0)},Polygon:function(t,n){Tr(t.coordinates,n)},MultiPolygon:function(t,n){for(var e=t.coordinates,r=-1,i=e.length;++r<i;)Tr(e[r],n)},GeometryCollection:function(t,n){for(var e=t.geometries,r=-1,i=e.length;++r<i;)wr(e[r],n)}},$_=function(t,n){t&&j_.hasOwnProperty(t.type)?j_[t.type](t,n):wr(t,n)},V_=$v(),W_=$v(),Z_={point:br,lineStart:br,lineEnd:br,polygonStart:function(){V_.reset(),Z_.lineStart=kr,Z_.lineEnd=Nr},polygonEnd:function(){var t=+V_;W_.add(t<0?A_+t:t),this.lineStart=this.lineEnd=this.point=br},sphere:function(){W_.add(A_)}},G_=function(t){return W_.reset(),$_(t,Z_),2*W_},J_=$v(),Q_={point:Ur,lineStart:Or,lineEnd:Fr,polygonStart:function(){Q_.point=Ir,Q_.lineStart=Yr,Q_.lineEnd=Br,J_.reset(),Z_.polygonStart()},polygonEnd:function(){Z_.polygonEnd(),Q_.point=Ur,Q_.lineStart=Or,Q_.lineEnd=Fr,V_<0?(Qv=-(t_=180),Kv=-(n_=90)):J_>k_?n_=90:J_<-k_&&(Kv=-90),a_[0]=Qv,a_[1]=t_}},K_=function(t){var n,e,r,i,o,u,a;if(n_=t_=-(Qv=Kv=1/0),u_=[],$_(t,Q_),e=u_.length){for(u_.sort(jr),n=1,r=u_[0],o=[r];n<e;++n)i=u_[n],Xr(r,i[0])||Xr(r,i[1])?(Hr(r[0],i[1])>Hr(r[0],r[1])&&(r[1]=i[1]),Hr(i[0],r[1])>Hr(r[0],r[1])&&(r[0]=i[0])):o.push(r=i);for(u=-1/0,e=o.length-1,n=0,r=o[e];n<=e;r=i,++n)i=o[n],(a=Hr(r[1],i[0]))>u&&(u=a,Qv=i[0],t_=r[1])}return u_=a_=null,Qv===1/0||Kv===1/0?[[NaN,NaN],[NaN,NaN]]:[[Qv,Kv],[t_,n_]]},ty={sphere:br,point:$r,lineStart:Wr,lineEnd:Jr,polygonStart:function(){ty.lineStart=Qr,ty.lineEnd=Kr},polygonEnd:function(){ty.lineStart=Wr,ty.lineEnd=Jr}},ny=function(t){c_=s_=f_=l_=h_=p_=d_=v_=__=y_=g_=0,$_(t,ty);var n=__,e=y_,r=g_,i=n*n+e*e+r*r;return i<1e-12&&(n=p_,e=d_,r=v_,s_<k_&&(n=f_,e=l_,r=h_),(i=n*n+e*e+r*r)<1e-12)?[NaN,NaN]:[R_(e,n)*C_,mr(r/B_(i))*C_]},ey=function(t){return function(){return t}},ry=function(t,n){function e(e,r){return e=t(e,r),n(e[0],e[1])}return t.invert&&n.invert&&(e.invert=function(e,r){return(e=n.invert(e,r))&&t.invert(e[0],e[1])}),e};ei.invert=ei;var iy,oy,uy,ay,cy,sy,fy,ly,hy,py,dy,vy=function(t){function n(n){return n=t(n[0]*z_,n[1]*z_),n[0]*=C_,n[1]*=C_,n}return t=ri(t[0]*z_,t[1]*z_,t.length>2?t[2]*z_:0),n.invert=function(n){return n=t.invert(n[0]*z_,n[1]*z_),n[0]*=C_,n[1]*=C_,n},n},_y=function(){function t(t,n){e.push(t=r(t,n)),t[0]*=C_,t[1]*=C_}function n(){var t=i.apply(this,arguments),n=o.apply(this,arguments)*z_,c=u.apply(this,arguments)*z_;return e=[],r=ri(-t[0]*z_,-t[1]*z_,0).invert,ai(a,n,c,1),t={type:\"Polygon\",coordinates:[e]},e=r=null,t}var e,r,i=ey([0,0]),o=ey(90),u=ey(6),a={point:t};return n.center=function(t){return arguments.length?(i=\"function\"==typeof t?t:ey([+t[0],+t[1]]),n):i},n.radius=function(t){return arguments.length?(o=\"function\"==typeof t?t:ey(+t),n):o},n.precision=function(t){return arguments.length?(u=\"function\"==typeof t?t:ey(+t),n):u},n},yy=function(){var t,n=[];return{point:function(n,e){t.push([n,e])},lineStart:function(){n.push(t=[])},lineEnd:br,rejoin:function(){n.length>1&&n.push(n.pop().concat(n.shift()))},result:function(){var e=n;return n=[],t=null,e}}},gy=function(t,n,e,r,i,o){var u,a=t[0],c=t[1],s=n[0],f=n[1],l=0,h=1,p=s-a,d=f-c;if(u=e-a,p||!(u>0)){if(u/=p,p<0){if(u<l)return;u<h&&(h=u)}else if(p>0){if(u>h)return;u>l&&(l=u)}if(u=i-a,p||!(u<0)){if(u/=p,p<0){if(u>h)return;u>l&&(l=u)}else if(p>0){if(u<l)return;u<h&&(h=u)}if(u=r-c,d||!(u>0)){if(u/=d,d<0){if(u<l)return;u<h&&(h=u)}else if(d>0){if(u>h)return;u>l&&(l=u)}if(u=o-c,d||!(u<0)){if(u/=d,d<0){if(u>h)return;u>l&&(l=u)}else if(d>0){if(u<l)return;u<h&&(h=u)}return l>0&&(t[0]=a+l*p,t[1]=c+l*d),h<1&&(n[0]=a+h*p,n[1]=c+h*d),!0}}}}},my=function(t,n){return P_(t[0]-n[0])<k_&&P_(t[1]-n[1])<k_},xy=function(t,n,e,r,i){var o,u,a=[],c=[];if(t.forEach(function(t){if(!((n=t.length-1)<=0)){var n,e,r=t[0],u=t[n];if(my(r,u)){for(i.lineStart(),o=0;o<n;++o)i.point((r=t[o])[0],r[1]);return void i.lineEnd()}a.push(e=new si(r,t,null,!0)),c.push(e.o=new si(r,null,e,!1)),a.push(e=new si(u,t,null,!1)),c.push(e.o=new si(u,null,e,!0))}}),a.length){for(c.sort(n),fi(a),fi(c),o=0,u=c.length;o<u;++o)c[o].e=e=!e;for(var s,f,l=a[0];;){for(var h=l,p=!0;h.v;)if((h=h.n)===l)return;s=h.z,i.lineStart();do{if(h.v=h.o.v=!0,h.e){if(p)for(o=0,u=s.length;o<u;++o)i.point((f=s[o])[0],f[1]);else r(h.x,h.n.x,1,i);h=h.n}else{if(p)for(s=h.p.z,o=s.length-1;o>=0;--o)i.point((f=s[o])[0],f[1]);else r(h.x,h.p.x,-1,i);h=h.p}h=h.o,s=h.z,p=!p}while(!h.v);i.lineEnd()}}},by=1e9,wy=-by,My=function(){var t,n,e,r=0,i=0,o=960,u=500;return e={stream:function(e){return t&&n===e?t:t=li(r,i,o,u)(n=e)},extent:function(a){return arguments.length?(r=+a[0][0],i=+a[0][1],o=+a[1][0],u=+a[1][1],t=n=null,e):[[r,i],[o,u]]}}},Ty=$v(),ky=function(t,n){var e=n[0],r=n[1],i=[I_(e),-q_(e),0],o=0,u=0;Ty.reset();for(var a=0,c=t.length;a<c;++a)if(f=(s=t[a]).length)for(var s,f,l=s[f-1],h=l[0],p=l[1]/2+E_,d=I_(p),v=q_(p),_=0;_<f;++_,h=g,d=x,v=b,l=y){var y=s[_],g=y[0],m=y[1]/2+E_,x=I_(m),b=q_(m),w=g-h,M=w>=0?1:-1,T=M*w,k=T>N_,N=d*x;if(Ty.add(R_(N*M*I_(T),v*b+N*q_(T))),o+=k?w+M*A_:w,k^h>=e^g>=e){var S=Pr(Cr(l),Cr(y));qr(S);var E=Pr(i,S);qr(E);var A=(k^w>=0?-1:1)*mr(E[2]);(r>A||r===A&&(S[0]||S[1]))&&(u+=k^w>=0?1:-1)}}return(o<-k_||o<k_&&Ty<-k_)^1&u},Ny=$v(),Sy={sphere:br,point:br,lineStart:hi,lineEnd:br,polygonStart:br,polygonEnd:br},Ey=function(t){return Ny.reset(),$_(t,Sy),+Ny},Ay=[null,null],Cy={type:\"LineString\",coordinates:Ay},zy=function(t,n){return Ay[0]=t,Ay[1]=n,Ey(Cy)},Py={Feature:function(t,n){return _i(t.geometry,n)},FeatureCollection:function(t,n){for(var e=t.features,r=-1,i=e.length;++r<i;)if(_i(e[r].geometry,n))return!0;return!1}},Ly={Sphere:function(){return!0},Point:function(t,n){return yi(t.coordinates,n)},MultiPoint:function(t,n){for(var e=t.coordinates,r=-1,i=e.length;++r<i;)if(yi(e[r],n))return!0;return!1},LineString:function(t,n){return gi(t.coordinates,n)},MultiLineString:function(t,n){for(var e=t.coordinates,r=-1,i=e.length;++r<i;)if(gi(e[r],n))return!0;return!1},Polygon:function(t,n){return mi(t.coordinates,n)},MultiPolygon:function(t,n){for(var e=t.coordinates,r=-1,i=e.length;++r<i;)if(mi(e[r],n))return!0;return!1},GeometryCollection:function(t,n){for(var e=t.geometries,r=-1,i=e.length;++r<i;)if(_i(e[r],n))return!0;return!1}},Ry=function(t,n){return(t&&Py.hasOwnProperty(t.type)?Py[t.type]:_i)(t,n)},qy=function(t,n){var e=t[0]*z_,r=t[1]*z_,i=n[0]*z_,o=n[1]*z_,u=q_(r),a=I_(r),c=q_(o),s=I_(o),f=u*q_(e),l=u*I_(e),h=c*q_(i),p=c*I_(i),d=2*mr(B_(xr(o-r)+u*c*xr(i-e))),v=I_(d),_=d?function(t){var n=I_(t*=d)/v,e=I_(d-t)/v,r=e*f+n*h,i=e*l+n*p,o=e*a+n*s;return[R_(i,r)*C_,R_(o,B_(r*r+i*i))*C_]}:function(){return[e*C_,r*C_]};return _.distance=d,_},Uy=function(t){return t},Dy=$v(),Oy=$v(),Fy={point:br,lineStart:br,lineEnd:br,polygonStart:function(){Fy.lineStart=Ni,Fy.lineEnd=Ai},polygonEnd:function(){Fy.lineStart=Fy.lineEnd=Fy.point=br,Dy.add(P_(Oy)),Oy.reset()},result:function(){var t=Dy/2;return Dy.reset(),t}},Iy=1/0,Yy=Iy,By=-Iy,Hy=By,jy={point:Ci,lineStart:br,lineEnd:br,polygonStart:br,polygonEnd:br,result:function(){var t=[[Iy,Yy],[By,Hy]];return By=Hy=-(Yy=Iy=1/0),t}},Xy=0,$y=0,Vy=0,Wy=0,Zy=0,Gy=0,Jy=0,Qy=0,Ky=0,tg={point:zi,lineStart:Pi,lineEnd:qi,polygonStart:function(){tg.lineStart=Ui,tg.lineEnd=Di},polygonEnd:function(){tg.point=zi,tg.lineStart=Pi,tg.lineEnd=qi},result:function(){var t=Ky?[Jy/Ky,Qy/Ky]:Gy?[Wy/Gy,Zy/Gy]:Vy?[Xy/Vy,$y/Vy]:[NaN,NaN];return Xy=$y=Vy=Wy=Zy=Gy=Jy=Qy=Ky=0,t}};Ii.prototype={_radius:4.5,pointRadius:function(t){return this._radius=t,this},polygonStart:function(){this._line=0},polygonEnd:function(){this._line=NaN},lineStart:function(){this._point=0},lineEnd:function(){0===this._line&&this._context.closePath(),this._point=NaN},point:function(t,n){switch(this._point){case 0:this._context.moveTo(t,n),this._point=1;break;case 1:this._context.lineTo(t,n);break;default:this._context.moveTo(t+this._radius,n),this._context.arc(t,n,this._radius,0,A_)}},result:br};var ng,eg,rg,ig,og,ug=$v(),ag={point:br,lineStart:function(){ag.point=Yi},lineEnd:function(){ng&&Bi(eg,rg),ag.point=br},polygonStart:function(){ng=!0},polygonEnd:function(){ng=null},result:function(){var t=+ug;return ug.reset(),t}};Hi.prototype={_radius:4.5,_circle:ji(4.5),pointRadius:function(t){return(t=+t)!==this._radius&&(this._radius=t,this._circle=null),this},polygonStart:function(){this._line=0},polygonEnd:function(){this._line=NaN},lineStart:function(){this._point=0},lineEnd:function(){0===this._line&&this._string.push(\"Z\"),this._point=NaN},point:function(t,n){switch(this._point){case 0:this._string.push(\"M\",t,\",\",n),this._point=1;break;case 1:this._string.push(\"L\",t,\",\",n);break;default:null==this._circle&&(this._circle=ji(this._radius)),this._string.push(\"M\",t,\",\",n,this._circle)}},result:function(){if(this._string.length){var t=this._string.join(\"\");return this._string=[],t}return null}};var cg=function(t,n){function e(t){return t&&(\"function\"==typeof o&&i.pointRadius(+o.apply(this,arguments)),$_(t,r(i))),i.result()}var r,i,o=4.5;return e.area=function(t){return $_(t,r(Fy)),Fy.result()},e.measure=function(t){return $_(t,r(ag)),ag.result()},e.bounds=function(t){return $_(t,r(jy)),jy.result()},e.centroid=function(t){return $_(t,r(tg)),tg.result()},e.projection=function(n){return arguments.length?(r=null==n?(t=null,Uy):(t=n).stream,e):t},e.context=function(t){return arguments.length?(i=null==t?(n=null,new Hi):new Ii(n=t),\"function\"!=typeof o&&i.pointRadius(o),e):n},e.pointRadius=function(t){return arguments.length?(o=\"function\"==typeof t?t:(i.pointRadius(+t),+t),e):o},e.projection(t).context(n)},sg=function(t,n,e,r){return function(i,o){function u(n,e){var r=i(n,e);t(n=r[0],e=r[1])&&o.point(n,e)}function a(t,n){var e=i(t,n);_.point(e[0],e[1])}function c(){b.point=a,_.lineStart()}function s(){b.point=u,_.lineEnd()}function f(t,n){v.push([t,n]);var e=i(t,n);m.point(e[0],e[1])}function l(){m.lineStart(),v=[]}function h(){f(v[0][0],v[0][1]),m.lineEnd();var t,n,e,r,i=m.clean(),u=g.result(),a=u.length;if(v.pop(),p.push(v),v=null,a)if(1&i){if(e=u[0],(n=e.length-1)>0){for(x||(o.polygonStart(),x=!0),o.lineStart(),t=0;t<n;++t)o.point((r=e[t])[0],r[1]);o.lineEnd()}}else a>1&&2&i&&u.push(u.pop().concat(u.shift())),d.push(u.filter(Xi))}var p,d,v,_=n(o),y=i.invert(r[0],r[1]),g=yy(),m=n(g),x=!1,b={point:u,lineStart:c,lineEnd:s,polygonStart:function(){b.point=f,b.lineStart=l,b.lineEnd=h,d=[],p=[]},polygonEnd:function(){b.point=u,b.lineStart=c,b.lineEnd=s,d=bf(d);var t=ky(p,y);d.length?(x||(o.polygonStart(),x=!0),xy(d,$i,t,e,o)):t&&(x||(o.polygonStart(),x=!0),o.lineStart(),e(null,null,1,o),o.lineEnd()),x&&(o.polygonEnd(),x=!1),d=p=null},sphere:function(){o.polygonStart(),o.lineStart(),e(null,null,1,o),o.lineEnd(),o.polygonEnd()}};return b}},fg=sg(function(){return!0},Vi,Zi,[-N_,-S_]),lg=function(t,n){function e(e,r,i,o){ai(o,t,n,i,e,r)}function r(t,n){return q_(t)*q_(n)>a}function i(t){var n,e,i,a,f;return{lineStart:function(){a=i=!1,f=1},point:function(l,h){var p,d=[l,h],v=r(l,h),_=c?v?0:u(l,h):v?u(l+(l<0?N_:-N_),h):0;if(!n&&(a=i=v)&&t.lineStart(),v!==i&&(!(p=o(n,d))||my(n,p)||my(d,p))&&(d[0]+=k_,d[1]+=k_,v=r(d[0],d[1])),v!==i)f=0,v?(t.lineStart(),p=o(d,n),t.point(p[0],p[1])):(p=o(n,d),t.point(p[0],p[1]),t.lineEnd()),n=p;else if(s&&n&&c^v){var y;_&e||!(y=o(d,n,!0))||(f=0,c?(t.lineStart(),t.point(y[0][0],y[0][1]),t.point(y[1][0],y[1][1]),t.lineEnd()):(t.point(y[1][0],y[1][1]),t.lineEnd(),t.lineStart(),t.point(y[0][0],y[0][1])))}!v||n&&my(n,d)||t.point(d[0],d[1]),n=d,i=v,e=_},lineEnd:function(){i&&t.lineEnd(),n=null},clean:function(){return f|(a&&i)<<1}}}function o(t,n,e){var r=Cr(t),i=Cr(n),o=[1,0,0],u=Pr(r,i),c=zr(u,u),s=u[0],f=c-s*s;if(!f)return!e&&t;var l=a*c/f,h=-a*s/f,p=Pr(o,u),d=Rr(o,l);Lr(d,Rr(u,h));var v=p,_=zr(d,v),y=zr(v,v),g=_*_-y*(zr(d,d)-1);if(!(g<0)){var m=B_(g),x=Rr(v,(-_-m)/y);if(Lr(x,d),x=Ar(x),!e)return x;var b,w=t[0],M=n[0],T=t[1],k=n[1];M<w&&(b=w,w=M,M=b);var N=M-w,S=P_(N-N_)<k_,E=S||N<k_;if(!S&&k<T&&(b=T,T=k,k=b),E?S?T+k>0^x[1]<(P_(x[0]-w)<k_?T:k):T<=x[1]&&x[1]<=k:N>N_^(w<=x[0]&&x[0]<=M)){var A=Rr(v,(-_+m)/y);return Lr(A,d),[x,Ar(A)]}}}function u(n,e){var r=c?t:N_-t,i=0;return n<-r?i|=1:n>r&&(i|=2),e<-r?i|=4:e>r&&(i|=8),i}var a=q_(t),c=a>0,s=P_(a)>k_;return sg(r,i,e,c?[0,-t]:[-N_,t-N_])},hg=function(t){return{stream:Gi(t)}};Ji.prototype={constructor:Ji,point:function(t,n){this.stream.point(t,n)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}};var pg=16,dg=q_(30*z_),vg=function(t,n){return+n?no(t,n):to(t)},_g=Gi({point:function(t,n){this.stream.point(t*z_,n*z_)}}),yg=function(){return io(uo).scale(155.424).center([0,33.6442])},gg=function(){return yg().parallels([29.5,45.5]).scale(1070).translate([480,250]).rotate([96,0]).center([-.6,38.7])},mg=function(){function t(t){var n=t[0],e=t[1];return a=null,i.point(n,e),a||(o.point(n,e),a)||(u.point(n,e),a)}function n(){return e=r=null,t}var e,r,i,o,u,a,c=gg(),s=yg().rotate([154,0]).center([-2,58.5]).parallels([55,65]),f=yg().rotate([157,0]).center([-3,19.9]).parallels([8,18]),l={point:function(t,n){a=[t,n]}};return t.invert=function(t){var n=c.scale(),e=c.translate(),r=(t[0]-e[0])/n,i=(t[1]-e[1])/n;return(i>=.12&&i<.234&&r>=-.425&&r<-.214?s:i>=.166&&i<.234&&r>=-.214&&r<-.115?f:c).invert(t)},t.stream=function(t){return e&&r===t?e:e=ao([c.stream(r=t),s.stream(t),f.stream(t)])},t.precision=function(t){return arguments.length?(c.precision(t),s.precision(t),f.precision(t),n()):c.precision()},t.scale=function(n){return arguments.length?(c.scale(n),s.scale(.35*n),f.scale(n),t.translate(c.translate())):c.scale()},t.translate=function(t){if(!arguments.length)return c.translate();var e=c.scale(),r=+t[0],a=+t[1];return i=c.translate(t).clipExtent([[r-.455*e,a-.238*e],[r+.455*e,a+.238*e]]).stream(l),o=s.translate([r-.307*e,a+.201*e]).clipExtent([[r-.425*e+k_,a+.12*e+k_],[r-.214*e-k_,a+.234*e-k_]]).stream(l),u=f.translate([r-.205*e,a+.212*e]).clipExtent([[r-.214*e+k_,a+.166*e+k_],[r-.115*e-k_,a+.234*e-k_]]).stream(l),n()},t.fitExtent=function(n,e){return Qi(t,n,e)},t.fitSize=function(n,e){return Ki(t,n,e)},t.scale(1070)},xg=co(function(t){return B_(2/(1+t))});xg.invert=so(function(t){return 2*mr(t/2)});var bg=function(){return eo(xg).scale(124.75).clipAngle(179.999)},wg=co(function(t){return(t=gr(t))&&t/I_(t)});wg.invert=so(function(t){return t});var Mg=function(){return eo(wg).scale(79.4188).clipAngle(179.999)};fo.invert=function(t,n){return[t,2*L_(D_(n))-S_]};var Tg=function(){return lo(fo).scale(961/A_)},kg=function(){return io(po).scale(109.5).parallels([30,30])};vo.invert=vo;var Ng=function(){return eo(vo).scale(152.63)},Sg=function(){return io(_o).scale(131.154).center([0,13.9389])};yo.invert=so(L_);var Eg=function(){return eo(yo).scale(144.049).clipAngle(60)},Ag=function(){function t(){return i=o=null,u}var n,e,r,i,o,u,a=1,c=0,s=0,f=1,l=1,h=Uy,p=null,d=Uy;return u={stream:function(t){return i&&o===t?i:i=h(d(o=t))},clipExtent:function(i){return arguments.length?(d=null==i?(p=n=e=r=null,Uy):li(p=+i[0][0],n=+i[0][1],e=+i[1][0],r=+i[1][1]),t()):null==p?null:[[p,n],[e,r]]},scale:function(n){return arguments.length?(h=go((a=+n)*f,a*l,c,s),t()):a},translate:function(n){return arguments.length?(h=go(a*f,a*l,c=+n[0],s=+n[1]),t()):[c,s]},reflectX:function(n){return arguments.length?(h=go(a*(f=n?-1:1),a*l,c,s),t()):f<0},reflectY:function(n){return arguments.length?(h=go(a*f,a*(l=n?-1:1),c,s),t()):l<0},fitExtent:function(t,n){return Qi(u,t,n)},fitSize:function(t,n){return Ki(u,t,n)}}};mo.invert=so(mr);var Cg=function(){return eo(mo).scale(249.5).clipAngle(90+k_)};xo.invert=so(function(t){return 2*L_(t)});var zg=function(){return eo(xo).scale(250).clipAngle(142)};bo.invert=function(t,n){return[-n,2*L_(D_(t))-S_]};var Pg=function(){var t=lo(bo),n=t.center,e=t.rotate;return t.center=function(t){return arguments.length?n([-t[1],t[0]]):(t=n(),[t[1],-t[0]])},t.rotate=function(t){return arguments.length?e([t[0],t[1],t.length>2?t[2]+90:90]):(t=e(),[t[0],t[1],t[2]-90])},e([0,0,90]).scale(159.155)},Lg=function(){function t(t){var o,u=0;t.eachAfter(function(t){var e=t.children;e?(t.x=Mo(e),t.y=ko(e)):(t.x=o?u+=n(t,o):0,t.y=0,o=t)});var a=So(t),c=Eo(t),s=a.x-n(a,c)/2,f=c.x+n(c,a)/2;return t.eachAfter(i?function(n){n.x=(n.x-t.x)*e,n.y=(t.y-n.y)*r}:function(n){n.x=(n.x-s)/(f-s)*e,n.y=(1-(t.y?n.y/t.y:1))*r})}var n=wo,e=1,r=1,i=!1;return t.separation=function(e){return arguments.length?(n=e,t):n},t.size=function(n){return arguments.length?(i=!1,e=+n[0],r=+n[1],t):i?null:[e,r]},t.nodeSize=function(n){return arguments.length?(i=!0,e=+n[0],r=+n[1],t):i?[e,r]:null},t},Rg=function(){return this.eachAfter(Ao)},qg=function(t){var n,e,r,i,o=this,u=[o];do{for(n=u.reverse(),u=[];o=n.pop();)if(t(o),e=o.children)for(r=0,i=e.length;r<i;++r)u.push(e[r])}while(u.length);return this},Ug=function(t){for(var n,e,r=this,i=[r];r=i.pop();)if(t(r),n=r.children)for(e=n.length-1;e>=0;--e)i.push(n[e]);return this},Dg=function(t){for(var n,e,r,i=this,o=[i],u=[];i=o.pop();)if(u.push(i),n=i.children)for(e=0,r=n.length;e<r;++e)o.push(n[e]);for(;i=u.pop();)t(i);return this},Og=function(t){return this.eachAfter(function(n){for(var e=+t(n.data)||0,r=n.children,i=r&&r.length;--i>=0;)e+=r[i].value;n.value=e})},Fg=function(t){return this.eachBefore(function(n){n.children&&n.children.sort(t)})},Ig=function(t){for(var n=this,e=Co(n,t),r=[n];n!==e;)n=n.parent,r.push(n);for(var i=r.length;t!==e;)r.splice(i,0,t),t=t.parent;return r},Yg=function(){for(var t=this,n=[t];t=t.parent;)n.push(t);return n},Bg=function(){var t=[];return this.each(function(n){t.push(n)}),t},Hg=function(){var t=[];return this.eachBefore(function(n){n.children||t.push(n)}),t},jg=function(){var t=this,n=[];return t.each(function(e){e!==t&&n.push({source:e.parent,target:e})}),n};Uo.prototype=zo.prototype={constructor:Uo,count:Rg,each:qg,eachAfter:Dg,eachBefore:Ug,sum:Og,sort:Fg,path:Ig,ancestors:Yg,descendants:Bg,leaves:Hg,links:jg,copy:Po};var Xg=function(t){for(var n=(t=t.slice()).length,e=null,r=e;n;){var i=new Do(t[n-1]);r=r?r.next=i:e=i,t[void 0]=t[--n]}return{head:e,tail:r}},$g=function(t){return Fo(Xg(t),[])},Vg=function(t){return Vo(t),t},Wg=function(t){return function(){return t}},Zg=function(){function t(t){return t.x=e/2,t.y=r/2,n?t.eachBefore(Qo(n)).eachAfter(Ko(i,.5)).eachBefore(tu(1)):t.eachBefore(Qo(Jo)).eachAfter(Ko(Go,1)).eachAfter(Ko(i,t.r/Math.min(e,r))).eachBefore(tu(Math.min(e,r)/(2*t.r))),t}var n=null,e=1,r=1,i=Go;return t.radius=function(e){return arguments.length?(n=Wo(e),t):n},t.size=function(n){return arguments.length?(e=+n[0],r=+n[1],t):[e,r]},t.padding=function(n){return arguments.length?(i=\"function\"==typeof n?n:Wg(+n),t):i},t},Gg=function(t){t.x0=Math.round(t.x0),t.y0=Math.round(t.y0),t.x1=Math.round(t.x1),t.y1=Math.round(t.y1)},Jg=function(t,n,e,r,i){for(var o,u=t.children,a=-1,c=u.length,s=t.value&&(r-n)/t.value;++a<c;)o=u[a],o.y0=e,o.y1=i,o.x0=n,o.x1=n+=o.value*s},Qg=function(){function t(t){var u=t.height+1;return t.x0=t.y0=i,t.x1=e,t.y1=r/u,t.eachBefore(n(r,u)),o&&t.eachBefore(Gg),t}function n(t,n){return function(e){e.children&&Jg(e,e.x0,t*(e.depth+1)/n,e.x1,t*(e.depth+2)/n);var r=e.x0,o=e.y0,u=e.x1-i,a=e.y1-i;u<r&&(r=u=(r+u)/2),a<o&&(o=a=(o+a)/2),e.x0=r,e.y0=o,e.x1=u,e.y1=a}}var e=1,r=1,i=0,o=!1;return t.round=function(n){return arguments.length?(o=!!n,t):o},t.size=function(n){return arguments.length?(e=+n[0],r=+n[1],t):[e,r]},t.padding=function(n){return arguments.length?(i=+n,t):i},t},Kg=\"$\",tm={depth:-1},nm={},em=function(){function t(t){var r,i,o,u,a,c,s,f=t.length,l=new Array(f),h={};for(i=0;i<f;++i)r=t[i],a=l[i]=new Uo(r),null!=(c=n(r,i,t))&&(c+=\"\")&&(s=Kg+(a.id=c),h[s]=s in h?nm:a);for(i=0;i<f;++i)if(a=l[i],null!=(c=e(t[i],i,t))&&(c+=\"\")){if(!(u=h[Kg+c]))throw new Error(\"missing: \"+c);if(u===nm)throw new Error(\"ambiguous: \"+c);u.children?u.children.push(a):u.children=[a],a.parent=u}else{if(o)throw new Error(\"multiple roots\");o=a}if(!o)throw new Error(\"no root\");if(o.parent=tm,o.eachBefore(function(t){t.depth=t.parent.depth+1,--f}).eachBefore(qo),o.parent=null,f>0)throw new Error(\"cycle\");return o}var n=nu,e=eu;return t.id=function(e){return arguments.length?(n=Zo(e),t):n},t.parentId=function(n){return arguments.length?(e=Zo(n),t):e},t};su.prototype=Object.create(Uo.prototype);var rm=function(){function t(t){var r=fu(t);if(r.eachAfter(n),r.parent.m=-r.z,r.eachBefore(e),c)t.eachBefore(i);else{var s=t,f=t,l=t;t.eachBefore(function(t){t.x<s.x&&(s=t),t.x>f.x&&(f=t),t.depth>l.depth&&(l=t)});var h=s===f?1:o(s,f)/2,p=h-s.x,d=u/(f.x+h+p),v=a/(l.depth||1);t.eachBefore(function(t){t.x=(t.x+p)*d,t.y=t.depth*v})}return t}function n(t){var n=t.children,e=t.parent.children,i=t.i?e[t.i-1]:null;if(n){au(t);var u=(n[0].z+n[n.length-1].z)/2;i?(t.z=i.z+o(t._,i._),t.m=t.z-u):t.z=u}else i&&(t.z=i.z+o(t._,i._));t.parent.A=r(t,i,t.parent.A||e[0])}function e(t){t._.x=t.z+t.parent.m,t.m+=t.parent.m}function r(t,n,e){if(n){for(var r,i=t,u=t,a=n,c=i.parent.children[0],s=i.m,f=u.m,l=a.m,h=c.m;a=ou(a),i=iu(i),a&&i;)c=iu(c),u=ou(u),u.a=t,r=a.z+l-i.z-s+o(a._,i._),r>0&&(uu(cu(a,t,e),t,r),s+=r,f+=r),l+=a.m,s+=i.m,h+=c.m,f+=u.m;a&&!ou(u)&&(u.t=a,u.m+=l-f),i&&!iu(c)&&(c.t=i,c.m+=s-h,e=t)}return e}function i(t){t.x*=u,t.y=t.depth*a}var o=ru,u=1,a=1,c=null;return t.separation=function(n){return arguments.length?(o=n,t):o},t.size=function(n){return arguments.length?(c=!1,u=+n[0],a=+n[1],t):c?null:[u,a]},t.nodeSize=function(n){return arguments.length?(c=!0,u=+n[0],a=+n[1],t):c?[u,a]:null},t},im=function(t,n,e,r,i){for(var o,u=t.children,a=-1,c=u.length,s=t.value&&(i-e)/t.value;++a<c;)o=u[a],o.x0=n,o.x1=r,o.y0=e,o.y1=e+=o.value*s},om=(1+Math.sqrt(5))/2,um=function t(n){function e(t,e,r,i,o){lu(n,t,e,r,i,o)}return e.ratio=function(n){return t((n=+n)>1?n:1)},e}(om),am=function(){function t(t){return t.x0=t.y0=0,t.x1=i,t.y1=o,t.eachBefore(n),u=[0],r&&t.eachBefore(Gg),t}function n(t){var n=u[t.depth],r=t.x0+n,i=t.y0+n,o=t.x1-n,h=t.y1-n;o<r&&(r=o=(r+o)/2),h<i&&(i=h=(i+h)/2),t.x0=r,t.y0=i,t.x1=o,t.y1=h,\nt.children&&(n=u[t.depth+1]=a(t)/2,r+=l(t)-n,i+=c(t)-n,o-=s(t)-n,h-=f(t)-n,o<r&&(r=o=(r+o)/2),h<i&&(i=h=(i+h)/2),e(t,r,i,o,h))}var e=um,r=!1,i=1,o=1,u=[0],a=Go,c=Go,s=Go,f=Go,l=Go;return t.round=function(n){return arguments.length?(r=!!n,t):r},t.size=function(n){return arguments.length?(i=+n[0],o=+n[1],t):[i,o]},t.tile=function(n){return arguments.length?(e=Zo(n),t):e},t.padding=function(n){return arguments.length?t.paddingInner(n).paddingOuter(n):t.paddingInner()},t.paddingInner=function(n){return arguments.length?(a=\"function\"==typeof n?n:Wg(+n),t):a},t.paddingOuter=function(n){return arguments.length?t.paddingTop(n).paddingRight(n).paddingBottom(n).paddingLeft(n):t.paddingTop()},t.paddingTop=function(n){return arguments.length?(c=\"function\"==typeof n?n:Wg(+n),t):c},t.paddingRight=function(n){return arguments.length?(s=\"function\"==typeof n?n:Wg(+n),t):s},t.paddingBottom=function(n){return arguments.length?(f=\"function\"==typeof n?n:Wg(+n),t):f},t.paddingLeft=function(n){return arguments.length?(l=\"function\"==typeof n?n:Wg(+n),t):l},t},cm=function(t,n,e,r,i){function o(t,n,e,r,i,u,a){if(t>=n-1){var s=c[t];return s.x0=r,s.y0=i,s.x1=u,s.y1=a,void 0}for(var l=f[t],h=e/2+l,p=t+1,d=n-1;p<d;){var v=p+d>>>1;f[v]<h?p=v+1:d=v}h-f[p-1]<f[p]-h&&t+1<p&&--p;var _=f[p]-l,y=e-_;if(u-r>a-i){var g=(r*y+u*_)/e;o(t,p,_,r,i,g,a),o(p,n,y,g,i,u,a)}else{var m=(i*y+a*_)/e;o(t,p,_,r,i,u,m),o(p,n,y,r,m,u,a)}}var u,a,c=t.children,s=c.length,f=new Array(s+1);for(f[0]=a=u=0;u<s;++u)f[u+1]=a+=c[u].value;o(0,s,t.value,n,e,r,i)},sm=function(t,n,e,r,i){(1&t.depth?im:Jg)(t,n,e,r,i)},fm=function t(n){function e(t,e,r,i,o){if((u=t._squarify)&&u.ratio===n)for(var u,a,c,s,f,l=-1,h=u.length,p=t.value;++l<h;){for(a=u[l],c=a.children,s=a.value=0,f=c.length;s<f;++s)a.value+=c[s].value;a.dice?Jg(a,e,r,i,r+=(o-r)*a.value/p):im(a,e,r,e+=(i-e)*a.value/p,o),p-=a.value}else t._squarify=u=lu(n,t,e,r,i,o),u.ratio=n}return e.ratio=function(n){return t((n=+n)>1?n:1)},e}(om),lm=function(t){for(var n,e=-1,r=t.length,i=t[r-1],o=0;++e<r;)n=i,i=t[e],o+=n[1]*i[0]-n[0]*i[1];return o/2},hm=function(t){for(var n,e,r=-1,i=t.length,o=0,u=0,a=t[i-1],c=0;++r<i;)n=a,a=t[r],c+=e=n[0]*a[1]-a[0]*n[1],o+=(n[0]+a[0])*e,u+=(n[1]+a[1])*e;return c*=3,[o/c,u/c]},pm=function(t,n,e){return(n[0]-t[0])*(e[1]-t[1])-(n[1]-t[1])*(e[0]-t[0])},dm=function(t){if((e=t.length)<3)return null;var n,e,r=new Array(e),i=new Array(e);for(n=0;n<e;++n)r[n]=[+t[n][0],+t[n][1],n];for(r.sort(hu),n=0;n<e;++n)i[n]=[r[n][0],-r[n][1]];var o=pu(r),u=pu(i),a=u[0]===o[0],c=u[u.length-1]===o[o.length-1],s=[];for(n=o.length-1;n>=0;--n)s.push(t[r[o[n]][2]]);for(n=+a;n<u.length-c;++n)s.push(t[r[u[n]][2]]);return s},vm=function(t,n){for(var e,r,i=t.length,o=t[i-1],u=n[0],a=n[1],c=o[0],s=o[1],f=!1,l=0;l<i;++l)o=t[l],e=o[0],r=o[1],r>a!=s>a&&u<(c-e)*(a-r)/(s-r)+e&&(f=!f),c=e,s=r;return f},_m=function(t){for(var n,e,r=-1,i=t.length,o=t[i-1],u=o[0],a=o[1],c=0;++r<i;)n=u,e=a,o=t[r],u=o[0],a=o[1],n-=u,e-=a,c+=Math.sqrt(n*n+e*e);return c},ym=[].slice,gm={};du.prototype=xu.prototype={constructor:du,defer:function(t){if(\"function\"!=typeof t)throw new Error(\"invalid callback\");if(this._call)throw new Error(\"defer after await\");if(null!=this._error)return this;var n=ym.call(arguments,1);return n.push(t),++this._waiting,this._tasks.push(n),vu(this),this},abort:function(){return null==this._error&&gu(this,new Error(\"abort\")),this},await:function(t){if(\"function\"!=typeof t)throw new Error(\"invalid callback\");if(this._call)throw new Error(\"multiple await\");return this._call=function(n,e){t.apply(null,[n].concat(e))},mu(this),this},awaitAll:function(t){if(\"function\"!=typeof t)throw new Error(\"invalid callback\");if(this._call)throw new Error(\"multiple await\");return this._call=t,mu(this),this}};var mm=function(){return Math.random()},xm=function t(n){function e(t,e){return t=null==t?0:+t,e=null==e?1:+e,1===arguments.length?(e=t,t=0):e-=t,function(){return n()*e+t}}return e.source=t,e}(mm),bm=function t(n){function e(t,e){var r,i;return t=null==t?0:+t,e=null==e?1:+e,function(){var o;if(null!=r)o=r,r=null;else do{r=2*n()-1,o=2*n()-1,i=r*r+o*o}while(!i||i>1);return t+e*o*Math.sqrt(-2*Math.log(i)/i)}}return e.source=t,e}(mm),wm=function t(n){function e(){var t=bm.source(n).apply(this,arguments);return function(){return Math.exp(t())}}return e.source=t,e}(mm),Mm=function t(n){function e(t){return function(){for(var e=0,r=0;r<t;++r)e+=n();return e}}return e.source=t,e}(mm),Tm=function t(n){function e(t){var e=Mm.source(n)(t);return function(){return e()/t}}return e.source=t,e}(mm),km=function t(n){function e(t){return function(){return-Math.log(1-n())/t}}return e.source=t,e}(mm),Nm=function(t,n){function e(t){var n,e=s.status;if(!e&&wu(s)||e>=200&&e<300||304===e){if(o)try{n=o.call(r,s)}catch(t){return void a.call(\"error\",r,t)}else n=s;a.call(\"load\",r,n)}else a.call(\"error\",r,t)}var r,i,o,u,a=v(\"beforesend\",\"progress\",\"load\",\"error\"),c=He(),s=new XMLHttpRequest,f=null,l=null,h=0;if(\"undefined\"==typeof XDomainRequest||\"withCredentials\"in s||!/^(http(s)?:)?\\/\\//.test(t)||(s=new XDomainRequest),\"onload\"in s?s.onload=s.onerror=s.ontimeout=e:s.onreadystatechange=function(t){s.readyState>3&&e(t)},s.onprogress=function(t){a.call(\"progress\",r,t)},r={header:function(t,n){return t=(t+\"\").toLowerCase(),arguments.length<2?c.get(t):(null==n?c.remove(t):c.set(t,n+\"\"),r)},mimeType:function(t){return arguments.length?(i=null==t?null:t+\"\",r):i},responseType:function(t){return arguments.length?(u=t,r):u},timeout:function(t){return arguments.length?(h=+t,r):h},user:function(t){return arguments.length<1?f:(f=null==t?null:t+\"\",r)},password:function(t){return arguments.length<1?l:(l=null==t?null:t+\"\",r)},response:function(t){return o=t,r},get:function(t,n){return r.send(\"GET\",t,n)},post:function(t,n){return r.send(\"POST\",t,n)},send:function(n,e,o){return s.open(n,t,!0,f,l),null==i||c.has(\"accept\")||c.set(\"accept\",i+\",*/*\"),s.setRequestHeader&&c.each(function(t,n){s.setRequestHeader(n,t)}),null!=i&&s.overrideMimeType&&s.overrideMimeType(i),null!=u&&(s.responseType=u),h>0&&(s.timeout=h),null==o&&\"function\"==typeof e&&(o=e,e=null),null!=o&&1===o.length&&(o=bu(o)),null!=o&&r.on(\"error\",o).on(\"load\",function(t){o(null,t)}),a.call(\"beforesend\",r,s),s.send(null==e?null:e),r},abort:function(){return s.abort(),r},on:function(){var t=a.on.apply(a,arguments);return t===a?r:t}},null!=n){if(\"function\"!=typeof n)throw new Error(\"invalid callback: \"+n);return r.get(n)}return r},Sm=function(t,n){return function(e,r){var i=Nm(e).mimeType(t).response(n);if(null!=r){if(\"function\"!=typeof r)throw new Error(\"invalid callback: \"+r);return i.get(r)}return i}},Em=Sm(\"text/html\",function(t){return document.createRange().createContextualFragment(t.responseText)}),Am=Sm(\"application/json\",function(t){return JSON.parse(t.responseText)}),Cm=Sm(\"text/plain\",function(t){return t.responseText}),zm=Sm(\"application/xml\",function(t){var n=t.responseXML;if(!n)throw new Error(\"parse error\");return n}),Pm=function(t,n){return function(e,r,i){arguments.length<3&&(i=r,r=null);var o=Nm(e).mimeType(t);return o.row=function(t){return arguments.length?o.response(Mu(n,r=t)):r},o.row(r),i?o.get(i):o}},Lm=Pm(\"text/csv\",Zd),Rm=Pm(\"text/tab-separated-values\",tv),qm=Array.prototype,Um=qm.map,Dm=qm.slice,Om={name:\"implicit\"},Fm=function(t){return function(){return t}},Im=function(t){return+t},Ym=[0,1],Bm=function(n,e,r){var o,u=n[0],a=n[n.length-1],c=i(u,a,null==e?10:e);switch(r=pr(null==r?\",f\":r),r.type){case\"s\":var s=Math.max(Math.abs(u),Math.abs(a));return null!=r.precision||isNaN(o=jv(c,s))||(r.precision=o),t.formatPrefix(r,s);case\"\":case\"e\":case\"g\":case\"p\":case\"r\":null!=r.precision||isNaN(o=Xv(c,Math.max(Math.abs(u),Math.abs(a))))||(r.precision=o-(\"e\"===r.type));break;case\"f\":case\"%\":null!=r.precision||isNaN(o=Hv(c))||(r.precision=o-2*(\"%\"===r.type))}return t.format(r)},Hm=function(t,n){t=t.slice();var e,r=0,i=t.length-1,o=t[r],u=t[i];return u<o&&(e=r,r=i,i=e,e=o,o=u,u=e),t[r]=n.floor(o),t[i]=n.ceil(u),t},jm=new Date,Xm=new Date,$m=Ju(function(){},function(t,n){t.setTime(+t+n)},function(t,n){return n-t});$m.every=function(t){return t=Math.floor(t),isFinite(t)&&t>0?t>1?Ju(function(n){n.setTime(Math.floor(n/t)*t)},function(n,e){n.setTime(+n+e*t)},function(n,e){return(e-n)/t}):$m:null};var Vm=$m.range,Wm=6e4,Zm=6048e5,Gm=Ju(function(t){t.setTime(1e3*Math.floor(t/1e3))},function(t,n){t.setTime(+t+1e3*n)},function(t,n){return(n-t)/1e3},function(t){return t.getUTCSeconds()}),Jm=Gm.range,Qm=Ju(function(t){t.setTime(Math.floor(t/Wm)*Wm)},function(t,n){t.setTime(+t+n*Wm)},function(t,n){return(n-t)/Wm},function(t){return t.getMinutes()}),Km=Qm.range,tx=Ju(function(t){var n=t.getTimezoneOffset()*Wm%36e5;n<0&&(n+=36e5),t.setTime(36e5*Math.floor((+t-n)/36e5)+n)},function(t,n){t.setTime(+t+36e5*n)},function(t,n){return(n-t)/36e5},function(t){return t.getHours()}),nx=tx.range,ex=Ju(function(t){t.setHours(0,0,0,0)},function(t,n){t.setDate(t.getDate()+n)},function(t,n){return(n-t-(n.getTimezoneOffset()-t.getTimezoneOffset())*Wm)/864e5},function(t){return t.getDate()-1}),rx=ex.range,ix=Qu(0),ox=Qu(1),ux=Qu(2),ax=Qu(3),cx=Qu(4),sx=Qu(5),fx=Qu(6),lx=ix.range,hx=ox.range,px=ux.range,dx=ax.range,vx=cx.range,_x=sx.range,yx=fx.range,gx=Ju(function(t){t.setDate(1),t.setHours(0,0,0,0)},function(t,n){t.setMonth(t.getMonth()+n)},function(t,n){return n.getMonth()-t.getMonth()+12*(n.getFullYear()-t.getFullYear())},function(t){return t.getMonth()}),mx=gx.range,xx=Ju(function(t){t.setMonth(0,1),t.setHours(0,0,0,0)},function(t,n){t.setFullYear(t.getFullYear()+n)},function(t,n){return n.getFullYear()-t.getFullYear()},function(t){return t.getFullYear()});xx.every=function(t){return isFinite(t=Math.floor(t))&&t>0?Ju(function(n){n.setFullYear(Math.floor(n.getFullYear()/t)*t),n.setMonth(0,1),n.setHours(0,0,0,0)},function(n,e){n.setFullYear(n.getFullYear()+e*t)}):null};var bx=xx.range,wx=Ju(function(t){t.setUTCSeconds(0,0)},function(t,n){t.setTime(+t+n*Wm)},function(t,n){return(n-t)/Wm},function(t){return t.getUTCMinutes()}),Mx=wx.range,Tx=Ju(function(t){t.setUTCMinutes(0,0,0)},function(t,n){t.setTime(+t+36e5*n)},function(t,n){return(n-t)/36e5},function(t){return t.getUTCHours()}),kx=Tx.range,Nx=Ju(function(t){t.setUTCHours(0,0,0,0)},function(t,n){t.setUTCDate(t.getUTCDate()+n)},function(t,n){return(n-t)/864e5},function(t){return t.getUTCDate()-1}),Sx=Nx.range,Ex=Ku(0),Ax=Ku(1),Cx=Ku(2),zx=Ku(3),Px=Ku(4),Lx=Ku(5),Rx=Ku(6),qx=Ex.range,Ux=Ax.range,Dx=Cx.range,Ox=zx.range,Fx=Px.range,Ix=Lx.range,Yx=Rx.range,Bx=Ju(function(t){t.setUTCDate(1),t.setUTCHours(0,0,0,0)},function(t,n){t.setUTCMonth(t.getUTCMonth()+n)},function(t,n){return n.getUTCMonth()-t.getUTCMonth()+12*(n.getUTCFullYear()-t.getUTCFullYear())},function(t){return t.getUTCMonth()}),Hx=Bx.range,jx=Ju(function(t){t.setUTCMonth(0,1),t.setUTCHours(0,0,0,0)},function(t,n){t.setUTCFullYear(t.getUTCFullYear()+n)},function(t,n){return n.getUTCFullYear()-t.getUTCFullYear()},function(t){return t.getUTCFullYear()});jx.every=function(t){return isFinite(t=Math.floor(t))&&t>0?Ju(function(n){n.setUTCFullYear(Math.floor(n.getUTCFullYear()/t)*t),n.setUTCMonth(0,1),n.setUTCHours(0,0,0,0)},function(n,e){n.setUTCFullYear(n.getUTCFullYear()+e*t)}):null};var Xx,$x=jx.range,Vx={\"-\":\"\",_:\" \",0:\"0\"},Wx=/^\\s*\\d+/,Zx=/^%/,Gx=/[\\\\\\^\\$\\*\\+\\?\\|\\[\\]\\(\\)\\.\\{\\}]/g;Ja({dateTime:\"%x, %X\",date:\"%-m/%-d/%Y\",time:\"%-I:%M:%S %p\",periods:[\"AM\",\"PM\"],days:[\"Sunday\",\"Monday\",\"Tuesday\",\"Wednesday\",\"Thursday\",\"Friday\",\"Saturday\"],shortDays:[\"Sun\",\"Mon\",\"Tue\",\"Wed\",\"Thu\",\"Fri\",\"Sat\"],months:[\"January\",\"February\",\"March\",\"April\",\"May\",\"June\",\"July\",\"August\",\"September\",\"October\",\"November\",\"December\"],shortMonths:[\"Jan\",\"Feb\",\"Mar\",\"Apr\",\"May\",\"Jun\",\"Jul\",\"Aug\",\"Sep\",\"Oct\",\"Nov\",\"Dec\"]});var Jx=Date.prototype.toISOString?Qa:t.utcFormat(\"%Y-%m-%dT%H:%M:%S.%LZ\"),Qx=+new Date(\"2000-01-01T00:00:00.000Z\")?Ka:t.utcParse(\"%Y-%m-%dT%H:%M:%S.%LZ\"),Kx=1e3,tb=60*Kx,nb=60*tb,eb=24*nb,rb=7*eb,ib=30*eb,ob=365*eb,ub=function(){return ec(xx,gx,ix,ex,tx,Qm,Gm,$m,t.timeFormat).domain([new Date(2e3,0,1),new Date(2e3,0,2)])},ab=function(){return ec(jx,Bx,Ex,Nx,Tx,wx,Gm,$m,t.utcFormat).domain([Date.UTC(2e3,0,1),Date.UTC(2e3,0,2)])},cb=function(t){return t.match(/.{6}/g).map(function(t){return\"#\"+t})},sb=cb(\"1f77b4ff7f0e2ca02cd627289467bd8c564be377c27f7f7fbcbd2217becf\"),fb=cb(\"393b795254a36b6ecf9c9ede6379398ca252b5cf6bcedb9c8c6d31bd9e39e7ba52e7cb94843c39ad494ad6616be7969c7b4173a55194ce6dbdde9ed6\"),lb=cb(\"3182bd6baed69ecae1c6dbefe6550dfd8d3cfdae6bfdd0a231a35474c476a1d99bc7e9c0756bb19e9ac8bcbddcdadaeb636363969696bdbdbdd9d9d9\"),hb=cb(\"1f77b4aec7e8ff7f0effbb782ca02c98df8ad62728ff98969467bdc5b0d58c564bc49c94e377c2f7b6d27f7f7fc7c7c7bcbd22dbdb8d17becf9edae5\"),pb=Zh(Wt(300,.5,0),Wt(-240,.5,1)),db=Zh(Wt(-100,.75,.35),Wt(80,1.5,.8)),vb=Zh(Wt(260,.75,.35),Wt(80,1.5,.8)),_b=Wt(),yb=function(t){(t<0||t>1)&&(t-=Math.floor(t));var n=Math.abs(t-.5);return _b.h=360*t-100,_b.s=1.5-1.5*n,_b.l=.8-.9*n,_b+\"\"},gb=rc(cb(\"44015444025645045745055946075a46085c460a5d460b5e470d60470e6147106347116447136548146748166848176948186a481a6c481b6d481c6e481d6f481f70482071482173482374482475482576482677482878482979472a7a472c7a472d7b472e7c472f7d46307e46327e46337f463480453581453781453882443983443a83443b84433d84433e85423f854240864241864142874144874045884046883f47883f48893e49893e4a893e4c8a3d4d8a3d4e8a3c4f8a3c508b3b518b3b528b3a538b3a548c39558c39568c38588c38598c375a8c375b8d365c8d365d8d355e8d355f8d34608d34618d33628d33638d32648e32658e31668e31678e31688e30698e306a8e2f6b8e2f6c8e2e6d8e2e6e8e2e6f8e2d708e2d718e2c718e2c728e2c738e2b748e2b758e2a768e2a778e2a788e29798e297a8e297b8e287c8e287d8e277e8e277f8e27808e26818e26828e26828e25838e25848e25858e24868e24878e23888e23898e238a8d228b8d228c8d228d8d218e8d218f8d21908d21918c20928c20928c20938c1f948c1f958b1f968b1f978b1f988b1f998a1f9a8a1e9b8a1e9c891e9d891f9e891f9f881fa0881fa1881fa1871fa28720a38620a48621a58521a68522a78522a88423a98324aa8325ab8225ac8226ad8127ad8128ae8029af7f2ab07f2cb17e2db27d2eb37c2fb47c31b57b32b67a34b67935b77937b87838b9773aba763bbb753dbc743fbc7340bd7242be7144bf7046c06f48c16e4ac16d4cc26c4ec36b50c46a52c56954c56856c66758c7655ac8645cc8635ec96260ca6063cb5f65cb5e67cc5c69cd5b6ccd5a6ece5870cf5773d05675d05477d1537ad1517cd2507fd34e81d34d84d44b86d54989d5488bd6468ed64590d74393d74195d84098d83e9bd93c9dd93ba0da39a2da37a5db36a8db34aadc32addc30b0dd2fb2dd2db5de2bb8de29bade28bddf26c0df25c2df23c5e021c8e020cae11fcde11dd0e11cd2e21bd5e21ad8e219dae319dde318dfe318e2e418e5e419e7e419eae51aece51befe51cf1e51df4e61ef6e620f8e621fbe723fde725\")),mb=rc(cb(\"00000401000501010601010802010902020b02020d03030f03031204041405041606051806051a07061c08071e0907200a08220b09240c09260d0a290e0b2b100b2d110c2f120d31130d34140e36150e38160f3b180f3d19103f1a10421c10441d11471e114920114b21114e22115024125325125527125829115a2a115c2c115f2d11612f116331116533106734106936106b38106c390f6e3b0f703d0f713f0f72400f74420f75440f764510774710784910784a10794c117a4e117b4f127b51127c52137c54137d56147d57157e59157e5a167e5c167f5d177f5f187f601880621980641a80651a80671b80681c816a1c816b1d816d1d816e1e81701f81721f817320817521817621817822817922827b23827c23827e24828025828125818326818426818627818827818928818b29818c29818e2a81902a81912b81932b80942c80962c80982d80992d809b2e7f9c2e7f9e2f7fa02f7fa1307ea3307ea5317ea6317da8327daa337dab337cad347cae347bb0357bb2357bb3367ab5367ab73779b83779ba3878bc3978bd3977bf3a77c03a76c23b75c43c75c53c74c73d73c83e73ca3e72cc3f71cd4071cf4070d0416fd2426fd3436ed5446dd6456cd8456cd9466bdb476adc4869de4968df4a68e04c67e24d66e34e65e44f64e55064e75263e85362e95462ea5661eb5760ec5860ed5a5fee5b5eef5d5ef05f5ef1605df2625df2645cf3655cf4675cf4695cf56b5cf66c5cf66e5cf7705cf7725cf8745cf8765cf9785df9795df97b5dfa7d5efa7f5efa815ffb835ffb8560fb8761fc8961fc8a62fc8c63fc8e64fc9065fd9266fd9467fd9668fd9869fd9a6afd9b6bfe9d6cfe9f6dfea16efea36ffea571fea772fea973feaa74feac76feae77feb078feb27afeb47bfeb67cfeb77efeb97ffebb81febd82febf84fec185fec287fec488fec68afec88cfeca8dfecc8ffecd90fecf92fed194fed395fed597fed799fed89afdda9cfddc9efddea0fde0a1fde2a3fde3a5fde5a7fde7a9fde9aafdebacfcecaefceeb0fcf0b2fcf2b4fcf4b6fcf6b8fcf7b9fcf9bbfcfbbdfcfdbf\")),xb=rc(cb(\"00000401000501010601010802010a02020c02020e03021004031204031405041706041907051b08051d09061f0a07220b07240c08260d08290e092b10092d110a30120a32140b34150b37160b39180c3c190c3e1b0c411c0c431e0c451f0c48210c4a230c4c240c4f260c51280b53290b552b0b572d0b592f0a5b310a5c320a5e340a5f3609613809623909633b09643d09653e0966400a67420a68440a68450a69470b6a490b6a4a0c6b4c0c6b4d0d6c4f0d6c510e6c520e6d540f6d550f6d57106e59106e5a116e5c126e5d126e5f136e61136e62146e64156e65156e67166e69166e6a176e6c186e6d186e6f196e71196e721a6e741a6e751b6e771c6d781c6d7a1d6d7c1d6d7d1e6d7f1e6c801f6c82206c84206b85216b87216b88226a8a226a8c23698d23698f24699025689225689326679526679727669827669a28659b29649d29649f2a63a02a63a22b62a32c61a52c60a62d60a82e5fa92e5eab2f5ead305dae305cb0315bb1325ab3325ab43359b63458b73557b93556ba3655bc3754bd3853bf3952c03a51c13a50c33b4fc43c4ec63d4dc73e4cc83f4bca404acb4149cc4248ce4347cf4446d04545d24644d34743d44842d54a41d74b3fd84c3ed94d3dda4e3cdb503bdd513ade5238df5337e05536e15635e25734e35933e45a31e55c30e65d2fe75e2ee8602de9612bea632aeb6429eb6628ec6726ed6925ee6a24ef6c23ef6e21f06f20f1711ff1731df2741cf3761bf37819f47918f57b17f57d15f67e14f68013f78212f78410f8850ff8870ef8890cf98b0bf98c0af98e09fa9008fa9207fa9407fb9606fb9706fb9906fb9b06fb9d07fc9f07fca108fca309fca50afca60cfca80dfcaa0ffcac11fcae12fcb014fcb216fcb418fbb61afbb81dfbba1ffbbc21fbbe23fac026fac228fac42afac62df9c72ff9c932f9cb35f8cd37f8cf3af7d13df7d340f6d543f6d746f5d949f5db4cf4dd4ff4df53f4e156f3e35af3e55df2e661f2e865f2ea69f1ec6df1ed71f1ef75f1f179f2f27df2f482f3f586f3f68af4f88ef5f992f6fa96f8fb9af9fc9dfafda1fcffa4\")),bb=rc(cb(\"0d088710078813078916078a19068c1b068d1d068e20068f2206902406912605912805922a05932c05942e05952f059631059733059735049837049938049a3a049a3c049b3e049c3f049c41049d43039e44039e46039f48039f4903a04b03a14c02a14e02a25002a25102a35302a35502a45601a45801a45901a55b01a55c01a65e01a66001a66100a76300a76400a76600a76700a86900a86a00a86c00a86e00a86f00a87100a87201a87401a87501a87701a87801a87a02a87b02a87d03a87e03a88004a88104a78305a78405a78606a68707a68808a68a09a58b0aa58d0ba58e0ca48f0da4910ea3920fa39410a29511a19613a19814a099159f9a169f9c179e9d189d9e199da01a9ca11b9ba21d9aa31e9aa51f99a62098a72197a82296aa2395ab2494ac2694ad2793ae2892b02991b12a90b22b8fb32c8eb42e8db52f8cb6308bb7318ab83289ba3388bb3488bc3587bd3786be3885bf3984c03a83c13b82c23c81c33d80c43e7fc5407ec6417dc7427cc8437bc9447aca457acb4679cc4778cc4977cd4a76ce4b75cf4c74d04d73d14e72d24f71d35171d45270d5536fd5546ed6556dd7566cd8576bd9586ada5a6ada5b69db5c68dc5d67dd5e66de5f65de6164df6263e06363e16462e26561e26660e3685fe4695ee56a5de56b5de66c5ce76e5be76f5ae87059e97158e97257ea7457eb7556eb7655ec7754ed7953ed7a52ee7b51ef7c51ef7e50f07f4ff0804ef1814df1834cf2844bf3854bf3874af48849f48948f58b47f58c46f68d45f68f44f79044f79143f79342f89441f89540f9973ff9983ef99a3efa9b3dfa9c3cfa9e3bfb9f3afba139fba238fca338fca537fca636fca835fca934fdab33fdac33fdae32fdaf31fdb130fdb22ffdb42ffdb52efeb72dfeb82cfeba2cfebb2bfebd2afebe2afec029fdc229fdc328fdc527fdc627fdc827fdca26fdcb26fccd25fcce25fcd025fcd225fbd324fbd524fbd724fad824fada24f9dc24f9dd25f8df25f8e125f7e225f7e425f6e626f6e826f5e926f5eb27f4ed27f3ee27f3f027f2f227f1f426f1f525f0f724f0f921\")),wb=function(t){return function(){return t}},Mb=Math.abs,Tb=Math.atan2,kb=Math.cos,Nb=Math.max,Sb=Math.min,Eb=Math.sin,Ab=Math.sqrt,Cb=1e-12,zb=Math.PI,Pb=zb/2,Lb=2*zb,Rb=function(){function t(){var t,s,f=+n.apply(this,arguments),l=+e.apply(this,arguments),h=o.apply(this,arguments)-Pb,p=u.apply(this,arguments)-Pb,d=Mb(p-h),v=p>h;if(c||(c=t=Ue()),l<f&&(s=l,l=f,f=s),l>Cb)if(d>Lb-Cb)c.moveTo(l*kb(h),l*Eb(h)),c.arc(0,0,l,h,p,!v),f>Cb&&(c.moveTo(f*kb(p),f*Eb(p)),c.arc(0,0,f,p,h,v));else{var _,y,g=h,m=p,x=h,b=p,w=d,M=d,T=a.apply(this,arguments)/2,k=T>Cb&&(i?+i.apply(this,arguments):Ab(f*f+l*l)),N=Sb(Mb(l-f)/2,+r.apply(this,arguments)),S=N,E=N;if(k>Cb){var A=uc(k/f*Eb(T)),C=uc(k/l*Eb(T));(w-=2*A)>Cb?(A*=v?1:-1,x+=A,b-=A):(w=0,x=b=(h+p)/2),(M-=2*C)>Cb?(C*=v?1:-1,g+=C,m-=C):(M=0,g=m=(h+p)/2)}var z=l*kb(g),P=l*Eb(g),L=f*kb(b),R=f*Eb(b);if(N>Cb){var q=l*kb(m),U=l*Eb(m),D=f*kb(x),O=f*Eb(x);if(d<zb){var F=w>Cb?hc(z,P,D,O,q,U,L,R):[L,R],I=z-F[0],Y=P-F[1],B=q-F[0],H=U-F[1],j=1/Eb(oc((I*B+Y*H)/(Ab(I*I+Y*Y)*Ab(B*B+H*H)))/2),X=Ab(F[0]*F[0]+F[1]*F[1]);S=Sb(N,(f-X)/(j-1)),E=Sb(N,(l-X)/(j+1))}}M>Cb?E>Cb?(_=pc(D,O,z,P,l,E,v),y=pc(q,U,L,R,l,E,v),c.moveTo(_.cx+_.x01,_.cy+_.y01),E<N?c.arc(_.cx,_.cy,E,Tb(_.y01,_.x01),Tb(y.y01,y.x01),!v):(c.arc(_.cx,_.cy,E,Tb(_.y01,_.x01),Tb(_.y11,_.x11),!v),c.arc(0,0,l,Tb(_.cy+_.y11,_.cx+_.x11),Tb(y.cy+y.y11,y.cx+y.x11),!v),c.arc(y.cx,y.cy,E,Tb(y.y11,y.x11),Tb(y.y01,y.x01),!v))):(c.moveTo(z,P),c.arc(0,0,l,g,m,!v)):c.moveTo(z,P),f>Cb&&w>Cb?S>Cb?(_=pc(L,R,q,U,f,-S,v),y=pc(z,P,D,O,f,-S,v),c.lineTo(_.cx+_.x01,_.cy+_.y01),S<N?c.arc(_.cx,_.cy,S,Tb(_.y01,_.x01),Tb(y.y01,y.x01),!v):(c.arc(_.cx,_.cy,S,Tb(_.y01,_.x01),Tb(_.y11,_.x11),!v),c.arc(0,0,f,Tb(_.cy+_.y11,_.cx+_.x11),Tb(y.cy+y.y11,y.cx+y.x11),v),c.arc(y.cx,y.cy,S,Tb(y.y11,y.x11),Tb(y.y01,y.x01),!v))):c.arc(0,0,f,b,x,v):c.lineTo(L,R)}else c.moveTo(0,0);if(c.closePath(),t)return c=null,t+\"\"||null}var n=ac,e=cc,r=wb(0),i=null,o=sc,u=fc,a=lc,c=null;return t.centroid=function(){var t=(+n.apply(this,arguments)+ +e.apply(this,arguments))/2,r=(+o.apply(this,arguments)+ +u.apply(this,arguments))/2-zb/2;return[kb(r)*t,Eb(r)*t]},t.innerRadius=function(e){return arguments.length?(n=\"function\"==typeof e?e:wb(+e),t):n},t.outerRadius=function(n){return arguments.length?(e=\"function\"==typeof n?n:wb(+n),t):e},t.cornerRadius=function(n){return arguments.length?(r=\"function\"==typeof n?n:wb(+n),t):r},t.padRadius=function(n){return arguments.length?(i=null==n?null:\"function\"==typeof n?n:wb(+n),t):i},t.startAngle=function(n){return arguments.length?(o=\"function\"==typeof n?n:wb(+n),t):o},t.endAngle=function(n){return arguments.length?(u=\"function\"==typeof n?n:wb(+n),t):u},t.padAngle=function(n){return arguments.length?(a=\"function\"==typeof n?n:wb(+n),t):a},t.context=function(n){return arguments.length?(c=null==n?null:n,t):c},t};dc.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._point=0},lineEnd:function(){(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,n){switch(t=+t,n=+n,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,n):this._context.moveTo(t,n);break;case 1:this._point=2;default:this._context.lineTo(t,n)}}};var qb=function(t){return new dc(t)},Ub=function(){function t(t){var a,c,s,f=t.length,l=!1;for(null==i&&(u=o(s=Ue())),a=0;a<=f;++a)!(a<f&&r(c=t[a],a,t))===l&&((l=!l)?u.lineStart():u.lineEnd()),l&&u.point(+n(c,a,t),+e(c,a,t));if(s)return u=null,s+\"\"||null}var n=vc,e=_c,r=wb(!0),i=null,o=qb,u=null;return t.x=function(e){return arguments.length?(n=\"function\"==typeof e?e:wb(+e),t):n},t.y=function(n){return arguments.length?(e=\"function\"==typeof n?n:wb(+n),t):e},t.defined=function(n){return arguments.length?(r=\"function\"==typeof n?n:wb(!!n),t):r},t.curve=function(n){return arguments.length?(o=n,null!=i&&(u=o(i)),t):o},t.context=function(n){return arguments.length?(null==n?i=u=null:u=o(i=n),t):i},t},Db=function(){function t(t){var n,f,l,h,p,d=t.length,v=!1,_=new Array(d),y=new Array(d);for(null==a&&(s=c(p=Ue())),n=0;n<=d;++n){if(!(n<d&&u(h=t[n],n,t))===v)if(v=!v)f=n,s.areaStart(),s.lineStart();else{for(s.lineEnd(),s.lineStart(),l=n-1;l>=f;--l)s.point(_[l],y[l]);s.lineEnd(),s.areaEnd()}v&&(_[n]=+e(h,n,t),y[n]=+i(h,n,t),s.point(r?+r(h,n,t):_[n],o?+o(h,n,t):y[n]))}if(p)return s=null,p+\"\"||null}function n(){return Ub().defined(u).curve(c).context(a)}var e=vc,r=null,i=wb(0),o=_c,u=wb(!0),a=null,c=qb,s=null;return t.x=function(n){return arguments.length?(e=\"function\"==typeof n?n:wb(+n),r=null,t):e},t.x0=function(n){return arguments.length?(e=\"function\"==typeof n?n:wb(+n),t):e},t.x1=function(n){return arguments.length?(r=null==n?null:\"function\"==typeof n?n:wb(+n),t):r},t.y=function(n){return arguments.length?(i=\"function\"==typeof n?n:wb(+n),o=null,t):i},t.y0=function(n){return arguments.length?(i=\"function\"==typeof n?n:wb(+n),t):i},t.y1=function(n){return arguments.length?(o=null==n?null:\"function\"==typeof n?n:wb(+n),t):o},t.lineX0=t.lineY0=function(){return n().x(e).y(i)},t.lineY1=function(){return n().x(e).y(o)},t.lineX1=function(){return n().x(r).y(i)},t.defined=function(n){return arguments.length?(u=\"function\"==typeof n?n:wb(!!n),t):u},t.curve=function(n){return arguments.length?(c=n,null!=a&&(s=c(a)),t):c},t.context=function(n){return arguments.length?(null==n?a=s=null:s=c(a=n),t):a},t},Ob=function(t,n){return n<t?-1:n>t?1:n>=t?0:NaN},Fb=function(t){return t},Ib=function(){function t(t){var a,c,s,f,l,h=t.length,p=0,d=new Array(h),v=new Array(h),_=+i.apply(this,arguments),y=Math.min(Lb,Math.max(-Lb,o.apply(this,arguments)-_)),g=Math.min(Math.abs(y)/h,u.apply(this,arguments)),m=g*(y<0?-1:1);for(a=0;a<h;++a)(l=v[d[a]=a]=+n(t[a],a,t))>0&&(p+=l);for(null!=e?d.sort(function(t,n){return e(v[t],v[n])}):null!=r&&d.sort(function(n,e){return r(t[n],t[e])}),a=0,s=p?(y-h*m)/p:0;a<h;++a,_=f)c=d[a],l=v[c],f=_+(l>0?l*s:0)+m,v[c]={data:t[c],index:a,value:l,startAngle:_,endAngle:f,padAngle:g};return v}var n=Fb,e=Ob,r=null,i=wb(0),o=wb(Lb),u=wb(0);return t.value=function(e){return arguments.length?(n=\"function\"==typeof e?e:wb(+e),t):n},t.sortValues=function(n){return arguments.length?(e=n,r=null,t):e},t.sort=function(n){return arguments.length?(r=n,e=null,t):r},t.startAngle=function(n){return arguments.length?(i=\"function\"==typeof n?n:wb(+n),t):i},t.endAngle=function(n){return arguments.length?(o=\"function\"==typeof n?n:wb(+n),t):o},t.padAngle=function(n){return arguments.length?(u=\"function\"==typeof n?n:wb(+n),t):u},t},Yb=gc(qb);yc.prototype={areaStart:function(){this._curve.areaStart()},areaEnd:function(){this._curve.areaEnd()},lineStart:function(){this._curve.lineStart()},lineEnd:function(){this._curve.lineEnd()},point:function(t,n){this._curve.point(n*Math.sin(t),n*-Math.cos(t))}};var Bb=function(){return mc(Ub().curve(Yb))},Hb=function(){var t=Db().curve(Yb),n=t.curve,e=t.lineX0,r=t.lineX1,i=t.lineY0,o=t.lineY1;return t.angle=t.x,delete t.x,t.startAngle=t.x0,delete t.x0,t.endAngle=t.x1,delete t.x1,t.radius=t.y,delete t.y,t.innerRadius=t.y0,delete t.y0,t.outerRadius=t.y1,delete t.y1,t.lineStartAngle=function(){return mc(e())},delete t.lineX0,t.lineEndAngle=function(){return mc(r())},delete t.lineX1,t.lineInnerRadius=function(){return mc(i())},delete t.lineY0,t.lineOuterRadius=function(){return mc(o())},delete t.lineY1,t.curve=function(t){return arguments.length?n(gc(t)):n()._curve},t},jb=Array.prototype.slice,Xb=function(t,n){return[(n=+n)*Math.cos(t-=Math.PI/2),n*Math.sin(t)]},$b={draw:function(t,n){var e=Math.sqrt(n/zb);t.moveTo(e,0),t.arc(0,0,e,0,Lb)}},Vb={draw:function(t,n){var e=Math.sqrt(n/5)/2;t.moveTo(-3*e,-e),t.lineTo(-e,-e),t.lineTo(-e,-3*e),t.lineTo(e,-3*e),t.lineTo(e,-e),t.lineTo(3*e,-e),t.lineTo(3*e,e),t.lineTo(e,e),t.lineTo(e,3*e),t.lineTo(-e,3*e),t.lineTo(-e,e),t.lineTo(-3*e,e),t.closePath()}},Wb=Math.sqrt(1/3),Zb=2*Wb,Gb={draw:function(t,n){var e=Math.sqrt(n/Zb),r=e*Wb;t.moveTo(0,-e),t.lineTo(r,0),t.lineTo(0,e),t.lineTo(-r,0),t.closePath()}},Jb=Math.sin(zb/10)/Math.sin(7*zb/10),Qb=Math.sin(Lb/10)*Jb,Kb=-Math.cos(Lb/10)*Jb,tw={draw:function(t,n){var e=Math.sqrt(.8908130915292852*n),r=Qb*e,i=Kb*e;t.moveTo(0,-e),t.lineTo(r,i);for(var o=1;o<5;++o){var u=Lb*o/5,a=Math.cos(u),c=Math.sin(u);t.lineTo(c*e,-a*e),t.lineTo(a*r-c*i,c*r+a*i)}t.closePath()}},nw={draw:function(t,n){var e=Math.sqrt(n),r=-e/2;t.rect(r,r,e,e)}},ew=Math.sqrt(3),rw={draw:function(t,n){var e=-Math.sqrt(n/(3*ew));t.moveTo(0,2*e),t.lineTo(-ew*e,-e),t.lineTo(ew*e,-e),t.closePath()}},iw=-.5,ow=Math.sqrt(3)/2,uw=1/Math.sqrt(12),aw=3*(uw/2+1),cw={draw:function(t,n){var e=Math.sqrt(n/aw),r=e/2,i=e*uw,o=r,u=e*uw+e,a=-o,c=u;t.moveTo(r,i),t.lineTo(o,u),t.lineTo(a,c),t.lineTo(iw*r-ow*i,ow*r+iw*i),t.lineTo(iw*o-ow*u,ow*o+iw*u),t.lineTo(iw*a-ow*c,ow*a+iw*c),t.lineTo(iw*r+ow*i,iw*i-ow*r),t.lineTo(iw*o+ow*u,iw*u-ow*o),t.lineTo(iw*a+ow*c,iw*c-ow*a),t.closePath()}},sw=[$b,Vb,Gb,nw,tw,rw,cw],fw=function(){function t(){var t;if(r||(r=t=Ue()),n.apply(this,arguments).draw(r,+e.apply(this,arguments)),t)return r=null,t+\"\"||null}var n=wb($b),e=wb(64),r=null;return t.type=function(e){return arguments.length?(n=\"function\"==typeof e?e:wb(e),t):n},t.size=function(n){return arguments.length?(e=\"function\"==typeof n?n:wb(+n),t):e},t.context=function(n){return arguments.length?(r=null==n?null:n,t):r},t},lw=function(){};Cc.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){switch(this._point){case 3:Ac(this,this._x1,this._y1);case 2:this._context.lineTo(this._x1,this._y1)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,n){switch(t=+t,n=+n,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,n):this._context.moveTo(t,n);break;case 1:this._point=2;break;case 2:this._point=3,this._context.lineTo((5*this._x0+this._x1)/6,(5*this._y0+this._y1)/6);default:Ac(this,t,n)}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=n}};var hw=function(t){return new Cc(t)};zc.prototype={areaStart:lw,areaEnd:lw,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._y0=this._y1=this._y2=this._y3=this._y4=NaN,this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x2,this._y2),this._context.closePath();break;case 2:this._context.moveTo((this._x2+2*this._x3)/3,(this._y2+2*this._y3)/3),this._context.lineTo((this._x3+2*this._x2)/3,(this._y3+2*this._y2)/3),this._context.closePath();break;case 3:this.point(this._x2,this._y2),this.point(this._x3,this._y3),this.point(this._x4,this._y4)}},point:function(t,n){switch(t=+t,n=+n,this._point){case 0:this._point=1,this._x2=t,this._y2=n;break;case 1:this._point=2,this._x3=t,this._y3=n;break;case 2:this._point=3,this._x4=t,this._y4=n,this._context.moveTo((this._x0+4*this._x1+t)/6,(this._y0+4*this._y1+n)/6);break;default:Ac(this,t,n)}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=n}};var pw=function(t){return new zc(t)};Pc.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,n){switch(t=+t,n=+n,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3;var e=(this._x0+4*this._x1+t)/6,r=(this._y0+4*this._y1+n)/6;this._line?this._context.lineTo(e,r):this._context.moveTo(e,r);break;case 3:this._point=4;default:Ac(this,t,n)}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=n}};var dw=function(t){return new Pc(t)};Lc.prototype={lineStart:function(){this._x=[],this._y=[],this._basis.lineStart()},lineEnd:function(){var t=this._x,n=this._y,e=t.length-1;if(e>0)for(var r,i=t[0],o=n[0],u=t[e]-i,a=n[e]-o,c=-1;++c<=e;)r=c/e,this._basis.point(this._beta*t[c]+(1-this._beta)*(i+r*u),this._beta*n[c]+(1-this._beta)*(o+r*a));this._x=this._y=null,this._basis.lineEnd()},point:function(t,n){this._x.push(+t),this._y.push(+n)}};var vw=function t(n){function e(t){return 1===n?new Cc(t):new Lc(t,n)}return e.beta=function(n){return t(+n)},e}(.85);qc.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:Rc(this,this._x1,this._y1)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,n){switch(t=+t,n=+n,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,n):this._context.moveTo(t,n);break;case 1:this._point=2,this._x1=t,this._y1=n;break;case 2:this._point=3;default:Rc(this,t,n)}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,\nthis._y1=this._y2,this._y2=n}};var _w=function t(n){function e(t){return new qc(t,n)}return e.tension=function(n){return t(+n)},e}(0);Uc.prototype={areaStart:lw,areaEnd:lw,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x3,this._y3),this._context.closePath();break;case 2:this._context.lineTo(this._x3,this._y3),this._context.closePath();break;case 3:this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5)}},point:function(t,n){switch(t=+t,n=+n,this._point){case 0:this._point=1,this._x3=t,this._y3=n;break;case 1:this._point=2,this._context.moveTo(this._x4=t,this._y4=n);break;case 2:this._point=3,this._x5=t,this._y5=n;break;default:Rc(this,t,n)}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=n}};var yw=function t(n){function e(t){return new Uc(t,n)}return e.tension=function(n){return t(+n)},e}(0);Dc.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,n){switch(t=+t,n=+n,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:Rc(this,t,n)}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=n}};var gw=function t(n){function e(t){return new Dc(t,n)}return e.tension=function(n){return t(+n)},e}(0);Fc.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:this.point(this._x2,this._y2)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,n){if(t=+t,n=+n,this._point){var e=this._x2-t,r=this._y2-n;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(e*e+r*r,this._alpha))}switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(t,n):this._context.moveTo(t,n);break;case 1:this._point=2;break;case 2:this._point=3;default:Oc(this,t,n)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=n}};var mw=function t(n){function e(t){return n?new Fc(t,n):new qc(t,0)}return e.alpha=function(n){return t(+n)},e}(.5);Ic.prototype={areaStart:lw,areaEnd:lw,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x3,this._y3),this._context.closePath();break;case 2:this._context.lineTo(this._x3,this._y3),this._context.closePath();break;case 3:this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5)}},point:function(t,n){if(t=+t,n=+n,this._point){var e=this._x2-t,r=this._y2-n;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(e*e+r*r,this._alpha))}switch(this._point){case 0:this._point=1,this._x3=t,this._y3=n;break;case 1:this._point=2,this._context.moveTo(this._x4=t,this._y4=n);break;case 2:this._point=3,this._x5=t,this._y5=n;break;default:Oc(this,t,n)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=n}};var xw=function t(n){function e(t){return n?new Ic(t,n):new Uc(t,0)}return e.alpha=function(n){return t(+n)},e}(.5);Yc.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,n){if(t=+t,n=+n,this._point){var e=this._x2-t,r=this._y2-n;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(e*e+r*r,this._alpha))}switch(this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:Oc(this,t,n)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=n}};var bw=function t(n){function e(t){return n?new Yc(t,n):new Dc(t,0)}return e.alpha=function(n){return t(+n)},e}(.5);Bc.prototype={areaStart:lw,areaEnd:lw,lineStart:function(){this._point=0},lineEnd:function(){this._point&&this._context.closePath()},point:function(t,n){t=+t,n=+n,this._point?this._context.lineTo(t,n):(this._point=1,this._context.moveTo(t,n))}};var ww=function(t){return new Bc(t)};Vc.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=this._t0=NaN,this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x1,this._y1);break;case 3:$c(this,this._t0,Xc(this,this._t0))}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,n){var e=NaN;if(t=+t,n=+n,t!==this._x1||n!==this._y1){switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(t,n):this._context.moveTo(t,n);break;case 1:this._point=2;break;case 2:this._point=3,$c(this,Xc(this,e=jc(this,t,n)),e);break;default:$c(this,this._t0,e=jc(this,t,n))}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=n,this._t0=e}}},(Wc.prototype=Object.create(Vc.prototype)).point=function(t,n){Vc.prototype.point.call(this,n,t)},Zc.prototype={moveTo:function(t,n){this._context.moveTo(n,t)},closePath:function(){this._context.closePath()},lineTo:function(t,n){this._context.lineTo(n,t)},bezierCurveTo:function(t,n,e,r,i,o){this._context.bezierCurveTo(n,t,r,e,o,i)}},Qc.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x=[],this._y=[]},lineEnd:function(){var t=this._x,n=this._y,e=t.length;if(e)if(this._line?this._context.lineTo(t[0],n[0]):this._context.moveTo(t[0],n[0]),2===e)this._context.lineTo(t[1],n[1]);else for(var r=Kc(t),i=Kc(n),o=0,u=1;u<e;++o,++u)this._context.bezierCurveTo(r[0][o],i[0][o],r[1][o],i[1][o],t[u],n[u]);(this._line||0!==this._line&&1===e)&&this._context.closePath(),this._line=1-this._line,this._x=this._y=null},point:function(t,n){this._x.push(+t),this._y.push(+n)}};var Mw=function(t){return new Qc(t)};ts.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x=this._y=NaN,this._point=0},lineEnd:function(){0<this._t&&this._t<1&&2===this._point&&this._context.lineTo(this._x,this._y),(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line>=0&&(this._t=1-this._t,this._line=1-this._line)},point:function(t,n){switch(t=+t,n=+n,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,n):this._context.moveTo(t,n);break;case 1:this._point=2;default:if(this._t<=0)this._context.lineTo(this._x,n),this._context.lineTo(t,n);else{var e=this._x*(1-this._t)+t*this._t;this._context.lineTo(e,this._y),this._context.lineTo(e,n)}}this._x=t,this._y=n}};var Tw=function(t){return new ts(t,.5)},kw=function(t,n){if((i=t.length)>1)for(var e,r,i,o=1,u=t[n[0]],a=u.length;o<i;++o)for(r=u,u=t[n[o]],e=0;e<a;++e)u[e][1]+=u[e][0]=isNaN(r[e][1])?r[e][0]:r[e][1]},Nw=function(t){for(var n=t.length,e=new Array(n);--n>=0;)e[n]=n;return e},Sw=function(){function t(t){var o,u,a=n.apply(this,arguments),c=t.length,s=a.length,f=new Array(s);for(o=0;o<s;++o){for(var l,h=a[o],p=f[o]=new Array(c),d=0;d<c;++d)p[d]=l=[0,+i(t[d],h,d,t)],l.data=t[d];p.key=h}for(o=0,u=e(f);o<s;++o)f[u[o]].index=o;return r(f,u),f}var n=wb([]),e=Nw,r=kw,i=rs;return t.keys=function(e){return arguments.length?(n=\"function\"==typeof e?e:wb(jb.call(e)),t):n},t.value=function(n){return arguments.length?(i=\"function\"==typeof n?n:wb(+n),t):i},t.order=function(n){return arguments.length?(e=null==n?Nw:\"function\"==typeof n?n:wb(jb.call(n)),t):e},t.offset=function(n){return arguments.length?(r=null==n?kw:n,t):r},t},Ew=function(t,n){if((r=t.length)>0){for(var e,r,i,o=0,u=t[0].length;o<u;++o){for(i=e=0;e<r;++e)i+=t[e][o][1]||0;if(i)for(e=0;e<r;++e)t[e][o][1]/=i}kw(t,n)}},Aw=function(t,n){if((a=t.length)>1)for(var e,r,i,o,u,a,c=0,s=t[n[0]].length;c<s;++c)for(o=u=0,e=0;e<a;++e)(i=(r=t[n[e]][c])[1]-r[0])>=0?(r[0]=o,r[1]=o+=i):i<0?(r[1]=u,r[0]=u+=i):r[0]=o},Cw=function(t,n){if((e=t.length)>0){for(var e,r=0,i=t[n[0]],o=i.length;r<o;++r){for(var u=0,a=0;u<e;++u)a+=t[u][r][1]||0;i[r][1]+=i[r][0]=-a/2}kw(t,n)}},zw=function(t,n){if((i=t.length)>0&&(r=(e=t[n[0]]).length)>0){for(var e,r,i,o=0,u=1;u<r;++u){for(var a=0,c=0,s=0;a<i;++a){for(var f=t[n[a]],l=f[u][1]||0,h=f[u-1][1]||0,p=(l-h)/2,d=0;d<a;++d){var v=t[n[d]];p+=(v[u][1]||0)-(v[u-1][1]||0)}c+=l,s+=p*l}e[u-1][1]+=e[u-1][0]=o,c&&(o-=s/c)}e[u-1][1]+=e[u-1][0]=o,kw(t,n)}},Pw=function(t){var n=t.map(is);return Nw(t).sort(function(t,e){return n[t]-n[e]})},Lw=function(t){return Pw(t).reverse()},Rw=function(t){var n,e,r=t.length,i=t.map(is),o=Nw(t).sort(function(t,n){return i[n]-i[t]}),u=0,a=0,c=[],s=[];for(n=0;n<r;++n)e=o[n],u<a?(u+=i[e],c.push(e)):(a+=i[e],s.push(e));return s.reverse().concat(c)},qw=function(t){return Nw(t).reverse()},Uw=function(t){return function(){return t}};as.prototype={constructor:as,insert:function(t,n){var e,r,i;if(t){if(n.P=t,n.N=t.N,t.N&&(t.N.P=n),t.N=n,t.R){for(t=t.R;t.L;)t=t.L;t.L=n}else t.R=n;e=t}else this._?(t=ls(this._),n.P=null,n.N=t,t.P=t.L=n,e=t):(n.P=n.N=null,this._=n,e=null);for(n.L=n.R=null,n.U=e,n.C=!0,t=n;e&&e.C;)r=e.U,e===r.L?(i=r.R,i&&i.C?(e.C=i.C=!1,r.C=!0,t=r):(t===e.R&&(ss(this,e),t=e,e=t.U),e.C=!1,r.C=!0,fs(this,r))):(i=r.L,i&&i.C?(e.C=i.C=!1,r.C=!0,t=r):(t===e.L&&(fs(this,e),t=e,e=t.U),e.C=!1,r.C=!0,ss(this,r))),e=t.U;this._.C=!1},remove:function(t){t.N&&(t.N.P=t.P),t.P&&(t.P.N=t.N),t.N=t.P=null;var n,e,r,i=t.U,o=t.L,u=t.R;if(e=o?u?ls(u):o:u,i?i.L===t?i.L=e:i.R=e:this._=e,o&&u?(r=e.C,e.C=t.C,e.L=o,o.U=e,e!==u?(i=e.U,e.U=t.U,t=e.R,i.L=t,e.R=u,u.U=e):(e.U=i,i=e,t=e.R)):(r=t.C,t=e),t&&(t.U=i),!r){if(t&&t.C)return void(t.C=!1);do{if(t===this._)break;if(t===i.L){if(n=i.R,n.C&&(n.C=!1,i.C=!0,ss(this,i),n=i.R),n.L&&n.L.C||n.R&&n.R.C){n.R&&n.R.C||(n.L.C=!1,n.C=!0,fs(this,n),n=i.R),n.C=i.C,i.C=n.R.C=!1,ss(this,i),t=this._;break}}else if(n=i.L,n.C&&(n.C=!1,i.C=!0,fs(this,i),n=i.L),n.L&&n.L.C||n.R&&n.R.C){n.L&&n.L.C||(n.R.C=!1,n.C=!0,ss(this,n),n=i.L),n.C=i.C,i.C=n.L.C=!1,fs(this,i),t=this._;break}n.C=!0,t=i,i=i.U}while(!t.C);t&&(t.C=!1)}}};var Dw,Ow,Fw,Iw,Yw,Bw=[],Hw=[],jw=1e-6,Xw=1e-12;Us.prototype={constructor:Us,polygons:function(){var t=this.edges;return this.cells.map(function(n){var e=n.halfedges.map(function(e){return xs(n,t[e])});return e.data=n.site.data,e})},triangles:function(){var t=[],n=this.edges;return this.cells.forEach(function(e,r){if(o=(i=e.halfedges).length)for(var i,o,u,a=e.site,c=-1,s=n[i[o-1]],f=s.left===a?s.right:s.left;++c<o;)u=f,s=n[i[c]],f=s.left===a?s.right:s.left,u&&f&&r<u.index&&r<f.index&&Rs(a,u,f)<0&&t.push([a.data,u.data,f.data])}),t},links:function(){return this.edges.filter(function(t){return t.right}).map(function(t){return{source:t.left.data,target:t.right.data}})},find:function(t,n,e){for(var r,i,o=this,u=o._found||0,a=o.cells.length;!(i=o.cells[u]);)if(++u>=a)return null;var c=t-i.site[0],s=n-i.site[1],f=c*c+s*s;do{i=o.cells[r=u],u=null,i.halfedges.forEach(function(e){var r=o.edges[e],a=r.left;if(a!==i.site&&a||(a=r.right)){var c=t-a[0],s=n-a[1],l=c*c+s*s;l<f&&(f=l,u=a.index)}})}while(null!==u);return o._found=r,null==e||f<=e*e?i.site:null}};var $w=function(){function t(t){return new Us(t.map(function(r,i){var o=[Math.round(n(r,i,t)/jw)*jw,Math.round(e(r,i,t)/jw)*jw];return o.index=i,o.data=r,o}),r)}var n=os,e=us,r=null;return t.polygons=function(n){return t(n).polygons()},t.links=function(n){return t(n).links()},t.triangles=function(n){return t(n).triangles()},t.x=function(e){return arguments.length?(n=\"function\"==typeof e?e:Uw(+e),t):n},t.y=function(n){return arguments.length?(e=\"function\"==typeof n?n:Uw(+n),t):e},t.extent=function(n){return arguments.length?(r=null==n?null:[[+n[0][0],+n[0][1]],[+n[1][0],+n[1][1]]],t):r&&[[r[0][0],r[0][1]],[r[1][0],r[1][1]]]},t.size=function(n){return arguments.length?(r=null==n?null:[[0,0],[+n[0],+n[1]]],t):r&&[r[1][0]-r[0][0],r[1][1]-r[0][1]]},t},Vw=function(t){return function(){return t}};Os.prototype={constructor:Os,scale:function(t){return 1===t?this:new Os(this.k*t,this.x,this.y)},translate:function(t,n){return 0===t&0===n?this:new Os(this.k,this.x+this.k*t,this.y+this.k*n)},apply:function(t){return[t[0]*this.k+this.x,t[1]*this.k+this.y]},applyX:function(t){return t*this.k+this.x},applyY:function(t){return t*this.k+this.y},invert:function(t){return[(t[0]-this.x)/this.k,(t[1]-this.y)/this.k]},invertX:function(t){return(t-this.x)/this.k},invertY:function(t){return(t-this.y)/this.k},rescaleX:function(t){return t.copy().domain(t.range().map(this.invertX,this).map(t.invert,t))},rescaleY:function(t){return t.copy().domain(t.range().map(this.invertY,this).map(t.invert,t))},toString:function(){return\"translate(\"+this.x+\",\"+this.y+\") scale(\"+this.k+\")\"}};var Ww=new Os(1,0,0);Fs.prototype=Os.prototype;var Zw=function(){t.event.preventDefault(),t.event.stopImmediatePropagation()},Gw=function(){function n(t){t.on(\"wheel.zoom\",s).on(\"mousedown.zoom\",f).on(\"dblclick.zoom\",l).on(\"touchstart.zoom\",h).on(\"touchmove.zoom\",p).on(\"touchend.zoom touchcancel.zoom\",d).style(\"-webkit-tap-highlight-color\",\"rgba(0,0,0,0)\").property(\"__zoom\",Hs)}function e(t,n){return n=Math.max(x,Math.min(b,n)),n===t.k?t:new Os(n,t.x,t.y)}function r(t,n,e){var r=n[0]-e[0]*t.k,i=n[1]-e[1]*t.k;return r===t.x&&i===t.y?t:new Os(t.k,r,i)}function i(t,n){var e=t.invertX(n[0][0])-w,r=t.invertX(n[1][0])-M,i=t.invertY(n[0][1])-T,o=t.invertY(n[1][1])-k;return t.translate(r>e?(e+r)/2:Math.min(0,e)||Math.max(0,r),o>i?(i+o)/2:Math.min(0,i)||Math.max(0,o))}function o(t){return[(+t[0][0]+ +t[1][0])/2,(+t[0][1]+ +t[1][1])/2]}function u(t,n,e){t.on(\"start.zoom\",function(){a(this,arguments).start()}).on(\"interrupt.zoom end.zoom\",function(){a(this,arguments).end()}).tween(\"zoom\",function(){var t=this,r=arguments,i=a(t,r),u=m.apply(t,r),c=e||o(u),s=Math.max(u[1][0]-u[0][0],u[1][1]-u[0][1]),f=t.__zoom,l=\"function\"==typeof n?n.apply(t,r):n,h=S(f.invert(c).concat(s/f.k),l.invert(c).concat(s/l.k));return function(t){if(1===t)t=l;else{var n=h(t),e=s/n[2];t=new Os(e,c[0]-n[0]*e,c[1]-n[1]*e)}i.zoom(null,t)}})}function a(t,n){for(var e,r=0,i=E.length;r<i;++r)if((e=E[r]).that===t)return e;return new c(t,n)}function c(t,n){this.that=t,this.args=n,this.index=-1,this.active=0,this.extent=m.apply(t,n)}function s(){function n(){o.wheel=null,o.end()}if(g.apply(this,arguments)){var o=a(this,arguments),u=this.__zoom,c=Math.max(x,Math.min(b,u.k*Math.pow(2,-t.event.deltaY*(t.event.deltaMode?120:1)/500))),s=Gf(this);if(o.wheel)o.mouse[0][0]===s[0]&&o.mouse[0][1]===s[1]||(o.mouse[1]=u.invert(o.mouse[0]=s)),clearTimeout(o.wheel);else{if(u.k===c)return;o.mouse=[s,u.invert(s)],gp(this),o.start()}Zw(),o.wheel=setTimeout(n,P),o.zoom(\"mouse\",i(r(e(u,c),o.mouse[0],o.mouse[1]),o.extent))}}function f(){function n(){if(Zw(),!o.moved){var n=t.event.clientX-s,e=t.event.clientY-f;o.moved=n*n+e*e>L}o.zoom(\"mouse\",i(r(o.that.__zoom,o.mouse[0]=Gf(o.that),o.mouse[1]),o.extent))}function e(){u.on(\"mousemove.zoom mouseup.zoom\",null),mt(t.event.view,o.moved),Zw(),o.end()}if(!y&&g.apply(this,arguments)){var o=a(this,arguments),u=Pl(t.event.view).on(\"mousemove.zoom\",n,!0).on(\"mouseup.zoom\",e,!0),c=Gf(this),s=t.event.clientX,f=t.event.clientY;Dl(t.event.view),Is(),o.mouse=[c,this.__zoom.invert(c)],gp(this),o.start()}}function l(){if(g.apply(this,arguments)){var o=this.__zoom,a=Gf(this),c=o.invert(a),s=o.k*(t.event.shiftKey?.5:2),f=i(r(e(o,s),a,c),m.apply(this,arguments));Zw(),N>0?Pl(this).transition().duration(N).call(u,f,a):Pl(this).call(n.transform,f)}}function h(){if(g.apply(this,arguments)){var n,e,r,i,o=a(this,arguments),u=t.event.changedTouches,c=u.length;for(Is(),e=0;e<c;++e)r=u[e],i=Rl(this,u,r.identifier),i=[i,this.__zoom.invert(i),r.identifier],o.touch0?o.touch1||(o.touch1=i):(o.touch0=i,n=!0);if(_&&(_=clearTimeout(_),!o.touch1))return o.end(),void((i=Pl(this).on(\"dblclick.zoom\"))&&i.apply(this,arguments));n&&(_=setTimeout(function(){_=null},z),gp(this),o.start())}}function p(){var n,o,u,c,s=a(this,arguments),f=t.event.changedTouches,l=f.length;for(Zw(),_&&(_=clearTimeout(_)),n=0;n<l;++n)o=f[n],u=Rl(this,f,o.identifier),s.touch0&&s.touch0[2]===o.identifier?s.touch0[0]=u:s.touch1&&s.touch1[2]===o.identifier&&(s.touch1[0]=u);if(o=s.that.__zoom,s.touch1){var h=s.touch0[0],p=s.touch0[1],d=s.touch1[0],v=s.touch1[1],y=(y=d[0]-h[0])*y+(y=d[1]-h[1])*y,g=(g=v[0]-p[0])*g+(g=v[1]-p[1])*g;o=e(o,Math.sqrt(y/g)),u=[(h[0]+d[0])/2,(h[1]+d[1])/2],c=[(p[0]+v[0])/2,(p[1]+v[1])/2]}else{if(!s.touch0)return;u=s.touch0[0],c=s.touch0[1]}s.zoom(\"touch\",i(r(o,u,c),s.extent))}function d(){var n,e,r=a(this,arguments),i=t.event.changedTouches,o=i.length;for(Is(),y&&clearTimeout(y),y=setTimeout(function(){y=null},z),n=0;n<o;++n)e=i[n],r.touch0&&r.touch0[2]===e.identifier?delete r.touch0:r.touch1&&r.touch1[2]===e.identifier&&delete r.touch1;r.touch1&&!r.touch0&&(r.touch0=r.touch1,delete r.touch1),r.touch0?r.touch0[1]=this.__zoom.invert(r.touch0[0]):r.end()}var _,y,g=Ys,m=Bs,x=0,b=1/0,w=-b,M=b,T=w,k=M,N=250,S=Hh,E=[],C=v(\"start\",\"zoom\",\"end\"),z=500,P=150,L=0;return n.transform=function(t,n){var e=t.selection?t.selection():t;e.property(\"__zoom\",Hs),t!==e?u(t,n):e.interrupt().each(function(){a(this,arguments).start().zoom(null,\"function\"==typeof n?n.apply(this,arguments):n).end()})},n.scaleBy=function(t,e){n.scaleTo(t,function(){return this.__zoom.k*(\"function\"==typeof e?e.apply(this,arguments):e)})},n.scaleTo=function(t,u){n.transform(t,function(){var t=m.apply(this,arguments),n=this.__zoom,a=o(t),c=n.invert(a);return i(r(e(n,\"function\"==typeof u?u.apply(this,arguments):u),a,c),t)})},n.translateBy=function(t,e,r){n.transform(t,function(){return i(this.__zoom.translate(\"function\"==typeof e?e.apply(this,arguments):e,\"function\"==typeof r?r.apply(this,arguments):r),m.apply(this,arguments))})},c.prototype={start:function(){return 1==++this.active&&(this.index=E.push(this)-1,this.emit(\"start\")),this},zoom:function(t,n){return this.mouse&&\"mouse\"!==t&&(this.mouse[1]=n.invert(this.mouse[0])),this.touch0&&\"touch\"!==t&&(this.touch0[1]=n.invert(this.touch0[0])),this.touch1&&\"touch\"!==t&&(this.touch1[1]=n.invert(this.touch1[0])),this.that.__zoom=n,this.emit(\"zoom\"),this},end:function(){return 0==--this.active&&(E.splice(this.index,1),this.index=-1,this.emit(\"end\")),this},emit:function(t){A(new Ds(n,t,this.that.__zoom),C.apply,C,[t,this.that,this.args])}},n.filter=function(t){return arguments.length?(g=\"function\"==typeof t?t:Vw(!!t),n):g},n.extent=function(t){return arguments.length?(m=\"function\"==typeof t?t:Vw([[+t[0][0],+t[0][1]],[+t[1][0],+t[1][1]]]),n):m},n.scaleExtent=function(t){return arguments.length?(x=+t[0],b=+t[1],n):[x,b]},n.translateExtent=function(t){return arguments.length?(w=+t[0][0],M=+t[1][0],T=+t[0][1],k=+t[1][1],n):[[w,T],[M,k]]},n.duration=function(t){return arguments.length?(N=+t,n):N},n.interpolate=function(t){return arguments.length?(S=t,n):S},n.on=function(){var t=C.on.apply(C,arguments);return t===C?n:t},n.clickDistance=function(t){return arguments.length?(L=(t=+t)*t,n):Math.sqrt(L)},n};t.version=\"4.9.1\",t.bisect=Vs,t.bisectRight=Vs,t.bisectLeft=Ws,t.ascending=js,t.bisector=Xs,t.cross=Gs,t.descending=Js,t.deviation=tf,t.extent=nf,t.histogram=df,t.thresholdFreedmanDiaconis=_f,t.thresholdScott=yf,t.thresholdSturges=pf,t.max=gf,t.mean=mf,t.median=xf,t.merge=bf,t.min=wf,t.pairs=Zs,t.permute=Mf,t.quantile=vf,t.range=cf,t.scan=Tf,t.shuffle=kf,t.sum=Nf,t.ticks=hf,t.tickIncrement=r,t.tickStep=i,t.transpose=Sf,t.variance=Ks,t.zip=Ef,t.axisTop=l,t.axisRight=h,t.axisBottom=p,t.axisLeft=d,t.brush=Ed,t.brushX=ze,t.brushY=Pe,t.brushSelection=Ce,t.chord=qd,t.ribbon=Yd,t.nest=Bd,t.set=Ze,t.map=He,t.keys=jd,t.values=Xd,t.entries=$d,t.color=Nt,t.rgb=Ct,t.hsl=Rt,t.lab=Ot,t.hcl=Xt,t.cubehelix=Wt,t.dispatch=v,t.drag=Fl,t.dragDisable=Dl,t.dragEnable=mt,t.dsvFormat=Vd,t.csvParse=Zd,t.csvParseRows=Gd,t.csvFormat=Jd,t.csvFormatRows=Qd,t.tsvParse=tv,t.tsvParseRows=nv,t.tsvFormat=ev,t.tsvFormatRows=rv,t.easeLinear=ie,t.easeQuad=ae,t.easeQuadIn=oe,t.easeQuadOut=ue,t.easeQuadInOut=ae,t.easeCubic=fe,t.easeCubicIn=ce,t.easeCubicOut=se,t.easeCubicInOut=fe,t.easePoly=Hp,t.easePolyIn=Yp,t.easePolyOut=Bp,t.easePolyInOut=Hp,t.easeSin=pe,t.easeSinIn=le,t.easeSinOut=he,t.easeSinInOut=pe,t.easeExp=_e,t.easeExpIn=de,t.easeExpOut=ve,t.easeExpInOut=_e,t.easeCircle=me,t.easeCircleIn=ye,t.easeCircleOut=ge,t.easeCircleInOut=me,t.easeBounce=be,t.easeBounceIn=xe,t.easeBounceOut=be,t.easeBounceInOut=we,t.easeBack=id,t.easeBackIn=ed,t.easeBackOut=rd,t.easeBackInOut=id,t.easeElastic=ad,t.easeElasticIn=ud,t.easeElasticOut=ad,t.easeElasticInOut=cd,t.forceCenter=iv,t.forceCollide=wv,t.forceLink=Mv,t.forceManyBody=Sv,t.forceSimulation=Nv,t.forceX=Ev,t.forceY=Av,t.formatDefaultLocale=vr,t.formatLocale=Bv,t.formatSpecifier=pr,t.precisionFixed=Hv,t.precisionPrefix=jv,t.precisionRound=Xv,t.geoArea=G_,t.geoBounds=K_,t.geoCentroid=ny,t.geoCircle=_y,t.geoClipExtent=My,t.geoContains=Ry,t.geoDistance=zy,t.geoGraticule=Ti,t.geoGraticule10=ki,t.geoInterpolate=qy,t.geoLength=Ey,t.geoPath=cg,t.geoAlbers=gg,t.geoAlbersUsa=mg,t.geoAzimuthalEqualArea=bg,t.geoAzimuthalEqualAreaRaw=xg,t.geoAzimuthalEquidistant=Mg,t.geoAzimuthalEquidistantRaw=wg,t.geoConicConformal=kg,t.geoConicConformalRaw=po,t.geoConicEqualArea=yg,t.geoConicEqualAreaRaw=uo,t.geoConicEquidistant=Sg,t.geoConicEquidistantRaw=_o,t.geoEquirectangular=Ng,t.geoEquirectangularRaw=vo,t.geoGnomonic=Eg,t.geoGnomonicRaw=yo,t.geoIdentity=Ag,t.geoProjection=eo,t.geoProjectionMutator=ro,t.geoMercator=Tg,t.geoMercatorRaw=fo,t.geoOrthographic=Cg,t.geoOrthographicRaw=mo,t.geoStereographic=zg,t.geoStereographicRaw=xo,t.geoTransverseMercator=Pg,t.geoTransverseMercatorRaw=bo,t.geoRotation=vy,t.geoStream=$_,t.geoTransform=hg,t.cluster=Lg,t.hierarchy=zo,t.pack=Zg,t.packSiblings=Vg,t.packEnclose=$g,t.partition=Qg,t.stratify=em,t.tree=rm,t.treemap=am,t.treemapBinary=cm,t.treemapDice=Jg,t.treemapSlice=im,t.treemapSliceDice=sm,t.treemapSquarify=um,t.treemapResquarify=fm,t.interpolate=qh,t.interpolateArray=Eh,t.interpolateBasis=wh,t.interpolateBasisClosed=Mh,t.interpolateDate=Ah,t.interpolateNumber=Ch,t.interpolateObject=zh,t.interpolateRound=Uh,t.interpolateString=Rh,t.interpolateTransformCss=Ih,t.interpolateTransformSvg=Yh,t.interpolateZoom=Hh,t.interpolateRgb=kh,t.interpolateRgbBasis=Nh,t.interpolateRgbBasisClosed=Sh,t.interpolateHsl=jh,t.interpolateHslLong=Xh,t.interpolateLab=pn,t.interpolateHcl=$h,t.interpolateHclLong=Vh,t.interpolateCubehelix=Wh,t.interpolateCubehelixLong=Zh,t.quantize=Gh,t.path=Ue,t.polygonArea=lm,t.polygonCentroid=hm;t.polygonHull=dm,t.polygonContains=vm,t.polygonLength=_m,t.quadtree=ir,t.queue=xu,t.randomUniform=xm,t.randomNormal=bm,t.randomLogNormal=wm,t.randomBates=Tm,t.randomIrwinHall=Mm,t.randomExponential=km,t.request=Nm,t.html=Em,t.json=Am,t.text=Cm,t.xml=zm,t.csv=Lm,t.tsv=Rm,t.scaleBand=ku,t.scalePoint=Su,t.scaleIdentity=Du,t.scaleLinear=Uu,t.scaleLog=ju,t.scaleOrdinal=Tu,t.scaleImplicit=Om,t.scalePow=$u,t.scaleSqrt=Vu,t.scaleQuantile=Wu,t.scaleQuantize=Zu,t.scaleThreshold=Gu,t.scaleTime=ub,t.scaleUtc=ab,t.schemeCategory10=sb,t.schemeCategory20b=fb,t.schemeCategory20c=lb,t.schemeCategory20=hb,t.interpolateCubehelixDefault=pb,t.interpolateRainbow=yb,t.interpolateWarm=db,t.interpolateCool=vb,t.interpolateViridis=gb,t.interpolateMagma=mb,t.interpolateInferno=xb,t.interpolatePlasma=bb,t.scaleSequential=ic,t.creator=If,t.local=w,t.matcher=Xf,t.mouse=Gf,t.namespace=Ff,t.namespaces=Of,t.select=Pl,t.selectAll=Ll,t.selection=yt,t.selector=Jf,t.selectorAll=Kf,t.style=X,t.touch=Rl,t.touches=ql,t.window=gl,t.customEvent=A,t.arc=Rb,t.area=Db,t.line=Ub,t.pie=Ib,t.radialArea=Hb,t.radialLine=Bb,t.linkHorizontal=Nc,t.linkVertical=Sc,t.linkRadial=Ec,t.symbol=fw,t.symbols=sw,t.symbolCircle=$b,t.symbolCross=Vb,t.symbolDiamond=Gb,t.symbolSquare=nw,t.symbolStar=tw,t.symbolTriangle=rw,t.symbolWye=cw,t.curveBasisClosed=pw,t.curveBasisOpen=dw,t.curveBasis=hw,t.curveBundle=vw,t.curveCardinalClosed=yw,t.curveCardinalOpen=gw,t.curveCardinal=_w,t.curveCatmullRomClosed=xw,t.curveCatmullRomOpen=bw,t.curveCatmullRom=mw,t.curveLinearClosed=ww,t.curveLinear=qb,t.curveMonotoneX=Gc,t.curveMonotoneY=Jc,t.curveNatural=Mw,t.curveStep=Tw,t.curveStepAfter=es,t.curveStepBefore=ns,t.stack=Sw,t.stackOffsetExpand=Ew,t.stackOffsetDiverging=Aw,t.stackOffsetNone=kw,t.stackOffsetSilhouette=Cw,t.stackOffsetWiggle=zw,t.stackOrderAscending=Pw,t.stackOrderDescending=Lw,t.stackOrderInsideOut=Rw,t.stackOrderNone=Nw,t.stackOrderReverse=qw,t.timeInterval=Ju,t.timeMillisecond=$m,t.timeMilliseconds=Vm,t.utcMillisecond=$m,t.utcMilliseconds=Vm,t.timeSecond=Gm,t.timeSeconds=Jm,t.utcSecond=Gm,t.utcSeconds=Jm,t.timeMinute=Qm,t.timeMinutes=Km,t.timeHour=tx,t.timeHours=nx,t.timeDay=ex,t.timeDays=rx,t.timeWeek=ix,t.timeWeeks=lx,t.timeSunday=ix,t.timeSundays=lx,t.timeMonday=ox,t.timeMondays=hx,t.timeTuesday=ux,t.timeTuesdays=px,t.timeWednesday=ax,t.timeWednesdays=dx,t.timeThursday=cx,t.timeThursdays=vx,t.timeFriday=sx,t.timeFridays=_x,t.timeSaturday=fx,t.timeSaturdays=yx,t.timeMonth=gx,t.timeMonths=mx,t.timeYear=xx,t.timeYears=bx,t.utcMinute=wx,t.utcMinutes=Mx,t.utcHour=Tx,t.utcHours=kx,t.utcDay=Nx,t.utcDays=Sx,t.utcWeek=Ex,t.utcWeeks=qx,t.utcSunday=Ex,t.utcSundays=qx,t.utcMonday=Ax,t.utcMondays=Ux,t.utcTuesday=Cx,t.utcTuesdays=Dx,t.utcWednesday=zx,t.utcWednesdays=Ox,t.utcThursday=Px,t.utcThursdays=Fx,t.utcFriday=Lx,t.utcFridays=Ix,t.utcSaturday=Rx,t.utcSaturdays=Yx,t.utcMonth=Bx,t.utcMonths=Hx,t.utcYear=jx,t.utcYears=$x,t.timeFormatDefaultLocale=Ja,t.timeFormatLocale=ra,t.isoFormat=Jx,t.isoParse=Qx,t.now=_n,t.timer=mn,t.timerFlush=xn,t.timeout=up,t.interval=ap,t.transition=ee,t.active=hd,t.interrupt=gp,t.voronoi=$w,t.zoom=Gw,t.zoomTransform=Fs,t.zoomIdentity=Ww,Object.defineProperty(t,\"__esModule\",{value:!0})});</script><script>//~~WEBPATH~~external/com_google_javascript_closure_library/closure/goog/base.js\nvar h;\nfunction aa(a){var b=typeof a;if(\"object\"==b)if(a){if(a instanceof Array)return\"array\";if(a instanceof Object)return b;var c=Object.prototype.toString.call(a);if(\"[object Window]\"==c)return\"object\";if(\"[object Array]\"==c||\"number\"==typeof a.length&&\"undefined\"!=typeof a.splice&&\"undefined\"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable(\"splice\"))return\"array\";if(\"[object Function]\"==c||\"undefined\"!=typeof a.call&&\"undefined\"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable(\"call\"))return\"function\"}else return\"null\";else if(\"function\"==\nb&&\"undefined\"==typeof a.call)return\"object\";return b}function ba(a,b){var c=Array.prototype.slice.call(arguments,1);return function(){var b=c.slice();b.push.apply(b,arguments);return a.apply(this,b)}}function da(a,b){function c(){}c.prototype=b.prototype;a.superClass_=b.prototype;a.prototype=new c;a.prototype.constructor=a;a.base=function(a,c,f){for(var d=Array(arguments.length-2),e=2;e<arguments.length;e++)d[e-2]=arguments[e];return b.prototype[c].apply(a,d)}};\n//~~WEBPATH~~external/com_google_javascript_closure_library/closure/goog/deps.js\n//~~WEBPATH~~external/com_google_javascript_closure_library/closure/goog/debug/error.js\nfunction ea(a){if(Error.captureStackTrace)Error.captureStackTrace(this,ea);else{var b=Error().stack;b&&(this.stack=b)}a&&(this.message=String(a));this.reportErrorToServer=!0}da(ea,Error);ea.prototype.name=\"CustomError\";\n//~~WEBPATH~~external/com_google_javascript_closure_library/closure/goog/dom/nodetype.js\n//~~WEBPATH~~external/com_google_javascript_closure_library/closure/goog/string/string.js\nfunction ha(a,b){for(var c=a.split(\"%s\"),d=\"\",e=Array.prototype.slice.call(arguments,1);e.length&&1<c.length;)d+=c.shift()+e.shift();return d+c.join(\"%s\")};\n//~~WEBPATH~~external/com_google_javascript_closure_library/closure/goog/asserts/asserts.js\nfunction ia(a,b){b.unshift(a);ea.call(this,ha.apply(null,b));b.shift();this.messagePattern=a}da(ia,ea);ia.prototype.name=\"AssertionError\";function ka(a,b){throw new ia(\"Failure\"+(a?\": \"+a:\"\"),Array.prototype.slice.call(arguments,1));};\n//~~WEBPATH~~external/com_google_javascript_closure_library/closure/goog/array/array.js\nvar ma=Array.prototype.forEach?function(a,b,c){Array.prototype.forEach.call(a,b,c)}:function(a,b,c){for(var d=a.length,e=\"string\"==typeof a?a.split(\"\"):a,f=0;f<d;f++)f in e&&b.call(c,e[f],f,a)},na=Array.prototype.map?function(a,b,c){return Array.prototype.map.call(a,b,c)}:function(a,b,c){for(var d=a.length,e=Array(d),f=\"string\"==typeof a?a.split(\"\"):a,g=0;g<d;g++)g in f&&(e[g]=b.call(c,f[g],g,a));return e};\n//~~WEBPATH~~external/com_google_javascript_closure_library/closure/goog/labs/useragent/util.js\n//~~WEBPATH~~external/com_google_javascript_closure_library/closure/goog/object/object.js\n//~~WEBPATH~~external/com_google_javascript_closure_library/closure/goog/labs/useragent/browser.js\n//~~WEBPATH~~external/com_google_javascript_closure_library/closure/goog/labs/useragent/engine.js\n//~~WEBPATH~~external/com_google_javascript_closure_library/closure/goog/labs/useragent/platform.js\n//~~WEBPATH~~external/com_google_javascript_closure_library/closure/goog/reflect/reflect.js\n//~~WEBPATH~~external/com_google_javascript_closure_library/closure/goog/useragent/useragent.js\n//~~WEBPATH~~external/com_google_javascript_closure_library/closure/goog/crypt/crypt.js\n//~~WEBPATH~~external/com_google_javascript_closure_library/closure/goog/useragent/product.js\n//~~WEBPATH~~external/com_google_javascript_closure_library/closure/goog/crypt/base64.js\nvar pa=null,qa=null;function ra(a){var b=new Uint8Array(Math.ceil(3*a.length/4)),c=0;ta(a,function(a){b[c++]=a});return b.subarray(0,c)}function ta(a,b){function c(b){for(;d<a.length;){var c=a.charAt(d++),e=qa[c];if(null!=e)return e;if(!/^[\\s\\xa0]*$/.test(c))throw Error(\"Unknown base64 encoding at char: \"+c);}return b}ua();for(var d=0;;){var e=c(-1),f=c(0),g=c(64),k=c(64);if(64===k&&-1===e)break;b(e<<2|f>>4);64!=g&&(b(f<<4&240|g>>2),64!=k&&b(g<<6&192|k))}}\nfunction ua(){if(!pa){pa={};qa={};for(var a=0;65>a;a++)pa[a]=\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\\x3d\".charAt(a),qa[pa[a]]=a,62<=a&&(qa[\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.\".charAt(a)]=a)}};\n//~~WEBPATH~~external/com_google_javascript_closure_library/closure/goog/json/json.js\n//~~WEBPATH~~external/com_google_javascript_closure_library/third_party/closure/goog/base.js\n//~~WEBPATH~~external/com_google_javascript_closure_library/third_party/closure/goog/deps.js\n//~~WEBPATH~~external/com_google_protobuf_js/js/map.js\n//~~WEBPATH~~external/com_google_protobuf_js/js/message.js\nfunction va(){}var wa=\"function\"==typeof Uint8Array;va.prototype.getJsPbMessageId=function(){return this.messageId_};\nfunction xa(a,b,c,d){a.wrappers_=null;b||(b=[]);a.messageId_=void 0;a.arrayIndexOffset_=-1;a.array=b;a:{if(a.array.length){b=a.array.length-1;var e=a.array[b];if(e&&\"object\"==typeof e&&\"array\"!=aa(e)&&!(wa&&e instanceof Uint8Array)){a.pivot_=b-a.arrayIndexOffset_;a.extensionObject_=e;break a}}a.pivot_=Number.MAX_VALUE}a.convertedFloatingPointFields_={};if(c)for(b=0;b<c.length;b++)e=c[b],e<a.pivot_?(e+=a.arrayIndexOffset_,a.array[e]=a.array[e]||ya):a.extensionObject_[e]=a.extensionObject_[e]||ya;d&&\nd.length&&ma(d,ba(za,a))}var ya=Object.freeze?Object.freeze([]):[];function Aa(a){var b=a.pivot_+a.arrayIndexOffset_;a.array[b]||(a.extensionObject_=a.array[b]={})}function Ba(a,b,c){for(var d=[],e=0;e<a.length;e++)d[e]=b.call(a[e],c,a[e]);return d}function Ca(a,b){if(b<a.pivot_){b+=a.arrayIndexOffset_;var c=a.array[b];return c===ya?a.array[b]=[]:c}c=a.extensionObject_[b];return c===ya?a.extensionObject_[b]=[]:c}function u(a,b,c){a=Ca(a,b);return null==a?c:a}\nfunction G(a,b,c){b<a.pivot_?a.array[b+a.arrayIndexOffset_]=c:a.extensionObject_[b]=c}function Da(a,b,c,d){(c=za(a,c))&&c!==b&&void 0!==d&&(a.wrappers_&&c in a.wrappers_&&(a.wrappers_[c]=void 0),G(a,c,void 0));G(a,b,d)}function za(a,b){var c,d;ma(b,function(b){var e=Ca(a,b);null!=e&&(c=b,d=e,G(a,b,void 0))});return c?(G(a,c,d),c):0}function O(a,b,c){a.wrappers_||(a.wrappers_={});if(!a.wrappers_[c]){var d=Ca(a,c);d&&(a.wrappers_[c]=new b(d))}return a.wrappers_[c]}\nfunction Ea(a,b,c){Fa(a,b,c);b=a.wrappers_[c];b==ya&&(b=a.wrappers_[c]=[]);return b}function Fa(a,b,c){a.wrappers_||(a.wrappers_={});if(!a.wrappers_[c]){for(var d=Ca(a,c),e=[],f=0;f<d.length;f++)e[f]=new b(d[f]);a.wrappers_[c]=e}}function Ga(a,b,c){a.wrappers_||(a.wrappers_={});var d=c?c.toArray():c;a.wrappers_[b]=c;G(a,b,d)}function Ha(a,b,c,d){a.wrappers_||(a.wrappers_={});var e=d?d.toArray():d;a.wrappers_[b]=d;Da(a,b,c,e)}\nfunction Ia(a,b,c){a.wrappers_||(a.wrappers_={});c=c||[];for(var d=[],e=0;e<c.length;e++)d[e]=c[e].toArray();a.wrappers_[b]=c;G(a,b,d)}function Ja(a,b,c,d,e){Fa(a,d,b);var f=a.wrappers_[b];f||(f=a.wrappers_[b]=[]);c=c?c:new d;a=Ca(a,b);void 0!=e?(f.splice(e,0,c),a.splice(e,0,c.toArray())):(f.push(c),a.push(c.toArray()));return c}function Ka(a){if(a.wrappers_)for(var b in a.wrappers_){var c=a.wrappers_[b];if(\"array\"==aa(c))for(var d=0;d<c.length;d++)c[d]&&c[d].toArray();else c&&c.toArray()}}h=va.prototype;\nh.toArray=function(){Ka(this);return this.array};h.toString=function(){Ka(this);return this.array.toString()};\nh.getExtension=function(a){if(this.extensionObject_){this.wrappers_||(this.wrappers_={});var b=a.fieldIndex;if(a.isRepeated){if(a.isMessageType())return this.wrappers_[b]||(this.wrappers_[b]=na(this.extensionObject_[b]||[],function(b){return new a.ctor(b)})),this.wrappers_[b]}else if(a.isMessageType())return!this.wrappers_[b]&&this.extensionObject_[b]&&(this.wrappers_[b]=new a.ctor(this.extensionObject_[b])),this.wrappers_[b];return this.extensionObject_[b]}};\nh.setExtension=function(a,b){this.wrappers_||(this.wrappers_={});Aa(this);var c=a.fieldIndex;a.isRepeated?(b=b||[],a.isMessageType()?(this.wrappers_[c]=b,this.extensionObject_[c]=na(b,function(a){return a.toArray()})):this.extensionObject_[c]=b):a.isMessageType()?(this.wrappers_[c]=b,this.extensionObject_[c]=b?b.toArray():b):this.extensionObject_[c]=b;return this};h.clone=function(){return new this.constructor(Ma(this.toArray()))};\nfunction Ma(a){var b;if(\"array\"==aa(a)){for(var c=Array(a.length),d=0;d<a.length;d++)null!=(b=a[d])&&(c[d]=\"object\"==typeof b?Ma(b):b);return c}if(wa&&a instanceof Uint8Array)return new Uint8Array(a);c={};for(d in a)null!=(b=a[d])&&(c[d]=\"object\"==typeof b?Ma(b):b);return c};\n//~~WEBPATH~~external/com_google_protobuf_js/js/binary/arith.js\nfunction Na(a,b){this.lo=a;this.hi=b}h=Na.prototype;h.cmp=function(a){return this.hi<a.hi||this.hi==a.hi&&this.lo<a.lo?-1:this.hi==a.hi&&this.lo==a.lo?0:1};function Oa(a){return new Na((a.lo>>>1|(a.hi&1)<<31)>>>0,a.hi>>>1>>>0)}function Pa(a){return new Na(a.lo<<1>>>0,(a.hi<<1|a.lo>>>31)>>>0)}h.lsb=function(){return!!(this.lo&1)};h.add=function(a){return new Na((this.lo+a.lo&4294967295)>>>0>>>0,((this.hi+a.hi&4294967295)>>>0)+(4294967296<=this.lo+a.lo?1:0)>>>0)};\nh.sub=function(a){return new Na((this.lo-a.lo&4294967295)>>>0>>>0,((this.hi-a.hi&4294967295)>>>0)-(0>this.lo-a.lo?1:0)>>>0)};function Ra(a){var b=a&65535,c=a>>>16;a=10*b+65536*(0*b&65535)+65536*(10*c&65535);for(b=0*c+(0*b>>>16)+(10*c>>>16);4294967296<=a;)a-=4294967296,b+=1;return new Na(a>>>0,b>>>0)}\nh.toString=function(){for(var a=\"\",b=this;0!=b.lo||0!=b.hi;){var c=new Na(0,0);for(var b=new Na(b.lo,b.hi),d=new Na(10,0),e=new Na(1,0);!(d.hi&2147483648);)d=Pa(d),e=Pa(e);for(;0!=e.lo||0!=e.hi;)0>=d.cmp(b)&&(c=c.add(e),b=b.sub(d)),d=Oa(d),e=Oa(e);c=[c,b];b=c[0];a=c[1].lo+a}\"\"==a&&(a=\"0\");return a};function Sa(a){for(var b=new Na(0,0),c=new Na(0,0),d=0;d<a.length;d++){if(\"0\">a[d]||\"9\"<a[d])return null;c.lo=parseInt(a[d],10);var e=Ra(b.lo),b=Ra(b.hi);b.hi=b.lo;b.lo=0;b=e.add(b).add(c)}return b}\nh.clone=function(){return new Na(this.lo,this.hi)};function Ta(a,b){this.lo=a;this.hi=b}Ta.prototype.add=function(a){return new Ta((this.lo+a.lo&4294967295)>>>0>>>0,((this.hi+a.hi&4294967295)>>>0)+(4294967296<=this.lo+a.lo?1:0)>>>0)};Ta.prototype.sub=function(a){return new Ta((this.lo-a.lo&4294967295)>>>0>>>0,((this.hi-a.hi&4294967295)>>>0)-(0>this.lo-a.lo?1:0)>>>0)};Ta.prototype.clone=function(){return new Ta(this.lo,this.hi)};\nTa.prototype.toString=function(){var a=0!=(this.hi&2147483648),b=new Na(this.lo,this.hi);a&&(b=(new Na(0,0)).sub(b));return(a?\"-\":\"\")+b.toString()};function Ua(a){var b=0<a.length&&\"-\"==a[0];b&&(a=a.substring(1));a=Sa(a);if(null===a)return null;b&&(a=(new Na(0,0)).sub(a));return new Ta(a.lo,a.hi)};\n//~~WEBPATH~~external/com_google_protobuf_js/js/binary/constants.js\nfunction Wa(a){switch(a){case 5:case 3:case 13:case 4:case 17:case 18:case 8:case 14:case 31:return 0;case 1:case 6:case 16:case 30:return 1;case 9:case 11:case 12:return 2;case 2:case 7:case 15:return 5;default:return-1}};\n//~~WEBPATH~~external/com_google_protobuf_js/js/binary/utils.js\nvar Xa=0,Ya=0;function Za(a){var b=a>>>0;a=Math.floor((a-b)/4294967296)>>>0;Xa=b;Ya=a}function bb(a){var b=0>a;a=Math.abs(a);var c=a>>>0;a=Math.floor((a-c)/4294967296);a>>>=0;b&&(a=~a>>>0,c=(~c>>>0)+1,4294967295<c&&(c=0,a++,4294967295<a&&(a=0)));Xa=c;Ya=a}function cb(a){var b=0>a;a=2*Math.abs(a);Za(a);a=Xa;var c=Ya;b&&(0==a?0==c?c=a=4294967295:(c--,a=4294967295):a--);Xa=a;Ya=c}\nfunction db(a){var b=a.charCodeAt(4),c=a.charCodeAt(5),d=a.charCodeAt(6),e=a.charCodeAt(7);Xa=a.charCodeAt(0)+(a.charCodeAt(1)<<8)+(a.charCodeAt(2)<<16)+(a.charCodeAt(3)<<24)>>>0;Ya=b+(c<<8)+(d<<16)+(e<<24)>>>0}function eb(a,b){var c=b&2147483648;c&&(a=~a+1>>>0,b=~b>>>0,0==a&&(b=b+1>>>0));a=4294967296*b+a;return c?-a:a}var fb=\"0123456789abcdef\".split(\"\");\nfunction gb(a,b){function c(a){for(var b=1E7,c=0;7>c;c++){var b=b/10,d=a/b%10>>>0;if(0!=d||f)f=!0,g+=e[d]}}if(2097151>=b)return\"\"+(4294967296*b+a);var d=(a>>>24|b<<8)>>>0&16777215;b=b>>16&65535;a=(a&16777215)+6777216*d+6710656*b;d+=8147497*b;b*=2;1E7<=a&&(d+=Math.floor(a/1E7),a%=1E7);1E7<=d&&(b+=Math.floor(d/1E7),d%=1E7);var e=fb,f=!1,g=\"\";(b||f)&&c(b);(d||f)&&c(d);(a||f)&&c(a);return g}\nfunction hb(a){if(a.constructor===Uint8Array)return a;if(a.constructor===ArrayBuffer)return new Uint8Array(a);if(a.constructor===Array)return new Uint8Array(a);if(a.constructor===String)return ra(a);ka(\"Type not convertible to Uint8Array.\");return new Uint8Array(0)};\n//~~WEBPATH~~external/com_google_protobuf_js/js/binary/decoder.js\nfunction ib(a,b,c){this.bytes_=null;this.tempHigh_=this.tempLow_=this.cursor_=this.end_=this.start_=0;this.error_=!1;a&&this.setBlock(a,b,c)}var jb=[];function kb(a,b,c){if(jb.length){var d=jb.pop();a&&d.setBlock(a,b,c);return d}return new ib(a,b,c)}h=ib.prototype;h.free=function(){this.clear();100>jb.length&&jb.push(this)};h.clone=function(){return kb(this.bytes_,this.start_,this.end_-this.start_)};h.clear=function(){this.bytes_=null;this.cursor_=this.end_=this.start_=0;this.error_=!1};\nh.getBuffer=function(){return this.bytes_};h.setBlock=function(a,b,c){this.bytes_=hb(a);this.start_=void 0!==b?b:0;this.end_=void 0!==c?this.start_+c:this.bytes_.length;this.cursor_=this.start_};h.setEnd=function(a){this.end_=a};h.reset=function(){this.cursor_=this.start_};h.getCursor=function(){return this.cursor_};h.advance=function(a){this.cursor_+=a};function lb(a){return a.cursor_==a.end_}h.pastEnd=function(){return this.cursor_>this.end_};\nh.getError=function(){return this.error_||0>this.cursor_||this.cursor_>this.end_};function mb(a){for(var b,c=0,d,e=0;4>e;e++)if(b=a.bytes_[a.cursor_++],c|=(b&127)<<7*e,128>b){a.tempLow_=c>>>0;a.tempHigh_=0;return}b=a.bytes_[a.cursor_++];c|=(b&127)<<28;d=0|(b&127)>>4;if(128>b)a.tempLow_=c>>>0,a.tempHigh_=d>>>0;else{for(e=0;5>e;e++)if(b=a.bytes_[a.cursor_++],d|=(b&127)<<7*e+3,128>b){a.tempLow_=c>>>0;a.tempHigh_=d>>>0;return}ka(\"Failed to read varint, encoding is invalid.\");a.error_=!0}}\nfunction nb(a,b){for(;128<b;)a.cursor_--,b>>>=7;a.cursor_--}h.readUnsignedVarint32=function(){var a=this.bytes_;var b=a[this.cursor_+0];var c=b&127;if(128>b)return this.cursor_+=1,c;b=a[this.cursor_+1];c|=(b&127)<<7;if(128>b)return this.cursor_+=2,c;b=a[this.cursor_+2];c|=(b&127)<<14;if(128>b)return this.cursor_+=3,c;b=a[this.cursor_+3];c|=(b&127)<<21;if(128>b)return this.cursor_+=4,c;b=a[this.cursor_+4];c|=(b&15)<<28;if(128>b)return this.cursor_+=5,c>>>0;this.cursor_+=10;return c};\nh.readSignedVarint32=ib.prototype.readUnsignedVarint32;h.readUnsignedVarint32String=function(){return this.readUnsignedVarint32().toString()};h.readSignedVarint32String=function(){return this.readSignedVarint32().toString()};h.readZigzagVarint32=function(){var a=this.readUnsignedVarint32();return a>>>1^-(a&1)};h.readUnsignedVarint64=function(){mb(this);return 4294967296*this.tempHigh_+this.tempLow_};h.readUnsignedVarint64String=function(){mb(this);return gb(this.tempLow_,this.tempHigh_)};\nh.readSignedVarint64=function(){mb(this);return eb(this.tempLow_,this.tempHigh_)};h.readSignedVarint64String=function(){mb(this);var a=this.tempLow_,b=this.tempHigh_,c=b&2147483648;c&&(a=~a+1>>>0,b=~b+(0==a?1:0)>>>0);a=gb(a,b);return c?\"-\"+a:a};h.readZigzagVarint64=function(){mb(this);var a=this.tempLow_,b=this.tempHigh_,c=a&1,a=(a>>>1|b<<31)>>>0,b=b>>>1;c&&(a=a+1>>>0,0==a&&(b=b+1>>>0));a=4294967296*b+a;return c?-a:a};h.readUint8=function(){var a=this.bytes_[this.cursor_+0];this.cursor_+=1;return a};\nh.readUint16=function(){var a=this.bytes_[this.cursor_+0],b=this.bytes_[this.cursor_+1];this.cursor_+=2;return a<<0|b<<8};h.readUint32=function(){var a=this.bytes_[this.cursor_+0],b=this.bytes_[this.cursor_+1],c=this.bytes_[this.cursor_+2],d=this.bytes_[this.cursor_+3];this.cursor_+=4;return(a<<0|b<<8|c<<16|d<<24)>>>0};h.readUint64=function(){var a=this.readUint32();return 4294967296*this.readUint32()+a};h.readInt8=function(){var a=this.bytes_[this.cursor_+0];this.cursor_+=1;return a<<24>>24};\nh.readInt16=function(){var a=this.bytes_[this.cursor_+0],b=this.bytes_[this.cursor_+1];this.cursor_+=2;return(a<<0|b<<8)<<16>>16};h.readInt32=function(){var a=this.bytes_[this.cursor_+0],b=this.bytes_[this.cursor_+1],c=this.bytes_[this.cursor_+2],d=this.bytes_[this.cursor_+3];this.cursor_+=4;return a<<0|b<<8|c<<16|d<<24};h.readInt64=function(){var a=this.readUint32(),b=this.readUint32();return eb(a,b)};\nh.readFloat=function(){var a=this.readUint32(),b=2*(a>>31)+1,c=a>>>23&255,a=a&8388607;return 255==c?a?NaN:Infinity*b:0==c?b*Math.pow(2,-149)*a:b*Math.pow(2,c-150)*(a+Math.pow(2,23))};h.readDouble=function(){var a=this.readUint32(),b=this.readUint32(),c=2*(b>>31)+1,d=b>>>20&2047,a=4294967296*(b&1048575)+a;return 2047==d?a?NaN:Infinity*c:0==d?c*Math.pow(2,-1074)*a:c*Math.pow(2,d-1075)*(a+4503599627370496)};h.readBool=function(){return!!this.bytes_[this.cursor_++]};h.readEnum=function(){return this.readSignedVarint32()};\nh.readString=function(a){for(var b=this.bytes_,c=this.cursor_,d=c+a,e=[];c<d;){var f=b[c++];if(128>f)e.push(f);else if(!(192>f))if(224>f)a=b[c++],e.push((f&31)<<6|a&63);else if(240>f){a=b[c++];var g=b[c++];e.push((f&15)<<12|(a&63)<<6|g&63)}}b=String.fromCharCode.apply(null,e);this.cursor_=c;return b};h.readStringWithLength=function(){var a=this.readUnsignedVarint32();return this.readString(a)};\nh.readBytes=function(a){if(0>a||this.cursor_+a>this.bytes_.length)return this.error_=!0,ka(\"Invalid byte length!\"),new Uint8Array(0);var b=this.bytes_.subarray(this.cursor_,this.cursor_+a);this.cursor_+=a;return b};h.readVarintHash64=function(){mb(this);var a=this.tempLow_,b=this.tempHigh_;return String.fromCharCode(a>>>0&255,a>>>8&255,a>>>16&255,a>>>24&255,b>>>0&255,b>>>8&255,b>>>16&255,b>>>24&255)};\nh.readFixedHash64=function(){var a=this.bytes_,b=this.cursor_,c=a[b+0],d=a[b+1],e=a[b+2],f=a[b+3],g=a[b+4],k=a[b+5],l=a[b+6],a=a[b+7];this.cursor_+=8;return String.fromCharCode(c,d,e,f,g,k,l,a)};\n//~~WEBPATH~~external/com_google_protobuf_js/js/binary/encoder.js\nfunction qb(){this.buffer_=[]}h=qb.prototype;h.length=function(){return this.buffer_.length};h.end=function(){var a=this.buffer_;this.buffer_=[];return a};function rb(a,b,c){for(;0<c||127<b;)a.buffer_.push(b&127|128),b=(b>>>7|c<<25)>>>0,c>>>=7;a.buffer_.push(b)}function sb(a,b){for(;127<b;)a.buffer_.push(b&127|128),b>>>=7;a.buffer_.push(b)}function tb(a,b){if(0<=b)sb(a,b);else{for(var c=0;9>c;c++)a.buffer_.push(b&127|128),b>>=7;a.buffer_.push(1)}}function ub(a,b){sb(a,(b<<1^b>>31)>>>0)}\nh.writeUint8=function(a){this.buffer_.push(a>>>0&255)};h.writeUint16=function(a){this.buffer_.push(a>>>0&255);this.buffer_.push(a>>>8&255)};h.writeUint32=function(a){this.buffer_.push(a>>>0&255);this.buffer_.push(a>>>8&255);this.buffer_.push(a>>>16&255);this.buffer_.push(a>>>24&255)};h.writeUint64=function(a){Za(a);this.writeUint32(Xa);this.writeUint32(Ya)};h.writeInt8=function(a){this.buffer_.push(a>>>0&255)};h.writeInt16=function(a){this.buffer_.push(a>>>0&255);this.buffer_.push(a>>>8&255)};\nh.writeInt32=function(a){this.buffer_.push(a>>>0&255);this.buffer_.push(a>>>8&255);this.buffer_.push(a>>>16&255);this.buffer_.push(a>>>24&255)};h.writeInt64=function(a){bb(a);this.writeUint32(Xa);this.writeUint32(Ya)};\nh.writeFloat=function(a){var b=a,b=(a=0>b?1:0)?-b:b;if(0===b)0<1/b?Xa=Ya=0:(Ya=0,Xa=2147483648);else if(isNaN(b))Ya=0,Xa=2147483647;else if(3.4028234663852886E38<b)Ya=0,Xa=(a<<31|2139095040)>>>0;else if(1.1754943508222875E-38>b)b=Math.round(b/Math.pow(2,-149)),Ya=0,Xa=(a<<31|b)>>>0;else{var c=Math.floor(Math.log(b)/Math.LN2);b*=Math.pow(2,-c);b=Math.round(8388608*b)&8388607;Ya=0;Xa=(a<<31|c+127<<23|b)>>>0}this.writeUint32(Xa)};\nh.writeDouble=function(a){var b=a,b=(a=0>b?1:0)?-b:b;if(0===b)Ya=0<1/b?0:2147483648,Xa=0;else if(isNaN(b))Ya=2147483647,Xa=4294967295;else if(1.7976931348623157E308<b)Ya=(a<<31|2146435072)>>>0,Xa=0;else if(2.2250738585072014E-308>b)b/=Math.pow(2,-1074),Ya=(a<<31|b/4294967296)>>>0,Xa=b>>>0;else{var c=Math.floor(Math.log(b)/Math.LN2);1024==c&&(c=1023);b*=Math.pow(2,-c);Ya=(a<<31|c+1023<<20|1048576*b&1048575)>>>0;Xa=4503599627370496*b>>>0}this.writeUint32(Xa);this.writeUint32(Ya)};\nh.writeBool=function(a){this.buffer_.push(a?1:0)};h.writeEnum=function(a){tb(this,a)};h.writeBytes=function(a){this.buffer_.push.apply(this.buffer_,a)};h.writeVarintHash64=function(a){db(a);rb(this,Xa,Ya)};h.writeFixedHash64=function(a){db(a);this.writeUint32(Xa);this.writeUint32(Ya)};\nh.writeString=function(a){for(var b=this.buffer_.length,c=0;c<a.length;c++){var d=a.charCodeAt(c);128>d?this.buffer_.push(d):(2048>d?this.buffer_.push(d>>6|192):(this.buffer_.push(d>>12|224),this.buffer_.push(d>>6&63|128)),this.buffer_.push(d&63|128))}return this.buffer_.length-b};\n//~~WEBPATH~~external/com_google_protobuf_js/js/binary/reader.js\nfunction vb(a,b,c){this.decoder_=kb(a,b,c);this.fieldCursor_=this.decoder_.getCursor();this.nextWireType_=this.nextField_=-1;this.error_=!1;this.readCallbacks_=null}var wb=[];h=vb.prototype;h.alloc=function(a,b,c){if(wb.length){var d=wb.pop();a&&d.decoder_.setBlock(a,b,c);return d}return new vb(a,b,c)};h.free=function(){this.decoder_.clear();this.nextWireType_=this.nextField_=-1;this.error_=!1;this.readCallbacks_=null;100>wb.length&&wb.push(this)};h.getFieldCursor=function(){return this.fieldCursor_};\nh.getCursor=function(){return this.decoder_.getCursor()};h.getBuffer=function(){return this.decoder_.getBuffer()};h.getWireType=function(){return this.nextWireType_};h.getError=function(){return this.error_||this.decoder_.getError()};h.setBlock=function(a,b,c){this.decoder_.setBlock(a,b,c);this.nextWireType_=this.nextField_=-1};h.reset=function(){this.decoder_.reset();this.nextWireType_=this.nextField_=-1};h.advance=function(a){this.decoder_.advance(a)};\nfunction xb(a){if(lb(a.decoder_))return!1;if(a.getError())return ka(\"Decoder hit an error\"),!1;a.fieldCursor_=a.decoder_.getCursor();var b=a.decoder_.readUnsignedVarint32(),c=b>>>3,b=b&7;if(0!=b&&5!=b&&1!=b&&2!=b&&3!=b&&4!=b)return ka(\"Invalid wire type\"),a.error_=!0,!1;a.nextField_=c;a.nextWireType_=b;return!0}\nh.skipMatchingFields=function(){var a=this.nextField_;for(nb(this.decoder_,this.nextField_<<3|this.nextWireType_);xb(this)&&this.nextField_==a;)yb(this);lb(this.decoder_)||nb(this.decoder_,this.nextField_<<3|this.nextWireType_)};\nfunction yb(a){switch(a.nextWireType_){case 0:if(0!=a.nextWireType_)ka(\"Invalid wire type for skipVarintField\"),yb(a);else{for(a=a.decoder_;a.bytes_[a.cursor_]&128;)a.cursor_++;a.cursor_++}break;case 1:1!=a.nextWireType_?(ka(\"Invalid wire type for skipFixed64Field\"),yb(a)):a.decoder_.advance(8);break;case 2:if(2!=a.nextWireType_)ka(\"Invalid wire type for skipDelimitedField\"),yb(a);else{var b=a.decoder_.readUnsignedVarint32();a.decoder_.advance(b)}break;case 5:5!=a.nextWireType_?(ka(\"Invalid wire type for skipFixed32Field\"),\nyb(a)):a.decoder_.advance(4);break;case 3:b=[a.nextField_];do{if(!xb(a)){ka(\"Unmatched start-group tag: stream EOF\");a.error_=!0;break}if(3==a.nextWireType_)b.push(a.nextField_);else if(4==a.nextWireType_&&a.nextField_!=b.pop()){ka(\"Unmatched end-group tag\");a.error_=!0;break}}while(0<b.length);break;default:ka(\"Invalid wire encoding for field.\")}}h.registerReadCallback=function(a,b){null===this.readCallbacks_&&(this.readCallbacks_={});this.readCallbacks_[a]=b};h.runReadCallback=function(a){return(0,this.readCallbacks_[a])(this)};\nh.readAny=function(a){this.nextWireType_=Wa(a);switch(a){case 1:return this.readDouble();case 2:return this.readFloat();case 3:return this.readInt64();case 4:return this.readUint64();case 5:return this.readInt32();case 6:return this.decoder_.readUint64();case 7:return this.decoder_.readUint32();case 8:return this.readBool();case 9:return this.readString();case 10:ka(\"Group field type not supported in readAny()\");case 11:ka(\"Message field type not supported in readAny()\");case 12:return this.readBytes();\ncase 13:return this.readUint32();case 14:return this.readEnum();case 15:return this.decoder_.readInt32();case 16:return this.decoder_.readInt64();case 17:return this.decoder_.readZigzagVarint32();case 18:return this.decoder_.readZigzagVarint64();case 30:return this.readFixedHash64();case 31:return this.readVarintHash64();default:ka(\"Invalid field type in readAny()\")}return 0};\nfunction zb(a,b,c){var d=a.decoder_.end_,e=a.decoder_.readUnsignedVarint32(),e=a.decoder_.getCursor()+e;a.decoder_.setEnd(e);c(b,a);a.decoder_.cursor_=e;a.decoder_.setEnd(d)}h.readGroup=function(a,b,c){c(b,this);this.error_||4==this.nextWireType_||(ka(\"Group submessage did not end with an END_GROUP tag\"),this.error_=!0)};h.getFieldDecoder=function(){var a=this.decoder_.readUnsignedVarint32(),b=this.decoder_.getCursor(),c=b+a,a=kb(this.decoder_.getBuffer(),b,a);this.decoder_.cursor_=c;return a};\nh.readInt32=function(){return this.decoder_.readSignedVarint32()};h.readInt32String=function(){return this.decoder_.readSignedVarint32String()};h.readInt64=function(){return this.decoder_.readSignedVarint64()};h.readInt64String=function(){return this.decoder_.readSignedVarint64String()};h.readUint32=function(){return this.decoder_.readUnsignedVarint32()};h.readUint32String=function(){return this.decoder_.readUnsignedVarint32String()};h.readUint64=function(){return this.decoder_.readUnsignedVarint64()};\nh.readUint64String=function(){return this.decoder_.readUnsignedVarint64String()};h.readFloat=function(){return this.decoder_.readFloat()};h.readDouble=function(){return this.decoder_.readDouble()};h.readBool=function(){return!!this.decoder_.readUnsignedVarint32()};h.readEnum=function(){return this.decoder_.readSignedVarint64()};h.readString=function(){var a=this.decoder_.readUnsignedVarint32();return this.decoder_.readString(a)};h.readBytes=function(){var a=this.decoder_.readUnsignedVarint32();return this.decoder_.readBytes(a)};\nh.readVarintHash64=function(){return this.decoder_.readVarintHash64()};h.readFixedHash64=function(){return this.decoder_.readFixedHash64()};function Ab(a,b){for(var c=a.decoder_.readUnsignedVarint32(),c=a.decoder_.getCursor()+c,d=[];a.decoder_.getCursor()<c;)d.push(b.call(a.decoder_));return d}h.readPackedInt32=function(){return Ab(this,this.decoder_.readSignedVarint32)};h.readPackedInt32String=function(){return Ab(this,this.decoder_.readSignedVarint32String)};\nh.readPackedInt64=function(){return Ab(this,this.decoder_.readSignedVarint64)};h.readPackedInt64String=function(){return Ab(this,this.decoder_.readSignedVarint64String)};h.readPackedUint32=function(){return Ab(this,this.decoder_.readUnsignedVarint32)};h.readPackedUint32String=function(){return Ab(this,this.decoder_.readUnsignedVarint32String)};h.readPackedUint64=function(){return Ab(this,this.decoder_.readUnsignedVarint64)};h.readPackedUint64String=function(){return Ab(this,this.decoder_.readUnsignedVarint64String)};\nh.readPackedSint32=function(){return Ab(this,this.decoder_.readZigzagVarint32)};h.readPackedSint64=function(){return Ab(this,this.decoder_.readZigzagVarint64)};h.readPackedFixed32=function(){return Ab(this,this.decoder_.readUint32)};h.readPackedFixed64=function(){return Ab(this,this.decoder_.readUint64)};h.readPackedSfixed32=function(){return Ab(this,this.decoder_.readInt32)};h.readPackedSfixed64=function(){return Ab(this,this.decoder_.readInt64)};h.readPackedFloat=function(){return Ab(this,this.decoder_.readFloat)};\nh.readPackedDouble=function(){return Ab(this,this.decoder_.readDouble)};h.readPackedBool=function(){return Ab(this,this.decoder_.readBool)};h.readPackedEnum=function(){return Ab(this,this.decoder_.readEnum)};h.readPackedVarintHash64=function(){return Ab(this,this.decoder_.readVarintHash64)};h.readPackedFixedHash64=function(){return Ab(this,this.decoder_.readFixedHash64)};\n//~~WEBPATH~~external/com_google_protobuf_js/js/binary/writer.js\nfunction Bb(){this.blocks_=[];this.totalLength_=0;this.encoder_=new qb;this.bookmarks_=[]}function Cb(a,b){var c=a.encoder_.end();a.blocks_.push(c);a.blocks_.push(b);a.totalLength_+=c.length+b.length}function Eb(a,b){V(a,b,2);b=a.encoder_.end();a.blocks_.push(b);a.totalLength_+=b.length;b.push(a.totalLength_);return b}function Fb(a,b){for(var c=b.pop(),c=a.totalLength_+a.encoder_.length()-c;127<c;)b.push(c&127|128),c>>>=7,a.totalLength_++;b.push(c);a.totalLength_++}h=Bb.prototype;\nh.maybeWriteSerializedMessage=function(a,b,c){null!=a&&null!=b&&null!=c&&Cb(this,a.subarray(b,c))};h.reset=function(){this.blocks_=[];this.encoder_.end();this.totalLength_=0;this.bookmarks_=[]};function Gb(a){for(var b=new Uint8Array(a.totalLength_+a.encoder_.length()),c=a.blocks_,d=c.length,e=0,f=0;f<d;f++){var g=c[f];b.set(g,e);e+=g.length}c=a.encoder_.end();b.set(c,e);a.blocks_=[b];return b}\nh.getResultBase64String=function(){var a=Gb(this);ua();for(var b=pa,c=[],d=0;d<a.length;d+=3){var e=a[d],f=d+1<a.length,g=f?a[d+1]:0,k=d+2<a.length,l=k?a[d+2]:0,m=e>>2,e=(e&3)<<4|g>>4,g=(g&15)<<2|l>>6,l=l&63;k||(l=64,f||(g=64));c.push(b[m],b[e],b[g],b[l])}return c.join(\"\")};h.beginSubMessage=function(a){this.bookmarks_.push(Eb(this,a))};h.endSubMessage=function(){Fb(this,this.bookmarks_.pop())};function V(a,b,c){sb(a.encoder_,8*b+c)}\nh.writeAny=function(a,b,c){switch(a){case 1:this.writeDouble(b,c);break;case 2:this.writeFloat(b,c);break;case 3:this.writeInt64(b,c);break;case 4:this.writeUint64(b,c);break;case 5:this.writeInt32(b,c);break;case 6:null!=c&&(V(this,b,1),this.encoder_.writeUint64(c));break;case 7:null!=c&&(V(this,b,5),this.encoder_.writeUint32(c));break;case 8:this.writeBool(b,c);break;case 9:this.writeString(b,c);break;case 10:ka(\"Group field type not supported in writeAny()\");break;case 11:ka(\"Message field type not supported in writeAny()\");\nbreak;case 12:this.writeBytes(b,c);break;case 13:this.writeUint32(b,c);break;case 14:this.writeEnum(b,c);break;case 15:null!=c&&(V(this,b,5),this.encoder_.writeInt32(c));break;case 16:null!=c&&(V(this,b,1),this.encoder_.writeInt64(c));break;case 17:null!=c&&null!=c&&(V(this,b,0),ub(this.encoder_,c));break;case 18:null!=c&&null!=c&&(V(this,b,0),a=this.encoder_,cb(c),rb(a,Xa,Ya));break;case 30:this.writeFixedHash64(b,c);break;case 31:this.writeVarintHash64(b,c);break;default:ka(\"Invalid field type in writeAny()\")}};\nfunction Hb(a,b,c){null!=c&&(V(a,b,0),sb(a.encoder_,c))}function Ib(a,b,c){null!=c&&(V(a,b,0),tb(a.encoder_,c))}h.writeInt32=function(a,b){null!=b&&Ib(this,a,b)};h.writeInt64=function(a,b){null!=b&&null!=b&&(V(this,a,0),a=this.encoder_,bb(b),rb(a,Xa,Ya))};h.writeUint32=function(a,b){null!=b&&Hb(this,a,b)};h.writeUint64=function(a,b){null!=b&&null!=b&&(V(this,a,0),a=this.encoder_,bb(b),rb(a,Xa,Ya))};h.writeFloat=function(a,b){null!=b&&(V(this,a,5),this.encoder_.writeFloat(b))};\nh.writeDouble=function(a,b){null!=b&&(V(this,a,1),this.encoder_.writeDouble(b))};h.writeBool=function(a,b){null!=b&&(V(this,a,0),this.encoder_.writeBool(b))};h.writeEnum=function(a,b){null!=b&&(V(this,a,0),tb(this.encoder_,b))};h.writeString=function(a,b){null!=b&&(a=Eb(this,a),this.encoder_.writeString(b),Fb(this,a))};h.writeBytes=function(a,b){null!=b&&(b=hb(b),V(this,a,2),sb(this.encoder_,b.length),Cb(this,b))};function Jb(a,b,c,d){null!=c&&(b=Eb(a,b),d(c,a),Fb(a,b))}\nh.writeGroup=function(a,b,c){null!=b&&(V(this,a,3),c(b,this),V(this,a,4))};h.writeFixedHash64=function(a,b){null!=b&&(V(this,a,1),this.encoder_.writeFixedHash64(b))};h.writeVarintHash64=function(a,b){null!=b&&(V(this,a,0),this.encoder_.writeVarintHash64(b))};h.writeRepeatedUnsignedVarint32_=function(a,b){if(null!=b)for(var c=0;c<b.length;c++)Hb(this,a,b[c])};h.writeRepeatedSignedVarint32_=function(a,b){if(null!=b)for(var c=0;c<b.length;c++)Ib(this,a,b[c])};\nh.writeRepeatedUnsignedVarint64_=function(a,b){if(null!=b)for(var c=0;c<b.length;c++){var d=b[c];if(null!=d){V(this,a,0);var e=this.encoder_;bb(d);rb(e,Xa,Ya)}}};h.writeRepeatedSignedVarint64_=function(a,b){if(null!=b)for(var c=0;c<b.length;c++){var d=b[c];if(null!=d){V(this,a,0);var e=this.encoder_;bb(d);rb(e,Xa,Ya)}}};h.writeRepeatedZigzag32_=function(a,b){if(null!=b)for(var c=0;c<b.length;c++){var d=b[c];null!=d&&(V(this,a,0),ub(this.encoder_,d))}};\nh.writeRepeatedZigzag_=function(a,b){if(null!=b)for(var c=0;c<b.length;c++){var d=b[c];if(null!=d){V(this,a,0);var e=this.encoder_;cb(d);rb(e,Xa,Ya)}}};h.writeRepeatedInt32=Bb.prototype.writeRepeatedSignedVarint32_;h.writeRepeatedInt32String=function(a,b){if(null!=b)for(var c=0;c<b.length;c++){var d=b[c];null!=d&&Ib(this,a,parseInt(d,10))}};h.writeRepeatedInt64=Bb.prototype.writeRepeatedSignedVarint64_;\nh.writeRepeatedInt64String=function(a,b){if(null!=b)for(var c=0;c<b.length;c++){var d=a,e=b[c];null!=e&&(e=Ua(e),V(this,d,0),rb(this.encoder_,e.lo,e.hi))}};h.writeRepeatedUint32=Bb.prototype.writeRepeatedUnsignedVarint32_;h.writeRepeatedUint32String=function(a,b){if(null!=b)for(var c=0;c<b.length;c++){var d=b[c];null!=d&&Hb(this,a,parseInt(d,10))}};h.writeRepeatedUint64=Bb.prototype.writeRepeatedUnsignedVarint64_;\nh.writeRepeatedUint64String=function(a,b){if(null!=b)for(var c=0;c<b.length;c++){var d=a,e=b[c];null!=e&&(e=Sa(e),V(this,d,0),rb(this.encoder_,e.lo,e.hi))}};h.writeRepeatedSint32=Bb.prototype.writeRepeatedZigzag32_;h.writeRepeatedSint64=Bb.prototype.writeRepeatedZigzag_;h.writeRepeatedFixed32=function(a,b){if(null!=b)for(var c=0;c<b.length;c++){var d=b[c];null!=d&&(V(this,a,5),this.encoder_.writeUint32(d))}};\nh.writeRepeatedFixed64=function(a,b){if(null!=b)for(var c=0;c<b.length;c++){var d=b[c];null!=d&&(V(this,a,1),this.encoder_.writeUint64(d))}};h.writeRepeatedSfixed32=function(a,b){if(null!=b)for(var c=0;c<b.length;c++){var d=b[c];null!=d&&(V(this,a,5),this.encoder_.writeInt32(d))}};h.writeRepeatedSfixed64=function(a,b){if(null!=b)for(var c=0;c<b.length;c++){var d=b[c];null!=d&&(V(this,a,1),this.encoder_.writeInt64(d))}};\nh.writeRepeatedFloat=function(a,b){if(null!=b)for(var c=0;c<b.length;c++)this.writeFloat(a,b[c])};h.writeRepeatedDouble=function(a,b){if(null!=b)for(var c=0;c<b.length;c++)this.writeDouble(a,b[c])};h.writeRepeatedBool=function(a,b){if(null!=b)for(var c=0;c<b.length;c++)this.writeBool(a,b[c])};h.writeRepeatedEnum=function(a,b){if(null!=b)for(var c=0;c<b.length;c++)this.writeEnum(a,b[c])};h.writeRepeatedString=function(a,b){if(null!=b)for(var c=0;c<b.length;c++)this.writeString(a,b[c])};\nh.writeRepeatedBytes=function(a,b){if(null!=b)for(var c=0;c<b.length;c++)this.writeBytes(a,b[c])};function Mb(a,b,c,d){if(null!=c)for(var e=0;e<c.length;e++){var f=Eb(a,b);d(c[e],a);Fb(a,f)}}h.writeRepeatedGroup=function(a,b,c){if(null!=b)for(var d=0;d<b.length;d++)V(this,a,3),c(b[d],this),V(this,a,4)};h.writeRepeatedFixedHash64=function(a,b){if(null!=b)for(var c=0;c<b.length;c++)this.writeFixedHash64(a,b[c])};\nh.writeRepeatedVarintHash64=function(a,b){if(null!=b)for(var c=0;c<b.length;c++)this.writeVarintHash64(a,b[c])};h.writePackedUnsignedVarint32_=function(a,b){if(null!=b&&b.length){a=Eb(this,a);for(var c=0;c<b.length;c++)sb(this.encoder_,b[c]);Fb(this,a)}};h.writePackedSignedVarint32_=function(a,b){if(null!=b&&b.length){a=Eb(this,a);for(var c=0;c<b.length;c++)tb(this.encoder_,b[c]);Fb(this,a)}};\nh.writePackedUnsignedVarint64_=function(a,b){if(null!=b&&b.length){a=Eb(this,a);for(var c=0;c<b.length;c++){var d=this.encoder_;bb(b[c]);rb(d,Xa,Ya)}Fb(this,a)}};h.writePackedSignedVarint64_=function(a,b){if(null!=b&&b.length){a=Eb(this,a);for(var c=0;c<b.length;c++){var d=this.encoder_;bb(b[c]);rb(d,Xa,Ya)}Fb(this,a)}};h.writePackedZigzag32_=function(a,b){if(null!=b&&b.length){a=Eb(this,a);for(var c=0;c<b.length;c++)ub(this.encoder_,b[c]);Fb(this,a)}};\nh.writePackedZigzag64_=function(a,b){if(null!=b&&b.length){a=Eb(this,a);for(var c=0;c<b.length;c++){var d=this.encoder_;cb(b[c]);rb(d,Xa,Ya)}Fb(this,a)}};h.writePackedInt32=Bb.prototype.writePackedSignedVarint32_;h.writePackedInt32String=function(a,b){if(null!=b&&b.length){a=Eb(this,a);for(var c=0;c<b.length;c++)tb(this.encoder_,parseInt(b[c],10));Fb(this,a)}};h.writePackedInt64=Bb.prototype.writePackedSignedVarint64_;\nh.writePackedInt64String=function(a,b){if(null!=b&&b.length){a=Eb(this,a);for(var c=0;c<b.length;c++){var d=Ua(b[c]);rb(this.encoder_,d.lo,d.hi)}Fb(this,a)}};h.writePackedUint32=Bb.prototype.writePackedUnsignedVarint32_;h.writePackedUint32String=function(a,b){if(null!=b&&b.length){a=Eb(this,a);for(var c=0;c<b.length;c++)sb(this.encoder_,parseInt(b[c],10));Fb(this,a)}};h.writePackedUint64=Bb.prototype.writePackedUnsignedVarint64_;\nh.writePackedUint64String=function(a,b){if(null!=b&&b.length){a=Eb(this,a);for(var c=0;c<b.length;c++){var d=Sa(b[c]);rb(this.encoder_,d.lo,d.hi)}Fb(this,a)}};h.writePackedSint32=Bb.prototype.writePackedZigzag32_;h.writePackedSint64=Bb.prototype.writePackedZigzag64_;h.writePackedFixed32=function(a,b){if(null!=b&&b.length)for(V(this,a,2),sb(this.encoder_,4*b.length),a=0;a<b.length;a++)this.encoder_.writeUint32(b[a])};\nh.writePackedFixed64=function(a,b){if(null!=b&&b.length)for(V(this,a,2),sb(this.encoder_,8*b.length),a=0;a<b.length;a++)this.encoder_.writeUint64(b[a])};h.writePackedSfixed32=function(a,b){if(null!=b&&b.length)for(V(this,a,2),sb(this.encoder_,4*b.length),a=0;a<b.length;a++)this.encoder_.writeInt32(b[a])};h.writePackedSfixed64=function(a,b){if(null!=b&&b.length)for(V(this,a,2),sb(this.encoder_,8*b.length),a=0;a<b.length;a++)this.encoder_.writeInt64(b[a])};\nh.writePackedFloat=function(a,b){if(null!=b&&b.length)for(V(this,a,2),sb(this.encoder_,4*b.length),a=0;a<b.length;a++)this.encoder_.writeFloat(b[a])};h.writePackedDouble=function(a,b){if(null!=b&&b.length)for(V(this,a,2),sb(this.encoder_,8*b.length),a=0;a<b.length;a++)this.encoder_.writeDouble(b[a])};h.writePackedBool=function(a,b){if(null!=b&&b.length)for(V(this,a,2),sb(this.encoder_,b.length),a=0;a<b.length;a++)this.encoder_.writeBool(b[a])};\nh.writePackedEnum=function(a,b){if(null!=b&&b.length){a=Eb(this,a);for(var c=0;c<b.length;c++)this.encoder_.writeEnum(b[c]);Fb(this,a)}};h.writePackedFixedHash64=function(a,b){if(null!=b&&b.length)for(V(this,a,2),sb(this.encoder_,8*b.length),a=0;a<b.length;a++)this.encoder_.writeFixedHash64(b[a])};h.writePackedVarintHash64=function(a,b){if(null!=b&&b.length){a=Eb(this,a);for(var c=0;c<b.length;c++)this.encoder_.writeVarintHash64(b[c]);Fb(this,a)}};\n//~~WEBPATH~~bazel-out/local-fastbuild/genfiles/facets_overview/proto/proto.js\nfunction Nb(a){xa(this,a,Ob,null)}da(Nb,va);var Ob=[1];Nb.prototype.toObject=function(a){var b={datasetsList:Ba(Pb(this),Qb,a)};a&&(b.$jspbMessageInstance=this);return b};function Rb(a){a=new vb(a);for(var b=new Nb;xb(a)&&4!=a.nextWireType_;)switch(a.nextField_){case 1:var c=new Sb;zb(a,c,Tb);Ja(b,1,c,Sb,void 0);break;default:yb(a)}return b}Nb.prototype.serializeBinary=function(){var a=new Bb;this.serializeBinaryToWriter(a);return Gb(a)};\nNb.prototype.serializeBinaryToWriter=function(a){var b=Pb(this);0<b.length&&Mb(a,1,b,Ub)};function Pb(a){return Ea(a,Sb,1)}Nb.prototype.clearDatasetsList=function(){Ia(this,1,[])};function Sb(a){xa(this,a,Vb,null)}da(Sb,va);var Vb=[3];h=Sb.prototype;h.toObject=function(a){return Qb(a,this)};function Qb(a,b){var c={name:u(b,1,\"\"),numExamples:u(b,2,0),weightedNumExamples:+u(b,4,0),featuresList:Ba(Wb(b),Xb,a)};a&&(c.$jspbMessageInstance=b);return c}\nfunction Tb(a,b){for(;xb(b)&&4!=b.nextWireType_;)switch(b.nextField_){case 1:var c=b.readString();a.setName(c);break;case 2:c=b.readUint64();G(a,2,c);break;case 4:c=b.readDouble();G(a,4,c);break;case 3:c=new Yb;zb(b,c,Zb);Ja(a,3,c,Yb,void 0);break;default:yb(b)}return a}function Ub(a,b){a.serializeBinaryToWriter(b)}h.serializeBinary=function(){var a=new Bb;this.serializeBinaryToWriter(a);return Gb(a)};\nh.serializeBinaryToWriter=function(a){var b=this.getName();0<b.length&&a.writeString(1,b);b=u(this,2,0);0!==b&&a.writeUint64(2,b);b=+u(this,4,0);0!==b&&a.writeDouble(4,b);b=Wb(this);0<b.length&&Mb(a,3,b,$b)};h.getName=function(){return u(this,1,\"\")};h.setName=function(a){G(this,1,a)};function Wb(a){return Ea(a,Yb,3)}h.clearFeaturesList=function(){Ia(this,3,[])};function Yb(a){xa(this,a,ac,fc)}da(Yb,va);var ac=[6],fc=[[3,4,5]];h=Yb.prototype;h.getStatsCase=function(){return za(this,fc[0])};\nh.toObject=function(a){return Xb(a,this)};function Xb(a,b){var c,d={name:u(b,1,\"\"),type:u(b,2,0),numStats:(c=W(b))&&gc(a,c),stringStats:(c=hc(b))&&ic(a,c),bytesStats:(c=jc(b))&&kc(a,c),customStatsList:Ba(lc(b),mc,a)};a&&(d.$jspbMessageInstance=b);return d}\nfunction Zb(a,b){for(;xb(b)&&4!=b.nextWireType_;)switch(b.nextField_){case 1:var c=b.readString();a.setName(c);break;case 2:c=b.readEnum();a.setType(c);break;case 3:c=new nc;zb(b,c,oc);Ha(a,3,fc[0],c);break;case 4:c=new pc;zb(b,c,qc);Ha(a,4,fc[0],c);break;case 5:c=new rc;zb(b,c,sc);Ha(a,5,fc[0],c);break;case 6:c=new tc;zb(b,c,uc);Ja(a,6,c,tc,void 0);break;default:yb(b)}return a}function $b(a,b){a.serializeBinaryToWriter(b)}\nh.serializeBinary=function(){var a=new Bb;this.serializeBinaryToWriter(a);return Gb(a)};h.serializeBinaryToWriter=function(a){var b=this.getName();0<b.length&&a.writeString(1,b);b=this.getType();0!==b&&a.writeEnum(2,b);b=W(this);null!=b&&Jb(a,3,b,vc);b=hc(this);null!=b&&Jb(a,4,b,wc);b=jc(this);null!=b&&Jb(a,5,b,xc);b=lc(this);0<b.length&&Mb(a,6,b,yc)};h.getName=function(){return u(this,1,\"\")};h.setName=function(a){G(this,1,a)};h.getType=function(){return u(this,2,0)};\nh.setType=function(a){G(this,2,a)};function W(a){return O(a,nc,3)}h.clearNumStats=function(){Ha(this,3,fc[0],void 0)};h.hasNumStats=function(){return null!=Ca(this,3)};function hc(a){return O(a,pc,4)}h.clearStringStats=function(){Ha(this,4,fc[0],void 0)};h.hasStringStats=function(){return null!=Ca(this,4)};function jc(a){return O(a,rc,5)}h.clearBytesStats=function(){Ha(this,5,fc[0],void 0)};h.hasBytesStats=function(){return null!=Ca(this,5)};function lc(a){return Ea(a,tc,6)}\nh.clearCustomStatsList=function(){Ia(this,6,[])};function zc(a){xa(this,a,null,null)}da(zc,va);h=zc.prototype;h.toObject=function(a){return Gc(a,this)};function Gc(a,b){var c={numNonMissing:+u(b,1,0),numMissing:+u(b,2,0),avgNumValues:+u(b,3,0),totNumValues:+u(b,4,0)};a&&(c.$jspbMessageInstance=b);return c}\nfunction Hc(a,b){for(;xb(b)&&4!=b.nextWireType_;)switch(b.nextField_){case 1:var c=b.readDouble();a.setNumNonMissing(c);break;case 2:c=b.readDouble();a.setNumMissing(c);break;case 3:c=b.readDouble();a.setAvgNumValues(c);break;case 4:c=b.readDouble();a.setTotNumValues(c);break;default:yb(b)}return a}function Ic(a,b){a.serializeBinaryToWriter(b)}h.serializeBinary=function(){var a=new Bb;this.serializeBinaryToWriter(a);return Gb(a)};\nh.serializeBinaryToWriter=function(a){var b=this.getNumNonMissing();0!==b&&a.writeDouble(1,b);b=this.getNumMissing();0!==b&&a.writeDouble(2,b);b=this.getAvgNumValues();0!==b&&a.writeDouble(3,b);b=this.getTotNumValues();0!==b&&a.writeDouble(4,b)};h.getNumNonMissing=function(){return+u(this,1,0)};h.setNumNonMissing=function(a){G(this,1,a)};h.getNumMissing=function(){return+u(this,2,0)};h.setNumMissing=function(a){G(this,2,a)};h.getAvgNumValues=function(){return+u(this,3,0)};\nh.setAvgNumValues=function(a){G(this,3,a)};h.getTotNumValues=function(){return+u(this,4,0)};h.setTotNumValues=function(a){G(this,4,a)};function tc(a){xa(this,a,null,Jc)}da(tc,va);var Jc=[[2,3,4]];h=tc.prototype;h.getValCase=function(){return za(this,Jc[0])};h.toObject=function(a){return mc(a,this)};function mc(a,b){var c,d={name:u(b,1,\"\"),num:+u(b,2,0),str:u(b,3,\"\"),histogram:(c=O(b,Kc,4))&&Lc(a,c)};a&&(d.$jspbMessageInstance=b);return d}\nfunction uc(a,b){for(;xb(b)&&4!=b.nextWireType_;)switch(b.nextField_){case 1:var c=b.readString();a.setName(c);break;case 2:c=b.readDouble();Da(a,2,Jc[0],c);break;case 3:c=b.readString();Da(a,3,Jc[0],c);break;case 4:c=new Kc;zb(b,c,Mc);Ha(a,4,Jc[0],c);break;default:yb(b)}return a}function yc(a,b){a.serializeBinaryToWriter(b)}h.serializeBinary=function(){var a=new Bb;this.serializeBinaryToWriter(a);return Gb(a)};\nh.serializeBinaryToWriter=function(a){var b=this.getName();0<b.length&&a.writeString(1,b);b=Ca(this,2);null!=b&&a.writeDouble(2,b);b=Ca(this,3);null!=b&&a.writeString(3,b);b=O(this,Kc,4);null!=b&&Jb(a,4,b,Nc)};h.getName=function(){return u(this,1,\"\")};h.setName=function(a){G(this,1,a)};h.clearNum=function(){Da(this,2,Jc[0],void 0)};h.hasNum=function(){return null!=Ca(this,2)};h.clearStr=function(){Da(this,3,Jc[0],void 0)};h.hasStr=function(){return null!=Ca(this,3)};\nh.clearHistogram=function(){Ha(this,4,Jc[0],void 0)};h.hasHistogram=function(){return null!=Ca(this,4)};function nc(a){xa(this,a,Oc,null)}da(nc,va);var Oc=[8];h=nc.prototype;h.toObject=function(a){return gc(a,this)};function gc(a,b){var c,d={commonStats:(c=Pc(b))&&Qc(a,c),mean:+u(b,2,0),stdDev:+u(b,3,0),numZeros:u(b,4,0),min:+u(b,5,0),median:+u(b,6,0),max:+u(b,7,0),histogramsList:Ba(b.getHistogramsList(),Lc,a),weightedNumericStats:(c=O(b,Rc,9))&&Sc(a,c)};a&&(d.$jspbMessageInstance=b);return d}\nfunction oc(a,b){for(;xb(b)&&4!=b.nextWireType_;)switch(b.nextField_){case 1:var c=new Tc;zb(b,c,Uc);a.setCommonStats(c);break;case 2:c=b.readDouble();a.setMean(c);break;case 3:c=b.readDouble();a.setStdDev(c);break;case 4:c=b.readUint64();G(a,4,c);break;case 5:c=b.readDouble();G(a,5,c);break;case 6:c=b.readDouble();a.setMedian(c);break;case 7:c=b.readDouble();G(a,7,c);break;case 8:c=new Kc;zb(b,c,Mc);a.addHistograms(c);break;case 9:c=new Rc;zb(b,c,ad);Ga(a,9,c);break;default:yb(b)}return a}\nfunction vc(a,b){a.serializeBinaryToWriter(b)}h.serializeBinary=function(){var a=new Bb;this.serializeBinaryToWriter(a);return Gb(a)};\nh.serializeBinaryToWriter=function(a){var b=Pc(this);null!=b&&Jb(a,1,b,bd);b=this.getMean();0!==b&&a.writeDouble(2,b);b=this.getStdDev();0!==b&&a.writeDouble(3,b);b=u(this,4,0);0!==b&&a.writeUint64(4,b);b=+u(this,5,0);0!==b&&a.writeDouble(5,b);b=this.getMedian();0!==b&&a.writeDouble(6,b);b=+u(this,7,0);0!==b&&a.writeDouble(7,b);b=this.getHistogramsList();0<b.length&&Mb(a,8,b,Nc);b=O(this,Rc,9);null!=b&&Jb(a,9,b,cd)};function Pc(a){return O(a,Tc,1)}h.setCommonStats=function(a){Ga(this,1,a)};\nh.clearCommonStats=function(){this.setCommonStats(void 0)};h.hasCommonStats=function(){return null!=Ca(this,1)};h.getMean=function(){return+u(this,2,0)};h.setMean=function(a){G(this,2,a)};h.getStdDev=function(){return+u(this,3,0)};h.setStdDev=function(a){G(this,3,a)};h.getMedian=function(){return+u(this,6,0)};h.setMedian=function(a){G(this,6,a)};h.getHistogramsList=function(){return Ea(this,Kc,8)};h.setHistogramsList=function(a){Ia(this,8,a)};h.addHistograms=function(a,b){return Ja(this,8,a,Kc,b)};\nh.clearHistogramsList=function(){this.setHistogramsList([])};h.clearWeightedNumericStats=function(){Ga(this,9,void 0)};h.hasWeightedNumericStats=function(){return null!=Ca(this,9)};function pc(a){xa(this,a,dd,null)}da(pc,va);var dd=[3];h=pc.prototype;h.toObject=function(a){return ic(a,this)};\nfunction ic(a,b){var c,d={commonStats:(c=Pc(b))&&Qc(a,c),unique:u(b,2,0),topValuesList:Ba(b.getTopValuesList(),ed,a),avgLength:+u(b,4,0),rankHistogram:(c=b.getRankHistogram())&&fd(a,c),weightedStringStats:(c=O(b,gd,6))&&hd(a,c)};a&&(d.$jspbMessageInstance=b);return d}\nfunction qc(a,b){for(;xb(b)&&4!=b.nextWireType_;)switch(b.nextField_){case 1:var c=new Tc;zb(b,c,Uc);a.setCommonStats(c);break;case 2:c=b.readUint64();a.setUnique(c);break;case 3:c=new id;zb(b,c,jd);a.addTopValues(c);break;case 4:c=b.readFloat();G(a,4,c);break;case 5:c=new kd;zb(b,c,ld);a.setRankHistogram(c);break;case 6:c=new gd;zb(b,c,md);Ga(a,6,c);break;default:yb(b)}return a}function wc(a,b){a.serializeBinaryToWriter(b)}\nh.serializeBinary=function(){var a=new Bb;this.serializeBinaryToWriter(a);return Gb(a)};h.serializeBinaryToWriter=function(a){var b=Pc(this);null!=b&&Jb(a,1,b,bd);b=u(this,2,0);0!==b&&a.writeUint64(2,b);b=this.getTopValuesList();0<b.length&&Mb(a,3,b,nd);b=+u(this,4,0);0!==b&&a.writeFloat(4,b);b=this.getRankHistogram();null!=b&&Jb(a,5,b,od);b=O(this,gd,6);null!=b&&Jb(a,6,b,pd)};h.getCommonStats=function(){return O(this,Tc,1)};h.setCommonStats=function(a){Ga(this,1,a)};h.clearCommonStats=function(){this.setCommonStats(void 0)};\nh.hasCommonStats=function(){return null!=Ca(this,1)};h.setUnique=function(a){G(this,2,a)};h.getTopValuesList=function(){return Ea(this,id,3)};h.setTopValuesList=function(a){Ia(this,3,a)};h.addTopValues=function(a,b){return Ja(this,3,a,id,b)};h.clearTopValuesList=function(){this.setTopValuesList([])};h.getRankHistogram=function(){return O(this,kd,5)};h.setRankHistogram=function(a){Ga(this,5,a)};h.clearRankHistogram=function(){this.setRankHistogram(void 0)};\nh.hasRankHistogram=function(){return null!=Ca(this,5)};h.clearWeightedStringStats=function(){Ga(this,6,void 0)};h.hasWeightedStringStats=function(){return null!=Ca(this,6)};function id(a){xa(this,a,null,null)}da(id,va);h=id.prototype;h.toObject=function(a){return ed(a,this)};function ed(a,b){var c={deprecatedFreq:u(b,1,0),value:u(b,2,\"\"),frequency:+u(b,3,0)};a&&(c.$jspbMessageInstance=b);return c}\nfunction jd(a,b){for(;xb(b)&&4!=b.nextWireType_;)switch(b.nextField_){case 1:var c=b.readUint64();G(a,1,c);break;case 2:c=b.readString();a.setValue(c);break;case 3:c=b.readDouble();G(a,3,c);break;default:yb(b)}return a}function nd(a,b){a.serializeBinaryToWriter(b)}h.serializeBinary=function(){var a=new Bb;this.serializeBinaryToWriter(a);return Gb(a)};\nh.serializeBinaryToWriter=function(a){var b=u(this,1,0);0!==b&&a.writeUint64(1,b);b=this.getValue();0<b.length&&a.writeString(2,b);b=+u(this,3,0);0!==b&&a.writeDouble(3,b)};h.getValue=function(){return u(this,2,\"\")};h.setValue=function(a){G(this,2,a)};function Rc(a){xa(this,a,qd,null)}da(Rc,va);var qd=[4];h=Rc.prototype;h.toObject=function(a){return Sc(a,this)};\nfunction Sc(a,b){var c={mean:+u(b,1,0),stdDev:+u(b,2,0),median:+u(b,3,0),histogramsList:Ba(b.getHistogramsList(),Lc,a)};a&&(c.$jspbMessageInstance=b);return c}function ad(a,b){for(;xb(b)&&4!=b.nextWireType_;)switch(b.nextField_){case 1:var c=b.readDouble();a.setMean(c);break;case 2:c=b.readDouble();a.setStdDev(c);break;case 3:c=b.readDouble();a.setMedian(c);break;case 4:c=new Kc;zb(b,c,Mc);a.addHistograms(c);break;default:yb(b)}return a}function cd(a,b){a.serializeBinaryToWriter(b)}\nh.serializeBinary=function(){var a=new Bb;this.serializeBinaryToWriter(a);return Gb(a)};h.serializeBinaryToWriter=function(a){var b=this.getMean();0!==b&&a.writeDouble(1,b);b=this.getStdDev();0!==b&&a.writeDouble(2,b);b=this.getMedian();0!==b&&a.writeDouble(3,b);b=this.getHistogramsList();0<b.length&&Mb(a,4,b,Nc)};h.getMean=function(){return+u(this,1,0)};h.setMean=function(a){G(this,1,a)};h.getStdDev=function(){return+u(this,2,0)};h.setStdDev=function(a){G(this,2,a)};\nh.getMedian=function(){return+u(this,3,0)};h.setMedian=function(a){G(this,3,a)};h.getHistogramsList=function(){return Ea(this,Kc,4)};h.setHistogramsList=function(a){Ia(this,4,a)};h.addHistograms=function(a,b){return Ja(this,4,a,Kc,b)};h.clearHistogramsList=function(){this.setHistogramsList([])};function gd(a){xa(this,a,rd,null)}da(gd,va);var rd=[1];h=gd.prototype;h.toObject=function(a){return hd(a,this)};\nfunction hd(a,b){var c,d={topValuesList:Ba(b.getTopValuesList(),ed,a),rankHistogram:(c=b.getRankHistogram())&&fd(a,c)};a&&(d.$jspbMessageInstance=b);return d}function md(a,b){for(;xb(b)&&4!=b.nextWireType_;)switch(b.nextField_){case 1:var c=new id;zb(b,c,jd);a.addTopValues(c);break;case 2:c=new kd;zb(b,c,ld);a.setRankHistogram(c);break;default:yb(b)}return a}function pd(a,b){a.serializeBinaryToWriter(b)}h.serializeBinary=function(){var a=new Bb;this.serializeBinaryToWriter(a);return Gb(a)};\nh.serializeBinaryToWriter=function(a){var b=this.getTopValuesList();0<b.length&&Mb(a,1,b,nd);b=this.getRankHistogram();null!=b&&Jb(a,2,b,od)};h.getTopValuesList=function(){return Ea(this,id,1)};h.setTopValuesList=function(a){Ia(this,1,a)};h.addTopValues=function(a,b){return Ja(this,1,a,id,b)};h.clearTopValuesList=function(){this.setTopValuesList([])};h.getRankHistogram=function(){return O(this,kd,2)};h.setRankHistogram=function(a){Ga(this,2,a)};h.clearRankHistogram=function(){this.setRankHistogram(void 0)};\nh.hasRankHistogram=function(){return null!=Ca(this,2)};function rc(a){xa(this,a,null,null)}da(rc,va);h=rc.prototype;h.toObject=function(a){return kc(a,this)};function kc(a,b){var c,d={commonStats:(c=Pc(b))&&Qc(a,c),unique:u(b,2,0),avgNumBytes:+u(b,3,0),minNumBytes:+u(b,4,0),maxNumBytes:+u(b,5,0)};a&&(d.$jspbMessageInstance=b);return d}\nfunction sc(a,b){for(;xb(b)&&4!=b.nextWireType_;)switch(b.nextField_){case 1:var c=new Tc;zb(b,c,Uc);a.setCommonStats(c);break;case 2:c=b.readUint64();a.setUnique(c);break;case 3:c=b.readFloat();G(a,3,c);break;case 4:c=b.readFloat();G(a,4,c);break;case 5:c=b.readFloat();G(a,5,c);break;default:yb(b)}return a}function xc(a,b){a.serializeBinaryToWriter(b)}h.serializeBinary=function(){var a=new Bb;this.serializeBinaryToWriter(a);return Gb(a)};\nh.serializeBinaryToWriter=function(a){var b=Pc(this);null!=b&&Jb(a,1,b,bd);b=u(this,2,0);0!==b&&a.writeUint64(2,b);b=+u(this,3,0);0!==b&&a.writeFloat(3,b);b=+u(this,4,0);0!==b&&a.writeFloat(4,b);b=+u(this,5,0);0!==b&&a.writeFloat(5,b)};h.getCommonStats=function(){return O(this,Tc,1)};h.setCommonStats=function(a){Ga(this,1,a)};h.clearCommonStats=function(){this.setCommonStats(void 0)};h.hasCommonStats=function(){return null!=Ca(this,1)};h.getUnique=function(){return u(this,2,0)};\nh.setUnique=function(a){G(this,2,a)};function Tc(a){xa(this,a,null,null)}da(Tc,va);h=Tc.prototype;h.toObject=function(a){return Qc(a,this)};function Qc(a,b){var c,d={numNonMissing:u(b,1,0),numMissing:u(b,2,0),minNumValues:u(b,3,0),maxNumValues:u(b,4,0),avgNumValues:+u(b,5,0),totNumValues:u(b,8,0),numValuesHistogram:(c=O(b,Kc,6))&&Lc(a,c),weightedCommonStats:(c=O(b,zc,7))&&Gc(a,c),featureListLengthHistogram:(c=O(b,Kc,9))&&Lc(a,c)};a&&(d.$jspbMessageInstance=b);return d}\nfunction Uc(a,b){for(;xb(b)&&4!=b.nextWireType_;)switch(b.nextField_){case 1:var c=b.readUint64();a.setNumNonMissing(c);break;case 2:c=b.readUint64();a.setNumMissing(c);break;case 3:c=b.readUint64();G(a,3,c);break;case 4:c=b.readUint64();G(a,4,c);break;case 5:c=b.readFloat();a.setAvgNumValues(c);break;case 8:c=b.readUint64();a.setTotNumValues(c);break;case 6:c=new Kc;zb(b,c,Mc);Ga(a,6,c);break;case 7:c=new zc;zb(b,c,Hc);Ga(a,7,c);break;case 9:c=new Kc;zb(b,c,Mc);Ga(a,9,c);break;default:yb(b)}return a}\nfunction bd(a,b){a.serializeBinaryToWriter(b)}h.serializeBinary=function(){var a=new Bb;this.serializeBinaryToWriter(a);return Gb(a)};\nh.serializeBinaryToWriter=function(a){var b=this.getNumNonMissing();0!==b&&a.writeUint64(1,b);b=this.getNumMissing();0!==b&&a.writeUint64(2,b);b=u(this,3,0);0!==b&&a.writeUint64(3,b);b=u(this,4,0);0!==b&&a.writeUint64(4,b);b=this.getAvgNumValues();0!==b&&a.writeFloat(5,b);b=this.getTotNumValues();0!==b&&a.writeUint64(8,b);b=O(this,Kc,6);null!=b&&Jb(a,6,b,Nc);b=O(this,zc,7);null!=b&&Jb(a,7,b,Ic);b=O(this,Kc,9);null!=b&&Jb(a,9,b,Nc)};h.getNumNonMissing=function(){return u(this,1,0)};\nh.setNumNonMissing=function(a){G(this,1,a)};h.getNumMissing=function(){return u(this,2,0)};h.setNumMissing=function(a){G(this,2,a)};h.getAvgNumValues=function(){return+u(this,5,0)};h.setAvgNumValues=function(a){G(this,5,a)};h.getTotNumValues=function(){return u(this,8,0)};h.setTotNumValues=function(a){G(this,8,a)};h.clearNumValuesHistogram=function(){Ga(this,6,void 0)};h.hasNumValuesHistogram=function(){return null!=Ca(this,6)};h.clearWeightedCommonStats=function(){Ga(this,7,void 0)};\nh.hasWeightedCommonStats=function(){return null!=Ca(this,7)};h.clearFeatureListLengthHistogram=function(){Ga(this,9,void 0)};h.hasFeatureListLengthHistogram=function(){return null!=Ca(this,9)};function Kc(a){xa(this,a,sd,null)}da(Kc,va);var sd=[3];h=Kc.prototype;h.toObject=function(a){return Lc(a,this)};function Lc(a,b){var c={numNan:u(b,1,0),numUndefined:u(b,2,0),bucketsList:Ba(b.getBucketsList(),td,a),type:u(b,4,0),name:u(b,5,\"\")};a&&(c.$jspbMessageInstance=b);return c}\nfunction Mc(a,b){for(;xb(b)&&4!=b.nextWireType_;)switch(b.nextField_){case 1:var c=b.readUint64();G(a,1,c);break;case 2:c=b.readUint64();G(a,2,c);break;case 3:c=new ud;zb(b,c,vd);a.addBuckets(c);break;case 4:c=b.readEnum();a.setType(c);break;case 5:c=b.readString();a.setName(c);break;default:yb(b)}return a}function Nc(a,b){a.serializeBinaryToWriter(b)}h.serializeBinary=function(){var a=new Bb;this.serializeBinaryToWriter(a);return Gb(a)};\nh.serializeBinaryToWriter=function(a){var b=u(this,1,0);0!==b&&a.writeUint64(1,b);b=u(this,2,0);0!==b&&a.writeUint64(2,b);b=this.getBucketsList();0<b.length&&Mb(a,3,b,wd);b=this.getType();0!==b&&a.writeEnum(4,b);b=this.getName();0<b.length&&a.writeString(5,b)};h.getBucketsList=function(){return Ea(this,ud,3)};h.setBucketsList=function(a){Ia(this,3,a)};h.addBuckets=function(a,b){return Ja(this,3,a,ud,b)};h.clearBucketsList=function(){this.setBucketsList([])};h.getType=function(){return u(this,4,0)};\nh.setType=function(a){G(this,4,a)};h.getName=function(){return u(this,5,\"\")};h.setName=function(a){G(this,5,a)};function ud(a){xa(this,a,null,null)}da(ud,va);h=ud.prototype;h.toObject=function(a){return td(a,this)};function td(a,b){var c={lowValue:+u(b,1,0),highValue:+u(b,2,0),deprecatedCount:u(b,3,0),sampleCount:+u(b,4,0)};a&&(c.$jspbMessageInstance=b);return c}\nfunction vd(a,b){for(;xb(b)&&4!=b.nextWireType_;)switch(b.nextField_){case 1:var c=b.readDouble();xd(a,c);break;case 2:c=b.readDouble();yd(a,c);break;case 3:c=b.readUint64();a.setDeprecatedCount(c);break;case 4:c=b.readDouble();a.setSampleCount(c);break;default:yb(b)}return a}function wd(a,b){a.serializeBinaryToWriter(b)}h.serializeBinary=function(){var a=new Bb;this.serializeBinaryToWriter(a);return Gb(a)};\nh.serializeBinaryToWriter=function(a){var b=this.getLowValue();0!==b&&a.writeDouble(1,b);b=zd(this);0!==b&&a.writeDouble(2,b);b=u(this,3,0);0!==b&&a.writeUint64(3,b);b=this.getSampleCount();0!==b&&a.writeDouble(4,b)};h.getLowValue=function(){return+u(this,1,0)};function xd(a,b){G(a,1,b)}function zd(a){return+u(a,2,0)}function yd(a,b){G(a,2,b)}h.setDeprecatedCount=function(a){G(this,3,a)};h.getSampleCount=function(){return+u(this,4,0)};h.setSampleCount=function(a){G(this,4,a)};\nfunction kd(a){xa(this,a,Ad,null)}da(kd,va);var Ad=[1];h=kd.prototype;h.toObject=function(a){return fd(a,this)};function fd(a,b){var c={bucketsList:Ba(b.getBucketsList(),Bd,a),name:u(b,2,\"\")};a&&(c.$jspbMessageInstance=b);return c}function ld(a,b){for(;xb(b)&&4!=b.nextWireType_;)switch(b.nextField_){case 1:var c=new Cd;zb(b,c,Dd);a.addBuckets(c);break;case 2:c=b.readString();a.setName(c);break;default:yb(b)}return a}function od(a,b){a.serializeBinaryToWriter(b)}\nh.serializeBinary=function(){var a=new Bb;this.serializeBinaryToWriter(a);return Gb(a)};h.serializeBinaryToWriter=function(a){var b=this.getBucketsList();0<b.length&&Mb(a,1,b,Ed);b=this.getName();0<b.length&&a.writeString(2,b)};h.getBucketsList=function(){return Ea(this,Cd,1)};h.setBucketsList=function(a){Ia(this,1,a)};h.addBuckets=function(a,b){return Ja(this,1,a,Cd,b)};h.clearBucketsList=function(){this.setBucketsList([])};h.getName=function(){return u(this,2,\"\")};\nh.setName=function(a){G(this,2,a)};function Cd(a){xa(this,a,null,null)}da(Cd,va);h=Cd.prototype;h.toObject=function(a){return Bd(a,this)};function Bd(a,b){var c={lowRank:u(b,1,0),highRank:u(b,2,0),deprecatedCount:u(b,3,0),label:u(b,4,\"\"),sampleCount:+u(b,5,0)};a&&(c.$jspbMessageInstance=b);return c}\nfunction Dd(a,b){for(;xb(b)&&4!=b.nextWireType_;)switch(b.nextField_){case 1:var c=b.readUint64();G(a,1,c);break;case 2:c=b.readUint64();G(a,2,c);break;case 3:c=b.readUint64();a.setDeprecatedCount(c);break;case 4:c=b.readString();G(a,4,c);break;case 5:c=b.readDouble();a.setSampleCount(c);break;default:yb(b)}return a}function Ed(a,b){a.serializeBinaryToWriter(b)}h.serializeBinary=function(){var a=new Bb;this.serializeBinaryToWriter(a);return Gb(a)};\nh.serializeBinaryToWriter=function(a){var b=u(this,1,0);0!==b&&a.writeUint64(1,b);b=u(this,2,0);0!==b&&a.writeUint64(2,b);b=u(this,3,0);0!==b&&a.writeUint64(3,b);b=Fd(this);0<b.length&&a.writeString(4,b);b=this.getSampleCount();0!==b&&a.writeDouble(5,b)};h.getDeprecatedCount=function(){return u(this,3,0)};h.setDeprecatedCount=function(a){G(this,3,a)};function Fd(a){return u(a,4,\"\")}h.getSampleCount=function(){return+u(this,5,0)};h.setSampleCount=function(a){G(this,5,a)};\n//~~WEBPATH~~/polymer/polymer-micro.html.js\n(function(){function a(){document.body.removeAttribute(\"unresolved\")}window.WebComponents?addEventListener(\"WebComponentsReady\",a):\"interactive\"===document.readyState||\"complete\"===document.readyState?a():addEventListener(\"DOMContentLoaded\",a)})();var Gd=window,Md=window.Polymer||{};if(!Md.noUrlSettings)for(var Nd=location.search.slice(1).split(\"\\x26\"),Od=0,Pd;Od<Nd.length&&(Pd=Nd[Od]);Od++)Pd=Pd.split(\"\\x3d\"),Pd[0]&&(Md[Pd[0]]=Pd[1]||!0);Md.wantShadow=\"shadow\"===Md.dom;Md.hasShadow=!!Element.prototype.createShadowRoot;\nMd.nativeShadow=Md.hasShadow&&!window.ShadowDOMPolyfill;Md.useShadow=Md.wantShadow&&Md.hasShadow;Md.hasNativeImports=\"import\"in document.createElement(\"link\");Md.useNativeImports=Md.hasNativeImports;Md.useNativeCustomElements=!window.CustomElements||window.CustomElements.useNative;Md.useNativeShadow=Md.useShadow&&Md.nativeShadow;Md.usePolyfillProto=!Md.useNativeCustomElements&&!Object.__proto__;\nMd.hasNativeCSSProperties=!navigator.userAgent.match(\"AppleWebKit/601\")&&window.CSS&&CSS.supports&&CSS.supports(\"box-shadow\",\"0 0 0 var(--foo)\");Md.useNativeCSSProperties=Md.hasNativeCSSProperties&&Md.lazyRegister&&Md.useNativeCSSProperties;Md.isIE=navigator.userAgent.match(\"Trident\");Gd.Polymer={Settings:Md};\n(function(){function a(a){var b=Polymer.Base;a.extends&&(b=Polymer.Base._getExtendedPrototype(a.extends));a=Polymer.Base.chainObject(a,b);a.registerCallback();return a}var b=window.Polymer;window.Polymer=function(b){\"function\"===typeof b&&(b=b.prototype);b||(b={});b=a(b);var c=b===b.constructor.prototype?b.constructor:null,d={prototype:b};b.extends&&(d.extends=b.extends);Polymer.telemetry._registrate(b);b=document.registerElement(b.is,d);return c||b};if(b)for(var c in b)Polymer[c]=b[c];Polymer.Class=\nfunction(b){b.factoryImpl||(b.factoryImpl=function(){});return a(b).constructor}})();Polymer.telemetry={registrations:[],_regLog:function(a){console.log(\"[\"+a.is+\"]: registered\")},_registrate:function(a){this.registrations.push(a);Polymer.log&&this._regLog(a)},dumpRegistrations:function(){this.registrations.forEach(this._regLog)}};Object.defineProperty(window,\"currentImport\",{enumerable:!0,configurable:!0,get:function(){return(document._currentScript||document.currentScript||{}).ownerDocument}});\nPolymer.RenderStatus={_ready:!1,_callbacks:[],whenReady:function(a){this._ready?a():this._callbacks.push(a)},_makeReady:function(){this._ready=!0;for(var a=0;a<this._callbacks.length;a++)this._callbacks[a]();this._callbacks=[]},_catchFirstRender:function(){requestAnimationFrame(function(){Polymer.RenderStatus._makeReady()})},_afterNextRenderQueue:[],_waitingNextRender:!1,afterNextRender:function(a,b,c){this._watchNextRender();this._afterNextRenderQueue.push([a,b,c])},hasRendered:function(){return this._ready},\n_watchNextRender:function(){if(!this._waitingNextRender){this._waitingNextRender=!0;var a=function(){Polymer.RenderStatus._flushNextRender()};this._ready?requestAnimationFrame(a):this.whenReady(a)}},_flushNextRender:function(){var a=this;setTimeout(function(){a._flushRenderCallbacks(a._afterNextRenderQueue);a._afterNextRenderQueue=[];a._waitingNextRender=!1})},_flushRenderCallbacks:function(a){for(var b=0,c;b<a.length;b++)c=a[b],c[1].apply(c[0],c[2]||Polymer.nar)}};\nwindow.HTMLImports?HTMLImports.whenReady(function(){Polymer.RenderStatus._catchFirstRender()}):Polymer.RenderStatus._catchFirstRender();Polymer.ImportStatus=Polymer.RenderStatus;Polymer.ImportStatus.whenLoaded=Polymer.ImportStatus.whenReady;\n(function(){var a=Polymer.Settings;Polymer.Base={__isPolymerInstance__:!0,_addFeature:function(a){this.mixin(this,a)},registerCallback:function(){if(\"max\"!==a.lazyRegister){this._desugarBehaviors();for(var b=0,c;b<this.behaviors.length;b++)c=this.behaviors[b],c.beforeRegister&&c.beforeRegister.call(this)}this.beforeRegister&&this.beforeRegister();this._registerFeatures();a.lazyRegister||this.ensureRegisterFinished()},createdCallback:function(){if(a.disableUpgradeEnabled){if(this.hasAttribute(\"disable-upgrade\")){this._propertySetter=\nb;this._configValue=null;this.__data__={};return}this.__hasInitialized=!0}this.__initialize()},__initialize:function(){this.__hasRegisterFinished||this._ensureRegisterFinished(this.__proto__);Polymer.telemetry.instanceCount++;this.root=this;for(var a=0,b;a<this.behaviors.length;a++)b=this.behaviors[a],b.created&&b.created.call(this);this.created&&this.created();this._initFeatures()},ensureRegisterFinished:function(){this._ensureRegisterFinished(this)},_ensureRegisterFinished:function(b){if(b.__hasRegisterFinished!==\nb.is||!b.is){if(\"max\"===a.lazyRegister){b._desugarBehaviors();for(var c=0,d;c<b.behaviors.length;c++)d=b.behaviors[c],d.beforeRegister&&d.beforeRegister.call(b)}b.__hasRegisterFinished=b.is;b._finishRegisterFeatures&&b._finishRegisterFeatures();for(c=0;c<b.behaviors.length;c++)d=b.behaviors[c],d.registered&&d.registered.call(b);b.registered&&b.registered();a.usePolyfillProto&&b!==this&&b.extend(this,b)}},attachedCallback:function(){var a=this;Polymer.RenderStatus.whenReady(function(){a.isAttached=\n!0;for(var b=0,c;b<a.behaviors.length;b++)c=a.behaviors[b],c.attached&&c.attached.call(a);a.attached&&a.attached()})},detachedCallback:function(){var a=this;Polymer.RenderStatus.whenReady(function(){a.isAttached=!1;for(var b=0,c;b<a.behaviors.length;b++)c=a.behaviors[b],c.detached&&c.detached.call(a);a.detached&&a.detached()})},attributeChangedCallback:function(a,b,c){this._attributeChangedImpl(a);for(var d=0,e;d<this.behaviors.length;d++)e=this.behaviors[d],e.attributeChanged&&e.attributeChanged.call(this,\na,b,c);this.attributeChanged&&this.attributeChanged(a,b,c)},_attributeChangedImpl:function(a){this._setAttributeToProperty(this,a)},extend:function(a,b){if(a&&b)for(var c=Object.getOwnPropertyNames(b),d=0,e;d<c.length&&(e=c[d]);d++)this.copyOwnProperty(e,b,a);return a||b},mixin:function(a,b){for(var c in b)a[c]=b[c];return a},copyOwnProperty:function(a,b,c){(b=Object.getOwnPropertyDescriptor(b,a))&&Object.defineProperty(c,a,b)},_logger:function(a,b){1===b.length&&Array.isArray(b[0])&&(b=b[0]);switch(a){case \"log\":case \"warn\":case \"error\":console[a].apply(console,\nb)}},_log:function(){this._logger(\"log\",Array.prototype.slice.call(arguments,0))},_warn:function(){this._logger(\"warn\",Array.prototype.slice.call(arguments,0))},_error:function(){this._logger(\"error\",Array.prototype.slice.call(arguments,0))},_logf:function(){return this._logPrefix.concat(this.is).concat(Array.prototype.slice.call(arguments,0))}};Polymer.Base._logPrefix=window.chrome&&!/edge/i.test(navigator.userAgent)||/firefox/i.test(navigator.userAgent)?[\"%c[%s::%s]:\",\"font-weight: bold; background-color:#EEEE00;\"]:\n[\"[%s::%s]:\"];Polymer.Base.chainObject=function(a,b){a&&b&&a!==b&&(Object.__proto__||(a=Polymer.Base.extend(Object.create(b),a)),a.__proto__=b);return a};Polymer.Base=Polymer.Base.chainObject(Polymer.Base,HTMLElement.prototype);Polymer.BaseDescriptors={};if(a.disableUpgradeEnabled){var b=function(a,b){this.__data__[a]=b};var c=Polymer.Base.attributeChangedCallback;Polymer.Base.attributeChangedCallback=function(a,b,f){this.__hasInitialized||\"disable-upgrade\"!==a||(this.__hasInitialized=!0,this._propertySetter=\nPolymer.Bind._modelApi._propertySetter,this._configValue=Polymer.Base._configValue,this.__initialize());c.call(this,a,b,f)}}Polymer.instanceof=window.CustomElements?CustomElements.instanceof:function(a,b){return a instanceof b};Polymer.isInstance=function(a){return!(!a||!a.__isPolymerInstance__)};Polymer.telemetry.instanceCount=0})();\n(function(){function a(){return document.createElement(\"dom-module\")}var b={},c={};a.prototype=Object.create(HTMLElement.prototype);Polymer.Base.mixin(a.prototype,{createdCallback:function(){this.register()},register:function(a){if(a=a||this.id||this.getAttribute(\"name\")||this.getAttribute(\"is\"))this.id=a,b[a]=this,c[a.toLowerCase()]=this},import:function(a,f){if(a){var e=b[a]||c[a.toLowerCase()];if(!e){if(d)for(var e=document._currentScript||document.currentScript,e=(e&&e.ownerDocument||document).querySelectorAll(\"dom-module\"),\nk=e.length-1,l;0<=k&&(l=e[k])&&!l.__upgraded__;k--)CustomElements.upgrade(l);e=b[a]||c[a.toLowerCase()]}e&&f&&(e=e.querySelector(f));return e}}});Object.defineProperty(a.prototype,\"constructor\",{value:a,configurable:!0,writable:!0});var d=window.CustomElements&&!CustomElements.useNative;document.registerElement(\"dom-module\",a)})();\nPolymer.Base._addFeature({_prepIs:function(){if(!this.is){var a=(document._currentScript||document.currentScript).parentNode;\"dom-module\"===a.localName&&(this.is=a.id||a.getAttribute(\"name\")||a.getAttribute(\"is\"))}this.is&&(this.is=this.is.toLowerCase())}});\nPolymer.Base._addFeature({behaviors:[],_desugarBehaviors:function(){this.behaviors.length&&(this.behaviors=this._desugarSomeBehaviors(this.behaviors))},_desugarSomeBehaviors:function(a){var b=[];a=this._flattenBehaviorsList(a);for(var c=a.length-1;0<=c;c--){var d=a[c];-1===b.indexOf(d)&&(this._mixinBehavior(d),b.unshift(d))}return b},_flattenBehaviorsList:function(a){for(var b=[],c=0;c<a.length;c++){var d=a[c];d instanceof Array?b=b.concat(this._flattenBehaviorsList(d)):d?b.push(d):this._warn(this._logf(\"_flattenBehaviorsList\",\n\"behavior is null, check for missing or 404 import\"))}return b},_mixinBehavior:function(a){for(var b=Object.getOwnPropertyNames(a),c=a._noAccessors,d=0,e;d<b.length&&(e=b[d]);d++)Polymer.Base._behaviorProperties[e]||this.hasOwnProperty(e)||(c?this[e]=a[e]:this.copyOwnProperty(e,a,this))},_prepBehaviors:function(){this._prepFlattenedBehaviors(this.behaviors)},_prepFlattenedBehaviors:function(a){for(var b=0,c=a.length;b<c;b++)this._prepBehavior(a[b]);this._prepBehavior(this)},_marshalBehaviors:function(){for(var a=\n0;a<this.behaviors.length;a++)this._marshalBehavior(this.behaviors[a]);this._marshalBehavior(this)}});Polymer.Base._behaviorProperties={hostAttributes:!0,beforeRegister:!0,registered:!0,properties:!0,observers:!0,listeners:!0,created:!0,attached:!0,detached:!0,attributeChanged:!0,ready:!0,_noAccessors:!0};\nPolymer.Base._addFeature({_getExtendedPrototype:function(a){return this._getExtendedNativePrototype(a)},_nativePrototypes:{},_getExtendedNativePrototype:function(a){var b=this._nativePrototypes[a];if(!b){for(var b=Object.create(this.getNativePrototype(a)),c=Object.getOwnPropertyNames(Polymer.Base),d=0,e;d<c.length&&(e=c[d]);d++)Polymer.BaseDescriptors[e]||(b[e]=Polymer.Base[e]);Object.defineProperties(b,Polymer.BaseDescriptors);this._nativePrototypes[a]=b}return b},getNativePrototype:function(a){return Object.getPrototypeOf(document.createElement(a))}});\nPolymer.Base._addFeature({_prepConstructor:function(){function a(){return this._factory(arguments)}this._factoryArgs=this.extends?[this.extends,this.is]:[this.is];this.hasOwnProperty(\"extends\")&&(a.extends=this.extends);Object.defineProperty(this,\"constructor\",{value:a,writable:!0,configurable:!0});a.prototype=this},_factory:function(a){var b=document.createElement.apply(document,this._factoryArgs);this.factoryImpl&&this.factoryImpl.apply(b,a);return b}});Polymer.nob=Object.create(null);\nPolymer.Base._addFeature({getPropertyInfo:function(a){var b=this._getPropertyInfo(a,this.properties);if(!b)for(var c=0;c<this.behaviors.length;c++)if(b=this._getPropertyInfo(a,this.behaviors[c].properties))return b;return b||Polymer.nob},_getPropertyInfo:function(a,b){var c=b&&b[a];\"function\"===typeof c&&(c=b[a]={type:c});c&&(c.defined=!0);return c},_prepPropertyInfo:function(){this._propertyInfo={};for(var a=0;a<this.behaviors.length;a++)this._addPropertyInfo(this._propertyInfo,this.behaviors[a].properties);\nthis._addPropertyInfo(this._propertyInfo,this.properties);this._addPropertyInfo(this._propertyInfo,this._propertyEffects)},_addPropertyInfo:function(a,b){if(b){var c;for(c in b){var d=a[c];var e=b[c];if(\"_\"!==c[0]||e.readOnly)a[c]?(d.type||(d.type=e.type),d.readOnly||(d.readOnly=e.readOnly)):a[c]={type:\"function\"===typeof e?e:e.type,readOnly:e.readOnly,attribute:Polymer.CaseMap.camelToDashCase(c)}}}}});var Qd={configurable:!0,writable:!0,enumerable:!0,value:{}};\nPolymer.BaseDescriptors.properties=Qd;Object.defineProperty(Polymer.Base,\"properties\",Qd);Polymer.CaseMap={_caseMap:{},_rx:{dashToCamel:/-[a-z]/g,camelToDash:/([A-Z])/g},dashToCamelCase:function(a){return this._caseMap[a]||(this._caseMap[a]=0>a.indexOf(\"-\")?a:a.replace(this._rx.dashToCamel,function(a){return a[1].toUpperCase()}))},camelToDashCase:function(a){return this._caseMap[a]||(this._caseMap[a]=a.replace(this._rx.camelToDash,\"-$1\").toLowerCase())}};\nPolymer.Base._addFeature({_addHostAttributes:function(a){this._aggregatedAttributes||(this._aggregatedAttributes={});a&&this.mixin(this._aggregatedAttributes,a)},_marshalHostAttributes:function(){this._aggregatedAttributes&&this._applyAttributes(this,this._aggregatedAttributes)},_applyAttributes:function(a,b){for(var c in b)this.hasAttribute(c)||\"class\"===c||this.serializeValueToAttribute(b[c],c,this)},_marshalAttributes:function(){this._takeAttributesToModel(this)},_takeAttributesToModel:function(a){if(this.hasAttributes())for(var b in this._propertyInfo){var c=\nthis._propertyInfo[b];this.hasAttribute(c.attribute)&&this._setAttributeToProperty(a,c.attribute,b,c)}},_setAttributeToProperty:function(a,b,c,d){this._serializing||(c=c||Polymer.CaseMap.dashToCamelCase(b),(d=d||this._propertyInfo&&this._propertyInfo[c])&&!d.readOnly&&(b=this.getAttribute(b),a[c]=this.deserialize(b,d.type)))},_serializing:!1,reflectPropertyToAttribute:function(a,b,c){this._serializing=!0;c=void 0===c?this[a]:c;this.serializeValueToAttribute(c,b||Polymer.CaseMap.camelToDashCase(a));\nthis._serializing=!1},serializeValueToAttribute:function(a,b,c){a=this.serialize(a);c=c||this;void 0===a?c.removeAttribute(b):c.setAttribute(b,a)},deserialize:function(a,b){switch(b){case Number:a=Number(a);break;case Boolean:a=null!=a;break;case Object:try{a=JSON.parse(a)}catch(c){}break;case Array:try{a=JSON.parse(a)}catch(c){a=null,console.warn(\"Polymer::Attributes: couldn`t decode Array as JSON\")}break;case Date:a=new Date(a)}return a},serialize:function(a){switch(typeof a){case \"boolean\":return a?\n\"\":void 0;case \"object\":if(a instanceof Date)return a.toString();if(a)try{return JSON.stringify(a)}catch(b){return\"\"}default:return null!=a?a:void 0}}});Polymer.version=\"1.8.1\";Polymer.Base._addFeature({_registerFeatures:function(){this._prepIs();this._prepBehaviors();this._prepConstructor();this._prepPropertyInfo()},_prepBehavior:function(a){this._addHostAttributes(a.hostAttributes)},_marshalBehavior:function(){},_initFeatures:function(){this._marshalHostAttributes();this._marshalBehaviors()}});\n</script>\n\n\n\n\n\n\n\n\n\n\n\n<script>//~~WEBPATH~~/polymer/polymer-mini.html.js\nPolymer.Base._addFeature({_prepTemplate:function(){void 0===this._template&&(this._template=Polymer.DomModule.import(this.is,\"template\"));this._template&&this._template.hasAttribute(\"is\")&&this._warn(this._logf(\"_prepTemplate\",\"top-level Polymer template must not be a type-extension, found\",this._template,\"Move inside simple \\x3ctemplate\\x3e.\"));this._template&&!this._template.content&&window.HTMLTemplateElement&&HTMLTemplateElement.decorate&&HTMLTemplateElement.decorate(this._template)},_stampTemplate:function(){this._template&&\n(this.root=this.instanceTemplate(this._template))},instanceTemplate:function(a){return document.importNode(a._content||a.content,!0)}});\n(function(){var a=Polymer.Base.attachedCallback;Polymer.Base._addFeature({_hostStack:[],ready:function(){},_registerHost:function(a){(this.dataHost=a=a||Polymer.Base._hostStack[Polymer.Base._hostStack.length-1])&&a._clients&&a._clients.push(this);this._clients=null;this._clientsReadied=!1},_beginHosting:function(){Polymer.Base._hostStack.push(this);this._clients||(this._clients=[])},_endHosting:function(){Polymer.Base._hostStack.pop()},_tryReady:function(){this._readied=!1;this._canReady()&&this._ready()},\n_canReady:function(){return!this.dataHost||this.dataHost._clientsReadied},_ready:function(){this._beforeClientsReady();this._template&&(this._setupRoot(),this._readyClients());this._clientsReadied=!0;this._clients=null;this._afterClientsReady();this._readySelf()},_readyClients:function(){this._beginDistribute();var a=this._clients;if(a)for(var c=0,d=a.length,e;c<d&&(e=a[c]);c++)e._ready();this._finishDistribute()},_readySelf:function(){for(var a=0,c;a<this.behaviors.length;a++)c=this.behaviors[a],\nc.ready&&c.ready.call(this);this.ready&&this.ready();this._readied=!0;this._attachedPending&&(this._attachedPending=!1,this.attachedCallback())},_beforeClientsReady:function(){},_afterClientsReady:function(){},_beforeAttached:function(){},attachedCallback:function(){this._readied?(this._beforeAttached(),a.call(this)):this._attachedPending=!0}})})();\nPolymer.ArraySplice=function(){function a(a,b){return{index:a,removed:[],addedCount:b}}function b(){}b.prototype={calcEditDistances:function(a,b,e,f,g,k){k=k-g+1;e=e-b+1;for(var c=Array(k),d=0;d<k;d++)c[d]=Array(e),c[d][0]=d;for(var n=0;n<e;n++)c[0][n]=n;for(d=1;d<k;d++)for(n=1;n<e;n++)if(this.equals(a[b+n-1],f[g+d-1]))c[d][n]=c[d-1][n-1];else{var q=c[d-1][n]+1,p=c[d][n-1]+1;c[d][n]=q<p?q:p}return c},spliceOperationsFromEditDistances:function(a){for(var b=a.length-1,c=a[0].length-1,f=a[b][c],g=[];0<\nb||0<c;)if(0==b)g.push(2),c--;else if(0==c)g.push(3),b--;else{var k=a[b-1][c-1],l=a[b-1][c],m=a[b][c-1];var n=l<m?l<k?l:k:m<k?m:k;n==k?(k==f?g.push(0):(g.push(1),f=k),b--,c--):n==l?(g.push(3),b--,f=l):(g.push(2),c--,f=m)}g.reverse();return g},calcSplices:function(b,d,e,f,g,k){var c=0,m=0,n=Math.min(e-d,k-g);0==d&&0==g&&(c=this.sharedPrefix(b,f,n));e==b.length&&k==f.length&&(m=this.sharedSuffix(b,f,n-c));d+=c;g+=c;e-=m;k-=m;if(0==e-d&&0==k-g)return[];if(d==e){for(b=a(d,0);g<k;)b.removed.push(f[g++]);\nreturn[b]}if(g==k)return[a(d,e-d)];k=this.spliceOperationsFromEditDistances(this.calcEditDistances(b,d,e,f,g,k));b=void 0;e=[];for(c=0;c<k.length;c++)switch(k[c]){case 0:b&&(e.push(b),b=void 0);d++;g++;break;case 1:b||(b=a(d,0));b.addedCount++;d++;b.removed.push(f[g]);g++;break;case 2:b||(b=a(d,0));b.addedCount++;d++;break;case 3:b||(b=a(d,0)),b.removed.push(f[g]),g++}b&&e.push(b);return e},sharedPrefix:function(a,b,e){for(var c=0;c<e;c++)if(!this.equals(a[c],b[c]))return c;return e},sharedSuffix:function(a,\nb,e){for(var c=a.length,d=b.length,k=0;k<e&&this.equals(a[--c],b[--d]);)k++;return k},calculateSplices:function(a,b){return this.calcSplices(a,0,a.length,b,0,b.length)},equals:function(a,b){return a===b}};return new b}();\nPolymer.domInnerHTML=function(){function a(a){switch(a){case \"\\x26\":return\"\\x26amp;\";case \"\\x3c\":return\"\\x26lt;\";case \"\\x3e\":return\"\\x26gt;\";case '\"':return\"\\x26quot;\";case \"\\u00a0\":return\"\\x26nbsp;\"}}function b(a){for(var b={},c=0;c<a.length;c++)b[a[c]]=!0;return b}function c(b,l){b instanceof HTMLTemplateElement&&(b=b.content);for(var k=\"\",n=Polymer.dom(b).childNodes,q=0,p=n.length,t;q<p&&(t=n[q]);q++){a:{var r=t;var v=b;var w=l;switch(r.nodeType){case Node.ELEMENT_NODE:for(var z=r.localName,y=\n\"\\x3c\"+z,B=r.attributes,A=0;v=B[A];A++)y+=\" \"+v.name+'\\x3d\"'+v.value.replace(d,a)+'\"';y+=\"\\x3e\";r=f[z]?y:y+c(r,w)+\"\\x3c/\"+z+\"\\x3e\";break a;case Node.TEXT_NODE:r=r.data;r=v&&g[v.localName]?r:r.replace(e,a);break a;case Node.COMMENT_NODE:r=\"\\x3c!--\"+r.data+\"--\\x3e\";break a;default:throw console.error(r),Error(\"not implemented\");}}k+=r}return k}var d=/[&\\u00A0\"]/g,e=/[&\\u00A0<>]/g,f=b(\"area base br col command embed hr img input keygen link meta param source track wbr\".split(\" \")),g=b(\"style script xmp iframe noembed noframes plaintext noscript\".split(\" \"));\nreturn{getInnerHTML:c}}();\n(function(){var a=Element.prototype.insertBefore,b=Element.prototype.appendChild,c=Element.prototype.removeChild;Polymer.TreeApi={arrayCopyChildNodes:function(a){var b=[],c=0;for(a=a.firstChild;a;a=a.nextSibling)b[c++]=a;return b},arrayCopyChildren:function(a){var b=[],c=0;for(a=a.firstElementChild;a;a=a.nextElementSibling)b[c++]=a;return b},arrayCopy:function(a){for(var b=a.length,c=Array(b),d=0;d<b;d++)c[d]=a[d];return c}};Polymer.TreeApi.Logical={hasParentNode:function(a){return!(!a.__dom||!a.__dom.parentNode)},\nhasChildNodes:function(a){return!(!a.__dom||void 0===a.__dom.childNodes)},getChildNodes:function(a){return this.hasChildNodes(a)?this._getChildNodes(a):a.childNodes},_getChildNodes:function(a){if(!a.__dom.childNodes){a.__dom.childNodes=[];for(var b=a.__dom.firstChild;b;b=b.__dom.nextSibling)a.__dom.childNodes.push(b)}return a.__dom.childNodes},getParentNode:function(a){return a.__dom&&void 0!==a.__dom.parentNode?a.__dom.parentNode:a.parentNode},getFirstChild:function(a){return a.__dom&&void 0!==a.__dom.firstChild?\na.__dom.firstChild:a.firstChild},getLastChild:function(a){return a.__dom&&void 0!==a.__dom.lastChild?a.__dom.lastChild:a.lastChild},getNextSibling:function(a){return a.__dom&&void 0!==a.__dom.nextSibling?a.__dom.nextSibling:a.nextSibling},getPreviousSibling:function(a){return a.__dom&&void 0!==a.__dom.previousSibling?a.__dom.previousSibling:a.previousSibling},getFirstElementChild:function(a){return a.__dom&&void 0!==a.__dom.firstChild?this._getFirstElementChild(a):a.firstElementChild},_getFirstElementChild:function(a){for(a=\na.__dom.firstChild;a&&a.nodeType!==Node.ELEMENT_NODE;)a=a.__dom.nextSibling;return a},getLastElementChild:function(a){return a.__dom&&void 0!==a.__dom.lastChild?this._getLastElementChild(a):a.lastElementChild},_getLastElementChild:function(a){for(a=a.__dom.lastChild;a&&a.nodeType!==Node.ELEMENT_NODE;)a=a.__dom.previousSibling;return a},getNextElementSibling:function(a){return a.__dom&&void 0!==a.__dom.nextSibling?this._getNextElementSibling(a):a.nextElementSibling},_getNextElementSibling:function(a){for(a=\na.__dom.nextSibling;a&&a.nodeType!==Node.ELEMENT_NODE;)a=a.__dom.nextSibling;return a},getPreviousElementSibling:function(a){return a.__dom&&void 0!==a.__dom.previousSibling?this._getPreviousElementSibling(a):a.previousElementSibling},_getPreviousElementSibling:function(a){for(a=a.__dom.previousSibling;a&&a.nodeType!==Node.ELEMENT_NODE;)a=a.__dom.previousSibling;return a},saveChildNodes:function(a){if(!this.hasChildNodes(a)){a.__dom=a.__dom||{};a.__dom.firstChild=a.firstChild;a.__dom.lastChild=a.lastChild;\na.__dom.childNodes=[];for(var b=a.firstChild;b;b=b.nextSibling)b.__dom=b.__dom||{},b.__dom.parentNode=a,a.__dom.childNodes.push(b),b.__dom.nextSibling=b.nextSibling,b.__dom.previousSibling=b.previousSibling}},recordInsertBefore:function(a,b,c){b.__dom.childNodes=null;if(a.nodeType===Node.DOCUMENT_FRAGMENT_NODE)for(a=a.firstChild;a;a=a.nextSibling)this._linkNode(a,b,c);else this._linkNode(a,b,c)},_linkNode:function(a,b,c){a.__dom=a.__dom||{};b.__dom=b.__dom||{};c&&(c.__dom=c.__dom||{});a.__dom.previousSibling=\nc?c.__dom.previousSibling:b.__dom.lastChild;a.__dom.previousSibling&&(a.__dom.previousSibling.__dom.nextSibling=a);a.__dom.nextSibling=c||null;a.__dom.nextSibling&&(a.__dom.nextSibling.__dom.previousSibling=a);a.__dom.parentNode=b;c?c===b.__dom.firstChild&&(b.__dom.firstChild=a):(b.__dom.lastChild=a,b.__dom.firstChild||(b.__dom.firstChild=a));b.__dom.childNodes=null},recordRemoveChild:function(a,b){a.__dom=a.__dom||{};b.__dom=b.__dom||{};a===b.__dom.firstChild&&(b.__dom.firstChild=a.__dom.nextSibling);\na===b.__dom.lastChild&&(b.__dom.lastChild=a.__dom.previousSibling);var c=a.__dom.previousSibling,d=a.__dom.nextSibling;c&&(c.__dom.nextSibling=d);d&&(d.__dom.previousSibling=c);a.__dom.parentNode=a.__dom.previousSibling=a.__dom.nextSibling=void 0;b.__dom.childNodes=null}};Polymer.TreeApi.Composed={getChildNodes:function(a){return Polymer.TreeApi.arrayCopyChildNodes(a)},getParentNode:function(a){return a.parentNode},clearChildNodes:function(a){a.textContent=\"\"},insertBefore:function(b,c,f){return a.call(b,\nc,f||null)},appendChild:function(a,c){return b.call(a,c)},removeChild:function(a,b){return c.call(a,b)}}})();\nPolymer.DomApi=function(){function a(b){this.node=d?a.wrap(b):b}var b=Polymer.Settings,c=Polymer.TreeApi,d=b.hasShadow&&!b.nativeShadow;a.wrap=window.wrap?window.wrap:function(a){return a};a.prototype={flush:function(){Polymer.dom.flush()},deepContains:function(a){if(this.node.contains(a))return!0;var b=a;for(a=a.ownerDocument;b&&b!==a&&b!==this.node;)b=Polymer.dom(b).parentNode||b.host;return b===this.node},queryDistributedElements:function(b){for(var c=this.getEffectiveChildNodes(),d=[],e=0,f=c.length,\ng;e<f&&(g=c[e]);e++)g.nodeType===Node.ELEMENT_NODE&&a.matchesSelector.call(g,b)&&d.push(g);return d},getEffectiveChildNodes:function(){for(var a=[],b=this.childNodes,c=0,d=b.length,n;c<d&&(n=b[c]);c++)if(n.localName===e)for(var q=f(n).getDistributedNodes(),p=0;p<q.length;p++)a.push(q[p]);else a.push(n);return a},observeNodes:function(b){if(b)return this.observer||(this.observer=this.node.localName===e?new a.DistributedNodesObserver(this):new a.EffectiveNodesObserver(this)),this.observer.addListener(b)},\nunobserveNodes:function(a){this.observer&&this.observer.removeListener(a)},notifyObserver:function(){this.observer&&this.observer.notify()},_query:function(a,b,d){b=b||this.node;var e=[];this._queryElements(c.Logical.getChildNodes(b),a,d,e);return e},_queryElements:function(a,b,c,d){for(var e=0,f=a.length,g;e<f&&(g=a[e]);e++)if(g.nodeType===Node.ELEMENT_NODE&&this._queryElement(g,b,c,d))return!0},_queryElement:function(a,b,d,e){var f=b(a);f&&e.push(a);if(d&&d(f))return f;this._queryElements(c.Logical.getChildNodes(a),\nb,d,e)}};var e=a.CONTENT=\"content\",f=a.factory=function(b){b=b||document;b.__domApi||(b.__domApi=new a.ctor(b));return b.__domApi};a.hasApi=function(a){return!!a.__domApi};a.ctor=a;Polymer.dom=function(b,c){return b instanceof Event?Polymer.EventApi.factory(b):a.factory(b,c)};b=Element.prototype;a.matchesSelector=b.matches||b.matchesSelector||b.mozMatchesSelector||b.msMatchesSelector||b.oMatchesSelector||b.webkitMatchesSelector;return a}();\n(function(){var a=Polymer.DomApi,b=a.factory,c=Polymer.TreeApi,d=Polymer.domInnerHTML.getInnerHTML,e=a.CONTENT;if(!Polymer.Settings.useShadow){var f=Element.prototype.cloneNode,g=Document.prototype.importNode;Polymer.Base.mixin(a.prototype,{_lazyDistribute:function(a){a.shadyRoot&&a.shadyRoot._distributionClean&&(a.shadyRoot._distributionClean=!1,Polymer.dom.addDebouncer(a.debounce(\"_distribute\",a._distributeContent)))},appendChild:function(a){return this.insertBefore(a)},insertBefore:function(d,\nf){if(f&&c.Logical.getParentNode(f)!==this.node)throw Error(\"The ref_node to be inserted before is not a child of this node\");if(d.nodeType!==Node.DOCUMENT_FRAGMENT_NODE){var g=c.Logical.getParentNode(d);g?(a.hasApi(g)&&b(g).notifyObserver(),this._removeNode(d)):this._removeOwnerShadyRoot(d)}this._addNode(d,f)||(f&&(f=f.localName===e?this._firstComposedNode(f):f),g=this.node._isShadyRoot?this.node.host:this.node,f?c.Composed.insertBefore(g,d,f):c.Composed.appendChild(g,d));this.notifyObserver();return d},\n_addNode:function(a,b){var d=this.getOwnerRoot();if(d){var e=this._maybeAddInsertionPoint(a,this.node);d._invalidInsertionPoints||(d._invalidInsertionPoints=e);this._addNodeToHost(d.host,a)}c.Logical.hasChildNodes(this.node)&&c.Logical.recordInsertBefore(a,this.node,b);if(b=this._maybeDistribute(a)||this.node.shadyRoot)if(a.nodeType===Node.DOCUMENT_FRAGMENT_NODE)for(;a.firstChild;)c.Composed.removeChild(a,a.firstChild);else(d=c.Composed.getParentNode(a))&&c.Composed.removeChild(d,a);return b},removeChild:function(a){if(c.Logical.getParentNode(a)!==\nthis.node)throw Error(\"The node to be removed is not a child of this node: \"+a);if(!this._removeNode(a)){var b=this.node._isShadyRoot?this.node.host:this.node;b===c.Composed.getParentNode(a)&&c.Composed.removeChild(b,a)}this.notifyObserver();return a},_removeNode:function(a){var d=c.Logical.hasParentNode(a)&&c.Logical.getParentNode(a),e=this._ownerShadyRootForNode(a);if(d){var f=b(a)._maybeDistributeParent();c.Logical.recordRemoveChild(a,d);e&&this._removeDistributedChildren(e,a)&&(e._invalidInsertionPoints=\n!0,this._lazyDistribute(e.host))}this._removeOwnerShadyRoot(a);e&&this._removeNodeFromHost(e.host,a);return f},replaceChild:function(a,b){this.insertBefore(a,b);this.removeChild(b);return a},_hasCachedOwnerRoot:function(a){return void 0!==a._ownerShadyRoot},getOwnerRoot:function(){return this._ownerShadyRootForNode(this.node)},_ownerShadyRootForNode:function(a){if(a){var b=a._ownerShadyRoot;void 0===b&&(b=a._isShadyRoot?a:(b=c.Logical.getParentNode(a))?b._isShadyRoot?b:this._ownerShadyRootForNode(b):\nnull,b||document.documentElement.contains(a))&&(a._ownerShadyRoot=b);return b}},_maybeDistribute:function(a){var d=a.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&!a.__noContent&&b(a).querySelector(e),f=d&&c.Logical.getParentNode(d).nodeType!==Node.DOCUMENT_FRAGMENT_NODE;(a=d||a.localName===e)&&(d=this.getOwnerRoot())&&this._lazyDistribute(d.host);(d=this._nodeNeedsDistribution(this.node))&&this._lazyDistribute(this.node);return d||a&&!f},_maybeAddInsertionPoint:function(a,d){if(a.nodeType!==Node.DOCUMENT_FRAGMENT_NODE||\na.__noContent)a.localName===e&&(c.Logical.saveChildNodes(d),c.Logical.saveChildNodes(a),t=!0);else for(var f=b(a).querySelectorAll(e),g=0,k,l;g<f.length&&(k=f[g]);g++){l=c.Logical.getParentNode(k);l===a&&(l=d);l=this._maybeAddInsertionPoint(k,l);var t=t||l}return t},_updateInsertionPoints:function(a){a=a.shadyRoot._insertionPoints=b(a.shadyRoot).querySelectorAll(e);for(var d=0,f;d<a.length;d++)f=a[d],c.Logical.saveChildNodes(f),c.Logical.saveChildNodes(c.Logical.getParentNode(f))},_nodeNeedsDistribution:function(b){return b&&\nb.shadyRoot&&a.hasInsertionPoint(b.shadyRoot)},_addNodeToHost:function(a,b){a._elementAdd&&a._elementAdd(b)},_removeNodeFromHost:function(a,b){a._elementRemove&&a._elementRemove(b)},_removeDistributedChildren:function(a,d){a=a._insertionPoints;for(var e=0;e<a.length;e++){var f=a[e];if(this._contains(d,f))for(var f=b(f).getDistributedNodes(),g=0;g<f.length;g++){var k=!0;var l=f[g],r=c.Composed.getParentNode(l);r&&c.Composed.removeChild(r,l)}}return k},_contains:function(a,b){for(;b;){if(b==a)return!0;\nb=c.Logical.getParentNode(b)}},_removeOwnerShadyRoot:function(a){if(this._hasCachedOwnerRoot(a))for(var b=c.Logical.getChildNodes(a),d=0,e=b.length,f;d<e&&(f=b[d]);d++)this._removeOwnerShadyRoot(f);a._ownerShadyRoot=void 0},_firstComposedNode:function(a){for(var c=b(a).getDistributedNodes(),d=0,e=c.length,f,g;d<e&&(f=c[d]);d++)if(g=b(f).getDestinationInsertionPoints(),g[g.length-1]===a)return f},querySelector:function(b){return this._query(function(c){return a.matchesSelector.call(c,b)},this.node,\nfunction(a){return!!a})[0]||null},querySelectorAll:function(b){return this._query(function(c){return a.matchesSelector.call(c,b)},this.node)},getDestinationInsertionPoints:function(){return this.node._destinationInsertionPoints||[]},getDistributedNodes:function(){return this.node._distributedNodes||[]},_clear:function(){for(;this.childNodes.length;)this.removeChild(this.childNodes[0])},setAttribute:function(a,b){this.node.setAttribute(a,b);this._maybeDistributeParent()},removeAttribute:function(a){this.node.removeAttribute(a);\nthis._maybeDistributeParent()},_maybeDistributeParent:function(){if(this._nodeNeedsDistribution(this.parentNode))return this._lazyDistribute(this.parentNode),!0},cloneNode:function(a){var c=f.call(this.node,!1);if(a){a=this.childNodes;for(var d=b(c),e=0,g;e<a.length;e++)g=b(a[e]).cloneNode(!0),d.appendChild(g)}return c},importNode:function(a,d){var e=this.node instanceof Document?this.node:this.node.ownerDocument,f=g.call(e,a,!1);if(d){a=c.Logical.getChildNodes(a);d=b(f);for(var k=0,l;k<a.length;k++)l=\nb(e).importNode(a[k],!0),d.appendChild(l)}return f},_getComposedInnerHTML:function(){return d(this.node,!0)}});Object.defineProperties(a.prototype,{activeElement:{get:function(){var a=document.activeElement;if(!a)return null;var c=!!this.node._isShadyRoot;if(!(this.node===document||c&&this.node.host!==a&&this.node.host.contains(a)))return null;for(c=b(a).getOwnerRoot();c&&c!==this.node;)a=c.host,c=b(a).getOwnerRoot();return this.node===document?c?null:a:c===this.node?a:null},configurable:!0},childNodes:{get:function(){var a=\nc.Logical.getChildNodes(this.node);return Array.isArray(a)?a:c.arrayCopyChildNodes(this.node)},configurable:!0},children:{get:function(){return c.Logical.hasChildNodes(this.node)?Array.prototype.filter.call(this.childNodes,function(a){return a.nodeType===Node.ELEMENT_NODE}):c.arrayCopyChildren(this.node)},configurable:!0},parentNode:{get:function(){return c.Logical.getParentNode(this.node)},configurable:!0},firstChild:{get:function(){return c.Logical.getFirstChild(this.node)},configurable:!0},lastChild:{get:function(){return c.Logical.getLastChild(this.node)},\nconfigurable:!0},nextSibling:{get:function(){return c.Logical.getNextSibling(this.node)},configurable:!0},previousSibling:{get:function(){return c.Logical.getPreviousSibling(this.node)},configurable:!0},firstElementChild:{get:function(){return c.Logical.getFirstElementChild(this.node)},configurable:!0},lastElementChild:{get:function(){return c.Logical.getLastElementChild(this.node)},configurable:!0},nextElementSibling:{get:function(){return c.Logical.getNextElementSibling(this.node)},configurable:!0},\npreviousElementSibling:{get:function(){return c.Logical.getPreviousElementSibling(this.node)},configurable:!0},textContent:{get:function(){var a=this.node.nodeType;if(a===Node.TEXT_NODE||a===Node.COMMENT_NODE)return this.node.textContent;for(var a=[],b=0,c=this.childNodes,d;d=c[b];b++)d.nodeType!==Node.COMMENT_NODE&&a.push(d.textContent);return a.join(\"\")},set:function(a){var b=this.node.nodeType;b===Node.TEXT_NODE||b===Node.COMMENT_NODE?this.node.textContent=a:(this._clear(),a&&this.appendChild(document.createTextNode(a)))},\nconfigurable:!0},innerHTML:{get:function(){var a=this.node.nodeType;return a===Node.TEXT_NODE||a===Node.COMMENT_NODE?null:d(this.node)},set:function(a){var b=this.node.nodeType;if(b!==Node.TEXT_NODE||b!==Node.COMMENT_NODE)for(this._clear(),b=document.createElement(\"div\"),b.innerHTML=a,a=c.arrayCopyChildNodes(b),b=0;b<a.length;b++)this.appendChild(a[b])},configurable:!0}});a.hasInsertionPoint=function(a){return!(!a||!a._insertionPoints.length)}}})();\n(function(){var a=Polymer.TreeApi,b=Polymer.DomApi;if(Polymer.Settings.useShadow){Polymer.Base.mixin(b.prototype,{querySelectorAll:function(b){return a.arrayCopy(this.node.querySelectorAll(b))},getOwnerRoot:function(){for(var a=this.node;a;){if(a.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&a.host)return a;a=a.parentNode}},importNode:function(a,b){return(this.node instanceof Document?this.node:this.node.ownerDocument).importNode(a,b)},getDestinationInsertionPoints:function(){var b=this.node.getDestinationInsertionPoints&&\nthis.node.getDestinationInsertionPoints();return b?a.arrayCopy(b):[]},getDistributedNodes:function(){var b=this.node.getDistributedNodes&&this.node.getDistributedNodes();return b?a.arrayCopy(b):[]}});Object.defineProperties(b.prototype,{activeElement:{get:function(){var a=b.wrap(this.node),c=a.activeElement;return a.contains(c)?c:null},configurable:!0},childNodes:{get:function(){return a.arrayCopyChildNodes(this.node)},configurable:!0},children:{get:function(){return a.arrayCopyChildren(this.node)},\nconfigurable:!0},textContent:{get:function(){return this.node.textContent},set:function(a){return this.node.textContent=a},configurable:!0},innerHTML:{get:function(){return this.node.innerHTML},set:function(a){return this.node.innerHTML=a},configurable:!0}});var c=function(a){b.prototype[a]=function(){return this.node[a].apply(this.node,arguments)}};(function(a){for(var b=0;b<a.length;b++)c(a[b])})(\"cloneNode appendChild insertBefore removeChild replaceChild setAttribute removeAttribute querySelector\".split(\" \"));\nvar d=function(a){Object.defineProperty(b.prototype,a,{get:function(){return this.node[a]},configurable:!0})};(function(a){for(var b=0;b<a.length;b++)d(a[b])})(\"parentNode firstChild lastChild nextSibling previousSibling firstElementChild lastElementChild nextElementSibling previousElementSibling\".split(\" \"))}})();\nPolymer.Base.mixin(Polymer.dom,{_flushGuard:0,_FLUSH_MAX:100,_needsTakeRecords:!Polymer.Settings.useNativeCustomElements,_debouncers:[],_staticFlushList:[],_finishDebouncer:null,flush:function(){this._flushGuard=0;for(this._prepareFlush();this._debouncers.length&&this._flushGuard<this._FLUSH_MAX;){for(;this._debouncers.length;)this._debouncers.shift().complete();this._finishDebouncer&&this._finishDebouncer.complete();this._prepareFlush();this._flushGuard++}this._flushGuard>=this._FLUSH_MAX&&console.warn(\"Polymer.dom.flush aborted. Flush may not be complete.\")},\n_prepareFlush:function(){this._needsTakeRecords&&CustomElements.takeRecords();for(var a=0;a<this._staticFlushList.length;a++)this._staticFlushList[a]()},addStaticFlush:function(a){this._staticFlushList.push(a)},removeStaticFlush:function(a){a=this._staticFlushList.indexOf(a);0<=a&&this._staticFlushList.splice(a,1)},addDebouncer:function(a){this._debouncers.push(a);this._finishDebouncer=Polymer.Debounce(this._finishDebouncer,this._finishFlush)},_finishFlush:function(){Polymer.dom._debouncers=[]}});\nPolymer.EventApi=function(){var a=Polymer.DomApi.ctor,b=Polymer.Settings;a.Event=function(a){this.event=a};a.Event.prototype=b.useShadow?{get rootTarget(){return this.event.path[0]},get localTarget(){return this.event.target},get path(){var a=this.event.path;Array.isArray(a)||(a=Array.prototype.slice.call(a));return a}}:{get rootTarget(){return this.event.target},get localTarget(){for(var a=this.event.currentTarget,a=a&&Polymer.dom(a).getOwnerRoot(),b=this.path,e=0;e<b.length;e++)if(Polymer.dom(b[e]).getOwnerRoot()===\na)return b[e]},get path(){if(!this.event._path){for(var a=[],b=this.rootTarget;b;){a.push(b);var e=Polymer.dom(b).getDestinationInsertionPoints();if(e.length){for(b=0;b<e.length-1;b++)a.push(e[b]);b=e[e.length-1]}else b=Polymer.dom(b).parentNode||b.host}a.push(window);this.event._path=a}return this.event._path}};return{factory:function(b){b.__eventApi||(b.__eventApi=new a.Event(b));return b.__eventApi}}}();\n(function(){var a=Polymer.DomApi.ctor,b=Polymer.Settings.useShadow;Object.defineProperty(a.prototype,\"classList\",{get:function(){this._classList||(this._classList=new a.ClassList(this));return this._classList},configurable:!0});a.ClassList=function(a){this.domApi=a;this.node=a.node};a.ClassList.prototype={add:function(){this.node.classList.add.apply(this.node.classList,arguments);this._distributeParent()},remove:function(){this.node.classList.remove.apply(this.node.classList,arguments);this._distributeParent()},\ntoggle:function(){this.node.classList.toggle.apply(this.node.classList,arguments);this._distributeParent()},_distributeParent:function(){b||this.domApi._maybeDistributeParent()},contains:function(){return this.node.classList.contains.apply(this.node.classList,arguments)}}})();\n(function(){var a=Polymer.DomApi.ctor,b=Polymer.Settings;a.EffectiveNodesObserver=function(a){this.domApi=a;this.node=this.domApi.node;this._listeners=[]};a.EffectiveNodesObserver.prototype={addListener:function(a){this._isSetup||(this._setup(),this._isSetup=!0);a={fn:a,_nodes:[]};this._listeners.push(a);this._scheduleNotify();return a},removeListener:function(a){var b=this._listeners.indexOf(a);0<=b&&(this._listeners.splice(b,1),a._nodes=[]);this._hasListeners()||(this._cleanup(),this._isSetup=!1)},\n_setup:function(){this._observeContentElements(this.domApi.childNodes)},_cleanup:function(){this._unobserveContentElements(this.domApi.childNodes)},_hasListeners:function(){return!!this._listeners.length},_scheduleNotify:function(){this._debouncer&&this._debouncer.stop();this._debouncer=Polymer.Debounce(this._debouncer,this._notify);this._debouncer.context=this;Polymer.dom.addDebouncer(this._debouncer)},notify:function(){this._hasListeners()&&this._scheduleNotify()},_notify:function(){this._beforeCallListeners();\nthis._callListeners()},_beforeCallListeners:function(){this._updateContentElements()},_updateContentElements:function(){this._observeContentElements(this.domApi.childNodes)},_observeContentElements:function(a){for(var b=0,c;b<a.length&&(c=a[b]);b++)this._isContent(c)&&(c.__observeNodesMap=c.__observeNodesMap||new WeakMap,c.__observeNodesMap.has(this)||c.__observeNodesMap.set(this,this._observeContent(c)))},_observeContent:function(a){var b=this;a=Polymer.dom(a).observeNodes(function(){b._scheduleNotify()});\na._avoidChangeCalculation=!0;return a},_unobserveContentElements:function(a){for(var b=0,c,d;b<a.length&&(c=a[b]);b++)this._isContent(c)&&(d=c.__observeNodesMap.get(this))&&(Polymer.dom(c).unobserveNodes(d),c.__observeNodesMap.delete(this))},_isContent:function(a){return\"content\"===a.localName},_callListeners:function(){for(var a=this._listeners,b=this._getEffectiveNodes(),c=0,d;c<a.length&&(d=a[c]);c++){var l=this._generateListenerInfo(d,b);(l||d._alwaysNotify)&&this._callListener(d,l)}},_getEffectiveNodes:function(){return this.domApi.getEffectiveChildNodes()},\n_generateListenerInfo:function(a,b){if(a._avoidChangeCalculation)return!0;for(var c={target:this.node,addedNodes:[],removedNodes:[]},d=Polymer.ArraySplice.calculateSplices(b,a._nodes),e=0,f;e<d.length&&(f=d[e]);e++)for(var n=0,q;n<f.removed.length&&(q=f.removed[n]);n++)c.removedNodes.push(q);e=0;for(f;e<d.length&&(f=d[e]);e++)for(n=f.index;n<f.index+f.addedCount;n++)c.addedNodes.push(b[n]);a._nodes=b;if(c.addedNodes.length||c.removedNodes.length)return c},_callListener:function(a,b){return a.fn.call(this.node,\nb)},enableShadowAttributeTracking:function(){}};if(b.useShadow){var c=a.EffectiveNodesObserver.prototype._setup,d=a.EffectiveNodesObserver.prototype._cleanup;Polymer.Base.mixin(a.EffectiveNodesObserver.prototype,{_setup:function(){if(!this._observer){var a=this;this._mutationHandler=function(b){b&&b.length&&a._scheduleNotify()};this._observer=new MutationObserver(this._mutationHandler);this._boundFlush=function(){a._flush()};Polymer.dom.addStaticFlush(this._boundFlush);this._observer.observe(this.node,\n{childList:!0})}c.call(this)},_cleanup:function(){this._observer.disconnect();this._mutationHandler=this._observer=null;Polymer.dom.removeStaticFlush(this._boundFlush);d.call(this)},_flush:function(){this._observer&&this._mutationHandler(this._observer.takeRecords())},enableShadowAttributeTracking:function(){if(this._observer){this._makeContentListenersAlwaysNotify();this._observer.disconnect();this._observer.observe(this.node,{childList:!0,attributes:!0,subtree:!0});var a=this.domApi.getOwnerRoot();\n(a=a&&a.host)&&Polymer.dom(a).observer&&Polymer.dom(a).observer.enableShadowAttributeTracking()}},_makeContentListenersAlwaysNotify:function(){for(var a=0,b;a<this._listeners.length;a++)b=this._listeners[a],b._alwaysNotify=b._isContentListener}})}})();\n(function(){var a=Polymer.DomApi.ctor,b=Polymer.Settings;a.DistributedNodesObserver=function(b){a.EffectiveNodesObserver.call(this,b)};a.DistributedNodesObserver.prototype=Object.create(a.EffectiveNodesObserver.prototype);Polymer.Base.mixin(a.DistributedNodesObserver.prototype,{_setup:function(){},_cleanup:function(){},_beforeCallListeners:function(){},_getEffectiveNodes:function(){return this.domApi.getDistributedNodes()}});b.useShadow&&Polymer.Base.mixin(a.DistributedNodesObserver.prototype,{_setup:function(){if(!this._observer){var a=\nthis.domApi.getOwnerRoot();if(a=a&&a.host){var b=this;this._observer=Polymer.dom(a).observeNodes(function(){b._scheduleNotify()});this._observer._isContentListener=!0;this._hasAttrSelect()&&Polymer.dom(a).observer.enableShadowAttributeTracking()}}},_hasAttrSelect:function(){var a=this.node.getAttribute(\"select\");return a&&a.match(/[[.]+/)},_cleanup:function(){var a=this.domApi.getOwnerRoot();(a=a&&a.host)&&Polymer.dom(a).unobserveNodes(this._observer);this._observer=null}})})();\n(function(){function a(a,b){b._distributedNodes.push(a);var c=a._destinationInsertionPoints;c?c.push(b):a._destinationInsertionPoints=[b]}function b(a){for(var b=d.Logical.getChildNodes(a),c=0,e;c<b.length;c++)if(e=b[c],e.localName&&\"content\"===e.localName)return a.domHost}var c=Polymer.DomApi,d=Polymer.TreeApi;Polymer.Base._addFeature({_prepShady:function(){this._useContent=this._useContent||!!this._template},_setupShady:function(){this.shadyRoot=null;this.__domApi||(this.__domApi=null);this.__dom||\n(this.__dom=null);this._ownerShadyRoot||(this._ownerShadyRoot=void 0)},_poolContent:function(){this._useContent&&d.Logical.saveChildNodes(this)},_setupRoot:function(){if(this._useContent&&(this._createLocalRoot(),!this.dataHost)){var a=d.Logical.getChildNodes(this);if(f&&a)for(var b=0;b<a.length;b++)CustomElements.upgrade(a[b])}},_createLocalRoot:function(){this.shadyRoot=this.root;this.shadyRoot._distributionClean=!1;this.shadyRoot._hasDistributed=!1;this.shadyRoot._isShadyRoot=!0;this.shadyRoot._dirtyRoots=\n[];var a=this.shadyRoot._insertionPoints=!this._notes||this._notes._hasContent?this.shadyRoot.querySelectorAll(\"content\"):[];d.Logical.saveChildNodes(this.shadyRoot);for(var b=0,c;b<a.length;b++)c=a[b],d.Logical.saveChildNodes(c),d.Logical.saveChildNodes(c.parentNode);this.shadyRoot.host=this},distributeContent:function(a){if(this.shadyRoot){this.shadyRoot._invalidInsertionPoints=this.shadyRoot._invalidInsertionPoints||a;for(a=this;a&&b(a);)a=a.domHost;Polymer.dom(this)._lazyDistribute(a)}},_distributeContent:function(){this._useContent&&\n!this.shadyRoot._distributionClean&&(this.shadyRoot._invalidInsertionPoints&&(Polymer.dom(this)._updateInsertionPoints(this),this.shadyRoot._invalidInsertionPoints=!1),this._beginDistribute(),this._distributeDirtyRoots(),this._finishDistribute())},_beginDistribute:function(){this._useContent&&c.hasInsertionPoint(this.shadyRoot)&&(this._resetDistribution(),this._distributePool(this.shadyRoot,this._collectPool()))},_distributeDirtyRoots:function(){for(var a=this.shadyRoot._dirtyRoots,b=0,c=a.length,\nd;b<c&&(d=a[b]);b++)d._distributeContent();this.shadyRoot._dirtyRoots=[]},_finishDistribute:function(){if(this._useContent){this.shadyRoot._distributionClean=!0;if(c.hasInsertionPoint(this.shadyRoot)){this._composeTree();for(var a=this.shadyRoot,b=0,e;b<a._insertionPoints.length;b++)e=a._insertionPoints[b],c.hasApi(e)&&Polymer.dom(e).notifyObserver()}else this.shadyRoot._hasDistributed?(a=this._composeNode(this),this._updateChildNodes(this,a)):(d.Composed.clearChildNodes(this),this.appendChild(this.shadyRoot));\nthis.shadyRoot._hasDistributed||c.hasApi(this)&&Polymer.dom(this).notifyObserver();this.shadyRoot._hasDistributed=!0}},elementMatches:function(a,b){return c.matchesSelector.call(b||this,a)},_resetDistribution:function(){for(var a=d.Logical.getChildNodes(this),b=0;b<a.length;b++){var c=a[b];c._destinationInsertionPoints&&(c._destinationInsertionPoints=void 0);if(\"content\"==c.localName){var e=c._distributedNodes;if(e)for(var f=0;f<e.length;f++){var q=e[f]._destinationInsertionPoints;q&&q.splice(q.indexOf(c)+\n1,q.length)}}}a=this.shadyRoot._insertionPoints;for(b=0;b<a.length;b++)a[b]._distributedNodes=[]},_collectPool:function(){for(var a=[],b=d.Logical.getChildNodes(this),c=0;c<b.length;c++){var e=b[c];\"content\"==e.localName?a.push.apply(a,e._distributedNodes):a.push(e)}return a},_distributePool:function(a,b){a=a._insertionPoints;for(var e=0,f=a.length,g;e<f&&(g=a[e]);e++){this._distributeInsertionPoint(g,b);var k=d.Logical.getParentNode(g);k&&k.shadyRoot&&c.hasInsertionPoint(k.shadyRoot)&&k.shadyRoot._distributionClean&&\n(k.shadyRoot._distributionClean=!1,this.shadyRoot._dirtyRoots.push(k))}},_distributeInsertionPoint:function(b,c){for(var e=!1,f=0,g=c.length,k;f<g;f++)(k=c[f])&&this._matchesContentSelect(k,b)&&(a(k,b),c[f]=void 0,e=!0);if(!e)for(c=d.Logical.getChildNodes(b),e=0;e<c.length;e++)a(c[e],b)},_composeTree:function(){this._updateChildNodes(this,this._composeNode(this));for(var a=this.shadyRoot._insertionPoints,b=0,c=a.length,e,f;b<c&&(e=a[b]);b++)f=d.Logical.getParentNode(e),f._useContent||f===this||f===\nthis.shadyRoot||this._updateChildNodes(f,this._composeNode(f))},_composeNode:function(a){var b=[];a=d.Logical.getChildNodes(a.shadyRoot||a);for(var c=0;c<a.length;c++){var e=a[c];if(\"content\"==e.localName)for(var f=e._distributedNodes,g=0;g<f.length;g++){var p=f[g],t=p._destinationInsertionPoints;t&&t[t.length-1]===e&&b.push(p)}else b.push(e)}return b},_updateChildNodes:function(a,b){for(var c=d.Composed.getChildNodes(a),e=Polymer.ArraySplice.calculateSplices(b,c),f=0,g=0,k;f<e.length&&(k=e[f]);f++){for(var t=\n0,r;t<k.removed.length&&(r=k.removed[t]);t++)d.Composed.getParentNode(r)===a&&d.Composed.removeChild(a,r),c.splice(k.index+g,1);g-=k.addedCount}for(f=0;f<e.length&&(k=e[f]);f++)for(g=c[k.index],t=k.index,r;t<k.index+k.addedCount;t++)r=b[t],d.Composed.insertBefore(a,r,g),c.splice(t,0,r)},_matchesContentSelect:function(a,b){b=b.getAttribute(\"select\");return b?(b=b.trim())?a instanceof Element&&/^(:not\\()?[*.#[a-zA-Z_|]/.test(b)?this.elementMatches(b,a):!1:!0:!0},_elementAdd:function(){},_elementRemove:function(){}});\nvar e={get:function(){var a=Polymer.dom(this).getOwnerRoot();return a&&a.host},configurable:!0};Object.defineProperty(Polymer.Base,\"domHost\",e);Polymer.BaseDescriptors.domHost=e;var f=window.CustomElements&&!CustomElements.useNative})();\nPolymer.Settings.useShadow&&Polymer.Base._addFeature({_poolContent:function(){},_beginDistribute:function(){},distributeContent:function(){},_distributeContent:function(){},_finishDistribute:function(){},_createLocalRoot:function(){this.createShadowRoot();this.shadowRoot.appendChild(this.root);this.root=this.shadowRoot}});\nPolymer.Async={_currVal:0,_lastVal:0,_callbacks:[],_twiddleContent:0,_twiddle:document.createTextNode(\"\"),run:function(a,b){if(0<b)return~setTimeout(a,b);this._twiddle.textContent=this._twiddleContent++;this._callbacks.push(a);return this._currVal++},cancel:function(a){if(0>a)clearTimeout(~a);else{var b=a-this._lastVal;if(0<=b){if(!this._callbacks[b])throw\"invalid async handle: \"+a;this._callbacks[b]=null}}},_atEndOfMicrotask:function(){for(var a=this._callbacks.length,b=0;b<a;b++){var c=this._callbacks[b];\nif(c)try{c()}catch(d){throw b++,this._callbacks.splice(0,b),this._lastVal+=b,this._twiddle.textContent=this._twiddleContent++,d;}}this._callbacks.splice(0,a);this._lastVal+=a}};(new window.MutationObserver(function(){Polymer.Async._atEndOfMicrotask()})).observe(Polymer.Async._twiddle,{characterData:!0});\nPolymer.Debounce=function(){function a(a){this.context=a;var b=this;this.boundComplete=function(){b.complete()}}var b=Polymer.Async;a.prototype={go:function(a,d){this.finish=function(){b.cancel(c)};var c=b.run(this.boundComplete,d);this.callback=a},stop:function(){this.finish&&(this.finish(),this.callback=this.finish=null)},complete:function(){if(this.finish){var a=this.callback;this.stop();a.call(this.context)}}};return function(b,d,e){b?b.stop():b=new a(this);b.go(d,e);return b}}();\nPolymer.Base._addFeature({_setupDebouncers:function(){this._debouncers={}},debounce:function(a,b,c){return this._debouncers[a]=Polymer.Debounce.call(this,this._debouncers[a],b,c)},isDebouncerActive:function(a){a=this._debouncers[a];return!(!a||!a.finish)},flushDebouncer:function(a){(a=this._debouncers[a])&&a.complete()},cancelDebouncer:function(a){(a=this._debouncers[a])&&a.stop()}});Polymer.DomModule=document.createElement(\"dom-module\");\nPolymer.Base._addFeature({_registerFeatures:function(){this._prepIs();this._prepBehaviors();this._prepConstructor();this._prepTemplate();this._prepShady();this._prepPropertyInfo()},_prepBehavior:function(a){this._addHostAttributes(a.hostAttributes)},_initFeatures:function(){this._registerHost();this._template&&(this._poolContent(),this._beginHosting(),this._stampTemplate(),this._endHosting());this._marshalHostAttributes();this._setupDebouncers();this._marshalBehaviors();this._tryReady()},_marshalBehavior:function(){}});\n</script>\n\n\n\n\n\n\n<script>//~~WEBPATH~~/polymer/polymer.html.js\n(function(){Polymer.nar=[];var a=Polymer.Settings.disableUpgradeEnabled;Polymer.Annotations={parseAnnotations:function(a,c){var b=[];this._parseNodeAnnotations(a._content||a.content,b,c||a.hasAttribute(\"strip-whitespace\"));return b},_parseNodeAnnotations:function(a,c,d){return a.nodeType===Node.TEXT_NODE?this._parseTextNodeAnnotation(a,c):this._parseElementAnnotations(a,c,d)},_bindingRegex:/(\\[\\[|{{)\\s*(?:(!)\\s*)?((?:[a-zA-Z_$][\\w.:$\\-*]*)\\s*(?:\\(\\s*(?:(?:(?:(?:[a-zA-Z_$][\\w.:$\\-*]*)|(?:[-+]?[0-9]*\\.?[0-9]+(?:[eE][-+]?[0-9]+)?)|(?:(?:'(?:[^'\\\\]|\\\\.)*')|(?:\"(?:[^\"\\\\]|\\\\.)*\"))\\s*)(?:,\\s*(?:(?:[a-zA-Z_$][\\w.:$\\-*]*)|(?:[-+]?[0-9]*\\.?[0-9]+(?:[eE][-+]?[0-9]+)?)|(?:(?:'(?:[^'\\\\]|\\\\.)*')|(?:\"(?:[^\"\\\\]|\\\\.)*\"))\\s*))*)?)\\)\\s*)?)(?:]]|}})/g,\n_parseBindings:function(a){for(var b=this._bindingRegex,d=[],e=0,f;null!==(f=b.exec(a));){f.index>e&&d.push({literal:a.slice(e,f.index)});var e=f[1][0],g=!!f[2];f=f[3].trim();var k;if(\"{\"==e&&0<(k=f.indexOf(\"::\"))){var l=f.substring(k+2);f=f.substring(0,k);var m=!0}d.push({compoundIndex:d.length,value:f,mode:e,negate:g,event:l,customEvent:m});e=b.lastIndex}e&&e<a.length&&(a=a.substring(e))&&d.push({literal:a});if(d.length)return d},_literalFromParts:function(a){for(var b=\"\",d=0;d<a.length;d++)b+=\na[d].literal||\"\";return b},_parseTextNodeAnnotation:function(a,c){var b=this._parseBindings(a.textContent);if(b)return a.textContent=this._literalFromParts(b)||\" \",a={bindings:[{kind:\"text\",name:\"textContent\",parts:b,isCompound:1!==b.length}]},c.push(a),a},_parseElementAnnotations:function(a,c,d){var b={bindings:[],events:[]};\"content\"===a.localName&&(c._hasContent=!0);this._parseChildNodesAnnotations(a,b,c,d);a.attributes&&(this._parseNodeAttributeAnnotations(a,b,c),this.prepElement&&this.prepElement(a));\n(b.bindings.length||b.events.length||b.id)&&c.push(b);return b},_parseChildNodesAnnotations:function(a,c,d,e){if(a.firstChild)for(var b=a.firstChild,g=0;b;){var k=b.nextSibling;\"template\"!==b.localName||b.hasAttribute(\"preserve-content\")||this._parseTemplate(b,g,d,c,e);\"slot\"==b.localName&&(b=this._replaceSlotWithContent(b));if(b.nodeType===Node.TEXT_NODE){for(var l=k;l&&l.nodeType===Node.TEXT_NODE;)b.textContent+=l.textContent,k=l.nextSibling,a.removeChild(l),l=k;e&&!b.textContent.trim()&&(a.removeChild(b),\ng--)}b.parentNode&&(b=this._parseNodeAnnotations(b,d,e))&&(b.parent=c,b.index=g);b=k;g++}},_replaceSlotWithContent:function(a){for(var b=a.ownerDocument.createElement(\"content\");a.firstChild;)b.appendChild(a.firstChild);for(var d=a.attributes,e=0;e<d.length;e++){var f=d[e];b.setAttribute(f.name,f.value)}(d=a.getAttribute(\"name\"))&&b.setAttribute(\"select\",\"[slot\\x3d'\"+d+\"']\");a.parentNode.replaceChild(b,a);return b},_parseTemplate:function(a,c,d,e,f){var b=document.createDocumentFragment();b._notes=\nthis.parseAnnotations(a,f);b.appendChild(a.content);d.push({bindings:Polymer.nar,events:Polymer.nar,templateContent:b,parent:e,index:c})},_parseNodeAttributeAnnotations:function(a,c){for(var b=Array.prototype.slice.call(a.attributes),e=b.length-1,f;f=b[e];e--){var g=f.name;f=f.value;var k;\"on-\"===g.slice(0,3)?(a.removeAttribute(g),c.events.push({name:g.slice(3),value:f})):(k=this._parseNodeAttributeAnnotation(a,g,f))?c.bindings.push(k):\"id\"===g&&(c.id=f)}},_parseNodeAttributeAnnotation:function(b,\nc,d){if(d=this._parseBindings(d)){var e=c,f=\"property\";\"$\"==c[c.length-1]&&(c=c.slice(0,-1),f=\"attribute\");var g=this._literalFromParts(d);g&&\"attribute\"==f&&b.setAttribute(c,g);\"input\"===b.localName&&\"value\"===e&&b.setAttribute(e,\"\");a&&\"disable-upgrade$\"===e&&b.setAttribute(c,\"\");b.removeAttribute(e);b=Polymer.CaseMap.dashToCamelCase(c);\"property\"===f&&(c=b);return{kind:f,name:c,propertyName:b,parts:d,literal:g,isCompound:1!==d.length}}},findAnnotatedNode:function(a,c){var b=c.parent&&Polymer.Annotations.findAnnotatedNode(a,\nc.parent);if(b)for(a=b.firstChild,b=0;a;a=a.nextSibling){if(c.index===b++)return a}else return a}}})();\n(function(){function a(a,c){return a.replace(e,function(a,d,e,f){return d+\"'\"+b(e.replace(/[\"']/g,\"\"),c)+\"'\"+f})}function b(a,b){if(a&&g.test(a))return a;b=b.body.__urlResolver||(b.body.__urlResolver=b.createElement(\"a\"));b.href=a;return b.href||a}var c,d,e=/(url\\()([^)]*)(\\))/g,f={\"*\":[\"href\",\"src\",\"style\",\"url\"],form:[\"action\"]},g=/(^\\/)|(^#)|(^[\\w-\\d]*:)/,k=/\\{\\{|\\[\\[/;Polymer.ResolveUrl={resolveCss:a,resolveAttrs:function(c,d){for(var e in f)for(var g=f[e],l=0,m=g.length,r,v,w;l<m&&(r=g[l]);l++)(\"*\"===\ne||c.localName===e)&&(w=(v=c.attributes[r])&&v.value)&&0>w.search(k)&&(v.value=\"style\"===r?a(w,d):b(w,d))},resolveUrl:function(a,e){c||(c=document.implementation.createHTMLDocument(\"temp\"),d=c.createElement(\"base\"),c.head.appendChild(d));d.href=e;return b(a,c)}}})();\nPolymer.Path={root:function(a){var b=a.indexOf(\".\");return-1===b?a:a.slice(0,b)},isDeep:function(a){return-1!==a.indexOf(\".\")},isAncestor:function(a,b){return 0===a.indexOf(b+\".\")},isDescendant:function(a,b){return 0===b.indexOf(a+\".\")},translate:function(a,b,c){return b+c.slice(a.length)},matches:function(a,b,c){return a===c||this.isAncestor(a,c)||!!b&&this.isDescendant(a,c)}};\nPolymer.Base._addFeature({_prepAnnotations:function(){if(this._template){var a=this;Polymer.Annotations.prepElement=function(b){a._prepElement(b)};this._template._content&&this._template._content._notes?this._notes=this._template._content._notes:(this._notes=Polymer.Annotations.parseAnnotations(this._template),this._processAnnotations(this._notes));Polymer.Annotations.prepElement=null}else this._notes=[]},_processAnnotations:function(a){for(var b=0;b<a.length;b++){for(var c=a[b],d=0;d<c.bindings.length;d++)for(var e=\nc.bindings[d],f=0;f<e.parts.length;f++){var g=e.parts[f];if(!g.literal){var k=this._parseMethod(g.value);k?g.signature=k:g.model=Polymer.Path.root(g.value)}}if(c.templateContent){this._processAnnotations(c.templateContent._notes);var e=c.templateContent._parentProps=this._discoverTemplateParentProps(c.templateContent._notes),d=[],l;for(l in e)e=\"_parent_\"+l,d.push({index:c.index,kind:\"property\",name:e,propertyName:e,parts:[{mode:\"{\",model:l,value:l}]});c.bindings=c.bindings.concat(d)}}},_discoverTemplateParentProps:function(a){for(var b=\n{},c=0,d;c<a.length&&(d=a[c]);c++){for(var e=0,f=d.bindings,g;e<f.length&&(g=f[e]);e++)for(var k=0,l=g.parts,m;k<l.length&&(m=l[k]);k++)if(m.signature){for(var n=m.signature.args,q=0;q<n.length;q++){var p=n[q].model;p&&(b[p]=!0)}m.signature.dynamicFn&&(b[m.signature.method]=!0)}else m.model&&(b[m.model]=!0);d.templateContent&&Polymer.Base.mixin(b,d.templateContent._parentProps)}return b},_prepElement:function(a){Polymer.ResolveUrl.resolveAttrs(a,this._template.ownerDocument)},_findAnnotatedNode:Polymer.Annotations.findAnnotatedNode,\n_marshalAnnotationReferences:function(){this._template&&(this._marshalIdNodes(),this._marshalAnnotatedNodes(),this._marshalAnnotatedListeners())},_configureAnnotationReferences:function(){for(var a=this._notes,b=this._nodes,c=0;c<a.length;c++){var d=a[c],e=b[c];this._configureTemplateContent(d,e);this._configureCompoundBindings(d,e)}},_configureTemplateContent:function(a,b){a.templateContent&&(b._content=a.templateContent)},_configureCompoundBindings:function(a,b){a=a.bindings;for(var c=0;c<a.length;c++){var d=\na[c];if(d.isCompound){for(var e=b.__compoundStorage__||(b.__compoundStorage__={}),f=d.parts,g=Array(f.length),k=0;k<f.length;k++)g[k]=f[k].literal;f=d.name;e[f]=g;d.literal&&\"property\"==d.kind&&(b._configValue?b._configValue(f,d.literal):b[f]=d.literal)}}},_marshalIdNodes:function(){this.$={};for(var a=0,b=this._notes.length,c;a<b&&(c=this._notes[a]);a++)c.id&&(this.$[c.id]=this._findAnnotatedNode(this.root,c))},_marshalAnnotatedNodes:function(){if(this._notes&&this._notes.length){for(var a=Array(this._notes.length),\nb=0;b<this._notes.length;b++)a[b]=this._findAnnotatedNode(this.root,this._notes[b]);this._nodes=a}},_marshalAnnotatedListeners:function(){for(var a=0,b=this._notes.length,c;a<b&&(c=this._notes[a]);a++)if(c.events&&c.events.length)for(var d=this._findAnnotatedNode(this.root,c),e=0,f=c.events,g;e<f.length&&(g=f[e]);e++)this.listen(d,g.name,g.value)}});\nPolymer.Base._addFeature({listeners:{},_listenListeners:function(a){var b;for(b in a){if(0>b.indexOf(\".\")){var c=this;var d=b}else d=b.split(\".\"),c=this.$[d[0]],d=d[1];this.listen(c,d,a[b])}},listen:function(a,b,c){var d=this._recallEventHandler(this,b,a,c);d||(d=this._createEventHandler(a,b,c));d._listening||(this._listen(a,b,d),d._listening=!0)},_boundListenerKey:function(a,b){return a+\":\"+b},_recordEventHandler:function(a,b,c,d,e){var f=a.__boundListeners;f||(f=a.__boundListeners=new WeakMap);\na=f.get(c);a||(a={},Polymer.Settings.isIE&&c==window||f.set(c,a));a[this._boundListenerKey(b,d)]=e},_recallEventHandler:function(a,b,c,d){if(a=a.__boundListeners)if(c=a.get(c))return c[this._boundListenerKey(b,d)]},_createEventHandler:function(a,b,c){function d(a){if(e[c])e[c](a,a.detail);else e._warn(e._logf(\"_createEventHandler\",\"listener method `\"+c+\"` not defined\"))}var e=this;d._listening=!1;this._recordEventHandler(e,b,a,c,d);return d},unlisten:function(a,b,c){if(c=this._recallEventHandler(this,\nb,a,c))this._unlisten(a,b,c),c._listening=!1},_listen:function(a,b,c){a.addEventListener(b,c)},_unlisten:function(a,b,c){a.removeEventListener(b,c)}});\n(function(){function a(a){var b=a.sourceCapabilities;if(!b||b.firesTouchEvents)if(a.__polymerGesturesHandled={skip:!0},\"click\"===a.type){for(var b=Polymer.dom(a).path,c=0;c<b.length;c++)if(b[c]===p.mouse.target)return;a.preventDefault();a.stopPropagation()}}function b(b){for(var c=q?[\"click\"]:k,d=0,e;d<c.length;d++)e=c[d],b?document.addEventListener(e,a,!0):document.removeEventListener(e,a,!0)}function c(a){var b=a.type;return-1===k.indexOf(b)?!1:\"mousemove\"===b?(b=void 0===a.buttons?1:a.buttons,\na instanceof window.MouseEvent&&!m&&(b=l[a.which]||0),!!(b&1)):0===(void 0===a.button?0:a.button)}function d(a,b,c){a.movefn=b;a.upfn=c;document.addEventListener(\"mousemove\",b);document.addEventListener(\"mouseup\",c)}function e(a){document.removeEventListener(\"mousemove\",a.movefn);document.removeEventListener(\"mouseup\",a.upfn);a.movefn=null;a.upfn=null}var f=Polymer.DomApi.wrap,g=\"string\"===typeof document.head.style.touchAction,k=[\"mousedown\",\"mousemove\",\"mouseup\",\"click\"],l=[0,1,4,2];try{var m=1===\n(new MouseEvent(\"test\",{buttons:1})).buttons}catch(v){m=!1}var n=!1;(function(){try{var a=Object.defineProperty({},\"passive\",{get:function(){n=!0}});window.addEventListener(\"test\",null,a);window.removeEventListener(\"test\",null,a)}catch(w){}})();var q=navigator.userAgent.match(/iP(?:[oa]d|hone)|Android/),p={mouse:{target:null,mouseIgnoreJob:null},touch:{x:0,y:0,id:-1,scrollDecided:!1}};document.addEventListener(\"touchend\",function(a){p.mouse.mouseIgnoreJob||b(!0);p.mouse.target=Polymer.dom(a).rootTarget;\np.mouse.mouseIgnoreJob=Polymer.Debounce(p.mouse.mouseIgnoreJob,function(){b();p.mouse.target=null;p.mouse.mouseIgnoreJob=null},2500)},n?{passive:!0}:!1);var t={gestures:{},recognizers:[],deepTargetFind:function(a,b){for(var c=document.elementFromPoint(a,b),d=c;d&&d.shadowRoot;)(d=d.shadowRoot.elementFromPoint(a,b))&&(c=d);return c},findOriginalTarget:function(a){return a.path?a.path[0]:a.target},handleNative:function(a){var b=a.type,c=f(a.currentTarget).__polymerGestures;if(c&&(c=c[b])){if(!a.__polymerGesturesHandled&&\n(a.__polymerGesturesHandled={},\"touch\"===b.slice(0,5))){var d=a.changedTouches[0];\"touchstart\"===b&&1===a.touches.length&&(p.touch.id=d.identifier);if(p.touch.id!==d.identifier)return;g||\"touchstart\"!==b&&\"touchmove\"!==b||t.handleTouchAction(a)}d=a.__polymerGesturesHandled;if(!d.skip){for(var e=t.recognizers,k=0,l;k<e.length;k++)l=e[k],c[l.name]&&!d[l.name]&&l.flow&&-1<l.flow.start.indexOf(a.type)&&l.reset&&l.reset();k=0;for(l;k<e.length;k++)l=e[k],c[l.name]&&!d[l.name]&&(d[l.name]=!0,l[b](a))}}},\nhandleTouchAction:function(a){var b=a.changedTouches[0],c=a.type;if(\"touchstart\"===c)p.touch.x=b.clientX,p.touch.y=b.clientY,p.touch.scrollDecided=!1;else if(\"touchmove\"===c&&!p.touch.scrollDecided){p.touch.scrollDecided=!0;for(var c=Polymer.dom(a).path,d=\"auto\",e=0,f;e<c.length;e++)if(f=c[e],f.__polymerGesturesTouchAction){d=f.__polymerGesturesTouchAction;break}c=d;d=!1;e=Math.abs(p.touch.x-b.clientX);b=Math.abs(p.touch.y-b.clientY);a.cancelable&&(\"none\"===c?d=!0:\"pan-x\"===c?d=b>e:\"pan-y\"===c&&(d=\ne>b));d?a.preventDefault():t.prevent(\"track\")}},add:function(a,b,c){a=f(a);var d=this.gestures[b],e=d.deps,g=d.name,l=a.__polymerGestures;l||(a.__polymerGestures=l={});for(var m=0,n,r;m<e.length;m++)n=e[m],q&&-1<k.indexOf(n)&&\"click\"!==n||((r=l[n])||(l[n]=r={_count:0}),0===r._count&&a.addEventListener(n,this.handleNative),r[g]=(r[g]||0)+1,r._count=(r._count||0)+1);a.addEventListener(b,c);d.touchAction&&this.setTouchAction(a,d.touchAction)},remove:function(a,b,c){a=f(a);var d=this.gestures[b],e=d.deps,\nd=d.name,g=a.__polymerGestures;if(g)for(var k=0,l,m;k<e.length;k++)l=e[k],(m=g[l])&&m[d]&&(m[d]=(m[d]||1)-1,m._count=(m._count||1)-1,0===m._count&&a.removeEventListener(l,this.handleNative));a.removeEventListener(b,c)},register:function(a){this.recognizers.push(a);for(var b=0;b<a.emits.length;b++)this.gestures[a.emits[b]]=a},findRecognizerByEvent:function(a){for(var b=0,c;b<this.recognizers.length;b++){c=this.recognizers[b];for(var d=0,e;d<c.emits.length;d++)if(e=c.emits[d],e===a)return c}return null},\nsetTouchAction:function(a,b){g&&(a.style.touchAction=b);a.__polymerGesturesTouchAction=b},fire:function(a,b,c){Polymer.Base.fire(b,c,{node:a,bubbles:!0,cancelable:!0}).defaultPrevented&&(a=c.preventer||c.sourceEvent)&&a.preventDefault&&a.preventDefault()},prevent:function(a){a=this.findRecognizerByEvent(a);a.info&&(a.info.prevent=!0)},resetMouseCanceller:function(){p.mouse.mouseIgnoreJob&&p.mouse.mouseIgnoreJob.complete()}};t.register({name:\"downup\",deps:[\"mousedown\",\"touchstart\",\"touchend\"],flow:{start:[\"mousedown\",\n\"touchstart\"],end:[\"mouseup\",\"touchend\"]},emits:[\"down\",\"up\"],info:{movefn:null,upfn:null},reset:function(){e(this.info)},mousedown:function(a){if(c(a)){var b=t.findOriginalTarget(a),f=this;d(this.info,function(a){c(a)||(f.fire(\"up\",b,a),e(f.info))},function(a){c(a)&&f.fire(\"up\",b,a);e(f.info)});this.fire(\"down\",b,a)}},touchstart:function(a){this.fire(\"down\",t.findOriginalTarget(a),a.changedTouches[0],a)},touchend:function(a){this.fire(\"up\",t.findOriginalTarget(a),a.changedTouches[0],a)},fire:function(a,\nb,c,d){t.fire(b,a,{x:c.clientX,y:c.clientY,sourceEvent:c,preventer:d,prevent:function(a){return t.prevent(a)}})}});t.register({name:\"track\",touchAction:\"none\",deps:[\"mousedown\",\"touchstart\",\"touchmove\",\"touchend\"],flow:{start:[\"mousedown\",\"touchstart\"],end:[\"mouseup\",\"touchend\"]},emits:[\"track\"],info:{x:0,y:0,state:\"start\",started:!1,moves:[],addMove:function(a){2<this.moves.length&&this.moves.shift();this.moves.push(a)},movefn:null,upfn:null,prevent:!1},reset:function(){this.info.state=\"start\";this.info.started=\n!1;this.info.moves=[];this.info.x=0;this.info.y=0;this.info.prevent=!1;e(this.info)},hasMovedEnough:function(a,b){if(this.info.prevent)return!1;if(this.info.started)return!0;b=Math.abs(this.info.y-b);return 5<=Math.abs(this.info.x-a)||5<=b},mousedown:function(a){if(c(a)){var b=t.findOriginalTarget(a),f=this,g=function(a){var d=a.clientX,g=a.clientY;f.hasMovedEnough(d,g)&&(f.info.state=f.info.started?\"mouseup\"===a.type?\"end\":\"track\":\"start\",\"start\"===f.info.state&&t.prevent(\"tap\"),f.info.addMove({x:d,\ny:g}),c(a)||(f.info.state=\"end\",e(f.info)),f.fire(b,a),f.info.started=!0)};d(this.info,g,function(a){f.info.started&&g(a);e(f.info)});this.info.x=a.clientX;this.info.y=a.clientY}},touchstart:function(a){a=a.changedTouches[0];this.info.x=a.clientX;this.info.y=a.clientY},touchmove:function(a){var b=t.findOriginalTarget(a);a=a.changedTouches[0];var c=a.clientX,d=a.clientY;this.hasMovedEnough(c,d)&&(\"start\"===this.info.state&&t.prevent(\"tap\"),this.info.addMove({x:c,y:d}),this.fire(b,a),this.info.state=\n\"track\",this.info.started=!0)},touchend:function(a){var b=t.findOriginalTarget(a),c=a.changedTouches[0];this.info.started&&(this.info.state=\"end\",this.info.addMove({x:c.clientX,y:c.clientY}),this.fire(b,c,a))},fire:function(a,b,c){var d=this.info.moves[this.info.moves.length-2],e=this.info.moves[this.info.moves.length-1],f=e.x-this.info.x,g=e.y-this.info.y,k=0;if(d){var l=e.x-d.x;k=e.y-d.y}return t.fire(a,\"track\",{state:this.info.state,x:b.clientX,y:b.clientY,dx:f,dy:g,ddx:l,ddy:k,sourceEvent:b,preventer:c,\nhover:function(){return t.deepTargetFind(b.clientX,b.clientY)}})}});t.register({name:\"tap\",deps:[\"mousedown\",\"click\",\"touchstart\",\"touchend\"],flow:{start:[\"mousedown\",\"touchstart\"],end:[\"click\",\"touchend\"]},emits:[\"tap\"],info:{x:NaN,y:NaN,prevent:!1},reset:function(){this.info.x=NaN;this.info.y=NaN;this.info.prevent=!1},save:function(a){this.info.x=a.clientX;this.info.y=a.clientY},mousedown:function(a){c(a)&&this.save(a)},click:function(a){c(a)&&this.forward(a)},touchstart:function(a){this.save(a.changedTouches[0],\na)},touchend:function(a){this.forward(a.changedTouches[0],a)},forward:function(a,b){var c=Math.abs(a.clientX-this.info.x),d=Math.abs(a.clientY-this.info.y),e=t.findOriginalTarget(a);if(!(c=isNaN(c)||isNaN(d)||25>=c&&25>=d))if(\"click\"===a.type)if(0===a.detail)c=!0;else var c=t.findOriginalTarget(a).getBoundingClientRect(),d=a.pageX,f=a.pageY,c=!(d>=c.left&&d<=c.right&&f>=c.top&&f<=c.bottom);else c=!1;c&&(this.info.prevent||t.fire(e,\"tap\",{x:a.clientX,y:a.clientY,sourceEvent:a,preventer:b}))}});var r=\n{x:\"pan-x\",y:\"pan-y\",none:\"none\",all:\"auto\"};Polymer.Base._addFeature({_setupGestures:function(){this.__polymerGestures=null},_listen:function(a,b,c){t.gestures[b]?t.add(a,b,c):a.addEventListener(b,c)},_unlisten:function(a,b,c){t.gestures[b]?t.remove(a,b,c):a.removeEventListener(b,c)},setScrollDirection:function(a,b){t.setTouchAction(b||this,r[a]||\"auto\")}});Polymer.Gestures=t})();\n(function(){Polymer.Base._addFeature({$$:function(a){return Polymer.dom(this.root).querySelector(a)},toggleClass:function(a,c,d){d=d||this;1==arguments.length&&(c=!d.classList.contains(a));c?Polymer.dom(d).classList.add(a):Polymer.dom(d).classList.remove(a)},toggleAttribute:function(a,c,d){d=d||this;1==arguments.length&&(c=!d.hasAttribute(a));c?Polymer.dom(d).setAttribute(a,\"\"):Polymer.dom(d).removeAttribute(a)},classFollows:function(a,c,d){d&&Polymer.dom(d).classList.remove(a);c&&Polymer.dom(c).classList.add(a)},\nattributeFollows:function(a,c,d){d&&Polymer.dom(d).removeAttribute(a);c&&Polymer.dom(c).setAttribute(a,\"\")},getEffectiveChildNodes:function(){return Polymer.dom(this).getEffectiveChildNodes()},getEffectiveChildren:function(){return Polymer.dom(this).getEffectiveChildNodes().filter(function(a){return a.nodeType===Node.ELEMENT_NODE})},getEffectiveTextContent:function(){for(var a=this.getEffectiveChildNodes(),c=[],d=0,e;e=a[d];d++)e.nodeType!==Node.COMMENT_NODE&&c.push(Polymer.dom(e).textContent);return c.join(\"\")},\nqueryEffectiveChildren:function(a){return(a=Polymer.dom(this).queryDistributedElements(a))&&a[0]},queryAllEffectiveChildren:function(a){return Polymer.dom(this).queryDistributedElements(a)},getContentChildNodes:function(a){return(a=Polymer.dom(this.root).querySelector(a||\"content\"))?Polymer.dom(a).getDistributedNodes():[]},getContentChildren:function(a){return this.getContentChildNodes(a).filter(function(a){return a.nodeType===Node.ELEMENT_NODE})},fire:function(a,c,d){d=d||Polymer.nob;var b=d.node||\nthis;c=null===c||void 0===c?{}:c;var f=d._useCache;d=this._getEvent(a,void 0===d.bubbles?!0:d.bubbles,!!d.cancelable,f);d.detail=c;f&&(this.__eventCache[a]=null);b.dispatchEvent(d);f&&(this.__eventCache[a]=d);return d},__eventCache:{},_getEvent:function(a,c,d,e){(e=e&&this.__eventCache[a])&&e.bubbles==c&&e.cancelable==d||(e=new Event(a,{bubbles:!!c,cancelable:d}));return e},async:function(a,c){var b=this;return Polymer.Async.run(function(){a.call(b)},c)},cancelAsync:function(a){Polymer.Async.cancel(a)},\narrayDelete:function(a,c){if(Array.isArray(a)){if(c=a.indexOf(c),0<=c)return a.splice(c,1)}else if(c=this._get(a).indexOf(c),0<=c)return this.splice(a,c,1)},transform:function(a,c){c=c||this;c.style.webkitTransform=a;c.style.transform=a},translate3d:function(a,c,d,e){this.transform(\"translate3d(\"+a+\",\"+c+\",\"+d+\")\",e||this)},importHref:function(a,c,d,e){function b(a){a.target.__firedError=!0;a.target.removeEventListener(\"load\",g);a.target.removeEventListener(\"error\",b);return d.call(n,a)}function g(a){a.target.__firedLoad=\n!0;a.target.removeEventListener(\"load\",g);a.target.removeEventListener(\"error\",b);return c.call(n,a)}var k=document.createElement(\"link\");k.rel=\"import\";k.href=a;a=Polymer.Base.importHref.imported=Polymer.Base.importHref.imported||{};var l=a[k.href],m=l||k,n=this;c&&m.addEventListener(\"load\",g);d&&m.addEventListener(\"error\",b);l?(l.__firedLoad&&l.dispatchEvent(new Event(\"load\")),l.__firedError&&l.dispatchEvent(new Event(\"error\"))):(a[k.href]=k,e&&k.setAttribute(\"async\",\"\"),document.head.appendChild(k));\nreturn m},create:function(a,c){a=document.createElement(a);if(c)for(var b in c)a[b]=c[b];return a},isLightDescendant:function(a){return this!==a&&this.contains(a)&&Polymer.dom(this).getOwnerRoot()===Polymer.dom(a).getOwnerRoot()},isLocalDescendant:function(a){return this.root===Polymer.dom(a).getOwnerRoot()}});if(!Polymer.Settings.useNativeCustomElements){var a=Polymer.Base.importHref;Polymer.Base.importHref=function(b,c,d,e){CustomElements.ready=!1;return a.call(this,b,function(a){CustomElements.upgradeDocumentTree(document);\nCustomElements.ready=!0;if(c)return c.call(this,a)},d,e)}}})();\nPolymer.Bind={prepareModel:function(a){Polymer.Base.mixin(a,this._modelApi)},_modelApi:{_notifyChange:function(a,b,c){c=void 0===c?this[a]:c;b=b||Polymer.CaseMap.camelToDashCase(a)+\"-changed\";this.fire(b,{value:c},{bubbles:!1,cancelable:!1,_useCache:Polymer.Settings.eventDataCache||!Polymer.Settings.isIE})},_propertySetter:function(a,b,c,d){var e=this.__data__[a];e===b||e!==e&&b!==b||(this.__data__[a]=b,\"object\"==typeof b&&this._clearPath(a),this._propertyChanged&&this._propertyChanged(a,b,e),c&&\nthis._effectEffects(a,b,c,e,d));return e},__setProperty:function(a,b,c,d){d=d||this;var e=d._propertyEffects&&d._propertyEffects[a];e?d._propertySetter(a,b,e,c):d[a]!==b&&(d[a]=b)},_effectEffects:function(a,b,c,d,e){b=0;for(var f=c.length,g;b<f&&(g=c[b]);b++)g.fn.call(this,a,this[a],g.effect,d,e)},_clearPath:function(a){for(var b in this.__data__)Polymer.Path.isDescendant(a,b)&&(this.__data__[b]=void 0)}},ensurePropertyEffects:function(a,b){a._propertyEffects||(a._propertyEffects={});var c=a._propertyEffects[b];\nc||(c=a._propertyEffects[b]=[]);return c},addPropertyEffect:function(a,b,c,d){a=this.ensurePropertyEffects(a,b);c={kind:c,effect:d,fn:Polymer.Bind[\"_\"+c+\"Effect\"]};a.push(c);return c},createBindings:function(a){var b=a._propertyEffects;if(b)for(var c in b){var d=b[c];d.sort(this._sortPropertyEffects);this._createAccessors(a,c,d)}},_sortPropertyEffects:function(){var a={compute:0,annotation:1,annotatedComputation:2,reflect:3,notify:4,observer:5,complexObserver:6,\"function\":7};return function(b,c){return a[b.kind]-\na[c.kind]}}(),_createAccessors:function(a,b,c){function d(a){this._propertySetter(b,a,c)}var e={get:function(){return this.__data__[b]}},f=a.getPropertyInfo&&a.getPropertyInfo(b);f&&f.readOnly?f.computed||(a[\"_set\"+this.upper(b)]=d):e.set=d;Object.defineProperty(a,b,e)},upper:function(a){return a[0].toUpperCase()+a.substring(1)},_addAnnotatedListener:function(a,b,c,d,e,f){a._bindListeners||(a._bindListeners=[]);f=this._notedListenerFactory(c,d,Polymer.Path.isDeep(d),f);e=e||Polymer.CaseMap.camelToDashCase(c)+\n\"-changed\";a._bindListeners.push({index:b,property:c,path:d,changedFn:f,event:e})},_isEventBogus:function(a,b){return a.path&&a.path[0]!==b},_notedListenerFactory:function(a,b,c,d){return function(e,f,g){g?(e=Polymer.Path.translate(a,b,g),this._notifyPath(e,f)):(f=e[a],d&&(f=!f),c?this.__data__[b]!=f&&this.set(b,f):this[b]=f)}},prepareInstance:function(a){a.__data__=Object.create(null)},setupBindListeners:function(a){for(var b=a._bindListeners,c=0,d=b.length,e;c<d&&(e=b[c]);c++)this._addNotifyListener(a._nodes[e.index],\na,e.event,e.changedFn)},_addNotifyListener:function(a,b,c,d){a.addEventListener(c,function(a){return b._notifyListener(d,a)})}};\nPolymer.Base.mixin(Polymer.Bind,{_shouldAddListener:function(a){return a.name&&\"attribute\"!=a.kind&&\"text\"!=a.kind&&!a.isCompound&&\"{\"===a.parts[0].mode},_annotationEffect:function(a,b,c){a!=c.value&&(b=this._get(c.value),this.__data__[c.value]=b);this._applyEffectValue(c,b)},_reflectEffect:function(a,b,c){this.reflectPropertyToAttribute(a,c.attribute,b)},_notifyEffect:function(a,b,c,d,e){e||this._notifyChange(a,c.event,b)},_functionEffect:function(a,b,c,d,e){c.call(this,a,b,d,e)},_observerEffect:function(a,\nb,c,d){(a=this[c.method])?a.call(this,b,d):this._warn(this._logf(\"_observerEffect\",\"observer method `\"+c.method+\"` not defined\"))},_complexObserverEffect:function(a,b,c){var d=this[c.method];d?(a=Polymer.Bind._marshalArgs(this.__data__,c,a,b))&&d.apply(this,a):c.dynamicFn||this._warn(this._logf(\"_complexObserverEffect\",\"observer method `\"+c.method+\"` not defined\"))},_computeEffect:function(a,b,c){var d=this[c.method];if(d){if(a=Polymer.Bind._marshalArgs(this.__data__,c,a,b))d=d.apply(this,a),this.__setProperty(c.name,\nd)}else c.dynamicFn||this._warn(this._logf(\"_computeEffect\",\"compute method `\"+c.method+\"` not defined\"))},_annotatedComputationEffect:function(a,b,c){var d=this._rootDataHost||this,e=d[c.method];if(e){if(a=Polymer.Bind._marshalArgs(this.__data__,c,a,b))d=e.apply(d,a),this._applyEffectValue(c,d)}else c.dynamicFn||d._warn(d._logf(\"_annotatedComputationEffect\",\"compute method `\"+c.method+\"` not defined\"))},_marshalArgs:function(a,b,c,d){var e=[],f=b.args;b=1<f.length||b.dynamicFn;for(var g=0,k=f.length;g<\nk;g++){var l=f[g],m=l.name;if(l.literal)var n=l.value;else c===m?n=d:(n=a[m],void 0===n&&l.structured&&(n=Polymer.Base._get(m,a)));if(b&&void 0===n)return;l.wildcard?(l=Polymer.Path.isAncestor(c,m),e[g]={path:l?c:m,value:l?d:n,base:n}):e[g]=n}return e}});\nPolymer.Base._addFeature({_addPropertyEffect:function(a,b,c){a=Polymer.Bind.addPropertyEffect(this,a,b,c);a.pathFn=this[\"_\"+a.kind+\"PathEffect\"]},_prepEffects:function(){Polymer.Bind.prepareModel(this);this._addAnnotationEffects(this._notes)},_prepBindings:function(){Polymer.Bind.createBindings(this)},_addPropertyEffects:function(a){if(a)for(var b in a){var c=a[b];c.observer&&this._addObserverEffect(b,c.observer);c.computed&&(c.readOnly=!0,this._addComputedEffect(b,c.computed));c.notify&&this._addPropertyEffect(b,\n\"notify\",{event:Polymer.CaseMap.camelToDashCase(b)+\"-changed\"});if(c.reflectToAttribute){var d=Polymer.CaseMap.camelToDashCase(b);\"-\"===d[0]?this._warn(this._logf(\"_addPropertyEffects\",\"Property \"+b+\" cannot be reflected to attribute \"+d+' because \"-\" is not a valid starting attribute name. Use a lowercase first letter for the property instead.')):this._addPropertyEffect(b,\"reflect\",{attribute:d})}c.readOnly&&Polymer.Bind.ensurePropertyEffects(this,b)}},_addComputedEffect:function(a,b){b=this._parseMethod(b);\nfor(var c=b.dynamicFn,d=0,e;d<b.args.length&&(e=b.args[d]);d++)this._addPropertyEffect(e.model,\"compute\",{method:b.method,args:b.args,trigger:e,name:a,dynamicFn:c});c&&this._addPropertyEffect(b.method,\"compute\",{method:b.method,args:b.args,trigger:null,name:a,dynamicFn:c})},_addObserverEffect:function(a,b){this._addPropertyEffect(a,\"observer\",{method:b,property:a})},_addComplexObserverEffects:function(a){if(a)for(var b=0,c;b<a.length&&(c=a[b]);b++)this._addComplexObserverEffect(c)},_addComplexObserverEffect:function(a){var b=\nthis._parseMethod(a);if(!b)throw Error(\"Malformed observer expression '\"+a+\"'\");a=b.dynamicFn;for(var c=0,d;c<b.args.length&&(d=b.args[c]);c++)this._addPropertyEffect(d.model,\"complexObserver\",{method:b.method,args:b.args,trigger:d,dynamicFn:a});a&&this._addPropertyEffect(b.method,\"complexObserver\",{method:b.method,args:b.args,trigger:null,dynamicFn:a})},_addAnnotationEffects:function(a){for(var b=0,c;b<a.length&&(c=a[b]);b++)for(var d=c.bindings,e=0,f;e<d.length&&(f=d[e]);e++)this._addAnnotationEffect(f,\nb)},_addAnnotationEffect:function(a,b){Polymer.Bind._shouldAddListener(a)&&Polymer.Bind._addAnnotatedListener(this,b,a.name,a.parts[0].value,a.parts[0].event,a.parts[0].negate);for(var c=0;c<a.parts.length;c++){var d=a.parts[c];d.signature?this._addAnnotatedComputationEffect(a,d,b):d.literal||(\"attribute\"===a.kind&&\"-\"===a.name[0]?this._warn(this._logf(\"_addAnnotationEffect\",\"Cannot set attribute \"+a.name+' because \"-\" is not a valid attribute starting character')):this._addPropertyEffect(d.model,\n\"annotation\",{kind:a.kind,index:b,name:a.name,propertyName:a.propertyName,value:d.value,isCompound:a.isCompound,compoundIndex:d.compoundIndex,event:d.event,customEvent:d.customEvent,negate:d.negate}))}},_addAnnotatedComputationEffect:function(a,b,c){var d=b.signature;if(d.static)this.__addAnnotatedComputationEffect(\"__static__\",c,a,b,null);else{for(var e=0,f;e<d.args.length&&(f=d.args[e]);e++)f.literal||this.__addAnnotatedComputationEffect(f.model,c,a,b,f);d.dynamicFn&&this.__addAnnotatedComputationEffect(d.method,\nc,a,b,null)}},__addAnnotatedComputationEffect:function(a,b,c,d,e){this._addPropertyEffect(a,\"annotatedComputation\",{index:b,isCompound:c.isCompound,compoundIndex:d.compoundIndex,kind:c.kind,name:c.name,negate:d.negate,method:d.signature.method,args:d.signature.args,trigger:e,dynamicFn:d.signature.dynamicFn})},_parseMethod:function(a){var b=a.match(/([^\\s]+?)\\(([\\s\\S]*)\\)/);if(b){a={method:b[1],static:!0};this.getPropertyInfo(a.method)!==Polymer.nob&&(a.static=!1,a.dynamicFn=!0);if(b[2].trim())return b=\nb[2].replace(/\\\\,/g,\"\\x26comma;\").split(\",\"),this._parseArgs(b,a);a.args=Polymer.nar;return a}},_parseArgs:function(a,b){b.args=a.map(function(a){a=this._parseArg(a);a.literal||(b.static=!1);return a},this);return b},_parseArg:function(a){a=a.trim().replace(/&comma;/g,\",\").replace(/\\\\(.)/g,\"$1\");var b={name:a},c=a[0];\"-\"===c&&(c=a[1]);\"0\"<=c&&\"9\">=c&&(c=\"#\");switch(c){case \"'\":case '\"':b.value=a.slice(1,-1);b.literal=!0;break;case \"#\":b.value=Number(a),b.literal=!0}b.literal||(b.model=Polymer.Path.root(a),\nb.structured=Polymer.Path.isDeep(a),b.structured&&(b.wildcard=\".*\"==a.slice(-2),b.wildcard&&(b.name=a.slice(0,-2))));return b},_marshalInstanceEffects:function(){Polymer.Bind.prepareInstance(this);this._bindListeners&&Polymer.Bind.setupBindListeners(this)},_applyEffectValue:function(a,b){var c=this._nodes[a.index],d=a.name;b=this._computeFinalAnnotationValue(c,d,b,a);\"attribute\"==a.kind?this.serializeValueToAttribute(b,d,c):(a=c._propertyInfo&&c._propertyInfo[d])&&a.readOnly||this.__setProperty(d,\nb,Polymer.Settings.suppressBindingNotifications,c)},_computeFinalAnnotationValue:function(a,b,c,d){d.negate&&(c=!c);if(d.isCompound){var e=a.__compoundStorage__[b];e[d.compoundIndex]=c;c=e.join(\"\")}\"attribute\"!==d.kind&&(\"className\"===b&&(c=this._scopeElementClass(a,c)),\"textContent\"===b||\"input\"==a.localName&&\"value\"==b)&&(c=void 0==c?\"\":c);return c},_executeStaticEffects:function(){this._propertyEffects&&this._propertyEffects.__static__&&this._effectEffects(\"__static__\",null,this._propertyEffects.__static__)}});\n(function(){var a=Polymer.Settings.usePolyfillProto,b=!!Object.getOwnPropertyDescriptor(document.documentElement,\"properties\");Polymer.Base._addFeature({_setupConfigure:function(a){this._config={};this._handlers=[];this._aboveConfig=null;if(a)for(var b in a)void 0!==a[b]&&(this._config[b]=a[b])},_marshalAttributes:function(){this._takeAttributesToModel(this._config)},_attributeChangedImpl:function(a){this._setAttributeToProperty(this._clientsReadied?this:this._config,a)},_configValue:function(a,b){var c=\nthis._propertyInfo[a];c&&c.readOnly||(this._config[a]=b)},_beforeClientsReady:function(){this._configure()},_configure:function(){this._configureAnnotationReferences();this._configureInstanceProperties();this._aboveConfig=this.mixin({},this._config);for(var a={},d=0;d<this.behaviors.length;d++)this._configureProperties(this.behaviors[d].properties,a);this._configureProperties(b?this.__proto__.properties:this.properties,a);this.mixin(a,this._aboveConfig);this._config=a;this._clients&&this._clients.length&&\nthis._distributeConfig(this._config)},_configureInstanceProperties:function(){for(var b in this._propertyEffects)!a&&this.hasOwnProperty(b)&&(this._configValue(b,this[b]),delete this[b])},_configureProperties:function(a,b){for(var c in a){var d=a[c];void 0!==d.value&&(d=d.value,\"function\"==typeof d&&(d=d.call(this,this._config)),b[c]=d)}},_distributeConfig:function(a){var b=this._propertyEffects;if(b)for(var c in a){var f=b[c];if(f)for(var g=0,k=f.length,l;g<k&&(l=f[g]);g++)if(\"annotation\"===l.kind){var m=\nthis._nodes[l.effect.index],n=l.effect.propertyName,q=\"attribute\"==l.effect.kind,p=m._propertyEffects&&m._propertyEffects[n];!m._configValue||!p&&q||(p=c===l.effect.value?a[c]:this._get(l.effect.value,a),p=this._computeFinalAnnotationValue(m,n,p,l.effect),q&&(p=m.deserialize(this.serialize(p),m._propertyInfo[n].type)),m._configValue(n,p))}}},_afterClientsReady:function(){this._executeStaticEffects();this._applyConfig(this._config,this._aboveConfig);this._flushHandlers()},_applyConfig:function(a,b){for(var c in a)void 0===\nthis[c]&&this.__setProperty(c,a[c],c in b)},_notifyListener:function(a,b){if(!Polymer.Bind._isEventBogus(b,b.target)){if(b.detail){var c=b.detail.value;var d=b.detail.path}if(this._clientsReadied)return a.call(this,b.target,c,d);this._queueHandler([a,b.target,c,d])}},_queueHandler:function(a){this._handlers.push(a)},_flushHandlers:function(){for(var a=this._handlers,b=0,e=a.length,f;b<e&&(f=a[b]);b++)f[0].call(this,f[1],f[2],f[3]);this._handlers=[]}})})();\n(function(){var a=Polymer.Path;Polymer.Base._addFeature({notifyPath:function(a,c,d){var b={},f=this._get(a,this,b);1===arguments.length&&(c=f);b.path&&this._notifyPath(b.path,c,d)},_notifyPath:function(a,c,d){var b=this._propertySetter(a,c);if(b!==c&&(b===b||c===c))return this._pathEffector(a,c),d||this._notifyPathUp(a,c),!0},_getPathParts:function(a){if(Array.isArray(a)){for(var b=[],d=0;d<a.length;d++)for(var e=a[d].toString().split(\".\"),f=0;f<e.length;f++)b.push(e[f]);return b}return a.toString().split(\".\")},\nset:function(a,c,d){var b=d||this,f=this._getPathParts(a),g=f[f.length-1];if(1<f.length){for(a=0;a<f.length-1;a++){var k=f[a];l&&\"#\"==k[0]?b=Polymer.Collection.get(l).getItem(k):(b=b[k],l&&parseInt(k,10)==k&&(f[a]=Polymer.Collection.get(l).getKey(b)));if(!b)return;var l=Array.isArray(b)?b:null}if(l){var k=Polymer.Collection.get(l);if(\"#\"==g[0]){var m=g;var n=k.getItem(m);g=l.indexOf(n);k.setItem(m,c)}else parseInt(g,10)==g&&(n=b[g],m=k.getKey(n),f[a]=m,k.setItem(m,c))}b[g]=c;d||this._notifyPath(f.join(\".\"),\nc)}else b[a]=c},get:function(a,c){return this._get(a,c)},_get:function(a,c,d){c=c||this;a=this._getPathParts(a);for(var b,f=0;f<a.length;f++){if(!c)return;var g=a[f];b&&\"#\"==g[0]?c=Polymer.Collection.get(b).getItem(g):(c=c[g],d&&b&&parseInt(g,10)==g&&(a[f]=Polymer.Collection.get(b).getKey(c)));b=Array.isArray(c)?c:null}d&&(d.path=a.join(\".\"));return c},_pathEffector:function(b,c){var d=a.root(b);if(d=this._propertyEffects&&this._propertyEffects[d])for(var e=0,f;e<d.length&&(f=d[e]);e++){var g=f.pathFn;\ng&&g.call(this,b,c,f.effect)}this._boundPaths&&this._notifyBoundPaths(b,c)},_annotationPathEffect:function(b,c,d){if(a.matches(d.value,!1,b))Polymer.Bind._annotationEffect.call(this,b,c,d);else if(!d.negate&&a.isDescendant(d.value,b)){var e=this._nodes[d.index];e&&e._notifyPath&&(b=a.translate(d.value,d.name,b),e._notifyPath(b,c,!0))}},_complexObserverPathEffect:function(b,c,d){a.matches(d.trigger.name,d.trigger.wildcard,b)&&Polymer.Bind._complexObserverEffect.call(this,b,c,d)},_computePathEffect:function(b,\nc,d){a.matches(d.trigger.name,d.trigger.wildcard,b)&&Polymer.Bind._computeEffect.call(this,b,c,d)},_annotatedComputationPathEffect:function(b,c,d){a.matches(d.trigger.name,d.trigger.wildcard,b)&&Polymer.Bind._annotatedComputationEffect.call(this,b,c,d)},linkPaths:function(a,c){this._boundPaths=this._boundPaths||{};c?this._boundPaths[a]=c:this.unlinkPaths(a)},unlinkPaths:function(a){this._boundPaths&&delete this._boundPaths[a]},_notifyBoundPaths:function(b,c){for(var d in this._boundPaths){var e=this._boundPaths[d];\na.isDescendant(d,b)?this._notifyPath(a.translate(d,e,b),c):a.isDescendant(e,b)&&this._notifyPath(a.translate(e,d,b),c)}},_notifyPathUp:function(b,c){var d=a.root(b),d=Polymer.CaseMap.camelToDashCase(d)+this._EVENT_CHANGED;this.fire(d,{path:b,value:c},{bubbles:!1,_useCache:Polymer.Settings.eventDataCache||!Polymer.Settings.isIE})},_EVENT_CHANGED:\"-changed\",notifySplices:function(a,c){var b={};a=this._get(a,this,b);this._notifySplices(a,b.path,c)},_notifySplices:function(a,c,d){d={keySplices:Polymer.Collection.applySplices(a,\nd),indexSplices:d};var b=c+\".splices\";this._notifyPath(b,d);this._notifyPath(c+\".length\",a.length);this.__data__[b]={keySplices:null,indexSplices:null}},_notifySplice:function(a,c,d,e,f){this._notifySplices(a,c,[{index:d,addedCount:e,removed:f,object:a,type:\"splice\"}])},push:function(a){var b={},d=this._get(a,this,b),e=Array.prototype.slice.call(arguments,1),f=d.length,g=d.push.apply(d,e);e.length&&this._notifySplice(d,b.path,f,e.length,[]);return g},pop:function(a){var b={},d=this._get(a,this,b),\ne=!!d.length,f=d.pop.apply(d,Array.prototype.slice.call(arguments,1));e&&this._notifySplice(d,b.path,d.length,0,[f]);return f},splice:function(a,c){var b={},e=this._get(a,this,b);(c=0>c?e.length-Math.floor(-c):Math.floor(c))||(c=0);var f=Array.prototype.slice.call(arguments,1),g=e.splice.apply(e,f);((f=Math.max(f.length-2,0))||g.length)&&this._notifySplice(e,b.path,c,f,g);return g},shift:function(a){var b={},d=this._get(a,this,b),e=!!d.length,f=d.shift.apply(d,Array.prototype.slice.call(arguments,\n1));e&&this._notifySplice(d,b.path,0,0,[f]);return f},unshift:function(a){var b={},d=this._get(a,this,b),e=Array.prototype.slice.call(arguments,1),f=d.unshift.apply(d,e);e.length&&this._notifySplice(d,b.path,0,e.length,[]);return f},prepareModelNotifyPath:function(a){this.mixin(a,{fire:Polymer.Base.fire,_getEvent:Polymer.Base._getEvent,__eventCache:Polymer.Base.__eventCache,notifyPath:Polymer.Base.notifyPath,_get:Polymer.Base._get,_EVENT_CHANGED:Polymer.Base._EVENT_CHANGED,_notifyPath:Polymer.Base._notifyPath,\n_notifyPathUp:Polymer.Base._notifyPathUp,_pathEffector:Polymer.Base._pathEffector,_annotationPathEffect:Polymer.Base._annotationPathEffect,_complexObserverPathEffect:Polymer.Base._complexObserverPathEffect,_annotatedComputationPathEffect:Polymer.Base._annotatedComputationPathEffect,_computePathEffect:Polymer.Base._computePathEffect,_notifyBoundPaths:Polymer.Base._notifyBoundPaths,_getPathParts:Polymer.Base._getPathParts})}})})();\nPolymer.Base._addFeature({resolveUrl:function(a){var b=Polymer.DomModule.import(this.is),c=\"\";b&&(c=b.getAttribute(\"assetpath\")||\"\",c=Polymer.ResolveUrl.resolveUrl(c,b.ownerDocument.baseURI));return Polymer.ResolveUrl.resolveUrl(a,c)}});\nPolymer.CssParse={parse:function(a){a=this._clean(a);return this._parseCss(this._lex(a),a)},_clean:function(a){return a.replace(this._rx.comments,\"\").replace(this._rx.port,\"\")},_lex:function(a){for(var b={start:0,end:a.length},c=b,d=0,e=a.length;d<e;d++)switch(a[d]){case this.OPEN_BRACE:c.rules||(c.rules=[]);var f=c,c={start:d+1,parent:f,previous:f.rules[f.rules.length-1]};f.rules.push(c);break;case this.CLOSE_BRACE:c.end=d+1,c=c.parent||b}return b},_parseCss:function(a,b){var c=b.substring(a.start,\na.end-1);a.parsedCssText=a.cssText=c.trim();a.parent&&(c=b.substring(a.previous?a.previous.end:a.parent.start,a.start-1),c=this._expandUnicodeEscapes(c),c=c.replace(this._rx.multipleSpaces,\" \"),c=c.substring(c.lastIndexOf(\";\")+1),c=a.parsedSelector=a.selector=c.trim(),a.atRule=0===c.indexOf(this.AT_START),a.atRule?0===c.indexOf(this.MEDIA_START)?a.type=this.types.MEDIA_RULE:c.match(this._rx.keyframesRule)&&(a.type=this.types.KEYFRAMES_RULE,a.keyframesName=a.selector.split(this._rx.multipleSpaces).pop()):\na.type=0===c.indexOf(this.VAR_START)?this.types.MIXIN_RULE:this.types.STYLE_RULE);if(c=a.rules)for(var d=0,e=c.length,f;d<e&&(f=c[d]);d++)this._parseCss(f,b);return a},_expandUnicodeEscapes:function(a){return a.replace(/\\\\([0-9a-f]{1,6})\\s/gi,function(a,c){a=c;for(c=6-a.length;c--;)a=\"0\"+a;return\"\\\\\"+a})},stringify:function(a,b,c){c=c||\"\";var d=\"\";if(a.cssText||a.rules){var e=a.rules;if(e&&!this._hasMixinRules(e))for(var f=0,g=e.length,k;f<g&&(k=e[f]);f++)d=this.stringify(k,b,d);else d=b?a.cssText:\nthis.removeCustomProps(a.cssText),(d=d.trim())&&(d=\"  \"+d+\"\\n\")}d&&(a.selector&&(c+=a.selector+\" \"+this.OPEN_BRACE+\"\\n\"),c+=d,a.selector&&(c+=this.CLOSE_BRACE+\"\\n\\n\"));return c},_hasMixinRules:function(a){return 0===a[0].selector.indexOf(this.VAR_START)},removeCustomProps:function(a){a=this.removeCustomPropAssignment(a);return this.removeCustomPropApply(a)},removeCustomPropAssignment:function(a){return a.replace(this._rx.customProp,\"\").replace(this._rx.mixinProp,\"\")},removeCustomPropApply:function(a){return a.replace(this._rx.mixinApply,\n\"\").replace(this._rx.varApply,\"\")},types:{STYLE_RULE:1,KEYFRAMES_RULE:7,MEDIA_RULE:4,MIXIN_RULE:1E3},OPEN_BRACE:\"{\",CLOSE_BRACE:\"}\",_rx:{comments:/\\/\\*[^*]*\\*+([^\\/*][^*]*\\*+)*\\//gim,port:/@import[^;]*;/gim,customProp:/(?:^[^;\\-\\s}]+)?--[^;{}]*?:[^{};]*?(?:[;\\n]|$)/gim,mixinProp:/(?:^[^;\\-\\s}]+)?--[^;{}]*?:[^{};]*?{[^}]*?}(?:[;\\n]|$)?/gim,mixinApply:/@apply\\s*\\(?[^);]*\\)?\\s*(?:[;\\n]|$)?/gim,varApply:/[^;:]*?:[^;]*?var\\([^;]*\\)(?:[;\\n]|$)?/gim,keyframesRule:/^@[^\\s]*keyframes/,multipleSpaces:/\\s+/g},\nVAR_START:\"--\",MEDIA_START:\"@media\",AT_START:\"@\"};\nPolymer.StyleUtil=function(){var a=Polymer.Settings;return{NATIVE_VARIABLES:Polymer.Settings.useNativeCSSProperties,MODULE_STYLES_SELECTOR:\"style, link[rel\\x3dimport][type~\\x3dcss], template\",INCLUDE_ATTR:\"include\",toCssText:function(a,c){\"string\"===typeof a&&(a=this.parser.parse(a));c&&this.forEachRule(a,c);return this.parser.stringify(a,this.NATIVE_VARIABLES)},forRulesInStyles:function(a,c,d){if(a)for(var b=0,f=a.length,g;b<f&&(g=a[b]);b++)this.forEachRuleInStyle(g,c,d)},forActiveRulesInStyles:function(a,\nc,d){if(a)for(var b=0,f=a.length,g;b<f&&(g=a[b]);b++)this.forEachRuleInStyle(g,c,d,!0)},rulesForStyle:function(a){!a.__cssRules&&a.textContent&&(a.__cssRules=this.parser.parse(a.textContent));return a.__cssRules},isKeyframesSelector:function(a){return a.parent&&a.parent.type===this.ruleTypes.KEYFRAMES_RULE},forEachRuleInStyle:function(a,c,d,e){var b=this.rulesForStyle(a),g,k;c&&(g=function(b){c(b,a)});d&&(k=function(b){d(b,a)});this.forEachRule(b,g,k,e)},forEachRule:function(a,c,d,e){if(a){var b=\n!1;if(e&&a.type===this.ruleTypes.MEDIA_RULE){var g=a.selector.match(this.rx.MEDIA_MATCH);g&&(window.matchMedia(g[1]).matches||(b=!0))}a.type===this.ruleTypes.STYLE_RULE?c(a):d&&a.type===this.ruleTypes.KEYFRAMES_RULE?d(a):a.type===this.ruleTypes.MIXIN_RULE&&(b=!0);if((a=a.rules)&&!b)for(var b=0,g=a.length,k;b<g&&(k=a[b]);b++)this.forEachRule(k,c,d,e)}},applyCss:function(a,c,d,e){a=this.createScopeStyle(a,c);return this.applyStyle(a,d,e)},applyStyle:function(a,c,d){c=c||document.head;d=d&&d.nextSibling||\nc.firstChild;this.__lastHeadApplyNode=a;return c.insertBefore(a,d)},createScopeStyle:function(a,c){var b=document.createElement(\"style\");c&&b.setAttribute(\"scope\",c);b.textContent=a;return b},__lastHeadApplyNode:null,applyStylePlaceHolder:function(a){a=document.createComment(\" Shady DOM styles for \"+a+\" \");var b=document.head;b.insertBefore(a,(this.__lastHeadApplyNode?this.__lastHeadApplyNode.nextSibling:null)||b.firstChild);return this.__lastHeadApplyNode=a},cssFromModules:function(a,c){a=a.trim().split(\" \");\nfor(var b=\"\",e=0;e<a.length;e++)b+=this.cssFromModule(a[e],c);return b},cssFromModule:function(a,c){var b=Polymer.DomModule.import(a);b&&!b._cssText&&(b._cssText=this.cssFromElement(b));!b&&c&&console.warn(\"Could not find style data in module named\",a);return b&&b._cssText||\"\"},cssFromElement:function(a){for(var b=\"\",d=Polymer.TreeApi.arrayCopy((a.content||a).querySelectorAll(this.MODULE_STYLES_SELECTOR)),e=0,f;e<d.length;e++)if(f=d[e],\"template\"===f.localName)f.hasAttribute(\"preserve-content\")||\n(b+=this.cssFromElement(f));else if(\"style\"===f.localName){var g=f.getAttribute(this.INCLUDE_ATTR);g&&(b+=this.cssFromModules(g,!0));f=f.__appliedElement||f;f.parentNode.removeChild(f);b+=this.resolveCss(f.textContent,a.ownerDocument)}else f.import&&f.import.body&&(b+=this.resolveCss(f.import.body.textContent,f.import));return b},styleIncludesToTemplate:function(a){a=a.content.querySelectorAll(\"style[include]\");for(var b=0,d;b<a.length;b++)d=a[b],d.parentNode.insertBefore(this._includesToFragment(d.getAttribute(\"include\")),\nd)},_includesToFragment:function(a){a=a.trim().split(\" \");for(var b=document.createDocumentFragment(),d=0;d<a.length;d++){var e=Polymer.DomModule.import(a[d],\"template\");e&&this._addStylesToFragment(b,e.content)}return b},_addStylesToFragment:function(a,c){c=c.querySelectorAll(\"style\");for(var b=0,e;b<c.length;b++){e=c[b];var f=e.getAttribute(\"include\");f&&a.appendChild(this._includesToFragment(f));e.textContent&&a.appendChild(e.cloneNode(!0))}},isTargetedBuild:function(b){return a.useNativeShadow?\n\"shadow\"===b:\"shady\"===b},cssBuildTypeForModule:function(a){if(a=Polymer.DomModule.import(a))return this.getCssBuildType(a)},getCssBuildType:function(a){return a.getAttribute(\"css-build\")},_findMatchingParen:function(a,c){for(var b=0,e=a.length;c<e;c++)switch(a[c]){case \"(\":b++;break;case \")\":if(0===--b)return c}return-1},processVariableAndFallback:function(a,c){var b=a.indexOf(\"var(\");if(-1===b)return c(a,\"\",\"\",\"\");var e=this._findMatchingParen(a,b+3),f=a.substring(b+4,e),b=a.substring(0,b);a=this.processVariableAndFallback(a.substring(e+\n1),c);var g=f.indexOf(\",\");if(-1===g)return c(b,f.trim(),\"\",a);e=f.substring(0,g).trim();f=f.substring(g+1).trim();return c(b,e,f,a)},rx:{VAR_ASSIGN:/(?:^|[;\\s{]\\s*)(--[\\w-]*?)\\s*:\\s*(?:([^;{]*)|{([^}]*)})(?:(?=[;\\s}])|$)/gi,MIXIN_MATCH:/(?:^|\\W+)@apply\\s*\\(?([^);\\n]*)\\)?/gi,VAR_CONSUMED:/(--[\\w-]+)\\s*([:,;)]|$)/gi,ANIMATION_MATCH:/(animation\\s*:)|(animation-name\\s*:)/,MEDIA_MATCH:/@media[^(]*(\\([^)]*\\))/,IS_VAR:/^--/,BRACKETED:/\\{[^}]*\\}/g,HOST_PREFIX:\"(?:^|[^.#[:])\",HOST_SUFFIX:\"($|[.:[\\\\s\\x3e+~])\"},\nresolveCss:Polymer.ResolveUrl.resolveCss,parser:Polymer.CssParse,ruleTypes:Polymer.CssParse.types}}();\nPolymer.StyleTransformer=function(){var a=Polymer.StyleUtil,b=Polymer.Settings,c={dom:function(a,b,c,d){this._transformDom(a,b||\"\",c,d)},_transformDom:function(a,b,c,d){a.setAttribute&&this.element(a,b,c,d);a=Polymer.dom(a).childNodes;for(var e=0;e<a.length;e++)this._transformDom(a[e],b,c,d)},element:function(a,b,c,e){c?e?a.removeAttribute(d):a.setAttribute(d,b):b&&(a.classList?e?(a.classList.remove(d),a.classList.remove(b)):(a.classList.add(d),a.classList.add(b)):a.getAttribute&&(c=a.getAttribute(B),\ne?c&&a.setAttribute(B,c.replace(d,\"\").replace(b,\"\")):a.setAttribute(B,(c?c+\" \":\"\")+d+\" \"+b)))},elementStyles:function(c,d){var e=c._styles,f=\"\",g=c.__cssBuild,g=b.useNativeShadow||\"shady\"===g;if(g){var k=this;var l=function(a){a.selector=k._slottedToContent(a.selector);a.selector=a.selector.replace(m,\":host \\x3e *\");d&&d(a)}}for(var n=0,q=e.length,r;n<q&&(r=e[n]);n++)var p=a.rulesForStyle(r),f=f+(g?a.toCssText(p,l):this.css(p,c.is,c.extends,d,c._scopeCssViaAttr)+\"\\n\\n\");return f.trim()},css:function(b,\nc,d,e,f){var g=this._calcHostScope(c,d);c=this._calcElementScope(c,f);var k=this;return a.toCssText(b,function(a){a.isScoped||(k.rule(a,c,g),a.isScoped=!0);e&&e(a,c,g)})},_calcElementScope:function(a,b){return a?b?w+a+z:v+a:\"\"},_calcHostScope:function(a,b){return b?\"[is\\x3d\"+a+\"]\":a},rule:function(a,b,c){this._transformRule(a,this._transformComplexSelector,b,c)},_transformRule:function(a,b,c,d){a.selector=a.transformedSelector=this._transformRuleCss(a,b,c,d)},_transformRuleCss:function(b,c,d,e){var g=\nb.selector.split(f);if(!a.isKeyframesSelector(b)){b=0;for(var k=g.length,l;b<k&&(l=g[b]);b++)g[b]=c.call(this,l,d,e)}return g.join(f)},_transformComplexSelector:function(a,b,c){var d=!1,e=!1,k=this;a=a.trim();a=this._slottedToContent(a);a=a.replace(m,\":host \\x3e *\");a=a.replace(A,l+\" $1\");a=a.replace(g,function(a,f,g){d?g=g.replace(r,\" \"):(a=k._transformCompoundSelector(g,f,b,c),d=d||a.stop,e=e||a.hostContext,f=a.combinator,g=a.value);return f+g});e&&(a=a.replace(p,function(a,b,d,e){return b+d+\" \"+\nc+e+f+\" \"+b+c+d+e}));return a},_transformCompoundSelector:function(a,b,c,d){var e=a.search(r),f=!1;0<=a.indexOf(q)?f=!0:0<=a.indexOf(l)?a=this._transformHostSelector(a,d):0!==e&&(a=c?this._transformSimpleSelector(a,c):a);0<=a.indexOf(t)&&(b=\"\");if(0<=e){a=a.replace(r,\" \");var g=!0}return{value:a,combinator:b,stop:g,hostContext:f}},_transformSimpleSelector:function(a,b){a=a.split(y);a[0]+=b;return a.join(y)},_transformHostSelector:function(a,b){var c=a.match(n);return(c=c&&c[2].trim()||\"\")?c[0].match(k)?\na.replace(n,function(a,c,d){return b+d}):c.split(k)[0]===b?c:D:a.replace(l,b)},documentRule:function(a){a.selector=a.parsedSelector;this.normalizeRootSelector(a);b.useNativeShadow||this._transformRule(a,this._transformDocumentSelector)},normalizeRootSelector:function(a){a.selector=a.selector.replace(m,\"html\")},_transformDocumentSelector:function(a){return a.match(r)?this._transformComplexSelector(a,e):this._transformSimpleSelector(a.trim(),e)},_slottedToContent:function(a){return a.replace(E,t+\"\\x3e $1\")},\nSCOPE_NAME:\"style-scope\"},d=c.SCOPE_NAME,e=\":not([\"+d+\"]):not(.\"+d+\")\",f=\",\",g=/(^|[\\s>+~]+)((?:\\[.+?\\]|[^\\s>+~=\\[])+)/g,k=/[[.:#*]/,l=\":host\",m=\":root\",n=/(:host)(?:\\(((?:\\([^)(]*\\)|[^)(]*)+?)\\))/,q=\":host-context\",p=/(.*)(?::host-context)(?:\\(((?:\\([^)(]*\\)|[^)(]*)+?)\\))(.*)/,t=\"::content\",r=/::content|::shadow|\\/deep\\//,v=\".\",w=\"[\"+d+\"~\\x3d\",z=\"]\",y=\":\",B=\"class\",A=new RegExp(\"^(\"+t+\")\"),D=\"should_not_match\",E=/(?:::slotted)(?:\\(((?:\\([^)(]*\\)|[^)(]*)+?)\\))/g;return c}();\nPolymer.StyleExtends=function(){var a=Polymer.StyleUtil;return{hasExtends:function(a){return!!a.match(this.rx.EXTEND)},transform:function(b){b=a.rulesForStyle(b);var c=this;a.forEachRule(b,function(a){c._mapRuleOntoParent(a);if(a.parent)for(var b;b=c.rx.EXTEND.exec(a.cssText);)(b=c._findExtendor(b[1],a))&&c._extendRule(a,b);a.cssText=a.cssText.replace(c.rx.EXTEND,\"\")});return a.toCssText(b,function(a){a.selector.match(c.rx.STRIP)&&(a.cssText=\"\")},!0)},_mapRuleOntoParent:function(a){if(a.parent){for(var b=\na.parent.map||(a.parent.map={}),d=a.selector.split(\",\"),e=0,f;e<d.length;e++)f=d[e],b[f.trim()]=a;return b}},_findExtendor:function(a,c){return c.parent&&c.parent.map&&c.parent.map[a]||this._findExtendor(a,c.parent)},_extendRule:function(a,c){a.parent!==c.parent&&this._cloneAndAddRuleToParent(c,a.parent);a.extends=a.extends||[];a.extends.push(c);c.selector=c.selector.replace(this.rx.STRIP,\"\");c.selector=(c.selector&&c.selector+\",\\n\")+a.selector;c.extends&&c.extends.forEach(function(b){this._extendRule(a,\nb)},this)},_cloneAndAddRuleToParent:function(a,c){a=Object.create(a);a.parent=c;a.extends&&(a.extends=a.extends.slice());c.rules.push(a)},rx:{EXTEND:/@extends\\(([^)]*)\\)\\s*?;/gim,STRIP:/%[^,]*$/}}}();\nPolymer.ApplyShim=function(){function a(a,b){a=a.trim();t[a]={properties:b,dependants:{}}}function b(a){a=a.trim();return t[a]}function c(a){a=a.split(\";\");for(var b,c,d={},e=0,f;e<a.length;e++)if(b=a[e])if(f=b.split(\":\"),1<f.length){c=b=f[0].trim();f=f.slice(1).join(\":\");var g=p.exec(f);g&&(f=g[1]?r._getInitialValueForProperty(c):\"apply-shim-inherit\");c=f;d[b]=c}return d}function d(a){var b=r.__currentElementProto,b=b&&b.is,c;for(c in a.dependants)c!==b&&(a.dependants[c].__applyShimInvalid=!0)}function e(e,\nf,l,m){l&&k.processVariableAndFallback(l,function(a,c){c&&b(c)&&(m=\"@apply \"+c+\";\")});if(!m)return e;var n=g(m),q=e.slice(0,e.indexOf(\"--\")),r=n=c(n),p=b(f),t=p&&p.properties;t?(r=Object.create(t),r=Polymer.Base.mixin(r,n)):a(f,r);var v=[],w,y=!1;for(w in r){var z=n[w];void 0===z&&(z=\"initial\");!t||w in t||(y=!0);v.push(f+\"_-_\"+w+\": \"+z)}y&&d(p);p&&(p.properties=r);l&&(q=e+\";\"+q);return q+v.join(\"; \")+\";\"}function f(a,b,c){return\"var(\"+b+\",var(\"+c+\"))\"}function g(d){for(var e;e=l.exec(d);){var f=\ne[0],g=e[1];e=e.index;var k=d.slice(0,e+f.indexOf(\"@apply\"));d=d.slice(e+f.length);var m=c(k),n,f=void 0,g=g.replace(q,\"\"),p=[];var t=b(g);t||(a(g,{}),t=b(g));if(t)for(f in(n=r.__currentElementProto)&&(t.dependants[n.is]=n),t.properties)t=m&&m[f],n=[f,\": var(\",g,\"_-_\",f],t&&n.push(\",\",t),n.push(\")\"),p.push(n.join(\"\"));f=p.join(\"; \");d=[k,f,d].join(\"\");l.lastIndex=e+f.length}return d}var k=Polymer.StyleUtil,l=k.rx.MIXIN_MATCH,m=k.rx.VAR_ASSIGN,n=/var\\(\\s*(--[^,]*),\\s*(--[^)]*)\\)/g,q=/;\\s*/m,p=/^\\s*(initial)|(inherit)\\s*$/,\nt={},r={_measureElement:null,_map:t,_separator:\"_-_\",transform:function(a,b){this.__currentElementProto=b;k.forRulesInStyles(a,this._boundFindDefinitions);k.forRulesInStyles(a,this._boundFindApplications);b&&(b.__applyShimInvalid=!1);this.__currentElementProto=null},_findDefinitions:function(a){var b=a.parsedCssText,b=b.replace(n,f),b=b.replace(m,e);a.cssText=b;\":root\"===a.selector&&(a.selector=\":host \\x3e *\")},_findApplications:function(a){a.cssText=g(a.cssText)},transformRule:function(a){this._findDefinitions(a);\nthis._findApplications(a)},_getInitialValueForProperty:function(a){this._measureElement||(this._measureElement=document.createElement(\"meta\"),this._measureElement.style.all=\"initial\",document.head.appendChild(this._measureElement));return window.getComputedStyle(this._measureElement).getPropertyValue(a)}};r._boundTransformRule=r.transformRule.bind(r);r._boundFindDefinitions=r._findDefinitions.bind(r);r._boundFindApplications=r._findApplications.bind(r);return r}();\n(function(){var a=Polymer.Base._prepElement,b=Polymer.Settings.useNativeShadow,c=Polymer.StyleUtil,d=Polymer.StyleTransformer,e=Polymer.StyleExtends,f=Polymer.ApplyShim,g=Polymer.Settings;Polymer.Base._addFeature({_prepElement:function(b){this._encapsulateStyle&&\"shady\"!==this.__cssBuild&&d.element(b,this.is,this._scopeCssViaAttr);a.call(this,b)},_prepStyles:function(){void 0===this._encapsulateStyle&&(this._encapsulateStyle=!b);b||(this._scopeStyle=c.applyStylePlaceHolder(this.is));this.__cssBuild=\nc.cssBuildTypeForModule(this.is)},_prepShimStyles:function(){if(this._template){var a=c.isTargetedBuild(this.__cssBuild);g.useNativeCSSProperties&&\"shadow\"===this.__cssBuild&&a?g.preserveStyleIncludes&&c.styleIncludesToTemplate(this._template):(this._styles=this._styles||this._collectStyles(),g.useNativeCSSProperties&&!this.__cssBuild&&f.transform(this._styles,this),a=g.useNativeCSSProperties&&a?this._styles.length&&this._styles[0].textContent.trim():d.elementStyles(this),this._prepStyleProperties(),\n!this._needsStyleProperties()&&a&&c.applyCss(a,this.is,b?this._template.content:null,this._scopeStyle))}else this._styles=[]},_collectStyles:function(){var a=[],b=\"\",d=this.styleModules;if(d)for(var f=0,g=d.length,p;f<g&&(p=d[f]);f++)b+=c.cssFromModule(p);b+=c.cssFromModule(this.is);d=this._template&&this._template.parentNode;!this._template||d&&d.id.toLowerCase()===this.is||(b+=c.cssFromElement(this._template));b&&(d=document.createElement(\"style\"),d.textContent=b,e.hasExtends(d.textContent)&&e.transform(d),\na.push(d));return a},_elementAdd:function(a){this._encapsulateStyle&&(a.__styleScoped?a.__styleScoped=!1:d.dom(a,this.is,this._scopeCssViaAttr))},_elementRemove:function(a){this._encapsulateStyle&&d.dom(a,this.is,this._scopeCssViaAttr,!0)},scopeSubtree:function(a,c){if(!b){var d=this,e=function(a){if(a.nodeType===Node.ELEMENT_NODE){var b=a.getAttribute(\"class\");a.setAttribute(\"class\",d._scopeElementClass(a,b));a=a.querySelectorAll(\"*\");for(var c=0,e;c<a.length&&(e=a[c]);c++)b=e.getAttribute(\"class\"),\ne.setAttribute(\"class\",d._scopeElementClass(e,b))}};e(a);if(c)return c=new MutationObserver(function(a){for(var b=0,c;b<a.length&&(c=a[b]);b++)if(c.addedNodes)for(var d=0;d<c.addedNodes.length;d++)e(c.addedNodes[d])}),c.observe(a,{childList:!0,subtree:!0}),c}}})})();\nPolymer.StyleProperties=function(){var a=Polymer.DomApi.matchesSelector,b=Polymer.StyleUtil,c=Polymer.StyleTransformer,d=navigator.userAgent.match(\"Trident\"),e=Polymer.Settings;return{decorateStyles:function(a,d){var e=this,f={},g=[],n=0,q=c._calcHostScope(d.is,d.extends);b.forRulesInStyles(a,function(a,c){e.decorateRule(a);a.index=n++;e.whenHostOrRootRule(d,a,c,function(c){a.parent.type===b.ruleTypes.MEDIA_RULE&&(d.__notStyleScopeCacheable=!0);c.isHost&&(c=c.selector.split(\" \").some(function(a){return 0===\na.indexOf(q)&&a.length!==q.length}),d.__notStyleScopeCacheable=d.__notStyleScopeCacheable||c)});e.collectPropertiesInCssText(a.propertyInfo.cssText,f)},function(a){g.push(a)});a._keyframes=g;a=[];for(var p in f)a.push(p);return a},decorateRule:function(a){if(a.propertyInfo)return a.propertyInfo;var b={},c={};this.collectProperties(a,c)&&(b.properties=c,a.rules=null);b.cssText=this.collectCssText(a);return a.propertyInfo=b},collectProperties:function(a,b){var c=a.propertyInfo;if(c){if(c.properties)return Polymer.Base.mixin(b,\nc.properties),!0}else{for(var c=this.rx.VAR_ASSIGN,d=a.parsedCssText,e;a=c.exec(d);)e=(a[2]||a[3]).trim(),\"inherit\"!==e&&(b[a[1].trim()]=e),e=!0;return e}},collectCssText:function(a){return this.collectConsumingCssText(a.parsedCssText)},collectConsumingCssText:function(a){return a.replace(this.rx.BRACKETED,\"\").replace(this.rx.VAR_ASSIGN,\"\")},collectPropertiesInCssText:function(a,b){for(var c;c=this.rx.VAR_CONSUMED.exec(a);){var d=c[1];\":\"!==c[2]&&(b[d]=!0)}},reify:function(a){for(var b=Object.getOwnPropertyNames(a),\nc=0,d;c<b.length;c++)d=b[c],a[d]=this.valueForProperty(a[d],a)},valueForProperty:function(a,c){if(a)if(0<=a.indexOf(\";\"))a=this.valueForProperties(a,c);else{var d=this;a=b.processVariableAndFallback(a,function(a,b,e,f){(b=d.valueForProperty(c[b],c))&&\"initial\"!==b?\"apply-shim-inherit\"===b&&(b=\"inherit\"):b=d.valueForProperty(c[e]||e,c)||e;return a+(b||\"\")+f})}return a&&a.trim()||\"\"},valueForProperties:function(a,b){a=a.split(\";\");for(var c=0,d,e;c<a.length;c++)if(d=a[c]){this.rx.MIXIN_MATCH.lastIndex=\n0;if(e=this.rx.MIXIN_MATCH.exec(d))d=this.valueForProperty(b[e[1]],b);else if(e=d.indexOf(\":\"),-1!==e){var f=d.substring(e),f=f.trim(),f=this.valueForProperty(f,b)||f;d=d.substring(0,e)+f}a[c]=d&&d.lastIndexOf(\";\")===d.length-1?d.slice(0,-1):d||\"\"}return a.join(\";\")},applyProperties:function(a,b){var c=\"\";a.propertyInfo||this.decorateRule(a);a.propertyInfo.cssText&&(c=this.valueForProperties(a.propertyInfo.cssText,b));a.cssText=c},applyKeyframeTransforms:function(a,b){var c=a.cssText,d=a.cssText;\nnull==a.hasAnimations&&(a.hasAnimations=this.rx.ANIMATION_MATCH.test(c));if(a.hasAnimations)if(null==a.keyframeNamesToTransform){a.keyframeNamesToTransform=[];for(var e in b)d=b[e],d=d(c),c!==d&&(c=d,a.keyframeNamesToTransform.push(e))}else{for(e=0;e<a.keyframeNamesToTransform.length;++e)d=b[a.keyframeNamesToTransform[e]],c=d(c);d=c}a.cssText=d},propertyDataFromStyles:function(c,d){var e={},f=this,g=[];b.forActiveRulesInStyles(c,function(b){b.propertyInfo||f.decorateRule(b);var c=b.transformedSelector||\nb.parsedSelector;d&&b.propertyInfo.properties&&c&&a.call(d,c)&&(f.collectProperties(b,e),b=b.index,c=parseInt(b/32),g[c]=(g[c]||0)|1<<b%32)});return{properties:e,key:g}},_rootSelector:/:root|:host\\s*>\\s*\\*/,_checkRoot:function(a,b){return!!b.match(this._rootSelector)||\"html\"===a&&-1<b.indexOf(\"html\")},whenHostOrRootRule:function(a,b,d,l){b.propertyInfo||self.decorateRule(b);if(b.propertyInfo.properties){var f=a.is?c._calcHostScope(a.is,a.extends):\"html\",g=b.parsedSelector,k=this._checkRoot(f,g),p=\n!k&&0===g.indexOf(\":host\");\"shady\"===(a.__cssBuild||d.__cssBuild)&&(k=g===f+\" \\x3e *.\"+f||-1<g.indexOf(\"html\"),p=!k&&0===g.indexOf(f));if(k||p)d=f,p&&(e.useNativeShadow&&!b.transformedSelector&&(b.transformedSelector=c._transformRuleCss(b,c._transformComplexSelector,a.is,f)),d=b.transformedSelector||b.parsedSelector),k&&\"html\"===f&&(d=b.transformedSelector||b.parsedSelector),l({selector:d,isHost:p,isRoot:k})}},hostAndRootPropertiesForScope:function(c){var d={},e={},f=this;b.forActiveRulesInStyles(c._styles,\nfunction(b,g){f.whenHostOrRootRule(c,b,g,function(g){a.call(c._element||c,g.selector)&&(g.isHost?f.collectProperties(b,d):f.collectProperties(b,e))})});return{rootProps:e,hostProps:d}},transformStyles:function(a,b,d){var f=this,g=c._calcHostScope(a.is,a.extends),k=new RegExp(this.rx.HOST_PREFIX+(a.extends?\"\\\\\"+g.slice(0,-1)+\"\\\\]\":g)+this.rx.HOST_SUFFIX),q=this._elementKeyframeTransforms(a,d);return c.elementStyles(a,function(c){f.applyProperties(c,b);e.useNativeShadow||Polymer.StyleUtil.isKeyframesSelector(c)||\n!c.cssText||(f.applyKeyframeTransforms(c,q),f._scopeSelector(c,k,g,a._scopeCssViaAttr,d))})},_elementKeyframeTransforms:function(a,b){a=a._styles._keyframes;var c={};if(!e.useNativeShadow&&a)for(var d=0,f=a[d];d<a.length;f=a[++d])this._scopeKeyframes(f,b),c[f.keyframesName]=this._keyframesRuleTransformer(f);return c},_keyframesRuleTransformer:function(a){return function(b){return b.replace(a.keyframesNameRx,a.transformedKeyframesName)}},_scopeKeyframes:function(a,b){a.keyframesNameRx=new RegExp(a.keyframesName,\n\"g\");a.transformedKeyframesName=a.keyframesName+\"-\"+b;a.transformedSelector=a.transformedSelector||a.selector;a.selector=a.transformedSelector.replace(a.keyframesName,a.transformedKeyframesName)},_scopeSelector:function(a,b,d,e,m){a.transformedSelector=a.transformedSelector||a.selector;e=e?\"[\"+c.SCOPE_NAME+\"~\\x3d\"+m+\"]\":\".\"+m;m=a.transformedSelector.split(\",\");for(var f=0,g=m.length,k;f<g&&(k=m[f]);f++)m[f]=k.match(b)?k.replace(d,e):e+\" \"+k;a.selector=m.join(\",\")},applyElementScopeSelector:function(a,\nb,d,e){var f=e?a.getAttribute(c.SCOPE_NAME):a.getAttribute(\"class\")||\"\";b=d?f.replace(d,b):(f?f+\" \":\"\")+this.XSCOPE_NAME+\" \"+b;f!==b&&(e?a.setAttribute(c.SCOPE_NAME,b):a.setAttribute(\"class\",b))},applyElementStyle:function(a,c,k,l){c=l?l.textContent||\"\":this.transformStyles(a,c,k);var f=a._customStyle;f&&!e.useNativeShadow&&f!==l&&(f._useCount--,0>=f._useCount&&f.parentNode&&f.parentNode.removeChild(f));e.useNativeShadow?a._customStyle?(a._customStyle.textContent=c,l=a._customStyle):c&&(l=b.applyCss(c,\nk,a.root,a._scopeStyle)):l?l.parentNode||(d&&-1<c.indexOf(\"@media\")&&(l.textContent=c),b.applyStyle(l,null,a._scopeStyle)):c&&(l=b.applyCss(c,k,null,a._scopeStyle));l&&(l._useCount=l._useCount||0,a._customStyle!=l&&l._useCount++,a._customStyle=l);return l},mixinCustomStyle:function(a,b){var c,d;for(d in b)if((c=b[d])||0===c)a[d]=c},updateNativeStyleProperties:function(a,b){var c=a.__customStyleProperties;if(c)for(var d=0;d<c.length;d++)a.style.removeProperty(c[d]);var c=[],e;for(e in b)null!==b[e]&&\n(a.style.setProperty(e,b[e]),c.push(e));a.__customStyleProperties=c},rx:b.rx,XSCOPE_NAME:\"x-scope\"}}();Polymer.StyleCache=function(){this.cache={}};\nPolymer.StyleCache.prototype={MAX:100,store:function(a,b,c,d){b.keyValues=c;b.styles=d;a=this.cache[a]=this.cache[a]||[];a.push(b);a.length>this.MAX&&a.shift()},retrieve:function(a,b,c){if(a=this.cache[a])for(var d=a.length-1,e;0<=d;d--)if(e=a[d],c===e.styles&&this._objectsEqual(b,e.keyValues))return e},clear:function(){this.cache={}},_objectsEqual:function(a,b){var c;for(c in a){var d=a[c];var e=b[c];if(\"object\"===typeof d&&d?!this._objectsStrictlyEqual(d,e):d!==e)return!1}return Array.isArray(a)?\na.length===b.length:!0},_objectsStrictlyEqual:function(a,b){return this._objectsEqual(a,b)&&this._objectsEqual(b,a)}};\nPolymer.StyleDefaults=function(){var a=Polymer.StyleProperties,b=Polymer.Settings.useNativeCSSProperties;return{_styles:[],_properties:null,customStyle:{},_styleCache:new Polymer.StyleCache,_element:Polymer.DomApi.wrap(document.documentElement),addStyle:function(a){this._styles.push(a);this._properties=null},get _styleProperties(){this._properties||(a.decorateStyles(this._styles,this),this._styles._scopeStyleProperties=null,this._properties=a.hostAndRootPropertiesForScope(this).rootProps,a.mixinCustomStyle(this._properties,\nthis.customStyle),a.reify(this._properties));return this._properties},hasStyleProperties:function(){return!!this._properties},_needsStyleProperties:function(){},_computeStyleProperties:function(){return this._styleProperties},updateStyles:function(c){this._properties=null;c&&Polymer.Base.mixin(this.customStyle,c);this._styleCache.clear();c=0;for(var d;c<this._styles.length;c++)d=this._styles[c],d=d.__importElement||d,d._apply();b&&a.updateNativeStyleProperties(document.documentElement,this.customStyle)}}}();\n(function(){var a=Polymer.Base.serializeValueToAttribute,b=Polymer.StyleProperties,c=Polymer.StyleTransformer,d=Polymer.StyleDefaults,e=Polymer.Settings.useNativeShadow,f=Polymer.Settings.useNativeCSSProperties;Polymer.Base._addFeature({_prepStyleProperties:function(){f||(this._ownStylePropertyNames=this._styles&&this._styles.length?b.decorateStyles(this._styles,this):null)},customStyle:null,getComputedStyleValue:function(a){f||this._styleProperties||this._computeStyleProperties();return!f&&this._styleProperties&&\nthis._styleProperties[a]||getComputedStyle(this).getPropertyValue(a)},_setupStyleProperties:function(){this.customStyle={};this._customStyle=this._ownStyleProperties=this._scopeSelector=this._styleProperties=this._styleCache=null},_needsStyleProperties:function(){return!(f||!this._ownStylePropertyNames||!this._ownStylePropertyNames.length)},_validateApplyShim:function(){if(this.__applyShimInvalid){Polymer.ApplyShim.transform(this._styles,this.__proto__);var a=c.elementStyles(this),b=e?this._template.content.querySelector(\"style\"):\nthis._scopeStyle&&this._scopeStyle.nextSibling;b&&(b.textContent=a)}},_beforeAttached:function(){this._scopeSelector&&!this.__stylePropertiesInvalid||!this._needsStyleProperties()||(this.__stylePropertiesInvalid=!1,this._updateStyleProperties())},_findStyleHost:function(){for(var a=this;a=Polymer.dom(a).getOwnerRoot();){if(Polymer.isInstance(a.host))return a.host;a=a.host}return d},_updateStyleProperties:function(){var a=this._findStyleHost();a._styleProperties||a._computeStyleProperties();a._styleCache||\n(a._styleCache=new Polymer.StyleCache);var c=b.propertyDataFromStyles(a._styles,this),d=!this.__notStyleScopeCacheable;if(d){c.key.customStyle=this.customStyle;var f=a._styleCache.retrieve(this.is,c.key,this._styles)}var k=!!f;k?this._styleProperties=f._styleProperties:this._computeStyleProperties(c.properties);this._computeOwnStyleProperties();k||(f=g.retrieve(this.is,this._ownStyleProperties,this._styles));var l=!!f&&!k;f=this._applyStyleProperties(f);k||(f=f&&e?f.cloneNode(!0):f,f={style:f,_scopeSelector:this._scopeSelector,\n_styleProperties:this._styleProperties},d&&(c.key.customStyle={},this.mixin(c.key.customStyle,this.customStyle),a._styleCache.store(this.is,f,c.key,this._styles)),l||g.store(this.is,Object.create(f),this._ownStyleProperties,this._styles))},_computeStyleProperties:function(a){var c=this._findStyleHost();c._styleProperties||c._computeStyleProperties();var d=Object.create(c._styleProperties),e=b.hostAndRootPropertiesForScope(this);this.mixin(d,e.hostProps);a=a||b.propertyDataFromStyles(c._styles,this).properties;\nthis.mixin(d,a);this.mixin(d,e.rootProps);b.mixinCustomStyle(d,this.customStyle);b.reify(d);this._styleProperties=d},_computeOwnStyleProperties:function(){for(var a={},b=0,c;b<this._ownStylePropertyNames.length;b++)c=this._ownStylePropertyNames[b],a[c]=this._styleProperties[c];this._ownStyleProperties=a},_scopeCount:0,_applyStyleProperties:function(a){var c=this._scopeSelector;this._scopeSelector=a?a._scopeSelector:this.is+\"-\"+this.__proto__._scopeCount++;a=b.applyElementStyle(this,this._styleProperties,\nthis._scopeSelector,a&&a.style);e||b.applyElementScopeSelector(this,this._scopeSelector,c,this._scopeCssViaAttr);return a},serializeValueToAttribute:function(b,c,d){d=d||this;if(\"class\"===c&&!e){var f=d===this?this.domHost||this.dataHost:this;f&&(b=f._scopeElementClass(d,b))}d=this.shadyRoot&&this.shadyRoot._hasDistributed?Polymer.dom(d):d;a.call(this,b,c,d)},_scopeElementClass:function(a,b){e||this._scopeCssViaAttr||(b=(b?b+\" \":\"\")+k+\" \"+this.is+(a._scopeSelector?\" \"+l+\" \"+a._scopeSelector:\"\"));\nreturn b},updateStyles:function(a){a&&this.mixin(this.customStyle,a);f?b.updateNativeStyleProperties(this,this.customStyle):(this.isAttached?this._needsStyleProperties()?this._updateStyleProperties():this._styleProperties=null:this.__stylePropertiesInvalid=!0,this._styleCache&&this._styleCache.clear(),this._updateRootStyles())},_updateRootStyles:function(a){a=a||this.root;a=Polymer.dom(a)._query(function(a){return a.shadyRoot||a.shadowRoot});for(var b=0,c=a.length,d;b<c&&(d=a[b]);b++)d.updateStyles&&\nd.updateStyles()}});Polymer.updateStyles=function(a){d.updateStyles(a);Polymer.Base._updateRootStyles(document)};var g=new Polymer.StyleCache;Polymer.customStyleCache=g;var k=c.SCOPE_NAME,l=b.XSCOPE_NAME})();\nPolymer.Base._addFeature({_registerFeatures:function(){this._prepIs();this.factoryImpl&&this._prepConstructor();this._prepStyles()},_finishRegisterFeatures:function(){this._prepTemplate();this._prepShimStyles();this._prepAnnotations();this._prepEffects();this._prepBehaviors();this._prepPropertyInfo();this._prepBindings();this._prepShady()},_prepBehavior:function(a){this._addPropertyEffects(a.properties);this._addComplexObserverEffects(a.observers);this._addHostAttributes(a.hostAttributes)},_initFeatures:function(){this._setupGestures();\nthis._setupConfigure(this.__data__);this._setupStyleProperties();this._setupDebouncers();this._setupShady();this._registerHost();this._template&&(this._validateApplyShim(),this._poolContent(),this._beginHosting(),this._stampTemplate(),this._endHosting(),this._marshalAnnotationReferences());this._marshalInstanceEffects();this._marshalBehaviors();this._marshalHostAttributes();this._marshalAttributes();this._tryReady()},_marshalBehavior:function(a){a.listeners&&this._listenListeners(a.listeners)}});\n(function(){var a=Polymer.StyleProperties,b=Polymer.StyleUtil,c=Polymer.CssParse,d=Polymer.StyleDefaults,e=Polymer.StyleTransformer,f=Polymer.ApplyShim,g=Polymer.Debounce,k=Polymer.Settings,l;Polymer({is:\"custom-style\",extends:\"style\",_template:null,properties:{include:String},ready:function(){this.__appliedElement=this.__appliedElement||this;this.__cssBuild=b.getCssBuildType(this);this.__appliedElement!==this&&(this.__appliedElement.__cssBuild=this.__cssBuild);this._tryApply()},attached:function(){this._tryApply()},\n_tryApply:function(){if(!this._appliesToDocument&&this.parentNode&&\"dom-module\"!==this.parentNode.localName){this._appliesToDocument=!0;var a=this.__appliedElement;k.useNativeCSSProperties||(this.__needsUpdateStyles=d.hasStyleProperties(),d.addStyle(a));if(a.textContent||this.include)this._apply(!0);else{var b=this,c=new MutationObserver(function(){c.disconnect();b._apply(!0)});c.observe(a,{childList:!0})}}},_updateStyles:function(){Polymer.updateStyles()},_apply:function(a){var c=this.__appliedElement;\nthis.include&&(c.textContent=b.cssFromModules(this.include,!0)+c.textContent);if(c.textContent){var d=this.__cssBuild,g=b.isTargetedBuild(d);if(!k.useNativeCSSProperties||!g){var l=b.rulesForStyle(c);g||(b.forEachRule(l,function(a){e.documentRule(a)}),k.useNativeCSSProperties&&!d&&f.transform([c]));if(k.useNativeCSSProperties)c.textContent=b.toCssText(l);else{var m=this,c=function(){m._flushCustomProperties()};a?Polymer.RenderStatus.whenReady(c):c()}}}},_flushCustomProperties:function(){this.__needsUpdateStyles?\n(this.__needsUpdateStyles=!1,l=g(l,this._updateStyles)):this._applyCustomProperties()},_applyCustomProperties:function(){var d=this.__appliedElement;this._computeStyleProperties();var e=this._styleProperties,f=b.rulesForStyle(d);f&&(d.textContent=b.toCssText(f,function(b){var d=b.cssText=b.parsedCssText;b.propertyInfo&&b.propertyInfo.cssText&&(d=c.removeCustomPropAssignment(d),b.cssText=a.valueForProperties(d,e))}))}})})();\nPolymer.Templatizer={properties:{__hideTemplateChildren__:{observer:\"_showHideChildren\"}},_instanceProps:Polymer.nob,_parentPropPrefix:\"_parent_\",templatize:function(a){this._templatized=a;a._content||(a._content=a.content);if(a._content._ctor)this.ctor=a._content._ctor,this._prepParentProperties(this.ctor.prototype,a);else{var b=Object.create(Polymer.Base);this._customPrepAnnotations(b,a);this._prepParentProperties(b,a);b._prepEffects();this._customPrepEffects(b);b._prepBehaviors();b._prepPropertyInfo();\nb._prepBindings();b._notifyPathUp=this._notifyPathUpImpl;b._scopeElementClass=this._scopeElementClassImpl;b.listen=this._listenImpl;b._showHideChildren=this._showHideChildrenImpl;b.__setPropertyOrig=this.__setProperty;b.__setProperty=this.__setPropertyImpl;var c=this._constructorImpl,d=function(a,b){c.call(this,a,b)};d.prototype=b;b.constructor=d;this.ctor=a._content._ctor=d}},_getRootDataHost:function(){return this.dataHost&&this.dataHost._rootDataHost||this.dataHost},_showHideChildrenImpl:function(a){for(var b=\nthis._children,c=0;c<b.length;c++){var d=b[c];!!a!=!!d.__hideTemplateChildren__&&(d.nodeType===Node.TEXT_NODE?a?(d.__polymerTextContent__=d.textContent,d.textContent=\"\"):d.textContent=d.__polymerTextContent__:d.style&&(a?(d.__polymerDisplay__=d.style.display,d.style.display=\"none\"):d.style.display=d.__polymerDisplay__));d.__hideTemplateChildren__=a}},__setPropertyImpl:function(a,b,c,d){d&&d.__hideTemplateChildren__&&\"textContent\"==a&&(a=\"__polymerTextContent__\");this.__setPropertyOrig(a,b,c,d)},_debounceTemplate:function(a){Polymer.dom.addDebouncer(this.debounce(\"_debounceTemplate\",\na))},_flushTemplates:function(){Polymer.dom.flush()},_customPrepEffects:function(a){var b=a._parentProps,c;for(c in b)a._addPropertyEffect(c,\"function\",this._createHostPropEffector(c));for(c in this._instanceProps)a._addPropertyEffect(c,\"function\",this._createInstancePropEffector(c))},_customPrepAnnotations:function(a,b){a._template=b;var c=b._content;if(!c._notes){var d=a._rootDataHost;d&&(Polymer.Annotations.prepElement=function(){d._prepElement()});c._notes=Polymer.Annotations.parseAnnotations(b);\nPolymer.Annotations.prepElement=null;this._processAnnotations(c._notes)}a._notes=c._notes;a._parentProps=c._parentProps},_prepParentProperties:function(a,b){var c=this._parentProps=a._parentProps;if(this._forwardParentProp&&c){var d=a._parentPropProto,e;if(!d){for(e in this._instanceProps)delete c[e];d=a._parentPropProto=Object.create(null);b!=this&&(Polymer.Bind.prepareModel(d),Polymer.Base.prepareModelNotifyPath(d));for(e in c)a=this._parentPropPrefix+e,c=[{kind:\"function\",effect:this._createForwardPropEffector(e),\nfn:Polymer.Bind._functionEffect},{kind:\"notify\",fn:Polymer.Bind._notifyEffect,effect:{event:Polymer.CaseMap.camelToDashCase(a)+\"-changed\"}}],d._propertyEffects=d._propertyEffects||{},d._propertyEffects[a]=c,Polymer.Bind._createAccessors(d,a,c)}var f=this;b!=this&&(Polymer.Bind.prepareInstance(b),b._forwardParentProp=function(a,b){f._forwardParentProp(a,b)});this._extendTemplate(b,d);b._pathEffector=function(a,b,c){return f._pathEffectorImpl(a,b,c)}}},_createForwardPropEffector:function(a){return function(b,\nc){this._forwardParentProp(a,c)}},_createHostPropEffector:function(a){var b=this._parentPropPrefix;return function(c,d){this.dataHost._templatized[b+a]=d}},_createInstancePropEffector:function(a){return function(b,c,d,e){e||this.dataHost._forwardInstanceProp(this,a,c)}},_extendTemplate:function(a,b){var c=Object.getOwnPropertyNames(b);b._propertySetter&&(a._propertySetter=b._propertySetter);for(var d=0,e;d<c.length&&(e=c[d]);d++){var f=a[e];f&&\"_propertyEffects\"==e?(f=Polymer.Base.mixin({},f),a._propertyEffects=\nPolymer.Base.mixin(f,b._propertyEffects)):(Object.defineProperty(a,e,Object.getOwnPropertyDescriptor(b,e)),void 0!==f&&a._propertySetter(e,f))}},_showHideChildren:function(){},_forwardInstancePath:function(){},_forwardInstanceProp:function(){},_notifyPathUpImpl:function(a,b){var c=this.dataHost,d=Polymer.Path.root(a);c._forwardInstancePath.call(c,this,a,b);d in c._parentProps&&c._templatized._notifyPath(c._parentPropPrefix+a,b)},_pathEffectorImpl:function(a,b,c){if(this._forwardParentPath&&0===a.indexOf(this._parentPropPrefix)){var d=\na.substring(this._parentPropPrefix.length);Polymer.Path.root(d)in this._parentProps&&this._forwardParentPath(d,b)}Polymer.Base._pathEffector.call(this._templatized,a,b,c)},_constructorImpl:function(a,b){this._rootDataHost=b._getRootDataHost();this._setupConfigure(a);this._registerHost(b);this._beginHosting();this.root=this.instanceTemplate(this._template);this.root.__noContent=!this._notes._hasContent;this.root.__styleScoped=!0;this._endHosting();this._marshalAnnotatedNodes();this._marshalInstanceEffects();\nthis._marshalAnnotatedListeners();a=[];for(var c=this.root.firstChild;c;c=c.nextSibling)a.push(c),c._templateInstance=this;this._children=a;b.__hideTemplateChildren__&&this._showHideChildren(!0);this._tryReady()},_listenImpl:function(a,b,c){var d=this,e=this._rootDataHost,f=e._createEventHandler(a,b,c);e._listen(a,b,function(a){a.model=d;f(a)})},_scopeElementClassImpl:function(a,b){var c=this._rootDataHost;return c?c._scopeElementClass(a,b):b},stamp:function(a){a=a||{};if(this._parentProps){var b=\nthis._templatized,c;for(c in this._parentProps)void 0===a[c]&&(a[c]=b[this._parentPropPrefix+c])}return new this.ctor(a,this)},modelForElement:function(a){for(var b;a;)if(b=a._templateInstance)if(b.dataHost!=this)a=b.dataHost;else return b;else a=a.parentNode}};Polymer({is:\"dom-template\",extends:\"template\",_template:null,behaviors:[Polymer.Templatizer],ready:function(){this.templatize(this)}});Polymer._collections=new WeakMap;\nPolymer.Collection=function(a){Polymer._collections.set(a,this);this.userArray=a;this.store=a.slice();this.initMap()};\nPolymer.Collection.prototype={constructor:Polymer.Collection,initMap:function(){for(var a=this.omap=new WeakMap,b=this.pmap={},c=this.store,d=0;d<c.length;d++){var e=c[d];e&&\"object\"==typeof e?a.set(e,d):b[e]=d}},add:function(a){var b=this.store.push(a)-1;a&&\"object\"==typeof a?this.omap.set(a,b):this.pmap[a]=b;return\"#\"+b},removeKey:function(a){if(a=Rd(a))Sd(this,this.store[a]),delete this.store[a]},remove:function(a){a=this.getKey(a);this.removeKey(a);return a},getKey:function(a){a=a&&\"object\"==\ntypeof a?this.omap.get(a):this.pmap[a];if(void 0!=a)return\"#\"+a},getKeys:function(){return Object.keys(this.store).map(function(a){return\"#\"+a})},setItem:function(a,b){if(a=Rd(a)){var c=this.store[a];c&&Sd(this,c);b&&\"object\"==typeof b?this.omap.set(b,a):this.pmap[b]=a;this.store[a]=b}},getItem:function(a){if(a=Rd(a))return this.store[a]},getItems:function(){var a=[],b=this.store,c;for(c in b)a.push(b[c]);return a}};function Rd(a){if(a&&\"#\"==a[0])return a.slice(1)}\nfunction Sd(a,b){b&&\"object\"==typeof b?a.omap.delete(b):delete a.pmap[b]}Polymer.Collection.get=function(a){return Polymer._collections.get(a)||new Polymer.Collection(a)};\nPolymer.Collection.applySplices=function(a,b){a=Polymer._collections.get(a);if(a){for(var c={},d=0,e;d<b.length&&(e=b[d]);d++){e.addedKeys=[];for(var f=0;f<e.removed.length;f++){var g=a.getKey(e.removed[f]);c[g]=c[g]?null:-1}for(f=0;f<e.addedCount;f++){var k=a.userArray[e.index+f];g=a.getKey(k);g=void 0===g?a.add(k):g;c[g]=c[g]?null:1;e.addedKeys.push(g)}}b=[];e=[];for(g in c)0>c[g]&&(a.removeKey(g),b.push(g)),0<c[g]&&e.push(g);g=[{removed:b,added:e}]}else g=null;return g};\nPolymer({is:\"dom-repeat\",extends:\"template\",_template:null,properties:{items:{type:Array},as:{type:String,value:\"item\"},indexAs:{type:String,value:\"index\"},sort:{type:Function,observer:\"_sortChanged\"},filter:{type:Function,observer:\"_filterChanged\"},observe:{type:String,observer:\"_observeChanged\"},delay:Number,renderedItemCount:{type:Number,notify:!Polymer.Settings.suppressTemplateNotifications,readOnly:!0},initialCount:{type:Number,observer:\"_initializeChunking\"},targetFramerate:{type:Number,value:20},\nnotifyDomChange:{type:Boolean},_targetFrameTime:{type:Number,computed:\"_computeFrameTime(targetFramerate)\"}},behaviors:[Polymer.Templatizer],observers:[\"_itemsChanged(items.*)\"],created:function(){this._instances=[];this._pool=[];this._limit=Infinity;var a=this;this._boundRenderChunk=function(){a._renderChunk()}},detached:function(){this.__isDetached=!0;for(var a=0;a<this._instances.length;a++)this._detachInstance(a)},attached:function(){if(this.__isDetached){this.__isDetached=!1;for(var a=Polymer.dom(Polymer.dom(this).parentNode),\nb=0;b<this._instances.length;b++)this._attachInstance(b,a)}},ready:function(){this._instanceProps={__key__:!0};this._instanceProps[this.as]=!0;this._instanceProps[this.indexAs]=!0;this.ctor||this.templatize(this)},_sortChanged:function(a){var b=this._getRootDataHost();this._sortFn=a&&(\"function\"==typeof a?a:function(){return b[a].apply(b,arguments)});this._needFullRefresh=!0;this.items&&this._debounceTemplate(this._render)},_filterChanged:function(a){var b=this._getRootDataHost();this._filterFn=a&&\n(\"function\"==typeof a?a:function(){return b[a].apply(b,arguments)});this._needFullRefresh=!0;this.items&&this._debounceTemplate(this._render)},_computeFrameTime:function(a){return Math.ceil(1E3/a)},_initializeChunking:function(){this.initialCount&&(this._chunkCount=this._limit=this.initialCount,this._lastChunkTime=performance.now())},_tryRenderChunk:function(){this.items&&this._limit<this.items.length&&this.debounce(\"renderChunk\",this._requestRenderChunk)},_requestRenderChunk:function(){requestAnimationFrame(this._boundRenderChunk)},\n_renderChunk:function(){var a=performance.now();this._chunkCount=Math.round(this._targetFrameTime/(a-this._lastChunkTime)*this._chunkCount)||1;this._limit+=this._chunkCount;this._lastChunkTime=a;this._debounceTemplate(this._render)},_observeChanged:function(){this._observePaths=this.observe&&this.observe.replace(\".*\",\".\").split(\" \")},_itemsChanged:function(a){if(\"items\"==a.path)Array.isArray(this.items)?this.collection=Polymer.Collection.get(this.items):this.items?this._error(this._logf(\"dom-repeat\",\n\"expected array for `items`, found\",this.items)):this.collection=null,this._keySplices=[],this._indexSplices=[],this._needFullRefresh=!0,this._initializeChunking(),this._debounceTemplate(this._render);else if(\"items.splices\"==a.path)this._keySplices=this._keySplices.concat(a.value.keySplices),this._indexSplices=this._indexSplices.concat(a.value.indexSplices),this._debounceTemplate(this._render);else{var b=a.path.slice(6);this._forwardItemPath(b,a.value);this._checkObservedPaths(b)}},_checkObservedPaths:function(a){if(this._observePaths){a=\na.substring(a.indexOf(\".\")+1);for(var b=this._observePaths,c=0;c<b.length;c++)if(0===a.indexOf(b[c])){this._needFullRefresh=!0;this.delay?this.debounce(\"render\",this._render,this.delay):this._debounceTemplate(this._render);break}}},render:function(){this._needFullRefresh=!0;this._debounceTemplate(this._render);this._flushTemplates()},_render:function(){this._needFullRefresh?(this._applyFullRefresh(),this._needFullRefresh=!1):this._keySplices.length&&(this._sortFn?this._applySplicesUserSort(this._keySplices):\nthis._filterFn?this._applyFullRefresh():this._applySplicesArrayOrder(this._indexSplices));this._keySplices=[];this._indexSplices=[];for(var a=this._keyToInstIdx={},b=this._instances.length-1;0<=b;b--){var c=this._instances[b];c.isPlaceholder&&b<this._limit?c=this._insertInstance(b,c.__key__):!c.isPlaceholder&&b>=this._limit&&(c=this._downgradeInstance(b,c.__key__));a[c.__key__]=b;c.isPlaceholder||c.__setProperty(this.indexAs,b,!0)}this._pool.length=0;this._setRenderedItemCount(this._instances.length);\nPolymer.Settings.suppressTemplateNotifications&&!this.notifyDomChange||this.fire(\"dom-change\");this._tryRenderChunk()},_applyFullRefresh:function(){var a=this.collection;if(this._sortFn)var b=a?a.getKeys():[];else{b=[];var c=this.items;if(c)for(var d=0;d<c.length;d++)b.push(a.getKey(c[d]))}var e=this;this._filterFn&&(b=b.filter(function(b){return e._filterFn(a.getItem(b))}));this._sortFn&&b.sort(function(b,c){return e._sortFn(a.getItem(b),a.getItem(c))});for(d=0;d<b.length;d++){var c=b[d],f=this._instances[d];\nf?(f.__key__=c,!f.isPlaceholder&&d<this._limit&&f.__setProperty(this.as,a.getItem(c),!0)):d<this._limit?this._insertInstance(d,c):this._insertPlaceholder(d,c)}for(b=this._instances.length-1;b>=d;b--)this._detachAndRemoveInstance(b)},_numericSort:function(a,b){return a-b},_applySplicesUserSort:function(a){for(var b=this.collection,c={},d,e=0,f;e<a.length&&(f=a[e]);e++){for(var g=0;g<f.removed.length;g++)d=f.removed[g],c[d]=c[d]?null:-1;for(g=0;g<f.added.length;g++)d=f.added[g],c[d]=c[d]?null:1}f=[];\na=[];for(d in c)-1===c[d]&&f.push(this._keyToInstIdx[d]),1===c[d]&&a.push(d);if(f.length)for(f.sort(this._numericSort),e=f.length-1;0<=e;e--)c=f[e],void 0!==c&&this._detachAndRemoveInstance(c);var k=this;if(a.length)for(this._filterFn&&(a=a.filter(function(a){return k._filterFn(b.getItem(a))})),a.sort(function(a,c){return k._sortFn(b.getItem(a),b.getItem(c))}),e=c=0;e<a.length;e++)c=this._insertRowUserSort(c,a[e])},_insertRowUserSort:function(a,b){for(var c=this.collection,d=c.getItem(b),e=this._instances.length-\n1,f=-1;a<=e;){var g=a+e>>1,k=this._sortFn(c.getItem(this._instances[g].__key__),d);if(0>k)a=g+1;else if(0<k)e=g-1;else{f=g;break}}0>f&&(f=e+1);this._insertPlaceholder(f,b);return f},_applySplicesArrayOrder:function(a){for(var b=0,c;b<a.length&&(c=a[b]);b++){for(var d=0;d<c.removed.length;d++)this._detachAndRemoveInstance(c.index);for(d=0;d<c.addedKeys.length;d++)this._insertPlaceholder(c.index+d,c.addedKeys[d])}},_detachInstance:function(a){a=this._instances[a];if(!a.isPlaceholder){for(var b=0;b<\na._children.length;b++){var c=a._children[b];Polymer.dom(a.root).appendChild(c)}return a}},_attachInstance:function(a,b){a=this._instances[a];a.isPlaceholder||b.insertBefore(a.root,this)},_detachAndRemoveInstance:function(a){var b=this._detachInstance(a);b&&this._pool.push(b);this._instances.splice(a,1)},_insertPlaceholder:function(a,b){this._instances.splice(a,0,{isPlaceholder:!0,__key__:b})},_stampInstance:function(a,b){var c={__key__:b};c[this.as]=this.collection.getItem(b);c[this.indexAs]=a;return this.stamp(c)},\n_insertInstance:function(a,b){var c=this._pool.pop();c?(c.__setProperty(this.as,this.collection.getItem(b),!0),c.__setProperty(\"__key__\",b,!0)):c=this._stampInstance(a,b);b=(b=this._instances[a+1])&&!b.isPlaceholder?b._children[0]:this;var d=Polymer.dom(this).parentNode;Polymer.dom(d).insertBefore(c.root,b);return this._instances[a]=c},_downgradeInstance:function(a,b){var c=this._detachInstance(a);c&&this._pool.push(c);c={isPlaceholder:!0,__key__:b};return this._instances[a]=c},_showHideChildren:function(a){for(var b=\n0;b<this._instances.length;b++)this._instances[b].isPlaceholder||this._instances[b]._showHideChildren(a)},_forwardInstanceProp:function(a,b,c){b==this.as&&(a=this._sortFn||this._filterFn?this.items.indexOf(this.collection.getItem(a.__key__)):a[this.indexAs],this.set(\"items.\"+a,c))},_forwardInstancePath:function(a,b,c){0===b.indexOf(this.as+\".\")&&this._notifyPath(\"items.\"+a.__key__+\".\"+b.slice(this.as.length+1),c)},_forwardParentProp:function(a,b){for(var c=this._instances,d=0,e;d<c.length&&(e=c[d]);d++)e.isPlaceholder||\ne.__setProperty(a,b,!0)},_forwardParentPath:function(a,b){for(var c=this._instances,d=0,e;d<c.length&&(e=c[d]);d++)e.isPlaceholder||e._notifyPath(a,b,!0)},_forwardItemPath:function(a,b){if(this._keyToInstIdx){var c=a.indexOf(\".\"),d=this._instances[this._keyToInstIdx[a.substring(0,0>c?a.length:c)]];d&&!d.isPlaceholder&&(0<=c?(a=this.as+\".\"+a.substring(c+1),d._notifyPath(a,b,!0)):d.__setProperty(this.as,b,!0))}},itemForElement:function(a){return(a=this.modelForElement(a))&&a[this.as]},keyForElement:function(a){return(a=\nthis.modelForElement(a))&&a.__key__},indexForElement:function(a){return(a=this.modelForElement(a))&&a[this.indexAs]}});\nPolymer({is:\"array-selector\",_template:null,properties:{items:{type:Array,observer:\"clearSelection\"},multi:{type:Boolean,value:!1,observer:\"clearSelection\"},selected:{type:Object,notify:!0},selectedItem:{type:Object,notify:!0},toggle:{type:Boolean,value:!1}},clearSelection:function(){if(Array.isArray(this.selected))for(var a=0;a<this.selected.length;a++)this.unlinkPaths(\"selected.\"+a);else this.unlinkPaths(\"selected\"),this.unlinkPaths(\"selectedItem\");if(this.multi){if(!this.selected||this.selected.length)this.selected=\n[],this._selectedColl=Polymer.Collection.get(this.selected)}else this._selectedColl=this.selected=null;this.selectedItem=null},isSelected:function(a){return this.multi?void 0!==this._selectedColl.getKey(a):this.selected==a},deselect:function(a){if(this.multi){if(this.isSelected(a)){var b=this._selectedColl.getKey(a);this.arrayDelete(\"selected\",a);this.unlinkPaths(\"selected.\"+b)}}else this.selectedItem=this.selected=null,this.unlinkPaths(\"selected\"),this.unlinkPaths(\"selectedItem\")},select:function(a){var b=\nPolymer.Collection.get(this.items).getKey(a);this.multi?this.isSelected(a)?this.toggle&&this.deselect(a):(this.push(\"selected\",a),a=this._selectedColl.getKey(a),this.linkPaths(\"selected.\"+a,\"items.\"+b)):this.toggle&&a==this.selected?this.deselect():(this.selectedItem=this.selected=a,this.linkPaths(\"selected\",\"items.\"+b),this.linkPaths(\"selectedItem\",\"items.\"+b))}});\nPolymer({is:\"dom-if\",extends:\"template\",_template:null,properties:{\"if\":{type:Boolean,value:!1,observer:\"_queueRender\"},restamp:{type:Boolean,value:!1,observer:\"_queueRender\"},notifyDomChange:{type:Boolean}},behaviors:[Polymer.Templatizer],_queueRender:function(){this._debounceTemplate(this._render)},detached:function(){this.parentNode&&(this.parentNode.nodeType!=Node.DOCUMENT_FRAGMENT_NODE||Polymer.Settings.hasShadow&&this.parentNode instanceof ShadowRoot)||this._teardownInstance()},attached:function(){this.if&&\nthis.ctor&&this.async(this._ensureInstance)},render:function(){this._flushTemplates()},_render:function(){this.if?(this.ctor||this.templatize(this),this._ensureInstance(),this._showHideChildren()):this.restamp&&this._teardownInstance();!this.restamp&&this._instance&&this._showHideChildren();this.if!=this._lastIf&&(Polymer.Settings.suppressTemplateNotifications&&!this.notifyDomChange||this.fire(\"dom-change\"),this._lastIf=this.if)},_ensureInstance:function(){var a=Polymer.dom(this).parentNode;if(a)if(a=\nPolymer.dom(a),this._instance){var b=this._instance._children;if(b&&b.length&&Polymer.dom(this).previousSibling!==b[b.length-1])for(var c=0,d;c<b.length&&(d=b[c]);c++)a.insertBefore(d,this)}else this._instance=this.stamp(),a.insertBefore(this._instance.root,this)},_teardownInstance:function(){if(this._instance){var a=this._instance._children;if(a&&a.length)for(var b=Polymer.dom(Polymer.dom(a[0]).parentNode),c=0,d;c<a.length&&(d=a[c]);c++)b.removeChild(d);this._instance=null}},_showHideChildren:function(){var a=\nthis.__hideTemplateChildren__||!this.if;this._instance&&this._instance._showHideChildren(a)},_forwardParentProp:function(a,b){this._instance&&this._instance.__setProperty(a,b,!0)},_forwardParentPath:function(a,b){this._instance&&this._instance._notifyPath(a,b,!0)}});\nPolymer({is:\"dom-bind\",properties:{notifyDomChange:{type:Boolean}},extends:\"template\",_template:null,created:function(){var a=this;Polymer.RenderStatus.whenReady(function(){\"loading\"==document.readyState?document.addEventListener(\"DOMContentLoaded\",function(){a._markImportsReady()}):a._markImportsReady()})},_ensureReady:function(){this._readied||this._readySelf()},_markImportsReady:function(){this._importsReady=!0;this._ensureReady()},_registerFeatures:function(){this._prepConstructor()},_insertChildren:function(){Polymer.dom(Polymer.dom(this).parentNode).insertBefore(this.root,\nthis)},_removeChildren:function(){if(this._children)for(var a=0;a<this._children.length;a++)this.root.appendChild(this._children[a])},_initFeatures:function(){},_scopeElementClass:function(a,b){return this.dataHost?this.dataHost._scopeElementClass(a,b):b},_configureInstanceProperties:function(){},_prepConfigure:function(){var a={},b;for(b in this._propertyEffects)a[b]=this[b];var c=this._setupConfigure;this._setupConfigure=function(){c.call(this,a)}},attached:function(){this._importsReady&&this.render()},\ndetached:function(){this._removeChildren()},render:function(){this._ensureReady();this._children||(this._template=this,this._prepAnnotations(),this._prepEffects(),this._prepBehaviors(),this._prepConfigure(),this._prepBindings(),this._prepPropertyInfo(),Polymer.Base._initFeatures.call(this),this._children=Polymer.TreeApi.arrayCopyChildNodes(this.root));this._insertChildren();Polymer.Settings.suppressTemplateNotifications&&!this.notifyDomChange||this.fire(\"dom-change\")}});\n</script>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n<style is=\"custom-style\">\n\n  :root {\n\n    /* Material Design color palette for Google products */\n\n    --google-red-100: #f4c7c3;\n    --google-red-300: #e67c73;\n    --google-red-500: #db4437;\n    --google-red-700: #c53929;\n\n    --google-blue-100: #c6dafc;\n    --google-blue-300: #7baaf7;\n    --google-blue-500: #4285f4;\n    --google-blue-700: #3367d6;\n\n    --google-green-100: #b7e1cd;\n    --google-green-300: #57bb8a;\n    --google-green-500: #0f9d58;\n    --google-green-700: #0b8043;\n\n    --google-yellow-100: #fce8b2;\n    --google-yellow-300: #f7cb4d;\n    --google-yellow-500: #f4b400;\n    --google-yellow-700: #f09300;\n\n    --google-grey-100: #f5f5f5;\n    --google-grey-300: #e0e0e0;\n    --google-grey-500: #9e9e9e;\n    --google-grey-700: #616161;\n    \n    /* Material Design color palette from online spec document */\n\n    --paper-red-50: #ffebee;\n    --paper-red-100: #ffcdd2;\n    --paper-red-200: #ef9a9a;\n    --paper-red-300: #e57373;\n    --paper-red-400: #ef5350;\n    --paper-red-500: #f44336;\n    --paper-red-600: #e53935;\n    --paper-red-700: #d32f2f;\n    --paper-red-800: #c62828;\n    --paper-red-900: #b71c1c;\n    --paper-red-a100: #ff8a80;\n    --paper-red-a200: #ff5252;\n    --paper-red-a400: #ff1744;\n    --paper-red-a700: #d50000;\n \n    --paper-pink-50: #fce4ec;\n    --paper-pink-100: #f8bbd0;\n    --paper-pink-200: #f48fb1;\n    --paper-pink-300: #f06292;\n    --paper-pink-400: #ec407a;\n    --paper-pink-500: #e91e63;\n    --paper-pink-600: #d81b60;\n    --paper-pink-700: #c2185b;\n    --paper-pink-800: #ad1457;\n    --paper-pink-900: #880e4f;\n    --paper-pink-a100: #ff80ab;\n    --paper-pink-a200: #ff4081;\n    --paper-pink-a400: #f50057;\n    --paper-pink-a700: #c51162;\n \n    --paper-purple-50: #f3e5f5;\n    --paper-purple-100: #e1bee7;\n    --paper-purple-200: #ce93d8;\n    --paper-purple-300: #ba68c8;\n    --paper-purple-400: #ab47bc;\n    --paper-purple-500: #9c27b0;\n    --paper-purple-600: #8e24aa;\n    --paper-purple-700: #7b1fa2;\n    --paper-purple-800: #6a1b9a;\n    --paper-purple-900: #4a148c;\n    --paper-purple-a100: #ea80fc;\n    --paper-purple-a200: #e040fb;\n    --paper-purple-a400: #d500f9;\n    --paper-purple-a700: #aa00ff;\n \n    --paper-deep-purple-50: #ede7f6;\n    --paper-deep-purple-100: #d1c4e9;\n    --paper-deep-purple-200: #b39ddb;\n    --paper-deep-purple-300: #9575cd;\n    --paper-deep-purple-400: #7e57c2;\n    --paper-deep-purple-500: #673ab7;\n    --paper-deep-purple-600: #5e35b1;\n    --paper-deep-purple-700: #512da8;\n    --paper-deep-purple-800: #4527a0;\n    --paper-deep-purple-900: #311b92;\n    --paper-deep-purple-a100: #b388ff;\n    --paper-deep-purple-a200: #7c4dff;\n    --paper-deep-purple-a400: #651fff;\n    --paper-deep-purple-a700: #6200ea;\n \n    --paper-indigo-50: #e8eaf6;\n    --paper-indigo-100: #c5cae9;\n    --paper-indigo-200: #9fa8da;\n    --paper-indigo-300: #7986cb;\n    --paper-indigo-400: #5c6bc0;\n    --paper-indigo-500: #3f51b5;\n    --paper-indigo-600: #3949ab;\n    --paper-indigo-700: #303f9f;\n    --paper-indigo-800: #283593;\n    --paper-indigo-900: #1a237e;\n    --paper-indigo-a100: #8c9eff;\n    --paper-indigo-a200: #536dfe;\n    --paper-indigo-a400: #3d5afe;\n    --paper-indigo-a700: #304ffe;\n \n    --paper-blue-50: #e3f2fd;\n    --paper-blue-100: #bbdefb;\n    --paper-blue-200: #90caf9;\n    --paper-blue-300: #64b5f6;\n    --paper-blue-400: #42a5f5;\n    --paper-blue-500: #2196f3;\n    --paper-blue-600: #1e88e5;\n    --paper-blue-700: #1976d2;\n    --paper-blue-800: #1565c0;\n    --paper-blue-900: #0d47a1;\n    --paper-blue-a100: #82b1ff;\n    --paper-blue-a200: #448aff;\n    --paper-blue-a400: #2979ff;\n    --paper-blue-a700: #2962ff;\n \n    --paper-light-blue-50: #e1f5fe;\n    --paper-light-blue-100: #b3e5fc;\n    --paper-light-blue-200: #81d4fa;\n    --paper-light-blue-300: #4fc3f7;\n    --paper-light-blue-400: #29b6f6;\n    --paper-light-blue-500: #03a9f4;\n    --paper-light-blue-600: #039be5;\n    --paper-light-blue-700: #0288d1;\n    --paper-light-blue-800: #0277bd;\n    --paper-light-blue-900: #01579b;\n    --paper-light-blue-a100: #80d8ff;\n    --paper-light-blue-a200: #40c4ff;\n    --paper-light-blue-a400: #00b0ff;\n    --paper-light-blue-a700: #0091ea;\n \n    --paper-cyan-50: #e0f7fa;\n    --paper-cyan-100: #b2ebf2;\n    --paper-cyan-200: #80deea;\n    --paper-cyan-300: #4dd0e1;\n    --paper-cyan-400: #26c6da;\n    --paper-cyan-500: #00bcd4;\n    --paper-cyan-600: #00acc1;\n    --paper-cyan-700: #0097a7;\n    --paper-cyan-800: #00838f;\n    --paper-cyan-900: #006064;\n    --paper-cyan-a100: #84ffff;\n    --paper-cyan-a200: #18ffff;\n    --paper-cyan-a400: #00e5ff;\n    --paper-cyan-a700: #00b8d4;\n \n    --paper-teal-50: #e0f2f1;\n    --paper-teal-100: #b2dfdb;\n    --paper-teal-200: #80cbc4;\n    --paper-teal-300: #4db6ac;\n    --paper-teal-400: #26a69a;\n    --paper-teal-500: #009688;\n    --paper-teal-600: #00897b;\n    --paper-teal-700: #00796b;\n    --paper-teal-800: #00695c;\n    --paper-teal-900: #004d40;\n    --paper-teal-a100: #a7ffeb;\n    --paper-teal-a200: #64ffda;\n    --paper-teal-a400: #1de9b6;\n    --paper-teal-a700: #00bfa5;\n \n    --paper-green-50: #e8f5e9;\n    --paper-green-100: #c8e6c9;\n    --paper-green-200: #a5d6a7;\n    --paper-green-300: #81c784;\n    --paper-green-400: #66bb6a;\n    --paper-green-500: #4caf50;\n    --paper-green-600: #43a047;\n    --paper-green-700: #388e3c;\n    --paper-green-800: #2e7d32;\n    --paper-green-900: #1b5e20;\n    --paper-green-a100: #b9f6ca;\n    --paper-green-a200: #69f0ae;\n    --paper-green-a400: #00e676;\n    --paper-green-a700: #00c853;\n \n    --paper-light-green-50: #f1f8e9;\n    --paper-light-green-100: #dcedc8;\n    --paper-light-green-200: #c5e1a5;\n    --paper-light-green-300: #aed581;\n    --paper-light-green-400: #9ccc65;\n    --paper-light-green-500: #8bc34a;\n    --paper-light-green-600: #7cb342;\n    --paper-light-green-700: #689f38;\n    --paper-light-green-800: #558b2f;\n    --paper-light-green-900: #33691e;\n    --paper-light-green-a100: #ccff90;\n    --paper-light-green-a200: #b2ff59;\n    --paper-light-green-a400: #76ff03;\n    --paper-light-green-a700: #64dd17;\n \n    --paper-lime-50: #f9fbe7;\n    --paper-lime-100: #f0f4c3;\n    --paper-lime-200: #e6ee9c;\n    --paper-lime-300: #dce775;\n    --paper-lime-400: #d4e157;\n    --paper-lime-500: #cddc39;\n    --paper-lime-600: #c0ca33;\n    --paper-lime-700: #afb42b;\n    --paper-lime-800: #9e9d24;\n    --paper-lime-900: #827717;\n    --paper-lime-a100: #f4ff81;\n    --paper-lime-a200: #eeff41;\n    --paper-lime-a400: #c6ff00;\n    --paper-lime-a700: #aeea00;\n \n    --paper-yellow-50: #fffde7;\n    --paper-yellow-100: #fff9c4;\n    --paper-yellow-200: #fff59d;\n    --paper-yellow-300: #fff176;\n    --paper-yellow-400: #ffee58;\n    --paper-yellow-500: #ffeb3b;\n    --paper-yellow-600: #fdd835;\n    --paper-yellow-700: #fbc02d;\n    --paper-yellow-800: #f9a825;\n    --paper-yellow-900: #f57f17;\n    --paper-yellow-a100: #ffff8d;\n    --paper-yellow-a200: #ffff00;\n    --paper-yellow-a400: #ffea00;\n    --paper-yellow-a700: #ffd600;\n \n    --paper-amber-50: #fff8e1;\n    --paper-amber-100: #ffecb3;\n    --paper-amber-200: #ffe082;\n    --paper-amber-300: #ffd54f;\n    --paper-amber-400: #ffca28;\n    --paper-amber-500: #ffc107;\n    --paper-amber-600: #ffb300;\n    --paper-amber-700: #ffa000;\n    --paper-amber-800: #ff8f00;\n    --paper-amber-900: #ff6f00;\n    --paper-amber-a100: #ffe57f;\n    --paper-amber-a200: #ffd740;\n    --paper-amber-a400: #ffc400;\n    --paper-amber-a700: #ffab00;\n \n    --paper-orange-50: #fff3e0;\n    --paper-orange-100: #ffe0b2;\n    --paper-orange-200: #ffcc80;\n    --paper-orange-300: #ffb74d;\n    --paper-orange-400: #ffa726;\n    --paper-orange-500: #ff9800;\n    --paper-orange-600: #fb8c00;\n    --paper-orange-700: #f57c00;\n    --paper-orange-800: #ef6c00;\n    --paper-orange-900: #e65100;\n    --paper-orange-a100: #ffd180;\n    --paper-orange-a200: #ffab40;\n    --paper-orange-a400: #ff9100;\n    --paper-orange-a700: #ff6500;\n \n    --paper-deep-orange-50: #fbe9e7;\n    --paper-deep-orange-100: #ffccbc;\n    --paper-deep-orange-200: #ffab91;\n    --paper-deep-orange-300: #ff8a65;\n    --paper-deep-orange-400: #ff7043;\n    --paper-deep-orange-500: #ff5722;\n    --paper-deep-orange-600: #f4511e;\n    --paper-deep-orange-700: #e64a19;\n    --paper-deep-orange-800: #d84315;\n    --paper-deep-orange-900: #bf360c;\n    --paper-deep-orange-a100: #ff9e80;\n    --paper-deep-orange-a200: #ff6e40;\n    --paper-deep-orange-a400: #ff3d00;\n    --paper-deep-orange-a700: #dd2c00;\n \n    --paper-brown-50: #efebe9;\n    --paper-brown-100: #d7ccc8;\n    --paper-brown-200: #bcaaa4;\n    --paper-brown-300: #a1887f;\n    --paper-brown-400: #8d6e63;\n    --paper-brown-500: #795548;\n    --paper-brown-600: #6d4c41;\n    --paper-brown-700: #5d4037;\n    --paper-brown-800: #4e342e;\n    --paper-brown-900: #3e2723;\n \n    --paper-grey-50: #fafafa;\n    --paper-grey-100: #f5f5f5;\n    --paper-grey-200: #eeeeee;\n    --paper-grey-300: #e0e0e0;\n    --paper-grey-400: #bdbdbd;\n    --paper-grey-500: #9e9e9e;\n    --paper-grey-600: #757575;\n    --paper-grey-700: #616161;\n    --paper-grey-800: #424242;\n    --paper-grey-900: #212121;\n \n    --paper-blue-grey-50: #eceff1;\n    --paper-blue-grey-100: #cfd8dc;\n    --paper-blue-grey-200: #b0bec5;\n    --paper-blue-grey-300: #90a4ae;\n    --paper-blue-grey-400: #78909c;\n    --paper-blue-grey-500: #607d8b;\n    --paper-blue-grey-600: #546e7a;\n    --paper-blue-grey-700: #455a64;\n    --paper-blue-grey-800: #37474f;\n    --paper-blue-grey-900: #263238;\n\n    /* opacity for dark text on a light background */\n    --dark-divider-opacity: 0.12;\n    --dark-disabled-opacity: 0.38; /* or hint text or icon */\n    --dark-secondary-opacity: 0.54;\n    --dark-primary-opacity: 0.87;\n\n    /* opacity for light text on a dark background */\n    --light-divider-opacity: 0.12;\n    --light-disabled-opacity: 0.3; /* or hint text or icon */\n    --light-secondary-opacity: 0.7;\n    --light-primary-opacity: 1.0;\n\n  }\n\n</style>\n\n\n\n\n<style is=\"custom-style\">\n\n  :root {\n    /*\n     * You can use these generic variables in your elements for easy theming.\n     * For example, if all your elements use `--primary-text-color` as its main\n     * color, then switching from a light to a dark theme is just a matter of\n     * changing the value of `--primary-text-color` in your application.\n     */\n    --primary-text-color: var(--light-theme-text-color);\n    --primary-background-color: var(--light-theme-background-color);\n    --secondary-text-color: var(--light-theme-secondary-color);\n    --disabled-text-color: var(--light-theme-disabled-color);\n    --divider-color: var(--light-theme-divider-color);\n    --error-color: var(--paper-deep-orange-a700);\n\n    /*\n     * Primary and accent colors. Also see color.html for more colors.\n     */\n    --primary-color: var(--paper-indigo-500);\n    --light-primary-color: var(--paper-indigo-100);\n    --dark-primary-color: var(--paper-indigo-700);\n\n    --accent-color: var(--paper-pink-a200);\n    --light-accent-color: var(--paper-pink-a100);\n    --dark-accent-color: var(--paper-pink-a400);\n\n\n    /*\n     * Material Design Light background theme\n     */\n    --light-theme-background-color: #ffffff;\n    --light-theme-base-color: #000000;\n    --light-theme-text-color: var(--paper-grey-900);\n    --light-theme-secondary-color: #737373;  /* for secondary text and icons */\n    --light-theme-disabled-color: #9b9b9b;  /* disabled/hint text */\n    --light-theme-divider-color: #dbdbdb;\n\n    /*\n     * Material Design Dark background theme\n     */\n    --dark-theme-background-color: var(--paper-grey-900);\n    --dark-theme-base-color: #ffffff;\n    --dark-theme-text-color: #ffffff;\n    --dark-theme-secondary-color: #bcbcbc;  /* for secondary text and icons */\n    --dark-theme-disabled-color: #646464;  /* disabled/hint text */\n    --dark-theme-divider-color: #3c3c3c;\n\n    /*\n     * Deprecated values because of their confusing names.\n     */\n    --text-primary-color: var(--dark-theme-text-color);\n    --default-primary-color: var(--primary-color);\n\n  }\n\n</style>\n\n\n\n\n\n\n\n\n<script>//~~WEBPATH~~/iron-meta/iron-meta.html.js\n(function(){var a={},b={},c=null;Polymer.IronMeta=function(a){if(a)for(var b in a)switch(b){case \"type\":case \"key\":case \"value\":this[b]=a[b]}};Polymer.IronMeta=Polymer({is:\"iron-meta\",properties:{type:{type:String,value:\"default\",observer:\"_typeChanged\"},key:{type:String,observer:\"_keyChanged\"},value:{type:Object,notify:!0,observer:\"_valueChanged\"},self:{type:Boolean,observer:\"_selfChanged\"},list:{type:Array,notify:!0}},hostAttributes:{hidden:!0},factoryImpl:function(a){if(a)for(var b in a)switch(b){case \"type\":case \"key\":case \"value\":this[b]=\na[b]}},created:function(){this._metaDatas=a;this._metaArrays=b},_keyChanged:function(a,b){this._resetRegistration(b)},_valueChanged:function(){this._resetRegistration(this.key)},_selfChanged:function(a){a&&(this.value=this)},_typeChanged:function(c){this._unregisterKey(this.key);a[c]||(a[c]={});this._metaData=a[c];b[c]||(b[c]=[]);this.list=b[c];this._registerKeyValue(this.key,this.value)},byKey:function(a){return this._metaData&&this._metaData[a]},_resetRegistration:function(a){this._unregisterKey(a);\nthis._registerKeyValue(this.key,this.value)},_unregisterKey:function(a){this._unregister(a,this._metaData,this.list)},_registerKeyValue:function(a,b){this._register(a,b,this._metaData,this.list)},_register:function(a,b,c,g){a&&c&&void 0!==b&&(c[a]=b,g.push(b))},_unregister:function(a,b,c){if(a&&b&&a in b){var d=b[a];delete b[a];this.arrayDelete(c,d)}}});Polymer.IronMeta.getIronMeta=function(){null===c&&(c=new Polymer.IronMeta);return c};Polymer.IronMetaQuery=function(a){if(a)for(var b in a)switch(b){case \"type\":case \"key\":this[b]=\na[b]}};Polymer.IronMetaQuery.prototype._setValue=function(){};Polymer.IronMetaQuery=Polymer({is:\"iron-meta-query\",properties:{type:{type:String,value:\"default\",observer:\"_typeChanged\"},key:{type:String,observer:\"_keyChanged\"},value:{type:Object,notify:!0,readOnly:!0},list:{type:Array,notify:!0}},factoryImpl:function(a){if(a)for(var b in a)switch(b){case \"type\":case \"key\":this[b]=a[b]}},created:function(){this._metaDatas=a;this._metaArrays=b},_keyChanged:function(a){this._setValue(this._metaData&&\nthis._metaData[a])},_typeChanged:function(c){this._metaData=a[c];this.list=b[c];this.key&&this._keyChanged(this.key)},byKey:function(a){return this._metaData&&this._metaData[a]}})})();\n</script>\n\n\n<script>//~~WEBPATH~~/iron-validatable-behavior/iron-validatable-behavior.html.js\nPolymer.IronValidatableBehaviorMeta=null;\nPolymer.IronValidatableBehavior={properties:{validator:{type:String},invalid:{notify:!0,reflectToAttribute:!0,type:Boolean,value:!1},_validatorMeta:{type:Object},validatorType:{type:String,value:\"validator\"},_validator:{type:Object,computed:\"__computeValidator(validator)\"}},observers:[\"_invalidChanged(invalid)\"],registered:function(){Polymer.IronValidatableBehaviorMeta=new Polymer.IronMeta({type:\"validator\"})},_invalidChanged:function(){this.invalid?this.setAttribute(\"aria-invalid\",\"true\"):this.removeAttribute(\"aria-invalid\")},\nhasValidator:function(){return null!=this._validator},validate:function(a){this.invalid=!this._getValidity(a);return!this.invalid},_getValidity:function(a){return this.hasValidator()?this._validator.validate(a):!0},__computeValidator:function(){return Polymer.IronValidatableBehaviorMeta&&Polymer.IronValidatableBehaviorMeta.byKey(this.validator)}};\n</script>\n\n\n\n<script>//~~WEBPATH~~/iron-form-element-behavior/iron-form-element-behavior.html.js\nPolymer.IronFormElementBehavior={properties:{name:{type:String},value:{notify:!0,type:String},required:{type:Boolean,value:!1},_parentForm:{type:Object}},attached:function(){this.fire(\"iron-form-element-register\")},detached:function(){this._parentForm&&this._parentForm.fire(\"iron-form-element-unregister\",{target:this})}};\n</script>\n\n\n<script>//~~WEBPATH~~/iron-checked-element-behavior/iron-checked-element-behavior.html.js\nPolymer.IronCheckedElementBehaviorImpl={properties:{checked:{type:Boolean,value:!1,reflectToAttribute:!0,notify:!0,observer:\"_checkedChanged\"},toggles:{type:Boolean,value:!0,reflectToAttribute:!0},value:{type:String,value:\"on\",observer:\"_valueChanged\"}},observers:[\"_requiredChanged(required)\"],created:function(){this._hasIronCheckedElementBehavior=!0},_getValidity:function(){return this.disabled||!this.required||this.required&&this.checked},_requiredChanged:function(){this.required?this.setAttribute(\"aria-required\",\n\"true\"):this.removeAttribute(\"aria-required\")},_checkedChanged:function(){this.active=this.checked;this.fire(\"iron-change\")},_valueChanged:function(){if(void 0===this.value||null===this.value)this.value=\"on\"}};Polymer.IronCheckedElementBehavior=[Polymer.IronFormElementBehavior,Polymer.IronValidatableBehavior,Polymer.IronCheckedElementBehaviorImpl];\n</script>\n\n\n\n\n\n<script>//~~WEBPATH~~/iron-a11y-keys-behavior/iron-a11y-keys-behavior.html.js\n(function(){function a(a,b){var c=\"\";if(a)if(a=a.toLowerCase(),\" \"===a||n.test(a))c=\"space\";else if(q.test(a))c=\"esc\";else if(1==a.length){if(!b||k.test(a))c=a}else c=m.test(a)?a.replace(\"arrow\",\"\"):\"multiply\"==a?\"*\":a;return c}function b(b,c){var d=b.hasModifiers;if(c.key)d=a(c.key,d);else if(c.detail&&c.detail.key)d=a(c.detail.key,d);else{var d=c.keyIdentifier,g=\"\";d&&(d in e?g=e[d]:l.test(d)?(d=parseInt(d.replace(\"U+\",\"0x\"),16),g=String.fromCharCode(d).toLowerCase()):g=d.toLowerCase());(d=g)||\n(d=c.keyCode,g=\"\",Number(d)&&(g=65<=d&&90>=d?String.fromCharCode(32+d):112<=d&&123>=d?\"f\"+(d-112):48<=d&&57>=d?String(d-48):96<=d&&105>=d?String(d-96):f[d]),d=g);d=d||\"\"}return d===b.key&&(!b.hasModifiers||!!c.shiftKey===!!b.shiftKey&&!!c.ctrlKey===!!b.ctrlKey&&!!c.altKey===!!b.altKey&&!!c.metaKey===!!b.metaKey)}function c(a){return 1===a.length?{combo:a,key:a,event:\"keydown\"}:a.split(\"+\").reduce(function(a,b){var c=b.split(\":\");b=c[0];c=c[1];b in g?(a[g[b]]=!0,a.hasModifiers=!0):(a.key=b,a.event=\nc||\"keydown\");return a},{combo:a.split(\":\").shift()})}function d(a){return a.trim().split(\" \").map(function(a){return c(a)})}var e={\"U+0008\":\"backspace\",\"U+0009\":\"tab\",\"U+001B\":\"esc\",\"U+0020\":\"space\",\"U+007F\":\"del\"},f={8:\"backspace\",9:\"tab\",13:\"enter\",27:\"esc\",33:\"pageup\",34:\"pagedown\",35:\"end\",36:\"home\",32:\"space\",37:\"left\",38:\"up\",39:\"right\",40:\"down\",46:\"del\",106:\"*\"},g={shift:\"shiftKey\",ctrl:\"ctrlKey\",alt:\"altKey\",meta:\"metaKey\"},k=/[a-z0-9*]/,l=/U\\+/,m=/^arrow/,n=/^space(bar)?/,q=/^escape$/;\nPolymer.IronA11yKeysBehavior={properties:{keyEventTarget:{type:Object,value:function(){return this}},stopKeyboardEventPropagation:{type:Boolean,value:!1},_boundKeyHandlers:{type:Array,value:function(){return[]}},_imperativeKeyBindings:{type:Object,value:function(){return{}}}},observers:[\"_resetKeyEventListeners(keyEventTarget, _boundKeyHandlers)\"],keyBindings:{},registered:function(){this._prepKeyBindings()},attached:function(){this._listenKeyEventListeners()},detached:function(){this._unlistenKeyEventListeners()},\naddOwnKeyBinding:function(a,b){this._imperativeKeyBindings[a]=b;this._prepKeyBindings();this._resetKeyEventListeners()},removeOwnKeyBindings:function(){this._imperativeKeyBindings={};this._prepKeyBindings();this._resetKeyEventListeners()},keyboardEventMatchesKeys:function(a,c){c=d(c);for(var e=0;e<c.length;++e)if(b(c[e],a))return!0;return!1},_collectKeyBindings:function(){var a=this.behaviors.map(function(a){return a.keyBindings});-1===a.indexOf(this.keyBindings)&&a.push(this.keyBindings);return a},\n_prepKeyBindings:function(){this._keyBindings={};this._collectKeyBindings().forEach(function(a){for(var b in a)this._addKeyBinding(b,a[b])},this);for(var a in this._imperativeKeyBindings)this._addKeyBinding(a,this._imperativeKeyBindings[a]);for(var b in this._keyBindings)this._keyBindings[b].sort(function(a,b){a=a[0].hasModifiers;return a===b[0].hasModifiers?0:a?-1:1})},_addKeyBinding:function(a,b){d(a).forEach(function(a){this._keyBindings[a.event]=this._keyBindings[a.event]||[];this._keyBindings[a.event].push([a,\nb])},this)},_resetKeyEventListeners:function(){this._unlistenKeyEventListeners();this.isAttached&&this._listenKeyEventListeners()},_listenKeyEventListeners:function(){this.keyEventTarget&&Object.keys(this._keyBindings).forEach(function(a){var b=this._onKeyBindingEvent.bind(this,this._keyBindings[a]);this._boundKeyHandlers.push([this.keyEventTarget,a,b]);this.keyEventTarget.addEventListener(a,b)},this)},_unlistenKeyEventListeners:function(){for(var a,b,c;this._boundKeyHandlers.length;)a=this._boundKeyHandlers.pop(),\nb=a[0],c=a[1],a=a[2],b.removeEventListener(c,a)},_onKeyBindingEvent:function(a,c){this.stopKeyboardEventPropagation&&c.stopPropagation();if(!c.defaultPrevented)for(var d=0;d<a.length;d++){var e=a[d][0],f=a[d][1];if(b(e,c)&&(this._triggerKeyHandler(e,f,c),c.defaultPrevented))break}},_triggerKeyHandler:function(a,b,c){var d=Object.create(a);d.keyboardEvent=c;a=new CustomEvent(a.event,{detail:d,cancelable:!0});this[b].call(this,a);a.defaultPrevented&&c.preventDefault()}}})();\n</script>\n\n\n\n<script>//~~WEBPATH~~/iron-behaviors/iron-control-state.html.js\nPolymer.IronControlState={properties:{focused:{type:Boolean,value:!1,notify:!0,readOnly:!0,reflectToAttribute:!0},disabled:{type:Boolean,value:!1,notify:!0,observer:\"_disabledChanged\",reflectToAttribute:!0},_oldTabIndex:{type:Number},_boundFocusBlurHandler:{type:Function,value:function(){return this._focusBlurHandler.bind(this)}}},observers:[\"_changedControlState(focused, disabled)\"],ready:function(){this.addEventListener(\"focus\",this._boundFocusBlurHandler,!0);this.addEventListener(\"blur\",this._boundFocusBlurHandler,\n!0)},_focusBlurHandler:function(a){if(a.target===this)this._setFocused(\"focus\"===a.type);else if(!this.shadowRoot){var b=Polymer.dom(a).localTarget;this.isLightDescendant(b)||this.fire(a.type,{sourceEvent:a},{node:this,bubbles:a.bubbles,cancelable:a.cancelable})}},_disabledChanged:function(a){this.setAttribute(\"aria-disabled\",a?\"true\":\"false\");this.style.pointerEvents=a?\"none\":\"\";a?(this._oldTabIndex=this.tabIndex,this._setFocused(!1),this.tabIndex=-1,this.blur()):void 0!==this._oldTabIndex&&(this.tabIndex=\nthis._oldTabIndex)},_changedControlState:function(){this._controlStateChanged&&this._controlStateChanged()}};\n</script>\n\n\n<script>//~~WEBPATH~~/iron-behaviors/iron-button-state.html.js\nPolymer.IronButtonStateImpl={properties:{pressed:{type:Boolean,readOnly:!0,value:!1,reflectToAttribute:!0,observer:\"_pressedChanged\"},toggles:{type:Boolean,value:!1,reflectToAttribute:!0},active:{type:Boolean,value:!1,notify:!0,reflectToAttribute:!0},pointerDown:{type:Boolean,readOnly:!0,value:!1},receivedFocusFromKeyboard:{type:Boolean,readOnly:!0},ariaActiveAttribute:{type:String,value:\"aria-pressed\",observer:\"_ariaActiveAttributeChanged\"}},listeners:{down:\"_downHandler\",up:\"_upHandler\",tap:\"_tapHandler\"},\nobservers:[\"_detectKeyboardFocus(focused)\",\"_activeChanged(active, ariaActiveAttribute)\"],keyBindings:{\"enter:keydown\":\"_asyncClick\",\"space:keydown\":\"_spaceKeyDownHandler\",\"space:keyup\":\"_spaceKeyUpHandler\"},_mouseEventRe:/^mouse/,_tapHandler:function(){this.toggles?this._userActivate(!this.active):this.active=!1},_detectKeyboardFocus:function(a){this._setReceivedFocusFromKeyboard(!this.pointerDown&&a)},_userActivate:function(a){this.active!==a&&(this.active=a,this.fire(\"change\"))},_downHandler:function(){this._setPointerDown(!0);\nthis._setPressed(!0);this._setReceivedFocusFromKeyboard(!1)},_upHandler:function(){this._setPointerDown(!1);this._setPressed(!1)},_spaceKeyDownHandler:function(a){a=a.detail.keyboardEvent;var b=Polymer.dom(a).localTarget;this.isLightDescendant(b)||(a.preventDefault(),a.stopImmediatePropagation(),this._setPressed(!0))},_spaceKeyUpHandler:function(a){a=Polymer.dom(a.detail.keyboardEvent).localTarget;this.isLightDescendant(a)||(this.pressed&&this._asyncClick(),this._setPressed(!1))},_asyncClick:function(){this.async(function(){this.click()},\n1)},_pressedChanged:function(){this._changedButtonState()},_ariaActiveAttributeChanged:function(a,b){b&&b!=a&&this.hasAttribute(b)&&this.removeAttribute(b)},_activeChanged:function(a){this.toggles?this.setAttribute(this.ariaActiveAttribute,a?\"true\":\"false\"):this.removeAttribute(this.ariaActiveAttribute);this._changedButtonState()},_controlStateChanged:function(){this.disabled?this._setPressed(!1):this._changedButtonState()},_changedButtonState:function(){this._buttonStateChanged&&this._buttonStateChanged()}};\nPolymer.IronButtonState=[Polymer.IronA11yKeysBehavior,Polymer.IronButtonStateImpl];\n</script>\n\n\n\n\n\n\n\n<dom-module id=\"paper-ripple\">\n\n  \n\n  <template>\n    <style>\n      :host {\n        display: block;\n        position: absolute;\n        border-radius: inherit;\n        overflow: hidden;\n        top: 0;\n        left: 0;\n        right: 0;\n        bottom: 0;\n\n        /* See PolymerElements/paper-behaviors/issues/34. On non-Chrome browsers,\n         * creating a node (with a position:absolute) in the middle of an event\n         * handler \"interrupts\" that event handler (which happens when the\n         * ripple is created on demand) */\n        pointer-events: none;\n      }\n\n      :host([animating]) {\n        /* This resolves a rendering issue in Chrome (as of 40) where the\n           ripple is not properly clipped by its parent (which may have\n           rounded corners). See: http://jsbin.com/temexa/4\n\n           Note: We only apply this style conditionally. Otherwise, the browser\n           will create a new compositing layer for every ripple element on the\n           page, and that would be bad. */\n        -webkit-transform: translate(0, 0);\n        transform: translate3d(0, 0, 0);\n      }\n\n      #background,\n      #waves,\n      .wave-container,\n      .wave {\n        pointer-events: none;\n        position: absolute;\n        top: 0;\n        left: 0;\n        width: 100%;\n        height: 100%;\n      }\n\n      #background,\n      .wave {\n        opacity: 0;\n      }\n\n      #waves,\n      .wave {\n        overflow: hidden;\n      }\n\n      .wave-container,\n      .wave {\n        border-radius: 50%;\n      }\n\n      :host(.circle) #background,\n      :host(.circle) #waves {\n        border-radius: 50%;\n      }\n\n      :host(.circle) .wave-container {\n        overflow: hidden;\n      }\n    </style>\n\n    <div id=\"background\"></div>\n    <div id=\"waves\"></div>\n  </template>\n</dom-module>\n<script>//~~WEBPATH~~/paper-ripple/paper-ripple.html.js\n(function(){function a(a){this.element=a;this.width=this.boundingRect.width;this.height=this.boundingRect.height;this.size=Math.max(this.width,this.height)}function b(a){this.element=a;this.color=window.getComputedStyle(a).color;this.wave=document.createElement(\"div\");this.waveContainer=document.createElement(\"div\");this.wave.style.backgroundColor=this.color;this.wave.classList.add(\"wave\");this.waveContainer.classList.add(\"wave-container\");Polymer.dom(this.waveContainer).appendChild(this.wave);this.resetInteractionState()}\nvar c={distance:function(a,b,c,g){a-=c;b-=g;return Math.sqrt(a*a+b*b)},now:window.performance&&window.performance.now?window.performance.now.bind(window.performance):Date.now};a.prototype={get boundingRect(){return this.element.getBoundingClientRect()},furthestCornerDistanceFrom:function(a,b){var d=c.distance(a,b,0,0),e=c.distance(a,b,this.width,0),k=c.distance(a,b,0,this.height);a=c.distance(a,b,this.width,this.height);return Math.max(d,e,k,a)}};b.MAX_RADIUS=300;b.prototype={get recenters(){return this.element.recenters},\nget center(){return this.element.center},get mouseDownElapsed(){if(!this.mouseDownStart)return 0;var a=c.now()-this.mouseDownStart;this.mouseUpStart&&(a-=this.mouseUpElapsed);return a},get mouseUpElapsed(){return this.mouseUpStart?c.now()-this.mouseUpStart:0},get mouseDownElapsedSeconds(){return this.mouseDownElapsed/1E3},get mouseUpElapsedSeconds(){return this.mouseUpElapsed/1E3},get mouseInteractionSeconds(){return this.mouseDownElapsedSeconds+this.mouseUpElapsedSeconds},get initialOpacity(){return this.element.initialOpacity},\nget opacityDecayVelocity(){return this.element.opacityDecayVelocity},get radius(){var a=1.1*Math.min(Math.sqrt(this.containerMetrics.width*this.containerMetrics.width+this.containerMetrics.height*this.containerMetrics.height),b.MAX_RADIUS)+5;return Math.abs(a*(1-Math.pow(80,-(this.mouseInteractionSeconds/(1.1-a/b.MAX_RADIUS*.2)))))},get opacity(){return this.mouseUpStart?Math.max(0,this.initialOpacity-this.mouseUpElapsedSeconds*this.opacityDecayVelocity):this.initialOpacity},get outerOpacity(){return Math.max(0,\nMath.min(.3*this.mouseUpElapsedSeconds,this.opacity))},get isOpacityFullyDecayed(){return.01>this.opacity&&this.radius>=Math.min(this.maxRadius,b.MAX_RADIUS)},get isRestingAtMaxRadius(){return this.opacity>=this.initialOpacity&&this.radius>=Math.min(this.maxRadius,b.MAX_RADIUS)},get isAnimationComplete(){return this.mouseUpStart?this.isOpacityFullyDecayed:this.isRestingAtMaxRadius},get translationFraction(){return Math.min(1,this.radius/this.containerMetrics.size*2/Math.sqrt(2))},get xNow(){return this.xEnd?\nthis.xStart+this.translationFraction*(this.xEnd-this.xStart):this.xStart},get yNow(){return this.yEnd?this.yStart+this.translationFraction*(this.yEnd-this.yStart):this.yStart},get isMouseDown(){return this.mouseDownStart&&!this.mouseUpStart},resetInteractionState:function(){this.slideDistance=this.yEnd=this.xEnd=this.yStart=this.xStart=this.mouseUpStart=this.mouseDownStart=this.maxRadius=0;this.containerMetrics=new a(this.element)},draw:function(){this.wave.style.opacity=this.opacity;var a=this.radius/\n(this.containerMetrics.size/2);var b=this.xNow-this.containerMetrics.width/2;var c=this.yNow-this.containerMetrics.height/2;this.waveContainer.style.webkitTransform=\"translate(\"+b+\"px, \"+c+\"px)\";this.waveContainer.style.transform=\"translate3d(\"+b+\"px, \"+c+\"px, 0)\";this.wave.style.webkitTransform=\"scale(\"+a+\",\"+a+\")\";this.wave.style.transform=\"scale3d(\"+a+\",\"+a+\",1)\"},downAction:function(a){var b=this.containerMetrics.width/2,d=this.containerMetrics.height/2;this.resetInteractionState();this.mouseDownStart=\nc.now();this.center?(this.xStart=b,this.yStart=d,this.slideDistance=c.distance(this.xStart,this.yStart,this.xEnd,this.yEnd)):(this.xStart=a?a.detail.x-this.containerMetrics.boundingRect.left:this.containerMetrics.width/2,this.yStart=a?a.detail.y-this.containerMetrics.boundingRect.top:this.containerMetrics.height/2);this.recenters&&(this.xEnd=b,this.yEnd=d,this.slideDistance=c.distance(this.xStart,this.yStart,this.xEnd,this.yEnd));this.maxRadius=this.containerMetrics.furthestCornerDistanceFrom(this.xStart,\nthis.yStart);this.waveContainer.style.top=(this.containerMetrics.height-this.containerMetrics.size)/2+\"px\";this.waveContainer.style.left=(this.containerMetrics.width-this.containerMetrics.size)/2+\"px\";this.waveContainer.style.width=this.containerMetrics.size+\"px\";this.waveContainer.style.height=this.containerMetrics.size+\"px\"},upAction:function(){this.isMouseDown&&(this.mouseUpStart=c.now())},remove:function(){Polymer.dom(this.waveContainer.parentNode).removeChild(this.waveContainer)}};Polymer({is:\"paper-ripple\",\nbehaviors:[Polymer.IronA11yKeysBehavior],properties:{initialOpacity:{type:Number,value:.25},opacityDecayVelocity:{type:Number,value:.8},recenters:{type:Boolean,value:!1},center:{type:Boolean,value:!1},ripples:{type:Array,value:function(){return[]}},animating:{type:Boolean,readOnly:!0,reflectToAttribute:!0,value:!1},holdDown:{type:Boolean,value:!1,observer:\"_holdDownChanged\"},noink:{type:Boolean,value:!1},_animating:{type:Boolean},_boundAnimate:{type:Function,value:function(){return this.animate.bind(this)}}},\nget target(){var a=Polymer.dom(this).getOwnerRoot();return 11==this.parentNode.nodeType?a.host:this.parentNode},keyBindings:{\"enter:keydown\":\"_onEnterKeydown\",\"space:keydown\":\"_onSpaceKeydown\",\"space:keyup\":\"_onSpaceKeyup\"},attached:function(){this.keyEventTarget=this.target;this.listen(this.target,\"up\",\"uiUpAction\");this.listen(this.target,\"down\",\"uiDownAction\")},detached:function(){this.unlisten(this.target,\"up\",\"uiUpAction\");this.unlisten(this.target,\"down\",\"uiDownAction\")},get shouldKeepAnimating(){for(var a=\n0;a<this.ripples.length;++a)if(!this.ripples[a].isAnimationComplete)return!0;return!1},simulatedRipple:function(){this.downAction(null);this.async(function(){this.upAction()},1)},uiDownAction:function(a){this.noink||this.downAction(a)},downAction:function(a){this.holdDown&&0<this.ripples.length||(this.addRipple().downAction(a),this._animating||this.animate())},uiUpAction:function(a){this.noink||this.upAction(a)},upAction:function(a){this.holdDown||(this.ripples.forEach(function(b){b.upAction(a)}),\nthis.animate())},onAnimationComplete:function(){this._animating=!1;this.$.background.style.backgroundColor=null;this.fire(\"transitionend\")},addRipple:function(){var a=new b(this);Polymer.dom(this.$.waves).appendChild(a.waveContainer);this.$.background.style.backgroundColor=a.color;this.ripples.push(a);this._setAnimating(!0);return a},removeRipple:function(a){var b=this.ripples.indexOf(a);0>b||(this.ripples.splice(b,1),a.remove(),this.ripples.length||this._setAnimating(!1))},animate:function(){var a;\nthis._animating=!0;for(a=0;a<this.ripples.length;++a){var b=this.ripples[a];b.draw();this.$.background.style.opacity=b.outerOpacity;b.isOpacityFullyDecayed&&!b.isRestingAtMaxRadius&&this.removeRipple(b)}if(this.shouldKeepAnimating||0!==this.ripples.length)window.requestAnimationFrame(this._boundAnimate);else this.onAnimationComplete()},_onEnterKeydown:function(){this.uiDownAction();this.async(this.uiUpAction,1)},_onSpaceKeydown:function(){this.uiDownAction()},_onSpaceKeyup:function(){this.uiUpAction()},\n_holdDownChanged:function(a,b){void 0!==b&&(a?this.downAction():this.upAction())}})})();\n</script>\n\n\n<script>//~~WEBPATH~~/paper-behaviors/paper-ripple-behavior.html.js\nPolymer.PaperRippleBehavior={properties:{noink:{type:Boolean,observer:\"_noinkChanged\"},_rippleContainer:{type:Object}},_buttonStateChanged:function(){this.focused&&this.ensureRipple()},_downHandler:function(a){Polymer.IronButtonStateImpl._downHandler.call(this,a);this.pressed&&this.ensureRipple(a)},ensureRipple:function(a){if(!this.hasRipple()){this._ripple=this._createRipple();this._ripple.noink=this.noink;var b=this._rippleContainer||this.root;b&&Polymer.dom(b).appendChild(this._ripple);if(a){var b=\nPolymer.dom(this._rippleContainer||this),c=Polymer.dom(a).rootTarget;b.deepContains(c)&&this._ripple.uiDownAction(a)}}},getRipple:function(){this.ensureRipple();return this._ripple},hasRipple:function(){return!!this._ripple},_createRipple:function(){return document.createElement(\"paper-ripple\")},_noinkChanged:function(a){this.hasRipple()&&(this._ripple.noink=a)}};\n</script>\n\n\n<script>//~~WEBPATH~~/paper-behaviors/paper-inky-focus-behavior.html.js\nPolymer.PaperInkyFocusBehaviorImpl={observers:[\"_focusedChanged(receivedFocusFromKeyboard)\"],_focusedChanged:function(a){a&&this.ensureRipple();this.hasRipple()&&(this._ripple.holdDown=a)},_createRipple:function(){var a=Polymer.PaperRippleBehavior._createRipple();a.id=\"ink\";a.setAttribute(\"center\",\"\");a.classList.add(\"circle\");return a}};Polymer.PaperInkyFocusBehavior=[Polymer.IronButtonState,Polymer.IronControlState,Polymer.PaperRippleBehavior,Polymer.PaperInkyFocusBehaviorImpl];\n</script>\n\n\n<script>//~~WEBPATH~~/paper-behaviors/paper-checked-element-behavior.html.js\nPolymer.PaperCheckedElementBehaviorImpl={_checkedChanged:function(){Polymer.IronCheckedElementBehaviorImpl._checkedChanged.call(this);this.hasRipple()&&(this.checked?this._ripple.setAttribute(\"checked\",\"\"):this._ripple.removeAttribute(\"checked\"))},_buttonStateChanged:function(){Polymer.PaperRippleBehavior._buttonStateChanged.call(this);!this.disabled&&this.isAttached&&(this.checked=this.active)}};\nPolymer.PaperCheckedElementBehavior=[Polymer.PaperInkyFocusBehavior,Polymer.IronCheckedElementBehavior,Polymer.PaperCheckedElementBehaviorImpl];\n</script>\n\n\n\n\n<dom-module id=\"paper-checkbox\">\n  <template strip-whitespace>\n    <style>\n      :host {\n        display: inline-block;\n        white-space: nowrap;\n        cursor: pointer;\n        --calculated-paper-checkbox-size: var(--paper-checkbox-size, 18px);\n        /* -1px is a sentinel for the default and is replaced in `attached`. */\n        --calculated-paper-checkbox-ink-size: var(--paper-checkbox-ink-size, -1px);\n        @apply --paper-font-common-base;\n        line-height: 0;\n        -webkit-tap-highlight-color: transparent;\n      }\n\n      :host([hidden]) {\n        display: none !important;\n      }\n\n      :host(:focus) {\n        outline: none;\n      }\n\n      .hidden {\n        display: none;\n      }\n\n      #checkboxContainer {\n        display: inline-block;\n        position: relative;\n        width: var(--calculated-paper-checkbox-size);\n        height: var(--calculated-paper-checkbox-size);\n        min-width: var(--calculated-paper-checkbox-size);\n        margin: var(--paper-checkbox-margin, initial);\n        vertical-align: var(--paper-checkbox-vertical-align, middle);\n        background-color: var(--paper-checkbox-unchecked-background-color, transparent);\n      }\n\n      #ink {\n        position: absolute;\n\n        /* Center the ripple in the checkbox by negative offsetting it by\n         * (inkWidth - rippleWidth) / 2 */\n        top: calc(0px - (var(--calculated-paper-checkbox-ink-size) - var(--calculated-paper-checkbox-size)) / 2);\n        left: calc(0px - (var(--calculated-paper-checkbox-ink-size) - var(--calculated-paper-checkbox-size)) / 2);\n        width: var(--calculated-paper-checkbox-ink-size);\n        height: var(--calculated-paper-checkbox-ink-size);\n        color: var(--paper-checkbox-unchecked-ink-color, var(--primary-text-color));\n        opacity: 0.6;\n        pointer-events: none;\n      }\n\n      :host-context([dir=\"rtl\"]) #ink {\n        right: calc(0px - (var(--calculated-paper-checkbox-ink-size) - var(--calculated-paper-checkbox-size)) / 2);\n        left: auto;\n      }\n\n      #ink[checked] {\n        color: var(--paper-checkbox-checked-ink-color, var(--primary-color));\n      }\n\n      #checkbox {\n        position: relative;\n        box-sizing: border-box;\n        height: 100%;\n        border: solid 2px;\n        border-color: var(--paper-checkbox-unchecked-color, var(--primary-text-color));\n        border-radius: 2px;\n        pointer-events: none;\n        -webkit-transition: background-color 140ms, border-color 140ms;\n        transition: background-color 140ms, border-color 140ms;\n      }\n\n      /* checkbox checked animations */\n      #checkbox.checked #checkmark {\n        -webkit-animation: checkmark-expand 140ms ease-out forwards;\n        animation: checkmark-expand 140ms ease-out forwards;\n      }\n\n      @-webkit-keyframes checkmark-expand {\n        0% {\n          -webkit-transform: scale(0, 0) rotate(45deg);\n        }\n        100% {\n          -webkit-transform: scale(1, 1) rotate(45deg);\n        }\n      }\n\n      @keyframes checkmark-expand {\n        0% {\n          transform: scale(0, 0) rotate(45deg);\n        }\n        100% {\n          transform: scale(1, 1) rotate(45deg);\n        }\n      }\n\n      #checkbox.checked {\n        background-color: var(--paper-checkbox-checked-color, var(--primary-color));\n        border-color: var(--paper-checkbox-checked-color, var(--primary-color));\n      }\n\n      #checkmark {\n        position: absolute;\n        width: 36%;\n        height: 70%;\n        border-style: solid;\n        border-top: none;\n        border-left: none;\n        border-right-width: calc(2/15 * var(--calculated-paper-checkbox-size));\n        border-bottom-width: calc(2/15 * var(--calculated-paper-checkbox-size));\n        border-color: var(--paper-checkbox-checkmark-color, white);\n        -webkit-transform-origin: 97% 86%;\n        transform-origin: 97% 86%;\n        box-sizing: content-box; /* protect against page-level box-sizing */\n      }\n\n      :host-context([dir=\"rtl\"]) #checkmark {\n        -webkit-transform-origin: 50% 14%;\n        transform-origin: 50% 14%;\n      }\n\n      /* label */\n      #checkboxLabel {\n        position: relative;\n        display: inline-block;\n        vertical-align: middle;\n        padding-left: var(--paper-checkbox-label-spacing, 8px);\n        white-space: normal;\n        line-height: normal;\n        color: var(--paper-checkbox-label-color, var(--primary-text-color));\n        @apply --paper-checkbox-label;\n      }\n\n      :host([checked]) #checkboxLabel {\n        color: var(--paper-checkbox-label-checked-color, var(--paper-checkbox-label-color, var(--primary-text-color)));\n        @apply --paper-checkbox-label-checked;\n      }\n\n      :host-context([dir=\"rtl\"]) #checkboxLabel {\n        padding-right: var(--paper-checkbox-label-spacing, 8px);\n        padding-left: 0;\n      }\n\n      #checkboxLabel[hidden] {\n        display: none;\n      }\n\n      /* disabled state */\n\n      :host([disabled]) #checkbox {\n        opacity: 0.5;\n        border-color: var(--paper-checkbox-unchecked-color, var(--primary-text-color));\n      }\n\n      :host([disabled][checked]) #checkbox {\n        background-color: var(--paper-checkbox-unchecked-color, var(--primary-text-color));\n        opacity: 0.5;\n      }\n\n      :host([disabled]) #checkboxLabel  {\n        opacity: 0.65;\n      }\n\n      /* invalid state */\n      #checkbox.invalid:not(.checked) {\n        border-color: var(--paper-checkbox-error-color, var(--error-color));\n      }\n    </style>\n\n    <div id=\"checkboxContainer\">\n      <div id=\"checkbox\" class$=\"[[_computeCheckboxClass(checked, invalid)]]\">\n        <div id=\"checkmark\" class$=\"[[_computeCheckmarkClass(checked)]]\"></div>\n      </div>\n    </div>\n\n    <div id=\"checkboxLabel\"><slot></slot></div>\n  </template>\n\n  <script>//~~WEBPATH~~/paper-checkbox/paper-checkbox.html.js\nPolymer({is:\"paper-checkbox\",behaviors:[Polymer.PaperCheckedElementBehavior],hostAttributes:{role:\"checkbox\",\"aria-checked\":!1,tabindex:0},properties:{ariaActiveAttribute:{type:String,value:\"aria-checked\"}},attached:function(){Polymer.RenderStatus.afterNextRender(this,function(){if(\"-1px\"===this.getComputedStyleValue(\"--calculated-paper-checkbox-ink-size\").trim()){var a=parseFloat(this.getComputedStyleValue(\"--calculated-paper-checkbox-size\").trim()),b=Math.floor(8/3*a);b%2!==a%2&&b++;this.updateStyles({\"--paper-checkbox-ink-size\":b+\n\"px\"})}})},_computeCheckboxClass:function(a,b){var c=\"\";a&&(c+=\"checked \");b&&(c+=\"invalid\");return c},_computeCheckmarkClass:function(a){return a?\"\":\"hidden\"},_createRipple:function(){this._rippleContainer=this.$.checkboxContainer;return Polymer.PaperInkyFocusBehaviorImpl._createRipple.call(this)}});\n</script>\n</dom-module>\n\n\n\n\n\n\n\n\n\n\n\n\n<style>\n  /* IE 10 support for HTML5 hidden attr */\n  [hidden] {\n    display: none !important;\n  }\n</style>\n\n<style is=\"custom-style\">\n  :root {\n\n    --layout: {\n      display: -ms-flexbox;\n      display: -webkit-flex;\n      display: flex;\n    };\n\n    --layout-inline: {\n      display: -ms-inline-flexbox;\n      display: -webkit-inline-flex;\n      display: inline-flex;\n    };\n\n    --layout-horizontal: {\n      @apply(--layout);\n\n      -ms-flex-direction: row;\n      -webkit-flex-direction: row;\n      flex-direction: row;\n    };\n\n    --layout-horizontal-reverse: {\n      @apply(--layout);\n\n      -ms-flex-direction: row-reverse;\n      -webkit-flex-direction: row-reverse;\n      flex-direction: row-reverse;\n    };\n\n    --layout-vertical: {\n      @apply(--layout);\n\n      -ms-flex-direction: column;\n      -webkit-flex-direction: column;\n      flex-direction: column;\n    };\n\n    --layout-vertical-reverse: {\n      @apply(--layout);\n\n      -ms-flex-direction: column-reverse;\n      -webkit-flex-direction: column-reverse;\n      flex-direction: column-reverse;\n    };\n\n    --layout-wrap: {\n      -ms-flex-wrap: wrap;\n      -webkit-flex-wrap: wrap;\n      flex-wrap: wrap;\n    };\n\n    --layout-wrap-reverse: {\n      -ms-flex-wrap: wrap-reverse;\n      -webkit-flex-wrap: wrap-reverse;\n      flex-wrap: wrap-reverse;\n    };\n\n    --layout-flex-auto: {\n      -ms-flex: 1 1 auto;\n      -webkit-flex: 1 1 auto;\n      flex: 1 1 auto;\n    };\n\n    --layout-flex-none: {\n      -ms-flex: none;\n      -webkit-flex: none;\n      flex: none;\n    };\n\n    --layout-flex: {\n      -ms-flex: 1 1 0.000000001px;\n      -webkit-flex: 1;\n      flex: 1;\n      -webkit-flex-basis: 0.000000001px;\n      flex-basis: 0.000000001px;\n    };\n\n    --layout-flex-2: {\n      -ms-flex: 2;\n      -webkit-flex: 2;\n      flex: 2;\n    };\n\n    --layout-flex-3: {\n      -ms-flex: 3;\n      -webkit-flex: 3;\n      flex: 3;\n    };\n\n    --layout-flex-4: {\n      -ms-flex: 4;\n      -webkit-flex: 4;\n      flex: 4;\n    };\n\n    --layout-flex-5: {\n      -ms-flex: 5;\n      -webkit-flex: 5;\n      flex: 5;\n    };\n\n    --layout-flex-6: {\n      -ms-flex: 6;\n      -webkit-flex: 6;\n      flex: 6;\n    };\n\n    --layout-flex-7: {\n      -ms-flex: 7;\n      -webkit-flex: 7;\n      flex: 7;\n    };\n\n    --layout-flex-8: {\n      -ms-flex: 8;\n      -webkit-flex: 8;\n      flex: 8;\n    };\n\n    --layout-flex-9: {\n      -ms-flex: 9;\n      -webkit-flex: 9;\n      flex: 9;\n    };\n\n    --layout-flex-10: {\n      -ms-flex: 10;\n      -webkit-flex: 10;\n      flex: 10;\n    };\n\n    --layout-flex-11: {\n      -ms-flex: 11;\n      -webkit-flex: 11;\n      flex: 11;\n    };\n\n    --layout-flex-12: {\n      -ms-flex: 12;\n      -webkit-flex: 12;\n      flex: 12;\n    };\n\n    /* alignment in cross axis */\n\n    --layout-start: {\n      -ms-flex-align: start;\n      -webkit-align-items: flex-start;\n      align-items: flex-start;\n    };\n\n    --layout-center: {\n      -ms-flex-align: center;\n      -webkit-align-items: center;\n      align-items: center;\n    };\n\n    --layout-end: {\n      -ms-flex-align: end;\n      -webkit-align-items: flex-end;\n      align-items: flex-end;\n    };\n\n    /* alignment in main axis */\n\n    --layout-start-justified: {\n      -ms-flex-pack: start;\n      -webkit-justify-content: flex-start;\n      justify-content: flex-start;\n    };\n\n    --layout-center-justified: {\n      -ms-flex-pack: center;\n      -webkit-justify-content: center;\n      justify-content: center;\n    };\n\n    --layout-end-justified: {\n      -ms-flex-pack: end;\n      -webkit-justify-content: flex-end;\n      justify-content: flex-end;\n    };\n\n    --layout-around-justified: {\n      -ms-flex-pack: distribute;\n      -webkit-justify-content: space-around;\n      justify-content: space-around;\n    };\n\n    --layout-justified: {\n      -ms-flex-pack: justify;\n      -webkit-justify-content: space-between;\n      justify-content: space-between;\n    };\n\n    --layout-center-center: {\n      @apply(--layout-center);\n      @apply(--layout-center-justified);\n    };\n\n    /* self alignment */\n\n    --layout-self-start: {\n      -ms-align-self: flex-start;\n      -webkit-align-self: flex-start;\n      align-self: flex-start;\n    };\n\n    --layout-self-center: {\n      -ms-align-self: center;\n      -webkit-align-self: center;\n      align-self: center;\n    };\n\n    --layout-self-end: {\n      -ms-align-self: flex-end;\n      -webkit-align-self: flex-end;\n      align-self: flex-end;\n    };\n\n    --layout-self-stretch: {\n      -ms-align-self: stretch;\n      -webkit-align-self: stretch;\n      align-self: stretch;\n    };\n\n    /*******************************\n              Other Layout\n    *******************************/\n\n    --layout-block: {\n      display: block;\n    };\n\n    --layout-invisible: {\n      visibility: hidden !important;\n    };\n\n    --layout-relative: {\n      position: relative;\n    };\n\n    --layout-fit: {\n      position: absolute;\n      top: 0;\n      right: 0;\n      bottom: 0;\n      left: 0;\n    };\n\n    --layout-scroll: {\n      -webkit-overflow-scrolling: touch;\n      overflow: auto;\n    };\n\n    --layout-fullbleed: {\n      margin: 0;\n      height: 100vh;\n    };\n\n    /* fixed position */\n\n    --layout-fixed-top: {\n      position: fixed;\n      top: 0;\n      left: 0;\n      right: 0;\n    };\n\n    --layout-fixed-right: {\n      position: fixed;\n      top: 0;\n      right: 0;\n      bottom: 0;\n    };\n\n    --layout-fixed-bottom: {\n      position: fixed;\n      right: 0;\n      bottom: 0;\n      left: 0;\n    };\n\n    --layout-fixed-left: {\n      position: fixed;\n      top: 0;\n      bottom: 0;\n      left: 0;\n    };\n\n  }\n\n</style>\n\n\n\n\n<dom-module id=\"iron-icon\">\n  <template>\n    <style>\n      :host {\n        @apply(--layout-inline);\n        @apply(--layout-center-center);\n        position: relative;\n\n        vertical-align: middle;\n\n        fill: var(--iron-icon-fill-color, currentcolor);\n        stroke: var(--iron-icon-stroke-color, none);\n\n        width: var(--iron-icon-width, 24px);\n        height: var(--iron-icon-height, 24px);\n        @apply(--iron-icon);\n      }\n    </style>\n  </template>\n\n  <script>//~~WEBPATH~~/iron-icon/iron-icon.html.js\nPolymer({is:\"iron-icon\",properties:{icon:{type:String},theme:{type:String},src:{type:String},_meta:{value:Polymer.Base.create(\"iron-meta\",{type:\"iconset\"})}},observers:[\"_updateIcon(_meta, isAttached)\",\"_updateIcon(theme, isAttached)\",\"_srcChanged(src, isAttached)\",\"_iconChanged(icon, isAttached)\"],_DEFAULT_ICONSET:\"icons\",_iconChanged:function(a){a=(a||\"\").split(\":\");this._iconName=a.pop();this._iconsetName=a.pop()||this._DEFAULT_ICONSET;this._updateIcon()},_srcChanged:function(){this._updateIcon()},\n_usesIconset:function(){return this.icon||!this.src},_updateIcon:function(){this._usesIconset()?(this._img&&this._img.parentNode&&Polymer.dom(this.root).removeChild(this._img),\"\"===this._iconName?this._iconset&&this._iconset.removeIcon(this):this._iconsetName&&this._meta&&((this._iconset=this._meta.byKey(this._iconsetName))?(this._iconset.applyIcon(this,this._iconName,this.theme),this.unlisten(window,\"iron-iconset-added\",\"_updateIcon\")):this.listen(window,\"iron-iconset-added\",\"_updateIcon\"))):(this._iconset&&\nthis._iconset.removeIcon(this),this._img||(this._img=document.createElement(\"img\"),this._img.style.width=\"100%\",this._img.style.height=\"100%\",this._img.draggable=!1),this._img.src=this.src,Polymer.dom(this.root).appendChild(this._img))}});\n</script>\n\n</dom-module>\n\n\n\n\n\n\n\n\n\n<dom-module id=\"iron-a11y-announcer\">\n  <template>\n    <style>\n      :host {\n        display: inline-block;\n        position: fixed;\n        clip: rect(0px,0px,0px,0px);\n      }\n    </style>\n    <div aria-live$=\"[[mode]]\">[[_text]]</div>\n  </template>\n\n  <script>//~~WEBPATH~~/iron-a11y-announcer/iron-a11y-announcer.html.js\nPolymer.IronA11yAnnouncer=function(){};Polymer.IronA11yAnnouncer=Polymer({is:\"iron-a11y-announcer\",properties:{mode:{type:String,value:\"polite\"},_text:{type:String,value:\"\"}},created:function(){Polymer.IronA11yAnnouncer.instance||(Polymer.IronA11yAnnouncer.instance=this);document.body.addEventListener(\"iron-announce\",this._onIronAnnounce.bind(this))},announce:function(a){this._text=\"\";this.async(function(){this._text=a},100)},_onIronAnnounce:function(a){a.detail&&a.detail.text&&this.announce(a.detail.text)}});\nPolymer.IronA11yAnnouncer.instance=null;Polymer.IronA11yAnnouncer.requestAvailability=function(){Polymer.IronA11yAnnouncer.instance||(Polymer.IronA11yAnnouncer.instance=document.createElement(\"iron-a11y-announcer\"));document.body.appendChild(Polymer.IronA11yAnnouncer.instance)};\n</script>\n</dom-module>\n\n\n\n<script>//~~WEBPATH~~/iron-input/iron-input.html.js\nPolymer({is:\"iron-input\",extends:\"input\",behaviors:[Polymer.IronValidatableBehavior],properties:{bindValue:{observer:\"_bindValueChanged\",type:String},preventInvalidInput:{type:Boolean},allowedPattern:{type:String,observer:\"_allowedPatternChanged\"},_previousValidInput:{type:String,value:\"\"},_patternAlreadyChecked:{type:Boolean,value:!1}},listeners:{input:\"_onInput\",keypress:\"_onKeypress\"},registered:function(){this._canDispatchEventOnDisabled()||(this._origDispatchEvent=this.dispatchEvent,this.dispatchEvent=\nthis._dispatchEventFirefoxIE)},created:function(){Polymer.IronA11yAnnouncer.requestAvailability()},_canDispatchEventOnDisabled:function(){var a=document.createElement(\"input\"),b=!1;a.disabled=!0;a.addEventListener(\"feature-check-dispatch-event\",function(){b=!0});try{a.dispatchEvent(new Event(\"feature-check-dispatch-event\"))}catch(c){}return b},_dispatchEventFirefoxIE:function(){var a=this.disabled;this.disabled=!1;this._origDispatchEvent.apply(this,arguments);this.disabled=a},get _patternRegExp(){if(this.allowedPattern)var a=\nnew RegExp(this.allowedPattern);else switch(this.type){case \"number\":a=/[0-9.,e-]/}return a},ready:function(){this.bindValue=this.value},_bindValueChanged:function(){this.value!==this.bindValue&&(this.value=this.bindValue||0===this.bindValue||!1===this.bindValue?this.bindValue:\"\");this.fire(\"bind-value-changed\",{value:this.bindValue})},_allowedPatternChanged:function(){this.preventInvalidInput=this.allowedPattern?!0:!1},_onInput:function(){!this.preventInvalidInput||this._patternAlreadyChecked||this._checkPatternValidity()||\n(this._announceInvalidCharacter(\"Invalid string of characters not entered.\"),this.value=this._previousValidInput);this._previousValidInput=this.bindValue=this.value;this._patternAlreadyChecked=!1},_isPrintable:function(a){var b=19==a.keyCode||20==a.keyCode||45==a.keyCode||46==a.keyCode||144==a.keyCode||145==a.keyCode||32<a.keyCode&&41>a.keyCode||111<a.keyCode&&124>a.keyCode;return!(8==a.keyCode||9==a.keyCode||13==a.keyCode||27==a.keyCode)&&!(0==a.charCode&&b)},_onKeypress:function(a){if(this.preventInvalidInput||\n\"number\"===this.type){var b=this._patternRegExp;if(b&&!(a.metaKey||a.ctrlKey||a.altKey)){this._patternAlreadyChecked=!0;var c=String.fromCharCode(a.charCode);this._isPrintable(a)&&!b.test(c)&&(a.preventDefault(),this._announceInvalidCharacter(\"Invalid character \"+c+\" not entered.\"))}}},_checkPatternValidity:function(){var a=this._patternRegExp;if(!a)return!0;for(var b=0;b<this.value.length;b++)if(!a.test(this.value[b]))return!1;return!0},validate:function(){var a=this.checkValidity();a&&(this.required&&\n\"\"===this.value?a=!1:this.hasValidator()&&(a=Polymer.IronValidatableBehavior.validate.call(this,this.value)));this.invalid=!a;this.fire(\"iron-input-validate\");return a},_announceInvalidCharacter:function(a){this.fire(\"iron-announce\",{text:a})}});\n</script>\n\n\n\n\n\n<script>//~~WEBPATH~~/paper-input/paper-input-behavior.html.js\nPolymer.PaperInputHelper={};Polymer.PaperInputHelper.NextLabelID=1;Polymer.PaperInputHelper.NextAddonID=1;\nPolymer.PaperInputBehaviorImpl={properties:{label:{type:String},value:{notify:!0,type:String},disabled:{type:Boolean,value:!1},invalid:{type:Boolean,value:!1,notify:!0},preventInvalidInput:{type:Boolean},allowedPattern:{type:String},type:{type:String},list:{type:String},pattern:{type:String},required:{type:Boolean,value:!1},errorMessage:{type:String},charCounter:{type:Boolean,value:!1},noLabelFloat:{type:Boolean,value:!1},alwaysFloatLabel:{type:Boolean,value:!1},autoValidate:{type:Boolean,value:!1},\nvalidator:{type:String},autocomplete:{type:String,value:\"off\"},autofocus:{type:Boolean,observer:\"_autofocusChanged\"},inputmode:{type:String},minlength:{type:Number},maxlength:{type:Number},min:{type:String},max:{type:String},step:{type:String},name:{type:String},placeholder:{type:String,value:\"\"},readonly:{type:Boolean,value:!1},size:{type:Number},autocapitalize:{type:String,value:\"none\"},autocorrect:{type:String,value:\"off\"},autosave:{type:String},results:{type:Number},accept:{type:String},multiple:{type:Boolean},\n_ariaDescribedBy:{type:String,value:\"\"},_ariaLabelledBy:{type:String,value:\"\"}},listeners:{\"addon-attached\":\"_onAddonAttached\"},keyBindings:{\"shift+tab:keydown\":\"_onShiftTabDown\"},hostAttributes:{tabindex:0},get inputElement(){return this.$.input},get _focusableElement(){return this.inputElement},registered:function(){this._typesThatHaveText=\"date datetime datetime-local month time week file\".split(\" \")},attached:function(){this._updateAriaLabelledBy();this.inputElement&&-1!==this._typesThatHaveText.indexOf(this.inputElement.type)&&\n(this.alwaysFloatLabel=!0)},_appendStringWithSpace:function(a,b){return a?a+\" \"+b:b},_onAddonAttached:function(a){a=a.path?a.path[0]:a.target;if(a.id)this._ariaDescribedBy=this._appendStringWithSpace(this._ariaDescribedBy,a.id);else{var b=\"paper-input-add-on-\"+Polymer.PaperInputHelper.NextAddonID++;a.id=b;this._ariaDescribedBy=this._appendStringWithSpace(this._ariaDescribedBy,b)}},validate:function(){return this.inputElement.validate()},_focusBlurHandler:function(a){Polymer.IronControlState._focusBlurHandler.call(this,\na);this.focused&&!this._shiftTabPressed&&this._focusableElement.focus()},_onShiftTabDown:function(){var a=this.getAttribute(\"tabindex\");this._shiftTabPressed=!0;this.setAttribute(\"tabindex\",\"-1\");this.async(function(){this.setAttribute(\"tabindex\",a);this._shiftTabPressed=!1},1)},_handleAutoValidate:function(){this.autoValidate&&this.validate()},updateValueAndPreserveCaret:function(a){try{var b=this.inputElement.selectionStart;this.value=a;this.inputElement.selectionStart=b;this.inputElement.selectionEnd=\nb}catch(c){this.value=a}},_computeAlwaysFloatLabel:function(a,b){return b||a},_updateAriaLabelledBy:function(){var a=Polymer.dom(this.root).querySelector(\"label\");if(a){if(a.id)var b=a.id;else b=\"paper-input-label-\"+Polymer.PaperInputHelper.NextLabelID++,a.id=b;this._ariaLabelledBy=b}else this._ariaLabelledBy=\"\"},_onChange:function(a){this.shadowRoot&&this.fire(a.type,{sourceEvent:a},{node:this,bubbles:a.bubbles,cancelable:a.cancelable})},_autofocusChanged:function(){if(this.autofocus&&this._focusableElement){var a=\ndocument.activeElement;a instanceof HTMLElement&&a!==document.body&&a!==document.documentElement||this._focusableElement.focus()}}};Polymer.PaperInputBehavior=[Polymer.IronControlState,Polymer.IronA11yKeysBehavior,Polymer.PaperInputBehaviorImpl];\n</script>\n\n\n\n<link rel=\"stylesheet\" href=\"https://fonts.googleapis.com/css?family=Roboto:400,300,300italic,400italic,500,500italic,700,700italic\">\n<link rel=\"stylesheet\" href=\"https://fonts.googleapis.com/css?family=Roboto+Mono:400,700\">\n\n\n<style is=\"custom-style\">\n\n  :root {\n\n    /* Shared Styles */\n    --paper-font-common-base: {\n      font-family: 'Roboto', 'Noto', sans-serif;\n      -webkit-font-smoothing: antialiased;\n    };\n\n    --paper-font-common-code: {\n      font-family: 'Roboto Mono', 'Consolas', 'Menlo', monospace;\n      -webkit-font-smoothing: antialiased;\n    };\n\n    --paper-font-common-expensive-kerning: {\n      text-rendering: optimizeLegibility;\n    };\n\n    --paper-font-common-nowrap: {\n      white-space: nowrap;\n      overflow: hidden;\n      text-overflow: ellipsis;\n    };\n\n    /* Material Font Styles */\n\n    --paper-font-display4: {\n      @apply(--paper-font-common-base);\n      @apply(--paper-font-common-nowrap);\n\n      font-size: 112px;\n      font-weight: 300;\n      letter-spacing: -.044em;\n      line-height: 120px;\n    };\n\n    --paper-font-display3: {\n      @apply(--paper-font-common-base);\n      @apply(--paper-font-common-nowrap);\n\n      font-size: 56px;\n      font-weight: 400;\n      letter-spacing: -.026em;\n      line-height: 60px;\n    };\n\n    --paper-font-display2: {\n      @apply(--paper-font-common-base);\n\n      font-size: 45px;\n      font-weight: 400;\n      letter-spacing: -.018em;\n      line-height: 48px;\n    };\n\n    --paper-font-display1: {\n      @apply(--paper-font-common-base);\n\n      font-size: 34px;\n      font-weight: 400;\n      letter-spacing: -.01em;\n      line-height: 40px;\n    };\n\n    --paper-font-headline: {\n      @apply(--paper-font-common-base);\n\n      font-size: 24px;\n      font-weight: 400;\n      letter-spacing: -.012em;\n      line-height: 32px;\n    };\n\n    --paper-font-title: {\n      @apply(--paper-font-common-base);\n      @apply(--paper-font-common-nowrap);\n\n      font-size: 20px;\n      font-weight: 500;\n      line-height: 28px;\n    };\n\n    --paper-font-subhead: {\n      @apply(--paper-font-common-base);\n\n      font-size: 16px;\n      font-weight: 400;\n      line-height: 24px;\n    };\n\n    --paper-font-body2: {\n      @apply(--paper-font-common-base);\n\n      font-size: 14px;\n      font-weight: 500;\n      line-height: 24px;\n    };\n\n    --paper-font-body1: {\n      @apply(--paper-font-common-base);\n\n      font-size: 14px;\n      font-weight: 400;\n      line-height: 20px;\n    };\n\n    --paper-font-caption: {\n      @apply(--paper-font-common-base);\n      @apply(--paper-font-common-nowrap);\n\n      font-size: 12px;\n      font-weight: 400;\n      letter-spacing: 0.011em;\n      line-height: 20px;\n    };\n\n    --paper-font-menu: {\n      @apply(--paper-font-common-base);\n      @apply(--paper-font-common-nowrap);\n\n      font-size: 13px;\n      font-weight: 500;\n      line-height: 24px;\n    };\n\n    --paper-font-button: {\n      @apply(--paper-font-common-base);\n      @apply(--paper-font-common-nowrap);\n\n      font-size: 14px;\n      font-weight: 500;\n      letter-spacing: 0.018em;\n      line-height: 24px;\n      text-transform: uppercase;\n    };\n\n    --paper-font-code2: {\n      @apply(--paper-font-common-code);\n\n      font-size: 14px;\n      font-weight: 700;\n      line-height: 20px;\n    };\n\n    --paper-font-code1: {\n      @apply(--paper-font-common-code);\n\n      font-size: 14px;\n      font-weight: 500;\n      line-height: 20px;\n    };\n\n  }\n\n</style>\n\n\n\n<script>//~~WEBPATH~~/paper-input/paper-input-addon-behavior.html.js\nPolymer.PaperInputAddonBehavior={hostAttributes:{\"add-on\":\"\"},attached:function(){this.fire(\"addon-attached\")},update:function(){}};\n</script>\n\n\n\n\n<dom-module id=\"paper-input-char-counter\">\n  <template>\n    <style>\n      :host {\n        display: inline-block;\n        float: right;\n\n        @apply(--paper-font-caption);\n        @apply(--paper-input-char-counter);\n      }\n\n      :host([hidden]) {\n        display: none !important;\n      }\n\n      :host-context([dir=\"rtl\"]) {\n        float: left;\n      }\n    </style>\n\n    <span>[[_charCounterStr]]</span>\n  </template>\n</dom-module>\n\n<script>//~~WEBPATH~~/paper-input/paper-input-char-counter.html.js\nPolymer({is:\"paper-input-char-counter\",behaviors:[Polymer.PaperInputAddonBehavior],properties:{_charCounterStr:{type:String,value:\"0\"}},update:function(a){if(a.inputElement){a.value=a.value||\"\";var b=a.value.toString().length.toString();a.inputElement.hasAttribute(\"maxlength\")&&(b+=\"/\"+a.inputElement.getAttribute(\"maxlength\"));this._charCounterStr=b}}});\n</script>\n\n\n\n\n\n\n\n\n<dom-module id=\"paper-input-container\">\n  <template>\n    <style>\n      :host {\n        display: block;\n        padding: 8px 0;\n\n        @apply(--paper-input-container);\n      }\n\n      :host([inline]) {\n        display: inline-block;\n      }\n\n      :host([disabled]) {\n        pointer-events: none;\n        opacity: 0.33;\n\n        @apply(--paper-input-container-disabled);\n      }\n\n      :host([hidden]) {\n        display: none !important;\n      }\n\n      .floated-label-placeholder {\n        @apply(--paper-font-caption);\n      }\n\n      .underline {\n        position: relative;\n      }\n\n      .focused-line {\n        @apply(--layout-fit);\n\n        background: var(--paper-input-container-focus-color, --primary-color);\n        height: 2px;\n\n        -webkit-transform-origin: center center;\n        transform-origin: center center;\n        -webkit-transform: scale3d(0,1,1);\n        transform: scale3d(0,1,1);\n\n        @apply(--paper-input-container-underline-focus);\n      }\n\n      .underline.is-highlighted .focused-line {\n        -webkit-transform: none;\n        transform: none;\n        -webkit-transition: -webkit-transform 0.25s;\n        transition: transform 0.25s;\n\n        @apply(--paper-transition-easing);\n      }\n\n      .underline.is-invalid .focused-line {\n        background: var(--paper-input-container-invalid-color, --error-color);\n        -webkit-transform: none;\n        transform: none;\n        -webkit-transition: -webkit-transform 0.25s;\n        transition: transform 0.25s;\n\n        @apply(--paper-transition-easing);\n      }\n\n      .unfocused-line {\n        @apply(--layout-fit);\n\n        background: var(--paper-input-container-color, --secondary-text-color);\n        height: 1px;\n\n        @apply(--paper-input-container-underline);\n      }\n\n      :host([disabled]) .unfocused-line {\n        border-bottom: 1px dashed;\n        border-color: var(--paper-input-container-color, --secondary-text-color);\n        background: transparent;\n\n        @apply(--paper-input-container-underline-disabled);\n      }\n\n      .label-and-input-container {\n        @apply(--layout-flex-auto);\n        @apply(--layout-relative);\n\n        width: 100%;\n        max-width: 100%;\n      }\n\n      .input-content {\n        @apply(--layout-horizontal);\n        @apply(--layout-center);\n\n        position: relative;\n      }\n\n      .input-content ::content label,\n      .input-content ::content .paper-input-label {\n        position: absolute;\n        top: 0;\n        right: 0;\n        left: 0;\n        width: 100%;\n        font: inherit;\n        color: var(--paper-input-container-color, --secondary-text-color);\n        -webkit-transition: -webkit-transform 0.25s, width 0.25s;\n        transition: transform 0.25s, width 0.25s;\n        -webkit-transform-origin: left top;\n        transform-origin: left top;\n\n        @apply(--paper-font-common-nowrap);\n        @apply(--paper-font-subhead);\n        @apply(--paper-input-container-label);\n        @apply(--paper-transition-easing);\n      }\n\n      .input-content.label-is-floating ::content label,\n      .input-content.label-is-floating ::content .paper-input-label {\n        -webkit-transform: translateY(-75%) scale(0.75);\n        transform: translateY(-75%) scale(0.75);\n\n        /* Since we scale to 75/100 of the size, we actually have 100/75 of the\n        original space now available */\n        width: 133%;\n\n        @apply(--paper-input-container-label-floating);\n      }\n\n      :host-context([dir=\"rtl\"]) .input-content.label-is-floating ::content label,\n      :host-context([dir=\"rtl\"]) .input-content.label-is-floating ::content .paper-input-label {\n        /* TODO(noms): Figure out why leaving the width at 133% before the animation\n         * actually makes\n         * it wider on the right side, not left side, as you would expect in RTL */\n        width: 100%;\n        -webkit-transform-origin: right top;\n        transform-origin: right top;\n      }\n\n      .input-content.label-is-highlighted ::content label,\n      .input-content.label-is-highlighted ::content .paper-input-label {\n        color: var(--paper-input-container-focus-color, --primary-color);\n\n        @apply(--paper-input-container-label-focus);\n      }\n\n      .input-content.is-invalid ::content label,\n      .input-content.is-invalid ::content .paper-input-label {\n        color: var(--paper-input-container-invalid-color, --error-color);\n      }\n\n      .input-content.label-is-hidden ::content label,\n      .input-content.label-is-hidden ::content .paper-input-label {\n        visibility: hidden;\n      }\n\n      .input-content ::content input,\n      .input-content ::content textarea,\n      .input-content ::content iron-autogrow-textarea,\n      .input-content ::content .paper-input-input {\n        position: relative; /* to make a stacking context */\n        outline: none;\n        box-shadow: none;\n        padding: 0;\n        width: 100%;\n        max-width: 100%;\n        background: transparent;\n        border: none;\n        color: var(--paper-input-container-input-color, --primary-text-color);\n        -webkit-appearance: none;\n        text-align: inherit;\n\n        @apply(--paper-font-subhead);\n        @apply(--paper-input-container-input);\n      }\n\n      ::content [prefix] {\n        @apply(--paper-font-subhead);\n\n        @apply(--paper-input-prefix);\n        @apply(--layout-flex-none);\n      }\n\n      ::content [suffix] {\n        @apply(--paper-font-subhead);\n\n        @apply(--paper-input-suffix);\n        @apply(--layout-flex-none);\n      }\n\n      /* Firefox sets a min-width on the input, which can cause layout issues */\n      .input-content ::content input {\n        min-width: 0;\n      }\n\n      .input-content ::content textarea {\n        resize: none;\n      }\n\n      .add-on-content {\n        position: relative;\n      }\n\n      .add-on-content.is-invalid ::content * {\n        color: var(--paper-input-container-invalid-color, --error-color);\n      }\n\n      .add-on-content.is-highlighted ::content * {\n        color: var(--paper-input-container-focus-color, --primary-color);\n      }\n    </style>\n\n    <template is=\"dom-if\" if=\"[[!noLabelFloat]]\">\n      <div class=\"floated-label-placeholder\" aria-hidden=\"true\">&nbsp;</div>\n    </template>\n\n    <div class$=\"[[_computeInputContentClass(noLabelFloat,alwaysFloatLabel,focused,invalid,_inputHasContent)]]\">\n      <content select=\"[prefix]\" id=\"prefix\"></content>\n\n      <div class=\"label-and-input-container\" id=\"labelAndInputContainer\">\n        <content select=\":not([add-on]):not([prefix]):not([suffix])\"></content>\n      </div>\n\n      <content select=\"[suffix]\"></content>\n    </div>\n\n    <div class$=\"[[_computeUnderlineClass(focused,invalid)]]\">\n      <div class=\"unfocused-line\"></div>\n      <div class=\"focused-line\"></div>\n    </div>\n\n    <div class$=\"[[_computeAddOnContentClass(focused,invalid)]]\">\n      <content id=\"addOnContent\" select=\"[add-on]\"></content>\n    </div>\n  </template>\n</dom-module>\n\n<script>//~~WEBPATH~~/paper-input/paper-input-container.html.js\nPolymer({is:\"paper-input-container\",properties:{noLabelFloat:{type:Boolean,value:!1},alwaysFloatLabel:{type:Boolean,value:!1},attrForValue:{type:String,value:\"bind-value\"},autoValidate:{type:Boolean,value:!1},invalid:{observer:\"_invalidChanged\",type:Boolean,value:!1},focused:{readOnly:!0,type:Boolean,value:!1,notify:!0},_addons:{type:Array},_inputHasContent:{type:Boolean,value:!1},_inputSelector:{type:String,value:\"input,textarea,.paper-input-input\"},_boundOnFocus:{type:Function,value:function(){return this._onFocus.bind(this)}},\n_boundOnBlur:{type:Function,value:function(){return this._onBlur.bind(this)}},_boundOnInput:{type:Function,value:function(){return this._onInput.bind(this)}},_boundValueChanged:{type:Function,value:function(){return this._onValueChanged.bind(this)}}},listeners:{\"addon-attached\":\"_onAddonAttached\",\"iron-input-validate\":\"_onIronInputValidate\"},get _valueChangedEvent(){return this.attrForValue+\"-changed\"},get _propertyForValue(){return Polymer.CaseMap.dashToCamelCase(this.attrForValue)},get _inputElement(){return Polymer.dom(this).querySelector(this._inputSelector)},\nget _inputElementValue(){return this._inputElement[this._propertyForValue]||this._inputElement.value},ready:function(){this._addons||(this._addons=[]);this.addEventListener(\"focus\",this._boundOnFocus,!0);this.addEventListener(\"blur\",this._boundOnBlur,!0)},attached:function(){this.attrForValue?this._inputElement.addEventListener(this._valueChangedEvent,this._boundValueChanged):this.addEventListener(\"input\",this._onInput);\"\"!=this._inputElementValue?this._handleValueAndAutoValidate(this._inputElement):\nthis._handleValue(this._inputElement)},_onAddonAttached:function(a){this._addons||(this._addons=[]);a=a.target;-1===this._addons.indexOf(a)&&(this._addons.push(a),this.isAttached&&this._handleValue(this._inputElement))},_onFocus:function(){this._setFocused(!0)},_onBlur:function(){this._setFocused(!1);this._handleValueAndAutoValidate(this._inputElement)},_onInput:function(a){this._handleValueAndAutoValidate(a.target)},_onValueChanged:function(a){this._handleValueAndAutoValidate(a.target)},_handleValue:function(a){var b=\nthis._inputElementValue;b||0===b||\"number\"===a.type&&!a.checkValidity()?this._inputHasContent=!0:this._inputHasContent=!1;this.updateAddons({inputElement:a,value:b,invalid:this.invalid})},_handleValueAndAutoValidate:function(a){this.autoValidate&&(this.invalid=!(a.validate?a.validate(this._inputElementValue):a.checkValidity()));this._handleValue(a)},_onIronInputValidate:function(){this.invalid=this._inputElement.invalid},_invalidChanged:function(){this._addons&&this.updateAddons({invalid:this.invalid})},\nupdateAddons:function(a){for(var b,c=0;b=this._addons[c];c++)b.update(a)},_computeInputContentClass:function(a,b,c,d,e){var f=\"input-content\";a?e&&(f+=\" label-is-hidden\"):(a=this.querySelector(\"label\"),b||e?(f+=\" label-is-floating\",this.$.labelAndInputContainer.style.position=\"static\",d?f+=\" is-invalid\":c&&(f+=\" label-is-highlighted\")):a&&(this.$.labelAndInputContainer.style.position=\"relative\"));return f},_computeUnderlineClass:function(a,b){var c=\"underline\";b?c+=\" is-invalid\":a&&(c+=\" is-highlighted\");\nreturn c},_computeAddOnContentClass:function(a,b){var c=\"add-on-content\";b?c+=\" is-invalid\":a&&(c+=\" is-highlighted\");return c}});\n</script>\n\n\n\n\n\n\n\n\n<dom-module id=\"paper-input-error\">\n  <template>\n    <style>\n      :host {\n        display: inline-block;\n        visibility: hidden;\n\n        color: var(--paper-input-container-invalid-color, --error-color);\n\n        @apply(--paper-font-caption);\n        @apply(--paper-input-error);\n        position: absolute;\n        left:0;\n        right:0;\n      }\n\n      :host([invalid]) {\n        visibility: visible;\n      };\n    </style>\n\n    <content></content>\n  </template>\n</dom-module>\n\n<script>//~~WEBPATH~~/paper-input/paper-input-error.html.js\nPolymer({is:\"paper-input-error\",behaviors:[Polymer.PaperInputAddonBehavior],properties:{invalid:{readOnly:!0,reflectToAttribute:!0,type:Boolean}},update:function(a){this._setInvalid(a.invalid)}});\n</script>\n\n\n\n\n<dom-module id=\"paper-input\">\n  <template>\n    <style>\n      :host {\n        display: block;\n      }\n\n      :host([focused]) {\n        outline: none;\n      }\n\n      :host([hidden]) {\n        display: none !important;\n      }\n\n      input::-webkit-input-placeholder {\n        color: var(--paper-input-container-color, --secondary-text-color);\n      }\n\n      input:-moz-placeholder {\n        color: var(--paper-input-container-color, --secondary-text-color);\n      }\n\n      input::-moz-placeholder {\n        color: var(--paper-input-container-color, --secondary-text-color);\n      }\n\n      input:-ms-input-placeholder {\n        color: var(--paper-input-container-color, --secondary-text-color);\n      }\n\n      label {\n        pointer-events: none;\n      }\n    </style>\n\n    <paper-input-container no-label-float=\"[[noLabelFloat]]\" always-float-label=\"[[_computeAlwaysFloatLabel(alwaysFloatLabel,placeholder)]]\" auto-validate$=\"[[autoValidate]]\" disabled$=\"[[disabled]]\" invalid=\"[[invalid]]\">\n\n      <content select=\"[prefix]\"></content>\n\n      <label hidden$=\"[[!label]]\" aria-hidden=\"true\" for=\"input\">[[label]]</label>\n\n      <input is=\"iron-input\" id=\"input\" aria-labelledby$=\"[[_ariaLabelledBy]]\" aria-describedby$=\"[[_ariaDescribedBy]]\" disabled$=\"[[disabled]]\" title$=\"[[title]]\" bind-value=\"{{value}}\" invalid=\"{{invalid}}\" prevent-invalid-input=\"[[preventInvalidInput]]\" allowed-pattern=\"[[allowedPattern]]\" validator=\"[[validator]]\" type$=\"[[type]]\" pattern$=\"[[pattern]]\" required$=\"[[required]]\" autocomplete$=\"[[autocomplete]]\" autofocus$=\"[[autofocus]]\" inputmode$=\"[[inputmode]]\" minlength$=\"[[minlength]]\" maxlength$=\"[[maxlength]]\" min$=\"[[min]]\" max$=\"[[max]]\" step$=\"[[step]]\" name$=\"[[name]]\" placeholder$=\"[[placeholder]]\" readonly$=\"[[readonly]]\" list$=\"[[list]]\" size$=\"[[size]]\" autocapitalize$=\"[[autocapitalize]]\" autocorrect$=\"[[autocorrect]]\" on-change=\"_onChange\" tabindex$=\"[[tabindex]]\" autosave$=\"[[autosave]]\" results$=\"[[results]]\" accept$=\"[[accept]]\" multiple$=\"[[multiple]]\">\n\n      <content select=\"[suffix]\"></content>\n\n      <template is=\"dom-if\" if=\"[[errorMessage]]\">\n        <paper-input-error aria-live=\"assertive\">[[errorMessage]]</paper-input-error>\n      </template>\n\n      <template is=\"dom-if\" if=\"[[charCounter]]\">\n        <paper-input-char-counter></paper-input-char-counter>\n      </template>\n\n    </paper-input-container>\n  </template>\n</dom-module>\n\n<script>//~~WEBPATH~~/paper-input/paper-input.html.js\nPolymer({is:\"paper-input\",behaviors:[Polymer.IronFormElementBehavior,Polymer.PaperInputBehavior]});\n</script>\n\n\n\n\n\n\n\n<script>//~~WEBPATH~~/iron-resizable-behavior/iron-resizable-behavior.html.js\nPolymer.IronResizableBehavior={properties:{_parentResizable:{type:Object,observer:\"_parentResizableChanged\"},_notifyingDescendant:{type:Boolean,value:!1}},listeners:{\"iron-request-resize-notifications\":\"_onIronRequestResizeNotifications\"},created:function(){this._interestedResizables=[];this._boundNotifyResize=this.notifyResize.bind(this)},attached:function(){this.fire(\"iron-request-resize-notifications\",null,{node:this,bubbles:!0,cancelable:!0});this._parentResizable||(window.addEventListener(\"resize\",\nthis._boundNotifyResize),this.notifyResize())},detached:function(){this._parentResizable?this._parentResizable.stopResizeNotificationsFor(this):window.removeEventListener(\"resize\",this._boundNotifyResize);this._parentResizable=null},notifyResize:function(){this.isAttached&&(this._interestedResizables.forEach(function(a){this.resizerShouldNotify(a)&&this._notifyDescendant(a)},this),this._fireResize())},assignParentResizable:function(a){this._parentResizable=a},stopResizeNotificationsFor:function(a){var b=\nthis._interestedResizables.indexOf(a);-1<b&&(this._interestedResizables.splice(b,1),this.unlisten(a,\"iron-resize\",\"_onDescendantIronResize\"))},resizerShouldNotify:function(){return!0},_onDescendantIronResize:function(a){this._notifyingDescendant?a.stopPropagation():Polymer.Settings.useShadow||this._fireResize()},_fireResize:function(){this.fire(\"iron-resize\",null,{node:this,bubbles:!1})},_onIronRequestResizeNotifications:function(a){var b=a.path?a.path[0]:a.target;b!==this&&(-1===this._interestedResizables.indexOf(b)&&\n(this._interestedResizables.push(b),this.listen(b,\"iron-resize\",\"_onDescendantIronResize\")),b.assignParentResizable(this),this._notifyDescendant(b),a.stopPropagation())},_parentResizableChanged:function(a){a&&window.removeEventListener(\"resize\",this._boundNotifyResize)},_notifyDescendant:function(a){this.isAttached&&(this._notifyingDescendant=!0,a.notifyResize(),this._notifyingDescendant=!1)}};\n</script>\n\n\n\n\n\n\n\n<script>//~~WEBPATH~~/iron-fit-behavior/iron-fit-behavior.html.js\nPolymer.IronFitBehavior={properties:{sizingTarget:{type:Object,value:function(){return this}},fitInto:{type:Object,value:window},noOverlap:{type:Boolean},positionTarget:{type:Element},horizontalAlign:{type:String},verticalAlign:{type:String},dynamicAlign:{type:Boolean},horizontalOffset:{type:Number,value:0,notify:!0},verticalOffset:{type:Number,value:0,notify:!0},autoFitOnAttach:{type:Boolean,value:!1},_fitInfo:{type:Object}},get _fitWidth(){return this.fitInto===window?this.fitInto.innerWidth:this.fitInto.getBoundingClientRect().width},\nget _fitHeight(){return this.fitInto===window?this.fitInto.innerHeight:this.fitInto.getBoundingClientRect().height},get _fitLeft(){return this.fitInto===window?0:this.fitInto.getBoundingClientRect().left},get _fitTop(){return this.fitInto===window?0:this.fitInto.getBoundingClientRect().top},get _defaultPositionTarget(){var a=Polymer.dom(this).parentNode;a&&a.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&(a=a.host);return a},get _localeHorizontalAlign(){if(this._isRTL){if(\"right\"===this.horizontalAlign)return\"left\";\nif(\"left\"===this.horizontalAlign)return\"right\"}return this.horizontalAlign},attached:function(){this._isRTL=\"rtl\"==window.getComputedStyle(this).direction;this.positionTarget=this.positionTarget||this._defaultPositionTarget;this.autoFitOnAttach&&(\"none\"===window.getComputedStyle(this).display?setTimeout(function(){this.fit()}.bind(this)):this.fit())},fit:function(){this.position();this.constrain();this.center()},_discoverInfo:function(){if(!this._fitInfo){var a=window.getComputedStyle(this),b=window.getComputedStyle(this.sizingTarget);\nthis._fitInfo={inlineStyle:{top:this.style.top||\"\",left:this.style.left||\"\",position:this.style.position||\"\"},sizerInlineStyle:{maxWidth:this.sizingTarget.style.maxWidth||\"\",maxHeight:this.sizingTarget.style.maxHeight||\"\",boxSizing:this.sizingTarget.style.boxSizing||\"\"},positionedBy:{vertically:\"auto\"!==a.top?\"top\":\"auto\"!==a.bottom?\"bottom\":null,horizontally:\"auto\"!==a.left?\"left\":\"auto\"!==a.right?\"right\":null},sizedBy:{height:\"none\"!==b.maxHeight,width:\"none\"!==b.maxWidth,minWidth:parseInt(b.minWidth,\n10)||0,minHeight:parseInt(b.minHeight,10)||0},margin:{top:parseInt(a.marginTop,10)||0,right:parseInt(a.marginRight,10)||0,bottom:parseInt(a.marginBottom,10)||0,left:parseInt(a.marginLeft,10)||0}};this.verticalOffset&&(this._fitInfo.margin.top=this._fitInfo.margin.bottom=this.verticalOffset,this._fitInfo.inlineStyle.marginTop=this.style.marginTop||\"\",this._fitInfo.inlineStyle.marginBottom=this.style.marginBottom||\"\",this.style.marginTop=this.style.marginBottom=this.verticalOffset+\"px\");this.horizontalOffset&&\n(this._fitInfo.margin.left=this._fitInfo.margin.right=this.horizontalOffset,this._fitInfo.inlineStyle.marginLeft=this.style.marginLeft||\"\",this._fitInfo.inlineStyle.marginRight=this.style.marginRight||\"\",this.style.marginLeft=this.style.marginRight=this.horizontalOffset+\"px\")}},resetFit:function(){var a=this._fitInfo||{},b;for(b in a.sizerInlineStyle)this.sizingTarget.style[b]=a.sizerInlineStyle[b];for(b in a.inlineStyle)this.style[b]=a.inlineStyle[b];this._fitInfo=null},refit:function(){var a=this.sizingTarget.scrollLeft,\nb=this.sizingTarget.scrollTop;this.resetFit();this.fit();this.sizingTarget.scrollLeft=a;this.sizingTarget.scrollTop=b},position:function(){if(this.horizontalAlign||this.verticalAlign){this._discoverInfo();this.style.position=\"fixed\";this.sizingTarget.style.boxSizing=\"border-box\";this.style.left=\"0px\";this.style.top=\"0px\";var a=this.getBoundingClientRect(),b=this.__getNormalizedRect(this.positionTarget),c=this.__getNormalizedRect(this.fitInto),d=this._fitInfo.margin,e=this.__getPosition(this._localeHorizontalAlign,\nthis.verticalAlign,{width:a.width+d.left+d.right,height:a.height+d.top+d.bottom},b,c),b=e.left+d.left,e=e.top+d.top,f=Math.min(c.right-d.right,b+a.width),c=Math.min(c.bottom-d.bottom,e+a.height),g=this._fitInfo.sizedBy.minWidth,k=this._fitInfo.sizedBy.minHeight;b<d.left&&(b=d.left,f-b<g&&(b=f-g));e<d.top&&(e=d.top,c-e<k&&(e=c-k));this.sizingTarget.style.maxWidth=f-b+\"px\";this.sizingTarget.style.maxHeight=c-e+\"px\";this.style.left=b-a.left+\"px\";this.style.top=e-a.top+\"px\"}},constrain:function(){if(!this.horizontalAlign&&\n!this.verticalAlign){this._discoverInfo();var a=this._fitInfo;a.positionedBy.vertically||(this.style.position=\"fixed\",this.style.top=\"0px\");a.positionedBy.horizontally||(this.style.position=\"fixed\",this.style.left=\"0px\");this.sizingTarget.style.boxSizing=\"border-box\";var b=this.getBoundingClientRect();a.sizedBy.height||this.__sizeDimension(b,a.positionedBy.vertically,\"top\",\"bottom\",\"Height\");a.sizedBy.width||this.__sizeDimension(b,a.positionedBy.horizontally,\"left\",\"right\",\"Width\")}},_sizeDimension:function(a,\nb,c,d,e){this.__sizeDimension(a,b,c,d,e)},__sizeDimension:function(a,b,c,d,e){var f=this._fitInfo,g=this.__getNormalizedRect(this.fitInto),g=\"Width\"===e?g.width:g.height;b=b===d;var k=\"offset\"+e;this.sizingTarget.style[\"max\"+e]=g-f.margin[b?c:d]-(b?g-a[d]:a[c])-(this[k]-this.sizingTarget[k])+\"px\"},center:function(){if(!this.horizontalAlign&&!this.verticalAlign){this._discoverInfo();var a=this._fitInfo.positionedBy;if(!a.vertically||!a.horizontally){this.style.position=\"fixed\";a.vertically||(this.style.top=\n\"0px\");a.horizontally||(this.style.left=\"0px\");var b=this.getBoundingClientRect(),c=this.__getNormalizedRect(this.fitInto);a.vertically||(this.style.top=c.top-b.top+(c.height-b.height)/2+\"px\");a.horizontally||(this.style.left=c.left-b.left+(c.width-b.width)/2+\"px\")}}},__getNormalizedRect:function(a){return a===document.documentElement||a===window?{top:0,left:0,width:window.innerWidth,height:window.innerHeight,right:window.innerWidth,bottom:window.innerHeight}:a.getBoundingClientRect()},__getCroppedArea:function(a,\nb,c){return Math.abs(Math.min(0,a.top)+Math.min(0,c.bottom-(a.top+b.height)))*b.width+Math.abs(Math.min(0,a.left)+Math.min(0,c.right-(a.left+b.width)))*b.height},__getPosition:function(a,b,c,d,e){var f=[{verticalAlign:\"top\",horizontalAlign:\"left\",top:d.top,left:d.left},{verticalAlign:\"top\",horizontalAlign:\"right\",top:d.top,left:d.right-c.width},{verticalAlign:\"bottom\",horizontalAlign:\"left\",top:d.bottom-c.height,left:d.left},{verticalAlign:\"bottom\",horizontalAlign:\"right\",top:d.bottom-c.height,left:d.right-\nc.width}];if(this.noOverlap){for(var g=0,k=f.length;g<k;g++){var l={},m;for(m in f[g])l[m]=f[g][m];f.push(l)}f[0].top=f[1].top+=d.height;f[2].top=f[3].top-=d.height;f[4].left=f[6].left+=d.width;f[5].left=f[7].left-=d.width}b=\"auto\"===b?null:b;a=\"auto\"===a?null:a;for(var n,g=0;g<f.length;g++){d=f[g];if(!this.dynamicAlign&&!this.noOverlap&&d.verticalAlign===b&&d.horizontalAlign===a){n=d;break}k=(!b||d.verticalAlign===b)&&(!a||d.horizontalAlign===a);if(this.dynamicAlign||k){n=n||d;d.croppedArea=this.__getCroppedArea(d,\nc,e);l=d.croppedArea-n.croppedArea;if(0>l||0===l&&k)n=d;if(0===n.croppedArea&&k)break}}return n}};\n</script>\n\n\n\n\n\n\n\n\n<dom-module id=\"iron-overlay-backdrop\">\n\n  <template>\n    <style>\n      :host {\n        position: fixed;\n        top: 0;\n        left: 0;\n        width: 100%;\n        height: 100%;\n        background-color: var(--iron-overlay-backdrop-background-color, #000);\n        opacity: 0;\n        transition: opacity 0.2s;\n        pointer-events: none;\n        @apply(--iron-overlay-backdrop);\n      }\n\n      :host(.opened) {\n        opacity: var(--iron-overlay-backdrop-opacity, 0.6);\n        pointer-events: auto;\n        @apply(--iron-overlay-backdrop-opened);\n      }\n    </style>\n\n    <content></content>\n  </template>\n\n</dom-module>\n\n<script>//~~WEBPATH~~/iron-overlay-behavior/iron-overlay-backdrop.html.js\nPolymer({is:\"iron-overlay-backdrop\",properties:{opened:{reflectToAttribute:!0,type:Boolean,value:!1,observer:\"_openedChanged\"}},listeners:{transitionend:\"_onTransitionend\"},created:function(){this.__openedRaf=null},attached:function(){this.opened&&this._openedChanged(this.opened)},prepare:function(){this.opened&&!this.parentNode&&Polymer.dom(document.body).appendChild(this)},open:function(){this.opened=!0},close:function(){this.opened=!1},complete:function(){this.opened||this.parentNode!==document.body||\nPolymer.dom(this.parentNode).removeChild(this)},_onTransitionend:function(a){a&&a.target===this&&this.complete()},_openedChanged:function(a){a?this.prepare():(a=window.getComputedStyle(this),\"0s\"!==a.transitionDuration&&0!=a.opacity||this.complete());this.isAttached&&(this.__openedRaf&&(window.cancelAnimationFrame(this.__openedRaf),this.__openedRaf=null),this.scrollTop=this.scrollTop,this.__openedRaf=window.requestAnimationFrame(function(){this.__openedRaf=null;this.toggleClass(\"opened\",this.opened)}.bind(this)))}});\n</script>\n\n\n<script>//~~WEBPATH~~/iron-overlay-behavior/iron-overlay-manager.html.js\nPolymer.IronOverlayManagerClass=function(){this._overlays=[];this._minimumZ=101;this._backdropElement=null;Polymer.Gestures.add(document,\"tap\",this._onCaptureClick.bind(this));document.addEventListener(\"focus\",this._onCaptureFocus.bind(this),!0);document.addEventListener(\"keydown\",this._onCaptureKeyDown.bind(this),!0)};\nPolymer.IronOverlayManagerClass.prototype={constructor:Polymer.IronOverlayManagerClass,get backdropElement(){this._backdropElement||(this._backdropElement=document.createElement(\"iron-overlay-backdrop\"));return this._backdropElement},get deepActiveElement(){for(var a=document.activeElement||document.body;a.root&&Polymer.dom(a.root).activeElement;)a=Polymer.dom(a.root).activeElement;return a},addOrRemoveOverlay:function(a){a.opened?Td(this,a):Ud(this,a)},ensureMinimumZ:function(a){this._minimumZ=Math.max(this._minimumZ,\na)},focusOverlay:function(){var a=Vd(this);a&&a._applyFocus()},getBackdrops:function(){for(var a=[],b=0;b<this._overlays.length;b++)this._overlays[b].withBackdrop&&a.push(this._overlays[b]);return a},backdropZ:function(){return Wd(this,Xd(this))-1},_onCaptureClick:function(a){var b=Vd(this),c;if(c=b){a:{c=(c=Polymer.dom(a).path)||[];for(var d=0;d<c.length;d++)if(c[d]._manager===this){c=c[d];break a}c=void 0}c=c!==b}c&&b._onCaptureClick(a)},_onCaptureFocus:function(a){var b=Vd(this);b&&b._onCaptureFocus(a)},\n_onCaptureKeyDown:function(a){var b=Vd(this);b&&(Polymer.IronA11yKeysBehavior.keyboardEventMatchesKeys(a,\"esc\")?b._onCaptureEsc(a):Polymer.IronA11yKeysBehavior.keyboardEventMatchesKeys(a,\"tab\")&&b._onCaptureTab(a))}};function Wd(a,b){a=a._minimumZ;b&&(b=Number(b.style.zIndex||window.getComputedStyle(b).zIndex),b===b&&(a=b));return a}function Xd(a){for(var b=0;b<a._overlays.length;b++)if(a._overlays[b].withBackdrop)return a._overlays[b]}\nfunction Yd(a){var b=Xd(a);if(b||a._backdropElement)a.backdropElement.style.zIndex=Wd(a,b)-1,a.backdropElement.opened=!!b}function Vd(a){return a._overlays[a._overlays.length-1]}function Ud(a,b){b=a._overlays.indexOf(b);-1!==b&&(a._overlays.splice(b,1),Yd(a))}\nfunction Td(a,b){var c=a._overlays.indexOf(b);if(0<=c){if(b=c,c=a._overlays[b]){var d=a._overlays.length-1,e=a._overlays[d];e&&!c.alwaysOnTop&&e.alwaysOnTop&&d--;if(!(b>=d)){e=Math.max(Wd(a,Vd(a)),a._minimumZ);Wd(a,c)<=e&&(c.style.zIndex=e+2);for(;b<d;)a._overlays[b]=a._overlays[b+1],b++;a._overlays[d]=c}}}else{var c=a._overlays.length,d=a._overlays[c-1],e=Math.max(Wd(a,d),a._minimumZ),f=Wd(a,b);d&&!b.alwaysOnTop&&d.alwaysOnTop&&(d.style.zIndex=e+2,c--,e=Math.max(Wd(a,a._overlays[c-1]),a._minimumZ));\nf<=e&&(b.style.zIndex=e+2);a._overlays.splice(c,0,b)}Yd(a)}Polymer.IronOverlayManager=new Polymer.IronOverlayManagerClass;\n</script>\n\n\n\n<script>//~~WEBPATH~~/iron-overlay-behavior/iron-focusables-helper.html.js\n(function(){var a=Element.prototype,b=a.matches||a.matchesSelector||a.mozMatchesSelector||a.msMatchesSelector||a.oMatchesSelector||a.webkitMatchesSelector;Polymer.IronFocusablesHelper={getTabbableNodes:function(a){var b=[];return this._collectTabbableNodes(a,b)?this._sortByTabIndex(b):b},isFocusable:function(a){return b.call(a,\"input, select, textarea, button, object\")?b.call(a,\":not([disabled])\"):b.call(a,\"a[href], area[href], iframe, [tabindex], [contentEditable]\")},isTabbable:function(a){return this.isFocusable(a)&&\nb.call(a,':not([tabindex\\x3d\"-1\"])')&&this._isVisible(a)},_normalizedTabIndex:function(a){return this.isFocusable(a)?(a=a.getAttribute(\"tabindex\")||0,Number(a)):-1},_collectTabbableNodes:function(a,b){if(a.nodeType!==Node.ELEMENT_NODE||!this._isVisible(a))return!1;var c=this._normalizedTabIndex(a),d=0<c;0<=c&&b.push(a);a=\"content\"===a.localName?Polymer.dom(a).getDistributedNodes():Polymer.dom(a.root||a).children;for(c=0;c<a.length;c++)var g=this._collectTabbableNodes(a[c],b),d=d||g;return d},_isVisible:function(a){var b=\na.style;return\"hidden\"!==b.visibility&&\"none\"!==b.display?(b=window.getComputedStyle(a),\"hidden\"!==b.visibility&&\"none\"!==b.display):!1},_sortByTabIndex:function(a){var b=a.length;if(2>b)return a;var c=Math.ceil(b/2),b=this._sortByTabIndex(a.slice(0,c));a=this._sortByTabIndex(a.slice(c));return this._mergeSortByTabIndex(b,a)},_mergeSortByTabIndex:function(a,b){for(var c=[];0<a.length&&0<b.length;)this._hasLowerTabOrder(a[0],b[0])?c.push(b.shift()):c.push(a.shift());return c.concat(a,b)},_hasLowerTabOrder:function(a,\nb){a=Math.max(a.tabIndex,0);b=Math.max(b.tabIndex,0);return 0===a||0===b?b>a:a>b}}})();\n</script>\n\n\n<script>//~~WEBPATH~~/iron-overlay-behavior/iron-overlay-behavior.html.js\nPolymer.IronOverlayBehaviorImpl={properties:{opened:{observer:\"_openedChanged\",type:Boolean,value:!1,notify:!0},canceled:{observer:\"_canceledChanged\",readOnly:!0,type:Boolean,value:!1},withBackdrop:{observer:\"_withBackdropChanged\",type:Boolean},noAutoFocus:{type:Boolean,value:!1},noCancelOnEscKey:{type:Boolean,value:!1},noCancelOnOutsideClick:{type:Boolean,value:!1},closingReason:{type:Object},restoreFocusOnClose:{type:Boolean,value:!1},alwaysOnTop:{type:Boolean},_manager:{type:Object,value:Polymer.IronOverlayManager},\n_focusedChild:{type:Object}},listeners:{\"iron-resize\":\"_onIronResize\"},get backdropElement(){return this._manager.backdropElement},get _focusNode(){return this._focusedChild||Polymer.dom(this).querySelector(\"[autofocus]\")||this},get _focusableNodes(){return Polymer.IronFocusablesHelper.getTabbableNodes(this)},ready:function(){this.__shouldRemoveTabIndex=this.__isAnimating=!1;this.__restoreFocusNode=this.__raf=this.__firstFocusableNode=this.__lastFocusableNode=null;this._ensureSetup()},attached:function(){this.opened&&\nthis._openedChanged(this.opened);this._observer=Polymer.dom(this).observeNodes(this._onNodesChange)},detached:function(){Polymer.dom(this).unobserveNodes(this._observer);this._observer=null;this.__raf&&(window.cancelAnimationFrame(this.__raf),this.__raf=null);Ud(this._manager,this)},toggle:function(){this._setCanceled(!1);this.opened=!this.opened},open:function(){this._setCanceled(!1);this.opened=!0},close:function(){this._setCanceled(!1);this.opened=!1},cancel:function(a){this.fire(\"iron-overlay-canceled\",\na,{cancelable:!0}).defaultPrevented||(this._setCanceled(!0),this.opened=!1)},invalidateTabbables:function(){this.__firstFocusableNode=this.__lastFocusableNode=null},_ensureSetup:function(){this._overlaySetup||(this._overlaySetup=!0,this.style.outline=\"none\",this.style.display=\"none\")},_openedChanged:function(a){a?this.removeAttribute(\"aria-hidden\"):this.setAttribute(\"aria-hidden\",\"true\");this.isAttached&&(this.__isAnimating=!0,this.__onNextAnimationFrame(this.__openedChanged))},_canceledChanged:function(){this.closingReason=\nthis.closingReason||{};this.closingReason.canceled=this.canceled},_withBackdropChanged:function(){this.withBackdrop&&!this.hasAttribute(\"tabindex\")?(this.setAttribute(\"tabindex\",\"-1\"),this.__shouldRemoveTabIndex=!0):this.__shouldRemoveTabIndex&&(this.removeAttribute(\"tabindex\"),this.__shouldRemoveTabIndex=!1);this.opened&&this.isAttached&&Yd(this._manager)},_prepareRenderOpened:function(){this.__restoreFocusNode=this._manager.deepActiveElement;this._preparePositioning();this.refit();this._finishPositioning();\nthis.noAutoFocus&&document.activeElement===this._focusNode&&(this._focusNode.blur(),this.__restoreFocusNode.focus())},_renderOpened:function(){this._finishRenderOpened()},_renderClosed:function(){this._finishRenderClosed()},_finishRenderOpened:function(){this.notifyResize();this.__isAnimating=!1;this.fire(\"iron-overlay-opened\")},_finishRenderClosed:function(){this.style.display=\"none\";this.style.zIndex=\"\";this.notifyResize();this.__isAnimating=!1;this.fire(\"iron-overlay-closed\",this.closingReason)},\n_preparePositioning:function(){this.style.transition=this.style.webkitTransition=\"none\";this.style.transform=this.style.webkitTransform=\"none\";this.style.display=\"\"},_finishPositioning:function(){this.style.display=\"none\";this.scrollTop=this.scrollTop;this.style.transition=this.style.webkitTransition=\"\";this.style.transform=this.style.webkitTransform=\"\";this.style.display=\"\";this.scrollTop=this.scrollTop},_applyFocus:function(){if(this.opened)this.noAutoFocus||this._focusNode.focus();else{this._focusNode.blur();\nthis._focusedChild=null;this.restoreFocusOnClose&&this.__restoreFocusNode&&this.__restoreFocusNode.focus();this.__restoreFocusNode=null;var a=Vd(this._manager);a&&this!==a&&a._applyFocus()}},_onCaptureClick:function(a){this.noCancelOnOutsideClick||this.cancel(a)},_onCaptureFocus:function(a){if(this.withBackdrop){var b=Polymer.dom(a).path;-1===b.indexOf(this)?(a.stopPropagation(),this._applyFocus()):this._focusedChild=b[0]}},_onCaptureEsc:function(a){this.noCancelOnEscKey||this.cancel(a)},_onCaptureTab:function(a){if(this.withBackdrop){this.__ensureFirstLastFocusables();\nvar b=a.shiftKey,c=b?this.__firstFocusableNode:this.__lastFocusableNode,b=b?this.__lastFocusableNode:this.__firstFocusableNode;if(c===b)c=!0;else var d=this._manager.deepActiveElement,c=d===c||d===this;c&&(a.preventDefault(),this._focusedChild=b,this._applyFocus())}},_onIronResize:function(){this.opened&&!this.__isAnimating&&this.__onNextAnimationFrame(this.refit)},_onNodesChange:function(){this.opened&&!this.__isAnimating&&(this.invalidateTabbables(),this.notifyResize())},__ensureFirstLastFocusables:function(){if(!this.__firstFocusableNode||\n!this.__lastFocusableNode){var a=this._focusableNodes;this.__firstFocusableNode=a[0];this.__lastFocusableNode=a[a.length-1]}},__openedChanged:function(){this.opened?(this._prepareRenderOpened(),Td(this._manager,this),this._applyFocus(),this._renderOpened()):(Ud(this._manager,this),this._applyFocus(),this._renderClosed())},__onNextAnimationFrame:function(a){this.__raf&&window.cancelAnimationFrame(this.__raf);var b=this;this.__raf=window.requestAnimationFrame(function(){b.__raf=null;a.call(b)})}};\nPolymer.IronOverlayBehavior=[Polymer.IronFitBehavior,Polymer.IronResizableBehavior,Polymer.IronOverlayBehaviorImpl];\n</script>\n\n\n\n\n\n\n\n\n<script>//~~WEBPATH~~/neon-animation/neon-animation-behavior.html.js\nPolymer.NeonAnimationBehavior={properties:{animationTiming:{type:Object,value:function(){return{duration:500,easing:\"cubic-bezier(0.4, 0, 0.2, 1)\",fill:\"both\"}}}},isNeonAnimation:!0,timingFromConfig:function(a){if(a.timing)for(var b in a.timing)this.animationTiming[b]=a.timing[b];return this.animationTiming},setPrefixedProperty:function(a,b,c){for(var d={transform:[\"webkitTransform\"],transformOrigin:[\"mozTransformOrigin\",\"webkitTransformOrigin\"]}[b],e,f=0;e=d[f];f++)a.style[e]=c;a.style[b]=c},complete:function(){}};\n</script>\n\n\n\n\n\n\n<script>//~~WEBPATH~~/neon-animation/animations/opaque-animation.html.js\nPolymer({is:\"opaque-animation\",behaviors:[Polymer.NeonAnimationBehavior],configure:function(a){var b=a.node;b.style.opacity=\"0\";return this._effect=new KeyframeEffect(b,[{opacity:\"1\"},{opacity:\"1\"}],this.timingFromConfig(a))},complete:function(a){a.node.style.opacity=\"\"}});\n</script>\n\n\n<script>//~~WEBPATH~~/neon-animation/neon-animatable-behavior.html.js\nPolymer.NeonAnimatableBehavior={properties:{animationConfig:{type:Object},entryAnimation:{observer:\"_entryAnimationChanged\",type:String},exitAnimation:{observer:\"_exitAnimationChanged\",type:String}},_entryAnimationChanged:function(){this.animationConfig=this.animationConfig||{};this.animationConfig.entry=\"fade-in-animation\"!==this.entryAnimation?[{name:\"opaque-animation\",node:this},{name:this.entryAnimation,node:this}]:[{name:this.entryAnimation,node:this}]},_exitAnimationChanged:function(){this.animationConfig=\nthis.animationConfig||{};this.animationConfig.exit=[{name:this.exitAnimation,node:this}]},_copyProperties:function(a,b){for(var c in b)a[c]=b[c]},_cloneConfig:function(a){var b={isClone:!0};this._copyProperties(b,a);return b},_getAnimationConfigRecursive:function(a,b,c){if(this.animationConfig)if(this.animationConfig.value&&\"function\"===typeof this.animationConfig.value)this._warn(this._logf(\"playAnimation\",\"Please put 'animationConfig' inside of your components 'properties' object instead of outside of it.\"));\nelse{var d=a?this.animationConfig[a]:this.animationConfig;Array.isArray(d)||(d=[d]);if(d)for(var e,f=0;e=d[f];f++)if(e.animatable)e.animatable._getAnimationConfigRecursive(e.type||a,b,c);else if(e.id){var g=b[e.id];g?(g.isClone||(b[e.id]=this._cloneConfig(g),g=b[e.id]),this._copyProperties(g,e)):b[e.id]=e}else c.push(e)}},getAnimationConfig:function(a){var b={},c=[];this._getAnimationConfigRecursive(a,b,c);for(var d in b)c.push(b[d]);return c}};\n</script>\n\n\n<script>//~~WEBPATH~~/neon-animation/neon-animation-runner-behavior.html.js\nPolymer.NeonAnimationRunnerBehaviorImpl={properties:{_player:{type:Object}},_configureAnimationEffects:function(a){var b=[];if(0<a.length)for(var c,d=0;c=a[d];d++){var e=document.createElement(c.name);if(e.isNeonAnimation){var f=e.configure(c);f&&b.push({animation:e,config:c,effect:f})}else Polymer.Base._warn(this.is+\":\",c.name,\"not found!\")}return b},_runAnimationEffects:function(a){return document.timeline.play(new GroupEffect(a))},_completeAnimations:function(a){for(var b,c=0;b=a[c];c++)b.animation.complete(b.config)},\nplayAnimation:function(a,b){if(a=this.getAnimationConfig(a)){var c=this._configureAnimationEffects(a);a=c.map(function(a){return a.effect});0<a.length?(this._player=this._runAnimationEffects(a),this._player.onfinish=function(){this._completeAnimations(c);this._player&&(this._player.cancel(),this._player=null);this.fire(\"neon-animation-finish\",b,{bubbles:!1})}.bind(this)):this.fire(\"neon-animation-finish\",b,{bubbles:!1})}},cancelAnimation:function(){this._player&&this._player.cancel()}};\nPolymer.NeonAnimationRunnerBehavior=[Polymer.NeonAnimatableBehavior,Polymer.NeonAnimationRunnerBehaviorImpl];\n</script>\n\n\n\n\n<script>//~~WEBPATH~~/iron-dropdown/iron-dropdown-scroll-manager.html.js\n(function(){var a=0,b=0,c=null,d=[];Polymer.IronDropdownScrollManager={get currentLockingElement(){return this._lockingElements[this._lockingElements.length-1]},elementIsScrollLocked:function(a){var b=this.currentLockingElement;if(void 0===b)return!1;if(this._hasCachedLockedElement(a))return!0;if(this._hasCachedUnlockedElement(a))return!1;(b=!!b&&b!==a&&!this._composedTreeContains(b,a))?this._lockedElementCache.push(a):this._unlockedElementCache.push(a);return b},pushScrollLock:function(a){0<=this._lockingElements.indexOf(a)||\n(0===this._lockingElements.length&&this._lockScrollInteractions(),this._lockingElements.push(a),this._lockedElementCache=[],this._unlockedElementCache=[])},removeScrollLock:function(a){a=this._lockingElements.indexOf(a);-1!==a&&(this._lockingElements.splice(a,1),this._lockedElementCache=[],this._unlockedElementCache=[],0===this._lockingElements.length&&this._unlockScrollInteractions())},_lockingElements:[],_lockedElementCache:null,_unlockedElementCache:null,_hasCachedLockedElement:function(a){return-1<\nthis._lockedElementCache.indexOf(a)},_hasCachedUnlockedElement:function(a){return-1<this._unlockedElementCache.indexOf(a)},_composedTreeContains:function(a,b){var c,d;if(a.contains(b))return!0;a=Polymer.dom(a).querySelectorAll(\"content\");for(c=0;c<a.length;++c){var e=Polymer.dom(a[c]).getDistributedNodes();for(d=0;d<e.length;++d)if(this._composedTreeContains(e[d],b))return!0}return!1},_scrollInteractionHandler:function(c){c.cancelable&&this._shouldPreventScrolling(c)&&c.preventDefault();c.targetTouches&&\n(c=c.targetTouches[0],a=c.pageX,b=c.pageY)},_lockScrollInteractions:function(){this._boundScrollHandler=this._boundScrollHandler||this._scrollInteractionHandler.bind(this);document.addEventListener(\"wheel\",this._boundScrollHandler,!0);document.addEventListener(\"mousewheel\",this._boundScrollHandler,!0);document.addEventListener(\"DOMMouseScroll\",this._boundScrollHandler,!0);document.addEventListener(\"touchstart\",this._boundScrollHandler,!0);document.addEventListener(\"touchmove\",this._boundScrollHandler,\n!0)},_unlockScrollInteractions:function(){document.removeEventListener(\"wheel\",this._boundScrollHandler,!0);document.removeEventListener(\"mousewheel\",this._boundScrollHandler,!0);document.removeEventListener(\"DOMMouseScroll\",this._boundScrollHandler,!0);document.removeEventListener(\"touchstart\",this._boundScrollHandler,!0);document.removeEventListener(\"touchmove\",this._boundScrollHandler,!0)},_shouldPreventScrolling:function(a){var b=Polymer.dom(a).rootTarget;\"touchmove\"!==a.type&&c!==b&&(c=b,d=this._getScrollableNodes(Polymer.dom(a).path));\nif(!d.length)return!0;if(\"touchstart\"===a.type)return!1;a=this._getScrollInfo(a);return!this._getScrollingNode(d,a.deltaX,a.deltaY)},_getScrollableNodes:function(a){for(var b=[],c=a.indexOf(this.currentLockingElement),d=0;d<=c;d++)if(a[d].nodeType===Node.ELEMENT_NODE){var e=a[d],m=e.style;\"scroll\"!==m.overflow&&\"auto\"!==m.overflow&&(m=window.getComputedStyle(e));\"scroll\"!==m.overflow&&\"auto\"!==m.overflow||b.push(e)}return b},_getScrollingNode:function(a,b,c){if(b||c)for(var d=Math.abs(c)>=Math.abs(b),\ne=0;e<a.length;e++){var f=a[e];if(d?0>c?0<f.scrollTop:f.scrollTop<f.scrollHeight-f.clientHeight:0>b?0<f.scrollLeft:f.scrollLeft<f.scrollWidth-f.clientWidth)return f}},_getScrollInfo:function(c){var d={deltaX:c.deltaX,deltaY:c.deltaY};\"deltaX\"in c||(\"wheelDeltaX\"in c?(d.deltaX=-c.wheelDeltaX,d.deltaY=-c.wheelDeltaY):\"axis\"in c?(d.deltaX=1===c.axis?c.detail:0,d.deltaY=2===c.axis?c.detail:0):c.targetTouches&&(c=c.targetTouches[0],d.deltaX=a-c.pageX,d.deltaY=b-c.pageY));return d}}})();\n</script>\n\n\n\n\n<dom-module id=\"iron-dropdown\">\n  <template>\n    <style>\n      :host {\n        position: fixed;\n      }\n\n      #contentWrapper ::content > * {\n        overflow: auto;\n      }\n\n      #contentWrapper.animating ::content > * {\n        overflow: hidden;\n      }\n    </style>\n\n    <div id=\"contentWrapper\">\n      <content id=\"content\" select=\".dropdown-content\"></content>\n    </div>\n  </template>\n\n  <script>//~~WEBPATH~~/iron-dropdown/iron-dropdown.html.js\nPolymer({is:\"iron-dropdown\",behaviors:[Polymer.IronControlState,Polymer.IronA11yKeysBehavior,Polymer.IronOverlayBehavior,Polymer.NeonAnimationRunnerBehavior],properties:{horizontalAlign:{type:String,value:\"left\",reflectToAttribute:!0},verticalAlign:{type:String,value:\"top\",reflectToAttribute:!0},openAnimationConfig:{type:Object},closeAnimationConfig:{type:Object},focusTarget:{type:Object},noAnimations:{type:Boolean,value:!1},allowOutsideScroll:{type:Boolean,value:!1},_boundOnCaptureScroll:{type:Function,\nvalue:function(){return this._onCaptureScroll.bind(this)}}},listeners:{\"neon-animation-finish\":\"_onNeonAnimationFinish\"},observers:[\"_updateOverlayPosition(positionTarget, verticalAlign, horizontalAlign, verticalOffset, horizontalOffset)\"],get containedElement(){return Polymer.dom(this.$.content).getDistributedNodes()[0]},get _focusTarget(){return this.focusTarget||this.containedElement},ready:function(){this._scrollLeft=this._scrollTop=0;this._refitOnScrollRAF=null},attached:function(){this.sizingTarget&&\nthis.sizingTarget!==this||(this.sizingTarget=this.containedElement||this)},detached:function(){this.cancelAnimation();document.removeEventListener(\"scroll\",this._boundOnCaptureScroll);Polymer.IronDropdownScrollManager.removeScrollLock(this)},_openedChanged:function(){this.opened&&this.disabled?this.cancel():(this.cancelAnimation(),this._updateAnimationConfig(),this._saveScrollPosition(),this.opened?(document.addEventListener(\"scroll\",this._boundOnCaptureScroll),!this.allowOutsideScroll&&Polymer.IronDropdownScrollManager.pushScrollLock(this)):\n(document.removeEventListener(\"scroll\",this._boundOnCaptureScroll),Polymer.IronDropdownScrollManager.removeScrollLock(this)),Polymer.IronOverlayBehaviorImpl._openedChanged.apply(this,arguments))},_renderOpened:function(){!this.noAnimations&&this.animationConfig.open?(this.$.contentWrapper.classList.add(\"animating\"),this.playAnimation(\"open\")):Polymer.IronOverlayBehaviorImpl._renderOpened.apply(this,arguments)},_renderClosed:function(){!this.noAnimations&&this.animationConfig.close?(this.$.contentWrapper.classList.add(\"animating\"),\nthis.playAnimation(\"close\")):Polymer.IronOverlayBehaviorImpl._renderClosed.apply(this,arguments)},_onNeonAnimationFinish:function(){this.$.contentWrapper.classList.remove(\"animating\");this.opened?this._finishRenderOpened():this._finishRenderClosed()},_onCaptureScroll:function(){this.allowOutsideScroll?(this._refitOnScrollRAF&&window.cancelAnimationFrame(this._refitOnScrollRAF),this._refitOnScrollRAF=window.requestAnimationFrame(this.refit.bind(this))):this._restoreScrollPosition()},_saveScrollPosition:function(){document.scrollingElement?\n(this._scrollTop=document.scrollingElement.scrollTop,this._scrollLeft=document.scrollingElement.scrollLeft):(this._scrollTop=Math.max(document.documentElement.scrollTop,document.body.scrollTop),this._scrollLeft=Math.max(document.documentElement.scrollLeft,document.body.scrollLeft))},_restoreScrollPosition:function(){document.scrollingElement?(document.scrollingElement.scrollTop=this._scrollTop,document.scrollingElement.scrollLeft=this._scrollLeft):(document.documentElement.scrollTop=this._scrollTop,\ndocument.documentElement.scrollLeft=this._scrollLeft,document.body.scrollTop=this._scrollTop,document.body.scrollLeft=this._scrollLeft)},_updateAnimationConfig:function(){for(var a=this.containedElement,b=[].concat(this.openAnimationConfig||[]).concat(this.closeAnimationConfig||[]),c=0;c<b.length;c++)b[c].node=a;this.animationConfig={open:this.openAnimationConfig,close:this.closeAnimationConfig}},_updateOverlayPosition:function(){this.isAttached&&this.notifyResize()},_applyFocus:function(){var a=\nthis.focusTarget||this.containedElement;a&&this.opened&&!this.noAutoFocus?a.focus():Polymer.IronOverlayBehaviorImpl._applyFocus.apply(this,arguments)}});\n</script>\n</dom-module>\n\n\n\n\n\n\n\n<script>//~~WEBPATH~~/neon-animation/animations/fade-in-animation.html.js\nPolymer({is:\"fade-in-animation\",behaviors:[Polymer.NeonAnimationBehavior],configure:function(a){return this._effect=new KeyframeEffect(a.node,[{opacity:\"0\"},{opacity:\"1\"}],this.timingFromConfig(a))}});\n</script>\n\n\n\n\n\n\n\n<script>//~~WEBPATH~~/neon-animation/animations/fade-out-animation.html.js\nPolymer({is:\"fade-out-animation\",behaviors:[Polymer.NeonAnimationBehavior],configure:function(a){return this._effect=new KeyframeEffect(a.node,[{opacity:\"1\"},{opacity:\"0\"}],this.timingFromConfig(a))}});\n</script>\n\n\n\n\n<style is=\"custom-style\">\n\n  :root {\n\n    --shadow-transition: {\n      transition: box-shadow 0.28s cubic-bezier(0.4, 0, 0.2, 1);\n    };\n\n    --shadow-none: {\n      box-shadow: none;\n    };\n\n    /* from http://codepen.io/shyndman/pen/c5394ddf2e8b2a5c9185904b57421cdb */\n\n    --shadow-elevation-2dp: {\n      box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14),\n                  0 1px 5px 0 rgba(0, 0, 0, 0.12),\n                  0 3px 1px -2px rgba(0, 0, 0, 0.2);\n    };\n\n    --shadow-elevation-3dp: {\n      box-shadow: 0 3px 4px 0 rgba(0, 0, 0, 0.14),\n                  0 1px 8px 0 rgba(0, 0, 0, 0.12),\n                  0 3px 3px -2px rgba(0, 0, 0, 0.4);\n    };\n\n    --shadow-elevation-4dp: {\n      box-shadow: 0 4px 5px 0 rgba(0, 0, 0, 0.14),\n                  0 1px 10px 0 rgba(0, 0, 0, 0.12),\n                  0 2px 4px -1px rgba(0, 0, 0, 0.4);\n    };\n\n    --shadow-elevation-6dp: {\n      box-shadow: 0 6px 10px 0 rgba(0, 0, 0, 0.14),\n                  0 1px 18px 0 rgba(0, 0, 0, 0.12),\n                  0 3px 5px -1px rgba(0, 0, 0, 0.4);\n    };\n\n    --shadow-elevation-8dp: {\n      box-shadow: 0 8px 10px 1px rgba(0, 0, 0, 0.14),\n                  0 3px 14px 2px rgba(0, 0, 0, 0.12),\n                  0 5px 5px -3px rgba(0, 0, 0, 0.4);\n    };\n\n    --shadow-elevation-12dp: {\n      box-shadow: 0 12px 16px 1px rgba(0, 0, 0, 0.14),\n                  0 4px 22px 3px rgba(0, 0, 0, 0.12),\n                  0 6px 7px -4px rgba(0, 0, 0, 0.4);\n    };\n\n    --shadow-elevation-16dp: {\n      box-shadow: 0 16px 24px 2px rgba(0, 0, 0, 0.14),\n                  0  6px 30px 5px rgba(0, 0, 0, 0.12),\n                  0  8px 10px -5px rgba(0, 0, 0, 0.4);\n    };\n\n  }\n\n</style>\n\n\n\n\n<script>//~~WEBPATH~~/paper-menu-button/paper-menu-button-animations.html.js\nPolymer({is:\"paper-menu-grow-height-animation\",behaviors:[Polymer.NeonAnimationBehavior],configure:function(a){var b=a.node,c=b.getBoundingClientRect().height;return this._effect=new KeyframeEffect(b,[{height:c/2+\"px\"},{height:c+\"px\"}],this.timingFromConfig(a))}});Polymer({is:\"paper-menu-grow-width-animation\",behaviors:[Polymer.NeonAnimationBehavior],configure:function(a){var b=a.node,c=b.getBoundingClientRect().width;return this._effect=new KeyframeEffect(b,[{width:c/2+\"px\"},{width:c+\"px\"}],this.timingFromConfig(a))}});\nPolymer({is:\"paper-menu-shrink-width-animation\",behaviors:[Polymer.NeonAnimationBehavior],configure:function(a){var b=a.node,c=b.getBoundingClientRect().width;return this._effect=new KeyframeEffect(b,[{width:c+\"px\"},{width:c-c/20+\"px\"}],this.timingFromConfig(a))}});\nPolymer({is:\"paper-menu-shrink-height-animation\",behaviors:[Polymer.NeonAnimationBehavior],configure:function(a){var b=a.node,c=b.getBoundingClientRect().height;this.setPrefixedProperty(b,\"transformOrigin\",\"0 0\");return this._effect=new KeyframeEffect(b,[{height:c+\"px\",transform:\"translateY(0)\"},{height:c/2+\"px\",transform:\"translateY(-20px)\"}],this.timingFromConfig(a))}});\n</script>\n\n\n\n\n\n\n<dom-module id=\"paper-menu-button\">\n  <template>\n    <style>\n      :host {\n        display: inline-block;\n        position: relative;\n        padding: 8px;\n        outline: none;\n\n        @apply(--paper-menu-button);\n      }\n\n      :host([disabled]) {\n        cursor: auto;\n        color: var(--disabled-text-color);\n\n        @apply(--paper-menu-button-disabled);\n      }\n\n      iron-dropdown {\n        @apply(--paper-menu-button-dropdown);\n      }\n\n      .dropdown-content {\n        @apply(--shadow-elevation-2dp);\n\n        position: relative;\n        border-radius: 2px;\n        background-color: var(--paper-menu-button-dropdown-background, --primary-background-color);\n\n        @apply(--paper-menu-button-content);\n      }\n\n      :host([vertical-align=\"top\"]) .dropdown-content {\n        margin-bottom: 20px;\n        margin-top: -10px;\n        top: 10px;\n      }\n\n      :host([vertical-align=\"bottom\"]) .dropdown-content {\n        bottom: 10px;\n        margin-bottom: -10px;\n        margin-top: 20px;\n      }\n    </style>\n\n    <div id=\"trigger\" on-tap=\"toggle\">\n      <content select=\".dropdown-trigger\"></content>\n    </div>\n\n    <iron-dropdown id=\"dropdown\" opened=\"{{opened}}\" horizontal-align=\"[[horizontalAlign]]\" vertical-align=\"[[verticalAlign]]\" dynamic-align=\"[[dynamicAlign]]\" horizontal-offset=\"[[horizontalOffset]]\" vertical-offset=\"[[verticalOffset]]\" no-overlap=\"[[noOverlap]]\" open-animation-config=\"[[openAnimationConfig]]\" close-animation-config=\"[[closeAnimationConfig]]\" no-animations=\"[[noAnimations]]\" focus-target=\"[[_dropdownContent]]\" allow-outside-scroll=\"[[allowOutsideScroll]]\" restore-focus-on-close=\"[[restoreFocusOnClose]]\" on-iron-overlay-canceled=\"__onIronOverlayCanceled\">\n      <div class=\"dropdown-content\">\n        <content id=\"content\" select=\".dropdown-content\"></content>\n      </div>\n    </iron-dropdown>\n  </template>\n\n  <script>//~~WEBPATH~~/paper-menu-button/paper-menu-button.html.js\nfunction Zd(){}h=Zd.prototype;h.registered=function(){};h.addOwnKeyBinding=function(){};h.removeOwnKeyBindings=function(){};h.keyboardEventMatchesKeys=function(){};h._collectKeyBindings=function(){};h._prepKeyBindings=function(){};h._addKeyBinding=function(){};h._resetKeyEventListeners=function(){};h._listenKeyEventListeners=function(){};h._unlistenKeyEventListeners=function(){};h._onKeyBindingEvent=function(){};h._triggerKeyHandler=function(){};\nh._focusBlurHandler=function(a){if(a.target===this)this._setFocused(\"focus\"===a.type);else if(!this.shadowRoot){var b=Polymer.dom(a).localTarget;this.isLightDescendant(b)||this.fire(a.type,{sourceEvent:a},{node:this,bubbles:a.bubbles,cancelable:a.cancelable})}};h._changedControlState=function(){this._controlStateChanged&&this._controlStateChanged()};h._setFocused=function(){};\n(function(){var a={ANIMATION_CUBIC_BEZIER:\"cubic-bezier(.3,.95,.5,1)\",MAX_ANIMATION_TIME_MS:400};Zd=Polymer({is:\"paper-menu-button\",behaviors:[Polymer.IronA11yKeysBehavior,Polymer.IronControlState],properties:{opened:{type:Boolean,value:!1,notify:!0,observer:\"_openedChanged\"},horizontalAlign:{type:String,value:\"left\",reflectToAttribute:!0},verticalAlign:{type:String,value:\"top\",reflectToAttribute:!0},dynamicAlign:{type:Boolean},horizontalOffset:{type:Number,value:0,notify:!0},verticalOffset:{type:Number,\nvalue:0,notify:!0},noOverlap:{type:Boolean},noAnimations:{type:Boolean,value:!1},ignoreSelect:{type:Boolean,value:!1},closeOnActivate:{type:Boolean,value:!1},openAnimationConfig:{type:Object,value:function(){return[{name:\"fade-in-animation\",timing:{delay:100,duration:200}},{name:\"paper-menu-grow-width-animation\",timing:{delay:100,duration:150,easing:a.ANIMATION_CUBIC_BEZIER}},{name:\"paper-menu-grow-height-animation\",timing:{delay:100,duration:275,easing:a.ANIMATION_CUBIC_BEZIER}}]}},closeAnimationConfig:{type:Object,\nvalue:function(){return[{name:\"fade-out-animation\",timing:{duration:150}},{name:\"paper-menu-shrink-width-animation\",timing:{delay:100,duration:50,easing:a.ANIMATION_CUBIC_BEZIER}},{name:\"paper-menu-shrink-height-animation\",timing:{duration:200,easing:\"ease-in\"}}]}},allowOutsideScroll:{type:Boolean,value:!1},restoreFocusOnClose:{type:Boolean,value:!0},_dropdownContent:{type:Object}},hostAttributes:{role:\"group\",\"aria-haspopup\":\"true\"},listeners:{\"iron-activate\":\"_onIronActivate\",\"iron-select\":\"_onIronSelect\"},\nget contentElement(){return Polymer.dom(this.$.content).getDistributedNodes()[0]},toggle:function(){this.opened?this.close():this.open()},open:function(){this.disabled||this.$.dropdown.open()},close:function(){this.$.dropdown.close()},_onIronSelect:function(){this.ignoreSelect||this.close()},_onIronActivate:function(){this.closeOnActivate&&this.close()},_openedChanged:function(a,c){a?(this._dropdownContent=this.contentElement,this.fire(\"paper-dropdown-open\")):null!=c&&this.fire(\"paper-dropdown-close\")},\n_disabledChanged:function(a){Polymer.IronControlState._disabledChanged.apply(this,arguments);a&&this.opened&&this.close()},__onIronOverlayCanceled:function(a){var b=a.detail;Polymer.dom(b);var d=this.$.trigger;-1<Polymer.dom(b).path.indexOf(d)&&a.preventDefault()}});Object.keys(a).forEach(function(b){Zd[b]=a[b]});Polymer.PaperMenuButton=Zd})();\n</script>\n</dom-module>\n\n\n\n\n\n\n\n<script>//~~WEBPATH~~/iron-iconset-svg/iron-iconset-svg.html.js\nPolymer({is:\"iron-iconset-svg\",properties:{name:{type:String,observer:\"_nameChanged\"},size:{type:Number,value:24},rtlMirroring:{type:Boolean,value:!1}},created:function(){this._meta=new Polymer.IronMeta({type:\"iconset\",key:null,value:null})},attached:function(){this.style.display=\"none\"},getIconNames:function(){this._icons=this._createIconMap();return Object.keys(this._icons).map(function(a){return this.name+\":\"+a},this)},applyIcon:function(a,b){this.removeIcon(a);if(b=this._cloneIcon(b,this.rtlMirroring&&\nthis._targetIsRTL(a))){var c=Polymer.dom(a.root||a);c.insertBefore(b,c.childNodes[0]);return a._svgIcon=b}return null},removeIcon:function(a){a._svgIcon&&(Polymer.dom(a.root||a).removeChild(a._svgIcon),a._svgIcon=null)},_targetIsRTL:function(a){null==this.__targetIsRTL&&(a&&a.nodeType!==Node.ELEMENT_NODE&&(a=a.host),this.__targetIsRTL=a&&\"rtl\"===window.getComputedStyle(a).direction);return this.__targetIsRTL},_nameChanged:function(){this._meta.value=null;this._meta.key=this.name;this._meta.value=\nthis;this.async(function(){this.fire(\"iron-iconset-added\",this,{node:window})})},_createIconMap:function(){var a=Object.create(null);Polymer.dom(this).querySelectorAll(\"[id]\").forEach(function(b){a[b.id]=b});return a},_cloneIcon:function(a,b){this._icons=this._icons||this._createIconMap();return this._prepareSvgClone(this._icons[a],this.size,b)},_prepareSvgClone:function(a,b,c){if(a){a=a.cloneNode(!0);var d=document.createElementNS(\"http://www.w3.org/2000/svg\",\"svg\");b=a.getAttribute(\"viewBox\")||\n\"0 0 \"+b+\" \"+b;var e=\"pointer-events: none; display: block; width: 100%; height: 100%;\";c&&a.hasAttribute(\"mirror-in-rtl\")&&(e+=\"-webkit-transform:scale(-1,1);transform:scale(-1,1);\");d.setAttribute(\"viewBox\",b);d.setAttribute(\"preserveAspectRatio\",\"xMidYMid meet\");d.style.cssText=e;d.appendChild(a).removeAttribute(\"id\");return d}return null}});\n</script>\n\n\n<iron-iconset-svg name=\"paper-dropdown-menu\" size=\"24\">\n<svg><defs>\n<g id=\"arrow-drop-down\"><path d=\"M7 10l5 5 5-5z\"></path></g>\n</defs></svg>\n</iron-iconset-svg>\n\n\n\n<dom-module id=\"paper-dropdown-menu-shared-styles\">\n  <template>\n    <style>\n      :host {\n        display: inline-block;\n        position: relative;\n        text-align: left;\n        cursor: pointer;\n\n        /* NOTE(cdata): Both values are needed, since some phones require the\n         * value to be `transparent`.\n         */\n        -webkit-tap-highlight-color: rgba(0,0,0,0);\n        -webkit-tap-highlight-color: transparent;\n\n        --paper-input-container-input: {\n          overflow: hidden;\n          white-space: nowrap;\n          text-overflow: ellipsis;\n          max-width: 100%;\n          box-sizing: border-box;\n          cursor: pointer;\n        };\n\n        @apply(--paper-dropdown-menu);\n      }\n\n      :host([disabled]) {\n        @apply(--paper-dropdown-menu-disabled);\n      }\n\n      :host([noink]) paper-ripple {\n        display: none;\n      }\n\n      :host([no-label-float]) paper-ripple {\n        top: 8px;\n      }\n\n      paper-ripple {\n        top: 12px;\n        left: 0px;\n        bottom: 8px;\n        right: 0px;\n\n        @apply(--paper-dropdown-menu-ripple);\n      }\n\n      paper-menu-button {\n        display: block;\n        padding: 0;\n\n        @apply(--paper-dropdown-menu-button);\n      }\n\n      paper-input {\n        @apply(--paper-dropdown-menu-input);\n      }\n\n      iron-icon {\n        color: var(--disabled-text-color);\n\n        @apply(--paper-dropdown-menu-icon);\n      }\n    </style>\n  </template>\n</dom-module>\n\n\n\n\n<dom-module id=\"paper-dropdown-menu\">\n  <template>\n    <style include=\"paper-dropdown-menu-shared-styles\"></style>\n\n    \n    <span role=\"button\"></span>\n    <paper-menu-button id=\"menuButton\" vertical-align=\"[[verticalAlign]]\" horizontal-align=\"[[horizontalAlign]]\" dynamic-align=\"[[dynamicAlign]]\" vertical-offset=\"[[_computeMenuVerticalOffset(noLabelFloat)]]\" disabled=\"[[disabled]]\" no-animations=\"[[noAnimations]]\" on-iron-select=\"_onIronSelect\" on-iron-deselect=\"_onIronDeselect\" opened=\"{{opened}}\" close-on-activate allow-outside-scroll=\"[[allowOutsideScroll]]\">\n      <div class=\"dropdown-trigger\">\n        <paper-ripple></paper-ripple>\n        \n        <paper-input type=\"text\" invalid=\"[[invalid]]\" readonly disabled=\"[[disabled]]\" value=\"[[selectedItemLabel]]\" placeholder=\"[[placeholder]]\" error-message=\"[[errorMessage]]\" always-float-label=\"[[alwaysFloatLabel]]\" no-label-float=\"[[noLabelFloat]]\" label=\"[[label]]\">\n          <iron-icon icon=\"paper-dropdown-menu:arrow-drop-down\" suffix></iron-icon>\n        </paper-input>\n      </div>\n      <content id=\"content\" select=\".dropdown-content\"></content>\n    </paper-menu-button>\n  </template>\n\n  <script>//~~WEBPATH~~/paper-dropdown-menu/paper-dropdown-menu.html.js\nPolymer({is:\"paper-dropdown-menu\",behaviors:[Polymer.IronButtonState,Polymer.IronControlState,Polymer.IronFormElementBehavior,Polymer.IronValidatableBehavior],properties:{selectedItemLabel:{type:String,notify:!0,readOnly:!0},selectedItem:{type:Object,notify:!0,readOnly:!0},value:{type:String,notify:!0,readOnly:!0},label:{type:String},placeholder:{type:String},errorMessage:{type:String},opened:{type:Boolean,notify:!0,value:!1,observer:\"_openedChanged\"},allowOutsideScroll:{type:Boolean,value:!1},noLabelFloat:{type:Boolean,\nvalue:!1,reflectToAttribute:!0},alwaysFloatLabel:{type:Boolean,value:!1},noAnimations:{type:Boolean,value:!1},horizontalAlign:{type:String,value:\"right\"},verticalAlign:{type:String,value:\"top\"},dynamicAlign:{type:Boolean}},listeners:{tap:\"_onTap\"},keyBindings:{\"up down\":\"open\",esc:\"close\"},hostAttributes:{role:\"combobox\",\"aria-autocomplete\":\"none\",\"aria-haspopup\":\"true\"},observers:[\"_selectedItemChanged(selectedItem)\"],attached:function(){var a=this.contentElement;a&&a.selectedItem&&this._setSelectedItem(a.selectedItem)},\nget contentElement(){return Polymer.dom(this.$.content).getDistributedNodes()[0]},open:function(){this.$.menuButton.open()},close:function(){this.$.menuButton.close()},_onIronSelect:function(a){this._setSelectedItem(a.detail.item)},_onIronDeselect:function(){this._setSelectedItem(null)},_onTap:function(a){Polymer.Gestures.findOriginalTarget(a)===this&&this.open()},_selectedItemChanged:function(a){a=a?a.label||a.getAttribute(\"label\")||a.textContent.trim():\"\";this._setValue(a);this._setSelectedItemLabel(a)},\n_computeMenuVerticalOffset:function(a){return a?-4:8},_getValidity:function(){return this.disabled||!this.required||this.required&&!!this.value},_openedChanged:function(){var a=this.opened?\"true\":\"false\",b=this.contentElement;b&&b.setAttribute(\"aria-expanded\",a)}});\n</script>\n</dom-module>\n\n\n\n\n\n\n\n<script>//~~WEBPATH~~/iron-selector/iron-selection.html.js\nPolymer.IronSelection=function(a){this.selection=[];this.selectCallback=a};Polymer.IronSelection.prototype={get:function(){return this.multi?this.selection.slice():this.selection[0]},clear:function(a){this.selection.slice().forEach(function(b){(!a||0>a.indexOf(b))&&$d(this,b,!1)},this)},isSelected:function(a){return 0<=this.selection.indexOf(a)},select:function(a){this.multi?this.toggle(a):this.get()!==a&&($d(this,this.get(),!1),$d(this,a,!0))},toggle:function(a){$d(this,a,!this.isSelected(a))}};\nfunction $d(a,b,c){if(null!=b&&c!==a.isSelected(b)){if(c)a.selection.push(b);else{var d=a.selection.indexOf(b);0<=d&&a.selection.splice(d,1)}a.selectCallback&&a.selectCallback(b,c)}};\n</script>\n\n\n<script>//~~WEBPATH~~/iron-selector/iron-selectable.html.js\nPolymer.IronSelectableBehavior={properties:{attrForSelected:{type:String,value:null},selected:{type:String,notify:!0},selectedItem:{type:Object,readOnly:!0,notify:!0},activateEvent:{type:String,value:\"tap\",observer:\"_activateEventChanged\"},selectable:String,selectedClass:{type:String,value:\"iron-selected\"},selectedAttribute:{type:String,value:null},fallbackSelection:{type:String,value:null},items:{type:Array,readOnly:!0,notify:!0,value:function(){return[]}},_excludedLocalNames:{type:Object,value:function(){return{template:1}}}},\nobservers:[\"_updateAttrForSelected(attrForSelected)\",\"_updateSelected(selected)\",\"_checkFallback(fallbackSelection)\"],created:function(){this._bindFilterItem=this._filterItem.bind(this);this._selection=new Polymer.IronSelection(this._applySelection.bind(this))},attached:function(){this._observer=this._observeItems(this);this._updateItems();this._shouldUpdateSelection||this._updateSelected();this._addListener(this.activateEvent)},detached:function(){this._observer&&Polymer.dom(this).unobserveNodes(this._observer);\nthis._removeListener(this.activateEvent)},indexOf:function(a){return this.items.indexOf(a)},select:function(a){this.selected=a},selectPrevious:function(){var a=this.items.length,a=(Number(this._valueToIndex(this.selected))-1+a)%a;this.selected=this._indexToValue(a)},selectNext:function(){var a=(Number(this._valueToIndex(this.selected))+1)%this.items.length;this.selected=this._indexToValue(a)},selectIndex:function(a){this.select(this._indexToValue(a))},forceSynchronousItemUpdate:function(){this._updateItems()},\nget _shouldUpdateSelection(){return null!=this.selected},_checkFallback:function(){this._shouldUpdateSelection&&this._updateSelected()},_addListener:function(a){this.listen(this,a,\"_activateHandler\")},_removeListener:function(a){this.unlisten(this,a,\"_activateHandler\")},_activateEventChanged:function(a,b){this._removeListener(b);this._addListener(a)},_updateItems:function(){var a=Polymer.dom(this).queryDistributedElements(this.selectable||\"*\"),a=Array.prototype.filter.call(a,this._bindFilterItem);\nthis._setItems(a)},_updateAttrForSelected:function(){this._shouldUpdateSelection&&(this.selected=this._indexToValue(this.indexOf(this.selectedItem)))},_updateSelected:function(){this._selectSelected(this.selected)},_selectSelected:function(){this._selection.select(this._valueToItem(this.selected));this.fallbackSelection&&this.items.length&&void 0===this._selection.get()&&(this.selected=this.fallbackSelection)},_filterItem:function(a){return!this._excludedLocalNames[a.localName]},_valueToItem:function(a){return null==\na?null:this.items[this._valueToIndex(a)]},_valueToIndex:function(a){if(this.attrForSelected)for(var b=0,c;c=this.items[b];b++){if(this._valueForItem(c)==a)return b}else return Number(a)},_indexToValue:function(a){if(this.attrForSelected){if(a=this.items[a])return this._valueForItem(a)}else return a},_valueForItem:function(a){var b=a[Polymer.CaseMap.dashToCamelCase(this.attrForSelected)];return void 0!=b?b:a.getAttribute(this.attrForSelected)},_applySelection:function(a,b){this.selectedClass&&this.toggleClass(this.selectedClass,\nb,a);this.selectedAttribute&&this.toggleAttribute(this.selectedAttribute,b,a);this._selectionChange();this.fire(\"iron-\"+(b?\"select\":\"deselect\"),{item:a})},_selectionChange:function(){this._setSelectedItem(this._selection.get())},_observeItems:function(a){return Polymer.dom(a).observeNodes(function(a){this._updateItems();this._shouldUpdateSelection&&this._updateSelected();this.fire(\"iron-items-changed\",a,{bubbles:!1,cancelable:!1})})},_activateHandler:function(a){a=a.target;for(var b=this.items;a&&\na!=this;){var c=b.indexOf(a);if(0<=c){b=this._indexToValue(c);this._itemActivate(b,a);break}a=a.parentNode}},_itemActivate:function(a,b){this.fire(\"iron-activate\",{selected:a,item:b},{cancelable:!0}).defaultPrevented||this.select(a)}};\n</script>\n\n\n<script>//~~WEBPATH~~/iron-selector/iron-multi-selectable.html.js\nPolymer.IronMultiSelectableBehaviorImpl={properties:{multi:{type:Boolean,value:!1,observer:\"multiChanged\"},selectedValues:{type:Array,notify:!0},selectedItems:{type:Array,readOnly:!0,notify:!0}},observers:[\"_updateSelected(selectedValues.splices)\"],select:function(a){this.multi?this.selectedValues?this._toggleSelected(a):this.selectedValues=[a]:this.selected=a},multiChanged:function(a){this._selection.multi=a},get _shouldUpdateSelection(){return null!=this.selected||null!=this.selectedValues&&this.selectedValues.length},\n_updateAttrForSelected:function(){this.multi?this._shouldUpdateSelection&&(this.selectedValues=this.selectedItems.map(function(a){return this._indexToValue(this.indexOf(a))},this).filter(function(a){return null!=a},this)):Polymer.IronSelectableBehavior._updateAttrForSelected.apply(this)},_updateSelected:function(){this.multi?this._selectMulti(this.selectedValues):this._selectSelected(this.selected)},_selectMulti:function(a){if(a){a=this._valuesToItems(a);this._selection.clear(a);for(var b=0;b<a.length;b++)$d(this._selection,\na[b],!0);this.fallbackSelection&&this.items.length&&!this._selection.get().length&&this._valueToItem(this.fallbackSelection)&&(this.selectedValues=[this.fallbackSelection])}else this._selection.clear()},_selectionChange:function(){var a=this._selection.get();this.multi?this._setSelectedItems(a):(this._setSelectedItems([a]),this._setSelectedItem(a))},_toggleSelected:function(a){var b=this.selectedValues.indexOf(a);0>b?this.push(\"selectedValues\",a):this.splice(\"selectedValues\",b,1)},_valuesToItems:function(a){return null==\na?null:a.map(function(a){return this._valueToItem(a)},this)}};Polymer.IronMultiSelectableBehavior=[Polymer.IronSelectableBehavior,Polymer.IronMultiSelectableBehaviorImpl];\n</script>\n\n\n\n<script>//~~WEBPATH~~/iron-menu-behavior/iron-menu-behavior.html.js\nPolymer.IronMenuBehaviorImpl={properties:{focusedItem:{observer:\"_focusedItemChanged\",readOnly:!0,type:Object},attrForItemTitle:{type:String},disabled:{type:Boolean,value:!1,observer:\"_disabledChanged\"}},_SEARCH_RESET_TIMEOUT_MS:1E3,_previousTabIndex:0,hostAttributes:{role:\"menu\"},observers:[\"_updateMultiselectable(multi)\"],listeners:{focus:\"_onFocus\",keydown:\"_onKeydown\",\"iron-items-changed\":\"_onIronItemsChanged\"},keyBindings:{up:\"_onUpKey\",down:\"_onDownKey\",esc:\"_onEscKey\",\"shift+tab:keydown\":\"_onShiftTabDown\"},\nattached:function(){this._resetTabindices()},select:function(a){this._defaultFocusAsync&&(this.cancelAsync(this._defaultFocusAsync),this._defaultFocusAsync=null);var b=this._valueToItem(a);b&&b.hasAttribute(\"disabled\")||(this._setFocusedItem(b),Polymer.IronMultiSelectableBehaviorImpl.select.apply(this,arguments))},_resetTabindices:function(){var a=this.multi?this.selectedItems&&this.selectedItems[0]:this.selectedItem;this.items.forEach(function(b){b.setAttribute(\"tabindex\",b===a?\"0\":\"-1\")},this)},\n_updateMultiselectable:function(a){a?this.setAttribute(\"aria-multiselectable\",\"true\"):this.removeAttribute(\"aria-multiselectable\")},_focusWithKeyboardEvent:function(a){this.cancelDebouncer(\"_clearSearchText\");var b=this._searchText||\"\",b=b+(a.key&&1==a.key.length?a.key:String.fromCharCode(a.keyCode)).toLocaleLowerCase();a=b.length;for(var c=0,d;d=this.items[c];c++)if(!d.hasAttribute(\"disabled\")){var e=this.attrForItemTitle||\"textContent\",e=(d[e]||d.getAttribute(e)||\"\").trim();if(!(e.length<a)&&e.slice(0,\na).toLocaleLowerCase()==b){this._setFocusedItem(d);break}}this._searchText=b;this.debounce(\"_clearSearchText\",this._clearSearchText,this._SEARCH_RESET_TIMEOUT_MS)},_clearSearchText:function(){this._searchText=\"\"},_focusPrevious:function(){for(var a=this.items.length,b=Number(this.indexOf(this.focusedItem)),c=1;c<a+1;c++){var d=this.items[(b-c+a)%a];if(!d.hasAttribute(\"disabled\")){var e=Polymer.dom(d).getOwnerRoot()||document;this._setFocusedItem(d);if(Polymer.dom(e).activeElement==d)break}}},_focusNext:function(){for(var a=\nthis.items.length,b=Number(this.indexOf(this.focusedItem)),c=1;c<a+1;c++){var d=this.items[(b+c)%a];if(!d.hasAttribute(\"disabled\")){var e=Polymer.dom(d).getOwnerRoot()||document;this._setFocusedItem(d);if(Polymer.dom(e).activeElement==d)break}}},_applySelection:function(a,b){b?a.setAttribute(\"aria-selected\",\"true\"):a.removeAttribute(\"aria-selected\");Polymer.IronSelectableBehavior._applySelection.apply(this,arguments)},_focusedItemChanged:function(a,b){b&&b.setAttribute(\"tabindex\",\"-1\");!a||a.hasAttribute(\"disabled\")||\nthis.disabled||(a.setAttribute(\"tabindex\",\"0\"),a.focus())},_onIronItemsChanged:function(a){a.detail.addedNodes.length&&this._resetTabindices()},_onShiftTabDown:function(){var a=this.getAttribute(\"tabindex\");Polymer.IronMenuBehaviorImpl._shiftTabPressed=!0;this._setFocusedItem(null);this.setAttribute(\"tabindex\",\"-1\");this.async(function(){this.setAttribute(\"tabindex\",a);Polymer.IronMenuBehaviorImpl._shiftTabPressed=!1},1)},_onFocus:function(a){!Polymer.IronMenuBehaviorImpl._shiftTabPressed&&(a=Polymer.dom(a).rootTarget,\na===this||\"undefined\"===typeof a.tabIndex||this.isLightDescendant(a))&&(this._defaultFocusAsync=this.async(function(){var a=this.multi?this.selectedItems&&this.selectedItems[0]:this.selectedItem;this._setFocusedItem(null);a?this._setFocusedItem(a):this.items[0]&&this._focusNext()}))},_onUpKey:function(a){this._focusPrevious();a.detail.keyboardEvent.preventDefault()},_onDownKey:function(a){this._focusNext();a.detail.keyboardEvent.preventDefault()},_onEscKey:function(){var a=this.focusedItem;a&&a.blur()},\n_onKeydown:function(a){this.keyboardEventMatchesKeys(a,\"up down esc\")||this._focusWithKeyboardEvent(a);a.stopPropagation()},_activateHandler:function(a){Polymer.IronSelectableBehavior._activateHandler.call(this,a);a.stopPropagation()},_disabledChanged:function(a){a?(this._previousTabIndex=this.hasAttribute(\"tabindex\")?this.tabIndex:0,this.removeAttribute(\"tabindex\")):this.hasAttribute(\"tabindex\")||this.setAttribute(\"tabindex\",this._previousTabIndex)}};\nPolymer.IronMenuBehaviorImpl._shiftTabPressed=!1;Polymer.IronMenuBehavior=[Polymer.IronMultiSelectableBehavior,Polymer.IronA11yKeysBehavior,Polymer.IronMenuBehaviorImpl];\n</script>\n\n\n\n\n\n<dom-module id=\"paper-listbox\">\n  <template>\n    <style>\n      :host {\n        display: block;\n        padding: 8px 0;\n\n        background: var(--paper-listbox-background-color, var(--primary-background-color));\n        color: var(--paper-listbox-color, var(--primary-text-color));\n\n        @apply --paper-listbox;\n      }\n    </style>\n\n    <slot></slot>\n  </template>\n\n  <script>//~~WEBPATH~~/paper-listbox/paper-listbox.html.js\nPolymer({is:\"paper-listbox\",behaviors:[Polymer.IronMenuBehavior],hostAttributes:{role:\"listbox\"}});\n</script>\n</dom-module>\n\n\n\n\n\n\n\n\n\n\n<script>//~~WEBPATH~~/paper-item/paper-item-behavior.html.js\nPolymer.PaperItemBehaviorImpl={hostAttributes:{role:\"option\",tabindex:\"0\"}};Polymer.PaperItemBehavior=[Polymer.IronButtonState,Polymer.IronControlState,Polymer.PaperItemBehaviorImpl];\n</script>\n\n\n\n\n\n<dom-module id=\"paper-item-shared-styles\">\n  <template>\n    <style>\n      :host {\n        display: block;\n        position: relative;\n        min-height: var(--paper-item-min-height, 48px);\n        padding: 0px 16px;\n      }\n\n      :host([hidden]) {\n        display: none !important;\n      }\n\n      :host(.iron-selected) {\n        font-weight: var(--paper-item-selected-weight, bold);\n\n        @apply(--paper-item-selected);\n      }\n\n      :host([disabled]) {\n        color: var(--paper-item-disabled-color, --disabled-text-color);\n\n        @apply(--paper-item-disabled);\n      }\n\n      :host(:focus) {\n        position: relative;\n        outline: 0;\n\n        @apply(--paper-item-focused);\n      }\n\n      :host(:focus):before {\n        @apply(--layout-fit);\n\n        background: currentColor;\n        content: '';\n        opacity: var(--dark-divider-opacity);\n        pointer-events: none;\n\n        @apply(--paper-item-focused-before);\n      }\n    </style>\n  </template>\n</dom-module>\n\n\n\n\n<dom-module id=\"paper-item\">\n  <template>\n    <style include=\"paper-item-shared-styles\"></style>\n    <style>\n      :host {\n        @apply(--layout-horizontal);\n        @apply(--layout-center);\n        @apply(--paper-font-subhead);\n\n        @apply(--paper-item);\n      }\n    </style>\n\n    <content></content>\n  </template>\n\n  <script>//~~WEBPATH~~/paper-item/paper-item.html.js\nPolymer({is:\"paper-item\",behaviors:[Polymer.PaperItemBehavior]});\n</script>\n</dom-module>\n\n\n\n\n<script>//~~WEBPATH~~/tf-imports/plottable.js\n/*\n MIT\n MIT\n\n @fileoverview manually add d3-selection-multi to d3 default bundle. Most of this code is\n copied from d3-selection-multi@1.0.0.\n See https://github.com/d3/d3-selection-multi/issues/11 for why we have to do this\n Plottable 3.1.0 (https://github.com/palantir/plottable)\n Copyright 2014-2017 Palantir Technologies\n Licensed under MIT (https://github.com/palantir/plottable/blob/master/LICENSE)\n*/\nfunction ae(a){return function(a){function b(c){if(d[c])return d[c].exports;var e=d[c]={i:c,l:!1,exports:{}};a[c].call(e.exports,e,e.exports,b);e.l=!0;return e.exports}var d={};b.m=a;b.c=d;b.i=function(a){return a};b.d=function(a,c,d){b.o(a,c)||Object.defineProperty(a,c,{configurable:!1,enumerable:!0,get:d})};b.n=function(a){var c=a&&a.__esModule?function(){return a[\"default\"]}:function(){return a};b.d(c,\"a\",c);return c};b.o=function(a,b){return Object.prototype.hasOwnProperty.call(a,b)};b.p=\"\";return b(b.s=\n129)}([function(a,c,d){function b(a){for(var b in a)c.hasOwnProperty(b)||(c[b]=a[b])}a=d(99);c.Array=a;a=d(102);c.Color=a;a=d(103);c.DOM=a;a=d(33);c.Math=a;a=d(106);c.Stacking=a;a=d(25);c.Window=a;b(d(100));b(d(101));b(d(12));b(d(104));b(d(105));b(d(50));b(d(107))},function(b){b.exports=a},function(a,c,d){var b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=null===b?Object.create(b):(c.prototype=b.prototype,new c)},f=\nd(1),g=d(7);a=d(4);var k=d(6),l=d(8),m=d(0),n=d(12),q=d(9),p=d(47);c.Renderer=q.makeEnum([\"svg\",\"canvas\"]);d=function(a){function c(){var b=a.call(this)||this;b._dataChanged=!1;b._animate=!1;b._animators={};b._resetEntityStore=function(){b._cachedEntityStore=void 0};b._overflowHidden=!0;b.addClass(\"plot\");b._datasetToDrawer=new m.Map;b._attrBindings=f.map();b._attrExtents=f.map();b._includedValuesProvider=function(a){return b._includedValuesForScale(a)};b._renderCallback=function(){return b.render()};\nb._onDatasetUpdateCallback=function(){return b._onDatasetUpdate()};b._propertyBindings=f.map();b._propertyExtents=f.map();var d=(new g.Easing).maxTotalDuration(c._ANIMATION_MAX_DURATION);b.animator(p.Animator.MAIN,d);b.animator(p.Animator.RESET,new g.Null);b._deferredResetEntityStore=m.Window.debounce(c._DEFERRED_RENDERING_DELAY,b._resetEntityStore);return b}b(c,a);c.getTotalDrawTime=function(a,b){return b.reduce(function(b,c){return b+c.animator.totalTime(a.length)},0)};c.applyDrawSteps=function(a,\nb){return a.map(function(a){var c=a.attrToProjector,d={};Object.keys(c).forEach(function(a){d[a]=function(d,e){return c[a](d,e,b)}});return{attrToAppliedProjector:d,animator:a.animator}})};c.prototype.anchor=function(b){b=n.coerceExternalD3(b);a.prototype.anchor.call(this,b);this._dataChanged=!0;this._resetEntityStore();this._updateExtents();return this};c.prototype._setup=function(){var b=this;this._isSetup||(a.prototype._setup.call(this),null!=this._canvas&&this._appendCanvasNode(),this._renderArea=\nthis.content().append(\"g\").classed(\"render-area\",!0),this.datasets().forEach(function(a){return b._createNodesForDataset(a)}))};c.prototype._appendCanvasNode=function(){var a=this.element().select(\".plot-canvas-container\");a.empty()&&(a=this.element().append(\"div\").classed(\"plot-canvas-container\",!0),a.node().appendChild(this._canvas.node()))};c.prototype.setBounds=function(b,c,d,e){a.prototype.setBounds.call(this,b,c,d,e);null!=this._canvas&&(d=null!=window.devicePixelRatio?window.devicePixelRatio:\n1,this._canvas.attr(\"width\",b*d),this._canvas.attr(\"height\",c*d),this._canvas.node().getContext(\"2d\").setTransform(d,0,0,d,0,0));return this};c.prototype.destroy=function(){var b=this;a.prototype.destroy.call(this);this._scales().forEach(function(a){return a.offUpdate(b._renderCallback)});this.datasets([])};c.prototype._createNodesForDataset=function(a){a=this._datasetToDrawer.get(a);\"svg\"===this.renderer()?a.useSVG(this._renderArea):a.useCanvas(this._canvas);return a};c.prototype._createDrawer=function(){return new k.ProxyDrawer(function(){return new l.SVGDrawer(\"path\",\n\"\")},function(){})};c.prototype._getAnimator=function(a){return this._animateOnNextRender()?this._animators[a]||new g.Null:new g.Null};c.prototype._onDatasetUpdate=function(){this._updateExtents();this._dataChanged=!0;this._resetEntityStore();this.render()};c.prototype.attr=function(a,b,c){if(null==b)return this._attrBindings.get(a);this._bindAttr(a,b,c);this.render();return this};c.prototype._bindProperty=function(a,b,c){var d=this._propertyBindings.get(a),d=null!=d?d.scale:null;this._propertyBindings.set(a,\n{accessor:\"function\"===typeof b?b:function(){return b},scale:c});this._updateExtentsForProperty(a);null!=d&&this._uninstallScaleForKey(d,a);null!=c&&this._installScaleForKey(c,a)};c.prototype._bindAttr=function(a,b,c){var d=this._attrBindings.get(a),d=null!=d?d.scale:null;this._attrBindings.set(a,{accessor:\"function\"===typeof b?b:function(){return b},scale:c});this._updateExtentsForAttr(a);null!=d&&this._uninstallScaleForKey(d,a);null!=c&&this._installScaleForKey(c,a)};c.prototype._generateAttrToProjector=\nfunction(){var a={};this._attrBindings.each(function(b,c){var d=b.accessor,e=b.scale;a[c]=e?function(a,b,c){return e.scale(d(a,b,c))}:d});var b=this._propertyProjectors();Object.keys(b).forEach(function(c){null==a[c]&&(a[c]=b[c])});return a};c.prototype.renderImmediately=function(){a.prototype.renderImmediately.call(this);this._isAnchored&&(this._paint(),this._dataChanged=!1);return this};c.prototype.animated=function(a){if(null==a)return this._animate;this._animate=a;return this};c.prototype.detach=\nfunction(){a.prototype.detach.call(this);this._updateExtents();return this};c.prototype._scales=function(){var a=[];this._attrBindings.each(function(b){b=b.scale;null!=b&&-1===a.indexOf(b)&&a.push(b)});this._propertyBindings.each(function(b){b=b.scale;null!=b&&-1===a.indexOf(b)&&a.push(b)});return a};c.prototype._updateExtents=function(){var a=this;this._resetEntityStore();this._attrBindings.each(function(b,c){return a._updateExtentsForAttr(c)});this._propertyExtents.each(function(b,c){return a._updateExtentsForProperty(c)});\nthis._scales().forEach(function(b){return b.addIncludedValuesProvider(a._includedValuesProvider)})};c.prototype._updateExtentsForAttr=function(a){this._updateExtentsForKey(a,this._attrBindings,this._attrExtents,null)};c.prototype._updateExtentsForProperty=function(a){this._updateExtentsForKey(a,this._propertyBindings,this._propertyExtents,this._filterForProperty(a))};c.prototype._filterForProperty=function(){return null};c.prototype._updateExtentsForKey=function(a,b,c,d){var e=this,f=b.get(a);null!=\nf&&null!=f.accessor&&c.set(a,this.datasets().map(function(a){return e._computeExtent(a,f,d)}))};c.prototype._computeExtent=function(a,b,c){var d=b.accessor;b=b.scale;if(null==b)return[];var e=a.data();null!=c&&(e=e.filter(function(b,d){return c(b,d,a)}));e=e.map(function(b,c){return d(b,c,a)});return b.extentOfValues(e)};c.prototype._extentsForProperty=function(a){return this._propertyExtents.get(a)};c.prototype._includedValuesForScale=function(a){var b=this;if(!this._isAnchored)return[];var c=[];\nthis._attrBindings.each(function(d,e){d.scale===a&&(d=b._attrExtents.get(e),null!=d&&(c=c.concat(f.merge(d))))});this._propertyBindings.each(function(d,e){d.scale===a&&(d=b._extentsForProperty(e),null!=d&&(c=c.concat(f.merge(d))))});return c};c.prototype.animator=function(a,b){if(void 0===b)return this._animators[a];this._animators[a]=b;return this};c.prototype.renderer=function(a){var b=this;if(void 0===a)return null==this._canvas?\"svg\":\"canvas\";null==this._canvas&&\"canvas\"===a?(this._canvas=f.select(document.createElement(\"canvas\")).classed(\"plot-canvas\",\n!0),null!=this.element()&&this._appendCanvasNode(),this._datasetToDrawer.forEach(function(a){a.useCanvas(b._canvas)}),this.render()):null!=this._canvas&&\"svg\"==a&&(this._canvas.remove(),this._canvas=null,this._datasetToDrawer.forEach(function(a){a.useSVG(b._renderArea)}),this.render());return this};c.prototype.addDataset=function(a){this._addDataset(a);this._onDatasetUpdate();return this};c.prototype._addDataset=function(a){this._removeDataset(a);var b=this._createDrawer(a);this._datasetToDrawer.set(a,\nb);this._isSetup&&this._createNodesForDataset(a);a.onUpdate(this._onDatasetUpdateCallback);return this};c.prototype.removeDataset=function(a){this._removeDataset(a);this._onDatasetUpdate();return this};c.prototype._removeDataset=function(a){if(-1===this.datasets().indexOf(a))return this;this._removeDatasetNodes(a);a.offUpdate(this._onDatasetUpdateCallback);this._datasetToDrawer.delete(a);return this};c.prototype._removeDatasetNodes=function(a){this._datasetToDrawer.get(a).remove()};c.prototype.datasets=\nfunction(a){var b=this,c=[];this._datasetToDrawer.forEach(function(a,b){return c.push(b)});if(null==a)return c;c.forEach(function(a){return b._removeDataset(a)});a.forEach(function(a){return b._addDataset(a)});this._onDatasetUpdate();return this};c.prototype._generateDrawSteps=function(){return[{attrToProjector:this._generateAttrToProjector(),animator:new g.Null}]};c.prototype._additionalPaint=function(){};c.prototype._buildLightweightPlotEntities=function(a){var b=this,c=[];a.forEach(function(a,\nd){var e=b._datasetToDrawer.get(a),f=0;a.data().forEach(function(g,k){var l=b._pixelPoint(g,k,a);m.Math.isNaN(l.x)||m.Math.isNaN(l.y)||(c.push({datum:g,get position(){return b._pixelPoint.call(b,g,k,a)},index:k,dataset:a,datasetIndex:d,component:b,drawer:e,validDatumIndex:f}),f++)})});return c};c.prototype._getDataToDraw=function(){var a=new m.Map;this.datasets().forEach(function(b){return a.set(b,b.data())});return a};c.prototype._paint=function(){var a=this,b=this._generateDrawSteps(),d=this._getDataToDraw(),\ne=this.datasets().map(function(b){return a._datasetToDrawer.get(b)});if(\"canvas\"===this.renderer()){var f=this._canvas.node();f.getContext(\"2d\").clearRect(0,0,f.width,f.height)}this.datasets().forEach(function(a,f){var g=c.applyDrawSteps(b,a);e[f].draw(d.get(a),g)});f=this.datasets().map(function(a){return c.getTotalDrawTime(d.get(a),b)});f=m.Math.max(f,0);this._additionalPaint(f)};c.prototype.selections=function(a){var b=this;void 0===a&&(a=this.datasets());if(\"canvas\"===this.renderer())return f.select(null);\nvar c=[];a.forEach(function(a){a=b._datasetToDrawer.get(a);null!=a&&(a=a.getVisualPrimitives(),c.push.apply(c,a))});return f.selectAll(c)};c.prototype.entities=function(a){var b=this;return this._getEntityStore(a).entities().map(function(a){return b._lightweightPlotEntityToPlotEntity(a)})};c.prototype._getEntityStore=function(a){if(void 0!==a){var b=new m.EntityStore;b.addAll(this._buildLightweightPlotEntities(a));return b}void 0===this._cachedEntityStore&&(b=new m.EntityStore,b.addAll(this._buildLightweightPlotEntities(this.datasets()),\nthis.bounds()),this._cachedEntityStore=b);return this._cachedEntityStore};c.prototype._lightweightPlotEntityToPlotEntity=function(a){return{datum:a.datum,position:a.position,dataset:a.dataset,datasetIndex:a.datasetIndex,index:a.index,component:a.component,selection:f.select(a.drawer.getVisualPrimitives()[a.validDatumIndex])}};c.prototype.entitiesAt=function(){throw Error(\"plots must implement entitiesAt\");};c.prototype.entityNearest=function(a,b){void 0===b&&this.bounds();a=this._getEntityStore().entityNearest(a);\nreturn void 0===a?void 0:this._lightweightPlotEntityToPlotEntity(a)};c.prototype._uninstallScaleForKey=function(a){a.offUpdate(this._renderCallback);a.offUpdate(this._deferredResetEntityStore);a.removeIncludedValuesProvider(this._includedValuesProvider)};c.prototype._installScaleForKey=function(a){a.onUpdate(this._renderCallback);a.onUpdate(this._deferredResetEntityStore);a.addIncludedValuesProvider(this._includedValuesProvider)};c.prototype._propertyProjectors=function(){return{}};c._scaledAccessor=\nfunction(a){return null==a.scale?a.accessor:function(b,c,d){return a.scale.scale(a.accessor(b,c,d))}};c.prototype._pixelPoint=function(){return{x:0,y:0}};c.prototype._animateOnNextRender=function(){return this._animate&&this._dataChanged};return c}(a.Component);d._ANIMATION_MAX_DURATION=600;d._DEFERRED_RENDERING_DELAY=200;c.Plot=d},function(a,c,d){function b(a){for(var b in a)c.hasOwnProperty(b)||(c[b]=a[b])}a=d(97);c.TickGenerators=a;b(d(49));b(d(93));b(d(94));b(d(95));b(d(96));b(d(98));var f=d(49),\ng=d(11);c.isTransformable=function(a){return a instanceof g.QuantitativeScale||a instanceof f.Category}},function(a,c,d){var b=d(1),f=d(28),g=d(0),k=d(12);a=d(9);c.XAlignment=a.makeEnum([\"left\",\"center\",\"right\"]);c.YAlignment=a.makeEnum([\"top\",\"center\",\"bottom\"]);a=function(){function a(){this._overflowHidden=!1;this._origin={x:0,y:0};this._xAlignment=\"left\";this._yAlignment=\"top\";this._isAnchored=this._isSetup=!1;this._cssClasses=new g.Set;this._destroyed=!1;this._onAnchorCallbacks=new g.CallbackSet;\nthis._onDetachCallbacks=new g.CallbackSet;this._cssClasses.add(\"component\")}a.prototype.anchor=function(a){a=k.coerceExternalD3(a);if(this._destroyed)throw Error(\"Can't reuse destroy()-ed Components!\");this.isRoot()&&(this._rootElement=a,this._rootElement.classed(\"plottable\",!0));null!=this._element?a.node().appendChild(this._element.node()):(this._element=a.append(\"div\"),this._setup());this._isAnchored=!0;this._onAnchorCallbacks.callCallbacks(this);return this};a.prototype.onAnchor=function(a){this._isAnchored&&\na(this);this._onAnchorCallbacks.add(a)};a.prototype.offAnchor=function(a){this._onAnchorCallbacks.delete(a)};a.prototype._setup=function(){var a=this;this._isSetup||(this._cssClasses.forEach(function(b){a._element.classed(b,!0)}),this._cssClasses=new g.Set,this._backgroundContainer=this._element.append(\"svg\").classed(\"background-container\",!0),this._content=this._element.append(\"svg\").classed(\"content\",!0),this._foregroundContainer=this._element.append(\"svg\").classed(\"foreground-container\",!0),this._overflowHidden?\nthis._content.classed(\"component-overflow-hidden\",!0):this._content.classed(\"component-overflow-visible\",!0),this._isSetup=!0)};a.prototype.requestedSpace=function(){return{minWidth:0,minHeight:0}};a.prototype.computeLayout=function(b,c,d){if(null==b||null==c||null==d){if(null==this._element)throw Error(\"anchor() must be called before computeLayout()\");if(null!=this._rootElement)b={x:0,y:0},d=this._rootElement.node(),c=g.DOM.elementWidth(d),d=g.DOM.elementHeight(d);else throw Error(\"null arguments cannot be passed to computeLayout() on a non-root, unanchored node\");\n}var e=this._sizeFromOffer(c,d),f=e.height,e=e.width;this.setBounds(e,f,b.x+(c-e)*a._xAlignToProportion[this._xAlignment],b.y+(d-f)*a._yAlignToProportion[this._yAlignment]);return this};a.prototype.setBounds=function(a,b,c,d){void 0===c&&(c=0);void 0===d&&(d=0);this._width=a;this._height=b;this._origin={x:c,y:d};null!=this._element&&this._element.styles({left:c+\"px\",height:b+\"px\",top:d+\"px\",width:a+\"px\"});null!=this._resizeHandler&&this._resizeHandler({width:a,height:b});return this};a.prototype._sizeFromOffer=\nfunction(a,b){var c=this.requestedSpace(a,b);return{width:this.fixedWidth()?Math.min(a,c.minWidth):a,height:this.fixedHeight()?Math.min(b,c.minHeight):b}};a.prototype.render=function(){this._isAnchored&&this._isSetup&&0<=this.width()&&0<=this.height()&&f.registerToRender(this);return this};a.prototype._scheduleComputeLayout=function(){this._isAnchored&&this._isSetup&&f.registerToComputeLayoutAndRender(this)};a.prototype.onResize=function(a){this._resizeHandler=a;return this};a.prototype.renderImmediately=\nfunction(){return this};a.prototype.redraw=function(){this._isAnchored&&this._isSetup&&(this.isRoot()?this._scheduleComputeLayout():this.parent().redraw());return this};a.prototype.invalidateCache=function(){};a.prototype.renderTo=function(a){this.detach();if(null!=a){a=\"string\"===typeof a?b.select(a):a instanceof Element?b.select(a):k.coerceExternalD3(a);if(!a.node()||null==a.node().nodeName)throw Error(\"Plottable requires a valid Element to renderTo\");if(\"svg\"===a.node().nodeName)throw Error(\"Plottable 3.x and later can only renderTo an HTML component; pass a div instead!\");\nthis.anchor(a)}if(null==this._element)throw Error(\"If a Component has never been rendered before, then renderTo must be given a node to render to, or a d3.Selection, or a selector string\");f.registerToComputeLayoutAndRender(this);f.flush()};a.prototype.xAlignment=function(b){if(null==b)return this._xAlignment;b=b.toLowerCase();if(null==a._xAlignToProportion[b])throw Error(\"Unsupported alignment: \"+b);this._xAlignment=b;this.redraw();return this};a.prototype.yAlignment=function(b){if(null==b)return this._yAlignment;\nb=b.toLowerCase();if(null==a._yAlignToProportion[b])throw Error(\"Unsupported alignment: \"+b);this._yAlignment=b;this.redraw();return this};a.prototype.hasClass=function(a){return null==a?!1:null==this._element?this._cssClasses.has(a):this._element.classed(a)};a.prototype.addClass=function(a){null!=a&&(null==this._element?this._cssClasses.add(a):this._element.classed(a,!0))};a.prototype.removeClass=function(a){null!=a&&(null==this._element?this._cssClasses.delete(a):this._element.classed(a,!1))};a.prototype.fixedWidth=\nfunction(){return!1};a.prototype.fixedHeight=function(){return!1};a.prototype.detach=function(){this.parent(null);this._isAnchored&&this._element.remove();this._isAnchored=!1;this._onDetachCallbacks.callCallbacks(this);return this};a.prototype.onDetach=function(a){this._onDetachCallbacks.add(a)};a.prototype.offDetach=function(a){this._onDetachCallbacks.delete(a)};a.prototype.parent=function(a){if(void 0===a)return this._parent;if(null!==a&&!a.has(this))throw Error(\"Passed invalid parent\");this._parent=\na;return this};a.prototype.bounds=function(){var a=this.origin();return{topLeft:a,bottomRight:{x:a.x+this.width(),y:a.y+this.height()}}};a.prototype.destroy=function(){this._destroyed=!0;this.detach()};a.prototype.width=function(){return this._width};a.prototype.height=function(){return this._height};a.prototype.origin=function(){return{x:this._origin.x,y:this._origin.y}};a.prototype.originToRoot=function(){for(var a=this.origin(),b=this.parent();null!=b;){var c=b.origin();a.x+=c.x;a.y+=c.y;b=b.parent()}return a};\na.prototype.root=function(){for(var a=this;!a.isRoot();)a=a.parent();return a};a.prototype.isRoot=function(){return null==this.parent()};a.prototype.foreground=function(){return this._foregroundContainer};a.prototype.content=function(){return this._content};a.prototype.element=function(){return this._element};a.prototype.rootElement=function(){return this.root()._rootElement};a.prototype.background=function(){return this._backgroundContainer};return a}();a._xAlignToProportion={left:0,center:.5,right:1};\na._yAlignToProportion={top:0,center:.5,bottom:1};c.Component=a},function(a,c,d){function b(a){for(var b in a)c.hasOwnProperty(b)||(c[b]=a[b])}b(d(51));b(d(54));b(d(122));b(d(20));b(d(56));b(d(58))},function(a,c,d){var b=d(19);a=function(){function a(a,b){this._svgDrawerFactory=a;this._canvasDrawStep=b}a.prototype.useSVG=function(a){null!=this._currentDrawer&&this._currentDrawer.remove();var b=this._svgDrawerFactory();b.attachTo(a);this._currentDrawer=b};a.prototype.useCanvas=function(a){null!=this._currentDrawer&&\nthis._currentDrawer.remove();this._currentDrawer=new b.CanvasDrawer(a.node().getContext(\"2d\"),this._canvasDrawStep)};a.prototype.getDrawer=function(){return this._currentDrawer};a.prototype.remove=function(){null!=this._currentDrawer&&this._currentDrawer.remove()};a.prototype.draw=function(a,b){this._currentDrawer.draw(a,b)};a.prototype.getVisualPrimitives=function(){return this._currentDrawer.getVisualPrimitives()};a.prototype.getVisualPrimitiveAtIndex=function(a){return this._currentDrawer.getVisualPrimitiveAtIndex(a)};\nreturn a}();c.ProxyDrawer=a},function(a,c,d){function b(a){for(var b in a)c.hasOwnProperty(b)||(c[b]=a[b])}b(d(64));b(d(65))},function(a,c,d){var b=d(1),f=d(0);a=function(){function a(a,c){this._root=b.select(document.createElementNS(\"http://www.w3.org/2000/svg\",\"g\"));this._className=c;this._svgElementName=a}a.prototype.draw=function(a,b){var c=this;this._createAndDestroyDOMElements(a);var d=0;b.forEach(function(b){f.Window.setTimeout(function(){return c._drawStep(b)},d);d+=b.animator.totalTime(a.length)})};\na.prototype.getVisualPrimitives=function(){null==this._cachedVisualPrimitivesNodes&&(this._cachedVisualPrimitivesNodes=this._selection.nodes());return this._cachedVisualPrimitivesNodes};a.prototype.getVisualPrimitiveAtIndex=function(a){return this.getVisualPrimitives()[a]};a.prototype.remove=function(){this._root.remove()};a.prototype.attachTo=function(a){a.node().appendChild(this._root.node())};a.prototype.getRoot=function(){return this._root};a.prototype.selector=function(){return this._svgElementName};\na.prototype._applyDefaultAttributes=function(){};a.prototype._createAndDestroyDOMElements=function(a){a=this._root.selectAll(this.selector()).data(a);this._selection=a.enter().append(this._svgElementName).merge(a);a.exit().remove();this._cachedVisualPrimitivesNodes=null;null!=this._className&&this._selection.classed(this._className,!0);this._applyDefaultAttributes(this._selection)};a.prototype._drawStep=function(a){var b=this;[\"fill\",\"stroke\"].forEach(function(c){null!=a.attrToAppliedProjector[c]&&\nb._selection.attr(c,a.attrToAppliedProjector[c])});a.animator.animate(this._selection,a.attrToAppliedProjector);null!=this._className&&this._selection.classed(this._className,!0)};return a}();c.SVGDrawer=a},function(a,c){c.makeEnum=function(a){return a.reduce(function(a,b){a[b]=b;return a},{})}},function(a,c,d){function b(a){void 0===a&&(a=3);f(a);return function(b){return b.toFixed(a)}}function f(a){if(0>a||20<a)throw new RangeError(\"Formatter precision must be between 0 and 20\");if(a!==Math.floor(a))throw new RangeError(\"Formatter precision must be an integer\");\n}var g=d(1);c.currency=function(a,c,d){void 0===a&&(a=2);void 0===c&&(c=\"$\");void 0===d&&(d=!0);var e=b(a);return function(a){var b=e(Math.abs(a));\"\"!==b&&(b=d?c+b:b+c,0>a&&(b=\"-\"+b));return b}};c.fixed=b;c.general=function(){var a;void 0===a&&(a=3);f(a);return function(b){if(\"number\"===typeof b){var c=Math.pow(10,a);return String(Math.round(b*c)/c)}return String(b)}};c.identity=function(){return function(a){return String(a)}};c.percentage=function(a){void 0===a&&(a=0);var c=b(a);return function(a){var b=\na.toString(),b=Math.pow(10,b.length-(b.indexOf(\".\")+1));return c(parseInt((100*a*b).toString(),10)/b)+\"%\"}};c.siSuffix=function(a){void 0===a&&(a=3);f(a);return function(b){return g.format(\".\"+a+\"s\")(b)}};c.shortScale=function(){var a=0;void 0===a&&(a=3);f(a);var b=g.format(\".\"+a+\"e\"),c=g.format(\".\"+a+\"f\"),d=Math.pow(10,18),e=Math.pow(10,-a);return function(a){var f=Math.abs(a);if((f<e||f>=d)&&0!==f)return b(a);for(var g=-1;f>=Math.pow(1E3,g+2)&&4>g;)g++;f=-1===g?c(a):c(a/Math.pow(1E3,g+1))+\"KMBTQ\"[g];\nif(0<a&&\"1000\"===f.substr(0,4)||0>a&&\"-1000\"===f.substr(0,5))4>g?(g++,f=c(a/Math.pow(1E3,g+1))+\"KMBTQ\"[g]):f=b(a);return f}};c.multiTime=function(){var a=[{specifier:\".%L\",predicate:function(a){return 0!==a.getMilliseconds()}},{specifier:\":%S\",predicate:function(a){return 0!==a.getSeconds()}},{specifier:\"%I:%M\",predicate:function(a){return 0!==a.getMinutes()}},{specifier:\"%I %p\",predicate:function(a){return 0!==a.getHours()}},{specifier:\"%a %d\",predicate:function(a){return 0!==a.getDay()&&1!==a.getDate()}},\n{specifier:\"%b %d\",predicate:function(a){return 1!==a.getDate()}},{specifier:\"%b\",predicate:function(a){return 0!==a.getMonth()}}];return function(b){var c=a.filter(function(a){return a.predicate(b)});return g.timeFormat(0<c.length?c[0].specifier:\"%Y\")(b)}};c.time=function(a){return g.timeFormat(a)}},function(a,c,d){var b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=null===b?Object.create(b):(c.prototype=b.prototype,\nnew c)},f=d(1),g=d(14),k=d(0);a=function(a){function c(){var b=a.call(this)||this;b._tickGenerator=function(a){return a.defaultTicks()};b._padProportion=.05;b._snappingDomainEnabled=!0;b._paddingExceptionsProviders=new k.Set;return b}b(c,a);c.prototype.autoDomain=function(){this._domainMax=this._domainMin=null;a.prototype.autoDomain.call(this);return this};c.prototype._autoDomainIfAutomaticMode=function(){if(null!=this._domainMin&&null!=this._domainMax)this._setDomain([this._domainMin,this._domainMax]);\nelse{var b=this._getExtent();null!=this._domainMin?(b=b[1],this._domainMin>=b&&(b=this._expandSingleValueDomain([this._domainMin,this._domainMin])[1]),this._setDomain([this._domainMin,b])):null!=this._domainMax?(b=b[0],this._domainMax<=b&&(b=this._expandSingleValueDomain([this._domainMax,this._domainMax])[0]),this._setDomain([b,this._domainMax])):a.prototype._autoDomainIfAutomaticMode.call(this)}};c.prototype._getExtent=function(){var a=this._getAllIncludedValues(),b=this._defaultExtent();0!==a.length&&\n(a=[k.Math.min(a,b[0]),k.Math.max(a,b[1])],b=this._padDomain(a));null!=this._domainMin&&(b[0]=this._domainMin);null!=this._domainMax&&(b[1]=this._domainMax);return b};c.prototype.addPaddingExceptionsProvider=function(a){this._paddingExceptionsProviders.add(a);this._autoDomainIfAutomaticMode()};c.prototype.removePaddingExceptionsProvider=function(a){this._paddingExceptionsProviders.delete(a);this._autoDomainIfAutomaticMode()};c.prototype.padProportion=function(a){if(null==a)return this._padProportion;\nif(0>a)throw Error(\"padProportion must be non-negative\");this._padProportion=a;this._autoDomainIfAutomaticMode();return this};c.prototype._padDomain=function(a){var b=this;if(a[0].valueOf()===a[1].valueOf())return this._expandSingleValueDomain(a);if(0===this._padProportion)return a;var c=this._padProportion/2,d=a[0],e=a[1],f=!1,g=!1;this._paddingExceptionsProviders.forEach(function(a){a(b).forEach(function(a){a.valueOf()===d.valueOf()&&(f=!0);a.valueOf()===e.valueOf()&&(g=!0)})});var k=this._backingScaleDomain();\nthis._backingScaleDomain(a);a=f?d:this.invert(this.scale(d)-(this.scale(e)-this.scale(d))*c);c=g?e:this.invert(this.scale(e)+(this.scale(e)-this.scale(d))*c);this._backingScaleDomain(k);return this._snappingDomainEnabled?this._niceDomain([a,c]):[a,c]};c.prototype.snappingDomainEnabled=function(a){null!=a&&(this._snappingDomainEnabled=a,this._autoDomainIfAutomaticMode())};c.prototype._expandSingleValueDomain=function(a){return a};c.prototype.invert=function(){throw Error(\"Subclasses should override invert\");\n};c.prototype.domain=function(b){null!=b&&(this._domainMin=b[0],this._domainMax=b[1]);return a.prototype.domain.call(this,b)};c.prototype.domainMin=function(a){if(null==a)return this.domain()[0];this._domainMin=a;this._autoDomainIfAutomaticMode();return this};c.prototype.domainMax=function(a){if(null==a)return this.domain()[1];this._domainMax=a;this._autoDomainIfAutomaticMode();return this};c.prototype.extentOfValues=function(a){a=f.extent(a.filter(function(a){return k.Math.isValidNumber(+a)}));return null==\na[0]||null==a[1]?[]:a};c.prototype.zoom=function(a,b){var c=this;this.domain(this.range().map(function(d){return c.invert(g.zoomAt(d,a,b))}))};c.prototype.pan=function(a){var b=this;this.domain(this.range().map(function(c){return b.invert(c+a)}))};c.prototype.scaleTransformation=function(){throw Error(\"Subclasses should override scaleTransformation\");};c.prototype.invertedTransformation=function(){throw Error(\"Subclasses should override invertedTransformation\");};c.prototype.getTransformationDomain=\nfunction(){throw Error(\"Subclasses should override getTransformationDomain\");};c.prototype._setDomain=function(b){function c(a){return k.Math.isNaN(a)||Infinity===a||-Infinity===a}c(b[0])||c(b[1])?k.Window.warn(\"Warning: QuantitativeScales cannot take NaN or Infinity as a domain value. Ignoring.\"):a.prototype._setDomain.call(this,b)};c.prototype.defaultTicks=function(){throw Error(\"Subclasses should override _getDefaultTicks\");};c.prototype.ticks=function(){return this._tickGenerator(this)};c.prototype._niceDomain=\nfunction(){throw Error(\"Subclasses should override _niceDomain\");};c.prototype._defaultExtent=function(){throw Error(\"Subclasses should override _defaultExtent\");};c.prototype.tickGenerator=function(a){if(null==a)return this._tickGenerator;this._tickGenerator=a;return this};return c}(d(18).Scale);a._DEFAULT_NUM_TICKS=10;c.QuantitativeScale=a},function(a,c,d){var b=d(1);c.coerceExternalD3=function(a){if(null==a.attrs){if(null==a.nodes){var c=[];a.each(function(){c.push(this)});return b.selectAll(c)}return b.selectAll(a.nodes())}return a}},\nfunction(a,c,d){function b(a){for(var b in a)c.hasOwnProperty(b)||(c[b]=a[b])}b(d(77));b(d(78));b(d(79))},function(a,c,d){function b(a){for(var b in a)c.hasOwnProperty(b)||(c[b]=a[b])}b(d(81));b(d(82));b(d(37));b(d(83));b(d(84))},function(a,c){a=function(){function a(){var a=this;this._anchorCallback=function(b){return a._anchor(b)};this._enabled=!0}a.prototype._anchor=function(){this._isAnchored=!0};a.prototype._unanchor=function(){this._isAnchored=!1};a.prototype.attachTo=function(a){this._disconnect();\nthis._componentAttachedTo=a;this._connect();return this};a.prototype._connect=function(){if(this.enabled()&&null!=this._componentAttachedTo&&!this._isAnchored)this._componentAttachedTo.onAnchor(this._anchorCallback)};a.prototype.detachFrom=function(){this._disconnect();this._componentAttachedTo=null};a.prototype._disconnect=function(){this._isAnchored&&this._unanchor();null!=this._componentAttachedTo&&this._componentAttachedTo.offAnchor(this._anchorCallback)};a.prototype.enabled=function(a){if(null==\na)return this._enabled;(this._enabled=a)?this._connect():this._disconnect();return this};a.prototype._translateToComponentSpace=function(a){var b=this._componentAttachedTo.originToRoot();return{x:a.x-b.x,y:a.y-b.y}};a.prototype._isInsideComponent=function(a){return 0<=a.x&&0<=a.y&&a.x<=this._componentAttachedTo.width()&&a.y<=this._componentAttachedTo.height()};return a}();c.Interaction=a},function(a,c,d){var b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&\n(a[d]=b[d]);a.prototype=null===b?Object.create(b):(c.prototype=b.prototype,new c)},f=d(3),g=d(0),k=d(2);a=function(a){function c(){function b(){null!=d._renderArea&&(d._renderArea.attr(\"transform\",\"translate(\"+e+\", \"+f+\") scale(\"+g+\", \"+k+\")\"),null!=d._canvas&&d._canvas.style(\"transform\",\"translate(\"+e+\"px, \"+f+\"px) scale(\"+g+\", \"+k+\")\"),clearTimeout(y),y=setTimeout(function(){d._cachedDomainX=l;d._cachedDomainY=m;f=e=0;k=g=1;d.render();d._renderArea.attr(\"transform\",\"translate(0, 0) scale(1, 1)\");\nnull!=d._canvas&&d._canvas.style(\"transform\",\"translate(0, 0) scale(1, 1)\")},c._DEFERRED_RENDERING_DELAY))}var d=a.call(this)||this;d._autoAdjustXScaleDomain=!1;d._autoAdjustYScaleDomain=!1;d._deferredRendering=!1;d._cachedDomainX=[null,null];d._cachedDomainY=[null,null];d.addClass(\"xy-plot\");d._adjustYDomainOnChangeFromXCallback=function(){return d._adjustYDomainOnChangeFromX()};d._adjustXDomainOnChangeFromYCallback=function(){return d._adjustXDomainOnChangeFromY()};var e=0,f=0,g=1,k=1,l=[null,null],\nm=[null,null],y=0;d._renderCallback=function(a){d.deferredRendering()&&d.x()&&d.x().scale===a?d._isAnchored&&(l=a.domain(),g=(a.scale(d._cachedDomainX[1])-a.scale(d._cachedDomainX[0]))/(a.scale(l[1])-a.scale(l[0]))||1,e=a.scale(d._cachedDomainX[0])-a.scale(l[0])||0,b()):d.deferredRendering()&&d.y()&&d.y().scale===a?d._isAnchored&&(m=a.domain(),k=(a.scale(d._cachedDomainY[1])-a.scale(d._cachedDomainY[0]))/(a.scale(m[1])-a.scale(m[0]))||1,f=a.scale(d._cachedDomainY[0])-a.scale(m[0])*k||0,b()):d.render()};\nreturn d}b(c,a);c.prototype.deferredRendering=function(){return this._deferredRendering};c.prototype.x=function(a,b){if(null==a)return this._propertyBindings.get(c._X_KEY);this._bindProperty(c._X_KEY,a,b);a=this.width();null!=b&&null!=a&&b.range([0,a]);this._autoAdjustYScaleDomain&&this._updateYExtentsAndAutodomain();this.render();return this};c.prototype.y=function(a,b){if(null==a)return this._propertyBindings.get(c._Y_KEY);this._bindProperty(c._Y_KEY,a,b);a=this.height();null!=b&&null!=a&&(b instanceof\nf.Category?b.range([0,a]):b.range([a,0]));this._autoAdjustXScaleDomain&&this._updateXExtentsAndAutodomain();this.render();return this};c.prototype._filterForProperty=function(a){return\"x\"===a&&this._autoAdjustXScaleDomain?this._makeFilterByProperty(\"y\"):\"y\"===a&&this._autoAdjustYScaleDomain?this._makeFilterByProperty(\"x\"):null};c.prototype._makeFilterByProperty=function(a){a=this._propertyBindings.get(a);if(null!=a){var b=a.accessor,c=a.scale;if(null!=c)return function(a,d,e){var f=c.range();return g.Math.inRange(c.scale(b(a,\nd,e)),f[0],f[1])}}return null};c.prototype._uninstallScaleForKey=function(b,d){a.prototype._uninstallScaleForKey.call(this,b,d);b.offUpdate(d===c._X_KEY?this._adjustYDomainOnChangeFromXCallback:this._adjustXDomainOnChangeFromYCallback)};c.prototype._installScaleForKey=function(b,d){a.prototype._installScaleForKey.call(this,b,d);b.onUpdate(d===c._X_KEY?this._adjustYDomainOnChangeFromXCallback:this._adjustXDomainOnChangeFromYCallback)};c.prototype.destroy=function(){a.prototype.destroy.call(this);this.x().scale&&\nthis.x().scale.offUpdate(this._adjustYDomainOnChangeFromXCallback);this.y().scale&&this.y().scale.offUpdate(this._adjustXDomainOnChangeFromYCallback);return this};c.prototype.autorangeMode=function(a){if(null==a)return this._autoAdjustXScaleDomain?\"x\":this._autoAdjustYScaleDomain?\"y\":\"none\";switch(a){case \"x\":this._autoAdjustXScaleDomain=!0;this._autoAdjustYScaleDomain=!1;this._adjustXDomainOnChangeFromY();break;case \"y\":this._autoAdjustXScaleDomain=!1;this._autoAdjustYScaleDomain=!0;this._adjustYDomainOnChangeFromX();\nbreak;case \"none\":this._autoAdjustYScaleDomain=this._autoAdjustXScaleDomain=!1;break;default:throw Error(\"Invalid scale name '\"+a+\"', must be 'x', 'y' or 'none'\");}return this};c.prototype.computeLayout=function(b,c,d){a.prototype.computeLayout.call(this,b,c,d);b=(b=this.x())&&b.scale;null!=b&&b.range([0,this.width()]);b=(b=this.y())&&b.scale;null!=b&&(b instanceof f.Category?b.range([0,this.height()]):b.range([this.height(),0]));return this};c.prototype._updateXExtentsAndAutodomain=function(){this._updateExtentsForProperty(\"x\");\nvar a=this.x().scale;null!=a&&a.autoDomain()};c.prototype._updateYExtentsAndAutodomain=function(){this._updateExtentsForProperty(\"y\");var a=this.y().scale;null!=a&&a.autoDomain()};c.prototype.showAllData=function(){this._updateXExtentsAndAutodomain();this._updateYExtentsAndAutodomain();return this};c.prototype._adjustYDomainOnChangeFromX=function(){this._projectorsReady()&&this._autoAdjustYScaleDomain&&this._updateYExtentsAndAutodomain()};c.prototype._adjustXDomainOnChangeFromY=function(){this._projectorsReady()&&\nthis._autoAdjustXScaleDomain&&this._updateXExtentsAndAutodomain()};c.prototype._projectorsReady=function(){var a=this.x(),b=this.y();return null!=a&&null!=a.accessor&&null!=b&&null!=b.accessor};c.prototype._pixelPoint=function(a,b,c){var d=k.Plot._scaledAccessor(this.x()),e=k.Plot._scaledAccessor(this.y());return{x:d(a,b,c),y:e(a,b,c)}};c.prototype._getDataToDraw=function(){var b=this,c=a.prototype._getDataToDraw.call(this);this.datasets().forEach(function(a){c.set(a,c.get(a).filter(function(c,d){var e=\nk.Plot._scaledAccessor(b.x())(c,d,a);c=k.Plot._scaledAccessor(b.y())(c,d,a);return g.Math.isValidNumber(e)&&g.Math.isValidNumber(c)}))});return c};return c}(k.Plot);a._X_KEY=\"x\";a._Y_KEY=\"y\";c.XYPlot=a},function(a,c,d){function b(a){for(var b in a)c.hasOwnProperty(b)||(c[b]=a[b])}b(d(46));b(d(24));b(d(47));b(d(85));b(d(48));b(d(86));b(d(87));b(d(88));b(d(89));b(d(90));b(d(91));b(d(92))},function(a,c,d){var b=d(0);a=function(){function a(){this._autoDomainAutomatically=!0;this._domainModificationInProgress=\n!1;this._callbacks=new b.CallbackSet;this._includedValuesProviders=new b.Set}a.prototype.extentOfValues=function(){return[]};a.prototype._getAllIncludedValues=function(){var a=this,b=[];this._includedValuesProviders.forEach(function(c){c=c(a);b=b.concat(c)});return b};a.prototype._getExtent=function(){return[]};a.prototype.onUpdate=function(a){this._callbacks.add(a);return this};a.prototype.offUpdate=function(a){this._callbacks.delete(a);return this};a.prototype._dispatchUpdate=function(){this._callbacks.callCallbacks(this)};\na.prototype.autoDomain=function(){this._autoDomainAutomatically=!0;this._setDomain(this._getExtent());return this};a.prototype._autoDomainIfAutomaticMode=function(){this._autoDomainAutomatically&&this.autoDomain()};a.prototype.scale=function(){throw Error(\"Subclasses should override scale\");};a.prototype.domain=function(a){if(null==a)return this._getDomain();this._autoDomainAutomatically=!1;this._setDomain(a);return this};a.prototype._getDomain=function(){throw Error(\"Subclasses should override _getDomain\");\n};a.prototype._setDomain=function(a){this._domainModificationInProgress||(this._domainModificationInProgress=!0,this._backingScaleDomain(a),this._dispatchUpdate(),this._domainModificationInProgress=!1)};a.prototype._backingScaleDomain=function(){throw Error(\"Subclasses should override _backingDomain\");};a.prototype.range=function(a){if(null==a)return this._getRange();this._setRange(a);return this};a.prototype._getRange=function(){throw Error(\"Subclasses should override _getRange\");};a.prototype._setRange=\nfunction(){throw Error(\"Subclasses should override _setRange\");};a.prototype.addIncludedValuesProvider=function(a){this._includedValuesProviders.add(a);this._autoDomainIfAutomaticMode();return this};a.prototype.removeIncludedValuesProvider=function(a){this._includedValuesProviders.delete(a);this._autoDomainIfAutomaticMode()};return a}();c.Scale=a},function(a,c,d){var b=d(1);a=function(){function a(a,b){this._context=a;this._drawStep=b}a.prototype.getDrawStep=function(){return this._drawStep};a.prototype.draw=\nfunction(a,b){b=b[b.length-1];this._context.save();this._drawStep(this._context,a,b.attrToAppliedProjector);this._context.restore()};a.prototype.getVisualPrimitives=function(){return[]};a.prototype.getVisualPrimitiveAtIndex=function(){return null};a.prototype.remove=function(){};return a}();c.CanvasDrawer=a;c.ContextStyleAttrs={strokeWidth:\"stroke-width\",stroke:\"stroke\",opacity:\"opacity\",fill:\"fill\"};c.resolveAttributesSubsetWithStyles=function(a,b,d,e){b=Object.keys(c.ContextStyleAttrs).concat(b);\nfor(var f={},g=0;g<b.length;g++){var k=b[g];a.hasOwnProperty(k)&&(f[k]=a[k](d,e))}return f};c.styleContext=function(a,d){d[c.ContextStyleAttrs.strokeWidth]&&(a.lineWidth=parseFloat(d[c.ContextStyleAttrs.strokeWidth]));if(d[c.ContextStyleAttrs.stroke]){var e=b.color(d[c.ContextStyleAttrs.stroke]);d[c.ContextStyleAttrs.opacity]&&(e.opacity=d[c.ContextStyleAttrs.opacity]);a.strokeStyle=e.rgb().toString();a.stroke()}d[c.ContextStyleAttrs.fill]&&(e=b.color(d[c.ContextStyleAttrs.fill]),d[c.ContextStyleAttrs.opacity]&&\n(e.opacity=d[c.ContextStyleAttrs.opacity]),a.fillStyle=e.rgb().toString(),a.fill())}},function(a,c,d){function b(a){for(var b in a)c.hasOwnProperty(b)||(c[b]=a[b])}b(d(123));b(d(124));b(d(125));b(d(126))},function(a,c,d){var b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=null===b?Object.create(b):(c.prototype=b.prototype,new c)},f=d(1),g=d(5);a=d(4);var k=d(10),l=d(0);d=d(9);c.AxisOrientation=d.makeEnum([\"bottom\",\"left\",\n\"right\",\"top\"]);d=function(a){function c(b,c){var d=a.call(this)||this;d._endTickLength=5;d._innerTickLength=5;d._tickLabelPadding=10;d._margin=15;d._showEndTickLabels=!1;d._annotationsEnabled=!1;d._annotationTierCount=1;if(null==b||null==c)throw Error(\"Axis requires a scale and orientation\");d._scale=b;d.orientation(c);d._setDefaultAlignment();d.addClass(\"axis\");d.isHorizontal()?d.addClass(\"x-axis\"):d.addClass(\"y-axis\");d.formatter(k.identity());d._rescaleCallback=function(){return d._rescale()};\nd._scale.onUpdate(d._rescaleCallback);d._annotatedTicks=[];d._annotationFormatter=k.identity();return d}b(c,a);c.prototype.destroy=function(){a.prototype.destroy.call(this);this._scale.offUpdate(this._rescaleCallback)};c.prototype.tickLabelDataOnElement=function(a){if(null!=a){for(var b;null!=a&&a.classList&&void 0===b;)a.classList.contains(c.TICK_LABEL_CLASS)?b=a:a=a.parentNode;return void 0===a?void 0:f.select(a).datum()}};c.prototype._computeWidth=function(){return this._maxLabelTickLength()};\nc.prototype._computeHeight=function(){return this._maxLabelTickLength()};c.prototype.requestedSpace=function(){var a=0,b=0;if(this.isHorizontal()){if(b=this._computeHeight()+this._margin,this.annotationsEnabled()){var d=this._annotationMeasurer.measure().height+2*c._ANNOTATION_LABEL_PADDING;b+=d*this.annotationTierCount()}}else a=this._computeWidth()+this._margin,this.annotationsEnabled()&&(d=this._annotationMeasurer.measure().height+2*c._ANNOTATION_LABEL_PADDING,a+=d*this.annotationTierCount());\nreturn{minWidth:a,minHeight:b}};c.prototype.fixedHeight=function(){return this.isHorizontal()};c.prototype.fixedWidth=function(){return!this.isHorizontal()};c.prototype._rescale=function(){this.render()};c.prototype.computeLayout=function(b,c,d){a.prototype.computeLayout.call(this,b,c,d);this.isHorizontal()?this._scale.range([0,this.width()]):this._scale.range([this.height(),0]);return this};c.prototype._sizeFromOffer=function(a,b){var c=this.requestedSpace(a,b);return this.isHorizontal()?{width:a,\nheight:c.minHeight}:{height:b,width:c.minWidth}};c.prototype._setup=function(){a.prototype._setup.call(this);this._tickMarkContainer=this.content().append(\"g\").classed(c.TICK_MARK_CLASS+\"-container\",!0);this._tickLabelContainer=this.content().append(\"g\").classed(c.TICK_LABEL_CLASS+\"-container\",!0);this._baseline=this.content().append(\"line\").classed(\"baseline\",!0);this._annotationContainer=this.content().append(\"g\").classed(\"annotation-container\",!0);this._annotationContainer.append(\"g\").classed(\"annotation-line-container\",\n!0);this._annotationContainer.append(\"g\").classed(\"annotation-circle-container\",!0);this._annotationContainer.append(\"g\").classed(\"annotation-rect-container\",!0);var b=this._annotationContainer.append(\"g\").classed(\"annotation-label-container\",!0),b=new g.SvgContext(b.node());this._annotationMeasurer=new g.CacheMeasurer(b);this._annotationWriter=new g.Writer(this._annotationMeasurer,b)};c.prototype._getTickValues=function(){return[]};c.prototype.renderImmediately=function(){var a=this._getTickValues(),\nb=this._tickMarkContainer.selectAll(\".\"+c.TICK_MARK_CLASS).data(a),d=b.enter().append(\"line\").classed(c.TICK_MARK_CLASS,!0).merge(b);d.attrs(this._generateTickMarkAttrHash());f.select(d.nodes()[0]).classed(c.END_TICK_MARK_CLASS,!0).attrs(this._generateTickMarkAttrHash(!0));f.select(d.nodes()[a.length-1]).classed(c.END_TICK_MARK_CLASS,!0).attrs(this._generateTickMarkAttrHash(!0));b.exit().remove();this._baseline.attrs(this._generateBaselineAttrHash());this.annotationsEnabled()?this._drawAnnotations():\nthis._removeAnnotations();return this};c.prototype.annotatedTicks=function(){return this._annotatedTicks};c.prototype.annotationFormatter=function(a){if(null==a)return this._annotationFormatter;this._annotationFormatter=a;this.render();return this};c.prototype.annotationsEnabled=function(){return this._annotationsEnabled};c.prototype.annotationTierCount=function(){return this._annotationTierCount};c.prototype._drawAnnotations=function(){function a(a){switch(k.orientation()){case \"bottom\":case \"right\":return e(a);\ncase \"top\":case \"left\":return e(a)-n.get(a).height}}function b(a){return E.has(a)?\"hidden\":\"visible\"}function d(a){return k._scale.scale(a)}function e(a){switch(k.orientation()){case \"bottom\":case \"right\":return D.get(a)*A+I;case \"top\":case \"left\":return F-I-D.get(a)*A}}function g(a,b,c){a=a.selectAll(\".\"+c).data(B);b=a.enter().append(b).classed(c,!0).merge(a);a.exit().remove();return b}var k=this,m=c._ANNOTATION_LABEL_PADDING,n=new l.Map,B=this._annotatedTicksToRender();B.forEach(function(a){var b=\nk._annotationMeasurer.measure(k.annotationFormatter()(a));n.set(a,{width:b.width+2*m,height:b.height+2*m})});var A=this._annotationMeasurer.measure().height+2*m,D=this._annotationToTier(n),E=new l.Set,F=this.isHorizontal()?this.height():this.width(),I=this._coreSize(),H=Math.min(this.annotationTierCount(),Math.floor((F-I)/A));D.forEach(function(a,b){(-1===a||a>=H)&&E.add(b)});switch(this.orientation()){case \"bottom\":case \"right\":var C=0;break;case \"top\":C=this.height();break;case \"left\":C=this.width()}var J=\nthis.isHorizontal();g(this._annotationContainer.select(\".annotation-line-container\"),\"line\",c.ANNOTATION_LINE_CLASS).attrs({x1:J?d:C,x2:J?d:e,y1:J?C:d,y2:J?e:d,visibility:b});g(this._annotationContainer.select(\".annotation-circle-container\"),\"circle\",c.ANNOTATION_CIRCLE_CLASS).attrs({cx:J?d:C,cy:J?C:d,r:3});g(this._annotationContainer.select(\".annotation-rect-container\"),\"rect\",c.ANNOTATION_RECT_CLASS).attrs({x:J?d:a,y:J?a:d,width:J?function(a){return n.get(a).width}:function(a){return n.get(a).height},\nheight:J?function(a){return n.get(a).height}:function(a){return n.get(a).width},visibility:b});var M=this._annotationWriter,T=this.annotationFormatter();C=g(this._annotationContainer.select(\".annotation-label-container\"),\"g\",c.ANNOTATION_LABEL_CLASS);C.selectAll(\".text-container\").remove();C.attrs({transform:function(b){var c=J?d(b):a(b);b=J?a(b):d(b);return\"translate(\"+c+\",\"+b+\")\"},visibility:b}).each(function(a){M.write(T(a),J?n.get(a).width:n.get(a).height,J?n.get(a).height:n.get(a).width,{xAlign:\"center\",\nyAlign:\"center\",textRotation:J?0:90},f.select(this).node())})};c.prototype._annotatedTicksToRender=function(){var a=this,b=this._scale.range();return l.Array.uniq(this.annotatedTicks().filter(function(c){return null==c?!1:l.Math.inRange(a._scale.scale(c),b[0],b[1])}))};c.prototype._coreSize=function(){var a=this.isHorizontal()?this.height():this.width(),b=this.isHorizontal()?this._computeHeight():this._computeWidth();return Math.min(b,a)};c.prototype._annotationTierHeight=function(){return this._annotationMeasurer.measure().height+\n2*c._ANNOTATION_LABEL_PADDING};c.prototype._annotationToTier=function(a){var b=this,c=[[]],d=new l.Map,e=this.isHorizontal()?this.width():this.height();this._annotatedTicksToRender().forEach(function(f){var g=b._scale.scale(f),k=a.get(f).width;if(0>g||g+k>e)d.set(f,-1);else{for(var l=function(d){return c[d].some(function(c){var d=b._scale.scale(c);c=a.get(c).width;return g+k>=d&&g<=d+c})},m=0;l(m);)m++,c.length===m&&c.push([]);c[m].push(f);d.set(f,m)}});return d};c.prototype._removeAnnotations=function(){this._annotationContainer.selectAll(\".annotation-line\").remove();\nthis._annotationContainer.selectAll(\".annotation-circle\").remove();this._annotationContainer.selectAll(\".annotation-rect\").remove();this._annotationContainer.selectAll(\".annotation-label\").remove()};c.prototype._generateBaselineAttrHash=function(){var a={x1:0,y1:0,x2:0,y2:0};switch(this._orientation){case \"bottom\":a.x2=this.width();break;case \"top\":a.x2=this.width();a.y1=this.height();a.y2=this.height();break;case \"left\":a.x1=this.width();a.x2=this.width();a.y2=this.height();break;case \"right\":a.y2=\nthis.height()}return a};c.prototype._generateTickMarkAttrHash=function(a){function b(a){return c._scale.scale(a)}var c=this;void 0===a&&(a=!1);var d={x1:0,y1:0,x2:0,y2:0};this.isHorizontal()?(d.x1=b,d.x2=b):(d.y1=b,d.y2=b);a=a?this._endTickLength:this._innerTickLength;switch(this._orientation){case \"bottom\":d.y2=a;break;case \"top\":d.y1=this.height();d.y2=this.height()-a;break;case \"left\":d.x1=this.width();d.x2=this.width()-a;break;case \"right\":d.x2=a}return d};c.prototype._setDefaultAlignment=function(){switch(this._orientation){case \"bottom\":this.yAlignment(\"top\");\nbreak;case \"top\":this.yAlignment(\"bottom\");break;case \"left\":this.xAlignment(\"right\");break;case \"right\":this.xAlignment(\"left\")}};c.prototype.isHorizontal=function(){return\"top\"===this._orientation||\"bottom\"===this._orientation};c.prototype.getScale=function(){return this._scale};c.prototype.formatter=function(a){if(null==a)return this._formatter;this._formatter=a;this.redraw();return this};c.prototype.innerTickLength=function(){return this._innerTickLength};c.prototype.endTickLength=function(){return this._endTickLength};\nc.prototype._maxLabelTickLength=function(){return this.showEndTickLabels()?Math.max(this.innerTickLength(),this.endTickLength()):this.innerTickLength()};c.prototype.tickLabelPadding=function(a){if(null==a)return this._tickLabelPadding;if(0>a)throw Error(\"tick label padding must be positive\");this._tickLabelPadding=a;this.redraw();return this};c.prototype.margin=function(a){if(null==a)return this._margin;if(0>a)throw Error(\"margin size must be positive\");this._margin=a;this.redraw();return this};c.prototype.orientation=\nfunction(a){if(null==a)return this._orientation;a=a.toLowerCase();if(\"top\"!==a&&\"bottom\"!==a&&\"left\"!==a&&\"right\"!==a)throw Error(\"unsupported orientation\");this._orientation=a;this.redraw();return this};c.prototype.showEndTickLabels=function(){return this._showEndTickLabels};c.prototype._showAllTickMarks=function(){this._tickMarkContainer.selectAll(\".\"+c.TICK_MARK_CLASS).each(function(){f.select(this).style(\"visibility\",\"inherit\")})};c.prototype._showAllTickLabels=function(){this._tickLabelContainer.selectAll(\".\"+\nc.TICK_LABEL_CLASS).each(function(){f.select(this).style(\"visibility\",\"inherit\")})};c.prototype._hideOverflowingTickLabels=function(){var a=this.element().node().getBoundingClientRect(),b=this._tickLabelContainer.selectAll(\".\"+c.TICK_LABEL_CLASS);b.empty()||b.each(function(){l.DOM.clientRectInside(this.getBoundingClientRect(),a)||f.select(this).style(\"visibility\",\"hidden\")})};c.prototype._hideTickMarksWithoutLabel=function(){var a=this._tickMarkContainer.selectAll(\".\"+c.TICK_MARK_CLASS),b=this._tickLabelContainer.selectAll(\".\"+\nc.TICK_LABEL_CLASS).filter(function(){var a=f.select(this).style(\"visibility\");return\"inherit\"===a||\"visible\"===a}).data();a.each(function(a){-1===b.indexOf(a)&&f.select(this).style(\"visibility\",\"hidden\")})};c.prototype.invalidateCache=function(){a.prototype.invalidateCache.call(this);this._annotationMeasurer.reset()};return c}(a.Component);d.END_TICK_MARK_CLASS=\"end-tick-mark\";d.TICK_MARK_CLASS=\"tick-mark\";d.TICK_LABEL_CLASS=\"tick-label\";d.ANNOTATION_LINE_CLASS=\"annotation-line\";d.ANNOTATION_RECT_CLASS=\n\"annotation-rect\";d.ANNOTATION_CIRCLE_CLASS=\"annotation-circle\";d.ANNOTATION_LABEL_CLASS=\"annotation-label\";d._ANNOTATION_LABEL_PADDING=4;c.Axis=d},function(a,c){c.SHOW_WARNINGS=!0;c.ADD_TITLE_ELEMENTS=!0},function(a,c,d){var b=d(0);a=function(){function a(){this._eventToProcessingFunction={};this._eventNameToCallbackSet={};this._connected=!1}a.prototype._hasNoCallbacks=function(){for(var a=Object.keys(this._eventNameToCallbackSet),b=0;b<a.length;b++)if(0!==this._eventNameToCallbackSet[a[b]].size)return!1;\nreturn!0};a.prototype._connect=function(){var a=this;this._connected||(Object.keys(this._eventToProcessingFunction).forEach(function(b){document.addEventListener(b,a._eventToProcessingFunction[b])}),this._connected=!0)};a.prototype._disconnect=function(){var a=this;this._connected&&this._hasNoCallbacks()&&(Object.keys(this._eventToProcessingFunction).forEach(function(b){document.removeEventListener(b,a._eventToProcessingFunction[b])}),this._connected=!1)};a.prototype._addCallbackForEvent=function(a,\nc){null==this._eventNameToCallbackSet[a]&&(this._eventNameToCallbackSet[a]=new b.CallbackSet);this._eventNameToCallbackSet[a].add(c);this._connect()};a.prototype._removeCallbackForEvent=function(a,b){null!=this._eventNameToCallbackSet[a]&&this._eventNameToCallbackSet[a].delete(b);this._disconnect()};a.prototype._callCallbacksForEvent=function(a){for(var b=[],c=1;c<arguments.length;c++)b[c-1]=arguments[c];c=this._eventNameToCallbackSet[a];null!=c&&c.callCallbacks.apply(c,b)};return a}();c.Dispatcher=\na},function(a,c,d){var b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=null===b?Object.create(b):(c.prototype=b.prototype,new c)},f=d(1),g=d(5),k=d(7),l=d(10),m=d(6),n=d(32),q=d(3),p=d(11),t=d(0);a=d(9);var r=d(17),v=d(2);d=d(16);c.BarOrientation=a.makeEnum([\"vertical\",\"horizontal\"]);c.LabelsPosition=a.makeEnum([\"start\",\"middle\",\"end\",\"outside\"]);c.BarAlignment=a.makeEnum([\"start\",\"middle\",\"end\"]);d=function(a){function d(b){void 0===\nb&&(b=\"vertical\");var d=a.call(this)||this;d._labelFormatter=l.identity();d._labelsEnabled=!1;d._labelsPosition=c.LabelsPosition.end;d._hideBarsIfAnyAreTooWide=!0;d._barAlignment=\"middle\";d._fixedWidth=!0;d._barPixelWidth=0;d.addClass(\"bar-plot\");if(\"vertical\"!==b&&\"horizontal\"!==b)throw Error(b+\" is not a valid orientation for Plots.Bar\");d._isVertical=\"vertical\"===b;d.animator(\"baseline\",new k.Null);d.attr(\"fill\",(new q.Color).range()[0]);d.attr(\"width\",function(){return d._barPixelWidth});d._labelConfig=\nnew t.Map;d._baselineValueProvider=function(){return[d.baselineValue()]};d._updateBarPixelWidthCallback=function(){return d._updateBarPixelWidth()};return d}b(d,a);d.prototype.x=function(b,c){if(null==b)return a.prototype.x.call(this);null==c?a.prototype.x.call(this,b):(a.prototype.x.call(this,b,c),c.onUpdate(this._updateBarPixelWidthCallback));this._updateWidthAccesor();this._updateValueScale();return this};d.prototype.y=function(b,c){if(null==b)return a.prototype.y.call(this);null==c?a.prototype.y.call(this,\nb):(a.prototype.y.call(this,b,c),c.onUpdate(this._updateBarPixelWidthCallback));this._updateValueScale();return this};d.prototype.barEnd=function(){return this._propertyBindings.get(d._BAR_END_KEY)};d.prototype.barAlignment=function(a){if(null==a)return this._barAlignment;this._barAlignment=a;this.render();return this};d.prototype.orientation=function(){return this._isVertical?\"vertical\":\"horizontal\"};d.prototype.render=function(){this._updateBarPixelWidth();this._updateExtents();a.prototype.render.call(this);\nreturn this};d.prototype._createDrawer=function(){return new m.ProxyDrawer(function(){return new n.RectangleSVGDrawer(d._BAR_AREA_CLASS)},n.RectangleCanvasDrawStep)};d.prototype._setup=function(){a.prototype._setup.call(this);this._baseline=this._renderArea.append(\"line\").classed(\"baseline\",!0)};d.prototype.baselineValue=function(){if(null!=this._baselineValue)return this._baselineValue;if(!this._projectorsReady())return 0;var a=this._isVertical?this.y().scale:this.x().scale;return a?a instanceof\nq.Time?new Date(0):0:0};d.prototype.addDataset=function(b){a.prototype.addDataset.call(this,b);this._updateBarPixelWidth();return this};d.prototype._addDataset=function(b){b.onUpdate(this._updateBarPixelWidthCallback);a.prototype._addDataset.call(this,b);return this};d.prototype.removeDataset=function(b){b.offUpdate(this._updateBarPixelWidthCallback);a.prototype.removeDataset.call(this,b);this._updateBarPixelWidth();return this};d.prototype._removeDataset=function(b){b.offUpdate(this._updateBarPixelWidthCallback);\na.prototype._removeDataset.call(this,b);return this};d.prototype.datasets=function(b){if(null==b)return a.prototype.datasets.call(this);a.prototype.datasets.call(this,b);this._updateBarPixelWidth();return this};d.prototype.labelsEnabled=function(a,b){if(null==a)return this._labelsEnabled;this._labelsEnabled=a;null!=b&&(this._labelsPosition=b);this.render();return this};d.prototype.labelFormatter=function(a){if(null==a)return this._labelFormatter;this._labelFormatter=a;this.render();return this};d.prototype._createNodesForDataset=\nfunction(b){var c=a.prototype._createNodesForDataset.call(this,b),e=this._renderArea.append(\"g\").classed(d._LABEL_AREA_CLASS,!0),f=new g.SvgContext(e.node()),k=new g.CacheMeasurer(f),f=new g.Writer(k,f);this._labelConfig.set(b,{labelArea:e,measurer:k,writer:f});return c};d.prototype._removeDatasetNodes=function(b){a.prototype._removeDatasetNodes.call(this,b);var c=this._labelConfig.get(b);null!=c&&(c.labelArea.remove(),this._labelConfig.delete(b))};d.prototype.entityNearest=function(a){var b=this,\nc=Infinity,d=Infinity,e=this._isVertical?a.x:a.y,g=this._isVertical?a.y:a.x,k=this.bounds(),l;this._getEntityStore().entities().forEach(function(m){if(b._entityVisibleOnPlot(m,k)){var n=0,q=0,r=b._pixelPoint(m.datum,m.index,m.dataset),p=t.DOM.elementBBox(f.select(m.drawer.getVisualPrimitiveAtIndex(m.validDatumIndex)));t.DOM.intersectsBBox(a.x,a.y,p,.5)||(n=Math.abs(e-(b._isVertical?r.x:r.y)),q=b._isVertical?p.y:p.x,p=q+(b._isVertical?p.height:p.width),q=g>=q-.5&&g<=p+.5?0:Math.abs(g-(b._isVertical?\nr.y:r.x)));if(n<c||n===c&&q<d)l=m,c=n,d=q}});if(void 0!==l)return this._lightweightPlotEntityToPlotEntity(l)};d.prototype._entityVisibleOnPlot=function(a,b){var c={min:0,max:b.bottomRight.x-b.topLeft.x};b={min:0,max:b.bottomRight.y-b.topLeft.y};var d=this._generateAttrToProjector(),e=a.datum,f=a.index;a=a.dataset;a={x:d.x(e,f,a),y:d.y(e,f,a),width:d.width(e,f,a),height:d.height(e,f,a)};return t.DOM.intersectsBBox(c,b,a)};d.prototype.entitiesAt=function(a){return this._entitiesIntersecting(a.x,a.y)};\nd.prototype.entitiesIn=function(a,b){if(null==b){var c={min:a.topLeft.x,max:a.bottomRight.x};a={min:a.topLeft.y,max:a.bottomRight.y}}else c=a,a=b;return this._entitiesIntersecting(c,a)};d.prototype._entitiesIntersecting=function(a,b){var c=this,d=[];this._getEntityStore().entities().forEach(function(e){var g=f.select(e.drawer.getVisualPrimitiveAtIndex(e.validDatumIndex));t.DOM.intersectsBBox(a,b,t.DOM.elementBBox(g))&&d.push(c._lightweightPlotEntityToPlotEntity(e))});return d};d.prototype._updateValueScale=\nfunction(){if(this._projectorsReady()){var a=this._isVertical?this.y().scale:this.x().scale;a instanceof p.QuantitativeScale&&(a.addPaddingExceptionsProvider(this._baselineValueProvider),a.addIncludedValuesProvider(this._baselineValueProvider))}};d.prototype._additionalPaint=function(a){var b=this,c=(this._isVertical?this.y().scale:this.x().scale).scale(this.baselineValue()),c={x1:this._isVertical?0:c,y1:this._isVertical?c:0,x2:this._isVertical?this.width():c,y2:this._isVertical?c:this.height()};\nthis._getAnimator(\"baseline\").animate(this._baseline,c);this.datasets().forEach(function(a){return b._labelConfig.get(a).labelArea.selectAll(\"g\").remove()});this._labelsEnabled&&t.Window.setTimeout(function(){return b._drawLabels()},a)};d.prototype._extentsForProperty=function(b){var c=this,d=a.prototype._extentsForProperty.call(this,b);if(\"x\"===b&&this._isVertical)b=this.x();else{if(\"y\"!==b||this._isVertical)return d;b=this.y()}if(!(b&&b.scale&&b.scale instanceof p.QuantitativeScale))return d;var e=\nb.scale,g=this._barPixelWidth;return d=d.map(function(a){return f.extent([e.invert(c._getAlignedX(e.scale(a[0]),g)),e.invert(c._getAlignedX(e.scale(a[0]),g)+g),e.invert(c._getAlignedX(e.scale(a[1]),g)),e.invert(c._getAlignedX(e.scale(a[1]),g)+g)])})};d.prototype._getAlignedX=function(a,b){this._isVertical||(a-=b,b*=-1);switch(this._barAlignment){case \"start\":return a;case \"end\":return a-b;default:return a-b/2}};d.prototype._drawLabels=function(){var a=this,b=this._getDataToDraw(),c=this._generateAttrToProjector(),\nd=this.datasets().some(function(d){return b.get(d).some(function(b,e){return a._drawLabel(b,e,d,c)})});this._hideBarsIfAnyAreTooWide&&d&&this.datasets().forEach(function(b){return a._labelConfig.get(b).labelArea.selectAll(\"g\").remove()})};d.prototype._drawLabel=function(a,b,c,e){var f=this._labelConfig.get(c),g=f.labelArea,k=f.measurer,f=f.writer,l=this._isVertical?this.y().accessor:this.x().accessor,m=l(a,b,c),n=this._isVertical?this.y().scale:this.x().scale,q=null!=n?n.scale(m):m,r=null!=n?n.scale(this.baselineValue()):\nthis.baselineValue(),p={x:e.x(a,b,c),y:e.y(a,b,c)},n={width:e.width(a,b,c),height:e.height(a,b,c)},l=this._labelFormatter(l(a,b,c)),k=k.measure(l),m=this._getShowLabelOnBar(p,n,k),t=this._calculateLabelProperties(p,n,k,m,this._isVertical?q<=r:q<r),q=t.containerDimensions,r=t.labelContainerOrigin,p=t.labelOrigin,t=t.alignment;a=e.fill(a,b,c);g=this._createLabelContainer(g,r,p,k,m,a);f.write(l,q.width,q.height,{xAlign:t.x,yAlign:t.y},g.node());return this._isVertical?n.width<k.width+2*d._LABEL_PADDING:\nn.height<k.height+2*d._LABEL_PADDING};d.prototype._getShowLabelOnBar=function(a,b,e){if(this._labelsPosition===c.LabelsPosition.outside)return!1;a=this._isVertical?a.y:a.x;b=this._isVertical?b.height:b.width;var f=this._isVertical?this.height():this.width();e=this._isVertical?e.height:e.width;var g=b;a+b>f?g=f-a:0>a&&(g=a+b);return e+2*d._LABEL_PADDING<=g};d.prototype._calculateLabelProperties=function(a,b,e,f,g){function k(a){switch(a){case \"topLeft\":r=l._isVertical?\"top\":\"left\";t+=d._LABEL_PADDING;\nv+=d._LABEL_PADDING;break;case \"center\":v+=(n+q)/2;break;case \"bottomRight\":r=l._isVertical?\"bottom\":\"right\",t-=d._LABEL_PADDING,v+=p-d._LABEL_PADDING-q}}var l=this,m=this._isVertical?a.y:a.x,n=this._isVertical?b.height:b.width,q=this._isVertical?e.height:e.width,r=\"center\",p=n,t=m,v=m;if(f)switch(this._labelsPosition){case c.LabelsPosition.start:g?k(\"bottomRight\"):k(\"topLeft\");break;case c.LabelsPosition.middle:k(\"center\");break;case c.LabelsPosition.end:g?k(\"topLeft\"):k(\"bottomRight\")}else g?(r=\nthis._isVertical?\"top\":\"left\",p=n+d._LABEL_PADDING+q,t-=d._LABEL_PADDING+q,v-=d._LABEL_PADDING+q):(r=this._isVertical?\"bottom\":\"right\",p=n+d._LABEL_PADDING+q,v+=n+d._LABEL_PADDING);return{containerDimensions:{width:this._isVertical?b.width:p,height:this._isVertical?p:b.height},labelContainerOrigin:{x:this._isVertical?a.x:t,y:this._isVertical?t:a.y},labelOrigin:{x:this._isVertical?a.x+b.width/2-e.width/2:v,y:this._isVertical?v:a.y+b.height/2-e.height/2},alignment:{x:this._isVertical?\"center\":r,y:this._isVertical?\nr:\"center\"}}};d.prototype._createLabelContainer=function(a,b,c,d,e,f){a=a.append(\"g\").attr(\"transform\",\"translate(\"+b.x+\", \"+b.y+\")\");e?(a.classed(\"on-bar-label\",!0),e=1.6*t.Color.contrast(\"white\",f)<t.Color.contrast(\"black\",f),a.classed(e?\"dark-label\":\"light-label\",!0)):a.classed(\"off-bar-label\",!0);c=0>c.x||0>c.y||c.x+d.width>this.width()||c.y+d.height>this.height();a.style(\"visibility\",c?\"hidden\":\"inherit\");return a};d.prototype._generateDrawSteps=function(){var a=[];if(this._animateOnNextRender()){var b=\nthis._generateAttrToProjector(),c=(this._isVertical?this.y().scale:this.x().scale).scale(this.baselineValue()),d=this._isVertical?\"height\":\"width\";b[this._isVertical?\"y\":\"x\"]=function(){return c};b[d]=function(){return 0};a.push({attrToProjector:b,animator:this._getAnimator(r.Animator.RESET)})}a.push({attrToProjector:this._generateAttrToProjector(),animator:this._getAnimator(r.Animator.MAIN)});return a};d.prototype._generateAttrToProjector=function(){function b(a,b,c){return Math.abs(k-n(a,b,c))}\nvar c=this,d=a.prototype._generateAttrToProjector.call(this),e=this._isVertical?this.y().scale:this.x().scale,f=this._isVertical?\"y\":\"x\",g=this._isVertical?\"x\":\"y\",k=e.scale(this.baselineValue()),l=this._isVertical?v.Plot._scaledAccessor(this.x()):v.Plot._scaledAccessor(this.y()),m=d.width,n=this._isVertical?v.Plot._scaledAccessor(this.y()):v.Plot._scaledAccessor(this.x()),q=d.gap,e=null==q?m:function(a,b,c){return m(a,b,c)-q(a,b,c)};d.width=this._isVertical?e:b;d.height=this._isVertical?b:e;d[g]=\nfunction(a,b,d){return c._getAlignedX(l(a,b,d),m(a,b,d))};d[f]=function(a,b,c){a=n(a,b,c);return a>k?k:a};return d};d.prototype._updateWidthAccesor=function(){var a=this,b=this._isVertical?this.x():this.y(),c=this.barEnd();null!=b&&null!=c?(this._fixedWidth=!1,this.attr(\"width\",function(a,d,e){var f=b.accessor(a,d,e);a=c.accessor(a,d,e);f=b.scale?b.scale.scale(f):f;a=c.scale?c.scale.scale(a):a;return Math.abs(a-f)})):(this._fixedWidth=!0,this._updateBarPixelWidth(),this.attr(\"width\",function(){return a._barPixelWidth}))};\nd.prototype._getBarPixelWidth=function(){if(!this._projectorsReady())return 0;var a=this._isVertical?this.x().scale:this.y().scale;if(a instanceof q.Category)var b=a.rangeBand();else{var c=this._isVertical?this.x().accessor:this.y().accessor;b=f.set(t.Array.flatten(this.datasets().map(function(a){return a.data().map(function(b,d){return c(b,d,a)}).filter(function(a){return null!=a}).map(function(a){return a.valueOf()})}))).values().map(function(a){return+a});b.sort(function(a,b){return a-b});b=b.map(function(b){return a.scale(b)});\nb=f.pairs(b);var e=this._isVertical?this.width():this.height();b=t.Math.min(b,function(a){return Math.abs(a[1]-a[0])},e*d._SINGLE_BAR_DIMENSION_RATIO);b*=d._BAR_WIDTH_RATIO}return b};d.prototype._updateBarPixelWidth=function(){this._fixedWidth&&(this._barPixelWidth=this._getBarPixelWidth())};d.prototype.entities=function(b){void 0===b&&(b=this.datasets());return this._projectorsReady()?a.prototype.entities.call(this,b):[]};d.prototype._pixelPoint=function(a,b,c){var d=this._generateAttrToProjector(),\ne=d.x(a,b,c),f=d.y(a,b,c),g=d.width(a,b,c),d=d.height(a,b,c);a=(this._isVertical?v.Plot._scaledAccessor(this.y()):v.Plot._scaledAccessor(this.x()))(a,b,c);b=(this._isVertical?this.y().scale:this.x().scale).scale(this.baselineValue());this._isVertical?(e+=g/2,f=a<=b?f:f+d):(e=a>=b?e+g:e,f+=d/2);return{x:e,y:f}};d.prototype._uninstallScaleForKey=function(b,c){b.offUpdate(this._updateBarPixelWidthCallback);a.prototype._uninstallScaleForKey.call(this,b,c)};d.prototype._getDataToDraw=function(){var a=\nnew t.Map,b=this._generateAttrToProjector();this.datasets().forEach(function(c){var d=c.data().filter(function(a,d){return t.Math.isValidNumber(b.x(a,d,c))&&t.Math.isValidNumber(b.y(a,d,c))&&t.Math.isValidNumber(b.width(a,d,c))&&t.Math.isValidNumber(b.height(a,d,c))});a.set(c,d)});return a};return d}(d.XYPlot);d._BAR_WIDTH_RATIO=.95;d._SINGLE_BAR_DIMENSION_RATIO=.4;d._BAR_AREA_CLASS=\"bar-area\";d._BAR_END_KEY=\"barEnd\";d._LABEL_AREA_CLASS=\"bar-label-text-area\";d._LABEL_PADDING=10;c.Bar=d},function(a,\nc,d){function b(a){g.SHOW_WARNINGS&&console.warn(a)}function f(a,b){for(var c=[],d=2;d<arguments.length;d++)c[d-2]=arguments[d];return 0===b?(a(c),-1):window.setTimeout(a,b,c)}var g=d(22);c.warn=b;c.setTimeout=f;c.debounce=function(a,b,c){function d(){b.apply(c,g)}var e=null,g=[];return function(){g=Array.prototype.slice.call(arguments);clearTimeout(e);e=f(d,a)}};c.deprecated=function(a,c,d){void 0===d&&(d=\"\");b(\"Method \"+a+\" has been deprecated in version \"+c+\". Please refer to the release notes. \"+\nd)}},function(a,c,d){var b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=null===b?Object.create(b):(c.prototype=b.prototype,new c)},f=d(1),g=d(5),k=d(10),l=d(3),m=d(0);a=d(9);var n=d(21);c.TimeInterval=a.makeEnum(\"second minute hour day week month year\".split(\" \"));c.TimeAxisOrientation=a.makeEnum([\"top\",\"bottom\"]);c.TierLabelPosition=a.makeEnum([\"between\",\"center\"]);d=function(a){function c(b,d){b=a.call(this,b,d)||\nthis;b._maxTimeIntervalPrecision=null;b._tierLabelPositions=[];b.addClass(\"time-axis\");b.tickLabelPadding(5);b.axisConfigurations(c._DEFAULT_TIME_AXIS_CONFIGURATIONS);b.annotationFormatter(k.time(\"%a %b %d, %Y\"));return b}b(c,a);c.prototype.tierLabelPositions=function(a){if(null==a)return this._tierLabelPositions;if(!a.every(function(a){return\"between\"===a.toLowerCase()||\"center\"===a.toLowerCase()}))throw Error(\"Unsupported position for tier labels\");this._tierLabelPositions=a;this.redraw();return this};\nc.prototype.maxTimeIntervalPrecision=function(a){if(null==a)return this._maxTimeIntervalPrecision;this._maxTimeIntervalPrecision=a;this.redraw();return this};c.prototype.currentAxisConfiguration=function(){return this._possibleTimeAxisConfigurations[this._mostPreciseConfigIndex]};c.prototype.axisConfigurations=function(a){if(null!=a){this._possibleTimeAxisConfigurations=a;this._numTiers=m.Math.max(this._possibleTimeAxisConfigurations.map(function(a){return a.length}),0);this._isAnchored&&this._setupDomElements();\na=this.tierLabelPositions();for(var b=[],c=0;c<this._numTiers;c++)b.push(a[c]||\"between\");this.tierLabelPositions(b);this.redraw()}};c.prototype._getMostPreciseConfigurationIndex=function(){var a=this,b=this._possibleTimeAxisConfigurations.length;this._possibleTimeAxisConfigurations.forEach(function(c,d){d<b&&c.every(function(b){return a._checkTimeAxisTierConfiguration(b)})&&(b=d)});b===this._possibleTimeAxisConfigurations.length&&(m.Window.warn(\"zoomed out too far: could not find suitable interval to display labels\"),\n--b);return b};c.prototype.orientation=function(b){if(b&&(\"right\"===b.toLowerCase()||\"left\"===b.toLowerCase()))throw Error(b+\" is not a supported orientation for TimeAxis - only horizontal orientations are supported\");return a.prototype.orientation.call(this,b)};c.prototype._computeHeight=function(){var a=this._measurer.measure().height;this._tierHeights=[];for(var b=0;b<this._numTiers;b++)this._tierHeights.push(a+this.tickLabelPadding()+(\"between\"===this._tierLabelPositions[b]?0:this._maxLabelTickLength()));\nreturn f.sum(this._tierHeights)};c.prototype._getIntervalLength=function(a){var b=this._scale.domain()[0];a=l.Time.timeIntervalToD3Time(a.interval).offset(b,a.step);return a>this._scale.domain()[1]?this.width():Math.abs(this._scale.scale(a)-this._scale.scale(b))};c.prototype._maxWidthForInterval=function(a){return this._measurer.measure(a.formatter(c._LONG_DATE)).width};c.prototype._checkTimeAxisTierConfiguration=function(a){if(null!=this._maxTimeIntervalPrecision){var b=c._SORTED_TIME_INTERVAL_INDEX[this._maxTimeIntervalPrecision],\nd=c._SORTED_TIME_INTERVAL_INDEX[a.interval];if(null!=b&&null!=d&&d<b)return!1}b=this._maxWidthForInterval(a)+2*this.tickLabelPadding();return Math.min(this._getIntervalLength(a),this.width())>=b};c.prototype._sizeFromOffer=function(b,c){var d=a.prototype._sizeFromOffer.call(this,b,c);b=this._tierHeights.reduce(function(a,b){return a+b>d.height?a:a+b});c=this.margin()+(this.annotationsEnabled()?this.annotationTierCount()*this._annotationTierHeight():0);d.height=Math.min(d.height,b+c);return d};c.prototype._setup=\nfunction(){a.prototype._setup.call(this);this._setupDomElements()};c.prototype._setupDomElements=function(){this.content().selectAll(\".\"+c.TIME_AXIS_TIER_CLASS).remove();this._tierLabelContainers=[];this._tierMarkContainers=[];this._tierBaselines=[];this._tickLabelContainer.remove();this._baseline.remove();for(var a=0;a<this._numTiers;++a){var b=this.content().append(\"g\").classed(c.TIME_AXIS_TIER_CLASS,!0);this._tierLabelContainers.push(b.append(\"g\").classed(n.Axis.TICK_LABEL_CLASS+\"-container\",!0));\nthis._tierMarkContainers.push(b.append(\"g\").classed(n.Axis.TICK_MARK_CLASS+\"-container\",!0));this._tierBaselines.push(b.append(\"line\").classed(\"baseline\",!0))}a=new g.SvgContext(this._tierLabelContainers[0].node());this._measurer=new g.CacheMeasurer(a)};c.prototype._getTickIntervalValues=function(a){return this._scale.tickInterval(a.interval,a.step)};c.prototype._getTickValues=function(){var a=this;return this._possibleTimeAxisConfigurations[this._mostPreciseConfigIndex].reduce(function(b,c){return b.concat(a._getTickIntervalValues(c))},\n[])};c.prototype._cleanTiers=function(){for(var a=0;a<this._tierLabelContainers.length;a++)this._tierLabelContainers[a].selectAll(\".\"+n.Axis.TICK_LABEL_CLASS).remove(),this._tierMarkContainers[a].selectAll(\".\"+n.Axis.TICK_MARK_CLASS).remove(),this._tierBaselines[a].style(\"visibility\",\"hidden\")};c.prototype._getTickValuesForConfiguration=function(a){a=this._scale.tickInterval(a.interval,a.step);var b=this._scale.domain(),c=a.map(function(a){return a.valueOf()});-1===c.indexOf(b[0].valueOf())&&a.unshift(b[0]);\n-1===c.indexOf(b[1].valueOf())&&a.push(b[1]);return a};c.prototype._renderTierLabels=function(a,b,c){var d=this,e=this._getTickValuesForConfiguration(b),g=[];\"between\"===this._tierLabelPositions[c]&&1===b.step?e.map(function(a,b){b+1>=e.length||g.push(new Date((e[b+1].valueOf()-e[b].valueOf())/2+e[b].valueOf()))}):g=e;a=a.selectAll(\".\"+n.Axis.TICK_LABEL_CLASS).data(g,function(a){return String(a.valueOf())});var k=a.enter().append(\"g\").classed(n.Axis.TICK_LABEL_CLASS,!0);k.append(\"text\");var l=\"center\"===\nthis._tierLabelPositions[c]||1===b.step?0:this.tickLabelPadding();var m=\"bottom\"===this.orientation()?f.sum(this._tierHeights.slice(0,c+1))-this.tickLabelPadding():\"center\"===this._tierLabelPositions[c]?this.height()-f.sum(this._tierHeights.slice(0,c))-this.tickLabelPadding()-this._maxLabelTickLength():this.height()-f.sum(this._tierHeights.slice(0,c))-this.tickLabelPadding();var k=a.merge(k),q=k.selectAll(\"text\");0<q.size()&&q.attr(\"transform\",\"translate(\"+l+\",\"+m+\")\");a.exit().remove();k.attr(\"transform\",\nfunction(a){return\"translate(\"+d._scale.scale(a)+\",0)\"});c=\"center\"===this._tierLabelPositions[c]||1===b.step?\"middle\":\"start\";k.selectAll(\"text\").text(b.formatter).style(\"text-anchor\",c)};c.prototype._renderTickMarks=function(a,b){a=this._tierMarkContainers[b].selectAll(\".\"+n.Axis.TICK_MARK_CLASS).data(a);var c=a.enter().append(\"line\").classed(n.Axis.TICK_MARK_CLASS,!0).merge(a),d=this._generateTickMarkAttrHash(),e=this._tierHeights.slice(0,b).reduce(function(a,b){return a+b},0);\"bottom\"===this.orientation()?\n(d.y1=e,d.y2=e+(\"center\"===this._tierLabelPositions[b]?this.innerTickLength():this._tierHeights[b])):(d.y1=this.height()-e,d.y2=this.height()-(e+(\"center\"===this._tierLabelPositions[b]?this.innerTickLength():this._tierHeights[b])));c.attrs(d);\"bottom\"===this.orientation()?(d.y1=e,d.y2=e+(\"center\"===this._tierLabelPositions[b]?this.endTickLength():this._tierHeights[b])):(d.y1=this.height()-e,d.y2=this.height()-(e+(\"center\"===this._tierLabelPositions[b]?this.endTickLength():this._tierHeights[b])));\nf.select(c.nodes()[0]).attrs(d);f.select(c.nodes()[c.size()-1]).attrs(d);f.select(c.nodes()[0]).classed(n.Axis.END_TICK_MARK_CLASS,!0);f.select(c.nodes()[c.size()-1]).classed(n.Axis.END_TICK_MARK_CLASS,!0);a.exit().remove()};c.prototype._renderLabellessTickMarks=function(a){a=this._tickMarkContainer.selectAll(\".\"+n.Axis.TICK_MARK_CLASS).data(a);var b=a.enter().append(\"line\").classed(n.Axis.TICK_MARK_CLASS,!0).merge(a),c=this._generateTickMarkAttrHash();c.y2=\"bottom\"===this.orientation()?this.tickLabelPadding():\nthis.height()-this.tickLabelPadding();b.attrs(c);a.exit().remove()};c.prototype._generateLabellessTicks=function(){return 1>this._mostPreciseConfigIndex?[]:this._getTickIntervalValues(this._possibleTimeAxisConfigurations[this._mostPreciseConfigIndex-1][0])};c.prototype.renderImmediately=function(){var a=this;this._mostPreciseConfigIndex=this._getMostPreciseConfigurationIndex();var b=this._possibleTimeAxisConfigurations[this._mostPreciseConfigIndex];this._cleanTiers();b.forEach(function(b,c){return a._renderTierLabels(a._tierLabelContainers[c],\nb,c)});for(var c=b.map(function(b){return a._getTickValuesForConfiguration(b)}),d=0,e=0;e<Math.max(b.length,1);++e){var f=this._generateBaselineAttrHash();f.y1+=\"bottom\"===this.orientation()?d:-d;f.y2=f.y1;this._tierBaselines[e].attrs(f).style(\"visibility\",\"inherit\");d+=this._tierHeights[e]}d=[];e=this._scale.domain();e=this._scale.scale(e[1])-this._scale.scale(e[0]);1.5*this._getIntervalLength(b[0])>=e&&(d=this._generateLabellessTicks());this._renderLabellessTickMarks(d);this._hideOverflowingTiers();\nfor(e=0;e<b.length;++e)this._renderTickMarks(c[e],e),this._hideOverlappingAndCutOffLabels(e);this.annotationsEnabled()?this._drawAnnotations():this._removeAnnotations();return this};c.prototype._hideOverflowingTiers=function(){var a=this,b=this.height(),d=0;this.content().selectAll(\".\"+c.TIME_AXIS_TIER_CLASS).attr(\"visibility\",function(c,e){d+=a._tierHeights[e];return d<=b?\"inherit\":\"hidden\"})};c.prototype._hideOverlappingAndCutOffLabels=function(a){var b=this,c=this.element().node().getBoundingClientRect(),\nd=this._tierMarkContainers[a].selectAll(\".\"+n.Axis.TICK_MARK_CLASS).filter(function(){var a=f.select(this).style(\"visibility\");return\"visible\"===a||\"inherit\"===a}).nodes().map(function(a){return a.getBoundingClientRect()}),e;this._tierLabelContainers[a].selectAll(\".\"+n.Axis.TICK_LABEL_CLASS).filter(function(){var a=f.select(this).style(\"visibility\");return\"visible\"===a||\"inherit\"===a}).each(function(a,g){a=this.getBoundingClientRect();var k=f.select(this),l=d[g],n=d[g+1];g=null!=e&&m.DOM.clientRectsOverlap(a,\ne);l=null!=l&&m.DOM.clientRectsOverlap(a,l);n=null!=n&&m.DOM.clientRectsOverlap(a,n);!(Math.floor(c.left)<=Math.ceil(a.left)&&Math.floor(c.top)<=Math.ceil(a.top)&&Math.floor(a.right)<=Math.ceil(c.left+b.width())&&Math.floor(a.bottom)<=Math.ceil(c.top+b.height()))||g||l||n?k.style(\"visibility\",\"hidden\"):(e=a,k.style(\"visibility\",\"inherit\"))})};c.prototype.invalidateCache=function(){a.prototype.invalidateCache.call(this);this._measurer.reset()};return c}(n.Axis);d.TIME_AXIS_TIER_CLASS=\"time-axis-tier\";\nd._SORTED_TIME_INTERVAL_INDEX=(q={},q[c.TimeInterval.second]=0,q[c.TimeInterval.minute]=1,q[c.TimeInterval.hour]=2,q[c.TimeInterval.day]=3,q[c.TimeInterval.week]=4,q[c.TimeInterval.month]=5,q[c.TimeInterval.year]=6,q);d._DEFAULT_TIME_AXIS_CONFIGURATIONS=[[{interval:c.TimeInterval.second,step:1,formatter:k.time(\"%I:%M:%S %p\")},{interval:c.TimeInterval.day,step:1,formatter:k.time(\"%B %e, %Y\")}],[{interval:c.TimeInterval.second,step:5,formatter:k.time(\"%I:%M:%S %p\")},{interval:c.TimeInterval.day,step:1,\nformatter:k.time(\"%B %e, %Y\")}],[{interval:c.TimeInterval.second,step:10,formatter:k.time(\"%I:%M:%S %p\")},{interval:c.TimeInterval.day,step:1,formatter:k.time(\"%B %e, %Y\")}],[{interval:c.TimeInterval.second,step:15,formatter:k.time(\"%I:%M:%S %p\")},{interval:c.TimeInterval.day,step:1,formatter:k.time(\"%B %e, %Y\")}],[{interval:c.TimeInterval.second,step:30,formatter:k.time(\"%I:%M:%S %p\")},{interval:c.TimeInterval.day,step:1,formatter:k.time(\"%B %e, %Y\")}],[{interval:c.TimeInterval.minute,step:1,formatter:k.time(\"%I:%M %p\")},\n{interval:c.TimeInterval.day,step:1,formatter:k.time(\"%B %e, %Y\")}],[{interval:c.TimeInterval.minute,step:5,formatter:k.time(\"%I:%M %p\")},{interval:c.TimeInterval.day,step:1,formatter:k.time(\"%B %e, %Y\")}],[{interval:c.TimeInterval.minute,step:10,formatter:k.time(\"%I:%M %p\")},{interval:c.TimeInterval.day,step:1,formatter:k.time(\"%B %e, %Y\")}],[{interval:c.TimeInterval.minute,step:15,formatter:k.time(\"%I:%M %p\")},{interval:c.TimeInterval.day,step:1,formatter:k.time(\"%B %e, %Y\")}],[{interval:c.TimeInterval.minute,\nstep:30,formatter:k.time(\"%I:%M %p\")},{interval:c.TimeInterval.day,step:1,formatter:k.time(\"%B %e, %Y\")}],[{interval:c.TimeInterval.hour,step:1,formatter:k.time(\"%I %p\")},{interval:c.TimeInterval.day,step:1,formatter:k.time(\"%B %e, %Y\")}],[{interval:c.TimeInterval.hour,step:3,formatter:k.time(\"%I %p\")},{interval:c.TimeInterval.day,step:1,formatter:k.time(\"%B %e, %Y\")}],[{interval:c.TimeInterval.hour,step:6,formatter:k.time(\"%I %p\")},{interval:c.TimeInterval.day,step:1,formatter:k.time(\"%B %e, %Y\")}],\n[{interval:c.TimeInterval.hour,step:12,formatter:k.time(\"%I %p\")},{interval:c.TimeInterval.day,step:1,formatter:k.time(\"%B %e, %Y\")}],[{interval:c.TimeInterval.day,step:1,formatter:k.time(\"%a %e\")},{interval:c.TimeInterval.month,step:1,formatter:k.time(\"%B %Y\")}],[{interval:c.TimeInterval.day,step:1,formatter:k.time(\"%e\")},{interval:c.TimeInterval.month,step:1,formatter:k.time(\"%B %Y\")}],[{interval:c.TimeInterval.month,step:1,formatter:k.time(\"%B\")},{interval:c.TimeInterval.year,step:1,formatter:k.time(\"%Y\")}],\n[{interval:c.TimeInterval.month,step:1,formatter:k.time(\"%b\")},{interval:c.TimeInterval.year,step:1,formatter:k.time(\"%Y\")}],[{interval:c.TimeInterval.month,step:3,formatter:k.time(\"%b\")},{interval:c.TimeInterval.year,step:1,formatter:k.time(\"%Y\")}],[{interval:c.TimeInterval.month,step:6,formatter:k.time(\"%b\")},{interval:c.TimeInterval.year,step:1,formatter:k.time(\"%Y\")}],[{interval:c.TimeInterval.year,step:1,formatter:k.time(\"%Y\")}],[{interval:c.TimeInterval.year,step:1,formatter:k.time(\"%y\")}],\n[{interval:c.TimeInterval.year,step:5,formatter:k.time(\"%Y\")}],[{interval:c.TimeInterval.year,step:25,formatter:k.time(\"%Y\")}],[{interval:c.TimeInterval.year,step:50,formatter:k.time(\"%Y\")}],[{interval:c.TimeInterval.year,step:100,formatter:k.time(\"%Y\")}],[{interval:c.TimeInterval.year,step:200,formatter:k.time(\"%Y\")}],[{interval:c.TimeInterval.year,step:500,formatter:k.time(\"%Y\")}],[{interval:c.TimeInterval.year,step:1E3,formatter:k.time(\"%Y\")}]];d._LONG_DATE=new Date(9999,8,29,12,59,9999);c.Time=\nd;var q},function(a,c,d){var b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=null===b?Object.create(b):(c.prototype=b.prototype,new c)},f=d(12);a=function(a){function c(){var b=a.call(this)||this;b._detachCallback=function(a){return b.remove(a)};return b}b(c,a);c.prototype.anchor=function(b){var c=this;b=f.coerceExternalD3(b);a.prototype.anchor.call(this,b);this._forEach(function(a){return a.anchor(c.element())});return this};\nc.prototype.render=function(){this._forEach(function(a){return a.render()});return this};c.prototype.has=function(){throw Error(\"has() is not implemented on ComponentContainer\");};c.prototype._adoptAndAnchor=function(a){a.parent(this);a.onDetach(this._detachCallback);this._isAnchored&&a.anchor(this.element())};c.prototype.remove=function(a){this.has(a)&&(a.offDetach(this._detachCallback),this._remove(a),a.detach(),this.redraw());return this};c.prototype._remove=function(){return!1};c.prototype._forEach=\nfunction(){throw Error(\"_forEach() is not implemented on ComponentContainer\");};c.prototype.destroy=function(){a.prototype.destroy.call(this);this._forEach(function(a){return a.destroy()})};c.prototype.invalidateCache=function(){this._forEach(function(a){return a.invalidateCache()})};return c}(d(4).Component);c.ComponentContainer=a},function(a,c,d){function b(a){l.add(a);k.add(a);m||(m=!0,q.render())}var f=d(0);a=d(9);var g=d(36),k=new f.Set,l=new f.Set,m=!1,n=!1;c.Policy=a.makeEnum([\"immediate\",\n\"animationFrame\",\"timeout\"]);var q=new g.AnimationFrame;c.renderPolicy=function(){var a=Plottable.RenderController.Policy.immediate;if(null!=a)switch(a){case c.Policy.immediate:q=new g.Immediate;break;case c.Policy.animationFrame:q=new g.AnimationFrame;break;case c.Policy.timeout:q=new g.Timeout;break;default:f.Window.warn(\"Unrecognized renderPolicy: \"+a)}};c.registerToRender=function(a){n&&f.Window.warn(\"Registered to render while other components are flushing: request may be ignored\");k.add(a);\nm||(m=!0,q.render())};c.registerToComputeLayoutAndRender=b;c.registerToComputeLayout=function(a){b(a)};c.flush=function(){if(m){l.forEach(function(a){return a.computeLayout()});k.forEach(function(a){return a.render()});n=!0;var a=new f.Set;k.forEach(function(b){try{b.renderImmediately()}catch(r){window.setTimeout(function(){throw r;},0),a.add(b)}});l=new f.Set;k=a;n=m=!1}}},function(a,c,d){var b=d(1);c.circle=function(){return function(a){return b.symbol().type(b.symbolCircle).size(Math.PI*Math.pow(a/\n2,2))}};c.square=function(){return function(a){return b.symbol().type(b.symbolSquare).size(Math.pow(a,2))}};c.cross=function(){return function(a){return b.symbol().type(b.symbolCross).size(5/9*Math.pow(a,2))}};c.diamond=function(){return function(a){return b.symbol().type(b.symbolDiamond).size(Math.tan(Math.PI/6)*Math.pow(a,2)/2)}};c.triangle=function(){return function(a){return b.symbol().type(b.symbolTriangle).size(Math.sqrt(3)*Math.pow(a/2,2))}};c.star=function(){return function(a){return b.symbol().type(b.symbolStar).size(.8908130915292852*\nMath.pow(a/2,2))}};var f=3*(1/Math.sqrt(12)/2+1);c.wye=function(){return function(a){return b.symbol().type(b.symbolWye).size(f*Math.pow(a/2.4,2))}}},function(a,c,d){var b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=null===b?Object.create(b):(c.prototype=b.prototype,new c)},f=d(14),g=d(0),k=d(12),l=d(35);a=function(a){function c(){var b=a.call(this)||this;b._detectionRadius=3;b._resizable=!1;b._movable=!1;b._hasCorners=\n!0;b.addClass(\"drag-box-layer\");b._dragInteraction=new f.Drag;b._setUpCallbacks();b._dragInteraction.attachTo(b);b._dragStartCallbacks=new g.CallbackSet;b._dragCallbacks=new g.CallbackSet;b._dragEndCallbacks=new g.CallbackSet;return b}b(c,a);c.prototype._setUpCallbacks=function(){function a(a,b){0===m&&a.x===b.x&&a.y===b.y&&d.boxVisible(!1);d._dragEndCallbacks.callCallbacks(d.bounds())}function b(a,b){switch(m){case 0:g.x=b.x;g.y=b.y;break;case 1:e.bottom?g.y=b.y:e.top&&(f.y=b.y);e.right?g.x=b.x:\ne.left&&(f.x=b.x);break;case 2:a=b.x-k.x;var c=b.y-k.y;f.x+=a;f.y+=c;g.x+=a;g.y+=c;k=b}d._setBounds({topLeft:f,bottomRight:g});d._xBoundsMode===l.PropertyMode.VALUE&&null!=d.xScale()&&d._setXExtent([d.xScale().invert(f.x),d.xScale().invert(g.x)]);d._yBoundsMode===l.PropertyMode.VALUE&&null!=d.yScale()&&d._setYExtent([d.yScale().invert(f.y),d.yScale().invert(g.y)]);d.render();d._dragCallbacks.callCallbacks(d.bounds())}function c(a){e=d._getResizingEdges(a);var b=d.bounds(),b=b.topLeft.x<=a.x&&a.x<=\nb.bottomRight.x&&b.topLeft.y<=a.y&&a.y<=b.bottomRight.y;d.boxVisible()&&(e.top||e.bottom||e.left||e.right)?m=1:d.boxVisible()&&d.movable()&&b?m=2:(m=0,d._setBounds({topLeft:a,bottomRight:a}),d._xBoundsMode===l.PropertyMode.VALUE&&null!=d.xScale()&&d._setXExtent([d.xScale().invert(a.x),d.xScale().invert(a.x)]),d._yBoundsMode===l.PropertyMode.VALUE&&null!=d.yScale()&&d._setYExtent([d.yScale().invert(a.y),d.yScale().invert(a.y)]),d.render());d.boxVisible(!0);b=d.bounds();f={x:b.topLeft.x,y:b.topLeft.y};\ng={x:b.bottomRight.x,y:b.bottomRight.y};k=a;d._dragStartCallbacks.callCallbacks(b)}var d=this,e,f,g,k,m=0;this._dragInteraction.onDragStart(c);this._dragInteraction.onDrag(b);this._dragInteraction.onDragEnd(a);this._disconnectInteraction=function(){d._dragInteraction.offDragStart(c);d._dragInteraction.offDrag(b);d._dragInteraction.offDragEnd(a);d._dragInteraction.detachFrom()}};c.prototype._setup=function(){function b(){return c._box.append(\"line\").styles({opacity:0,stroke:\"pink\",\"pointer-events\":\"visibleStroke\"})}\nvar c=this;a.prototype._setup.call(this);this._detectionEdgeT=b().classed(\"drag-edge-tb\",!0);this._detectionEdgeB=b().classed(\"drag-edge-tb\",!0);this._detectionEdgeL=b().classed(\"drag-edge-lr\",!0);this._detectionEdgeR=b().classed(\"drag-edge-lr\",!0);if(this._hasCorners){var d=function(){return c._box.append(\"circle\").styles({opacity:0,fill:\"pink\",\"pointer-events\":\"visibleFill\"})};this._detectionCornerTL=d().classed(\"drag-corner-tl\",!0);this._detectionCornerTR=d().classed(\"drag-corner-tr\",!0);this._detectionCornerBL=\nd().classed(\"drag-corner-bl\",!0);this._detectionCornerBR=d().classed(\"drag-corner-br\",!0)}};c.prototype._getResizingEdges=function(a){var b={top:!1,bottom:!1,left:!1,right:!1};if(!this.resizable())return b;var c=this.bounds(),d=c.topLeft.y,e=c.bottomRight.y,f=c.topLeft.x,c=c.bottomRight.x,g=this._detectionRadius;f-g<=a.x&&a.x<=c+g&&(b.top=d-g<=a.y&&a.y<=d+g,b.bottom=e-g<=a.y&&a.y<=e+g);d-g<=a.y&&a.y<=e+g&&(b.left=f-g<=a.x&&a.x<=f+g,b.right=c-g<=a.x&&a.x<=c+g);return b};c.prototype.renderImmediately=\nfunction(){a.prototype.renderImmediately.call(this);if(this.boxVisible()){var b=this.bounds(),c=b.topLeft.y,d=b.bottomRight.y,e=b.topLeft.x,b=b.bottomRight.x;this._detectionEdgeT.attrs({x1:e,y1:c,x2:b,y2:c,\"stroke-width\":2*this._detectionRadius});this._detectionEdgeB.attrs({x1:e,y1:d,x2:b,y2:d,\"stroke-width\":2*this._detectionRadius});this._detectionEdgeL.attrs({x1:e,y1:c,x2:e,y2:d,\"stroke-width\":2*this._detectionRadius});this._detectionEdgeR.attrs({x1:b,y1:c,x2:b,y2:d,\"stroke-width\":2*this._detectionRadius});\nthis._hasCorners&&(this._detectionCornerTL.attrs({cx:e,cy:c,r:this._detectionRadius}),this._detectionCornerTR.attrs({cx:b,cy:c,r:this._detectionRadius}),this._detectionCornerBL.attrs({cx:e,cy:d,r:this._detectionRadius}),this._detectionCornerBR.attrs({cx:b,cy:d,r:this._detectionRadius}))}return this};c.prototype.detectionRadius=function(a){if(null==a)return this._detectionRadius;if(0>a)throw Error(\"detection radius cannot be negative.\");this._detectionRadius=a;this.render();return this};c.prototype.resizable=\nfunction(){return this._resizable};c.prototype._setResizableClasses=function(a){a&&this.enabled()?(this.addClass(\"x-resizable\"),this.addClass(\"y-resizable\")):(this.removeClass(\"x-resizable\"),this.removeClass(\"y-resizable\"))};c.prototype.movable=function(){return this._movable};c.prototype._setMovableClass=function(){this.movable()&&this.enabled()?this.addClass(\"movable\"):this.removeClass(\"movable\")};c.prototype.onDragStart=function(a){this._dragStartCallbacks.add(a);return this};c.prototype.offDragStart=\nfunction(a){this._dragStartCallbacks.delete(a);return this};c.prototype.onDrag=function(a){this._dragCallbacks.add(a);return this};c.prototype.offDrag=function(a){this._dragCallbacks.delete(a);return this};c.prototype.onDragEnd=function(a){this._dragEndCallbacks.add(a);return this};c.prototype.offDragEnd=function(a){this._dragEndCallbacks.delete(a);return this};c.prototype.dragInteraction=function(){return this._dragInteraction};c.prototype.enabled=function(a){if(null==a)return this._dragInteraction.enabled();\nthis._dragInteraction.enabled(a);this._setResizableClasses(this.resizable());this._setMovableClass();return this};c.prototype.destroy=function(){var b=this;a.prototype.destroy.call(this);this._dragStartCallbacks.forEach(function(a){return b._dragCallbacks.delete(a)});this._dragCallbacks.forEach(function(a){return b._dragCallbacks.delete(a)});this._dragEndCallbacks.forEach(function(a){return b._dragEndCallbacks.delete(a)});this._disconnectInteraction()};c.prototype.detach=function(){this._resetState();\nthis._dragInteraction.detachFrom();a.prototype.detach.call(this);return this};c.prototype.anchor=function(b){b=k.coerceExternalD3(b);this._dragInteraction.attachTo(this);a.prototype.anchor.call(this,b);return this};c.prototype._resetState=function(){this.bounds({topLeft:{x:0,y:0},bottomRight:{x:0,y:0}})};return c}(d(40).SelectionBoxLayer);c.DragBoxLayer=a},function(a,c,d){var b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=\nnull===b?Object.create(b):(c.prototype=b.prototype,new c)},f=d(19);a=function(a){function c(){return a.call(this,\"path\",\"line\")||this}b(c,a);c.prototype._applyDefaultAttributes=function(a){a.style(\"fill\",\"none\")};c.prototype.getVisualPrimitiveAtIndex=function(){return a.prototype.getVisualPrimitiveAtIndex.call(this,0)};return c}(d(8).SVGDrawer);c.LineSVGDrawer=a;c.makeLineCanvasDrawStep=function(a){return function(b,c,d){var e=a();d=f.resolveAttributesSubsetWithStyles(d,[],c[0],0);b.save();b.beginPath();\ne.context(b);e(c[0]);b.lineJoin=\"round\";f.styleContext(b,d);b.restore()}}},function(a,c,d){var b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=null===b?Object.create(b):(c.prototype=b.prototype,new c)},f=d(19);a=function(a){function c(b){void 0===b&&(b=\"\");var c=a.call(this,\"rect\",\"\")||this;c._rootClassName=b;c._root.classed(c._rootClassName,!0);return c}b(c,a);return c}(d(8).SVGDrawer);c.RectangleSVGDrawer=a;c.RectangleCanvasDrawStep=\nfunction(a,b,c){a.save();b.forEach(function(b,d){b=f.resolveAttributesSubsetWithStyles(c,[\"x\",\"y\",\"width\",\"height\"],b,d);a.beginPath();a.rect(b.x,b.y,b.width,b.height);f.styleContext(a,b)});a.restore()}},function(a,c,d){var b=d(1),f=Math;c.inRange=function(a,b,c){return f.min(b,c)<=a&&a<=f.max(b,c)};c.clamp=function(a,b,c){return f.min(f.max(b,a),c)};c.max=function(a,c,d){var e=\"function\"===typeof c?c:null;c=null==e?c:d;a=null==e?b.max(a):b.max(a,e);return void 0!==a?a:c};c.min=function(a,c,d){var e=\n\"function\"===typeof c?c:null;c=null==e?c:d;a=null==e?b.min(a):b.min(a,e);return void 0!==a?a:c};c.isNaN=function(a){return a!==a};c.isValidNumber=function(a){return\"number\"===typeof a&&1>a-a};c.range=function(a,b,c){void 0===c&&(c=1);if(0===c)throw Error(\"step cannot be 0\");b=f.max(f.ceil((b-a)/c),0);for(var d=[],e=0;e<b;++e)d[e]=a+c*e;return d};c.distanceSquared=function(a,b){return f.pow(b.y-a.y,2)+f.pow(b.x-a.x,2)};c.degreesToRadians=function(a){return a/360*f.PI*2};c.within=function(a,b){return b.topLeft.x<=\na.x&&b.bottomRight.x>=a.x&&b.topLeft.y<=a.y&&b.bottomRight.y>=a.y}},function(a,c){a=function(){function a(a){this.ruler=null!=a.createRuler?a.createRuler():a}a.prototype.measure=function(b){void 0===b&&(b=a.HEIGHT_TEXT);return this.ruler(b)};return a}();a.HEIGHT_TEXT=\"bdpql\";c.AbstractMeasurer=a},function(a,c,d){function b(a){for(var b in a)c.hasOwnProperty(b)||(c[b]=a[b])}b(d(30));b(d(68));b(d(69));b(d(38));b(d(39));b(d(70));b(d(71));b(d(72));b(d(73));b(d(40));b(d(74));b(d(75));b(d(76))},function(a,\nc,d){var b=d(0),f=d(28);a=function(){function a(){}a.prototype.render=function(){f.flush()};return a}();c.Immediate=a;a=function(){function a(){}a.prototype.render=function(){b.DOM.requestAnimationFramePolyfill(f.flush)};return a}();c.AnimationFrame=a;a=function(){function a(){this._timeoutMsec=b.DOM.SCREEN_REFRESH_RATE_MILLISECONDS}a.prototype.render=function(){setTimeout(f.flush,this._timeoutMsec)};return a}();c.Timeout=a},function(a,c,d){var b=this&&this.__extends||function(a,b){function c(){this.constructor=\na}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=null===b?Object.create(b):(c.prototype=b.prototype,new c)},f=d(13),g=d(0);a=function(a){function c(){var b=null!==a&&a.apply(this,arguments)||this;b._keyPressCallbacks={};b._keyReleaseCallbacks={};b._mouseMoveCallback=function(){return!1};b._downedKeys=new g.Set;b._keyDownCallback=function(a,c){return b._handleKeyDownEvent(a,c)};b._keyUpCallback=function(a){return b._handleKeyUpEvent(a)};return b}b(c,a);c.prototype._anchor=function(b){a.prototype._anchor.call(this,\nb);this._positionDispatcher=f.Mouse.getDispatcher(this._componentAttachedTo);this._positionDispatcher.onMouseMove(this._mouseMoveCallback);this._keyDispatcher=f.Key.getDispatcher();this._keyDispatcher.onKeyDown(this._keyDownCallback);this._keyDispatcher.onKeyUp(this._keyUpCallback)};c.prototype._unanchor=function(){a.prototype._unanchor.call(this);this._positionDispatcher.offMouseMove(this._mouseMoveCallback);this._positionDispatcher=null;this._keyDispatcher.offKeyDown(this._keyDownCallback);this._keyDispatcher.offKeyUp(this._keyUpCallback);\nthis._keyDispatcher=null};c.prototype._handleKeyDownEvent=function(a,b){var c=this._translateToComponentSpace(this._positionDispatcher.lastMousePosition());this._isInsideComponent(c)&&!b.repeat&&(this._keyPressCallbacks[a]&&this._keyPressCallbacks[a].callCallbacks(a),this._downedKeys.add(a))};c.prototype._handleKeyUpEvent=function(a){this._downedKeys.has(a)&&this._keyReleaseCallbacks[a]&&this._keyReleaseCallbacks[a].callCallbacks(a);this._downedKeys.delete(a)};c.prototype.onKeyPress=function(a,b){this._keyPressCallbacks[a]||\n(this._keyPressCallbacks[a]=new g.CallbackSet);this._keyPressCallbacks[a].add(b);return this};c.prototype.offKeyPress=function(a,b){this._keyPressCallbacks[a].delete(b);0===this._keyPressCallbacks[a].size&&delete this._keyPressCallbacks[a];return this};c.prototype.onKeyRelease=function(a,b){this._keyReleaseCallbacks[a]||(this._keyReleaseCallbacks[a]=new g.CallbackSet);this._keyReleaseCallbacks[a].add(b);return this};c.prototype.offKeyRelease=function(a,b){this._keyReleaseCallbacks[a].delete(b);0===\nthis._keyReleaseCallbacks[a].size&&delete this._keyReleaseCallbacks[a];return this};return c}(d(15).Interaction);c.Key=a},function(a,c,d){var b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=null===b?Object.create(b):(c.prototype=b.prototype,new c)},f=d(0);a=function(a){function c(b){void 0===b&&(b=[]);var c=a.call(this)||this;c._components=[];c.addClass(\"component-group\");b.forEach(function(a){return c.append(a)});return c}\nb(c,a);c.prototype._forEach=function(a){this.components().forEach(a)};c.prototype.has=function(a){return 0<=this._components.indexOf(a)};c.prototype.requestedSpace=function(a,b){var c=this._components.map(function(c){return c.requestedSpace(a,b)});return{minWidth:f.Math.max(c,function(a){return a.minWidth},0),minHeight:f.Math.max(c,function(a){return a.minHeight},0)}};c.prototype.computeLayout=function(b,c,d){var e=this;a.prototype.computeLayout.call(this,b,c,d);this._forEach(function(a){a.computeLayout({x:0,\ny:0},e.width(),e.height())});return this};c.prototype._sizeFromOffer=function(a,b){return{width:a,height:b}};c.prototype.fixedWidth=function(){return this._components.every(function(a){return a.fixedWidth()})};c.prototype.fixedHeight=function(){return this._components.every(function(a){return a.fixedHeight()})};c.prototype.components=function(){return this._components.slice()};c.prototype.append=function(a){null==a||this.has(a)||(a.detach(),this._components.push(a),this._adoptAndAnchor(a),this.redraw());\nreturn this};c.prototype._remove=function(a){a=this._components.indexOf(a);return 0<=a?(this._components.splice(a,1),!0):!1};return c}(d(27).ComponentContainer);c.Group=a},function(a,c,d){var b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=null===b?Object.create(b):(c.prototype=b.prototype,new c)};d(0);a=d(4);var f;(function(a){a[a.VALUE=0]=\"VALUE\";a[a.PIXEL=1]=\"PIXEL\"})(f||(f={}));a=function(a){function c(b){var d=\na.call(this)||this;d._mode=f.VALUE;if(b!==c.ORIENTATION_VERTICAL&&b!==c.ORIENTATION_HORIZONTAL)throw Error(b+\" is not a valid orientation for GuideLineLayer\");d._orientation=b;d._overflowHidden=!0;d.addClass(\"guide-line-layer\");d._isVertical()?d.addClass(\"vertical\"):d.addClass(\"horizontal\");d._scaleUpdateCallback=function(){d._syncPixelPositionAndValue();d.render()};return d}b(c,a);c.prototype._setup=function(){a.prototype._setup.call(this);this._guideLine=this.content().append(\"line\").classed(\"guide-line\",\n!0)};c.prototype._sizeFromOffer=function(a,b){return{width:a,height:b}};c.prototype._isVertical=function(){return this._orientation===c.ORIENTATION_VERTICAL};c.prototype.fixedWidth=function(){return!0};c.prototype.fixedHeight=function(){return!0};c.prototype.computeLayout=function(b,c,d){a.prototype.computeLayout.call(this,b,c,d);null!=this.scale()&&(this._isVertical()?this.scale().range([0,this.width()]):this.scale().range([this.height(),0]));return this};c.prototype.renderImmediately=function(){a.prototype.renderImmediately.call(this);\nthis._syncPixelPositionAndValue();this._guideLine.attrs({x1:this._isVertical()?this.pixelPosition():0,y1:this._isVertical()?0:this.pixelPosition(),x2:this._isVertical()?this.pixelPosition():this.width(),y2:this._isVertical()?this.height():this.pixelPosition()});return this};c.prototype._syncPixelPositionAndValue=function(){null!=this.scale()&&(this._mode===f.VALUE&&null!=this.value()?this._pixelPosition=this.scale().scale(this.value()):this._mode===f.PIXEL&&null!=this.pixelPosition()&&(this._value=\nthis.scale().invert(this.pixelPosition())))};c.prototype._setPixelPositionWithoutChangingMode=function(a){this._pixelPosition=a;null!=this.scale()&&(this._value=this.scale().invert(this.pixelPosition()));this.render()};c.prototype.scale=function(a){if(null==a)return this._scale;var b=this._scale;null!=b&&b.offUpdate(this._scaleUpdateCallback);this._scale=a;this._scale.onUpdate(this._scaleUpdateCallback);this._syncPixelPositionAndValue();this.redraw();return this};c.prototype.value=function(a){if(null==\na)return this._value;this._value=a;this._mode=f.VALUE;this._syncPixelPositionAndValue();this.render();return this};c.prototype.pixelPosition=function(){return this._pixelPosition};c.prototype.destroy=function(){a.prototype.destroy.call(this);null!=this.scale()&&this.scale().offUpdate(this._scaleUpdateCallback)};return c}(a.Component);a.ORIENTATION_VERTICAL=\"vertical\";a.ORIENTATION_HORIZONTAL=\"horizontal\";c.GuideLineLayer=a},function(a,c,d){var b=this&&this.__extends||function(a,b){function c(){this.constructor=\na}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=null===b?Object.create(b):(c.prototype=b.prototype,new c)},f=d(0);a=d(4);var g;(function(a){a[a.VALUE=0]=\"VALUE\";a[a.PIXEL=1]=\"PIXEL\"})(g=c.PropertyMode||(c.PropertyMode={}));a=function(a){function c(){var b=a.call(this)||this;b._boxVisible=!1;b._boxBounds={topLeft:{x:0,y:0},bottomRight:{x:0,y:0}};b._xBoundsMode=g.PIXEL;b._yBoundsMode=g.PIXEL;b.addClass(\"selection-box-layer\");b._adjustBoundsCallback=function(){b.render()};b._overflowHidden=\n!0;b._xExtent=[void 0,void 0];b._yExtent=[void 0,void 0];return b}b(c,a);c.prototype._setup=function(){a.prototype._setup.call(this);this._box=this.content().append(\"g\").classed(\"selection-box\",!0).remove();this._boxArea=this._box.append(\"rect\").classed(\"selection-area\",!0)};c.prototype._sizeFromOffer=function(a,b){return{width:a,height:b}};c.prototype.bounds=function(a){if(null==a)return this._getBounds();this._setBounds(a);this._yBoundsMode=this._xBoundsMode=g.PIXEL;this.render();return this};c.prototype._setBounds=\nfunction(a){this._boxBounds={topLeft:{x:Math.min(a.topLeft.x,a.bottomRight.x),y:Math.min(a.topLeft.y,a.bottomRight.y)},bottomRight:{x:Math.max(a.topLeft.x,a.bottomRight.x),y:Math.max(a.topLeft.y,a.bottomRight.y)}}};c.prototype._getBounds=function(){return{topLeft:{x:this._xBoundsMode===g.PIXEL?this._boxBounds.topLeft.x:null==this._xScale?0:Math.min(this.xScale().scale(this.xExtent()[0]),this.xScale().scale(this.xExtent()[1])),y:this._yBoundsMode===g.PIXEL?this._boxBounds.topLeft.y:null==this._yScale?\n0:Math.min(this.yScale().scale(this.yExtent()[0]),this.yScale().scale(this.yExtent()[1]))},bottomRight:{x:this._xBoundsMode===g.PIXEL?this._boxBounds.bottomRight.x:null==this._xScale?0:Math.max(this.xScale().scale(this.xExtent()[0]),this.xScale().scale(this.xExtent()[1])),y:this._yBoundsMode===g.PIXEL?this._boxBounds.bottomRight.y:null==this._yScale?0:Math.max(this.yScale().scale(this.yExtent()[0]),this.yScale().scale(this.yExtent()[1]))}}};c.prototype.renderImmediately=function(){a.prototype.renderImmediately.call(this);\nif(this._boxVisible){var b=this.bounds(),c=b.topLeft.y,d=b.bottomRight.y,e=b.topLeft.x,b=b.bottomRight.x;if(!(f.Math.isValidNumber(c)&&f.Math.isValidNumber(d)&&f.Math.isValidNumber(e)&&f.Math.isValidNumber(b)))throw Error(\"bounds have not been properly set\");this._boxArea.attrs({x:e,y:c,width:b-e,height:d-c});this.content().node().appendChild(this._box.node())}else this._box.remove();return this};c.prototype.boxVisible=function(a){if(null==a)return this._boxVisible;this._boxVisible=a;this.render();\nreturn this};c.prototype.fixedWidth=function(){return!0};c.prototype.fixedHeight=function(){return!0};c.prototype.xScale=function(a){if(null==a)return this._xScale;null!=this._xScale&&this._xScale.offUpdate(this._adjustBoundsCallback);this._xScale=a;this._xBoundsMode=g.VALUE;this._xScale.onUpdate(this._adjustBoundsCallback);this.render();return this};c.prototype.yScale=function(a){if(null==a)return this._yScale;null!=this._yScale&&this._yScale.offUpdate(this._adjustBoundsCallback);this._yScale=a;\nthis._yBoundsMode=g.VALUE;this._yScale.onUpdate(this._adjustBoundsCallback);this.render();return this};c.prototype.xExtent=function(a){if(null==a)return this._getXExtent();this._setXExtent(a);this._xBoundsMode=g.VALUE;this.render();return this};c.prototype._getXExtent=function(){return this._xBoundsMode===g.VALUE?this._xExtent:null==this._xScale?[void 0,void 0]:[this._xScale.invert(this._boxBounds.topLeft.x),this._xScale.invert(this._boxBounds.bottomRight.x)]};c.prototype._setXExtent=function(a){this._xExtent=\na};c.prototype.yExtent=function(a){if(null==a)return this._getYExtent();this._setYExtent(a);this._yBoundsMode=g.VALUE;this.render();return this};c.prototype._getYExtent=function(){return this._yBoundsMode===g.VALUE?this._yExtent:null==this._yScale?[void 0,void 0]:[this._yScale.invert(this._boxBounds.topLeft.y),this._yScale.invert(this._boxBounds.bottomRight.y)]};c.prototype._setYExtent=function(a){this._yExtent=a};c.prototype.destroy=function(){a.prototype.destroy.call(this);null!=this._xScale&&this.xScale().offUpdate(this._adjustBoundsCallback);\nnull!=this._yScale&&this.yScale().offUpdate(this._adjustBoundsCallback)};return c}(a.Component);c.SelectionBoxLayer=a},function(a,c,d){var b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=null===b?Object.create(b):(c.prototype=b.prototype,new c)};a=function(a){function c(){return a.call(this,\"path\",\"arc fill\")||this}b(c,a);c.prototype._applyDefaultAttributes=function(a){a.style(\"stroke\",\"none\")};return c}(d(8).SVGDrawer);\nc.ArcSVGDrawer=a},function(a,c,d){var b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=null===b?Object.create(b):(c.prototype=b.prototype,new c)};a=function(a){function c(){return a.call(this,\"path\",\"arc outline\")||this}b(c,a);c.prototype._applyDefaultAttributes=function(a){a.style(\"fill\",\"none\")};return c}(d(8).SVGDrawer);c.ArcOutlineSVGDrawer=a},function(a,c,d){var b=this&&this.__extends||function(a,b){function c(){this.constructor=\na}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=null===b?Object.create(b):(c.prototype=b.prototype,new c)};a=function(a){function c(){return a.call(this,\"path\",\"area\")||this}b(c,a);c.prototype._applyDefaultAttributes=function(a){a.style(\"stroke\",\"none\")};c.prototype.getVisualPrimitiveAtIndex=function(){return a.prototype.getVisualPrimitiveAtIndex.call(this,0)};return c}(d(8).SVGDrawer);c.AreaSVGDrawer=a},function(a,c,d){var b=this&&this.__extends||function(a,b){function c(){this.constructor=\na}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=null===b?Object.create(b):(c.prototype=b.prototype,new c)};a=function(a){function c(){return a.call(this,\"line\",\"\")||this}b(c,a);return c}(d(8).SVGDrawer);c.SegmentSVGDrawer=a},function(a,c,d){var b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=null===b?Object.create(b):(c.prototype=b.prototype,new c)},f=d(80),g=d(19);a=function(a){function c(){return a.call(this,\n\"path\",\"symbol\")||this}b(c,a);return c}(d(8).SVGDrawer);c.SymbolSVGDrawer=a;c.makeSymbolCanvasDrawStep=function(a,b,c){var d=this;return function(e,k,l){for(var m=e.canvas,n=m.width,m=m.height,q=new f.CanvasBuffer(0,0),p=b(),t=c(),B=null,A=null,D=null,E=0;E<k.length;E++){var F=k[E],I=g.resolveAttributesSubsetWithStyles(l,[\"x\",\"y\"],F,E),H=t(F,E,a),C=I.x,J=I.y;if(0<=C+H&&C-H<=n&&0<=J+H&&J-H<=m){a:if(C=Object.keys(g.ContextStyleAttrs),null==B)C=!1;else{for(J=0;J<C.length;J++){var M=C[J];if(B[M]!=I[M]){C=\n!1;break a}}C=!0}F=p(F,E,d._dataset);C&&D==H&&A==F||((H>q.screenWidth||H>q.screenHeight)&&q.resize(H,H,!0),q.clear(),B=q.ctx,B.beginPath(),F(H).context(B)(null),B.closePath(),g.styleContext(B,I),A=F,D=H,B=I);q.blitCenter(e,I.x,I.y)}}}}},function(a,c,d){var b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=null===b?Object.create(b):(c.prototype=b.prototype,new c)},f=d(1),g=d(3),k=d(0),l=d(43),m=d(6),n=d(31),q=d(25),p=d(17);\na=d(48);var t=d(2);d=function(a){function c(){var b=a.call(this)||this;b.addClass(\"area-plot\");b.y0(0);b.attr(\"fill-opacity\",.25);b.attr(\"fill\",(new g.Color).range()[0]);b._lineDrawers=new k.Map;return b}b(c,a);c.prototype._setup=function(){var b=this;a.prototype._setup.call(this);this._lineDrawers.forEach(function(a){return a.attachTo(b._renderArea)})};c.prototype.y=function(b,d){if(null==b)return a.prototype.y.call(this);null==d?a.prototype.y.call(this,b):a.prototype.y.call(this,b,d);null!=d&&(b=\nthis.y0().accessor,null!=b&&this._bindProperty(c._Y0_KEY,b,d),this._updateYScale());return this};c.prototype.y0=function(a){if(null==a)return this._propertyBindings.get(c._Y0_KEY);var b=this.y();this._bindProperty(c._Y0_KEY,a,b&&b.scale);this._updateYScale();this.render();return this};c.prototype._onDatasetUpdate=function(){a.prototype._onDatasetUpdate.call(this);this._updateYScale()};c.prototype.addDataset=function(b){a.prototype.addDataset.call(this,b);return this};c.prototype._addDataset=function(b){var c=\nnew n.LineSVGDrawer;this._isSetup&&c.attachTo(this._renderArea);this._lineDrawers.set(b,c);a.prototype._addDataset.call(this,b);return this};c.prototype._removeDatasetNodes=function(b){a.prototype._removeDatasetNodes.call(this,b);this._lineDrawers.get(b).remove()};c.prototype._additionalPaint=function(){var a=this,b=this._generateLineDrawSteps(),c=this._getDataToDraw();this.datasets().forEach(function(d){var e=t.Plot.applyDrawSteps(b,d);a._lineDrawers.get(d).draw(c.get(d),e)})};c.prototype._generateLineDrawSteps=\nfunction(){var a=[];if(this._animateOnNextRender()){var b=this._generateLineAttrToProjector();b.d=this._constructLineProjector(t.Plot._scaledAccessor(this.x()),this._getResetYFunction());a.push({attrToProjector:b,animator:this._getAnimator(p.Animator.RESET)})}a.push({attrToProjector:this._generateLineAttrToProjector(),animator:this._getAnimator(p.Animator.MAIN)});return a};c.prototype._generateLineAttrToProjector=function(){var a=this._generateAttrToProjector();a.d=this._constructLineProjector(t.Plot._scaledAccessor(this.x()),\nt.Plot._scaledAccessor(this.y()));return a};c.prototype._createDrawer=function(){return new m.ProxyDrawer(function(){return new l.AreaSVGDrawer},function(){q.warn(\"canvas renderer not implemented on Area Plot!\")})};c.prototype._generateDrawSteps=function(){var a=[];if(this._animateOnNextRender()){var b=this._generateAttrToProjector();b.d=this._constructAreaProjector(t.Plot._scaledAccessor(this.x()),this._getResetYFunction(),t.Plot._scaledAccessor(this.y0()));a.push({attrToProjector:b,animator:this._getAnimator(p.Animator.RESET)})}a.push({attrToProjector:this._generateAttrToProjector(),\nanimator:this._getAnimator(p.Animator.MAIN)});return a};c.prototype._updateYScale=function(){var a=this._propertyExtents.get(\"y0\"),a=k.Array.flatten(a),a=k.Array.uniq(a),b=1===a.length?a[0]:null,a=(a=this.y())&&a.scale;null!=a&&(null!=this._constantBaselineValueProvider&&(a.removePaddingExceptionsProvider(this._constantBaselineValueProvider),this._constantBaselineValueProvider=null),null!=b&&(this._constantBaselineValueProvider=function(){return[b]},a.addPaddingExceptionsProvider(this._constantBaselineValueProvider)))};\nc.prototype._getResetYFunction=function(){return t.Plot._scaledAccessor(this.y0())};c.prototype._propertyProjectors=function(){var b=a.prototype._propertyProjectors.call(this);b.d=this._constructAreaProjector(t.Plot._scaledAccessor(this.x()),t.Plot._scaledAccessor(this.y()),t.Plot._scaledAccessor(this.y0()));return b};c.prototype.selections=function(b){var c=this;void 0===b&&(b=this.datasets());var d=a.prototype.selections.call(this,b).nodes();b.map(function(a){return c._lineDrawers.get(a)}).filter(function(a){return null!=\na}).forEach(function(a){return d.push.apply(d,a.getVisualPrimitives())});return f.selectAll(d)};c.prototype._constructAreaProjector=function(a,b,c){var d=this;return function(e,g,l){g=d._getCurveFactory();return f.area().x(function(b,c){return a(b,c,l)}).y1(function(a,c){return b(a,c,l)}).y0(function(a,b){return c(a,b,l)}).curve(g).defined(function(a,b){var c=t.Plot._scaledAccessor(d.x())(a,b,l);a=t.Plot._scaledAccessor(d.y())(a,b,l);return k.Math.isValidNumber(c)&&k.Math.isValidNumber(a)})(e)}};\nreturn c}(a.Line);d._Y0_KEY=\"y0\";c.Area=d},function(a,c){a=c.Animator||(c.Animator={});a.MAIN=\"main\";a.RESET=\"reset\"},function(a,c,d){var b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=null===b?Object.create(b):(c.prototype=b.prototype,new c)},f=d(1),g=d(7),k=d(6),l=d(31),m=d(3),n=d(11),q=d(0);a=d(9);var p=d(17),t=d(2);d=d(16);var r={linear:f.curveLinear,linearClosed:f.curveLinearClosed,step:f.curveStep,stepBefore:f.curveStepBefore,\nstepAfter:f.curveStepAfter,basis:f.curveBasis,basisOpen:f.curveBasisOpen,basisClosed:f.curveBasisClosed,bundle:f.curveBundle,cardinal:f.curveCardinal,cardinalOpen:f.curveCardinalOpen,cardinalClosed:f.curveCardinalClosed,monotone:f.curveMonotoneX};c.CurveName=a.makeEnum(\"linear linearClosed step stepBefore stepAfter basis basisOpen basisClosed bundle cardinal cardinalOpen cardinalClosed monotone\".split(\" \"));d=function(a){function c(){var b=a.call(this)||this;b._curve=\"linear\";b._autorangeSmooth=!1;\nb._croppedRenderingEnabled=!0;b._collapseDenseVerticalLinesEnabled=!1;b._downsamplingEnabled=!1;b.addClass(\"line-plot\");var c=new g.Easing;c.stepDuration(t.Plot._ANIMATION_MAX_DURATION);c.easingMode(\"expInOut\");c.maxTotalDuration(t.Plot._ANIMATION_MAX_DURATION);b.animator(p.Animator.MAIN,c);b.attr(\"stroke\",(new m.Color).range()[0]);b.attr(\"stroke-width\",\"2px\");return b}b(c,a);c.prototype.x=function(b,c){if(null==b)return a.prototype.x.call(this);null==c?a.prototype.x.call(this,b):a.prototype.x.call(this,\nb,c);this._setScaleSnapping();return this};c.prototype.y=function(b,c){if(null==b)return a.prototype.y.call(this);a.prototype.y.call(this,b,c);this._setScaleSnapping();return this};c.prototype.autorangeMode=function(b){if(null==b)return a.prototype.autorangeMode.call(this);a.prototype.autorangeMode.call(this,b);this._setScaleSnapping();return this};c.prototype.autorangeSmooth=function(){return this._autorangeSmooth};c.prototype._setScaleSnapping=function(){\"x\"===this.autorangeMode()&&this.x()&&this.x().scale&&\nthis.x().scale instanceof n.QuantitativeScale&&this.x().scale.snappingDomainEnabled(!this.autorangeSmooth());\"y\"===this.autorangeMode()&&this.y()&&this.y().scale&&this.y().scale instanceof n.QuantitativeScale&&this.y().scale.snappingDomainEnabled(!this.autorangeSmooth())};c.prototype.curve=function(a){if(null==a)return this._curve;this._curve=a;this.render();return this};c.prototype.downsamplingEnabled=function(a){if(null==a)return this._downsamplingEnabled;this._downsamplingEnabled=a;return this};\nc.prototype.croppedRenderingEnabled=function(a){if(null==a)return this._croppedRenderingEnabled;this._croppedRenderingEnabled=a;this.render();return this};c.prototype.collapseDenseLinesEnabled=function(a){if(null==a)return this._collapseDenseVerticalLinesEnabled;this._collapseDenseVerticalLinesEnabled=a;this.render();return this};c.prototype._createDrawer=function(a){var b=this;return new k.ProxyDrawer(function(){return new l.LineSVGDrawer},l.makeLineCanvasDrawStep(function(){return b._d3LineFactory(a)}))};\nc.prototype._extentsForProperty=function(b){var c=a.prototype._extentsForProperty.call(this,b);if(!this._autorangeSmooth||this.autorangeMode()!==b||\"x\"!==this.autorangeMode()&&\"y\"!==this.autorangeMode())return c;b=this._getEdgeIntersectionPoints();var d=\"y\"===this.autorangeMode()?b.left.concat(b.right).map(function(a){return a.y}):b.top.concat(b.bottom).map(function(a){return a.x});return c.map(function(a){return f.extent(f.merge([a,d]))})};c.prototype._getEdgeIntersectionPoints=function(){var a=\nthis;if(!(this.y().scale instanceof n.QuantitativeScale&&this.x().scale instanceof n.QuantitativeScale))return{left:[],right:[],top:[],bottom:[]};var b=this.y().scale,c=this.x().scale,d={left:[],right:[],top:[],bottom:[]},e=c.scale(c.domain()[0]),f=c.scale(c.domain()[1]),g=b.scale(b.domain()[0]),k=b.scale(b.domain()[1]);this.datasets().forEach(function(l){for(var m=l.data(),n,q,p,r,t,v,w,y=1;y<m.length;y++)r=v||c.scale(a.x().accessor(m[y-1],y-1,l)),t=w||b.scale(a.y().accessor(m[y-1],y-1,l)),v=c.scale(a.x().accessor(m[y],\ny,l)),w=b.scale(a.y().accessor(m[y],y,l)),r<e===e<=v&&(n=e-r,q=v-r,p=w-t,n=n*p/q,d.left.push({x:e,y:b.invert(t+n)})),r<f===f<=v&&(n=f-r,q=v-r,p=w-t,n=n*p/q,d.right.push({x:f,y:b.invert(t+n)})),t<k===k<=w&&(q=v-r,n=k-t,p=w-t,n=n*q/p,d.top.push({x:c.invert(r+n),y:k})),t<g===g<=w&&(q=v-r,n=g-t,p=w-t,n=n*q/p,d.bottom.push({x:c.invert(r+n),y:g}))});return d};c.prototype._getResetYFunction=function(){var a=this.y().scale.domain(),b=Math.max(a[0],a[1]),a=Math.min(a[0],a[1]),b=0>b&&b||0<a&&a||0,c=this.y().scale.scale(b);\nreturn function(){return c}};c.prototype._generateDrawSteps=function(){var a=[];if(this._animateOnNextRender()){var b=this._generateAttrToProjector();b.d=this._constructLineProjector(t.Plot._scaledAccessor(this.x()),this._getResetYFunction());a.push({attrToProjector:b,animator:this._getAnimator(p.Animator.RESET)})}a.push({attrToProjector:this._generateAttrToProjector(),animator:this._getAnimator(p.Animator.MAIN)});return a};c.prototype._generateAttrToProjector=function(){var b=a.prototype._generateAttrToProjector.call(this);\nObject.keys(b).forEach(function(a){if(\"d\"!==a){var c=b[a];b[a]=function(a,b,d){return 0<a.length?c(a[0],b,d):null}}});return b};c.prototype.entitiesAt=function(a){a=this.entityNearestByXThenY(a);return null!=a?[a]:[]};c.prototype.entitiesIn=function(a,b){if(null==b){var c={min:a.topLeft.x,max:a.bottomRight.x};var d={min:a.topLeft.y,max:a.bottomRight.y}}else c=a,d=b;var e=t.Plot._scaledAccessor(this.x()),f=t.Plot._scaledAccessor(this.y());return this.entities().filter(function(a){var b=a.datum,g=a.index,\nk=a.dataset;a=e(b,g,k);b=f(b,g,k);return c.min<=a&&a<=c.max&&d.min<=b&&b<=d.max})};c.prototype.entityNearestByXThenY=function(a){var b=Infinity,c=Infinity,d,e=this.bounds();this.entities().forEach(function(f){if(q.Math.within(f.position,e)){var g=Math.abs(a.x-f.position.x),k=Math.abs(a.y-f.position.y);if(g<b||g===b&&k<c)d=f,b=g,c=k}});return d};c.prototype._propertyProjectors=function(){var b=a.prototype._propertyProjectors.call(this);b.d=this._constructLineProjector(t.Plot._scaledAccessor(this.x()),\nt.Plot._scaledAccessor(this.y()));return b};c.prototype._constructLineProjector=function(a,b){var c=this;return function(d,e,f){return c._d3LineFactory(f,a,b)(d)}};c.prototype._d3LineFactory=function(a,b,c){void 0===b&&(b=t.Plot._scaledAccessor(this.x()));void 0===c&&(c=t.Plot._scaledAccessor(this.y()));return f.line().x(function(c,d){return b(c,d,a)}).y(function(b,d){return c(b,d,a)}).curve(this._getCurveFactory()).defined(function(d,e){var f=b(d,e,a);d=c(d,e,a);return q.Math.isValidNumber(f)&&q.Math.isValidNumber(d)})};\nc.prototype._getCurveFactory=function(){var a=this.curve();return\"string\"===typeof a?(a=r[a],null==a?r.linear:a):a};c.prototype._getDataToDraw=function(){var a=this,b=new q.Map;this.datasets().forEach(function(c){var d=c.data();if(a._croppedRenderingEnabled||a._downsamplingEnabled){var e=d.map(function(a,b){return b});a._croppedRenderingEnabled&&(e=a._filterCroppedRendering(c,e));a._downsamplingEnabled&&(e=a._filterDownsampling(c,e));a._collapseDenseVerticalLinesEnabled&&(e=a._filterDenseLines(c,\ne));b.set(c,[e.map(function(a){return d[a]})])}else b.set(c,[d])});return b};c.prototype._filterCroppedRendering=function(a,b){function c(a,b){return q.Math.inRange(a,0,d.width())&&q.Math.inRange(b,0,d.height())}for(var d=this,e=t.Plot._scaledAccessor(this.x()),f=t.Plot._scaledAccessor(this.y()),g=a.data(),k=[],l=0;l<b.length;l++){var m=e(g[b[l]],b[l],a),n=f(g[b[l]],b[l],a),m=c(m,n);if(!m&&null!=b[l-1]&&null!=g[b[l-1]])var n=e(g[b[l-1]],b[l-1],a),p=f(g[b[l-1]],b[l-1],a),m=m||c(n,p);m||null==b[l+1]||\nnull==g[b[l+1]]||(n=e(g[b[l+1]],b[l+1],a),p=f(g[b[l+1]],b[l+1],a),m=m||c(n,p));m&&k.push(b[l])}return k};c.prototype._filterDownsampling=function(a,b){function c(c,g){var k=e(d[b[c]],b[c],a),l=f(d[b[c]],b[c],a),m=e(d[b[c+1]],b[c+1],a);c=f(d[b[c+1]],b[c+1],a);return Infinity===g?Math.floor(k)===Math.floor(m):Math.floor(c)===Math.floor(l+(m-k)*g)}if(0===b.length)return[];for(var d=a.data(),e=t.Plot._scaledAccessor(this.x()),f=t.Plot._scaledAccessor(this.y()),g=[b[0]],k=0;k<b.length-1;){for(var l=b[k],\nm=e(d[b[k]],b[k],a),n=f(d[b[k]],b[k],a),q=e(d[b[k+1]],b[k+1],a),p=f(d[b[k+1]],b[k+1],a),p=Math.floor(m)===Math.floor(q)?Infinity:(p-n)/(q-m),q=b[k],n=Infinity===p?n:m,m=q,r=n,v=!0;k<b.length-1&&(v||c(k,p));){k++;var v=!1,w=Infinity===p?f(d[b[k]],b[k],a):e(d[b[k]],b[k],a);w>r&&(r=w,m=b[k]);w<n&&(n=w,q=b[k])}p=b[k];q!==l&&g.push(q);m!==q&&m!==l&&g.push(m);p!==l&&p!==q&&p!==m&&g.push(p)}return g};c.prototype._filterDenseLines=function(a,b){if(0===b.length)return[];var c=a.data(),d=t.Plot._scaledAccessor(this.x()),\ne=t.Plot._scaledAccessor(this.y());return this._bucketByX(a,b,function(b){return d(c[b],b,a)},function(b){return e(c[b],b,a)})};c.prototype._bucketByX=function(a,b,c,d){var e=[];a=a.data();for(var f=null,g=0;g<=b.length;++g){var k=b[g];if(null!=a[k]){var l=Math.floor(c(k)),m=d(k);null==f?f=new q.Bucket(k,l,m):f.isInBucket(l)?f.addToBucket(m,k):(e.push.apply(e,f.getUniqueIndices()),f=new q.Bucket(k,l,m))}}null!=f&&e.push.apply(e,f.getUniqueIndices());return e};return c}(d.XYPlot);c.Line=d},function(a,\nc,d){var b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=null===b?Object.create(b):(c.prototype=b.prototype,new c)},f=d(1),g=d(14),k=d(0),l=[0,1];a=function(a){function c(){var b=a.call(this)||this;b._range=[0,1];b._d3Scale=f.scaleBand();b._d3Scale.range(l);b._d3TransformationScale=f.scaleLinear();b._d3TransformationScale.domain(l);b._innerPadding=c._convertToPlottableInnerPadding();b._outerPadding=c._convertToPlottableOuterPadding();\nreturn b}b(c,a);c.prototype.cloneWithoutProviders=function(){var a=(new c).domain(this.domain()).range(this.range()).innerPadding(this.innerPadding()).outerPadding(this.outerPadding());a._d3TransformationScale.domain(this._d3TransformationScale.domain());return a};c.prototype.extentOfValues=function(a){return k.Array.uniq(a)};c.prototype._getExtent=function(){return k.Array.uniq(this._getAllIncludedValues())};c.prototype.domain=function(b){return a.prototype.domain.call(this,b)};c.prototype.invertRange=\nfunction(){var a,b=this;void 0===a&&(a=this.range());var c=this._d3Scale.bandwidth(),d=this.invertedTransformation(a[0]),e=this.invertedTransformation(a[1]);a=this._d3Scale.domain();var g=a.map(function(a){return b._d3Scale(a)+c/2}),d=f.bisect(g,d),e=f.bisect(g,e);return a.slice(d,e)};c.prototype.range=function(b){return a.prototype.range.call(this,b)};c._convertToPlottableInnerPadding=function(){return 1/.7-1};c._convertToPlottableOuterPadding=function(){return.5/.7};c.prototype._setBands=function(){var a=\n1-1/(1+this.innerPadding()),b=this.outerPadding()/(1+this.innerPadding());this._d3Scale.paddingInner(a);this._d3Scale.paddingOuter(b)};c.prototype.rangeBand=function(){return this._rescaleBand(this._d3Scale.bandwidth())};c.prototype.stepWidth=function(){return this._rescaleBand(this._d3Scale.bandwidth()*(1+this.innerPadding()))};c.prototype.innerPadding=function(a){if(null==a)return this._innerPadding;this._innerPadding=a;this.range(this.range());this._dispatchUpdate();return this};c.prototype.outerPadding=\nfunction(a){if(null==a)return this._outerPadding;this._outerPadding=a;this.range(this.range());this._dispatchUpdate();return this};c.prototype.scale=function(a){a=this._d3Scale(a)+this._d3Scale.bandwidth()/2;return this._d3TransformationScale(a)};c.prototype.zoom=function(a,b){var c=this;this._d3TransformationScale.domain(this._d3TransformationScale.range().map(function(d){return c._d3TransformationScale.invert(g.zoomAt(d,a,b))}));this._dispatchUpdate()};c.prototype.pan=function(a){var b=this;this._d3TransformationScale.domain(this._d3TransformationScale.range().map(function(c){return b._d3TransformationScale.invert(c+\na)}));this._dispatchUpdate()};c.prototype.scaleTransformation=function(a){return this._d3TransformationScale(a)};c.prototype.invertedTransformation=function(a){return this._d3TransformationScale.invert(a)};c.prototype.getTransformationDomain=function(){return this._d3TransformationScale.domain()};c.prototype._getDomain=function(){return this._backingScaleDomain()};c.prototype._backingScaleDomain=function(a){if(null==a)return this._d3Scale.domain();this._d3Scale.domain(a);this._setBands();return this};\nc.prototype._getRange=function(){return this._range};c.prototype._setRange=function(a){this._range=a;this._d3TransformationScale.range(a);this._setBands()};c.prototype._rescaleBand=function(a){return Math.abs(this._d3TransformationScale(a)-this._d3TransformationScale(0))};return c}(d(18).Scale);c.Category=a},function(a,c){a=function(){function a(){\"function\"===typeof window.Set?this._es6Set=new window.Set:this._values=[];this.size=0}a.prototype.add=function(a){if(null!=this._es6Set)return this._es6Set.add(a),\nthis.size=this._es6Set.size,this;this.has(a)||(this._values.push(a),this.size=this._values.length);return this};a.prototype.delete=function(a){if(null!=this._es6Set)return a=this._es6Set.delete(a),this.size=this._es6Set.size,a;a=this._values.indexOf(a);return-1!==a?(this._values.splice(a,1),this.size=this._values.length,!0):!1};a.prototype.has=function(a){return null!=this._es6Set?this._es6Set.has(a):-1!==this._values.indexOf(a)};a.prototype.forEach=function(a,b){var c=this;null!=this._es6Set?this._es6Set.forEach(function(d,\ne){return a.call(b,d,e,c)},b):this._values.forEach(function(d){a.call(b,d,d,c)})};return a}();c.Set=a},function(a,c,d){function b(a){for(var b in a)c.hasOwnProperty(b)||(c[b]=a[b])}b(d(120));b(d(119))},function(a,c,d){var b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=null===b?Object.create(b):(c.prototype=b.prototype,new c)},f=d(20);a=function(a){function c(b,c){var d=a.call(this,b,c)||this;d.cache=new f.Cache(function(a){return d._measureCharacterNotFromCache(a)});\nreturn d}b(c,a);c.prototype._measureCharacterNotFromCache=function(b){return a.prototype._measureCharacter.call(this,b)};c.prototype._measureCharacter=function(a){return this.cache.get(a)};c.prototype.reset=function(){this.cache.clear()};return c}(d(53).CharacterMeasurer);c.CacheCharacterMeasurer=a},function(a,c,d){var b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=null===b?Object.create(b):(c.prototype=b.prototype,\nnew c)};a=function(a){function c(){return a.apply(this,arguments)||this}b(c,a);c.prototype._measureCharacter=function(b){return a.prototype._measureLine.call(this,b)};c.prototype._measureLine=function(a){var b=this;a=a.split(\"\").map(function(a){return b._measureCharacter(a)});return{height:a.reduce(function(a,b){return Math.max(a,b.height)},0),width:a.reduce(function(a,b){return a+b.width},0)}};return c}(d(55).Measurer);c.CharacterMeasurer=a},function(a,c,d){function b(a){for(var b in a)c.hasOwnProperty(b)||\n(c[b]=a[b])}b(d(34));b(d(52));b(d(121));b(d(53));b(d(55))},function(a,c,d){var b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=null===b?Object.create(b):(c.prototype=b.prototype,new c)},f=d(34);a=function(a){function c(b,c){void 0===c&&(c=!1);b=a.call(this,b)||this;b.useGuards=c;return b}b(c,a);c.prototype._addGuards=function(a){return f.AbstractMeasurer.HEIGHT_TEXT+a+f.AbstractMeasurer.HEIGHT_TEXT};c.prototype._measureLine=\nfunction(b,c){void 0===c&&(c=!1);c=this.useGuards||c||/^[\\t ]$/.test(b);b=a.prototype.measure.call(this,c?this._addGuards(b):b);b.width-=c?2*this.getGuardWidth():0;return b};c.prototype.measure=function(a){var b=this;void 0===a&&(a=f.AbstractMeasurer.HEIGHT_TEXT);if(\"\"===a.trim())return{width:0,height:0};a=a.trim().split(\"\\n\").map(function(a){return b._measureLine(a)});return{height:a.reduce(function(a,b){return a+b.height},0),width:a.reduce(function(a,b){return Math.max(a,b.width)},0)}};c.prototype.getGuardWidth=\nfunction(){null==this.guardWidth&&(this.guardWidth=a.prototype.measure.call(this).width);return this.guardWidth};return c}(f.AbstractMeasurer);c.Measurer=a},function(a,c,d){function b(a){for(var b in a)c.hasOwnProperty(b)||(c[b]=a[b])}b(d(127));b(d(57))},function(a,c,d){var b=d(20);a=function(){function a(){this.maxLines(Infinity);this.textTrimming();this.allowBreakingWords();this._tokenizer=new b.Tokenizer;this._breakingCharacter=\"-\"}a.prototype.maxLines=function(a){if(null==a)return this._maxLines;\nthis._maxLines=a;return this};a.prototype.textTrimming=function(){this._textTrimming=\"ellipsis\"};a.prototype.allowBreakingWords=function(){this._allowBreakingWords=!0};a.prototype.wrap=function(a,b,c,d){var e=this;void 0===d&&(d=Infinity);var f={noBrokeWords:0,noLines:0,originalText:a,truncatedText:\"\",wrappedText:\"\"};c={availableLines:Math.min(Math.floor(d/b.measure().height),this._maxLines),availableWidth:c,canFitText:!0,currentLine:\"\",wrapping:f};var g=a.split(\"\\n\");return g.reduce(function(a,c,\nd){return e.breakLineToFitWidth(a,c,d!==g.length-1,b)},c).wrapping};a.prototype.breakLineToFitWidth=function(a,c,d,e){var f=this;a.canFitText||\"\"===a.wrapping.truncatedText||(a.wrapping.truncatedText+=\"\\n\");a=this._tokenizer.tokenize(c).reduce(function(a,b){return f.wrapNextToken(b,a,e)},a);c=b.StringMethods.trimEnd(a.currentLine);a.wrapping.noLines+=+(\"\"!==c);a.wrapping.noLines===a.availableLines&&\"none\"!==this._textTrimming&&d?a.canFitText=!1:a.wrapping.wrappedText+=c;a.currentLine=\"\\n\";return a};\na.prototype.canFitToken=function(a,b,c){var d=this,e=this._allowBreakingWords?a.split(\"\").map(function(b,c){return c!==a.length-1?b+d._breakingCharacter:b}):[a];return c.measure(a).width<=b||e.every(function(a){return c.measure(a).width<=b})};a.prototype.addEllipsis=function(a,c,d){if(\"none\"===this._textTrimming)return{remainingToken:\"\",wrappedToken:a};var e=a.substring(0).trim(),f=d.measure(e).width,g=d.measure(\"...\").width,k=0<a.length&&\"\\n\"===a[0]?\"\\n\":\"\";if(c<=g)return{remainingToken:a,wrappedToken:k+\n\"...\".substr(0,Math.floor(c/(g/3)))};for(;f+g>c;)e=b.StringMethods.trimEnd(e.substr(0,e.length-1)),f=d.measure(e).width;return{remainingToken:b.StringMethods.trimEnd(a.substring(e.length),\"-\").trim(),wrappedToken:k+e+\"...\"}};a.prototype.wrapNextToken=function(a,c,d){if(!c.canFitText||c.availableLines===c.wrapping.noLines||!this.canFitToken(a,c.availableWidth,d))return this.finishWrapping(a,c,d);for(;a;){var e=this.breakTokenToFitInWidth(a,c.currentLine,c.availableWidth,d);c.currentLine=e.line;a=e.remainingToken;\nif(null!=a)if(c.wrapping.noBrokeWords+=+e.breakWord,++c.wrapping.noLines,c.availableLines===c.wrapping.noLines){d=this.addEllipsis(c.currentLine,c.availableWidth,d);c.wrapping.wrappedText+=d.wrappedToken;c.wrapping.truncatedText+=d.remainingToken+a;c.currentLine=\"\\n\";break}else c.wrapping.wrappedText+=b.StringMethods.trimEnd(c.currentLine),c.currentLine=\"\\n\"}return c};a.prototype.finishWrapping=function(a,b,c){b.canFitText&&b.availableLines!==b.wrapping.noLines&&this._allowBreakingWords&&\"none\"!==\nthis._textTrimming?(c=this.addEllipsis(b.currentLine+a,b.availableWidth,c),b.wrapping.wrappedText+=c.wrappedToken,b.wrapping.truncatedText+=c.remainingToken,b.wrapping.noBrokeWords+=+(c.remainingToken.length<a.length),b.wrapping.noLines+=+(0<c.wrappedToken.length),b.currentLine=\"\"):b.wrapping.truncatedText+=a;b.canFitText=!1;return b};a.prototype.breakTokenToFitInWidth=function(a,b,c,d){if(void 0===e)var e=this._breakingCharacter;if(d.measure(b+a).width<=c)return{breakWord:!1,line:b+a,remainingToken:null};\nif(\"\"===a.trim())return{breakWord:!1,line:b,remainingToken:\"\"};if(!this._allowBreakingWords)return{breakWord:!1,line:b,remainingToken:a};for(var f=0;f<a.length;)if(d.measure(b+a.substring(0,f+1)+e).width<=c)++f;else break;c=\"\";0<f&&(c=e);return{breakWord:0<f,line:b+a.substring(0,f)+c,remainingToken:a.substring(f)}};return a}();c.Wrapper=a},function(a,c,d){a=d(128);for(var b in a)c.hasOwnProperty(b)||(c[b]=a[b])},function(a,c,d){function b(a){for(var b in a)c.hasOwnProperty(b)||(c[b]=a[b])}b(d(66));\nb(d(67));b(d(26))},function(a,c,d){var b=d(0);a=function(){function a(a,c){void 0===a&&(a=[]);void 0===c&&(c={});this._data=a;this._metadata=c;this._callbacks=new b.CallbackSet}a.prototype.onUpdate=function(a){this._callbacks.add(a);return this};a.prototype.offUpdate=function(a){this._callbacks.delete(a);return this};a.prototype.data=function(a){if(null==a)return this._data;this._data=a;this._callbacks.callCallbacks(this);return this};a.prototype.metadata=function(a){if(null==a)return this._metadata;\nthis._metadata=a;this._callbacks.callCallbacks(this);return this};return a}();c.Dataset=a},function(a,c){c.version=\"3.1.0\"},function(a,c,d){function b(a){for(var b in a)c.hasOwnProperty(b)||(c[b]=a[b])}b(d(41));b(d(42));b(d(43));b(d(19));b(d(6));b(d(31));b(d(32));b(d(44));b(d(8));b(d(45))},function(a,c,d){function b(a,b){return a.each(function(){var a=b.apply(this,arguments),c=r.select(this),d;for(d in a)c.attr(d,a[d])})}function f(a,b){for(var c in b)a.attr(c,b[c]);return a}function g(a,b,c){return a.each(function(){var a=\nb.apply(this,arguments),d=r.select(this),e;for(e in a)d.style(e,a[e],c)})}function k(a,b,c){for(var d in b)a.style(d,b[d],c);return a}function l(a,b){return a.each(function(){var a=b.apply(this,arguments),c=r.select(this),d;for(d in a)c.property(d,a[d])})}function m(a,b){for(var c in b)a.property(c,b[c]);return a}function n(a,b){return a.each(function(){var c=b.apply(this,arguments),d=r.select(this).transition(a),e;for(e in c)d.attr(e,c[e])})}function q(a,b){for(var c in b)a.attr(c,b[c]);return a}\nfunction p(a,b,c){return a.each(function(){var d=b.apply(this,arguments),e=r.select(this).transition(a),f;for(f in d)e.style(f,d[f],c)})}function t(a,b,c){for(var d in b)a.style(d,b[d],c);return a}var r=a=d(1);r.selection.prototype.attrs=function(a){return(\"function\"===typeof a?b:f)(this,a)};r.selection.prototype.styles=function(a,b){return(\"function\"===typeof a?g:k)(this,a,null==b?\"\":b)};r.selection.prototype.properties=function(a){return(\"function\"===typeof a?l:m)(this,a)};a.transition.prototype.attrs=\nfunction(a){return(\"function\"===typeof a?n:q)(this,a)};a.transition.prototype.styles=function(a,b){return(\"function\"===typeof a?p:t)(this,a,null==b?\"\":b)}},function(a,c,d){a=d(108);var b=d(12);d=d(9);var f={linear:a.easeLinear,quad:a.easeQuad,quadIn:a.easeQuadIn,quadOut:a.easeQuadOut,quadInOut:a.easeQuadInOut,cubic:a.easeCubic,cubicIn:a.easeCubicIn,cubicOut:a.easeCubicOut,cubicInOut:a.easeCubicInOut,poly:a.easePoly,polyIn:a.easePolyIn,polyOut:a.easePolyOut,polyInOut:a.easePolyInOut,sin:a.easeSin,\nsinIn:a.easeSinIn,sinOut:a.easeSinOut,sinInOut:a.easeSinInOut,exp:a.easeExp,expIn:a.easeExpIn,expOut:a.easeExpOut,expInOut:a.easeExpInOut,circle:a.easeCircle,circleIn:a.easeCircleIn,circleOut:a.easeCircleOut,circleInOut:a.easeCircleInOut,bounce:a.easeBounce,bounceIn:a.easeBounceIn,bounceOut:a.easeBounceOut,bounceInOut:a.easeBounceInOut,back:a.easeBack,backIn:a.easeBackIn,backOut:a.easeBackOut,backInOut:a.easeBackInOut,elastic:a.easeElastic,elasticIn:a.easeElasticIn,elasticOut:a.easeElasticOut,elasticInOut:a.easeElasticInOut};\nc.EaseName=d.makeEnum(\"linear quad quadIn quadOut quadInOut cubic cubicIn cubicOut cubicInOut poly polyIn polyOut polyInOut sin sinIn sinOut sinInOut exp expIn expOut expInOut circle circleIn circleOut circleInOut bounce bounceIn bounceOut bounceInOut back backIn backOut backInOut elastic elasticIn elasticOut elasticInOut\".split(\" \"));d=function(){function a(){this._startDelay=a._DEFAULT_START_DELAY_MILLISECONDS;this._stepDuration=a._DEFAULT_STEP_DURATION_MILLISECONDS;this._stepDelay=a._DEFAULT_ITERATIVE_DELAY_MILLISECONDS;\nthis._maxTotalDuration=a._DEFAULT_MAX_TOTAL_DURATION_MILLISECONDS;this._easingMode=a._DEFAULT_EASING_MODE}a.prototype.totalTime=function(a){var b=this._getAdjustedIterativeDelay(a);return this.startDelay()+b*Math.max(a-1,0)+this.stepDuration()};a.prototype.animate=function(a,c){var d=this;a=b.coerceExternalD3(a);var e=a.size(),f=this._getAdjustedIterativeDelay(e);return a.transition().ease(this._getEaseFactory()).duration(this.stepDuration()).delay(function(a,b){return d.startDelay()+f*b}).attrs(c)};\na.prototype.startDelay=function(a){if(null==a)return this._startDelay;this._startDelay=a;return this};a.prototype.stepDuration=function(a){if(null==a)return Math.min(this._stepDuration,this._maxTotalDuration);this._stepDuration=a;return this};a.prototype.stepDelay=function(){return this._stepDelay};a.prototype.maxTotalDuration=function(a){if(null==a)return this._maxTotalDuration;this._maxTotalDuration=a;return this};a.prototype.easingMode=function(a){if(null==a)return this._easingMode;this._easingMode=\na;return this};a.prototype._getEaseFactory=function(){var a=this.easingMode();return\"string\"===typeof a?(a=f[a],null==a?f.linear:a):a};a.prototype._getAdjustedIterativeDelay=function(a){var b=this.maxTotalDuration()-this.stepDuration(),b=Math.max(b,0);a=b/Math.max(a-1,1);return Math.min(this.stepDelay(),a)};return a}();d._DEFAULT_START_DELAY_MILLISECONDS=0;d._DEFAULT_STEP_DURATION_MILLISECONDS=300;d._DEFAULT_ITERATIVE_DELAY_MILLISECONDS=15;d._DEFAULT_MAX_TOTAL_DURATION_MILLISECONDS=Infinity;d._DEFAULT_EASING_MODE=\n\"expOut\";c.Easing=d},function(a,c,d){var b=d(12);a=function(){function a(){}a.prototype.totalTime=function(){return 0};a.prototype.animate=function(a,c){a=b.coerceExternalD3(a);return a.attrs(c)};return a}();c.Null=a},function(a,c,d){var b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=null===b?Object.create(b):(c.prototype=b.prototype,new c)},f=d(1),g=d(5),k=d(4),l=d(0),m=d(21);a=function(a){function c(b,c){void 0===\nc&&(c=\"bottom\");b=a.call(this,b,c)||this;b._tickLabelAngle=0;b._tickLabelShearAngle=0;b.addClass(\"category-axis\");return b}b(c,a);Object.defineProperty(c.prototype,\"_wrapper\",{get:function(){var a=new g.Wrapper;null!=this._tickLabelMaxLines&&a.maxLines(this._tickLabelMaxLines);return a},enumerable:!0,configurable:!0});Object.defineProperty(c.prototype,\"_writer\",{get:function(){return new g.Writer(this._measurer,this._typesetterContext,this._wrapper)},enumerable:!0,configurable:!0});c.prototype._setup=\nfunction(){a.prototype._setup.call(this);this._typesetterContext=new g.SvgContext(this._tickLabelContainer.node());this._measurer=new g.CacheMeasurer(this._typesetterContext)};c.prototype._rescale=function(){return this.redraw()};c.prototype.requestedSpace=function(a,b){var c=this.isHorizontal()?0:this._tickSpaceRequired()+this.margin(),d=this.isHorizontal()?this._tickSpaceRequired()+this.margin():0;if(0===this._scale.domain().length)return{minWidth:0,minHeight:0};if(this.annotationsEnabled()){var e=\nthis._annotationTierHeight()*this.annotationTierCount();this.isHorizontal()?d+=e:c+=e}a=this._measureTickLabels(a,b);return{minWidth:a.usedWidth+c,minHeight:a.usedHeight+d}};c.prototype._coreSize=function(){var a=this.isHorizontal()?this.height():this.width(),b=this.isHorizontal()?this.requestedSpace(this.width(),this.height()).minHeight:this.requestedSpace(this.width(),this.height()).minWidth,c=this.margin()+this._annotationTierHeight();return Math.min(b-c,a)};c.prototype._getTickValues=function(){return this.getDownsampleInfo().domain};\nc.prototype._sizeFromOffer=function(a,b){return k.Component.prototype._sizeFromOffer.call(this,a,b)};c.prototype.getDownsampleInfo=function(a){var b;void 0===a&&(a=this._scale);void 0===b&&(b=a.invertRange());var d=Math.ceil(c._MINIMUM_WIDTH_PER_LABEL_PX*(0===this._tickLabelAngle?1:1/Math.cos(this._tickLabelShearAngle/180*Math.PI))/a.stepWidth());return{domain:b.filter(function(a,b){return 0===b%d}),stepWidth:d*a.stepWidth()}};c.prototype.tickLabelAngle=function(){return this._tickLabelAngle;throw Error(\"Angle undefined not supported; only 0, 90, and -90 are valid values\");\n};c.prototype.tickLabelShearAngle=function(){return this._tickLabelShearAngle};c.prototype.tickLabelMaxWidth=function(a){if(0===arguments.length)return this._tickLabelMaxWidth;this._tickLabelMaxWidth=a;this.redraw();return this};c.prototype.tickLabelMaxLines=function(a){if(0===arguments.length)return this._tickLabelMaxLines;this._tickLabelMaxLines=a;this.redraw();return this};c.prototype._tickSpaceRequired=function(){return this._maxLabelTickLength()+this.tickLabelPadding()};c.prototype._drawTicks=\nfunction(a,b){var c=this;switch(this.tickLabelAngle()){case 0:var d={left:\"right\",right:\"left\",top:\"center\",bottom:\"center\"};var e={left:\"center\",right:\"center\",top:\"bottom\",bottom:\"top\"};break;case 90:d={left:\"center\",right:\"center\",top:\"right\",bottom:\"left\"};e={left:\"top\",right:\"bottom\",top:\"center\",bottom:\"center\"};break;case -90:d={left:\"center\",right:\"center\",top:\"left\",bottom:\"right\"},e={left:\"bottom\",right:\"top\",top:\"center\",bottom:\"center\"}}b.each(function(b){var g=f.select(this),k=c.isHorizontal()?\na:c.width()-c._tickSpaceRequired(),l=c.isHorizontal()?c.height()-c._tickSpaceRequired():a,m={xAlign:d[c.orientation()],yAlign:e[c.orientation()],textRotation:c.tickLabelAngle(),textShear:c.tickLabelShearAngle()};if(null!=c._tickLabelMaxWidth){if(\"left\"===c.orientation()&&k>c._tickLabelMaxWidth){var n=k-c._tickLabelMaxWidth,n=g.attr(\"transform\")+\" translate(\"+n+\", 0)\";g.attr(\"transform\",n)}k=Math.min(k,c._tickLabelMaxWidth)}c._writer.write(c.formatter()(b),k,l,m,g.node())})};c.prototype._measureTickLabels=\nfunction(a,b){var c=this,d=this._scale.cloneWithoutProviders().range([0,this.isHorizontal()?a:b]),e=this.getDownsampleInfo(d),d=e.domain,e=e.stepWidth,g=a-this._tickSpaceRequired();this.isHorizontal()&&(g=e,0!==this._tickLabelAngle&&(g=b-this._tickSpaceRequired()),g=Math.max(g,0));var k=e;this.isHorizontal()&&(k=b-this._tickSpaceRequired(),0!==this._tickLabelAngle&&(k=a-this._tickSpaceRequired()),k=Math.max(k,0));null!=this._tickLabelMaxWidth&&(g=Math.min(g,this._tickLabelMaxWidth));b=d.map(function(a){return c._wrapper.wrap(c.formatter()(a),\nc._measurer,g,k)});d=this.isHorizontal()&&0===this._tickLabelAngle?l.Math.max:f.sum;a=(this.isHorizontal()&&0===this._tickLabelAngle?f.sum:l.Math.max)(b,function(a){return c._measurer.measure(a.wrappedText).width},0);b=d(b,function(a){return c._measurer.measure(a.wrappedText).height},0);0!==this._tickLabelAngle&&(b=[b,a],a=b[0],b=b[1]);return{usedWidth:a,usedHeight:b}};c.prototype.renderImmediately=function(){var b=this;a.prototype.renderImmediately.call(this);var c=this._scale,d=this.getDownsampleInfo(c),\ne=d.domain,f=d=d.stepWidth;this.isHorizontal()&&null!=this._tickLabelMaxWidth&&(f=Math.min(f,this._tickLabelMaxWidth));var e=this._tickLabelContainer.selectAll(\".\"+m.Axis.TICK_LABEL_CLASS).data(e),g=e.enter().append(\"g\").classed(m.Axis.TICK_LABEL_CLASS,!0).merge(e);e.exit().remove();g.attr(\"transform\",function(a){a=c.scale(a)-f/2;return\"translate(\"+(b.isHorizontal()?a:0)+\",\"+(b.isHorizontal()?0:a)+\")\"});g.text(\"\");this._drawTicks(d,g);d=\"right\"===this.orientation()?this._tickSpaceRequired():0;e=\"bottom\"===\nthis.orientation()?this._tickSpaceRequired():0;this._tickLabelContainer.attr(\"transform\",\"translate(\"+d+\",\"+e+\")\");this._showAllTickMarks();this._showAllTickLabels();this._hideTickMarksWithoutLabel();return this};c.prototype.computeLayout=function(b,c,d){a.prototype.computeLayout.call(this,b,c,d);this.isHorizontal()||this._scale.range([0,this.height()]);return this};c.prototype.invalidateCache=function(){a.prototype.invalidateCache.call(this);this._measurer.reset()};return c}(m.Axis);a._MINIMUM_WIDTH_PER_LABEL_PX=\n15;c.Category=a},function(a,c,d){var b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=null===b?Object.create(b):(c.prototype=b.prototype,new c)},f=d(1),g=d(5),k=d(10),l=d(0),m=d(21);a=function(a){function c(b,c){b=a.call(this,b,c)||this;b._tickLabelPositioning=\"center\";b._usesTextWidthApproximation=!1;b.formatter(k.general());return b}b(c,a);c.prototype._setup=function(){a.prototype._setup.call(this);var b=new g.SvgContext(this._tickLabelContainer.node(),\nm.Axis.TICK_LABEL_CLASS);this._measurer=new g.CacheMeasurer(b);this._wrapper=(new g.Wrapper).maxLines(1)};c.prototype._computeWidth=function(){var a=this._usesTextWidthApproximation?this._computeApproximateTextWidth():this._computeExactTextWidth();return\"center\"===this._tickLabelPositioning?this._maxLabelTickLength()+this.tickLabelPadding()+a:Math.max(this._maxLabelTickLength(),this.tickLabelPadding()+a)};c.prototype._computeExactTextWidth=function(){var a=this,b=this._getTickValues().map(function(b){b=\na.formatter()(b);return a._measurer.measure(b).width});return l.Math.max(b,0)};c.prototype._computeApproximateTextWidth=function(){var a=this,b=this._getTickValues(),c=this._measurer.measure(\"M\").width,b=b.map(function(b){return a.formatter()(b).length*c});return l.Math.max(b,0)};c.prototype._computeHeight=function(){var a=this._measurer.measure().height;return\"center\"===this._tickLabelPositioning?this._maxLabelTickLength()+this.tickLabelPadding()+a:Math.max(this._maxLabelTickLength(),this.tickLabelPadding()+\na)};c.prototype._getTickValues=function(){var a=this._scale,b=a.domain(),c=b[0]<=b[1]?b[0]:b[1],d=b[0]>=b[1]?b[0]:b[1];return a.ticks().filter(function(a){return a>=c&&a<=d})};c.prototype._rescale=function(){if(this._isSetup){if(!this.isHorizontal()){var a=this._computeWidth();if(a>this.width()||a<this.width()-this.margin()){this.redraw();return}}this.render()}};c.prototype.renderImmediately=function(){var b=this;a.prototype.renderImmediately.call(this);var c={x:0,y:0,dx:\"0em\",dy:\"0.3em\"},d=this._maxLabelTickLength(),\ne=this.tickLabelPadding(),f=\"middle\",g=0,k=0,l=0,n=0;if(this.isHorizontal())switch(this._tickLabelPositioning){case \"left\":f=\"end\";g=-e;n=e;break;case \"center\":n=d+e;break;case \"right\":f=\"start\",n=g=e}else switch(this._tickLabelPositioning){case \"top\":c.dy=\"-0.3em\";l=e;k=-e;break;case \"center\":l=d+e;break;case \"bottom\":c.dy=\"1em\",k=l=e}d=this._generateTickMarkAttrHash();switch(this.orientation()){case \"bottom\":c.x=d.x1;c.dy=\"0.95em\";k=d.y1+n;break;case \"top\":c.x=d.x1;c.dy=\"-.25em\";k=d.y1-n;break;\ncase \"left\":f=\"end\";g=d.x1-l;c.y=d.y1;break;case \"right\":f=\"start\",g=d.x1+l,c.y=d.y1}l=this._getTickValues();l=this._tickLabelContainer.selectAll(\".\"+m.Axis.TICK_LABEL_CLASS).data(l);l.exit().remove();l.enter().append(\"text\").classed(m.Axis.TICK_LABEL_CLASS,!0).merge(l).style(\"text-anchor\",f).style(\"visibility\",\"inherit\").attrs(c).text(function(a){return b.formatter()(a)});this._tickLabelContainer.attr(\"transform\",\"translate(\"+g+\", \"+k+\")\");this._showAllTickMarks();this.showEndTickLabels()||this._hideEndTickLabels();\nthis._hideOverflowingTickLabels();this._hideOverlappingTickLabels();\"center\"!==this._tickLabelPositioning&&this._hideTickMarksWithoutLabel();return this};c.prototype.tickLabelPosition=function(a){if(null==a)return this._tickLabelPositioning;a=a.toLowerCase();if(this.isHorizontal()){if(\"left\"!==a&&\"center\"!==a&&\"right\"!==a)throw Error(a+\" is not a valid tick label position for a horizontal NumericAxis\");}else if(\"top\"!==a&&\"center\"!==a&&\"bottom\"!==a)throw Error(a+\" is not a valid tick label position for a vertical NumericAxis\");\nthis._tickLabelPositioning=a;this.redraw();return this};c.prototype.usesTextWidthApproximation=function(a){if(null==a)return this._usesTextWidthApproximation;this._usesTextWidthApproximation=a;return this};c.prototype._hideEndTickLabels=function(){var a=this.element().node().getBoundingClientRect(),b=this._tickLabelContainer.selectAll(\".\"+m.Axis.TICK_LABEL_CLASS);if(0!==b.size()){var c=b.nodes()[0];l.DOM.clientRectInside(c.getBoundingClientRect(),a)||f.select(c).style(\"visibility\",\"hidden\");b=b.nodes()[b.size()-\n1];l.DOM.clientRectInside(b.getBoundingClientRect(),a)||f.select(b).style(\"visibility\",\"hidden\")}};c.prototype._hideOverlappingTickLabels=function(){for(var a=this._tickLabelContainer.selectAll(\".\"+m.Axis.TICK_LABEL_CLASS).filter(function(){var a=f.select(this).style(\"visibility\");return\"inherit\"===a||\"visible\"===a}),b=a.nodes().map(function(a){return a.getBoundingClientRect()}),c=1;!this._hasOverlapWithInterval(c,b)&&c<b.length;)c+=1;a.each(function(a,b){a=f.select(this);0!==b%c&&a.style(\"visibility\",\n\"hidden\")})};c.prototype._hasOverlapWithInterval=function(a,b){var c=\"center\"===this._tickLabelPositioning?this.tickLabelPadding():3*this.tickLabelPadding();b=b.map(function(a){return l.DOM.expandRect(a,c)});for(var d=0;d<b.length-a;d+=a)if(l.DOM.clientRectsOverlap(b[d],b[d+a]))return!1;return!0};c.prototype.invalidateCache=function(){a.prototype.invalidateCache.call(this);this._measurer.reset()};return c}(m.Axis);c.Numeric=a},function(a,c,d){var b=this&&this.__extends||function(a,b){function c(){this.constructor=\na}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=null===b?Object.create(b):(c.prototype=b.prototype,new c)};a=d(39);var f=d(14),g=d(0);d=function(a){function c(b){function c(){l&&(l=!1,k._dragEndCallbacks.callCallbacks(k))}function d(a,b){l&&(k._setPixelPositionWithoutChangingMode(k._isVertical()?b.x:b.y),k._dragCallbacks.callCallbacks(k))}function e(a){if(k._isVertical()&&k.pixelPosition()-k.detectionRadius()<=a.x&&a.x<=k.pixelPosition()+k.detectionRadius()||!k._isVertical()&&k.pixelPosition()-\nk.detectionRadius()<=a.y&&a.y<=k.pixelPosition()+k.detectionRadius())l=!0,k._dragStartCallbacks.callCallbacks(k)}var k=a.call(this,b)||this;k._detectionRadius=3;k._enabled=!0;k.addClass(\"drag-line-layer\");k.addClass(\"enabled\");k._dragInteraction=new f.Drag;k._dragInteraction.attachTo(k);var l=!1;k._dragInteraction.onDragStart(e);k._dragInteraction.onDrag(d);k._dragInteraction.onDragEnd(c);k._disconnectInteraction=function(){k._dragInteraction.offDragStart(e);k._dragInteraction.offDrag(d);k._dragInteraction.offDragEnd(c);\nk._dragInteraction.detachFrom()};k._dragStartCallbacks=new g.CallbackSet;k._dragCallbacks=new g.CallbackSet;k._dragEndCallbacks=new g.CallbackSet;return k}b(c,a);c.prototype._setup=function(){a.prototype._setup.call(this);this._detectionEdge=this.content().append(\"line\").styles({opacity:0,stroke:\"pink\",\"pointer-events\":\"visibleStroke\"}).classed(\"drag-edge\",!0)};c.prototype.renderImmediately=function(){a.prototype.renderImmediately.call(this);this._detectionEdge.attrs({x1:this._isVertical()?this.pixelPosition():\n0,y1:this._isVertical()?0:this.pixelPosition(),x2:this._isVertical()?this.pixelPosition():this.width(),y2:this._isVertical()?this.height():this.pixelPosition(),\"stroke-width\":2*this._detectionRadius});return this};c.prototype.detectionRadius=function(a){if(null==a)return this._detectionRadius;if(0>a)throw Error(\"detection radius cannot be negative.\");this._detectionRadius=a;this.render();return this};c.prototype.enabled=function(a){if(null==a)return this._enabled;(this._enabled=a)?this.addClass(\"enabled\"):\nthis.removeClass(\"enabled\");this._dragInteraction.enabled(a);return this};c.prototype.onDragStart=function(a){this._dragStartCallbacks.add(a);return this};c.prototype.offDragStart=function(a){this._dragStartCallbacks.delete(a);return this};c.prototype.onDrag=function(a){this._dragCallbacks.add(a);return this};c.prototype.offDrag=function(a){this._dragCallbacks.delete(a);return this};c.prototype.onDragEnd=function(a){this._dragEndCallbacks.add(a);return this};c.prototype.offDragEnd=function(a){this._dragEndCallbacks.delete(a);\nreturn this};c.prototype.destroy=function(){var b=this;a.prototype.destroy.call(this);this._dragStartCallbacks.forEach(function(a){return b._dragStartCallbacks.delete(a)});this._dragCallbacks.forEach(function(a){return b._dragCallbacks.delete(a)});this._dragEndCallbacks.forEach(function(a){return b._dragEndCallbacks.delete(a)});this._disconnectInteraction()};return c}(a.GuideLineLayer);c.DragLineLayer=d},function(a,c,d){var b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&\n(a[d]=b[d]);a.prototype=null===b?Object.create(b):(c.prototype=b.prototype,new c)},f=d(11);a=function(a){function c(b,c){var d=this;if(null!=b&&!f.QuantitativeScale.prototype.isPrototypeOf(b))throw Error(\"xScale needs to inherit from Scale.QuantitativeScale\");if(null!=c&&!f.QuantitativeScale.prototype.isPrototypeOf(c))throw Error(\"yScale needs to inherit from Scale.QuantitativeScale\");d=a.call(this)||this;d.addClass(\"gridlines\");d._xScale=b;d._yScale=c;d._renderCallback=function(){return d.render()};\nif(d._xScale)d._xScale.onUpdate(d._renderCallback);if(d._yScale)d._yScale.onUpdate(d._renderCallback);return d}b(c,a);c.prototype.destroy=function(){a.prototype.destroy.call(this);this._xScale&&this._xScale.offUpdate(this._renderCallback);this._yScale&&this._yScale.offUpdate(this._renderCallback);return this};c.prototype._setup=function(){a.prototype._setup.call(this);this._xLinesContainer=this.content().append(\"g\").classed(\"x-gridlines\",!0);this._yLinesContainer=this.content().append(\"g\").classed(\"y-gridlines\",\n!0)};c.prototype.renderImmediately=function(){a.prototype.renderImmediately.call(this);this._redrawXLines();this._redrawYLines();return this};c.prototype.computeLayout=function(b,c,d){a.prototype.computeLayout.call(this,b,c,d);null!=this._xScale&&this._xScale.range([0,this.width()]);null!=this._yScale&&this._yScale.range([this.height(),0]);return this};c.prototype._redrawXLines=function(){var a=this;if(this._xScale){var b=this._xScale.ticks(),c=function(b){return a._xScale.scale(b)},b=this._xLinesContainer.selectAll(\"line\").data(b);\nb.enter().append(\"line\").merge(b).attr(\"x1\",c).attr(\"y1\",0).attr(\"x2\",c).attr(\"y2\",this.height()).classed(\"zeroline\",function(a){return 0===a});b.exit().remove()}};c.prototype._redrawYLines=function(){var a=this;if(this._yScale){var b=this._yScale.ticks(),c=function(b){return a._yScale.scale(b)},b=this._yLinesContainer.selectAll(\"line\").data(b);b.enter().append(\"line\").merge(b).attr(\"x1\",0).attr(\"y1\",c).attr(\"x2\",this.width()).attr(\"y2\",c).classed(\"zeroline\",function(a){return 0===a});b.exit().remove()}};\nreturn c}(d(4).Component);c.Gridlines=a},function(a,c,d){var b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=null===b?Object.create(b):(c.prototype=b.prototype,new c)},f=d(5),g=d(22),k=d(10),l=d(0);a=function(a){function c(b){var c=a.call(this)||this;c._textPadding=5;if(null==b)throw Error(\"InterpolatedColorLegend requires a interpolatedColorScale\");c._scale=b;c._redrawCallback=function(){return c.redraw()};c._scale.onUpdate(c._redrawCallback);\nc._formatter=k.general();c._orientation=\"horizontal\";c._expands=!1;c.addClass(\"legend\");c.addClass(\"interpolated-color-legend\");return c}b(c,a);c.prototype.destroy=function(){a.prototype.destroy.call(this);this._scale.offUpdate(this._redrawCallback)};c.prototype.formatter=function(a){if(void 0===a)return this._formatter;this._formatter=a;this.redraw();return this};c.prototype.expands=function(){return this._expands};c._ensureOrientation=function(a){a=a.toLowerCase();if(\"horizontal\"===a||\"left\"===\na||\"right\"===a)return a;throw Error('\"'+a+'\" is not a valid orientation for InterpolatedColorLegend');};c.prototype.orientation=function(a){if(null==a)return this._orientation;this._orientation=c._ensureOrientation(a);this.redraw();return this};c.prototype.fixedWidth=function(){return!this.expands()||this._isVertical()};c.prototype.fixedHeight=function(){return!this.expands()||!this._isVertical()};c.prototype._generateTicks=function(a){void 0===a&&(a=c._DEFAULT_NUM_SWATCHES);var b=this._scale.domain();\nif(1===a)return[b[0]];for(var d=(b[1]-b[0])/(a-1),e=[],f=0;f<a;f++)e.push(b[0]+d*f);return e};c.prototype._setup=function(){a.prototype._setup.call(this);this._swatchContainer=this.content().append(\"g\").classed(\"swatch-container\",!0);this._swatchBoundingBox=this.content().append(\"rect\").classed(\"swatch-bounding-box\",!0);this._lowerLabel=this.content().append(\"g\").classed(c.LEGEND_LABEL_CLASS,!0);this._upperLabel=this.content().append(\"g\").classed(c.LEGEND_LABEL_CLASS,!0);var b=new f.SvgContext(this.content().node());\nthis._measurer=new f.Measurer(b);this._wrapper=new f.Wrapper;this._writer=new f.Writer(this._measurer,b,this._wrapper)};c.prototype.requestedSpace=function(){var a=this,b=this._measurer.measure().height,d=this._scale.domain().map(function(b){return a._measurer.measure(a._formatter(b)).width}),e=c._DEFAULT_NUM_SWATCHES;if(this._isVertical()){var f=l.Math.max(d,0);d=b+b+this._textPadding+f+this._textPadding;f=e*b}else f=b+b+b,d=this._textPadding+d[0]+e*b+d[1]+this._textPadding;return{minWidth:d,minHeight:f}};\nc.prototype._isVertical=function(){return\"horizontal\"!==this._orientation};c.prototype.renderImmediately=function(){var b=this;a.prototype.renderImmediately.call(this);var c=this._scale.domain(),d=this._formatter(c[0]),e=this._measurer.measure(d).width,f=this._formatter(c[1]),c=this._measurer.measure(f).width,k=this._measurer.measure().height,l=this._textPadding,m=0,n=0,A=0,D=0,E={xAlign:\"center\",yAlign:\"center\",textRotation:0},F={xAlign:\"center\",yAlign:\"center\",textRotation:0},I={x:0,y:0,width:0,\nheight:0};if(this._isVertical()){var H=Math.floor(this.height());var C=Math.max(e,c);var J=(this.width()-C-2*this._textPadding)/2;c=Math.max(this.width()-J-2*l-C,0);k=1;var M=function(a,c){return b.height()-(c+1)};F.yAlign=\"top\";n=0;E.yAlign=\"bottom\";D=0;if(\"left\"===this._orientation){var T=function(){return l+C+l};F.xAlign=\"right\";m=-(J+c+l);E.xAlign=\"right\";A=-(J+c+l)}else T=function(){return J},F.xAlign=\"left\",m=J+c+l,E.xAlign=\"left\",A=J+c+l;I.width=c;I.height=H*k}else J=Math.max(l,(this.height()-\nk)/2),H=Math.max(Math.floor(this.width()-4*l-e-c),0),c=1,k=Math.max(this.height()-2*J,0),T=function(a,b){return Math.floor(e+2*l)+b},M=function(){return J},F.xAlign=\"right\",m=-l,E.xAlign=\"left\",A=l,I.y=J,I.width=H*c,I.height=k;I.x=T(null,0);this._upperLabel.text(\"\");this._writer.write(f,this.width(),this.height(),F,this._upperLabel.node());this._upperLabel.attr(\"transform\",\"translate(\"+m+\", \"+n+\")\");this._lowerLabel.text(\"\");this._writer.write(d,this.width(),this.height(),E,this._lowerLabel.node());\nthis._lowerLabel.attr(\"transform\",\"translate(\"+A+\", \"+D+\")\");this._swatchBoundingBox.attrs(I);d=this._generateTicks(H);d=this._swatchContainer.selectAll(\"rect.swatch\").data(d);f=d.enter().append(\"rect\").classed(\"swatch\",!0);m=d.merge(f);d.exit().remove();m.attrs({fill:function(a){return b._scale.scale(a)},width:c,height:k,x:T,y:M,\"shape-rendering\":\"crispEdges\"});g.ADD_TITLE_ELEMENTS&&f.append(\"title\").text(function(a){return b._formatter(a)});return this};return c}(d(4).Component);a._DEFAULT_NUM_SWATCHES=\n11;a.LEGEND_LABEL_CLASS=\"legend-label\";c.InterpolatedColorLegend=a},function(a,c,d){var b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=null===b?Object.create(b):(c.prototype=b.prototype,new c)},f=d(5);a=function(a){function c(b,c){void 0===b&&(b=\"\");void 0===c&&(c=0);var d=a.call(this)||this;d.addClass(\"label\");d.text(b);d.angle(c);d.xAlignment(\"center\").yAlignment(\"center\");d._padding=0;return d}b(c,a);c.prototype.requestedSpace=\nfunction(){var a=this._measurer.measure(this._text),b=(0===this.angle()?a.width:a.height)+2*this.padding(),a=(0===this.angle()?a.height:a.width)+2*this.padding();return{minWidth:b,minHeight:a}};c.prototype._setup=function(){a.prototype._setup.call(this);this._textContainer=this.content().append(\"g\");var b=new f.SvgContext(this._textContainer.node());this._measurer=new f.CacheMeasurer(b);this._wrapper=new f.Wrapper;this._writer=new f.Writer(this._measurer,b,this._wrapper);this.text(this._text)};c.prototype.text=\nfunction(a){if(null==a)return this._text;if(\"string\"!==typeof a)throw Error(\"Label.text() only takes strings as input\");this._text=a;this.redraw();return this};c.prototype.angle=function(a){if(null==a)return this._angle;a%=360;180<a?a-=360:-180>a&&(a+=360);if(-90===a||0===a||90===a)this._angle=a;else throw Error(a+\" is not a valid angle for Label\");this.redraw();return this};c.prototype.padding=function(a){if(null==a)return this._padding;a=+a;if(0>a)throw Error(a+\" is not a valid padding value. Cannot be less than 0.\");\nthis._padding=a;this.redraw();return this};c.prototype.fixedWidth=function(){return!0};c.prototype.fixedHeight=function(){return!0};c.prototype.renderImmediately=function(){a.prototype.renderImmediately.call(this);this._textContainer.selectAll(\"g\").remove();var b=this._measurer.measure(this._text),c=Math.max(Math.min((this.height()-b.height)/2,this.padding()),0),b=Math.max(Math.min((this.width()-b.width)/2,this.padding()),0);this._textContainer.attr(\"transform\",\"translate(\"+b+\",\"+c+\")\");var b=this.width()-\n2*b,c=this.height()-2*c,d={xAlign:this.xAlignment(),yAlign:this.yAlignment(),textRotation:this.angle()};this._writer.write(this._text,b,c,d);return this};c.prototype.invalidateCache=function(){a.prototype.invalidateCache.call(this);this._measurer.reset()};return c}(d(4).Component);c.Label=a;d=function(a){function c(b,d){b=a.call(this,b,d)||this;b.addClass(c.TITLE_LABEL_CLASS);return b}b(c,a);return c}(a);d.TITLE_LABEL_CLASS=\"title-label\";c.TitleLabel=d;a=function(a){function c(b,d){b=a.call(this,\nb,d)||this;b.addClass(c.AXIS_LABEL_CLASS);return b}b(c,a);return c}(a);a.AXIS_LABEL_CLASS=\"axis-label\";c.AxisLabel=a},function(a,c,d){var b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=null===b?Object.create(b):(c.prototype=b.prototype,new c)},f=d(1),g=d(5),k=d(22),l=d(10),m=d(29),n=d(0);a=d(4);var q=function(){function a(a,b,c){void 0===a&&(a=[]);void 0===b&&(b=0);void 0===c&&(c=Infinity);this.columns=a;this.bottomPadding=\nb;this.maxWidth=c}a.prototype.addColumn=function(a){var b=a.width,c=this.getWidthAvailable();a.width=Math.min(c,b);this.columns.push(a)};a.prototype.getBounds=function(a){for(var b=this.columns[a],c=0,d=0;d<a;d++)c+=this.columns[d].width;return{topLeft:{x:c,y:0},bottomRight:{x:c+b.width,y:b.height}}};a.prototype.getHeight=function(){return n.Math.max(this.columns.map(function(a){return a.height}),0)+this.bottomPadding};a.prototype.getWidth=function(){return Math.min(this.columns.reduce(function(a,\nb){return a+b.width},0),this.maxWidth)};a.prototype.getWidthAvailable=function(){var a=this.getWidth();return Math.max(this.maxWidth-a,0)};return a}(),p=function(){function a(a,b,c,d){void 0===a&&(a=Infinity);void 0===b&&(b=Infinity);void 0===c&&(c=0);void 0===d&&(d=[]);this.maxWidth=a;this.maxHeight=b;this.padding=c;this.rows=d}a.prototype.addRow=function(a){a.maxWidth=this.maxWidth-2*this.padding;this.rows.push(a)};a.prototype.getColumnBounds=function(a,b){var c=this.getRowBounds(a);a=this.rows[a].getBounds(b);\na.topLeft.x+=c.topLeft.x;a.bottomRight.x+=c.topLeft.x;a.topLeft.y+=c.topLeft.y;a.bottomRight.y+=c.topLeft.y;return a};a.prototype.getRowBounds=function(a){for(var b=this.padding,c=this.padding,d=0;d<a;d++)c+=this.rows[d].getHeight();return{topLeft:{x:b,y:c},bottomRight:{x:b+this.rows[a].getWidth(),y:c+this.rows[a].getHeight()}}};a.prototype.getHeight=function(){return Math.min(this.rows.reduce(function(a,b){return a+b.getHeight()},0)+2*this.padding,this.maxHeight)};a.prototype.getWidth=function(){return Math.min(n.Math.max(this.rows.map(function(a){return a.getWidth()}),\n0)+2*this.padding,this.maxWidth)};return a}();a=function(a){function c(b){var c=a.call(this)||this;c._padding=5;c._rowBottomPadding=3;c.addClass(\"legend\");c.maxEntriesPerRow(1);if(null==b)throw Error(\"Legend requires a colorScale\");c._colorScale=b;c._redrawCallback=function(){return c.redraw()};c._colorScale.onUpdate(c._redrawCallback);c._formatter=l.identity();c.maxLinesPerEntry(1);c.xAlignment(\"right\").yAlignment(\"top\");c.comparator(function(a,b){var d=c._colorScale.domain().slice().map(function(a){return c._formatter(a)});\nreturn d.indexOf(a)-d.indexOf(b)});c._symbolFactoryAccessor=function(){return m.circle()};c._symbolOpacityAccessor=function(){return 1};return c}b(c,a);c.prototype._setup=function(){a.prototype._setup.call(this);var b=this.content().append(\"g\").classed(c.LEGEND_ROW_CLASS,!0);b.append(\"g\").classed(c.LEGEND_ENTRY_CLASS,!0).append(\"text\");b=new g.SvgContext(b.node(),null,k.ADD_TITLE_ELEMENTS);this._measurer=new g.Measurer(b);this._wrapper=(new g.Wrapper).maxLines(this.maxLinesPerEntry());this._writer=\nnew g.Writer(this._measurer,b,this._wrapper)};c.prototype.formatter=function(a){if(null==a)return this._formatter;this._formatter=a;this.redraw();return this};c.prototype.maxEntriesPerRow=function(a){if(null==a)return this._maxEntriesPerRow;this._maxEntriesPerRow=a;this.redraw();return this};c.prototype.maxLinesPerEntry=function(a){if(null==a)return this._maxLinesPerEntry;this._maxLinesPerEntry=a;this.redraw();return this};c.prototype.maxWidth=function(a){if(null==a)return this._maxWidth;this._maxWidth=\na;this.redraw();return this};c.prototype.comparator=function(a){null!=a&&(this._comparator=a,this.redraw())};c.prototype.colorScale=function(a){return null!=a?(this._colorScale.offUpdate(this._redrawCallback),this._colorScale=a,this._colorScale.onUpdate(this._redrawCallback),this.redraw(),this):this._colorScale};c.prototype.destroy=function(){a.prototype.destroy.call(this);this._colorScale.offUpdate(this._redrawCallback)};c.prototype._buildLegendTable=function(a,b){var c=this,d=this._measurer.measure().height,\ne=new p(a,b,this._padding);a=this._colorScale.domain().slice().sort(function(a,b){return c._comparator(c._formatter(a),c._formatter(b))});var f=new q;e.addRow(f);f.bottomPadding=this._rowBottomPadding;a.forEach(function(a){f.columns.length/2===c.maxEntriesPerRow()&&(f=new q,f.bottomPadding=c._rowBottomPadding,e.addRow(f));var b=f.getWidthAvailable(),g=c._formatter(a),k=c._measurer.measure(g).width;0>b-d-k&&1<f.columns.length&&(f=new q,f.bottomPadding=c._rowBottomPadding,e.addRow(f));f.addColumn({width:d,\nheight:d,data:{name:a,type:\"symbol\"}});b=f.getWidthAvailable();b=Math.min(b,k);c._wrapper.maxLines(c.maxLinesPerEntry());g=c._wrapper.wrap(g,c._measurer,b).noLines*d;f.addColumn({width:b,height:g,data:{name:a,type:\"text\"}})});return e};c.prototype.requestedSpace=function(a,b){a=this._buildLegendTable(n.Math.min([this.maxWidth(),a],a),b);return{minHeight:a.getHeight(),minWidth:a.getWidth()}};c.prototype.entitiesAt=function(a){var b=this;if(!this._isSetup)return[];var d=this._buildLegendTable(this.width(),\nthis.height());return d.rows.reduce(function(e,g,k){if(0!==e.length)return e;var l=d.getRowBounds(k);return n.Math.within(a,l)?g.columns.reduce(function(e,g,l){var m=d.getColumnBounds(k,l);return n.Math.within(a,m)?(e=b.content().selectAll(\".\"+c.LEGEND_ROW_CLASS).nodes()[k],l=f.select(e).selectAll(\".\"+c.LEGEND_ENTRY_CLASS).nodes()[Math.floor(l/2)],m=f.select(l).select(\".\"+c.LEGEND_SYMBOL_CLASS),e=n.DOM.getTranslateValues(f.select(e)),m=n.DOM.getTranslateValues(m),[{datum:g.data.name,position:{x:e[0]+\nm[0],y:e[1]+m[1]},selection:f.select(l),component:b}]):e},e):e},[])};c.prototype.renderImmediately=function(){a.prototype.renderImmediately.call(this);var b=this._buildLegendTable(this.width(),this.height());this.content().selectAll(\"*\").remove();var d=this.content().selectAll(\"g.\"+c.LEGEND_ROW_CLASS).data(b.rows),e=d.enter().append(\"g\").classed(c.LEGEND_ROW_CLASS,!0).merge(d);d.exit().remove();e.attr(\"transform\",function(a,c){a=b.getRowBounds(c);return\"translate(\"+a.topLeft.x+\", \"+a.topLeft.y+\")\"});\nvar g=this;e.each(function(a,d){for(var e=[],k=0;k<a.columns.length;k+=2)e.push([a.columns[k],a.columns[k+1]]);a=f.select(this).selectAll(\"g.\"+c.LEGEND_ENTRY_CLASS).data(e);e=a.enter().append(\"g\").classed(c.LEGEND_ENTRY_CLASS,!0).merge(a);e.append(\"path\").attr(\"d\",function(a){a=a[0];return g.symbol()(a.data.name,d)(.6*a.height)(null)}).attr(\"transform\",function(a){a=a[0];return\"translate(\"+(b.getColumnBounds(d,b.rows[d].columns.indexOf(a)).topLeft.x+a.width/2)+\", \"+a.height/2+\")\"}).attr(\"fill\",function(a){return g._colorScale.scale(a[0].data.name)}).attr(\"opacity\",\nfunction(a){return g.symbolOpacity()(a[0].data.name,d)}).classed(c.LEGEND_SYMBOL_CLASS,!0);e.append(\"g\").classed(\"text-container\",!0).attr(\"transform\",function(a){return\"translate(\"+b.getColumnBounds(d,b.rows[d].columns.indexOf(a[1])).topLeft.x+\", 0)\"}).each(function(a){var b=f.select(this);a=a[1];g._writer.write(g._formatter(a.data.name),a.width,g.height(),{xAlign:\"left\",yAlign:\"top\",textRotation:0},b.node())});a.exit().remove()});return this};c.prototype.symbol=function(a){if(null==a)return this._symbolFactoryAccessor;\nthis._symbolFactoryAccessor=a;this.render();return this};c.prototype.symbolOpacity=function(){return this._symbolOpacityAccessor};c.prototype.fixedWidth=function(){return!0};c.prototype.fixedHeight=function(){return!0};return c}(a.Component);a.LEGEND_ROW_CLASS=\"legend-row\";a.LEGEND_ENTRY_CLASS=\"legend-entry\";a.LEGEND_SYMBOL_CLASS=\"legend-symbol\";c.Legend=a},function(a,c,d){var b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=\nnull===b?Object.create(b):(c.prototype=b.prototype,new c)},f=d(2),g=d(0);a=function(a){function c(){return null!==a&&a.apply(this,arguments)||this}b(c,a);c.prototype.entityNearest=function(a){var b,c=Infinity;this.components().forEach(function(d){d=d.entityNearest(a);if(null!=d){var e=g.Math.distanceSquared(d.position,a);e<=c&&(c=e,b=d)}});return b};c.prototype.append=function(b){if(null!=b&&!(b instanceof f.Plot))throw Error(\"Plot Group only accepts plots\");a.prototype.append.call(this,b);return this};\nreturn c}(d(38).Group);c.PlotGroup=a},function(a,c,d){var b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=null===b?Object.create(b):(c.prototype=b.prototype,new c)},f=d(1),g=d(0);a=function(a){function c(b){void 0===b&&(b=[]);var c=a.call(this)||this;c._rowPadding=0;c._columnPadding=0;c._rows=[];c._rowWeights=[];c._columnWeights=[];c._nRows=0;c._nCols=0;c._calculatedLayout=null;c.addClass(\"table\");b.forEach(function(a,\nb){a.forEach(function(a,d){null!=a&&c.add(a,b,d)})});return c}b(c,a);c.prototype._forEach=function(a){for(var b=0;b<this._nRows;b++)for(var c=0;c<this._nCols;c++)null!=this._rows[b][c]&&a(this._rows[b][c])};c.prototype.has=function(a){for(var b=0;b<this._nRows;b++)for(var c=0;c<this._nCols;c++)if(this._rows[b][c]===a)return!0;return!1};c.prototype.componentAt=function(a){return 0>=this._nRows||0>a||a>=this._nCols?null:this._rows[0][a]};c.prototype.add=function(a,b,c){if(null==a)throw Error(\"Cannot add null to a table cell\");\nif(!this.has(a)){if(null!=(this._rows[b]&&this._rows[b][c]))throw Error(\"cell is occupied\");a.detach();this._nRows=Math.max(b+1,this._nRows);this._nCols=Math.max(c+1,this._nCols);this._padTableToSize(this._nRows,this._nCols);this._rows[b][c]=a;this._adoptAndAnchor(a);this.redraw()}return this};c.prototype._remove=function(a){for(var b=0;b<this._nRows;b++)for(var c=0;c<this._nCols;c++)if(this._rows[b][c]===a)return this._rows[b][c]=null,!0;return!1};c.prototype._iterateLayout=function(a,b,d){void 0===\nd&&(d=!1);var e=this._rows,k=f.transpose(this._rows);a-=this._columnPadding*(this._nCols-1);b-=this._rowPadding*(this._nRows-1);for(var e=c._calcComponentWeights(this._rowWeights,e,function(a){return null==a||a.fixedHeight()}),k=c._calcComponentWeights(this._columnWeights,k,function(a){return null==a||a.fixedWidth()}),l=k.map(function(a){return 0===a?.5:a}),m=e.map(function(a){return 0===a?.5:a}),l=c._calcProportionalSpace(l,a),n=c._calcProportionalSpace(m,b),q=g.Array.createFilledArray(0,this._nCols),\ny=g.Array.createFilledArray(0,this._nRows),B,A,m=0,D,E,F;;){y=g.Array.add(y,n);l=g.Array.add(q,l);D=this._determineGuarantees(l,y,d);q=D.guaranteedWidths;y=D.guaranteedHeights;E=D.wantsWidthArr.some(function(a){return a});F=D.wantsHeightArr.some(function(a){return a});var I=B,H=A;B=a-f.sum(D.guaranteedWidths);A=b-f.sum(D.guaranteedHeights);l=void 0;E?(l=D.wantsWidthArr.map(function(a){return a?.1:0}),l=g.Array.add(l,k)):l=k;n=void 0;F?(n=D.wantsHeightArr.map(function(a){return a?.1:0}),n=g.Array.add(n,\ne)):n=e;l=c._calcProportionalSpace(l,B);n=c._calcProportionalSpace(n,A);m++;H=0<A&&A!==H;if(!(0<B&&B!==I||H))break;if(5<m)break}B=a-f.sum(D.guaranteedWidths);A=b-f.sum(D.guaranteedHeights);l=c._calcProportionalSpace(k,B);n=c._calcProportionalSpace(e,A);return{colProportionalSpace:l,rowProportionalSpace:n,guaranteedWidths:D.guaranteedWidths,guaranteedHeights:D.guaranteedHeights,wantsWidth:E,wantsHeight:F}};c.prototype._determineGuarantees=function(a,b,c){void 0===c&&(c=!1);var d=g.Array.createFilledArray(0,\nthis._nCols),e=g.Array.createFilledArray(0,this._nRows),f=g.Array.createFilledArray(!1,this._nCols),k=g.Array.createFilledArray(!1,this._nRows);this._rows.forEach(function(g,l){g.forEach(function(g,m){g=null!=g?g.requestedSpace(a[m],b[l]):{minWidth:0,minHeight:0};d[m]=Math.max(d[m],c?Math.min(g.minWidth,a[m]):g.minWidth);e[l]=Math.max(e[l],c?Math.min(g.minHeight,b[l]):g.minHeight);var n=g.minWidth>a[m];f[m]=f[m]||n;m=g.minHeight>b[l];k[l]=k[l]||m})});return{guaranteedWidths:d,guaranteedHeights:e,\nwantsWidthArr:f,wantsHeightArr:k}};c.prototype.requestedSpace=function(a,b){this._calculatedLayout=this._iterateLayout(a,b);return{minWidth:f.sum(this._calculatedLayout.guaranteedWidths),minHeight:f.sum(this._calculatedLayout.guaranteedHeights)}};c.prototype.computeLayout=function(b,c,d){var e=this;a.prototype.computeLayout.call(this,b,c,d);b=f.sum(this._calculatedLayout.guaranteedWidths);c=f.sum(this._calculatedLayout.guaranteedHeights);d=this._calculatedLayout;if(b>this.width()||c>this.height())d=\nthis._iterateLayout(this.width(),this.height(),!0);var k=0,l=g.Array.add(d.rowProportionalSpace,d.guaranteedHeights),m=g.Array.add(d.colProportionalSpace,d.guaranteedWidths);this._rows.forEach(function(a,b){var c=0;a.forEach(function(a,d){null!=a&&a.computeLayout({x:c,y:k},m[d],l[b]);c+=m[d]+e._columnPadding});k+=l[b]+e._rowPadding});return this};c.prototype.rowPadding=function(a){if(null==a)return this._rowPadding;if(!g.Math.isValidNumber(a)||0>a)throw Error(\"rowPadding must be a non-negative finite value\");\nthis._rowPadding=a;this.redraw();return this};c.prototype.columnPadding=function(a){if(null!=a){if(!g.Math.isValidNumber(a)||0>a)throw Error(\"columnPadding must be a non-negative finite value\");this._columnPadding=a;this.redraw()}};c.prototype.rowWeight=function(a,b){if(null==b)return this._rowWeights[a];if(!g.Math.isValidNumber(b)||0>b)throw Error(\"rowWeight must be a non-negative finite value\");this._rowWeights[a]=b;this.redraw();return this};c.prototype.columnWeight=function(a,b){if(null==b)return this._columnWeights[a];\nif(!g.Math.isValidNumber(b)||0>b)throw Error(\"columnWeight must be a non-negative finite value\");this._columnWeights[a]=b;this.redraw();return this};c.prototype.fixedWidth=function(){var a=f.transpose(this._rows);return c._fixedSpace(a,function(a){return null==a||a.fixedWidth()})};c.prototype.fixedHeight=function(){return c._fixedSpace(this._rows,function(a){return null==a||a.fixedHeight()})};c.prototype._padTableToSize=function(a,b){for(var c=0;c<a;c++){void 0===this._rows[c]&&(this._rows[c]=[],\nthis._rowWeights[c]=null);for(var d=0;d<b;d++)void 0===this._rows[c][d]&&(this._rows[c][d]=null)}for(d=0;d<b;d++)void 0===this._columnWeights[d]&&(this._columnWeights[d]=null)};c._calcComponentWeights=function(a,b,c){return a.map(function(a,d){return null!=a?a:b[d].map(c).reduce(function(a,b){return a&&b},!0)?0:1})};c._calcProportionalSpace=function(a,b){var c=f.sum(a);return 0===c?g.Array.createFilledArray(0,a.length):a.map(function(a){return b*a/c})};c._fixedSpace=function(a,b){function c(a){return a.reduce(function(a,\nb){return a&&b},!0)}return c(a.map(function(a){return c(a.map(b))}))};return c}(d(27).ComponentContainer);c.Table=a},function(a,c,d){var b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=null===b?Object.create(b):(c.prototype=b.prototype,new c)};a=function(a){function c(){var b=a.call(this)||this;b.addClass(\"x-drag-box-layer\");b._hasCorners=!1;return b}b(c,a);c.prototype.computeLayout=function(b,c,d){a.prototype.computeLayout.call(this,\nb,c,d);this._setBounds(this.bounds());return this};c.prototype._setBounds=function(b){a.prototype._setBounds.call(this,{topLeft:{x:b.topLeft.x,y:0},bottomRight:{x:b.bottomRight.x,y:this.height()}})};c.prototype._setResizableClasses=function(a){a&&this.enabled()?this.addClass(\"x-resizable\"):this.removeClass(\"x-resizable\")};c.prototype.yScale=function(b){if(null==b)return a.prototype.yScale.call(this);throw Error(\"yScales cannot be set on an XDragBoxLayer\");};c.prototype.yExtent=function(b){if(null==\nb)return a.prototype.yExtent.call(this);throw Error(\"XDragBoxLayer has no yExtent\");};return c}(d(30).DragBoxLayer);c.XDragBoxLayer=a},function(a,c,d){var b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=null===b?Object.create(b):(c.prototype=b.prototype,new c)};a=function(a){function c(){var b=a.call(this)||this;b.addClass(\"y-drag-box-layer\");b._hasCorners=!1;return b}b(c,a);c.prototype.computeLayout=function(b,c,d){a.prototype.computeLayout.call(this,\nb,c,d);this._setBounds(this.bounds());return this};c.prototype._setBounds=function(b){a.prototype._setBounds.call(this,{topLeft:{x:0,y:b.topLeft.y},bottomRight:{x:this.width(),y:b.bottomRight.y}})};c.prototype._setResizableClasses=function(a){a&&this.enabled()?this.addClass(\"y-resizable\"):this.removeClass(\"y-resizable\")};c.prototype.xScale=function(b){if(null==b)return a.prototype.xScale.call(this);throw Error(\"xScales cannot be set on an YDragBoxLayer\");};c.prototype.xExtent=function(b){if(null==\nb)return a.prototype.xExtent.call(this);throw Error(\"YDragBoxLayer has no xExtent\");};return c}(d(30).DragBoxLayer);c.YDragBoxLayer=a},function(a,c,d){var b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=null===b?Object.create(b):(c.prototype=b.prototype,new c)};a=function(a){function c(){var b=a.call(this)||this;b._eventToProcessingFunction[c._KEYDOWN_EVENT_NAME]=function(a){return b._processKeydown(a)};b._eventToProcessingFunction[c._KEYUP_EVENT_NAME]=\nfunction(a){return b._processKeyup(a)};return b}b(c,a);c.getDispatcher=function(){var a=document[c._DISPATCHER_KEY];null==a&&(a=new c,document[c._DISPATCHER_KEY]=a);return a};c.prototype._processKeydown=function(a){this._callCallbacksForEvent(c._KEYDOWN_EVENT_NAME,a.keyCode,a)};c.prototype._processKeyup=function(a){this._callCallbacksForEvent(c._KEYUP_EVENT_NAME,a.keyCode,a)};c.prototype.onKeyDown=function(a){this._addCallbackForEvent(c._KEYDOWN_EVENT_NAME,a)};c.prototype.offKeyDown=function(a){this._removeCallbackForEvent(c._KEYDOWN_EVENT_NAME,\na)};c.prototype.onKeyUp=function(a){this._addCallbackForEvent(c._KEYUP_EVENT_NAME,a)};c.prototype.offKeyUp=function(a){this._removeCallbackForEvent(c._KEYUP_EVENT_NAME,a)};return c}(d(23).Dispatcher);a._DISPATCHER_KEY=\"__Plottable_Dispatcher_Key\";a._KEYDOWN_EVENT_NAME=\"keydown\";a._KEYUP_EVENT_NAME=\"keyup\";c.Key=a},function(a,c,d){var b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=null===b?Object.create(b):(c.prototype=\nb.prototype,new c)},f=d(0);a=function(a){function c(b){function d(a){return e._measureAndDispatch(b,a,c._MOUSEMOVE_EVENT_NAME,\"page\")}var e=a.call(this)||this;e._translator=f.getTranslator(b);e._lastMousePosition={x:-1,y:-1};e._eventToProcessingFunction[c._MOUSEOVER_EVENT_NAME]=d;e._eventToProcessingFunction[c._MOUSEMOVE_EVENT_NAME]=d;e._eventToProcessingFunction[c._MOUSEOUT_EVENT_NAME]=d;e._eventToProcessingFunction[c._MOUSEDOWN_EVENT_NAME]=function(a){return e._measureAndDispatch(b,a,c._MOUSEDOWN_EVENT_NAME)};\ne._eventToProcessingFunction[c._MOUSEUP_EVENT_NAME]=function(a){return e._measureAndDispatch(b,a,c._MOUSEUP_EVENT_NAME,\"page\")};e._eventToProcessingFunction[c._WHEEL_EVENT_NAME]=function(a){return e._measureAndDispatch(b,a,c._WHEEL_EVENT_NAME)};e._eventToProcessingFunction[c._DBLCLICK_EVENT_NAME]=function(a){return e._measureAndDispatch(b,a,c._DBLCLICK_EVENT_NAME)};return e}b(c,a);c.getDispatcher=function(a){var b=a.root().rootElement(),d=b[c._DISPATCHER_KEY];null==d&&(d=new c(a),b[c._DISPATCHER_KEY]=\nd);return d};c.prototype.onMouseMove=function(a){this._addCallbackForEvent(c._MOUSEMOVE_EVENT_NAME,a)};c.prototype.offMouseMove=function(a){this._removeCallbackForEvent(c._MOUSEMOVE_EVENT_NAME,a)};c.prototype.onMouseDown=function(a){this._addCallbackForEvent(c._MOUSEDOWN_EVENT_NAME,a)};c.prototype.offMouseDown=function(a){this._removeCallbackForEvent(c._MOUSEDOWN_EVENT_NAME,a)};c.prototype.onMouseUp=function(a){this._addCallbackForEvent(c._MOUSEUP_EVENT_NAME,a)};c.prototype.offMouseUp=function(a){this._removeCallbackForEvent(c._MOUSEUP_EVENT_NAME,\na)};c.prototype.onWheel=function(a){this._addCallbackForEvent(c._WHEEL_EVENT_NAME,a)};c.prototype.offWheel=function(a){this._removeCallbackForEvent(c._WHEEL_EVENT_NAME,a)};c.prototype.onDblClick=function(a){this._addCallbackForEvent(c._DBLCLICK_EVENT_NAME,a)};c.prototype.offDblClick=function(a){this._removeCallbackForEvent(c._DBLCLICK_EVENT_NAME,a)};c.prototype._measureAndDispatch=function(a,b,c,d){void 0===d&&(d=\"element\");if(\"page\"!==d&&\"element\"!==d)throw Error(\"Invalid scope '\"+d+\"', must be 'element' or 'page'\");\nif(\"page\"===d||this.eventInside(a,b))a=this._translator.computePosition(b.clientX,b.clientY),null!=a&&(this._lastMousePosition=a,this._callCallbacksForEvent(c,this.lastMousePosition(),b))};c.prototype.eventInside=function(a,b){return this._translator.isInside(a,b)};c.prototype.lastMousePosition=function(){return this._lastMousePosition};return c}(d(23).Dispatcher);a._DISPATCHER_KEY=\"__Plottable_Dispatcher_Mouse\";a._MOUSEOVER_EVENT_NAME=\"mouseover\";a._MOUSEMOVE_EVENT_NAME=\"mousemove\";a._MOUSEOUT_EVENT_NAME=\n\"mouseout\";a._MOUSEDOWN_EVENT_NAME=\"mousedown\";a._MOUSEUP_EVENT_NAME=\"mouseup\";a._WHEEL_EVENT_NAME=\"wheel\";a._DBLCLICK_EVENT_NAME=\"dblclick\";c.Mouse=a},function(a,c,d){var b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=null===b?Object.create(b):(c.prototype=b.prototype,new c)},f=d(0);a=function(a){function c(b){var d=a.call(this)||this;d._translator=f.getTranslator(b);d._eventToProcessingFunction[c._TOUCHSTART_EVENT_NAME]=\nfunction(a){return d._measureAndDispatch(b,a,c._TOUCHSTART_EVENT_NAME,\"page\")};d._eventToProcessingFunction[c._TOUCHMOVE_EVENT_NAME]=function(a){return d._measureAndDispatch(b,a,c._TOUCHMOVE_EVENT_NAME,\"page\")};d._eventToProcessingFunction[c._TOUCHEND_EVENT_NAME]=function(a){return d._measureAndDispatch(b,a,c._TOUCHEND_EVENT_NAME,\"page\")};d._eventToProcessingFunction[c._TOUCHCANCEL_EVENT_NAME]=function(a){return d._measureAndDispatch(b,a,c._TOUCHCANCEL_EVENT_NAME,\"page\")};return d}b(c,a);c.getDispatcher=\nfunction(a){var b=a.root().rootElement(),d=b[c._DISPATCHER_KEY];null==d&&(d=new c(a),b[c._DISPATCHER_KEY]=d);return d};c.prototype.onTouchStart=function(a){this._addCallbackForEvent(c._TOUCHSTART_EVENT_NAME,a)};c.prototype.offTouchStart=function(a){this._removeCallbackForEvent(c._TOUCHSTART_EVENT_NAME,a)};c.prototype.onTouchMove=function(a){this._addCallbackForEvent(c._TOUCHMOVE_EVENT_NAME,a)};c.prototype.offTouchMove=function(a){this._removeCallbackForEvent(c._TOUCHMOVE_EVENT_NAME,a)};c.prototype.onTouchEnd=\nfunction(a){this._addCallbackForEvent(c._TOUCHEND_EVENT_NAME,a)};c.prototype.offTouchEnd=function(a){this._removeCallbackForEvent(c._TOUCHEND_EVENT_NAME,a)};c.prototype.onTouchCancel=function(a){this._addCallbackForEvent(c._TOUCHCANCEL_EVENT_NAME,a)};c.prototype.offTouchCancel=function(a){this._removeCallbackForEvent(c._TOUCHCANCEL_EVENT_NAME,a)};c.prototype._measureAndDispatch=function(a,b,c,d){void 0===d&&(d=\"element\");if(\"page\"!==d&&\"element\"!==d)throw Error(\"Invalid scope '\"+d+\"', must be 'element' or 'page'\");\nif(\"element\"!==d||this.eventInside(a,b)){a=b.changedTouches;d={};for(var e=[],f=0;f<a.length;f++){var g=a[f],k=g.identifier,g=this._translator.computePosition(g.clientX,g.clientY);null!=g&&(d[k]=g,e.push(k))}0<e.length&&this._callCallbacksForEvent(c,e,d,b)}};c.prototype.eventInside=function(a,b){return this._translator.isInside(a,b)};return c}(d(23).Dispatcher);a._DISPATCHER_KEY=\"__Plottable_Dispatcher_Touch\";a._TOUCHSTART_EVENT_NAME=\"touchstart\";a._TOUCHMOVE_EVENT_NAME=\"touchmove\";a._TOUCHEND_EVENT_NAME=\n\"touchend\";a._TOUCHCANCEL_EVENT_NAME=\"touchcancel\";c.Touch=a},function(a,c){a=function(){function a(b,c,d){void 0===d&&(d=window.devicePixelRatio);this.screenWidth=b;this.screenHeight=c;this.devicePixelRatio=d;this.pixelWidth=b*d;this.pixelHeight=c*d;this.canvas=document.createElement(\"canvas\");this.ctx=this.canvas.getContext(\"2d\");a.sizePixels(this.ctx,b,c,d)}a.sizePixels=function(a,b,c,d){var e=a.canvas;e.width=b*d;e.height=c*d;e.style.width=b+\"px\";e.style.height=c+\"px\";a.setTransform(1,0,0,1,0,\n0);a.scale(d,d)};a.prototype.blit=function(a,b,c){void 0===b&&(b=0);void 0===c&&(c=0);a.drawImage(this.canvas,b,c,this.screenWidth,this.screenHeight)};a.prototype.blitCenter=function(a,b,c){void 0===b&&(b=0);void 0===c&&(c=0);this.blit(a,Math.floor(b-this.screenWidth/2),Math.floor(c-this.screenHeight/2))};a.prototype.resize=function(b,c,d){void 0===d&&(d=!1);var e=this.devicePixelRatio;this.screenWidth=b;this.screenHeight=c;this.pixelWidth=b*e;this.pixelHeight=c*e;a.sizePixels(this.ctx,b,c,e);d&&\nthis.ctx.translate(b/2,b/2);return this};a.prototype.clear=function(a){var b=this.pixelWidth,c=this.pixelHeight,d=this.ctx;d.save();d.setTransform(1,0,0,1,0,0);null==a?d.clearRect(0,0,b,c):(d.fillStyle=a,d.fillRect(0,0,b,c));d.restore();return this};a.prototype.getImageData=function(){return this.ctx.getImageData(0,0,this.pixelWidth,this.pixelHeight)};return a}();c.CanvasBuffer=a},function(a,c,d){var b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&\n(a[d]=b[d]);a.prototype=null===b?Object.create(b):(c.prototype=b.prototype,new c)},f=d(13),g=d(0);a=function(a){function c(){var b=null!==a&&a.apply(this,arguments)||this;b._clickedDown=!1;b._doubleClicking=!1;b._onClickCallbacks=new g.CallbackSet;b._onDoubleClickCallbacks=new g.CallbackSet;b._mouseDownCallback=function(a){return b._handleClickDown(a)};b._mouseUpCallback=function(a,c){return b._handleClickUp(a,c)};b._dblClickCallback=function(a,c){return b._handleDblClick(a,c)};b._touchStartCallback=\nfunction(a,c){return b._handleClickDown(c[a[0]])};b._touchEndCallback=function(a,c,d){return b._handleClickUp(c[a[0]],d)};b._touchCancelCallback=function(){return b._clickedDown=!1};return b}b(c,a);c.prototype._anchor=function(b){a.prototype._anchor.call(this,b);this._mouseDispatcher=f.Mouse.getDispatcher(b);this._mouseDispatcher.onMouseDown(this._mouseDownCallback);this._mouseDispatcher.onMouseUp(this._mouseUpCallback);this._mouseDispatcher.onDblClick(this._dblClickCallback);this._touchDispatcher=\nf.Touch.getDispatcher(b);this._touchDispatcher.onTouchStart(this._touchStartCallback);this._touchDispatcher.onTouchEnd(this._touchEndCallback);this._touchDispatcher.onTouchCancel(this._touchCancelCallback)};c.prototype._unanchor=function(){a.prototype._unanchor.call(this);this._mouseDispatcher.offMouseDown(this._mouseDownCallback);this._mouseDispatcher.offMouseUp(this._mouseUpCallback);this._mouseDispatcher.offDblClick(this._dblClickCallback);this._mouseDispatcher=null;this._touchDispatcher.offTouchStart(this._touchStartCallback);\nthis._touchDispatcher.offTouchEnd(this._touchEndCallback);this._touchDispatcher.offTouchCancel(this._touchCancelCallback);this._touchDispatcher=null};c.prototype._handleClickDown=function(a){a=this._translateToComponentSpace(a);this._isInsideComponent(a)&&(this._clickedDown=!0,this._clickedPoint=a)};c.prototype._handleClickUp=function(a,b){var d=this,e=this._translateToComponentSpace(a);this._clickedDown&&c._pointsEqual(e,this._clickedPoint)&&setTimeout(function(){d._doubleClicking||d._onClickCallbacks.callCallbacks(e,\nb)},0);this._clickedDown=!1};c.prototype._handleDblClick=function(a,b){var c=this;a=this._translateToComponentSpace(a);this._doubleClicking=!0;this._onDoubleClickCallbacks.callCallbacks(a,b);setTimeout(function(){return c._doubleClicking=!1},0)};c._pointsEqual=function(a,b){return a.x===b.x&&a.y===b.y};c.prototype.onClick=function(a){this._onClickCallbacks.add(a)};c.prototype.offClick=function(a){this._onClickCallbacks.delete(a)};c.prototype.onDoubleClick=function(a){this._onDoubleClickCallbacks.add(a);\nreturn this};c.prototype.offDoubleClick=function(a){this._onDoubleClickCallbacks.delete(a);return this};return c}(d(15).Interaction);c.Click=a},function(a,c,d){var b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=null===b?Object.create(b):(c.prototype=b.prototype,new c)},f=d(13),g=d(0);a=function(a){function c(){var b=null!==a&&a.apply(this,arguments)||this;b._dragging=!1;b._constrainedToComponent=!0;b._dragStartCallbacks=\nnew g.CallbackSet;b._dragCallbacks=new g.CallbackSet;b._dragEndCallbacks=new g.CallbackSet;b._mouseDownCallback=function(a,c){return b._startDrag(a,c)};b._mouseMoveCallback=function(a){return b._doDrag(a)};b._mouseUpCallback=function(a,c){return b._endDrag(a,c)};b._touchStartCallback=function(a,c,d){return b._startDrag(c[a[0]],d)};b._touchMoveCallback=function(a,c){return b._doDrag(c[a[0]])};b._touchEndCallback=function(a,c,d){return b._endDrag(c[a[0]],d)};return b}b(c,a);c.prototype._anchor=function(b){a.prototype._anchor.call(this,\nb);this._mouseDispatcher=f.Mouse.getDispatcher(this._componentAttachedTo);this._mouseDispatcher.onMouseDown(this._mouseDownCallback);this._mouseDispatcher.onMouseMove(this._mouseMoveCallback);this._mouseDispatcher.onMouseUp(this._mouseUpCallback);this._touchDispatcher=f.Touch.getDispatcher(this._componentAttachedTo);this._touchDispatcher.onTouchStart(this._touchStartCallback);this._touchDispatcher.onTouchMove(this._touchMoveCallback);this._touchDispatcher.onTouchEnd(this._touchEndCallback)};c.prototype._unanchor=\nfunction(){a.prototype._unanchor.call(this);this._mouseDispatcher.offMouseDown(this._mouseDownCallback);this._mouseDispatcher.offMouseMove(this._mouseMoveCallback);this._mouseDispatcher.offMouseUp(this._mouseUpCallback);this._mouseDispatcher=null;this._touchDispatcher.offTouchStart(this._touchStartCallback);this._touchDispatcher.offTouchMove(this._touchMoveCallback);this._touchDispatcher.offTouchEnd(this._touchEndCallback);this._touchDispatcher=null};c.prototype._translateAndConstrain=function(a){a=\nthis._translateToComponentSpace(a);return this._constrainedToComponent?{x:g.Math.clamp(a.x,0,this._componentAttachedTo.width()),y:g.Math.clamp(a.y,0,this._componentAttachedTo.height())}:a};c.prototype._startDrag=function(a,b){b instanceof MouseEvent&&0!==b.button||(a=this._translateToComponentSpace(a),this._isInsideComponent(a)&&(b.preventDefault(),this._dragging=!0,this._dragOrigin=a,this._dragStartCallbacks.callCallbacks(this._dragOrigin)))};c.prototype._doDrag=function(a){this._dragging&&this._dragCallbacks.callCallbacks(this._dragOrigin,\nthis._translateAndConstrain(a))};c.prototype._endDrag=function(a,b){b instanceof MouseEvent&&0!==b.button||!this._dragging||(this._dragging=!1,this._dragEndCallbacks.callCallbacks(this._dragOrigin,this._translateAndConstrain(a)))};c.prototype.constrainedToComponent=function(){this._constrainedToComponent=!1};c.prototype.onDragStart=function(a){this._dragStartCallbacks.add(a);return this};c.prototype.offDragStart=function(a){this._dragStartCallbacks.delete(a);return this};c.prototype.onDrag=function(a){this._dragCallbacks.add(a);\nreturn this};c.prototype.offDrag=function(a){this._dragCallbacks.delete(a);return this};c.prototype.onDragEnd=function(a){this._dragEndCallbacks.add(a);return this};c.prototype.offDragEnd=function(a){this._dragEndCallbacks.delete(a);return this};return c}(d(15).Interaction);c.Drag=a},function(a,c,d){function b(a,b,c){return c-(c-a)*b}var f=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=null===b?Object.create(b):(c.prototype=\nb.prototype,new c)},g=d(1),k=d(13),l=d(3),m=d(0),n=d(14);a=d(15);c.zoomAt=b;a=function(a){function c(b,c){var d=a.call(this)||this;d._wheelCallback=function(a,b){return d._handleWheelEvent(a,b)};d._touchStartCallback=function(a,b){return d._handleTouchStart(a,b)};d._touchMoveCallback=function(a,b){return d._handlePinch(a,b)};d._touchEndCallback=function(a){return d._handleTouchEnd(a)};d._touchCancelCallback=function(a){return d._handleTouchEnd(a)};d._panEndCallbacks=new m.CallbackSet;d._zoomEndCallbacks=\nnew m.CallbackSet;d._xScales=new m.Set;d._yScales=new m.Set;d._dragInteraction=new n.Drag;d._setupDragInteraction();d._touchIds=g.map();d._minDomainExtents=new m.Map;d._maxDomainExtents=new m.Map;d._minDomainValues=new m.Map;d._maxDomainValues=new m.Map;null!=b&&d.addXScale(b);null!=c&&d.addYScale(c);return d}f(c,a);c.prototype.pan=function(a){var b=this;this.xScales().forEach(function(c){c.pan(b._constrainedTranslation(c,a.x))});this.yScales().forEach(function(c){c.pan(b._constrainedTranslation(c,\na.y))})};c.prototype.zoom=function(a,b){this.xScales().forEach(function(c){var d=c.range();c.zoom(a,void 0===b?(d[1]-d[0])/2:b.x)});this.yScales().forEach(function(c){var d=c.range();c.zoom(a,void 0===b?(d[1]-d[0])/2:b.y)})};c.prototype._anchor=function(b){a.prototype._anchor.call(this,b);this._dragInteraction.attachTo(b);this._mouseDispatcher=k.Mouse.getDispatcher(this._componentAttachedTo);this._mouseDispatcher.onWheel(this._wheelCallback);this._touchDispatcher=k.Touch.getDispatcher(this._componentAttachedTo);\nthis._touchDispatcher.onTouchStart(this._touchStartCallback);this._touchDispatcher.onTouchMove(this._touchMoveCallback);this._touchDispatcher.onTouchEnd(this._touchEndCallback);this._touchDispatcher.onTouchCancel(this._touchCancelCallback)};c.prototype._unanchor=function(){a.prototype._unanchor.call(this);this._mouseDispatcher.offWheel(this._wheelCallback);this._mouseDispatcher=null;this._touchDispatcher.offTouchStart(this._touchStartCallback);this._touchDispatcher.offTouchMove(this._touchMoveCallback);\nthis._touchDispatcher.offTouchEnd(this._touchEndCallback);this._touchDispatcher.offTouchCancel(this._touchCancelCallback);this._touchDispatcher=null;this._dragInteraction.detachFrom()};c.prototype._handleTouchStart=function(a,b){for(var c=0;c<a.length&&2>this._touchIds.size();c++){var d=a[c];this._touchIds.set(d.toString(),this._translateToComponentSpace(b[d]))}};c.prototype._handlePinch=function(a,b){var d=this;if(!(2>this._touchIds.size())){var e=this._touchIds.values();if(this._isInsideComponent(this._translateToComponentSpace(e[0]))&&\nthis._isInsideComponent(this._translateToComponentSpace(e[1]))){var f=c._pointDistance(e[0],e[1]);if(0!==f){a.forEach(function(a){d._touchIds.has(a.toString())&&d._touchIds.set(a.toString(),d._translateToComponentSpace(b[a]))});a=this._touchIds.values();var g=c._pointDistance(a[0],a[1]);if(0!==g){var k=f/g,l=a.map(function(a,b){return{x:(a.x-e[b].x)/k,y:(a.y-e[b].y)/k}}),f=c.centerPoint(e[0],e[1]),m=f.x,n=f.y;this.xScales().forEach(function(a){a=d._constrainedZoom(a,k,m);m=a.centerPoint;k=a.zoomAmount});\nthis.yScales().forEach(function(a){a=d._constrainedZoom(a,k,n);n=a.centerPoint;k=a.zoomAmount});f=e.map(function(a,b){return{x:l[b].x*k+a.x,y:l[b].y*k+a.y}});f={x:m-(f[0].x+f[1].x)/2,y:n-(f[0].y+f[1].y)/2};this.zoom(k,{x:m,y:n});this.pan(f)}}}}};c.centerPoint=function(a,b){return{x:(Math.min(a.x,b.x)+Math.max(a.x,b.x))/2,y:(Math.max(a.y,b.y)+Math.min(a.y,b.y))/2}};c._pointDistance=function(a,b){return Math.sqrt(Math.pow(Math.max(a.x,b.x)-Math.min(a.x,b.x),2)+Math.pow(Math.max(a.y,b.y)-Math.min(a.y,\nb.y),2))};c.prototype._handleTouchEnd=function(a){var b=this;a.forEach(function(a){b._touchIds.remove(a.toString())});0<this._touchIds.size()&&this._zoomEndCallbacks.callCallbacks()};c.prototype._handleWheelEvent=function(a,b){var d=this;a=this._translateToComponentSpace(a);if(this._isInsideComponent(a)){b.preventDefault();var e=Math.pow(2,b.deltaY*(b.deltaMode?c._PIXELS_PER_LINE:1)*.002),f=a.x,g=a.y;this.xScales().forEach(function(a){a=d._constrainedZoom(a,e,f);f=a.centerPoint;e=a.zoomAmount});this.yScales().forEach(function(a){a=\nd._constrainedZoom(a,e,g);g=a.centerPoint;e=a.zoomAmount});this.zoom(e,{x:f,y:g});this._zoomEndCallbacks.callCallbacks()}};c.prototype._isRangeReversed=function(a){a=a.range();return a[1]<a[0]};c.prototype._constrainedZoom=function(a,b,c){b=this._constrainZoomExtents(a,b);return this._constrainZoomValues(a,b,c)};c.prototype._constrainZoomExtents=function(a,b){var c=1<b,d=c?this.maxDomainExtent(a):this.minDomainExtent(a);if(null==d)return b;a=a.getTransformationDomain();return(c?Math.min:Math.max)(b,\nd/Math.abs(a[1]-a[0]))};c.prototype._constrainZoomValues=function(a,c,d){if(1>=c)return{centerPoint:d,zoomAmount:c};var e=this._isRangeReversed(a),f=this.minDomainValue(a),g=this.maxDomainValue(a);if(null==f&&null==g)return{centerPoint:d,zoomAmount:c};var k=a.getTransformationDomain();var l=k[0],m=k[1];if(null!=g){var n=a.scaleTransformation(g);var q=a.scaleTransformation(m);var p=b(q,c,d);p>n!=e&&(d=this._getZoomCenterForTarget(q,c,n))}if(null!=f){var r=a.scaleTransformation(f);k=a.scaleTransformation(l);\nvar t=b(k,c,d);t<r!=e&&(d=this._getZoomCenterForTarget(k,c,r))}null!=g&&null!=g&&(n=a.scaleTransformation(g),q=a.scaleTransformation(m),p=b(q,c,d),r=a.scaleTransformation(f),k=a.scaleTransformation(l),t=b(k,c,d),p>n!=e||t<r!=e)&&(a=q-k+r-n,0===a?(d=(q+k)/2,c=1):(d=(q*r-k*n)/a,c=(n-r)/(q-k)));return{centerPoint:d,zoomAmount:c}};c.prototype._getZoomCenterForTarget=function(a,b,c){return(a*b-c)/(b-1)};c.prototype._setupDragInteraction=function(){var a=this;this._dragInteraction.constrainedToComponent();\nvar b;this._dragInteraction.onDragStart(function(){return b=null});this._dragInteraction.onDrag(function(c,d){2<=a._touchIds.size()||(a.pan({x:(null==b?c.x:b.x)-d.x,y:(null==b?c.y:b.y)-d.y}),b=d)});this._dragInteraction.onDragEnd(function(){return a._panEndCallbacks.callCallbacks()})};c.prototype._constrainedTranslation=function(a,b){var c=a.getTransformationDomain(),d=c[0],e=c[1],c=this._isRangeReversed(a);if(0<b!==c){var f=this.maxDomainValue(a);null!=f&&(d=a.scaleTransformation(e),a=a.scaleTransformation(f),\nb=(c?Math.max:Math.min)(d+b,a)-d)}else f=this.minDomainValue(a),null!=f&&(d=a.scaleTransformation(d),a=a.scaleTransformation(f),b=(c?Math.min:Math.max)(d+b,a)-d);return b};c.prototype._nonLinearScaleWithExtents=function(a){return null!=this.minDomainExtent(a)&&null!=this.maxDomainExtent(a)&&!(a instanceof l.Linear)&&!(a instanceof l.Time)};c.prototype.xScales=function(){var a=[];this._xScales.forEach(function(b){a.push(b)});return a};c.prototype.yScales=function(){var a=[];this._yScales.forEach(function(b){a.push(b)});\nreturn a};c.prototype.addXScale=function(a){this._xScales.add(a)};c.prototype.removeXScale=function(a){this._xScales.delete(a);this._minDomainExtents.delete(a);this._maxDomainExtents.delete(a);this._minDomainValues.delete(a);this._maxDomainValues.delete(a);return this};c.prototype.addYScale=function(a){this._yScales.add(a)};c.prototype.removeYScale=function(a){this._yScales.delete(a);this._minDomainExtents.delete(a);this._maxDomainExtents.delete(a);this._minDomainValues.delete(a);this._maxDomainValues.delete(a);\nreturn this};c.prototype.minDomainExtent=function(a){return this._minDomainExtents.get(a)};c.prototype.maxDomainExtent=function(a){return this._maxDomainExtents.get(a)};c.prototype.minDomainValue=function(a,b){if(null==b)return this._minDomainValues.get(a);this._minDomainValues.set(a,b);return this};c.prototype.maxDomainValue=function(a,b){if(null==b)return this._maxDomainValues.get(a);this._maxDomainValues.set(a,b);return this};c.prototype.setMinMaxDomainValuesTo=function(a){this._minDomainValues.delete(a);\nthis._maxDomainValues.delete(a);var b=a.getTransformationDomain(),c=b[1];this.minDomainValue(a,b[0]);this.maxDomainValue(a,c);return this};c.prototype.onPanEnd=function(a){this._panEndCallbacks.add(a);return this};c.prototype.offPanEnd=function(a){this._panEndCallbacks.delete(a);return this};c.prototype.onZoomEnd=function(a){this._zoomEndCallbacks.add(a);return this};c.prototype.offZoomEnd=function(a){this._zoomEndCallbacks.delete(a);return this};return c}(a.Interaction);a._PIXELS_PER_LINE=120;c.PanZoom=\na},function(a,c,d){var b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=null===b?Object.create(b):(c.prototype=b.prototype,new c)},f=d(13),g=d(0);a=function(a){function c(){var b=null!==a&&a.apply(this,arguments)||this;b._overComponent=!1;b._pointerEnterCallbacks=new g.CallbackSet;b._pointerMoveCallbacks=new g.CallbackSet;b._pointerExitCallbacks=new g.CallbackSet;b._mouseMoveCallback=function(a,c){return b._handleMouseEvent(a,\nc)};b._touchStartCallback=function(a,c,d){return b._handleTouchEvent(c[a[0]],d)};return b}b(c,a);c.prototype._anchor=function(b){a.prototype._anchor.call(this,b);this._mouseDispatcher=f.Mouse.getDispatcher(this._componentAttachedTo);this._mouseDispatcher.onMouseMove(this._mouseMoveCallback);this._touchDispatcher=f.Touch.getDispatcher(this._componentAttachedTo);this._touchDispatcher.onTouchStart(this._touchStartCallback)};c.prototype._unanchor=function(){a.prototype._unanchor.call(this);this._mouseDispatcher.offMouseMove(this._mouseMoveCallback);\nthis._mouseDispatcher=null;this._touchDispatcher.offTouchStart(this._touchStartCallback);this._touchDispatcher=null};c.prototype._handleMouseEvent=function(a,b){b=this._mouseDispatcher.eventInside(this._componentAttachedTo,b);this._handlePointerEvent(a,b)};c.prototype._handleTouchEvent=function(a,b){b=this._touchDispatcher.eventInside(this._componentAttachedTo,b);this._handlePointerEvent(a,b)};c.prototype._handlePointerEvent=function(a,b){a=this._translateToComponentSpace(a);var c=this._isInsideComponent(a);\nc&&b?(this._overComponent||this._pointerEnterCallbacks.callCallbacks(a),this._pointerMoveCallbacks.callCallbacks(a)):this._overComponent&&this._pointerExitCallbacks.callCallbacks(a);this._overComponent=c&&b};c.prototype.onPointerEnter=function(a){this._pointerEnterCallbacks.add(a);return this};c.prototype.offPointerEnter=function(a){this._pointerEnterCallbacks.delete(a);return this};c.prototype.onPointerMove=function(a){this._pointerMoveCallbacks.add(a)};c.prototype.offPointerMove=function(a){this._pointerMoveCallbacks.delete(a)};\nc.prototype.onPointerExit=function(a){this._pointerExitCallbacks.add(a)};c.prototype.offPointerExit=function(a){this._pointerExitCallbacks.delete(a);return this};return c}(d(15).Interaction);c.Pointer=a},function(a,c,d){var b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=null===b?Object.create(b):(c.prototype=b.prototype,new c)},f=d(3),g=d(0);a=d(24);var k=d(2);d=function(a){function c(b){void 0===b&&(b=\"vertical\");\nb=a.call(this,b)||this;b._clusterOffsets=new g.Map;return b}b(c,a);c.prototype._generateAttrToProjector=function(){function b(){return e.rangeBand()}var c=this,d=a.prototype._generateAttrToProjector.call(this),e=this._makeInnerScale();d.width=this._isVertical?b:d.width;d.height=this._isVertical?d.height:b;var f=d.x,g=d.y;d.x=this._isVertical?function(a,b,d){return f(a,b,d)+c._clusterOffsets.get(d)}:function(a,b,c){return f(a,b,c)};d.y=this._isVertical?function(a,b,c){return g(a,b,c)}:function(a,b,\nd){return g(a,b,d)+c._clusterOffsets.get(d)};return d};c.prototype._updateClusterPosition=function(){var a=this,b=this._makeInnerScale();this.datasets().forEach(function(c,d){return a._clusterOffsets.set(c,b.scale(String(d))-b.rangeBand()/2)})};c.prototype._makeInnerScale=function(){var a=new f.Category;a.domain(this.datasets().map(function(a,b){return String(b)}));var b=k.Plot._scaledAccessor(this.attr(\"width\"));a.range([0,b(null,0,null)]);return a};c.prototype._getDataToDraw=function(){this._updateClusterPosition();\nreturn a.prototype._getDataToDraw.call(this)};return c}(a.Bar);c.ClusteredBar=d},function(a,c,d){var b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=null===b?Object.create(b):(c.prototype=b.prototype,new c)},f=d(1),g=d(5),k=d(7),l=d(10),m=d(3),n=d(0),q=d(41),p=d(42),t=d(6),r=d(25),v=d(2);a=function(a){function c(){var b=a.call(this)||this;b._startAngle=0;b._endAngle=2*Math.PI;b._labelFormatter=l.identity();b._labelsEnabled=\n!1;b.innerRadius(0);b.outerRadius(function(){var a=b._pieCenter();return Math.min(Math.max(b.width()-a.x,a.x),Math.max(b.height()-a.y,a.y))});b.addClass(\"pie-plot\");b.attr(\"fill\",function(a,b){return String(b)},new m.Color);b._strokeDrawers=new n.Map;return b}b(c,a);c.prototype._setup=function(){var b=this;a.prototype._setup.call(this);this._strokeDrawers.forEach(function(a){return a.attachTo(b._renderArea)})};c.prototype.computeLayout=function(b,c,d){a.prototype.computeLayout.call(this,b,c,d);b=\nthis._pieCenter();this._renderArea.attr(\"transform\",\"translate(\"+b.x+\",\"+b.y+\")\");b=Math.min(Math.max(this.width()-b.x,b.x),Math.max(this.height()-b.y,b.y));null!=this.innerRadius().scale&&this.innerRadius().scale.range([0,b]);null!=this.outerRadius().scale&&this.outerRadius().scale.range([0,b]);return this};c.prototype.addDataset=function(b){a.prototype.addDataset.call(this,b);return this};c.prototype._addDataset=function(b){if(1===this.datasets().length)return n.Window.warn(\"Only one dataset is supported in Pie plots\"),\nthis;this._updatePieAngles();var c=new p.ArcOutlineSVGDrawer;this._isSetup&&c.attachTo(this._renderArea);this._strokeDrawers.set(b,c);a.prototype._addDataset.call(this,b);return this};c.prototype.removeDataset=function(b){a.prototype.removeDataset.call(this,b);return this};c.prototype._removeDatasetNodes=function(b){a.prototype._removeDatasetNodes.call(this,b);this._strokeDrawers.get(b).remove()};c.prototype._removeDataset=function(b){a.prototype._removeDataset.call(this,b);this._startAngles=[];this._endAngles=\n[];return this};c.prototype.selections=function(b){var c=this;void 0===b&&(b=this.datasets());var d=a.prototype.selections.call(this,b).nodes();b.forEach(function(a){a=c._strokeDrawers.get(a);null!=a&&d.push.apply(d,a.getVisualPrimitives())});return f.selectAll(d)};c.prototype._onDatasetUpdate=function(){a.prototype._onDatasetUpdate.call(this);this._updatePieAngles();this.render()};c.prototype._createDrawer=function(){return new t.ProxyDrawer(function(){return new q.ArcSVGDrawer},function(){r.warn(\"canvas renderer is not supported on Pie Plot!\")})};\nc.prototype.entities=function(b){var c=this;void 0===b&&(b=this.datasets());return a.prototype.entities.call(this,b).map(function(a){a.position.x+=c.width()/2;a.position.y+=c.height()/2;var b=f.select(c._strokeDrawers.get(a.dataset).getVisualPrimitiveAtIndex(a.index));a.strokeSelection=b;return a})};c.prototype.sectorValue=function(){return this._propertyBindings.get(c._SECTOR_VALUE_KEY)};c.prototype.innerRadius=function(a,b){if(null==a)return this._propertyBindings.get(c._INNER_RADIUS_KEY);this._bindProperty(c._INNER_RADIUS_KEY,\na,b);this.render();return this};c.prototype.outerRadius=function(a,b){if(null==a)return this._propertyBindings.get(c._OUTER_RADIUS_KEY);this._bindProperty(c._OUTER_RADIUS_KEY,a,b);this.render();return this};c.prototype.startAngle=function(a){if(null==a)return this._startAngle;this._startAngle=a;this._updatePieAngles();this.render();return this};c.prototype.endAngle=function(a){if(null==a)return this._endAngle;this._endAngle=a;this._updatePieAngles();this.render();return this};c.prototype.labelsEnabled=\nfunction(a){if(null==a)return this._labelsEnabled;this._labelsEnabled=a;this.render();return this};c.prototype.labelFormatter=function(a){if(null==a)return this._labelFormatter;this._labelFormatter=a;this.render();return this};c.prototype.entitiesAt=function(a){var b=this.width()/2,c=this.height()/2;a=this._sliceIndexForPoint({x:a.x-b,y:a.y-c});return null==a?[]:[this.entities()[a]]};c.prototype._propertyProjectors=function(){var b=this,c=a.prototype._propertyProjectors.call(this),d=v.Plot._scaledAccessor(this.innerRadius()),\ne=v.Plot._scaledAccessor(this.outerRadius());c.d=function(a,c,g){return f.arc().innerRadius(d(a,c,g)).outerRadius(e(a,c,g)).startAngle(b._startAngles[c]).endAngle(b._endAngles[c])(a,c)};return c};c.prototype._updatePieAngles=function(){if(null!=this.sectorValue()&&0!==this.datasets().length){var a=v.Plot._scaledAccessor(this.sectorValue()),b=this.datasets()[0],c=this._getDataToDraw().get(b),c=f.pie().sort(null).startAngle(this._startAngle).endAngle(this._endAngle).value(function(c,d){return a(c,d,\nb)})(c);this._startAngles=c.map(function(a){return a.startAngle});this._endAngles=c.map(function(a){return a.endAngle})}};c.prototype._pieCenter=function(){var a=this._startAngle<this._endAngle?this._startAngle:this._endAngle,b=this._startAngle<this._endAngle?this._endAngle:this._startAngle,c=Math.sin(a),a=Math.cos(a),d=Math.sin(b),b=Math.cos(b),e;if(0<=c&&0<=d)if(0<=a&&0<=b){var f=a;var g=e=0;var k=d}else 0>a&&0>b?(f=0,e=-b,g=0,k=c):0<=a&&0>b?(f=a,e=-b,g=0,k=c):0>a&&0<=b&&(g=e=f=1,k=Math.max(c,d));\nelse 0<=c&&0>d?0<=a&&0<=b?(f=Math.max(a,b),k=g=e=1):0>a&&0>b?(f=0,e=1,g=-d,k=c):0<=a&&0>b?(f=a,e=1,g=-d,k=1):0>a&&0<=b&&(f=b,g=e=1,k=c):0>c&&0<=d?0<=a&&0<=b?(f=1,e=0,g=-c,k=d):0>a&&0>b?(f=1,e=Math.max(-a,-b),k=g=1):0<=a&&0>b?(f=1,e=-b,g=-c,k=1):0>a&&0<=b&&(f=1,e=-a,g=1,k=d):0>c&&0>d&&(0<=a&&0<=b?(f=b,e=0,g=-c,k=0):0>a&&0>b?(f=0,e=-a,g=-d,k=0):0<=a&&0>b?(e=f=1,g=Math.max(a,-b),k=1):0>a&&0<=b&&(f=b,e=-a,g=1,k=0));return{x:0==g+k?0:g/(g+k)*this.width(),y:0==f+e?0:f/(f+e)*this.height()}};c.prototype._getDataToDraw=\nfunction(){var b=a.prototype._getDataToDraw.call(this);if(0===this.datasets().length)return b;var d=v.Plot._scaledAccessor(this.sectorValue()),e=this.datasets()[0],f=b.get(e).filter(function(a,b){return c._isValidData(d(a,b,e))});b.set(e,f);return b};c._isValidData=function(a){return n.Math.isValidNumber(a)&&0<=a};c.prototype._pixelPoint=function(a,b,d){var e=v.Plot._scaledAccessor(this.sectorValue());if(!c._isValidData(e(a,b,d)))return{x:NaN,y:NaN};var g=v.Plot._scaledAccessor(this.innerRadius())(a,\nb,d);a=v.Plot._scaledAccessor(this.outerRadius())(a,b,d);g=(g+a)/2;a=f.pie().sort(null).value(function(a,b){a=e(a,b,d);return c._isValidData(a)?a:0}).startAngle(this._startAngle).endAngle(this._endAngle)(d.data());b=(a[b].startAngle+a[b].endAngle)/2;return{x:g*Math.sin(b),y:-g*Math.cos(b)}};c.prototype._additionalPaint=function(a){var b=this;this._renderArea.select(\".label-area\").remove();this._labelsEnabled&&n.Window.setTimeout(function(){return b._drawLabels()},a);var c=this._generateStrokeDrawSteps(),\nd=this._getDataToDraw();this.datasets().forEach(function(a){var e=v.Plot.applyDrawSteps(c,a);b._strokeDrawers.get(a).draw(d.get(a),e)})};c.prototype._generateStrokeDrawSteps=function(){return[{attrToProjector:this._generateAttrToProjector(),animator:new k.Null}]};c.prototype._sliceIndexForPoint=function(a){var b=Math.sqrt(Math.pow(a.x,2)+Math.pow(a.y,2)),c=Math.acos(-a.y/b);0>a.x&&(c=2*Math.PI-c);for(a=0;a<this._startAngles.length;a++)if(this._startAngles[a]<c&&this._endAngles[a]>c){var d=a;break}if(void 0!==\nd){a=this.datasets()[0];var e=a.data()[d],c=this.innerRadius().accessor(e,d,a);a=this.outerRadius().accessor(e,d,a);if(b>c&&b<a)return d}return null};c.prototype._drawLabels=function(){var a=this,b=this._generateAttrToProjector(),c=this._renderArea.append(\"g\").classed(\"label-area\",!0),d=new g.SvgContext(c.node()),e=new g.CacheMeasurer(d),f=new g.Writer(e,d),k=this.datasets()[0];this._getDataToDraw().get(k).forEach(function(d,g){var l=a.sectorValue().accessor(d,g,k);if(n.Math.isValidNumber(l)){var l=\na._labelFormatter(l),m=e.measure(l),q=(a._endAngles[g]+a._startAngles[g])/2,p=a.outerRadius().accessor(d,g,k);a.outerRadius().scale&&(p=a.outerRadius().scale.scale(p));var r=a.innerRadius().accessor(d,g,k);a.innerRadius().scale&&(r=a.innerRadius().scale.scale(r));var r=(p+r)/2,p=Math.sin(q)*r-m.width/2,r=-Math.cos(q)*r-m.height/2,t=[{x:p,y:r},{x:p,y:r+m.height},{x:p+m.width,y:r},{x:p+m.width,y:r+m.height}];(q=t.every(function(b){return Math.abs(b.x)<=a.width()/2&&Math.abs(b.y)<=a.height()/2}))&&(q=\nt.map(function(b){return a._sliceIndexForPoint(b)}).every(function(a){return a===g}));d=b.fill(d,g,k);d=1.6*n.Color.contrast(\"white\",d)<n.Color.contrast(\"black\",d);p=c.append(\"g\").attr(\"transform\",\"translate(\"+p+\",\"+r+\")\");p.classed(d?\"dark-label\":\"light-label\",!0);p.style(\"visibility\",q?\"inherit\":\"hidden\");f.write(l,m.width,m.height,{xAlign:\"center\",yAlign:\"center\"},p.node())}})};return c}(v.Plot);a._INNER_RADIUS_KEY=\"inner-radius\";a._OUTER_RADIUS_KEY=\"outer-radius\";a._SECTOR_VALUE_KEY=\"sector-value\";\nc.Pie=a},function(a,c,d){var b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=null===b?Object.create(b):(c.prototype=b.prototype,new c)},f=d(1),g=d(5),k=d(7),l=d(6),m=d(32),n=d(3),q=d(0),p=d(2);a=function(a){function c(){var b=a.call(this)||this;b._labelsEnabled=!1;b._label=null;b.animator(\"rectangles\",new k.Null);b.addClass(\"rectangle-plot\");b.attr(\"fill\",(new n.Color).range()[0]);return b}b(c,a);c.prototype._createDrawer=\nfunction(){return new l.ProxyDrawer(function(){return new m.RectangleSVGDrawer},m.RectangleCanvasDrawStep)};c.prototype._generateAttrToProjector=function(){var b=this,d=a.prototype._generateAttrToProjector.call(this),e=p.Plot._scaledAccessor(this.x()),f=d[c._X2_KEY],g=p.Plot._scaledAccessor(this.y()),k=d[c._Y2_KEY],l=this.x().scale,m=this.y().scale;null!=f?(d.width=function(a,b,c){return Math.abs(f(a,b,c)-e(a,b,c))},d.x=function(a,b,c){return Math.min(f(a,b,c),e(a,b,c))}):(d.width=function(){return b._rectangleWidth(l)},\nd.x=function(a,b,c){return e(a,b,c)-.5*d.width(a,b,c)});null!=k?(d.height=function(a,b,c){return Math.abs(k(a,b,c)-g(a,b,c))},d.y=function(a,b,c){return Math.max(k(a,b,c),g(a,b,c))-d.height(a,b,c)}):(d.height=function(){return b._rectangleWidth(m)},d.y=function(a,b,c){return g(a,b,c)-.5*d.height(a,b,c)});delete d[c._X2_KEY];delete d[c._Y2_KEY];return d};c.prototype._generateDrawSteps=function(){return[{attrToProjector:this._generateAttrToProjector(),animator:this._getAnimator(\"rectangles\")}]};c.prototype._updateExtentsForProperty=\nfunction(b){a.prototype._updateExtentsForProperty.call(this,b);\"x\"===b?a.prototype._updateExtentsForProperty.call(this,\"x2\"):\"y\"===b&&a.prototype._updateExtentsForProperty.call(this,\"y2\")};c.prototype._filterForProperty=function(b){return\"x2\"===b?a.prototype._filterForProperty.call(this,\"x\"):\"y2\"===b?a.prototype._filterForProperty.call(this,\"y\"):a.prototype._filterForProperty.call(this,b)};c.prototype.x=function(b,d){if(null==b)return a.prototype.x.call(this);null==d?a.prototype.x.call(this,b):a.prototype.x.call(this,\nb,d);null!=d&&(b=(b=this.x2())&&b.accessor,null!=b&&this._bindProperty(c._X2_KEY,b,d));d instanceof n.Category&&d.innerPadding(0).outerPadding(0);return this};c.prototype.x2=function(a){if(null==a)return this._propertyBindings.get(c._X2_KEY);var b=this.x();this._bindProperty(c._X2_KEY,a,b&&b.scale);this.render();return this};c.prototype.y=function(b,d){if(null==b)return a.prototype.y.call(this);null==d?a.prototype.y.call(this,b):a.prototype.y.call(this,b,d);null!=d&&(b=(b=this.y2())&&b.accessor,null!=\nb&&this._bindProperty(c._Y2_KEY,b,d));d instanceof n.Category&&d.innerPadding(0).outerPadding(0);return this};c.prototype.y2=function(a){if(null==a)return this._propertyBindings.get(c._Y2_KEY);var b=this.y();this._bindProperty(c._Y2_KEY,a,b&&b.scale);this.render();return this};c.prototype.entitiesAt=function(a){var b=this._generateAttrToProjector();return this.entities().filter(function(c){var d=c.datum,e=c.index,f=c.dataset;c=b.x(d,e,f);var g=b.y(d,e,f),k=b.width(d,e,f),d=b.height(d,e,f);return c<=\na.x&&a.x<=c+k&&g<=a.y&&a.y<=g+d})};c.prototype.entitiesIn=function(a,b){if(null==b){var c={min:a.topLeft.x,max:a.bottomRight.x};a={min:a.topLeft.y,max:a.bottomRight.y}}else c=a,a=b;return this._entitiesIntersecting(c,a)};c.prototype._entityBBox=function(a,b,c,d){return{x:d.x(a,b,c),y:d.y(a,b,c),width:d.width(a,b,c),height:d.height(a,b,c)}};c.prototype._entitiesIntersecting=function(a,b){var c=this,d=[],e=this._generateAttrToProjector();this.entities().forEach(function(f){q.DOM.intersectsBBox(a,b,\nc._entityBBox(f.datum,f.index,f.dataset,e))&&d.push(f)});return d};c.prototype.label=function(a){if(null==a)return this._label;this._label=a;this.render();return this};c.prototype.labelsEnabled=function(a){if(null==a)return this._labelsEnabled;this._labelsEnabled=a;this.render();return this};c.prototype._propertyProjectors=function(){var b=a.prototype._propertyProjectors.call(this);null!=this.x2()&&(b.x2=p.Plot._scaledAccessor(this.x2()));null!=this.y2()&&(b.y2=p.Plot._scaledAccessor(this.y2()));\nreturn b};c.prototype._pixelPoint=function(a,b,c){var d=this._generateAttrToProjector(),e=d.x(a,b,c),f=d.y(a,b,c),g=d.width(a,b,c);a=d.height(a,b,c);return{x:e+g/2,y:f+a/2}};c.prototype._rectangleWidth=function(a){if(a instanceof n.Category)return a.rangeBand();var b=a===this.x().scale?this.x().accessor:this.y().accessor,c=f.set(q.Array.flatten(this.datasets().map(function(a){return a.data().map(function(c,d){return b(c,d,a).valueOf()})}))).values().map(function(a){return+a}),d=q.Math.min(c,0),c=\nq.Math.max(c,0),e=a.scale(d);return(a.scale(c)-e)/Math.abs(c-d)};c.prototype._getDataToDraw=function(){var a=new q.Map,b=this._generateAttrToProjector();this.datasets().forEach(function(c){var d=c.data().filter(function(a,d){return q.Math.isValidNumber(b.x(a,d,c))&&q.Math.isValidNumber(b.y(a,d,c))&&q.Math.isValidNumber(b.width(a,d,c))&&q.Math.isValidNumber(b.height(a,d,c))});a.set(c,d)});return a};c.prototype._additionalPaint=function(a){var b=this;this._renderArea.selectAll(\".label-area\").remove();\nthis._labelsEnabled&&null!=this.label()&&q.Window.setTimeout(function(){return b._drawLabels()},a)};c.prototype._drawLabels=function(){var a=this,b=this._getDataToDraw();this.datasets().forEach(function(c,d){return a._drawLabel(b,c,d)})};c.prototype._drawLabel=function(a,b,c){var d=this,e=this._generateAttrToProjector(),f=this._renderArea.append(\"g\").classed(\"label-area\",!0),k=new g.SvgContext(f.node()),l=new g.CacheMeasurer(k),m=new g.Writer(l,k),k=this.x().scale.range(),n=this.y().scale.range(),\np=Math.min.apply(null,k),r=Math.max.apply(null,k),t=Math.min.apply(null,n),v=Math.max.apply(null,n);a.get(b).forEach(function(g,k){var n=\"\"+d.label()(g,k,b),w=l.measure(n),z=e.x(g,k,b),y=e.y(g,k,b),A=e.width(g,k,b),D=e.height(g,k,b);w.height<=D&&w.width<=A&&(D=(D-w.height)/2,z+=(A-w.width)/2,y+=D,A={min:z,max:z+w.width},D={min:y,max:y+w.height},A.min<p||A.max>r||D.min<t||D.max>v||d._overlayLabel(A,D,k,c,a)||(g=e.fill(g,k,b),g=1.6*q.Color.contrast(\"white\",g)<q.Color.contrast(\"black\",g),z=f.append(\"g\").attr(\"transform\",\n\"translate(\"+z+\",\"+y+\")\"),z.classed(g?\"dark-label\":\"light-label\",!0),m.write(n,w.width,w.height,{xAlign:\"center\",yAlign:\"center\"},z.node())))})};c.prototype._overlayLabel=function(a,b,c,d,e){for(var f=this._generateAttrToProjector(),g=this.datasets(),k=d;k<g.length;k++)for(var l=g[k],m=e.get(l),n=k===d?c+1:0;n<m.length;n++)if(q.DOM.intersectsBBox(a,b,this._entityBBox(m[n],n,l,f)))return!0;return!1};return c}(d(16).XYPlot);a._X2_KEY=\"x2\";a._Y2_KEY=\"y2\";c.Rectangle=a},function(a,c,d){var b=this&&this.__extends||\nfunction(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=null===b?Object.create(b):(c.prototype=b.prototype,new c)},f=d(29),g=d(6),k=d(45),l=d(7),m=d(3),n=d(0),q=d(17),p=d(2);a=function(a){function c(){var b=a.call(this)||this;b.addClass(\"scatter-plot\");var c=new l.Easing;c.startDelay(5);c.stepDuration(250);c.maxTotalDuration(p.Plot._ANIMATION_MAX_DURATION);b.animator(q.Animator.MAIN,c);b.attr(\"opacity\",.6);b.attr(\"fill\",(new m.Color).range()[0]);b.size(6);\nvar d=f.circle();b.symbol(function(){return d});return b}b(c,a);c.prototype._buildLightweightPlotEntities=function(b){var c=this;return a.prototype._buildLightweightPlotEntities.call(this,b).map(function(a){var b=p.Plot._scaledAccessor(c.size())(a.datum,a.index,a.dataset);a.diameter=b;return a})};c.prototype._createDrawer=function(a){var b=this;return new g.ProxyDrawer(function(){return new k.SymbolSVGDrawer},k.makeSymbolCanvasDrawStep(a,function(){return p.Plot._scaledAccessor(b.symbol())},function(){return p.Plot._scaledAccessor(b.size())}))};\nc.prototype.size=function(a,b){if(null==a)return this._propertyBindings.get(c._SIZE_KEY);this._bindProperty(c._SIZE_KEY,a,b);this.render();return this};c.prototype.symbol=function(a){if(null==a)return this._propertyBindings.get(c._SYMBOL_KEY);this._propertyBindings.set(c._SYMBOL_KEY,{accessor:a});this.render();return this};c.prototype._generateDrawSteps=function(){var a=[];if(this._animateOnNextRender()){var b=this._generateAttrToProjector(),c=p.Plot._scaledAccessor(this.symbol());b.d=function(a,\nb,d){return c(a,b,d)(0)(null)};a.push({attrToProjector:b,animator:this._getAnimator(q.Animator.RESET)})}a.push({attrToProjector:this._generateAttrToProjector(),animator:this._getAnimator(q.Animator.MAIN)});return a};c.prototype._propertyProjectors=function(){var b=a.prototype._propertyProjectors.call(this),c=p.Plot._scaledAccessor(this.x()),d=p.Plot._scaledAccessor(this.y());b.x=c;b.y=d;b.transform=function(a,b,e){return\"translate(\"+c(a,b,e)+\",\"+d(a,b,e)+\")\"};b.d=this._constructSymbolGenerator();\nreturn b};c.prototype._constructSymbolGenerator=function(){var a=p.Plot._scaledAccessor(this.symbol()),b=p.Plot._scaledAccessor(this.size());return function(c,d,e){return a(c,d,e)(b(c,d,e))(null)}};c.prototype._entityVisibleOnPlot=function(a,b){return n.DOM.intersectsBBox({min:b.topLeft.x,max:b.bottomRight.x},{min:b.topLeft.y,max:b.bottomRight.y},{x:a.position.x-a.diameter,y:a.position.y-a.diameter,width:a.diameter,height:a.diameter})};c.prototype.entitiesIn=function(a,b){if(null==b){var c={min:a.topLeft.x,\nmax:a.bottomRight.x};var d={min:a.topLeft.y,max:a.bottomRight.y}}else c=a,d=b;var e=p.Plot._scaledAccessor(this.x()),f=p.Plot._scaledAccessor(this.y());return this.entities().filter(function(a){var b=a.datum,g=a.index,k=a.dataset;a=e(b,g,k);b=f(b,g,k);return c.min<=a&&a<=c.max&&d.min<=b&&b<=d.max})};c.prototype.entitiesAt=function(a){var b=p.Plot._scaledAccessor(this.x()),c=p.Plot._scaledAccessor(this.y()),d=p.Plot._scaledAccessor(this.size());return this.entities().filter(function(e){var f=e.datum,\ng=e.index,k=e.dataset;e=b(f,g,k);var l=c(f,g,k),f=d(f,g,k);return e-f/2<=a.x&&a.x<=e+f/2&&l-f/2<=a.y&&a.y<=l+f/2})};return c}(d(16).XYPlot);a._SIZE_KEY=\"size\";a._SYMBOL_KEY=\"symbol\";c.Scatter=a},function(a,c,d){var b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=null===b?Object.create(b):(c.prototype=b.prototype,new c)},f=d(7),g=d(6),k=d(44),l=d(3),m=d(25),n=d(2);a=function(a){function c(){var b=a.call(this)||this;b.addClass(\"segment-plot\");\nb.attr(\"stroke\",(new l.Color).range()[0]);b.attr(\"stroke-width\",\"2px\");return b}b(c,a);c.prototype._createDrawer=function(){return new g.ProxyDrawer(function(){return new k.SegmentSVGDrawer},function(){m.warn(\"canvas renderer is not supported on Segment Plot!\")})};c.prototype._generateDrawSteps=function(){return[{attrToProjector:this._generateAttrToProjector(),animator:new f.Null}]};c.prototype._updateExtentsForProperty=function(b){a.prototype._updateExtentsForProperty.call(this,b);\"x\"===b?a.prototype._updateExtentsForProperty.call(this,\n\"x2\"):\"y\"===b&&a.prototype._updateExtentsForProperty.call(this,\"y2\")};c.prototype._filterForProperty=function(b){return\"x2\"===b?a.prototype._filterForProperty.call(this,\"x\"):\"y2\"===b?a.prototype._filterForProperty.call(this,\"y\"):a.prototype._filterForProperty.call(this,b)};c.prototype.x=function(b,d){if(null==b)return a.prototype.x.call(this);null==d?a.prototype.x.call(this,b):(a.prototype.x.call(this,b,d),b=(b=this.x2())&&b.accessor,null!=b&&this._bindProperty(c._X2_KEY,b,d));return this};c.prototype.x2=\nfunction(a){if(null==a)return this._propertyBindings.get(c._X2_KEY);var b=this.x();this._bindProperty(c._X2_KEY,a,b&&b.scale);this.render();return this};c.prototype.y=function(b,d){if(null==b)return a.prototype.y.call(this);null==d?a.prototype.y.call(this,b):(a.prototype.y.call(this,b,d),b=(b=this.y2())&&b.accessor,null!=b&&this._bindProperty(c._Y2_KEY,b,d));return this};c.prototype.y2=function(a){if(null==a)return this._propertyBindings.get(c._Y2_KEY);var b=this.y();this._bindProperty(c._Y2_KEY,\na,b&&b.scale);this.render();return this};c.prototype._propertyProjectors=function(){var b=a.prototype._propertyProjectors.call(this);b.x1=n.Plot._scaledAccessor(this.x());b.x2=null==this.x2()?n.Plot._scaledAccessor(this.x()):n.Plot._scaledAccessor(this.x2());b.y1=n.Plot._scaledAccessor(this.y());b.y2=null==this.y2()?n.Plot._scaledAccessor(this.y()):n.Plot._scaledAccessor(this.y2());return b};c.prototype.entitiesAt=function(a){a=this.entityNearest(a);return null!=a?[a]:[]};c.prototype.entitiesIn=function(a,\nb){if(null==b){var c={min:a.topLeft.x,max:a.bottomRight.x};a={min:a.topLeft.y,max:a.bottomRight.y}}else c=a,a=b;return this._entitiesIntersecting(c,a)};c.prototype._entitiesIntersecting=function(a,b){var c=this,d=[],e=this._generateAttrToProjector();this.entities().forEach(function(f){c._lineIntersectsBox(f,a,b,e)&&d.push(f)});return d};c.prototype._lineIntersectsBox=function(a,b,c,d){var e=this,f=d.x1(a.datum,a.index,a.dataset),g=d.x2(a.datum,a.index,a.dataset),k=d.y1(a.datum,a.index,a.dataset);\na=d.y2(a.datum,a.index,a.dataset);if(b.min<=f&&f<=b.max&&c.min<=k&&k<=c.max||b.min<=g&&g<=b.max&&c.min<=a&&a<=c.max)return!0;var l={x:f,y:k},m={x:g,y:a},n=[{x:b.min,y:c.min},{x:b.min,y:c.max},{x:b.max,y:c.max},{x:b.max,y:c.min}];return 0<n.filter(function(a,b){return 0!==b?e._lineIntersectsSegment(l,m,a,n[b-1])&&e._lineIntersectsSegment(a,n[b-1],l,m):!1}).length};c.prototype._lineIntersectsSegment=function(a,b,c,d){return 0>((b.x-a.x)*(c.y-b.y)-(b.y-a.y)*(c.x-b.x))*((b.x-a.x)*(d.y-b.y)-(b.y-a.y)*\n(d.x-b.x))};return c}(d(16).XYPlot);a._X2_KEY=\"x2\";a._Y2_KEY=\"y2\";c.Segment=a},function(a,c,d){var b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=null===b?Object.create(b):(c.prototype=b.prototype,new c)},f=d(1),g=d(7),k=d(0);a=d(46);var l=d(2);d=function(a){function c(){var b=a.call(this)||this;b._baselineValue=0;b._stackingOrder=\"bottomup\";b.addClass(\"stacked-area-plot\");b.attr(\"fill-opacity\",1);b._stackingResult=\nnew k.Map;b._stackedExtent=[];b._baselineValueProvider=function(){return[b._baselineValue]};b.croppedRenderingEnabled(!1);return b}b(c,a);c.prototype.croppedRenderingEnabled=function(b){return null==b?a.prototype.croppedRenderingEnabled.call(this):b?(k.Window.warn(\"Warning: Stacked Area Plot does not support cropped rendering.\"),this):a.prototype.croppedRenderingEnabled.call(this,b)};c.prototype._getAnimator=function(){return new g.Null};c.prototype._setup=function(){a.prototype._setup.call(this);\nthis._baseline=this._renderArea.append(\"line\").classed(\"baseline\",!0)};c.prototype.x=function(b,c){if(null==b)return a.prototype.x.call(this);null==c?a.prototype.x.call(this,b):a.prototype.x.call(this,b,c);this._updateStackExtentsAndOffsets();return this};c.prototype.y=function(b,c){if(null==b)return a.prototype.y.call(this);null==c?a.prototype.y.call(this,b):a.prototype.y.call(this,b,c);this._updateStackExtentsAndOffsets();return this};c.prototype.stackingOrder=function(a){if(null==a)return this._stackingOrder;\nthis._stackingOrder=a;this._onDatasetUpdate();return this};c.prototype.downsamplingEnabled=function(b){if(null==b)return a.prototype.downsamplingEnabled.call(this);k.Window.warn(\"Warning: Stacked Area Plot does not support downsampling\");return this};c.prototype._additionalPaint=function(){var a=this.y().scale.scale(this._baselineValue),a={x1:0,y1:a,x2:this.width(),y2:a};this._getAnimator(\"baseline\").animate(this._baseline,a)};c.prototype._updateYScale=function(){var a=this.y(),a=a&&a.scale;null!=\na&&(a.addPaddingExceptionsProvider(this._baselineValueProvider),a.addIncludedValuesProvider(this._baselineValueProvider))};c.prototype._onDatasetUpdate=function(){this._updateStackExtentsAndOffsets();a.prototype._onDatasetUpdate.call(this);return this};c.prototype._updateExtentsForProperty=function(b){a.prototype._updateExtentsForProperty.call(this,b);\"x\"!==b&&\"y\"!==b||!this._projectorsReady()||this._updateStackExtentsAndOffsets()};c.prototype._extentsForProperty=function(b){return\"y\"===b?[this._stackedExtent]:\na.prototype._extentsForProperty.call(this,b)};c.prototype._updateStackExtentsAndOffsets=function(){if(this._projectorsReady()){var a=this.datasets(),b=this.x().accessor,c=this.y().accessor,d=this._filterForProperty(\"y\");this._checkSameDomain(a,b);this._stackingResult=k.Stacking.stack(a,b,c,this._stackingOrder);this._stackedExtent=k.Stacking.stackedExtent(this._stackingResult,b,d)}};c.prototype._checkSameDomain=function(a,b){var d=a.map(function(a){return f.set(a.data().map(function(c,d){return b(c,\nd,a).toString()})).values()}),e=c._domainKeys(a,b);d.some(function(a){return a.length!==e.length})&&k.Window.warn(\"the domains across the datasets are not the same. Plot may produce unintended behavior.\")};c._domainKeys=function(a,b){var c=f.set();a.forEach(function(a){a.data().forEach(function(d,e){c.add(b(d,e,a))})});return c.values()};c.prototype._propertyProjectors=function(){var b=this,c=a.prototype._propertyProjectors.call(this),d=this.y().accessor,e=this.x().accessor;c.d=this._constructAreaProjector(l.Plot._scaledAccessor(this.x()),\nfunction(a,c,f){return b.y().scale.scale(+d(a,c,f)+b._stackingResult.get(f).get(k.Stacking.normalizeKey(e(a,c,f))).offset)},function(a,c,d){return b.y().scale.scale(b._stackingResult.get(d).get(k.Stacking.normalizeKey(e(a,c,d))).offset)});return c};c.prototype._pixelPoint=function(b,c,d){var e=a.prototype._pixelPoint.call(this,b,c,d),f=this.x().accessor(b,c,d);b=this.y().accessor(b,c,d);d=this.y().scale.scale(+b+this._stackingResult.get(d).get(k.Stacking.normalizeKey(f)).offset);return{x:e.x,y:d}};\nreturn c}(a.Area);c.StackedArea=d},function(a,c,d){var b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=null===b?Object.create(b):(c.prototype=b.prototype,new c)},f=d(5),g=d(0),k=d(24);a=function(a){function c(b){void 0===b&&(b=\"vertical\");b=a.call(this,b)||this;b.addClass(\"stacked-bar-plot\");b._stackingOrder=\"bottomup\";b._stackingResult=new g.Map;b._stackedExtent=[];return b}b(c,a);c.prototype.x=function(b,c){if(null==\nb)return a.prototype.x.call(this);null==c?a.prototype.x.call(this,b):a.prototype.x.call(this,b,c);this._updateStackExtentsAndOffsets();return this};c.prototype.y=function(b,c){if(null==b)return a.prototype.y.call(this);null==c?a.prototype.y.call(this,b):a.prototype.y.call(this,b,c);this._updateStackExtentsAndOffsets();return this};c.prototype.stackingOrder=function(a){if(null==a)return this._stackingOrder;this._stackingOrder=a;this._onDatasetUpdate();return this};c.prototype._setup=function(){a.prototype._setup.call(this);\nthis._labelArea=this._renderArea.append(\"g\").classed(k.Bar._LABEL_AREA_CLASS,!0);var b=new f.SvgContext(this._labelArea.node());this._measurer=new f.CacheMeasurer(b);this._writer=new f.Writer(this._measurer,b)};c.prototype._drawLabels=function(){function b(a,b,e){var f=e.x,g=e.y,k=b.height,l=b.width;e=d._isVertical?l>z-2*c._LABEL_PADDING:k>z-2*c._LABEL_PADDING;0>f||0>g||f+l>d.width()||g+k>d.height()||e||(f=d._labelArea.append(\"g\").attr(\"transform\",\"translate(\"+f+\", \"+g+\")\"),f.classed(\"stacked-bar-label\",\n!0),d._writer.write(a,b.width,b.height,{xAlign:\"center\",yAlign:\"center\"},f.node()));return e}var d=this;a.prototype._drawLabels.call(this);this._labelArea.selectAll(\"g\").remove();var e=+this.baselineValue(),f=this._isVertical?this.x().scale:this.y().scale,k=this._isVertical?this.y().scale:this.x().scale,l=g.Stacking.stackedExtents(this._stackingResult),m=l.maximumExtents,l=l.minimumExtents,z=this._getBarPixelWidth(),y=[];m.forEach(function(a){if(a.extent!==e){var g=d.labelFormatter()(a.extent),l=\nd._measurer.measure(g),m=d._isVertical?l.width:l.height,n=d._isVertical?l.height:l.width,q=d._isVertical?f.scale(a.axisValue)-m/2:k.scale(a.extent)+c._STACKED_BAR_LABEL_PADDING;a=d._isVertical?k.scale(a.extent)-n-c._STACKED_BAR_LABEL_PADDING:f.scale(a.axisValue)-m/2;y.push(b(g,l,{x:q,y:a}))}});l.forEach(function(a){if(a.extent!==e){var g=d.labelFormatter()(a.extent),l=d._measurer.measure(g),m=d._isVertical?l.width:l.height,n=d._isVertical?l.height:l.width,n=d._isVertical?f.scale(a.axisValue)-m/2:\nk.scale(a.extent)-n-c._STACKED_BAR_LABEL_PADDING;a=d._isVertical?k.scale(a.extent)+c._STACKED_BAR_LABEL_PADDING:f.scale(a.axisValue)-m/2;y.push(b(g,l,{x:n,y:a}))}});y.some(function(a){return a})&&this._labelArea.selectAll(\"g\").remove()};c.prototype._generateAttrToProjector=function(){function b(a,b,c){return 0>+B(a,b,c)?e(a,b,c):d(a,b,c)}function c(a,b,c){return Math.abs(d(a,b,c)-e(a,b,c))}function d(a,b,c){return y.scale(+B(a,b,c)+f._stackingResult.get(c).get(g.Stacking.normalizeKey(A(a,b,c))).offset)}\nfunction e(a,b,c){return y.scale(f._stackingResult.get(c).get(g.Stacking.normalizeKey(A(a,b,c))).offset)}var f=this,k=a.prototype._generateAttrToProjector.call(this),l=this._isVertical?\"y\":\"x\",m=this._isVertical?\"x\":\"y\",y=this._isVertical?this.y().scale:this.x().scale,B=this._propertyBindings.get(l).accessor,A=this._propertyBindings.get(m).accessor;k[this._isVertical?\"height\":\"width\"]=c;k[l]=function(a,d,e){return f._isVertical?b(a,d,e):b(a,d,e)-c(a,d,e)};return k};c.prototype._onDatasetUpdate=function(){this._updateStackExtentsAndOffsets();\na.prototype._onDatasetUpdate.call(this);return this};c.prototype._updateExtentsForProperty=function(b){a.prototype._updateExtentsForProperty.call(this,b);\"x\"!==b&&\"y\"!==b||!this._projectorsReady()||this._updateStackExtentsAndOffsets()};c.prototype._extentsForProperty=function(b){return b===(this._isVertical?\"y\":\"x\")?[this._stackedExtent]:a.prototype._extentsForProperty.call(this,b)};c.prototype._updateStackExtentsAndOffsets=function(){if(this._projectorsReady()){var a=this.datasets(),b=this._isVertical?\nthis.x().accessor:this.y().accessor,c=this._isVertical?this.y().accessor:this.x().accessor,d=this._filterForProperty(this._isVertical?\"y\":\"x\");this._stackingResult=g.Stacking.stack(a,b,c,this._stackingOrder);this._stackedExtent=g.Stacking.stackedExtent(this._stackingResult,b,d)}};c.prototype.invalidateCache=function(){a.prototype.invalidateCache.call(this);this._measurer.reset()};return c}(k.Bar);a._STACKED_BAR_LABEL_PADDING=5;c.StackedBar=a},function(a,c,d){var b=this&&this.__extends||function(a,\nb){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=null===b?Object.create(b):(c.prototype=b.prototype,new c)},f=d(0);a=d(24);var g=d(2);d=function(a){function c(){var b=a.call(this)||this;b._connectorsEnabled=!1;b.addClass(\"waterfall-plot\");return b}b(c,a);c.prototype.connectorsEnabled=function(a){if(null==a)return this._connectorsEnabled;this._connectorsEnabled=a;return this};c.prototype.total=function(a){if(null==a)return this._propertyBindings.get(c._TOTAL_KEY);\nthis._bindProperty(c._TOTAL_KEY,a,null);return this};c.prototype._additionalPaint=function(a){var b=this;this._connectorArea.selectAll(\"line\").remove();this._connectorsEnabled&&f.Window.setTimeout(function(){return b._drawConnectors()},a)};c.prototype._createNodesForDataset=function(b){b=a.prototype._createNodesForDataset.call(this,b);this._connectorArea=this._renderArea.append(\"g\").classed(c._CONNECTOR_AREA_CLASS,!0);return b};c.prototype._extentsForProperty=function(b){return\"y\"===b?[this._extent]:\na.prototype._extentsForProperty.call(this,b)};c.prototype._generateAttrToProjector=function(){var b=this,d=a.prototype._generateAttrToProjector.call(this),e=this.y().scale,f=g.Plot._scaledAccessor(this.total());null==this.attr(\"y\")&&(d.y=function(a,c,d){var g=b.y().accessor(a,c,d);if(f(a,c,d))return Math.min(e.scale(g),e.scale(0));a=b._subtotals[c];if(0===c)return 0>g?e.scale(a-g):e.scale(a);c=b._subtotals[c-1];return a>c?e.scale(a):e.scale(c)});null==this.attr(\"height\")&&(d.height=function(a,c,d){var g=\nf(a,c,d);a=b.y().accessor(a,c,d);if(g)return Math.abs(e.scale(a)-e.scale(0));g=b._subtotals[c];if(0===c)return Math.abs(e.scale(g)-e.scale(g-a));c=b._subtotals[c-1];return Math.abs(e.scale(g)-e.scale(c))});d[\"class\"]=function(a,d,e){var g=\"\";null!=b.attr(\"class\")&&(g=b.attr(\"class\").accessor(a,d,e)+\" \");if(f(a,d,e))return g+c._BAR_TOTAL_CLASS;a=b.y().accessor(a,d,e);return g+(0<a?c._BAR_GROWTH_CLASS:c._BAR_DECLINE_CLASS)};return d};c.prototype._onDatasetUpdate=function(){this._updateSubtotals();a.prototype._onDatasetUpdate.call(this);\nreturn this};c.prototype._calculateSubtotalsAndExtent=function(a){var b=this,c=Number.MAX_VALUE,d=Number.MIN_VALUE,e=0,f=!1;a.data().forEach(function(g,k){var l=b.y().accessor(g,k,a);(g=b.total().accessor(g,k,a))&&0!==k||(e+=l);b._subtotals.push(e);e<c&&(c=e);e>d&&(d=e);g&&(l<c&&(c=l),l>d&&(d=l));if(!f&&g){k=l-e;for(l=0;l<b._subtotals.length;l++)b._subtotals[l]+=k;f=!0;e+=k;c+=k;d+=k}});this._extent=[c,d]};c.prototype._drawConnectors=function(){for(var a=this._generateAttrToProjector(),b=this.datasets()[0],\nd=1;d<b.data().length;d++){var e=d-1,f=b.data()[d],g=b.data()[e],g=a.x(g,e,b),k=a.x(f,d,b)+a.width(f,d,b),l=a.y(f,d,b);if(0<this._subtotals[d]&&this._subtotals[d]>this._subtotals[e]||0>this._subtotals[d]&&this._subtotals[d]>=this._subtotals[e])l=a.y(f,d,b)+a.height(f,d,b);this._connectorArea.append(\"line\").classed(c._CONNECTOR_CLASS,!0).attr(\"x1\",g).attr(\"x2\",k).attr(\"y1\",l).attr(\"y2\",l)}};c.prototype._updateSubtotals=function(){var a=this.datasets();0<a.length&&(a=a[a.length-1],this._subtotals=[],\nthis._calculateSubtotalsAndExtent(a))};return c}(a.Bar);d._BAR_DECLINE_CLASS=\"waterfall-decline\";d._BAR_GROWTH_CLASS=\"waterfall-growth\";d._BAR_TOTAL_CLASS=\"waterfall-total\";d._CONNECTOR_CLASS=\"connector\";d._CONNECTOR_AREA_CLASS=\"connector-area\";d._TOTAL_KEY=\"total\";c.Waterfall=d},function(a,c,d){var b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=null===b?Object.create(b):(c.prototype=b.prototype,new c)},f=d(1),g=d(0);\na=function(a){function c(b){var d=a.call(this)||this;switch(b){case null:case void 0:null==c._plottableColorCache&&(c._plottableColorCache=c._getPlottableColors());b=f.scaleOrdinal().range(c._plottableColorCache);break;case \"Category10\":case \"category10\":case \"10\":b=f.scaleOrdinal(f.schemeCategory10);break;case \"Category20\":case \"category20\":case \"20\":b=f.scaleOrdinal(f.schemeCategory20);break;case \"Category20b\":case \"category20b\":case \"20b\":b=f.scaleOrdinal(f.schemeCategory20b);break;case \"Category20c\":case \"category20c\":case \"20c\":b=\nf.scaleOrdinal(f.schemeCategory20c);break;default:throw Error(\"Unsupported ColorScale type\");}d._d3Scale=b;return d}b(c,a);c.prototype.extentOfValues=function(a){return g.Array.uniq(a)};c.prototype._getExtent=function(){return g.Array.uniq(this._getAllIncludedValues())};c.invalidateColorCache=function(){c._plottableColorCache=null};c._getPlottableColors=function(){for(var a=[],b=f.select(\"body\").append(\"plottable-color-tester\"),c=g.Color.colorTest(b,\"\"),d=0,e=g.Color.colorTest(b,\"plottable-colors-0\");null!=\ne&&d<this._MAXIMUM_COLORS_FROM_CSS&&(e!==c||e!==a[a.length-1]);)a.push(e),d++,e=g.Color.colorTest(b,\"plottable-colors-\"+d);b.remove();return a};c.prototype.scale=function(a){var b=this._d3Scale(a);a=this.domain().indexOf(a);a=Math.floor(a/this.range().length);return g.Color.lightenColor(b,Math.log(a*c._LOOP_LIGHTEN_FACTOR+1))};c.prototype._getDomain=function(){return this._backingScaleDomain()};c.prototype._backingScaleDomain=function(a){if(null==a)return this._d3Scale.domain();this._d3Scale.domain(a);\nreturn this};c.prototype._getRange=function(){return this._d3Scale.range()};c.prototype._setRange=function(a){this._d3Scale.range(a)};return c}(d(18).Scale);a._LOOP_LIGHTEN_FACTOR=1.6;a._MAXIMUM_COLORS_FROM_CSS=256;c.Color=a},function(a,c,d){var b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=null===b?Object.create(b):(c.prototype=b.prototype,new c)},f=d(1),g=d(0);a=function(a){function c(b){void 0===b&&(b=\"linear\");\nvar d=a.call(this)||this;switch(b){case \"linear\":d._colorScale=f.scaleLinear();break;case \"log\":d._colorScale=f.scaleLog();break;case \"sqrt\":d._colorScale=f.scaleSqrt();break;case \"pow\":d._colorScale=f.scalePow()}if(null==d._colorScale)throw Error(\"unknown QuantitativeScale scale type \"+b);d.range(c.REDS);return d}b(c,a);c.prototype.extentOfValues=function(a){a=f.extent(a);return null==a[0]||null==a[1]?[]:a};c.prototype._d3InterpolatedScale=function(){return this._colorScale.range([0,1]).interpolate(this._interpolateColors())};\nc.prototype._interpolateColors=function(){var a=this._colorRange;if(2>a.length)throw Error(\"Color scale arrays must have at least two elements.\");return function(){return function(b){b=Math.max(0,Math.min(1,b));b*=a.length-1;var c=Math.floor(b),d=b-c;return f.interpolateLab(a[c],a[Math.ceil(b)])(d)}}};c.prototype._resetScale=function(){this._d3Scale=this._d3InterpolatedScale();this._autoDomainIfAutomaticMode();this._dispatchUpdate()};c.prototype.autoDomain=function(){var a=this._getAllIncludedValues();\n0<a.length&&this._setDomain([g.Math.min(a,0),g.Math.max(a,0)]);return this};c.prototype.scale=function(a){return this._d3Scale(a)};c.prototype._getDomain=function(){return this._backingScaleDomain()};c.prototype._backingScaleDomain=function(a){if(null==a)return this._d3Scale.domain();this._d3Scale.domain(a);return this};c.prototype._getRange=function(){return this._colorRange};c.prototype._setRange=function(a){this._colorRange=a;this._resetScale()};return c}(d(18).Scale);a.REDS=\"#FFFFFF #FFF6E1 #FEF4C0 #FED976 #FEB24C #FD8D3C #FC4E2A #E31A1C #B10026\".split(\" \");\na.BLUES=\"#FFFFFF #CCFFFF #A5FFFD #85F7FB #6ED3EF #55A7E0 #417FD0 #2545D3 #0B02E1\".split(\" \");a.POSNEG=\"#0B02E1 #2545D3 #417FD0 #55A7E0 #6ED3EF #85F7FB #A5FFFD #CCFFFF #FFFFFF #FFF6E1 #FEF4C0 #FED976 #FEB24C #FD8D3C #FC4E2A #E31A1C #B10026\".split(\" \");c.InterpolatedColor=a},function(a,c,d){var b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=null===b?Object.create(b):(c.prototype=b.prototype,new c)},f=d(1);a=function(a){function c(){var b=\na.call(this)||this;b._d3Scale=f.scaleLinear();return b}b(c,a);c.prototype._defaultExtent=function(){return[0,1]};c.prototype._expandSingleValueDomain=function(a){return a[0]===a[1]?[a[0]-1,a[1]+1]:a};c.prototype.scale=function(a){return this._d3Scale(a)};c.prototype.scaleTransformation=function(a){return this.scale(a)};c.prototype.invertedTransformation=function(a){return this.invert(a)};c.prototype.getTransformationDomain=function(){return this.domain()};c.prototype._getDomain=function(){return this._backingScaleDomain()};\nc.prototype._backingScaleDomain=function(a){if(null==a)return this._d3Scale.domain();this._d3Scale.domain(a);return this};c.prototype._getRange=function(){return this._d3Scale.range()};c.prototype._setRange=function(a){this._d3Scale.range(a)};c.prototype.invert=function(a){return this._d3Scale.invert(a)};c.prototype.defaultTicks=function(){return this._d3Scale.ticks(c._DEFAULT_NUM_TICKS)};c.prototype._niceDomain=function(a,b){return this._d3Scale.copy().domain(a).nice(b).domain()};return c}(d(11).QuantitativeScale);\nc.Linear=a},function(a,c,d){var b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=null===b?Object.create(b):(c.prototype=b.prototype,new c)},f=d(1),g=d(0),k=d(3);a=function(a){function c(b){void 0===b&&(b=10);var c=a.call(this)||this;c._d3Scale=f.scaleLinear();c._base=b;c._pivot=c._base;c._setDomain(c._defaultExtent());if(1>=b)throw Error(\"ModifiedLogScale: The base must be \\x3e 1\");return c}b(c,a);c.prototype._adjustedLog=\nfunction(a){var b=0>a?-1:1;a*=b;a<this._pivot&&(a+=(this._pivot-a)/this._pivot);a=Math.log(a)/Math.log(this._base);return a*b};c.prototype._invertedAdjustedLog=function(a){var b=0>a?-1:1;a=Math.pow(this._base,a*b);a<this._pivot&&(a=this._pivot*(a-1)/(this._pivot-1));return a*b};c.prototype.scale=function(a){return this._d3Scale(this._adjustedLog(a))};c.prototype.invert=function(a){return this._invertedAdjustedLog(this._d3Scale.invert(a))};c.prototype.scaleTransformation=function(a){return this.scale(a)};\nc.prototype.invertedTransformation=function(a){return this.invert(a)};c.prototype.getTransformationDomain=function(){return this.domain()};c.prototype._getDomain=function(){return this._untransformedDomain};c.prototype._setDomain=function(b){this._untransformedDomain=b;a.prototype._setDomain.call(this,[this._adjustedLog(b[0]),this._adjustedLog(b[1])])};c.prototype._backingScaleDomain=function(a){if(null==a)return this._d3Scale.domain();this._d3Scale.domain(a);return this};c.prototype.ticks=function(){function a(a,\nb,c){return[a,b,c].sort(function(a,b){return a-b})[1]}var b=g.Math.min(this._untransformedDomain,0),c=g.Math.max(this._untransformedDomain,0),d=a(b,c,-this._pivot),e=a(b,c,this._pivot),d=this._logTicks(-d,-b).map(function(a){return-a}).reverse(),e=this._logTicks(e,c),l=Math.max(b,-this._pivot),m=Math.min(c,this._pivot),l=f.scaleLinear().domain([l,m]).ticks(this._howManyTicks(l,m)),d=d.concat(l).concat(e);1>=d.length&&(d=f.scaleLinear().domain([b,c]).ticks(k.ModifiedLog._DEFAULT_NUM_TICKS));return d};\nc.prototype._logTicks=function(a,b){var c=this,d=this._howManyTicks(a,b);if(0===d)return[];var e=Math.floor(Math.log(a)/Math.log(this._base)),k=Math.ceil(Math.log(b)/Math.log(this._base)),d=f.range(k,e,-Math.ceil((k-e)/d)),e=f.range(this._base,1,-(this._base-1)).map(Math.floor),l=g.Array.uniq(e),d=d.map(function(a){return l.map(function(b){return Math.pow(c._base,a-1)*b})});return g.Array.flatten(d).filter(function(c){return a<=c&&c<=b}).sort(function(a,b){return a-b})};c.prototype._howManyTicks=\nfunction(a,b){var c=this._adjustedLog(g.Math.min(this._untransformedDomain,0)),d=this._adjustedLog(g.Math.max(this._untransformedDomain,0));return Math.ceil((this._adjustedLog(b)-this._adjustedLog(a))/(d-c)*k.ModifiedLog._DEFAULT_NUM_TICKS)};c.prototype._niceDomain=function(a){return a};c.prototype._defaultExtent=function(){return[0,this._base]};c.prototype._expandSingleValueDomain=function(a){return a[0]===a[1]?(a=a[0],0<a?[a/this._base,a*this._base]:0===a?[-this._base,this._base]:[a*this._base,\na/this._base]):a};c.prototype._getRange=function(){return this._d3Scale.range()};c.prototype._setRange=function(a){this._d3Scale.range(a)};c.prototype.defaultTicks=function(){return this._d3Scale.ticks(k.ModifiedLog._DEFAULT_NUM_TICKS)};return c}(d(11).QuantitativeScale);c.ModifiedLog=a},function(a,c,d){var b=d(0);c.intervalTickGenerator=function(a){if(0>=a)throw Error(\"interval must be positive number\");return function(c){c=c.domain();var d=Math.min(c[0],c[1]);c=Math.max(c[0],c[1]);var e=Math.ceil(d/\na)*a,d=0===d%a?[]:[d],f=b.Math.range(0,Math.floor((c-e)/a)+1).map(function(b){return e+b*a});return d.concat(f).concat(0===c%a?[]:[c])}};c.integerTickGenerator=function(){return function(a){var b=a.defaultTicks();return b.filter(function(a,c){return 0===a%1||0===c||c===b.length-1})}}},function(a,c,d){var b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=null===b?Object.create(b):(c.prototype=b.prototype,new c)},f=d(1),\ng=d(26);a=function(a){function c(){var b=a.call(this)||this;b._d3Scale=f.scaleTime();b.autoDomain();return b}b(c,a);c.prototype.tickInterval=function(a,b){void 0===b&&(b=1);var d=f.scaleTime();a=c.timeIntervalToD3Time(a).every(b);d.domain(this.domain());d.range(this.range());return d.ticks(a)};c.prototype._setDomain=function(b){if(b[1]<b[0])throw Error(\"Scale.Time domain values must be in chronological order\");return a.prototype._setDomain.call(this,b)};c.prototype._defaultExtent=function(){return[new Date(\"1970-01-01\"),\nnew Date(\"1970-01-02\")]};c.prototype._expandSingleValueDomain=function(a){var b=a[0].getTime(),c=a[1].getTime();return b===c?(a=new Date(b),a.setDate(a.getDate()-1),c=new Date(c),c.setDate(c.getDate()+1),[a,c]):a};c.prototype.scale=function(a){return this._d3Scale(a)};c.prototype.scaleTransformation=function(a){return this.scale(new Date(a))};c.prototype.invertedTransformation=function(a){return this.invert(a).getTime()};c.prototype.getTransformationDomain=function(){var a=this.domain();return[a[0].valueOf(),\na[1].valueOf()]};c.prototype._getDomain=function(){return this._backingScaleDomain()};c.prototype._backingScaleDomain=function(a){if(null==a)return this._d3Scale.domain();this._d3Scale.domain(a);return this};c.prototype._getRange=function(){return this._d3Scale.range()};c.prototype._setRange=function(a){this._d3Scale.range(a)};c.prototype.invert=function(a){return this._d3Scale.invert(a)};c.prototype.defaultTicks=function(){return this._d3Scale.ticks(c._DEFAULT_NUM_TICKS)};c.prototype._niceDomain=\nfunction(a){return this._d3Scale.copy().domain(a).nice().domain()};c.timeIntervalToD3Time=function(a){switch(a){case g.TimeInterval.second:return f.timeSecond;case g.TimeInterval.minute:return f.timeMinute;case g.TimeInterval.hour:return f.timeHour;case g.TimeInterval.day:return f.timeDay;case g.TimeInterval.week:return f.timeWeek;case g.TimeInterval.month:return f.timeMonth;case g.TimeInterval.year:return f.timeYear;default:throw Error(\"TimeInterval specified does not exist: \"+a);}};return c}(d(11).QuantitativeScale);\nc.Time=a},function(a,c,d){var b=d(1),f=Array;c.add=function(a,b){if(a.length!==b.length)throw Error(\"attempted to add arrays of unequal length\");return a.map(function(c,d){return a[d]+b[d]})};c.uniq=function(a){var c=b.set(),d=[];a.forEach(function(a){c.has(String(a))||(c.add(String(a)),d.push(a))});return d};c.flatten=function(a){return f.prototype.concat.apply([],a)};c.createFilledArray=function(a,b){for(var c=[],d=0;d<b;d++)c[d]=\"function\"===typeof a?a(d):a;return c}},function(a,c){a=function(){function a(a,\nb,c){this.maxIndex=this.minIndex=this.exitIndex=this.entryIndex=a;this.bucketValue=b;this.maxValue=this.minValue=c}a.prototype.isInBucket=function(a){return a==this.bucketValue};a.prototype.addToBucket=function(a,b){a<this.minValue&&(this.minValue=a,this.minIndex=b);a>this.maxValue&&(this.maxValue=a,this.maxIndex=b);this.exitIndex=b};a.prototype.getUniqueIndices=function(){var a=[this.entryIndex,this.maxIndex,this.minIndex,this.exitIndex];return a.filter(function(b,c){return 0==c||b!=a[c-1]})};return a}();\nc.Bucket=a},function(a,c,d){var b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=null===b?Object.create(b):(c.prototype=b.prototype,new c)};a=function(a){function c(){return null!==a&&a.apply(this,arguments)||this}b(c,a);c.prototype.callCallbacks=function(){for(var a=this,b=[],c=0;c<arguments.length;c++)b[c]=arguments[c];this.forEach(function(c){c.apply(a,b)});return this};return c}(d(50).Set);c.CallbackSet=a},function(a,\nc,d){function b(a){function b(a){a/=255;return.03928>=a?a/12.92:g.pow((a+.055)/1.055,2.4)}a=f.rgb(a);return.2126*b(a.r)+.7152*b(a.g)+.0722*b(a.b)}var f=d(1),g=Math;c.contrast=function(a,c){a=b(a)+.05;c=b(c)+.05;return a>c?a/c:c/a};c.lightenColor=function(a,b){return f.color(a).brighter(b).rgb().toString()};c.colorTest=function(a,b){a.classed(b,!0);var c=a.style(\"background-color\");if(\"transparent\"===c)return null;c=/\\((.+)\\)/.exec(c)[1].split(\",\").map(function(a){a=+a;var b=a.toString(16);return 16>\na?\"0\"+b:b});if(4===c.length&&\"00\"===c[3])return null;c=\"#\"+c.join(\"\");a.classed(b,!1);return c}},function(a,c,d){function b(a){if(\"number\"===typeof a)return{min:a,max:a};if(a instanceof Object&&\"min\"in a&&\"max\"in a)return a;throw Error(\"input '\"+a+\"' can't be parsed as an Range\");}function f(a,b){a=a.getPropertyValue(b);return parseFloat(a)||0}var g=d(1),k=Math;c.contains=function(a,b){for(;null!=b&&b!==a;)b=b.parentNode;return b===a};c.elementBBox=function(a){try{var b=a.node().getBBox()}catch(t){b=\n{x:0,y:0,width:0,height:0}}return b};c.SCREEN_REFRESH_RATE_MILLISECONDS=1E3/60;c.requestAnimationFramePolyfill=function(a){null!=window.requestAnimationFrame?window.requestAnimationFrame(a):setTimeout(a,c.SCREEN_REFRESH_RATE_MILLISECONDS)};c.elementWidth=function(a){a=a instanceof g.selection?a.node():a;a=window.getComputedStyle(a);return f(a,\"width\")+f(a,\"padding-left\")+f(a,\"padding-right\")+f(a,\"border-left-width\")+f(a,\"border-right-width\")};c.elementHeight=function(a){a=a instanceof g.selection?\na.node():a;a=window.getComputedStyle(a);return f(a,\"height\")+f(a,\"padding-top\")+f(a,\"padding-bottom\")+f(a,\"border-top-width\")+f(a,\"border-bottom-width\")};var l=/translate\\s*\\(\\s*((?:[-+]?[0-9]*\\.?[0-9]+))(?:(?:(?:\\s+,?\\s*)|(?:,\\s*))((?:[-+]?[0-9]*\\.?[0-9]+)))?\\s*\\)/,m=/rotate\\s*\\(\\s*((?:[-+]?[0-9]*\\.?[0-9]+))\\s*\\)/,n=/scale\\s*\\(\\s*((?:[-+]?[0-9]*\\.?[0-9]+))(?:(?:(?:\\s+,?\\s*)|(?:,\\s*))((?:[-+]?[0-9]*\\.?[0-9]+)))?\\s*\\)/;c.getTranslateValues=function(a){a=l.exec(a.attr(\"transform\"));if(null!=a){var b=\na[2];return[+a[1],+(void 0===b?0:b)]}return[0,0]};c.getRotate=function(a){a=m.exec(a.attr(\"transform\"));return null!=a?+a[1]:0};c.getScaleValues=function(a){var b=n.exec(a.attr(\"transform\"));return null!=b?(a=b[1],b=b[2],[+a,null==b?+a:+b]):[0,0]};c.clientRectsOverlap=function(a,b){return k.floor(a.right)<=k.ceil(b.left)||k.ceil(a.left)>=k.floor(b.right)||k.floor(a.bottom)<=k.ceil(b.top)||k.ceil(a.top)>=k.floor(b.bottom)?!1:!0};c.expandRect=function(a,b){return{left:a.left-b,top:a.top-b,right:a.right+\nb,bottom:a.bottom+b,width:a.width+2*b,height:a.height+2*b}};c.clientRectInside=function(a,b){return k.floor(b.left)<=k.ceil(a.left)&&k.floor(b.top)<=k.ceil(a.top)&&k.floor(a.right)<=k.ceil(b.right)&&k.floor(a.bottom)<=k.ceil(b.bottom)};c.intersectsBBox=function(a,c,d,e){void 0===e&&(e=.5);a=b(a);c=b(c);return d.x+d.width>=a.min-e&&d.x<=a.max+e&&d.y+d.height>=c.min-e&&d.y<=c.max+e}},function(a,c,d){var b=d(1),f=d(33);a=function(){function a(){this._entities=[];this._tree=b.quadtree().x(function(a){return Math.floor(a.position.x)}).y(function(a){return Math.floor(a.position.y)})}\na.prototype.addAll=function(a,b){(d=this._entities).push.apply(d,a);if(void 0!==b)for(d=0;d<a.length;d++){var c=a[d];f.within(c.position,b)&&this._tree.add(c)}else this._tree.addAll(a);var d};a.prototype.entityNearest=function(a){return this._tree.find(a.x,a.y)};a.prototype.entities=function(){return this._entities};return a}();c.EntityStore=a},function(a,c,d){var b=d(33);a=function(){function a(){\"function\"===typeof window.Map?this._es6Map=new window.Map:this._keyValuePairs=[]}a.prototype.set=function(a,\nc){if(b.isNaN(a))throw Error(\"NaN may not be used as a key to the Map\");if(null!=this._es6Map)return this._es6Map.set(a,c),this;for(var d=0;d<this._keyValuePairs.length;d++)if(this._keyValuePairs[d].key===a)return this._keyValuePairs[d].value=c,this;this._keyValuePairs.push({key:a,value:c});return this};a.prototype.get=function(a){if(null!=this._es6Map)return this._es6Map.get(a);for(var b=0;b<this._keyValuePairs.length;b++)if(this._keyValuePairs[b].key===a)return this._keyValuePairs[b].value};a.prototype.has=\nfunction(a){if(null!=this._es6Map)return this._es6Map.has(a);for(var b=0;b<this._keyValuePairs.length;b++)if(this._keyValuePairs[b].key===a)return!0;return!1};a.prototype.forEach=function(a,b){var c=this;null!=this._es6Map?this._es6Map.forEach(function(d,e){return a.call(b,d,e,c)},b):this._keyValuePairs.forEach(function(d){a.call(b,d.value,d.key,c)})};a.prototype.delete=function(a){if(null!=this._es6Map)return this._es6Map.delete(a);for(var b=0;b<this._keyValuePairs.length;b++)if(this._keyValuePairs[b].key===\na)return this._keyValuePairs.splice(b,1),!0;return!1};return a}();c.Map=a},function(a,c,d){var b=d(1),f=d(0);a=d(9);c.IStackingOrder=a.makeEnum([\"topdown\",\"bottomup\"]);var g=Math;c.stack=function(a,c,d,e){void 0===e&&(e=\"bottomup\");var g=b.map(),k=b.map(),l=new f.Map;\"topdown\"===e&&(a=a.slice(),a.reverse());a.forEach(function(a){var b=new f.Map;a.data().forEach(function(e,f){var l=String(c(e,f,a)),m=+d(e,f,a),n=0<=m?g:k;if(n.has(l)){var q=n.get(l);n.set(l,q+m)}else q=0,n.set(l,m);b.set(l,{offset:q,\nvalue:m,axisValue:c(e,f,a)})});l.set(a,b)});return l};c.stackedExtents=function(a){var b=new f.Map,c=new f.Map;a.forEach(function(a){a.forEach(function(a,d){var e=f.Math.max([a.offset+a.value,a.offset],a.offset),g=f.Math.min([a.offset+a.value,a.offset],a.offset);b.has(d)?b.get(d).extent<e&&b.set(d,{extent:e,axisValue:a.axisValue}):b.set(d,{extent:e,axisValue:a.axisValue});c.has(d)?c.get(d).extent>g&&c.set(d,{extent:g,axisValue:a.axisValue}):c.set(d,{extent:g,axisValue:a.axisValue})})});return{maximumExtents:b,\nminimumExtents:c}};c.stackedExtent=function(a,b,c){var d=[];a.forEach(function(a,e){e.data().forEach(function(f,g){if(null==c||c(f,g,e))f=a.get(String(b(f,g,e))),d.push(f.value+f.offset)})});a=f.Math.max(d,0);var e=f.Math.min(d,0);return[g.min(e,0),g.max(0,a)]};c.normalizeKey=function(a){return String(a)}},function(a,c,d){function b(a,b,c){a.styles({left:b+\"px\",top:c+\"px\"});a.attrs({x:\"\"+b,y:\"\"+c})}var f=d(1),g=d(0);c.getTranslator=function(a){a=a.root().rootElement().node();var b=a.__Plottable_ClientTranslator;\nnull==b&&(b=document.createElementNS(a.namespaceURI,\"svg\"),b.setAttribute(\"class\",\"measurer\"),b.setAttribute(\"style\",\"opacity: 0; visibility: hidden; position: absolute; width: 1px; height: 1px;\"),a.appendChild(b),b=new k(f.select(b)),a.__Plottable_ClientTranslator=b);return b};var k=function(){function a(a){this._measurementElement=a}a.prototype.computePosition=function(c,d){b(this._measurementElement,0,0);var e=this._measurementElement.node().getBoundingClientRect(),f=e.left,g=e.top;b(this._measurementElement,\na.SAMPLE_DISTANCE,a.SAMPLE_DISTANCE);var e=this._measurementElement.node().getBoundingClientRect(),k=e.left,e=e.top;if(f===k||g===e)return null;var k=(k-f)/a.SAMPLE_DISTANCE,l=(e-g)/a.SAMPLE_DISTANCE;b(this._measurementElement,(c-f)/k,(d-g)/l);e=this._measurementElement.node().getBoundingClientRect();return{x:(e.left-f)/k,y:(e.top-g)/l}};a.prototype.isInside=function(a,b){return g.DOM.contains(a.root().rootElement().node(),b.target)};return a}();k.SAMPLE_DISTANCE=100;c.Translator=k},function(a,c,\nd){Object.defineProperty(c,\"__esModule\",{value:!0});var b=d(115);d.d(c,\"easeLinear\",function(){return b.a});var f=d(117);d.d(c,\"easeQuad\",function(){return f.a});d.d(c,\"easeQuadIn\",function(){return f.b});d.d(c,\"easeQuadOut\",function(){return f.c});d.d(c,\"easeQuadInOut\",function(){return f.a});var g=d(112);d.d(c,\"easeCubic\",function(){return g.a});d.d(c,\"easeCubicIn\",function(){return g.b});d.d(c,\"easeCubicOut\",function(){return g.c});d.d(c,\"easeCubicInOut\",function(){return g.a});var k=d(116);d.d(c,\n\"easePoly\",function(){return k.a});d.d(c,\"easePolyIn\",function(){return k.b});d.d(c,\"easePolyOut\",function(){return k.c});d.d(c,\"easePolyInOut\",function(){return k.a});var l=d(118);d.d(c,\"easeSin\",function(){return l.a});d.d(c,\"easeSinIn\",function(){return l.b});d.d(c,\"easeSinOut\",function(){return l.c});d.d(c,\"easeSinInOut\",function(){return l.a});var m=d(114);d.d(c,\"easeExp\",function(){return m.a});d.d(c,\"easeExpIn\",function(){return m.b});d.d(c,\"easeExpOut\",function(){return m.c});d.d(c,\"easeExpInOut\",\nfunction(){return m.a});var n=d(111);d.d(c,\"easeCircle\",function(){return n.a});d.d(c,\"easeCircleIn\",function(){return n.b});d.d(c,\"easeCircleOut\",function(){return n.c});d.d(c,\"easeCircleInOut\",function(){return n.a});var q=d(110);d.d(c,\"easeBounce\",function(){return q.a});d.d(c,\"easeBounceIn\",function(){return q.b});d.d(c,\"easeBounceOut\",function(){return q.a});d.d(c,\"easeBounceInOut\",function(){return q.c});var p=d(109);d.d(c,\"easeBack\",function(){return p.a});d.d(c,\"easeBackIn\",function(){return p.b});\nd.d(c,\"easeBackOut\",function(){return p.c});d.d(c,\"easeBackInOut\",function(){return p.a});var t=d(113);d.d(c,\"easeElastic\",function(){return t.a});d.d(c,\"easeElasticIn\",function(){return t.b});d.d(c,\"easeElasticOut\",function(){return t.a});d.d(c,\"easeElasticInOut\",function(){return t.c})},function(a,c,d){d.d(c,\"b\",function(){return b});d.d(c,\"c\",function(){return f});d.d(c,\"a\",function(){return g});var b=function l(a){function b(b){return b*b*((a+1)*b-a)}a=+a;b.overshoot=l;return b}(1.70158),f=function m(a){function b(b){return--b*\nb*((a+1)*b+a)+1}a=+a;b.overshoot=m;return b}(1.70158),g=function n(a){function b(b){return(1>(b*=2)?b*b*((a+1)*b-a):(b-=2)*b*((a+1)*b+a)+2)/2}a=+a;b.overshoot=n;return b}(1.70158)},function(a,c){function b(a){return(a=+a)<e?t*a*a:a<g?t*(a-=f)*a+k:a<m?t*(a-=l)*a+n:t*(a-=q)*a+p}c.b=function(a){return 1-b(1-a)};c.a=b;c.c=function(a){return(1>=(a*=2)?1-b(1-a):b(a-1)+1)/2};var e=4/11,f=6/11,g=8/11,k=.75,l=9/11,m=10/11,n=.9375,q=21/22,p=.984375,t=1/e/e},function(a,c){c.b=function(a){return 1-Math.sqrt(1-\na*a)};c.c=function(a){return Math.sqrt(1- --a*a)};c.a=function(a){return(1>=(a*=2)?1-Math.sqrt(1-a*a):Math.sqrt(1-(a-=2)*a)+1)/2}},function(a,c){c.b=function(a){return a*a*a};c.c=function(a){return--a*a*a+1};c.a=function(a){return(1>=(a*=2)?a*a*a:(a-=2)*a*a+2)/2}},function(a,c,d){d.d(c,\"b\",function(){return f});d.d(c,\"a\",function(){return g});d.d(c,\"c\",function(){return k});var b=2*Math.PI,f=function m(a,c){function d(b){return a*Math.pow(2,10*--b)*Math.sin((e-b)/c)}var e=Math.asin(1/(a=Math.max(1,\na)))*(c/=b);d.amplitude=function(a){return m(a,c*b)};d.period=function(b){return m(a,b)};return d}(1,.3),g=function n(a,c){function d(b){return 1-a*Math.pow(2,-10*(b=+b))*Math.sin((b+e)/c)}var e=Math.asin(1/(a=Math.max(1,a)))*(c/=b);d.amplitude=function(a){return n(a,c*b)};d.period=function(b){return n(a,b)};return d}(1,.3),k=function q(a,c){function d(b){return(0>(b=2*b-1)?a*Math.pow(2,10*b)*Math.sin((e-b)/c):2-a*Math.pow(2,-10*b)*Math.sin((e+b)/c))/2}var e=Math.asin(1/(a=Math.max(1,a)))*(c/=b);\nd.amplitude=function(a){return q(a,c*b)};d.period=function(b){return q(a,b)};return d}(1,.3)},function(a,c){c.b=function(a){return Math.pow(2,10*a-10)};c.c=function(a){return 1-Math.pow(2,-10*a)};c.a=function(a){return(1>=(a*=2)?Math.pow(2,10*a-10):2-Math.pow(2,10-10*a))/2}},function(a,c){c.a=function(a){return+a}},function(a,c,d){d.d(c,\"b\",function(){return b});d.d(c,\"c\",function(){return f});d.d(c,\"a\",function(){return g});var b=function l(a){function b(b){return Math.pow(b,a)}a=+a;b.exponent=l;\nreturn b}(3),f=function m(a){function b(b){return 1-Math.pow(1-b,a)}a=+a;b.exponent=m;return b}(3),g=function n(a){function b(b){return(1>=(b*=2)?Math.pow(b,a):2-Math.pow(2-b,a))/2}a=+a;b.exponent=n;return b}(3)},function(a,c){c.b=function(a){return a*a};c.c=function(a){return a*(2-a)};c.a=function(a){return(1>=(a*=2)?a*a:--a*(2-a)+1)/2}},function(a,c){c.b=function(a){return 1-Math.cos(a*e)};c.c=function(a){return Math.sin(a*e)};c.a=function(a){return(1-Math.cos(b*a))/2};var b=Math.PI,e=b/2},function(a,\nc){a=function(){function a(a,b,c){void 0===b&&(b=10);void 0===c&&(c={});var d=this;this.ctx=a;this.lineHeight=b;this.style=c;this.createRuler=function(){return function(a){d.ctx.font=d.style.font;return{width:d.ctx.measureText(a).width,height:d.lineHeight}}};this.createPen=function(a,b,c){null==c&&(c=d.ctx);c.save();c.translate(b.translate[0],b.translate[1]);c.rotate(b.rotate*Math.PI/180);return d.createCanvasPen(c)};void 0===this.style.fill&&(this.style.fill=\"#444\")}a.prototype.createCanvasPen=function(a){var b=\nthis;return{destroy:function(){a.restore()},write:function(c,d,e,f){a.textAlign=d;null!=b.style.font&&(a.font=b.style.font);null!=b.style.fill&&(a.fillStyle=b.style.fill,a.fillText(c,e,f));null!=b.style.stroke&&(a.strokeStyle=b.style.fill,a.strokeText(c,e,f))}}};return a}();c.CanvasContext=a},function(a,c){var b=function(){function a(){}a.append=function(b,c){for(var d=[],e=2;e<arguments.length;e++)d[e-2]=arguments[e];d=a.create.apply(a,[c].concat(d));b.appendChild(d);return d};a.create=function(b){for(var c=\n[],d=1;d<arguments.length;d++)c[d-1]=arguments[d];d=document.createElementNS(a.SVG_NS,b);a.addClasses.apply(a,[d].concat(c));return d};a.addClasses=function(a){for(var b=[],c=1;c<arguments.length;c++)b[c-1]=arguments[c];b=b.filter(function(a){return null!=a});null!=a.classList?b.forEach(function(b){a.classList.add(b)}):a.setAttribute(\"class\",b.join(\" \"))};a.getDimensions=function(a){if(a.getBBox)try{var b=a.getBBox();return{width:b.width,height:b.height}}catch(k){}return{height:0,width:0}};return a}();\nb.SVG_NS=\"http://www.w3.org/2000/svg\";c.SvgUtils=b;a=function(){function a(a,c,d){void 0===d&&(d=!1);var e=this;this.element=a;this.className=c;this.addTitleElement=d;this.createRuler=function(){var a=e.getTextElements(e.element),c=a.parentElement,d=a.containerElement,f=a.textElement;return function(a){c.appendChild(d);f.textContent=a;a=b.getDimensions(f);c.removeChild(d);return a}};this.createPen=function(a,c,d){null==d&&(d=e.element);d=b.append(d,\"g\",\"text-container\",e.className);e.addTitleElement&&\n(b.append(d,\"title\").textContent=a,d.setAttribute(\"title\",a));a=b.append(d,\"g\",\"text-area\");a.setAttribute(\"transform\",\"translate(\"+c.translate[0]+\",\"+c.translate[1]+\")\"+(\"rotate(\"+c.rotate+\")\"));return e.createSvgLinePen(a)}}a.prototype.setAddTitleElement=function(a){this.addTitleElement=a};a.prototype.createSvgLinePen=function(a){return{write:function(c,d,e,f){var g=b.append(a,\"text\",\"text-line\");g.textContent=c;g.setAttribute(\"text-anchor\",d);g.setAttribute(\"transform\",\"translate(\"+e+\",\"+f+\")\");\ng.setAttribute(\"y\",\"-0.25em\")}}};a.prototype.getTextElements=function(a){if(\"text\"===a.tagName){var c=a.parentElement;null==c&&(c=a.parentNode);c.removeChild(a);return{containerElement:a,parentElement:c,textElement:a}}var d=a.querySelector(\"text\");if(null!=d)return c=a.parentElement,null==c&&(c=a.parentNode),c.removeChild(a),{containerElement:a,parentElement:c,textElement:d};c=b.create(\"text\",this.className);return{containerElement:c,parentElement:a,textElement:c}};return a}();c.SvgContext=a},function(a,\nc,d){var b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=null===b?Object.create(b):(c.prototype=b.prototype,new c)},f=d(20),g=d(34);a=function(a){function c(b){var c=a.call(this,b)||this;c.dimCache=new f.Cache(function(a){return c._measureNotFromCache(a)});return c}b(c,a);c.prototype._measureNotFromCache=function(b){return a.prototype.measure.call(this,b)};c.prototype.measure=function(a){void 0===a&&(a=g.AbstractMeasurer.HEIGHT_TEXT);\nreturn this.dimCache.get(a)};c.prototype.reset=function(){this.dimCache.clear();a.prototype.reset.call(this)};return c}(d(52).CacheCharacterMeasurer);c.CacheMeasurer=a},function(a,c,d){var b=d(51),f=d(54),g=d(56),k=d(58);a=function(){function a(a){this.context=a;this.measurer=new f.CacheMeasurer(this.context);this.wrapper=new g.Wrapper;this.writer=new k.Writer(this.measurer,this.context,this.wrapper)}a.svg=function(c,d,e){return new a(new b.SvgContext(c,d,e))};a.canvas=function(c,d,e){return new a(new b.CanvasContext(c,\nd,e))};a.prototype.write=function(a,b,c,d,e){this.writer.write(a,b,c,d,e)};a.prototype.clearMeasurerCache=function(){this.measurer.reset()};return a}();c.Typesetter=a},function(a,c){a=function(){function a(a){this.cache={};this.compute=a}a.prototype.get=function(a){this.cache.hasOwnProperty(a)||(this.cache[a]=this.compute(a));return this.cache[a]};a.prototype.clear=function(){this.cache={};return this};return a}();c.Cache=a},function(a,c){a=function(){function a(){}a.arrayEq=function(a,b){if(null==\na||null==b)return a===b;if(a.length!==b.length)return!1;for(var c=0;c<a.length;c++)if(a[c]!==b[c])return!1;return!0};a.objEq=function(b,c){if(null==b||null==c)return b===c;var d=Object.keys(b).sort(),e=Object.keys(c).sort(),f=d.map(function(a){return b[a]}),m=e.map(function(a){return c[a]});return a.arrayEq(d,e)&&a.arrayEq(f,m)};a.strictEq=function(a,b){return a===b};a.defaults=function(a){for(var b=[],c=1;c<arguments.length;c++)b[c-1]=arguments[c];if(null==a)throw new TypeError(\"Cannot convert undefined or null to object\");\nvar d=Object(a);b.forEach(function(a){if(null!=a)for(var b in a)Object.prototype.hasOwnProperty.call(a,b)&&(d[b]=a[b])});return d};return a}();c.Methods=a},function(a,c){a=function(){function a(){}a.combineWhitespace=function(a){return a.replace(/[ \\t]+/g,\" \")};a.isNotEmptyString=function(a){return a&&\"\"!==a.trim()};a.trimStart=function(b,c){if(!b)return b;b=b.split(\"\");var d=c?function(b){return b.split(c).some(a.isNotEmptyString)}:a.isNotEmptyString;return b.reduce(function(a,b){return d(a+b)?a+\nb:a},\"\")};a.trimEnd=function(b,c){if(!b)return b;b=b.split(\"\");b.reverse();b=a.trimStart(b.join(\"\"),c).split(\"\");b.reverse();return b.join(\"\")};return a}();c.StringMethods=a},function(a,c){a=function(){function a(){this.WordDividerRegExp=/\\W/;this.WhitespaceRegExp=/\\s/}a.prototype.tokenize=function(a){var b=this;return a.split(\"\").reduce(function(a,c){return a.slice(0,-1).concat(b.shouldCreateNewToken(a[a.length-1],c))},[\"\"])};a.prototype.shouldCreateNewToken=function(a,b){if(!a)return[b];var c=a[a.length-\n1];return this.WhitespaceRegExp.test(c)&&this.WhitespaceRegExp.test(b)?[a+b]:this.WhitespaceRegExp.test(c)||this.WhitespaceRegExp.test(b)?[a,b]:this.WordDividerRegExp.test(c)||this.WordDividerRegExp.test(b)?c===b?[a+b]:[a,b]:[a+b]};return a}();c.Tokenizer=a},function(a,c,d){var b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=null===b?Object.create(b):(c.prototype=b.prototype,new c)};a=function(a){function c(){return a.apply(this,\narguments)||this}b(c,a);c.prototype.wrap=function(b,d,e,f){void 0===f&&(f=Infinity);if(1<b.split(\"\\n\").length)throw Error(\"SingleLineWrapper is designed to work only on single line\");var g=a.prototype.wrap.call(this,b,d,e,f);if(2>g.noLines)return g;for(var k=0,l=0;l<c.NO_WRAP_ITERATIONS&&e>k;++l){var m=(e+k)/2,n=a.prototype.wrap.call(this,b,d,m,f);this.areSameResults(g,n)?(e=m,g=n):k=m}return g};c.prototype.areSameResults=function(a,b){return a.noLines===b.noLines&&a.truncatedText===b.truncatedText};\nreturn c}(d(57).Wrapper);a.NO_WRAP_ITERATIONS=5;c.SingleLineWrapper=a},function(a,c,d){var b=d(20),f={textRotation:0,textShear:0,xAlign:\"left\",yAlign:\"top\"};a=function(){function a(a,b,c){this._measurer=a;this._penFactory=b;this._wrapper=c}a.prototype.measurer=function(a){this._measurer=a;return this};a.prototype.wrapper=function(a){this._wrapper=a;return this};a.prototype.penFactory=function(a){this._penFactory=a;return this};a.prototype.write=function(c,d,e,g,q){void 0===g&&(g={});g=b.Methods.defaults({},\nf,g);if(-1===a.SupportedRotation.indexOf(g.textRotation))throw Error(\"unsupported rotation - \"+g.textRotation+\". Supported rotations are \"+a.SupportedRotation.join(\", \"));if(null!=g.textShear&&-80>g.textShear||80<g.textShear)throw Error(\"unsupported shear angle - \"+g.textShear+\". Must be between -80 and 80\");var k=45<Math.abs(Math.abs(g.textRotation)-90),l=k?d:e,m=k?e:d,n=g.textShear,w=n*Math.PI/180,k=this._measurer.measure().height,z=k*Math.tan(w),l=l/Math.cos(w)-Math.abs(z),y=m*Math.cos(w),m=b.StringMethods.combineWhitespace(c),\nm=(this._wrapper?this._wrapper.wrap(m,this._measurer,l,y).wrappedText:m).split(\"\\n\"),w=a.XOffsetFactor[g.xAlign]*l*Math.sin(w)-a.YOffsetFactor[g.yAlign]*(y-m.length*k),n=g.textRotation+n;switch(g.textRotation){case 90:d=[d+w,0];break;case -90:d=[-w,e];break;case 180:d=[d,e+w];break;default:d=[0,-w]}c=this._penFactory.createPen(c,{translate:d,rotate:n},q);this.writeLines(m,c,l,k,z,g.xAlign);null!=c.destroy&&c.destroy()};a.prototype.writeLines=function(b,c,d,e,f,g){b.forEach(function(b,k){c.write(b,\na.AnchorConverter[g],(0<f?(k+1)*f:k*f)+d*a.XOffsetFactor[g],(k+1)*e)})};return a}();a.SupportedRotation=[-90,0,180,90];a.AnchorConverter={center:\"middle\",left:\"start\",right:\"end\"};a.XOffsetFactor={center:.5,left:0,right:1};a.YOffsetFactor={bottom:1,center:.5,top:0};c.Writer=a},function(a,c,d){function b(a){for(var b in a)c.hasOwnProperty(b)||(c[b]=a[b])}d(63);a=d(7);c.Animators=a;a=d(59);c.Axes=a;a=d(35);c.Components=a;a=d(22);c.Configs=a;a=d(10);c.Formatters=a;a=d(28);c.RenderController=a;a=d(36);\nc.RenderPolicies=a;a=d(29);c.SymbolFactories=a;a=d(13);c.Dispatchers=a;a=d(62);c.Drawers=a;a=d(14);c.Interactions=a;a=d(17);c.Plots=a;a=d(3);c.Scales=a;a=d(0);c.Utils=a;b(d(21));a=d(26);c.TimeInterval=a.TimeInterval;b(d(4));b(d(27));b(d(60));a=d(61);c.version=a.version;b(d(23));b(d(6));b(d(15));b(d(37));b(d(16));b(d(2));b(d(11));b(d(18))}])}\n\"object\"===typeof exports&&\"object\"===typeof module?module.exports=ae(require(\"d3\")):\"function\"===typeof define&&define.amd?define([\"d3\"],ae):\"object\"===typeof exports?exports.Plottable=ae(require(\"d3\")):this.Plottable=ae(this.d3);\n</script>\n<style>\n.plottable-colors-0 {\n  background-color: #5279c7; /* INDIGO */\n}\n\n.plottable-colors-1 {\n  background-color: #fd373e; /* CORAL_RED */\n}\n\n.plottable-colors-2 {\n  background-color: #63c261; /* FERN */\n}\n\n.plottable-colors-3 {\n  background-color: #fad419; /* BRIGHT_SUN */\n}\n\n.plottable-colors-4 {\n  background-color: #2c2b6f; /* JACARTA */\n}\n\n.plottable-colors-5 {\n  background-color: #ff7939; /* BURNING_ORANGE */\n}\n\n.plottable-colors-6 {\n  background-color: #db2e65; /* CERISE_RED */\n}\n\n.plottable-colors-7 {\n  background-color: #99ce50; /* CONIFER */\n}\n\n.plottable-colors-8 {\n  background-color: #962565; /* ROYAL_HEATH */\n}\n\n.plottable-colors-9 {\n  background-color: #06cccc; /* ROBINS_EGG_BLUE */\n}\n\n/**\n * User-supplied renderTo element.\n */\n.plottable {\n  display: block; /* must be block elements for width/height calculations to work in Firefox. */\n  pointer-events: visibleFill;\n  position: relative;\n  /**\n   * Pre 3.0, users could set the dimension of the root element in two ways: either using CSS\n   * (inline or through a stylesheet), or using the SVG width/height attributes. By default, we\n   * set the SVG width/height attributes to 100%.\n   *\n   * Post 3.0 the root element is always a normal div and the only way to set the dimensions is\n   * to use CSS. To replicate the \"100%-by-default\" behavior, we apply width/height 100%.\n   */\n  width: 100%;\n  height: 100%;\n}\n\n/**\n * The _element that roots each Component's DOM.\n */\n.plottable .component {\n  /* Allow components to be positioned with explicit left/top/width/height styles */\n  position: absolute;\n}\n\n.plottable .background-container,\n.plottable .content,\n.plottable .foreground-container {\n  position: absolute;\n  width: 100%;\n  height: 100%;\n}\n\n/**\n * Don't allow svg elements above the content to steal events\n */\n.plottable .foreground-container {\n  pointer-events: none;\n}\n\n.plottable .component-overflow-hidden {\n  overflow: hidden;\n}\n\n.plottable .component-overflow-visible {\n  overflow: visible;\n}\n\n.plottable .plot-canvas-container {\n  width: 100%;\n  height: 100%;\n  overflow: hidden;\n}\n\n.plottable .plot-canvas {\n  width: 100%;\n  height: 100%;\n  /**\n   * Play well with deferred rendering.\n   */\n  transform-origin: 0px 0px 0px;\n}\n\n.plottable .label text {\n  font-family: \"Helvetica Neue\", sans-serif;\n  fill: #32313F;\n}\n\n.plottable .bar-label-text-area text {\n  font-family: \"Helvetica Neue\", sans-serif;\n  font-size: 12px;\n}\n\n.plottable .label-area text {\n  fill: #32313F;\n  font-family: \"Helvetica Neue\", sans-serif;\n  font-size: 14px;\n}\n\n.plottable .light-label text {\n  fill: white;\n}\n\n.plottable .dark-label text {\n  fill: #32313F;\n}\n\n.plottable .off-bar-label text {\n  fill: #32313F;\n}\n\n.plottable .stacked-bar-label text {\n  fill: #32313F;\n  font-style: normal;\n}\n\n.plottable .stacked-bar-plot .off-bar-label {\n  /* HACKHACK #2795: correct off-bar label logic to be implemented on StackedBar */\n  visibility: hidden !important;\n}\n\n.plottable .axis-label text {\n  font-size: 10px;\n  font-weight: bold;\n  letter-spacing: 1px;\n  line-height: normal;\n  text-transform: uppercase;\n}\n\n.plottable .title-label text {\n  font-size: 20px;\n  font-weight: bold;\n}\n\n.plottable .axis line.baseline {\n  stroke: #CCC;\n  stroke-width: 1px;\n}\n\n.plottable .axis line.tick-mark {\n  stroke: #CCC;\n  stroke-width: 1px;\n}\n\n.plottable .axis text {\n  fill: #32313F;\n  font-family: \"Helvetica Neue\", sans-serif;\n  font-size: 12px;\n  font-weight: 200;\n  line-height: normal;\n}\n\n.plottable .axis .annotation-circle {\n  fill: white;\n  stroke-width: 1px;\n  stroke: #CCC;\n}\n\n.plottable .axis .annotation-line {\n  stroke: #CCC;\n  stroke-width: 1px;\n}\n\n.plottable .axis .annotation-rect {\n  stroke: #CCC;\n  stroke-width: 1px;\n  fill: white;\n}\n\n.plottable .bar-plot .baseline {\n  stroke: #999;\n}\n\n.plottable .gridlines line {\n  stroke: #3C3C3C; /* hackhack: gridlines should be solid; see #820 */\n  opacity: 0.25;\n  stroke-width: 1px;\n}\n\n.plottable .selection-box-layer .selection-area {\n  fill: black;\n  fill-opacity: 0.03;\n  stroke: #CCC;\n}\n/* DragBoxLayer */\n.plottable .drag-box-layer.x-resizable .drag-edge-lr {\n  cursor: ew-resize;\n}\n.plottable .drag-box-layer.y-resizable .drag-edge-tb {\n  cursor: ns-resize;\n}\n\n.plottable .drag-box-layer.x-resizable.y-resizable .drag-corner-tl {\n  cursor: nwse-resize;\n}\n.plottable .drag-box-layer.x-resizable.y-resizable .drag-corner-tr {\n  cursor: nesw-resize;\n}\n.plottable .drag-box-layer.x-resizable.y-resizable .drag-corner-bl {\n  cursor: nesw-resize;\n}\n.plottable .drag-box-layer.x-resizable.y-resizable .drag-corner-br {\n  cursor: nwse-resize;\n}\n\n.plottable .drag-box-layer.movable .selection-area {\n  cursor: move; /* IE fallback */\n  cursor: -moz-grab;\n  cursor: -webkit-grab;\n  cursor: grab;\n}\n\n.plottable .drag-box-layer.movable .selection-area:active {\n  cursor: -moz-grabbing;\n  cursor: -webkit-grabbing;\n  cursor: grabbing;\n}\n/* /DragBoxLayer */\n\n.plottable .guide-line-layer line.guide-line {\n  stroke: #CCC;\n  stroke-width: 1px;\n}\n\n.plottable .drag-line-layer.enabled.vertical line.drag-edge {\n  cursor: ew-resize;\n}\n\n.plottable .drag-line-layer.enabled.horizontal line.drag-edge {\n  cursor: ns-resize;\n}\n\n.plottable .legend text {\n  fill: #32313F;\n  font-family: \"Helvetica Neue\", sans-serif;\n  font-size: 12px;\n  font-weight: bold;\n  line-height: normal;\n}\n\n.plottable .interpolated-color-legend rect.swatch-bounding-box {\n  fill: none;\n  stroke: #CCC;\n  stroke-width: 1px;\n  pointer-events: none;\n}\n\n.plottable .waterfall-plot line.connector {\n  stroke: #CCC;\n  stroke-width: 1px;\n}\n\n.plottable .pie-plot .arc.outline {\n  stroke-linejoin: round;\n}\n</style>\n\n<script>//~~WEBPATH~~/facets-overview/common/feature_statistics_generator.js\n/*\n\n Copyright 2017 Google Inc.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n     http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n*/\nfunction be(){this.vals=[];this.counts=[]}function ce(a){var b=new Nb;a.forEach(function(a){var c=de(a.data);c.setName(a.name);Pb(b).push(c)});return b}\nfunction de(a){var b={};if(null==a)return new Sb;a.forEach(function(a,d){if(null!=a){for(var c=Object.keys(a),f={},g=0;g<c.length;g++){var k=c[g],l=a[k];f[k]=!0;k in b||(b[k]=new be,b[k].missing=d,b[k].counts=[]);\"number\"===typeof l||\"string\"===typeof l?(b[k].vals.push(l),b[k].counts.push(1)):l instanceof Array&&(b[k].counts.push(l.length),(m=b[k].vals).push.apply(m,l))}Object.keys(b).forEach(function(a){a in f||(b[a].missing+=1)});var m}});Object.keys(b).forEach(function(a){var c=0,e=0,f=!1;b[a].vals.forEach(function(a){\"string\"===\ntypeof a?c+=1:(e+=1,f=f||!(a===+a&&a===(a|0)))});b[a].type=e>c?f?1:0:2});return ee(b,a.length)}function ee(a,b){var c=new Sb;G(c,2,b);for(var d in a)if(a.hasOwnProperty(d)){var e=new Yb;Wb(c).push(e);var f=a[d];e.setName(d);e.setType(f.type);1===f.type||0===f.type?(f=fe(f.vals,f.counts,b,f.missing),Ha(e,3,fc[0],f)):2===f.type&&(f=ge(f.vals,f.counts,b,f.missing),Ha(e,4,fc[0],f))}return c}\nfunction fe(a,b,c,d){var e=new nc;e.setCommonStats(he(b,c,d));var f=0,g=0,k=0;b=a.filter(function(a){return\"number\"===typeof a&&!isNaN(a)}).map(function(a){return+a}).sort(function(a,b){return a-b});0<b.length&&(G(e,5,b[0]),G(e,7,b[b.length-1]),c=Math.floor(b.length/2),e.setMedian(0!==b.length%2?b[c]:(b[c]+b[c-1])/2));b.forEach(function(a){0===a&&(k+=1);f+=a;g+=a*a});1<b.length&&e.setStdDev(Math.sqrt((g-f*f/b.length)/(b.length-1)));e.setMean(f/a.length);G(e,4,k);a=b.filter(function(a){return Infinity!==\na&&-Infinity!==a});c=b.filter(function(a){return Infinity===a}).length;d=b.filter(function(a){return-Infinity===a}).length;var l=a[0],m=a[a.length-1],l=d3.range(l,m,(m-l)/10),l=d3.histogram().thresholds(l)(a),n=e.addHistograms();n.setType(0);l.forEach(function(a){var b=n.addBuckets();b.setSampleCount(a.length);xd(b,a.x0);yd(b,a.x1)});l=n.getBucketsList();b.length&&-Infinity===b[0]&&(xd(l[0],-Infinity),l[0].setSampleCount(l[0].getSampleCount()+d));b.length&&Infinity===b[b.length-1]&&(yd(l[l.length-\n1],Infinity),l[l.length-1].setSampleCount(l[l.length-1].getSampleCount()+c));n=e.addHistograms();ie(n,a);return e}function ie(a,b){var c=[0,10,20,30,40,50,60,70,80,90,100],d=c.length-1,c=c.map(function(a){if(0===b.length)a=NaN;else{a=a/100*(b.length-1);var c=Math.floor(a);a=c===a?b[a]:b[c]+(b[c+1]-b[c])*(a-c)}return a});a.setType(1);for(var e=b.length/d,f=0;f<d;f++){var g=a.addBuckets();g.setSampleCount(e);xd(g,c[f]);yd(g,c[f+1])}}\nfunction ge(a,b,c,d){var e=new pc;e.setCommonStats(he(b,c,d));var f=0,g={};a.forEach(function(a){a=String(a);g[a]=(g[a]||0)+1;f+=a.length});0<a.length&&G(e,4,f/a.length);a=[];for(var k in g)g.hasOwnProperty(k)&&a.push({str:k,count:g[k]});e.setUnique(a.length);a=a.sort(function(a,b){return b.count-a.count});var l=new kd;e.setRankHistogram(l);a.length&&(k=e.addTopValues(),k.setValue(a[0].str),G(k,3,a[0].count));a.forEach(function(a,b){var c=l.addBuckets();c.setSampleCount(a.count);G(c,1,b);G(c,2,b);\nG(c,4,a.str)});return e}function he(a,b,c){var d=new Tc,e=Infinity,f=0,g=0;a.forEach(function(a){a<e&&(e=a);a>f&&(f=a);g+=a});d.setNumNonMissing(b-c);d.setNumMissing(c);G(d,3,e);G(d,4,f);0<a.length&&d.setAvgNumValues(g/a.length);b=new Kc;Ga(d,6,b);ie(b,a);return d};\n</script>\n<script>//~~WEBPATH~~/facets-overview/common/utils.js\nfunction je(){}function ke(a,b,c,d,e,f,g,k){var l=this;this.histMap={};this.name=a;b&&(this.histMap[le(!1,me)]=b);c&&(this.histMap[le(!0,me)]=c);d&&(this.histMap[le(!1,ne)]=d);e&&(this.histMap[le(!0,ne)]=e);f&&(this.histMap[le(!1,oe)]=f);g&&(this.histMap[le(!1,pe)]=g);k&&Object.keys(k).forEach(function(a){return l.histMap[a]=k[a]})}\nvar qe=function(){function a(a,c,d,e){this.name=a;this.stringValue=c;this.lowNumValue=d;this.highNumValue=e}a.prototype.clear=function(){this.highNumValue=this.lowNumValue=this.stringValue=this.name=void 0};a.prototype.equals=function(a){return a?this.name===a.name&&this.stringValue===a.stringValue&&this.lowNumValue===a.lowNumValue&&this.highNumValue===a.highNumValue:!1};return a}();\nfunction re(a){var b=se(a);if(0===b)return 0;var c=a.reduce(function(a,c){c=+c.getSampleCount()||0;if(0===c)return a;c/=b;return a-c*Math.log(c)},0);return 0===c?0:c/Math.log(a.length)}function te(a,b){return isFinite(a)&&-1===a.toString().indexOf(\"e\")?+(Math.round(Number(a+\"e+\"+b))+\"e-\"+b):a}function ue(a,b,c){return(a=a.histMap[le(b,c)])?a.getBucketsList():[]}function le(a,b){b=null==b?me:b;a&&(b=\"weighted\"+b);return b}\nfunction se(a){return a.map(function(a){return a.getSampleCount()}).reduce(function(a,c){return(+c||0)+a},0)}function ve(a){return a.map(function(a){return se(ue(a,!1))})}function we(a){var b=[];a.forEach(function(a){a.forEach(function(a){a=xe(Fd(a));-1===b.indexOf(a)&&b.push(a)})});return b}function xe(a){return null==a||\"\"===a?\"\\u00a0\":a}function Y(a){return null==a?0:\"inf\"===a?Infinity:\"-inf\"===a?-Infinity:+a}\nfunction ye(a){var b,c,d=a.map(function(a){return ue(a,!1)});var e=null;for(var f=0;f<d.length;f++)if(0<d[f].length){e=d[f][0];break}if(!e)return 0;for(var g=ve(a),f=0;f<g.length;f++)if(0===g[f])return Infinity;var k=0;if(e instanceof Cd)for(var l=we(d),f=1;f<a.length;f++){var m=d[0];var n=d[f];for(var q=c=0;q<l.length;q++){for(var p=l[q],t=e=b=0;t<m.length;t++)if(Fd(m[t])===p){b=m[t].getSampleCount()?m[t].getSampleCount():0;break}for(t=0;t<n.length;t++)if(Fd(n[t])===p){e=n[t].getSampleCount()?n[t].getSampleCount():\n0;break}c=ze(c,b,g[0],e,g[f])}k=Math.max(k,c)}else for(f=1;f<a.length;f++){m=d[0];n=d[f];c=0;l=Math.max(m.length,n.length);for(q=0;q<l;q++)b=q<m.length&&m[q].getSampleCount()?m[q].getSampleCount():0,e=q<n.length&&n[q].getSampleCount()?n[q].getSampleCount():0,c=ze(c,b,g[0],e,g[f]);k=Math.max(k,c)}return k}function ze(a,b,c,d,e){var f=b/c-d/e;b=b/(c*c)+d/(e*e);return a+(b?f*f/b:0)}\nfunction Ae(a){Pb(a).forEach(function(a){Wb(a).forEach(function(a){var b=[];if(hc(a)){var c=hc(a).getRankHistogram();c&&b.push(c);(a=hc(a).getTopValuesList())&&a.forEach(function(a){var b=u(a,1,0);b&&!+u(a,3,0)&&G(a,3,b)})}else W(a)&&(a=W(a).getHistogramsList())&&(b=b.concat(a));b.forEach(function(a){(a=a.getBucketsList())&&a.forEach(function(a){var b=u(a,3,0);b&&!a.getSampleCount()&&a.setSampleCount(b)})})})});return a}\nfunction Be(a){var b=!0;Pb(a).forEach(function(a){Wb(a).forEach(function(a){var c=[];if(hc(a)){var d=hc(a).getRankHistogram();d&&c.push(d);(a=hc(a).getTopValuesList())&&a.forEach(function(a){u(a,1,0)&&!+u(a,3,0)&&(b=!1)})}else W(a)&&(a=W(a).getHistogramsList())&&(c=c.concat(a));c.forEach(function(a){(a=a.getBucketsList())&&a.forEach(function(a){u(a,3,0)&&!a.getSampleCount()&&(b=!1)})})})});return b}\nfunction Ce(a){if(!a)return!1;for(var b=0;b<a.length;b++)if(a[b].histMap[le(!0,me)])return!0;return!1}function De(a){if(!a)return!1;for(var b=0;b<a.length;b++)if(a[b].histMap[ne])return!0;return!1}function Ee(a){return a?a.getNumNonMissing()*a.getAvgNumValues():0}\nfunction Fe(a){switch(a){case 0:return\"int\";case 1:return\"fixed-length ints\";case 2:return\"variable-length ints\";case 3:return\"float\";case 4:return\"fixed-length floats\";case 5:return\"variable-length floats\";case 6:return\"string\";case 7:return\"fixed-length strings\";case 8:return\"variable-length strings\";case 9:return\"bytes\";case 10:return\"fixed-length bytes\";case 11:return\"variable-length bytes\";default:return\"unknown\"}}function Ge(){}function He(){}function Ie(){}\nfunction Je(a){for(var b=0,c=0,d=0;d<a.length;d++)a[d].rawBuckets.length>b&&(b=a[d].rawBuckets.length,c=d);for(var d=[],e=0;e<b;e++){var f=new Ie;f.value=Fd(a[c].rawBuckets[e]);f.counts=[];for(var g=0;g<a.length;g++)a[g].rawBuckets.length<=e?f.counts.push(0):f.counts.push(a[g].rawBuckets[e].getSampleCount());d.push(f)}return d}\nfunction Ke(a,b){for(var c=[],d=0;d<b.length;d++){var e=new Ie,f=b[d];e.value=f;e.counts=[];for(var g=0;g<a.length;g++){for(var k=a[g].rawBuckets,l=-1,m=0;m<k.length;m++)if(Fd(k[m])===f){l=m;break}-1===l?e.counts.push(0):e.counts.push(k[l].getSampleCount())}c.push(e)}return c}var Le,Me=Le||(Le={});Me[Me.HISTOGRAM=0]=\"HISTOGRAM\";Me[Me.BAR_CHART=1]=\"BAR_CHART\";Me[Me.CUMDIST_CHART=2]=\"CUMDIST_CHART\";var me=\"Standard\",ne=\"Quantiles\",oe=\"Value list length\",pe=\"Feature list length\";\nfunction Ne(a,b){var c=!0,d=0;a.forEach(function(a){a.histMap[me]&&(a=a.histMap[me].getBucketsList(),d=Math.max(d,a.length),a.forEach(function(a){a.getLowValue||(c=!1)}))});return c?Le.HISTOGRAM:d>b?Le.CUMDIST_CHART:Le.BAR_CHART}var Oe=function(){function a(a,c,d){this.str=a;this.cssClass=c;this.fullStr=d;this.fullStr||(this.fullStr=a)}a.prototype.append=function(a,c){c&&(this.str+=c,this.fullStr+=c);this.str+=a.str;this.fullStr+=a.fullStr;this.cssClass+=a.cssClass};return a}();\nfunction Pe(a){var b=Math.abs(a);return(.01>b&&0<b||1E4<b)&&isFinite(a)?d3.format(\".3s\")(a).replace(/G$/,\"B\"):a.toLocaleString()}function Qe(a,b){var c=Pe(te(Y(a),1E6<Math.abs(a)?0:2));b=Re(a,b,void 0);return new Oe(c,b,a.toLocaleString([],{maximumFractionDigits:9}))}function Se(a,b,c){a=Y(a);a=null!=a&&b?a/b:0;b=.999999<a&&1>a?\"~100%\":1E-6>a&&0<a?\"~0%\":te(100*a,2)+\"%\";c=Re(a,!1,c);return new Oe(b,c,100*a+\"%\")}function Te(a,b,c){var d=Pe(a);b=Re(a,b,c);return new Oe(d,b,a.toLocaleString())}\nfunction Ue(a,b){a=xe(a);a=0===a.length||isNaN(+a)?a:'\"'+a+'\"';b=Re(a,b,void 0);return new Oe(a,b)}function Re(a,b,c){b=b?\"data-weighted \":\"\";if(c&&c(a)||\"number\"===typeof a&&!isFinite(a))b+=\"data-error \";return b}function Ve(a){var b=[];a?(b.push(Te(a.getNumNonMissing(),!1,function(a){return 0>=a})),b.push(Se(a.getNumMissing(),Y(a.getNumNonMissing())+Y(a.getNumMissing()),function(a){return.02<a}))):(b.push(Te(0,!1,function(a){return 0>=a})),b.push(Se(1,1,function(a){return.02<a})));return b}\nfunction We(a,b,c){var d=[];if(a)(c=c?O(a,Rc,9):null)?(d.push(Qe(c.getMean(),!0)),d.push(Qe(c.getStdDev(),!0))):(d.push(Qe(a.getMean())),d.push(Qe(a.getStdDev()))),d.push(Se(u(a,4,0),Ee(b),function(a){return.1<a})),b=Xe(a),d.push(Qe(b?NaN:+u(a,5,0))),c?d.push(Qe(c.getMedian(),!0)):d.push(Qe(a.getMedian())),d.push(Qe(b?NaN:+u(a,7,0)));else for(a=0;6>a;a++)d.push(Ue(\"-\"));return d}function Xe(a){if(!a)return!1;a=a.getHistogramsList();for(var b=0;b<a.length;b++)if(0<u(a[b],1,0))return!0;return!1}\nfunction Ye(a,b){var c=[];if(a){b=b?O(a,gd,6):null;c.push(Te(u(a,2,0)));var d=b?b.getTopValuesList():a.getTopValuesList();d&&0<d.length?(c.push(Ue(d[0].getValue(),!!b)),c.push(Qe(+u(d[0],3,0),!!b))):(c.push(Ue(\"-\")),c.push(Ue(\"-\")));c.push(Qe(+u(a,4,0)))}else for(a=0;4>a;a++)c.push(Ue(\"-\"));return c}\nfunction Ze(a){var b=[];if(a&&0<a.length){var c=new Oe(\"\",\"data-custom \");a.forEach(function(a){if(!O(a,Kc,4)){var b=a.getName();\"\"!==c.str&&(b=\"\\n\"+b);c.append(Ue(b));u(a,3,\"\")?c.append(Ue(u(a,3,\"\")),\": \"):c.append(Qe(+u(a,2,0)),\": \")}});b.push(c)}else a=new Oe(\"-\",\"data-custom \"),b.push(a);return b}\nfunction $e(a){var b=a.map(function(){return 0});a.forEach(function(a,d){a.forEach(function(a){b[d]+=Y(a.getSampleCount())})});return a.map(function(a,d){return a.map(function(a){if(a instanceof ud){var c=new ud;c.setSampleCount(a.getSampleCount()/b[d]);xd(c,a.getLowValue());yd(c,zd(a))}else{c=new Cd;c.setSampleCount(a.getSampleCount()/b[d]);var e=u(a,1,0);G(c,1,e);e=u(a,2,0);G(c,2,e);a=Fd(a);G(c,4,a)}return c})})}var af=Le;\n</script>\n<script>//~~WEBPATH~~/facets-overview/common/overview_data_model.js\nvar bf=function(){function a(a){this.data=a;this.colorScale=new Plottable.Scales.Color;this.colorScale.domain(Pb(a).map(function(a){return a.getName()}));this.colorScale.range(\"#4285F4 #F09300 #0F9D58 #9C27B0 #607D8B #0B8043 #757575\".split(\" \"));if(!Be(a))throw Error(\"input proto has not been cleaned\");this.featuresBySpec=this.makeFeatureBySpecList()}a.prototype.makeFeatureBySpecList=function(){for(var a=this,c=[],d=0;13>d;d++)c[d]=[];this.getUniqueFeatures().forEach(function(b){var d=a.getFeatureSpecForFeature(b.getName());\nc[d].push(b.getName())});return c};a.prototype.getNonEmptyFeatureSpecLists=function(){for(var a=[],c=0;13>c;c++)if(0!==this.featuresBySpec[c].length){var d=new Ge;d.features=this.featuresBySpec[c];d.spec=c;a.push(d)}return a};a.prototype.getFeatureSpecForFeature=function(a){for(var b=this.getDatasetNames(),d=12,e=0;e<b.length;e++){var f=this.getFeature(a,b[e]);if(null==f)f=12;else{var f=f.getType(),g=this.getFeatureCommonStats(a,b[e]),k=12;if(null!=g&&0!==g.getNumNonMissing()){var l=k=!1;u(g,3,0)===\nu(g,4,0)&&(1===u(g,3,0)?k=!0:l=!0);k=1===f?k?3:l?4:5:0===f?k?0:l?1:2:2===f?k?6:l?7:8:k?9:l?10:11}f=k}d=12===d?f:13<=d||12===f?d:3<=d&&5>=d&&3<=f&&5>=f||0<=d&&2>=d&&0<=f&&2>=f||6<=d&&8>=d&&6<=f&&8>=f||9<=d&&11>=d&&9<=f&&11>=f?Math.max(d,f):13}13===d&&(d=12);return d};a.prototype.getDatasetFeatureStatistics=function(){return this.data};a.prototype.getColorScale=function(){return this.colorScale};a.prototype.getDatasetNames=function(){return this.data?Pb(this.data).map(function(a){return a.getName()}):\n[]};a.prototype.getDataset=function(a){if(!this.data)return null;for(var b=0,d=Pb(this.data);b<d.length;b++){var e=d[b];if(e.getName()===a)return e}return null};a.prototype.getFeature=function(a,c){if(!a||!this.data)return null;var b=this.getDataset(c);if(!b)return null;c=0;for(b=Wb(b);c<b.length;c++){var e=b[c];if(e.getName()===a)return e}return null};a.prototype.getExtraHistogramNames=function(a){if(!this.data)return[];a=a.map(function(a){return a.getName()});for(var b={},d=0,e=Pb(this.data);d<\ne.length;d++)for(var f=0,g=Wb(e[d]);f<g.length;f++){var k=g[f];if(-1!==a.indexOf(k.getName())&&(lc(k)&&lc(k).forEach(function(a){O(a,Kc,4)&&(b[a.getName()]=!0)}),W(k)&&(k=W(k).getHistogramsList())))for(var l=0;l<k.length;l++){var m=k[l];m.getName()&&(b[m.getName()]=!0)}}return Object.keys(b)};a.prototype.getFeatureCommonStats=function(a,c){a=this.getFeature(a,c);return null==a?null:W(a)?Pc(W(a)):hc(a)?Pc(hc(a)):jc(a)?Pc(jc(a)):null};a.prototype.getFeatureNames=function(a){return a&&this.data?(a=this.getDataset(a))?\nWb(a).map(function(a){return a.getName()}):[]:null};a.prototype.getFeatureIndex=function(a,c){if(!this.data)return null;var b=this.getDataset(a);if(!b)return null;for(var e=a=0,b=Wb(b);e<b.length;e++){if(b[e].getName()===c)return a;++a}return null};a.prototype.getUniqueFeatures=function(){if(!this.data)return[];for(var a={},c=0,d=Pb(this.data);c<d.length;c++)for(var e=0,f=Wb(d[c]);e<f.length;e++){var g=f[e];a[g.getName()]=g}return Object.keys(a).map(function(b){return a[b]})};a.prototype.getNumUniqueFeaturesByType=\nfunction(a){return this.getUniqueFeatures().filter(function(b){return null!=W(b)===a}).length};a.prototype.featureHasSingleValue=function(a){if(!a)return!1;if(hc(a)){var b=u(hc(a),2,0);return 1===Y(b)}return jc(a)?(b=u(jc(a),2,0),1===Y(b)):W(a)?(b=+u(W(a),5,0),a=+u(W(a),7,0),null==b&&null==a?!1:Y(b)===Y(a)):!1};a.prototype.featureAcrossAllDatasetsHasSingleValue=function(a){if(!a||!this.data)return!1;for(var b=0,d=Pb(this.data);b<d.length;b++)for(var e=0,f=Wb(d[b]);e<f.length;e++){var g=f[e];if(a===\ng.getName()&&!this.featureHasSingleValue(g))return!1}return!0};a.prototype.getFeatureSingleValue=function(a){if(null==a)return\"\\x3cnull\\x3e\";if(hc(a))return a=hc(a).getTopValuesList(),null==a||0===a.length?\"\\x3cnull\\x3e\":a[0].getValue();if(jc(a))return 0===u(jc(a),2,0)?\"\\x3cnull\\x3e\":\"\\x3cbinary data\\x3e\";if(W(a)){var b=+u(W(a),5,0);if(b)return Y(b).toString();if(a=+u(W(a),7,0))return Y(a).toString()}return\"\\x3cunknown type\\x3e\"};a.prototype.getDatasetHistogramsForFeature=function(a){var b=[];if(this.data)for(var d=\nfunction(c){var d,f=c.getName(),g=null,k=null,p=null,t=null,r=null,v=null,w={};var z=0;for(var y=Wb(c);z<y.length;z++)if(c=y[z],c.getName()===a){if(z=e.getFeatureCommonStats(a,f))r=O(z,Kc,6),v=O(z,Kc,9);lc(c)&&lc(c).forEach(function(a){O(a,Kc,4)&&(w[a.getName()]=O(a,Kc,4))});if(W(c)){if(d=W(c).getHistogramsList())for(y=0;y<d.length;y++)z=d[y],z.getName()?w[z.getName()]=z:0===z.getType()?g=z:p=z;if(O(W(c),Rc,9)&&(c=O(W(c),Rc,9).getHistogramsList()))for(y=0;y<c.length;y++)z=c[y],0===z.getType()?k=z:\nt=z}else hc(c)&&(g=hc(c).getRankHistogram(),O(hc(c),gd,6)&&(k=O(hc(c),gd,6).getRankHistogram()));break}b.push(new ke(f,g,k,p,t,r,v,w))},e=this,f=0,g=Pb(this.data);f<g.length;f++)d(g[f]);return b};a.prototype.doesContainWeightedStats=function(){if(null==this.containsWeightedStats){a:{var a=this.data;for(var c=0;c<Pb(a).length;c++)for(var d=Pb(a)[c],e=0;e<Wb(d).length;e++){var f=Wb(d)[e];if(hc(f)){if(O(hc(f),gd,6)){a=!0;break a}}else if(W(f)&&O(W(f),Rc,9)){a=!0;break a}}a=!1}this.containsWeightedStats=\na}return this.containsWeightedStats};a.prototype.doesContainCustomStats=function(){if(null==this.containsCustomStats){a:{var a=this.data;for(var c=0;c<Pb(a).length;c++)for(var d=Pb(a)[c],e=0;e<Wb(d).length;e++){var f=lc(Wb(d)[e]);if(null!=f&&0<f.length){a=!0;break a}}a=!1}this.containsCustomStats=a}return this.containsCustomStats};a.prototype.doesContainFeatureListLengthData=function(){if(null==this.containsFeatureListLengthData){a:{var a=this.data;for(var c=0;c<Pb(a).length;c++)for(var d=Pb(a)[c],\ne=0;e<Wb(d).length;e++){var f=Wb(d)[e],g=null;hc(f)?g=Pc(hc(f)):W(f)?g=Pc(W(f)):jc(f)&&(g=Pc(jc(f)));if(g&&O(g,Kc,9)){a=!0;break a}}a=!1}this.containsFeatureListLengthData=a}return this.containsFeatureListLengthData};a.prototype.getChartAlpha=function(){return 2<=this.getDatasetNames().length?.4:1};a.prototype.getChartColorString=function(a){a=this.getColorScale().scale(this.getDatasetNames()[a]);var b=this.getChartAlpha();return a.replace(\"rgb\",\"rgba\").replace(\")\",\", \"+b+\")\")};return a}();\n</script>\n\n\n\n\n\n\n\n<script>//~~WEBPATH~~/iron-scroll-target-behavior/iron-scroll-target-behavior.html.js\nPolymer.IronScrollTargetBehavior={properties:{scrollTarget:{type:Object,value:function(){return this._defaultScrollTarget}}},observers:[\"_scrollTargetChanged(scrollTarget, isAttached)\"],_shouldHaveListener:!0,_scrollTargetChanged:function(a,b){this._oldScrollTarget&&(this._toggleScrollListener(!1,this._oldScrollTarget),this._oldScrollTarget=null);b&&(\"document\"===a?this.scrollTarget=this._doc:\"string\"===typeof a?this.scrollTarget=this.domHost?this.domHost.$[a]:Polymer.dom(this.ownerDocument).querySelector(\"#\"+\na):this._isValidScrollTarget()&&(this._boundScrollHandler=this._boundScrollHandler||this._scrollHandler.bind(this),this._oldScrollTarget=a,this._toggleScrollListener(this._shouldHaveListener,a)))},_scrollHandler:function(){},get _defaultScrollTarget(){return this._doc},get _doc(){return this.ownerDocument.documentElement},get _scrollTop(){return this._isValidScrollTarget()?this.scrollTarget===this._doc?window.pageYOffset:this.scrollTarget.scrollTop:0},get _scrollLeft(){return this._isValidScrollTarget()?\nthis.scrollTarget===this._doc?window.pageXOffset:this.scrollTarget.scrollLeft:0},set _scrollTop(a){this.scrollTarget===this._doc?window.scrollTo(window.pageXOffset,a):this._isValidScrollTarget()&&(this.scrollTarget.scrollTop=a)},set _scrollLeft(a){this.scrollTarget===this._doc?window.scrollTo(a,window.pageYOffset):this._isValidScrollTarget()&&(this.scrollTarget.scrollLeft=a)},scroll:function(a,b){this.scrollTarget===this._doc?window.scrollTo(a,b):this._isValidScrollTarget()&&(this.scrollTarget.scrollLeft=\na,this.scrollTarget.scrollTop=b)},get _scrollTargetWidth(){return this._isValidScrollTarget()?this.scrollTarget===this._doc?window.innerWidth:this.scrollTarget.offsetWidth:0},get _scrollTargetHeight(){return this._isValidScrollTarget()?this.scrollTarget===this._doc?window.innerHeight:this.scrollTarget.offsetHeight:0},_isValidScrollTarget:function(){return this.scrollTarget instanceof HTMLElement},_toggleScrollListener:function(a,b){this._boundScrollHandler&&(b=b===this._doc?window:b,a?b.addEventListener(\"scroll\",\nthis._boundScrollHandler):b.removeEventListener(\"scroll\",this._boundScrollHandler))},toggleScrollListener:function(a){this._shouldHaveListener=a;this._toggleScrollListener(a,this.scrollTarget)}};\n</script>\n\n\n\n\n<dom-module id=\"iron-list\">\n  <template>\n    <style>\n      :host {\n        display: block;\n        position: relative;\n      }\n\n      @media only screen and (-webkit-max-device-pixel-ratio: 1) {\n        :host {\n          will-change: transform;\n        }\n      }\n\n      #items {\n        @apply(--iron-list-items-container);\n        position: relative;\n      }\n\n      :host(:not([grid])) #items > ::content > * {\n        width: 100%;\n      };\n\n      #items > ::content > * {\n        box-sizing: border-box;\n        margin: 0;\n        position: absolute;\n        top: 0;\n        will-change: transform;\n      }\n    </style>\n\n    <array-selector id=\"selector\" items=\"{{items}}\" selected=\"{{selectedItems}}\" selected-item=\"{{selectedItem}}\">\n    </array-selector>\n\n    <div id=\"items\">\n      <content></content>\n    </div>\n\n  </template>\n</dom-module>\n\n<script>//~~WEBPATH~~/iron-list/iron-list.html.js\n(function(){var a=navigator.userAgent.match(/iP(?:hone|ad;(?: U;)? CPU) OS (\\d+)/),b=a&&8<=a[1];Polymer({is:\"iron-list\",properties:{items:{type:Array},maxPhysicalCount:{type:Number,value:500},as:{type:String,value:\"item\"},indexAs:{type:String,value:\"index\"},selectedAs:{type:String,value:\"selected\"},grid:{type:Boolean,value:!1,reflectToAttribute:!0},selectionEnabled:{type:Boolean,value:!1},selectedItem:{type:Object,notify:!0},selectedItems:{type:Object,notify:!0},multiSelection:{type:Boolean,value:!1}},\nobservers:[\"_itemsChanged(items.*)\",\"_selectionEnabledChanged(selectionEnabled)\",\"_multiSelectionChanged(multiSelection)\",\"_setOverflow(scrollTarget)\"],behaviors:[Polymer.Templatizer,Polymer.IronResizableBehavior,Polymer.IronA11yKeysBehavior,Polymer.IronScrollTargetBehavior],keyBindings:{up:\"_didMoveUp\",down:\"_didMoveDown\",enter:\"_didEnter\"},_ratio:.5,_scrollerPaddingTop:0,_scrollPosition:0,_physicalSize:0,_physicalAverage:0,_physicalAverageCount:0,_physicalTop:0,_virtualCount:0,_physicalIndexForKey:null,\n_estScrollHeight:0,_scrollHeight:0,_viewportHeight:0,_viewportWidth:0,_physicalItems:null,_physicalSizes:null,_firstVisibleIndexVal:null,_lastVisibleIndexVal:null,_collection:null,_maxPages:3,_focusedItem:null,_focusedIndex:-1,_offscreenFocusedItem:null,_focusBackfillItem:null,_itemsPerRow:1,_itemWidth:0,_rowHeight:0,_templateCost:0,get _physicalBottom(){return this._physicalTop+this._physicalSize},get _scrollBottom(){return this._scrollPosition+this._viewportHeight},get _virtualEnd(){return this._virtualStart+\nthis._physicalCount-1},get _hiddenContentSize(){return(this.grid?this._physicalRows*this._rowHeight:this._physicalSize)-this._viewportHeight},get _maxScrollTop(){return this._estScrollHeight-this._viewportHeight+this._scrollerPaddingTop},_minVirtualStart:0,get _maxVirtualStart(){return Math.max(0,this._virtualCount-this._physicalCount)},_virtualStartVal:0,set _virtualStart(a){this._virtualStartVal=Math.min(this._maxVirtualStart,Math.max(this._minVirtualStart,a))},get _virtualStart(){return this._virtualStartVal||\n0},_physicalStartVal:0,set _physicalStart(a){this._physicalStartVal=a%this._physicalCount;0>this._physicalStartVal&&(this._physicalStartVal=this._physicalCount+this._physicalStartVal);this._physicalEnd=(this._physicalStart+this._physicalCount-1)%this._physicalCount},get _physicalStart(){return this._physicalStartVal||0},_physicalCountVal:0,set _physicalCount(a){this._physicalCountVal=a;this._physicalEnd=(this._physicalStart+this._physicalCount-1)%this._physicalCount},get _physicalCount(){return this._physicalCountVal},\n_physicalEnd:0,get _optPhysicalSize(){return this.grid?this._estRowsInView*this._rowHeight*this._maxPages:this._viewportHeight*this._maxPages},get _optPhysicalCount(){return this._estRowsInView*this._itemsPerRow*this._maxPages},get _isVisible(){return!(!this.offsetWidth&&!this.offsetHeight)},get firstVisibleIndex(){if(null===this._firstVisibleIndexVal){var a=Math.floor(this._physicalTop+this._scrollerPaddingTop);this._firstVisibleIndexVal=this._iterateItems(function(b,c){a+=this._getPhysicalSizeIncrement(b);\nif(a>this._scrollPosition)return this.grid?c-c%this._itemsPerRow:c;if(this.grid&&this._virtualCount-1===c)return c-c%this._itemsPerRow})||0}return this._firstVisibleIndexVal},get lastVisibleIndex(){if(null===this._lastVisibleIndexVal)if(this.grid)this._lastVisibleIndexVal=Math.min(this._virtualCount,this.firstVisibleIndex+this._estRowsInView*this._itemsPerRow-1);else{var a=this._physicalTop;this._iterateItems(function(b,c){if(a<this._scrollBottom)this._lastVisibleIndexVal=c;else return!0;a+=this._getPhysicalSizeIncrement(b)})}return this._lastVisibleIndexVal},\nget _defaultScrollTarget(){return this},get _virtualRowCount(){return Math.ceil(this._virtualCount/this._itemsPerRow)},get _estRowsInView(){return Math.ceil(this._viewportHeight/this._rowHeight)},get _physicalRows(){return Math.ceil(this._physicalCount/this._itemsPerRow)},ready:function(){this.addEventListener(\"focus\",this._didFocus.bind(this),!0)},attached:function(){this.updateViewportBoundaries();0===this._physicalCount&&this._debounceTemplate(this._render);this.listen(this,\"iron-resize\",\"_resizeHandler\")},\ndetached:function(){this.unlisten(this,\"iron-resize\",\"_resizeHandler\")},_setOverflow:function(a){this.style.webkitOverflowScrolling=a===this?\"touch\":\"\";this.style.overflow=a===this?\"auto\":\"\"},updateViewportBoundaries:function(){this._scrollerPaddingTop=this.scrollTarget===this?0:parseInt(window.getComputedStyle(this)[\"padding-top\"],10);this._viewportHeight=this._scrollTargetHeight;this.grid&&this._updateGridMetrics()},_scrollHandler:function(){var a=Math.max(0,Math.min(this._maxScrollTop,this._scrollTop)),\nb=a-this._scrollPosition,e=this._ratio,f=0,g=this._hiddenContentSize,k,l=[];this._scrollPosition=a;this._lastVisibleIndexVal=this._firstVisibleIndexVal=null;var m=this._scrollBottom;var n=this._physicalBottom;if(Math.abs(b)>this._physicalSize)this._physicalTop+=b,f=Math.round(b/this._physicalAverage);else if(0>b){var q=a-this._physicalTop;l=this._virtualStart;var p=[];b=this._physicalEnd;for(k=q/g;k<e&&f<this._physicalCount&&0<l-f&&n-this._getPhysicalSizeIncrement(b)>m;)q=this._getPhysicalSizeIncrement(b),\nk+=q/g,n-=q,p.push(b),f++,b=0===b?this._physicalCount-1:b-1;l=p;f=-f}else if(0<b){var t=this._virtualEnd,r=this._virtualCount-1;p=[];b=this._physicalStart;for(k=(n-m)/g;k<e&&f<this._physicalCount&&t+f<r&&this._physicalTop+this._getPhysicalSizeIncrement(b)<a;)q=this._getPhysicalSizeIncrement(b),k+=q/g,this._physicalTop+=q,p.push(b),f++,b=(b+1)%this._physicalCount}0===f?(n<m||this._physicalTop>a)&&this._increasePoolIfNeeded():(this._virtualStart+=f,this._physicalStart+=f,this._update(p,l))},_update:function(a,\nb){this._manageFocus();this._assignModels(a);this._updateMetrics(a);if(b)for(;b.length;)a=b.pop(),this._physicalTop-=this._getPhysicalSizeIncrement(a);this._positionItems();this._updateScrollerSize();this._increasePoolIfNeeded()},_createPool:function(a){var b=Array(a);this._ensureTemplatized();for(var c=0;c<a;c++){var f=this.stamp(null);b[c]=f.root.querySelector(\"*\");Polymer.dom(this).appendChild(f.root)}return b},_increasePoolIfNeeded:function(){if(0===this._viewportHeight)return!1;var a=this,b=\nthis._physicalBottom>=this._scrollBottom&&this._physicalTop<=this._scrollPosition;if(this._physicalSize>=this._optPhysicalSize&&b)return!1;var e=Math.round(.5*this._physicalCount);if(!b)return this._debounceTemplate(this._increasePool.bind(this,e)),!0;this._yield(function(){a._increasePool(Math.min(e,Math.max(1,Math.round(50/a._templateCost))))});return!0},_yield:function(a){var b=window,c=b.requestIdleCallback?b.requestIdleCallback(a):b.setTimeout(a,16);Polymer.dom.addDebouncer({complete:function(){b.cancelIdleCallback?\nb.cancelIdleCallback(c):b.clearTimeout(c);a()}})},_increasePool:function(a){var b=this._physicalCount;a=Math.min(this._physicalCount+a,this._virtualCount-this._virtualStart,Math.max(this.maxPhysicalCount,3))-b;var c=window.performance.now();0>=a||([].push.apply(this._physicalItems,this._createPool(a)),[].push.apply(this._physicalSizes,Array(a)),this._physicalCount=b+a,this._physicalStart>this._physicalEnd&&this._isIndexRendered(this._focusedIndex)&&this._getPhysicalIndex(this._focusedIndex)<this._physicalEnd&&\n(this._physicalStart+=a),this._update(),this._templateCost=(window.performance.now()-c)/a)},_render:function(){this.isAttached&&this._isVisible&&(0===this._physicalCount?this._increasePool(3):this._update())},_ensureTemplatized:function(){if(!this.ctor){var a={__key__:!0};a[this.as]=!0;a[this.indexAs]=!0;a[this.selectedAs]=!0;a.tabIndex=!0;this._instanceProps=a;(this._userTemplate=Polymer.dom(this).querySelector(\"template\"))?this.templatize(this._userTemplate):console.warn(\"iron-list requires a template to be provided in light-dom\")}},\n_getStampedChildren:function(){return this._physicalItems},_forwardInstancePath:function(a,b,e){0===b.indexOf(this.as+\".\")&&this.notifyPath(\"items.\"+a.__key__+\".\"+b.slice(this.as.length+1),e)},_forwardParentProp:function(a,b){this._physicalItems&&this._physicalItems.forEach(function(c){c._templateInstance[a]=b},this)},_forwardParentPath:function(a,b){this._physicalItems&&this._physicalItems.forEach(function(c){c._templateInstance.notifyPath(a,b,!0)},this)},_forwardItemPath:function(a,b){if(this._physicalIndexForKey){var c=\na.indexOf(\".\"),d=a.substring(0,0>c?a.length:c),g=this._physicalIndexForKey[d],k=this._offscreenFocusedItem;if((g=k&&k._templateInstance.__key__===d?k:this._physicalItems[g])&&g._templateInstance.__key__===d)if(0<=c)a=this.as+\".\"+a.substring(c+1),g._templateInstance.notifyPath(a,b,!0);else{a=g._templateInstance[this.as];if(Array.isArray(this.selectedItems))for(c=0;c<this.selectedItems.length;c++){if(this.selectedItems[c]===a){this.set(\"selectedItems.\"+c,b);break}}else this.selectedItem===a&&this.set(\"selectedItem\",\nb);g._templateInstance[this.as]=b}}},_itemsChanged:function(a){\"items\"===a.path?(this._physicalTop=this._virtualStart=0,this._virtualCount=this.items?this.items.length:0,this._collection=this.items?Polymer.Collection.get(this.items):null,this._physicalIndexForKey={},this._lastVisibleIndexVal=this._firstVisibleIndexVal=null,this._physicalCount=this._physicalCount||0,this._physicalItems=this._physicalItems||[],this._physicalSizes=this._physicalSizes||[],this._physicalStart=0,this._resetScrollPosition(0),\nthis._removeFocusedItem(),this._debounceTemplate(this._render)):\"items.splices\"===a.path?(this._adjustVirtualIndex(a.value.indexSplices),this._virtualCount=this.items?this.items.length:0,this._debounceTemplate(this._render)):this._forwardItemPath(a.path.split(\".\").slice(1).join(\".\"),a.value)},_adjustVirtualIndex:function(a){a.forEach(function(a){a.removed.forEach(this._removeItem,this);a.index<this._virtualStart&&(a=Math.max(a.addedCount-a.removed.length,a.index-this._virtualStart),this._virtualStart+=\na,0<=this._focusedIndex&&(this._focusedIndex+=a))},this)},_removeItem:function(a){this.$.selector.deselect(a);this._focusedItem&&this._focusedItem._templateInstance[this.as]===a&&this._removeFocusedItem()},_iterateItems:function(a,b){var c,d;if(2===arguments.length&&b)for(d=0;d<b.length;d++){var g=b[d];var k=this._computeVidx(g);if(null!=(c=a.call(this,g,k)))return c}else{g=this._physicalStart;for(k=this._virtualStart;g<this._physicalCount;g++,k++)if(null!=(c=a.call(this,g,k)))return c;for(g=0;g<\nthis._physicalStart;g++,k++)if(null!=(c=a.call(this,g,k)))return c}},_computeVidx:function(a){return a>=this._physicalStart?this._virtualStart+(a-this._physicalStart):this._virtualStart+(this._physicalCount-this._physicalStart)+a},_assignModels:function(a){this._iterateItems(function(a,b){var c=this._physicalItems[a],d=c._templateInstance,e=this.items&&this.items[b];null!=e?(d[this.as]=e,d.__key__=this._collection.getKey(e),d[this.selectedAs]=this.$.selector.isSelected(e),d[this.indexAs]=b,d.tabIndex=\nthis._focusedIndex===b?0:-1,this._physicalIndexForKey[d.__key__]=a,c.removeAttribute(\"hidden\")):(d.__key__=null,c.setAttribute(\"hidden\",\"\"))},a)},_updateMetrics:function(a){Polymer.dom.flush();var b=0,c=0,f=this._physicalAverageCount,g=this._physicalAverage;this._iterateItems(function(a){c+=this._physicalSizes[a]||0;this._physicalSizes[a]=this._physicalItems[a].offsetHeight;b+=this._physicalSizes[a];this._physicalAverageCount+=this._physicalSizes[a]?1:0},a);this._viewportHeight=this._scrollTargetHeight;\nthis.grid?(this._updateGridMetrics(),this._physicalSize=Math.ceil(this._physicalCount/this._itemsPerRow)*this._rowHeight):this._physicalSize=this._physicalSize+b-c;this._physicalAverageCount!==f&&(this._physicalAverage=Math.round((g*f+b)/this._physicalAverageCount))},_updateGridMetrics:function(){this._viewportWidth=this.$.items.offsetWidth;this._itemWidth=0<this._physicalCount?this._physicalItems[0].getBoundingClientRect().width:200;this._rowHeight=0<this._physicalCount?this._physicalItems[0].offsetHeight:\n200;this._itemsPerRow=this._itemWidth?Math.floor(this._viewportWidth/this._itemWidth):this._itemsPerRow},_positionItems:function(){this._adjustScrollPosition();var a=this._physicalTop;if(this.grid){var b=(this._viewportWidth-this._itemsPerRow*this._itemWidth)/2;this._iterateItems(function(c,d){this.translate3d(Math.floor(d%this._itemsPerRow*this._itemWidth+b)+\"px\",a+\"px\",0,this._physicalItems[c]);this._shouldRenderNextRow(d)&&(a+=this._rowHeight)})}else this._iterateItems(function(b){this.translate3d(0,\na+\"px\",0,this._physicalItems[b]);a+=this._physicalSizes[b]})},_getPhysicalSizeIncrement:function(a){return this.grid?this._computeVidx(a)%this._itemsPerRow!==this._itemsPerRow-1?0:this._rowHeight:this._physicalSizes[a]},_shouldRenderNextRow:function(a){return a%this._itemsPerRow===this._itemsPerRow-1},_adjustScrollPosition:function(){var a=0===this._virtualStart?this._physicalTop:Math.min(this._scrollPosition+this._physicalTop,0);a&&(this._physicalTop-=a,b||0===this._physicalTop||this._resetScrollPosition(this._scrollTop-\na))},_resetScrollPosition:function(a){this.scrollTarget&&(this._scrollPosition=this._scrollTop=a)},_updateScrollerSize:function(a){this._estScrollHeight=this.grid?this._virtualRowCount*this._rowHeight:this._physicalBottom+Math.max(this._virtualCount-this._physicalCount-this._virtualStart,0)*this._physicalAverage;if((a=(a=(a=a||0===this._scrollHeight)||this._scrollPosition>=this._estScrollHeight-this._physicalSize)||this.grid&&this.$.items.style.height<this._estScrollHeight)||Math.abs(this._estScrollHeight-\nthis._scrollHeight)>=this._optPhysicalSize)this.$.items.style.height=this._estScrollHeight+\"px\",this._scrollHeight=this._estScrollHeight},scrollToItem:function(a){return this.scrollToIndex(this.items.indexOf(a))},scrollToIndex:function(a){if(!(\"number\"!==typeof a||0>a||a>this.items.length-1)&&(Polymer.dom.flush(),0!==this._physicalCount)){a=Math.min(Math.max(a,0),this._virtualCount-1);if(!this._isIndexRendered(a)||a>=this._maxVirtualStart)this._virtualStart=this.grid?a-2*this._itemsPerRow:a-1;this._manageFocus();\nthis._assignModels();this._updateMetrics();this._physicalTop=Math.floor(this._virtualStart/this._itemsPerRow)*this._physicalAverage;for(var b=this._physicalStart,c=this._virtualStart,f=0,g=this._hiddenContentSize;c<a&&f<=g;)f+=this._getPhysicalSizeIncrement(b),b=(b+1)%this._physicalCount,c++;this._updateScrollerSize(!0);this._positionItems();this._resetScrollPosition(this._physicalTop+this._scrollerPaddingTop+f);this._increasePoolIfNeeded();this._lastVisibleIndexVal=this._firstVisibleIndexVal=null}},\n_resetAverage:function(){this._physicalAverageCount=this._physicalAverage=0},_resizeHandler:function(){a&&100>Math.abs(this._viewportHeight-this._scrollTargetHeight)||Polymer.dom.addDebouncer(this.debounce(\"_debounceTemplate\",function(){this.updateViewportBoundaries();this._render();0<this._physicalCount&&this._isVisible&&(this._resetAverage(),this.scrollToIndex(this.firstVisibleIndex))}.bind(this),1))},_getModelFromItem:function(a){a=this._collection.getKey(a);a=this._physicalIndexForKey[a];return null!=\na?this._physicalItems[a]._templateInstance:null},_getNormalizedItem:function(a){if(void 0===this._collection.getKey(a)){if(\"number\"===typeof a){a=this.items[a];if(!a)throw new RangeError(\"\\x3citem\\x3e not found\");return a}throw new TypeError(\"\\x3citem\\x3e should be a valid item\");}return a},selectItem:function(a){a=this._getNormalizedItem(a);var b=this._getModelFromItem(a);!this.multiSelection&&this.selectedItem&&this.deselectItem(this.selectedItem);b&&(b[this.selectedAs]=!0);this.$.selector.select(a);\nthis.updateSizeForItem(a)},deselectItem:function(a){a=this._getNormalizedItem(a);var b=this._getModelFromItem(a);b&&(b[this.selectedAs]=!1);this.$.selector.deselect(a);this.updateSizeForItem(a)},toggleSelectionForItem:function(a){a=this._getNormalizedItem(a);this.$.selector.isSelected(a)?this.deselectItem(a):this.selectItem(a)},clearSelection:function(){function a(a){(a=this._getModelFromItem(a))&&(a[this.selectedAs]=!1)}Array.isArray(this.selectedItems)?this.selectedItems.forEach(a,this):this.selectedItem&&\na.call(this,this.selectedItem);this.$.selector.clearSelection()},_selectionEnabledChanged:function(a){(a?this.listen:this.unlisten).call(this,this,\"tap\",\"_selectionHandler\")},_selectionHandler:function(a){var b=this.modelForElement(a.target);if(b){var c=Polymer.dom(a).path[0];a=Polymer.dom(this.domHost?this.domHost.root:document).activeElement;var f=this._physicalItems[this._getPhysicalIndex(b[this.indexAs])];if(\"input\"!==c.localName&&\"button\"!==c.localName&&\"select\"!==c.localName){c=b.tabIndex;b.tabIndex=\n-100;var g=a?a.tabIndex:-1;b.tabIndex=c;a&&f!==a&&f.contains(a)&&-100!==g||this.toggleSelectionForItem(b[this.as])}}},_multiSelectionChanged:function(a){this.clearSelection();this.$.selector.multi=a},updateSizeForItem:function(a){a=this._getNormalizedItem(a);a=this._collection.getKey(a);a=this._physicalIndexForKey[a];null!=a&&(this._updateMetrics([a]),this._positionItems())},_manageFocus:function(){var a=this._focusedIndex;0<=a&&a<this._virtualCount?this._isIndexRendered(a)?this._restoreFocusedItem():\nthis._createFocusBackfillItem():0<this._virtualCount&&0<this._physicalCount&&(this._focusedIndex=this._virtualStart,this._focusedItem=this._physicalItems[this._physicalStart])},_isIndexRendered:function(a){return a>=this._virtualStart&&a<=this._virtualEnd},_isIndexVisible:function(a){return a>=this.firstVisibleIndex&&a<=this.lastVisibleIndex},_getPhysicalIndex:function(a){return this._physicalIndexForKey[this._collection.getKey(this._getNormalizedItem(a))]},_focusPhysicalItem:function(a){if(!(0>a||\na>=this._virtualCount)){this._restoreFocusedItem();this._isIndexRendered(a)||this.scrollToIndex(a);var b=this._physicalItems[this._getPhysicalIndex(a)],c=b._templateInstance,f;c.tabIndex=-100;-100===b.tabIndex&&(f=b);f||(f=Polymer.dom(b).querySelector('[tabindex\\x3d\"-100\"]'));c.tabIndex=0;this._focusedIndex=a;f&&f.focus()}},_removeFocusedItem:function(){this._offscreenFocusedItem&&Polymer.dom(this).removeChild(this._offscreenFocusedItem);this._focusedItem=this._focusBackfillItem=this._offscreenFocusedItem=\nnull;this._focusedIndex=-1},_createFocusBackfillItem:function(){var a=this._focusedIndex;if(!(this._offscreenFocusedItem||0>a)){if(!this._focusBackfillItem){var b=this.stamp(null);this._focusBackfillItem=b.root.querySelector(\"*\");Polymer.dom(this).appendChild(b.root)}a=this._getPhysicalIndex(a);null!=a&&(this._offscreenFocusedItem=this._physicalItems[a],this._physicalItems[a]=this._focusBackfillItem,this.translate3d(0,\"-10000px\",0,this._offscreenFocusedItem))}},_restoreFocusedItem:function(){var a=\nthis._focusedIndex;!this._offscreenFocusedItem||0>this._focusedIndex||(this._assignModels(),a=this._getPhysicalIndex(a),null!=a&&(this._focusBackfillItem=this._physicalItems[a],this._physicalItems[a]=this._offscreenFocusedItem,this._offscreenFocusedItem=null,this.translate3d(0,\"-10000px\",0,this._focusBackfillItem)))},_didFocus:function(a){a=this.modelForElement(a.target);var b=this._focusedItem?this._focusedItem._templateInstance:null,c=null!==this._offscreenFocusedItem,f=this._focusedIndex;a&&b&&\n(b===a?this._isIndexVisible(f)||this.scrollToIndex(f):(this._restoreFocusedItem(),b.tabIndex=-1,a.tabIndex=0,this._focusedIndex=f=a[this.indexAs],this._focusedItem=this._physicalItems[this._getPhysicalIndex(f)],c&&!this._offscreenFocusedItem&&this._update()))},_didMoveUp:function(){this._focusPhysicalItem(this._focusedIndex-1)},_didMoveDown:function(a){a.detail.keyboardEvent.preventDefault();this._focusPhysicalItem(this._focusedIndex+1)},_didEnter:function(a){this._focusPhysicalItem(this._focusedIndex);\nthis._selectionHandler(a.detail.keyboardEvent)}})})();\n</script>\n\n\n\n\n\n\n\n\n<dom-module id=\"facets-overview-row-stats\">\n  <template>\n    <style>\n      * {\n        text-align: right;\n        white-space: nowrap;\n        overflow-x: hidden;\n        text-overflow: ellipsis;\n      }\n      .data-error {\n        color: red;\n        font-weight: bold;\n      }\n      .data-weighted {\n        font-style: italic;\n      }\n      .table-row {\n        display: flex;\n        margin-bottom: 4px;\n      }\n      .table-cell {\n        min-width: 70px;\n        max-width: 70px;\n        padding-right: 4px;\n      }\n      .data-custom {\n        min-width: 150px;\n        max-width: 150px;\n        white-space: pre;;\n      }\n      #legend-box {\n        width: 6px;\n        height: 16px;\n        margin-left: 4px;\n      }\n    </style>\n    <div class=\"table-row\">\n      <div id=\"legend-box\"></div>\n      <template is=\"dom-repeat\" items=\"[[_entries]]\">\n        <div class$=\"[[item.cssClass]] table-cell\" title=\"[[item.fullStr]]\">[[item.str]]</div>\n      </template>\n    </div>\n  </template>\n</dom-module>\n<script>//~~WEBPATH~~/facets-overview/components/facets-overview-row-stats/facets-overview-row-stats.js\nPolymer({is:\"facets-overview-row-stats\",properties:{type:Object,stats:Object,showWeighted:Boolean,hasCustom:Boolean,dataModel:Object,datasetIndex:Number,compareMode:Boolean,_entries:{type:Array,computed:\"_getEntries(type, stats, showWeighted, hasCustom)\"}},observers:[\"_colorLegendBox(dataModel, datasetIndex, compareMode)\"],_getEntries:function(a,b,c,d){a=null;if(b){hc(b)?a=Pc(hc(b)):W(b)?a=Pc(W(b)):jc(b)&&(a=Pc(jc(b)));var e=Ve(a),e=W(b)?e.concat(We(W(b),a,c)):e.concat(Ye(hc(b),c));d&&(e=e.concat(Ze(lc(b))));\nb=e}else b=[];return b},_colorLegendBox:function(a,b,c){var d=d3.select(this.$$(\"#legend-box\"));2>a.getDatasetNames().length&&!c?d.style(\"visibility\",\"hidden\"):(d.style(\"visibility\",null),d.style(\"background-color\",a.getChartColorString(b)))}});\n</script>\n\n\n\n\n<dom-module id=\"facets-overview-row-legend\">\n  <template>\n    <style>\n      .table-row {\n        display: flex;\n        background: rgba(61,140,207,0.1);\n        border-left: solid 0.5px rgba(0,0,0,0.1);\n        border-bottom: solid 0.5px rgba(0,0,0,0.1);\n      }\n      .table-cell {\n        padding: 20px 4px 8px 0;\n        min-width: 69px;\n        max-width: 69px;\n        text-align: right;\n        font-size: 14px;\n        font-weight: 300;\n        border-right: solid 0.5px rgba(0,0,0,0.1);\n      }\n      .data-weighted {\n        font-style: italic;\n      }\n      .data-custom {\n        min-width: 150px;\n        max-width: 150px;\n      }\n      .legend-space {\n        width: 6px;\n        height: 8px;\n        margin-left: 4px;\n      }\n    </style>\n    <div class=\"table-row\">\n      <div class=\"legend-space\"></div>\n      \n      <template is=\"dom-repeat\" items=\"[[_entries]]\">\n        <div class$=\"[[item.cssClass]] table-cell\">[[item.str]]</div>\n      </template>\n    </div>\n  </template>\n</dom-module>\n<script>//~~WEBPATH~~/facets-overview/components/facets-overview-row-legend/facets-overview-row-legend.js\nPolymer({is:\"facets-overview-row-legend\",properties:{type:Object,showWeighted:Boolean,hasCustom:Boolean,dataModel:Object,_entries:{type:Array,computed:\"_getEntries(type, showWeighted, hasCustom)\"}},_getEntries:function(a,b,c){var d=[];d.push(Ue(\"count\"));d.push(Ue(\"missing\"));0===a||1===a?(d.push(Ue(\"mean\",b)),d.push(Ue(\"std dev\",b)),d.push(Ue(\"zeros\")),d.push(Ue(\"min\")),d.push(Ue(\"median\",b)),d.push(Ue(\"max\"))):(d.push(Ue(\"unique\")),d.push(Ue(\"top\",b)),d.push(Ue(\"freq top\",b)),d.push(Ue(\"avg str len\")));\nc&&(a=new Oe(\"custom\",\"data-custom \"),d.push(a));return d}});\n</script>\n\n\n\n\n\n\n\n\n<dom-module id=\"paper-material-shared-styles\">\n  <template>\n    <style>\n      :host {\n        display: block;\n        position: relative;\n      }\n\n      :host([elevation=\"1\"]) {\n        @apply --shadow-elevation-2dp;\n      }\n\n      :host([elevation=\"2\"]) {\n        @apply --shadow-elevation-4dp;\n      }\n\n      :host([elevation=\"3\"]) {\n        @apply --shadow-elevation-6dp;\n      }\n\n      :host([elevation=\"4\"]) {\n        @apply --shadow-elevation-8dp;\n      }\n\n      :host([elevation=\"5\"]) {\n        @apply --shadow-elevation-16dp;\n      }\n    </style>\n  </template>\n</dom-module>\n\n\n\n\n<dom-module id=\"paper-material\">\n  <template>\n    <style include=\"paper-material-shared-styles\"></style>\n    <style>\n      :host([animated]) {\n        @apply --shadow-transition;\n      }\n      :host {\n        @apply --paper-material;\n      }\n    </style>\n\n    <slot></slot>\n  </template>\n</dom-module>\n<script>//~~WEBPATH~~/paper-material/paper-material.html.js\nPolymer({is:\"paper-material\",properties:{elevation:{type:Number,reflectToAttribute:!0,value:1},animated:{type:Boolean,reflectToAttribute:!0,value:!1}}});\n</script>\n\n\n\n\n\n\n<script>//~~WEBPATH~~/paper-behaviors/paper-button-behavior.html.js\nPolymer.PaperButtonBehaviorImpl={properties:{elevation:{type:Number,reflectToAttribute:!0,readOnly:!0}},observers:[\"_calculateElevation(focused, disabled, active, pressed, receivedFocusFromKeyboard)\",\"_computeKeyboardClass(receivedFocusFromKeyboard)\"],hostAttributes:{role:\"button\",tabindex:\"0\",animated:!0},_calculateElevation:function(){var a=1;this.disabled?a=0:this.active||this.pressed?a=4:this.receivedFocusFromKeyboard&&(a=3);this._setElevation(a)},_computeKeyboardClass:function(a){this.toggleClass(\"keyboard-focus\",\na)},_spaceKeyDownHandler:function(a){Polymer.IronButtonStateImpl._spaceKeyDownHandler.call(this,a);this.hasRipple()&&1>this.getRipple().ripples.length&&this._ripple.uiDownAction()},_spaceKeyUpHandler:function(a){Polymer.IronButtonStateImpl._spaceKeyUpHandler.call(this,a);this.hasRipple()&&this._ripple.uiUpAction()}};Polymer.PaperButtonBehavior=[Polymer.IronButtonState,Polymer.IronControlState,Polymer.PaperRippleBehavior,Polymer.PaperButtonBehaviorImpl];\n</script>\n\n\n\n\n\n<dom-module id=\"paper-button\">\n  <template strip-whitespace>\n\n    <style include=\"paper-material\">\n      :host {\n        display: inline-block;\n        position: relative;\n        box-sizing: border-box;\n        min-width: 5.14em;\n        margin: 0 0.29em;\n        background: transparent;\n        text-align: center;\n        font: inherit;\n        text-transform: uppercase;\n        outline-width: 0;\n        border-radius: 3px;\n        -moz-user-select: none;\n        -ms-user-select: none;\n        -webkit-user-select: none;\n        user-select: none;\n        cursor: pointer;\n        z-index: 0;\n        padding: 0.7em 0.57em;\n\n        @apply(--paper-button);\n      }\n\n      :host([raised].keyboard-focus) {\n        font-weight: bold;\n        @apply(--paper-button-raised-keyboard-focus);\n      }\n\n      :host(:not([raised]).keyboard-focus) {\n        font-weight: bold;\n        @apply(--paper-button-flat-keyboard-focus);\n      }\n\n      :host([disabled]) {\n        background: #eaeaea;\n        color: #a8a8a8;\n        cursor: auto;\n        pointer-events: none;\n\n        @apply(--paper-button-disabled);\n      }\n\n      paper-ripple {\n        color: var(--paper-button-ink-color);\n      }\n\n      :host > ::content * {\n        text-transform: inherit;\n      }\n    </style>\n    <content></content>\n  </template>\n</dom-module>\n\n<script>//~~WEBPATH~~/paper-button/paper-button.html.js\nPolymer({is:\"paper-button\",behaviors:[Polymer.PaperButtonBehavior],properties:{raised:{type:Boolean,reflectToAttribute:!0,value:!1,observer:\"_calculateElevation\"}},_calculateElevation:function(){this.raised?Polymer.PaperButtonBehaviorImpl._calculateElevation.apply(this):this._setElevation(0)}});\n</script>\n\n\n\n\n\n<dom-module id=\"facets-overview-chart\">\n  \n  <template>\n    <style>\n      .chart-small {\n        height: 46px;\n        width: 250px;\n      }\n      .xaxis-small{\n        height: 30px;\n        width: 250px;\n      }\n      .chart-big {\n        height: 200px;\n        width: 550px;\n      }\n      .xaxis-big {\n        height: 50px;\n        width: 550px;\n      }\n      #show_table_button {\n        margin: 0 0 0 5px;\n        padding: 0 3px;\n        font-size: 7pt;\n        background-color: #d3d3d3;\n      }\n      .dialog-row-entry {\n        padding: 0 10px 0 0;\n      }\n      .table-header {\n        border-bottom: 1px solid black;\n      }\n      .dialog-row, .dialog-header-row {\n        display: flex;\n      }\n      .dialog-row.selected {\n        border: 1px solid black\n      }\n      .dialog-row:hover {\n        background-color: #D0D0D0;\n        cursor: pointer;\n      }\n      .dialog-table {\n        clear: left;\n      }\n      .label-cell {\n        width: 100px;\n        max-width: 100px;\n        min-width: 100px;\n        overflow-wrap: break-word;\n      }\n      .count-cell {\n        width: 100px;\n        max-width: 100px;\n        min-width: 100px;\n        overflow-wrap: break-word;\n      }\n      .weighted-cell {\n        font-style: italic;\n      }\n      .data-list-small {\n        height: 60px;\n      }\n      .data-list-big {\n        height: 180px;\n        width: 550px;\n      }\n      .hidechart {\n        display: none;\n      }\n      .showchart {\n        display: inline;\n      }\n      #tooltip {\n        background-color: var(--paper-tooltip-background, #616161);\n        opacity: 0;\n        color: white;\n        pointer-events:none;\n        transition: opacity 0.3s;\n        position: absolute;\n        text-align:center;\n        padding: 6px;\n        border-radius: 2px;\n        font-size: 12px;\n        line-height: 1;\n        margin-left: 50px;\n        white-space: pre;\n        top: 0px;\n      }\n      .toplevel {\n        position: relative;\n        text-align: left;\n        padding-top: 4px;\n      }\n    </style>\n    <div class=\"toplevel\">\n      <template is=\"dom-if\" if=\"[[_isStringChart(_chartType, chartSelection)]]\">\n        <paper-button id=\"show_table_button\" on-click=\"_toggleShowTable\">[[_getShowTableButtonText(_showTable)]]</paper-button>\n      </template>\n      <div class$=\"[[_chartClass]]\">\n        <div id=\"chart\" class$=\"[[_chartSvgClass]]\"></div>\n        <div id=\"xaxis\" class$=\"[[_xAxisSvgClass]]\"></div>\n      </div>\n      <template is=\"dom-if\" if=\"[[_showTable]]\">\n        <div class=\"dialog-table\">\n          <div class=\"dialog-header-row\">\n            <div class=\"dialog-row-entry table-header label-cell\">Value</div>\n            <template is=\"dom-repeat\" items=\"[[data]]\" as=\"data\">\n              <div class=\"dialog-row-entry table-header label-cell\">[[data.name]]</div>\n            </template>\n          </div>\n          <iron-list items=\"[[_tableData]]\" as=\"entry\" class$=\"[[_tableDataClass]]\">\n            <template>\n              <div class$=\"[[_getEntryRowClass(entry, selection)]]\" on-tap=\"_rowClick\" data-value=\"[[_getEntryRowValue(entry)]]\">\n                <div class=\"dialog-row-entry label-cell\">[[entry.value]]</div>\n                <template is=\"dom-repeat\" items=\"[[entry.counts]]\" as=\"count\">\n                  <div class$=\"[[_getCountCellClass(showWeighted)]]\">[[count]]</div>\n                </template>\n              </div>\n            </template>\n          <iron-list>\n        </iron-list></iron-list></div>\n      </template>\n      <div id=\"tooltip\"></div>\n    </div>\n  </template>\n</dom-module>\n<script>//~~WEBPATH~~/facets-overview/components/facets-overview-chart/facets-overview-chart.js\nPolymer({is:\"facets-overview-chart\",properties:{data:{type:Object,observer:\"_updateData\"},dataModel:Object,feature:String,_maxBucketsForBarChart:{type:Number,value:10,readOnly:!0},_chartAlpha:{type:Number,value:1},logScale:Boolean,showWeighted:Boolean,showPercentage:Boolean,chartSelection:{type:Number,observer:\"_updateChartSelection\"},selection:{type:Object,observer:\"_updateSelectionVisibility\",notify:!0},expandChart:Boolean,_selectionElem:Object,_minBarHeightRatio:{type:Number,value:.01,readOnly:!0},\n_onClick:Object,_onClickFunction:Object,_onPointer:Object,_onPointerEnterFunction:Object,_onPointerExitFunction:Object,_tableData:Array,_showTable:{type:Boolean,value:!1},_chartType:Object,_chartClass:{type:String,computed:\"_getChartClass(_showTable)\"},_chartSvgClass:{type:String,computed:\"_getChartSvgClass(expandChart)\"},_xAxisSvgClass:{type:String,computed:\"_getXAxisSvgClass(expandChart)\"},_tableDataClass:{type:String,computed:\"_getTableDataClass(expandChart)\"}},observers:[\"_render(data, logScale, showWeighted, chartSelection, _showTable, expandChart, showPercentage, dataModel)\"],\n_updateData:function(){this._showTable=!1},_updateChartSelection:function(){this._showTable=!1},_hasWeightedHistogram:function(a){return Ce(a)},_hasQuantiles:function(a){return De(a)},_isStringChart:function(a,b){return(a===af.CUMDIST_CHART||a===af.BAR_CHART)&&b!==oe&&b!==pe},_disableLogCheckbox:function(a,b){return a||b!==me},_render:function(a,b,c,d,e,f,g,k){var l=this;this._onPointer&&(this._onPointer.offPointerMove(this._onPointerEnterFunction),this._onPointer.offPointerMove(this._onPointerExitFunction));\nthis._onClick&&this._onClick.offClick(this._onClickFunction);a&&(this._chartAlpha=k.getChartAlpha(),e=a.map(function(a){return l._getBuckets(a,c,d)}),this._chartType=Ne(a,this._maxBucketsForBarChart),a=a.map(function(a){return a.name}),d===oe||d===pe||d===ne?this._renderQuantileChart(e,a,b):this._chartType===af.HISTOGRAM?this._renderHistogramChart(e,a,b,g):this._chartType===af.CUMDIST_CHART?this._renderCdfChart(e,a,b):this._renderBarChart(e,a,b,g))},_renderHistogramChart:function(a,b,c,d){var e=this,\nf=[],g=new Plottable.Plots.Rectangle,k=Infinity,l=-Infinity,m=0;d&&(a=$e(a));a.forEach(function(a,c){a.forEach(function(a){var b=Y(a.getLowValue()),c=Y(zd(a));a=Y(a.getSampleCount());b<k&&(k=b);c>l&&(l=c);a>m&&(m=a);isFinite(b)&&isFinite(c)&&f.push(c-b)});g.addDataset(new Plottable.Dataset(a,{name:b[c]}))});var n=0<f.length?f.reduce(function(a,b){return a+b})/f.length:0;0===n&&(n=1);d=[];isFinite(k)&&(d.push(k),isFinite(l)&&d.push(l));a=new Plottable.Scales.Linear;0<d.length&&a.domain(d);d=this._getScale(c).domain([0]);\nvar q=new Plottable.Axes.Numeric(a,\"bottom\"),p=new Plottable.Axes.Numeric(d,\"left\");p.formatter(this._chartAxisScaleFormatter());q.formatter(this._chartAxisScaleFormatter());g.x(function(a){var b=Y(a.getLowValue());if(-Infinity===b||b===zd(a))a=Y(zd(a)),isFinite(a)?b=a-n:(b=0,-Infinity===a&&(b-=n));return b},a).x2(function(a){var b=Y(zd(a));if(Infinity===b||b===a.getLowValue())a=Y(a.getLowValue()),isFinite(a)?b=a+n:(b=0,Infinity===a&&(b+=n));return b},a).y(function(){return 0},d).y2(function(a){return e._getCountWithFloor(a,\nm,c)},d);g.attr(\"fill\",function(a,b,c){return c.metadata().name},this.dataModel.getColorScale()).attr(\"opacity\",this._chartAlpha);this._renderChart(g,q,p,null,null,function(a){return g.entitiesAt(a)},function(a){return te(Y(a.getLowValue()),2).toLocaleString()+\"-\"+te(Y(zd(a)),2).toLocaleString()+\": \"+Y(a.getSampleCount()).toLocaleString()},function(a){return new qe(e.feature,void 0,Y(a.getLowValue()),Y(zd(a)))},function(a){return a.append(\"rect\").attr(\"stroke\",\"black\").attr(\"fill\",\"none\").attr(\"stroke-width\",\n\"1px\")},function(a,b){return a.attr(\"x\",b.position.x-b.selection._groups[0][0].width.baseVal.value/2).attr(\"y\",b.position.y-b.selection._groups[0][0].height.baseVal.value/2).attr(\"width\",b.selection._groups[0][0].width.baseVal.value).attr(\"height\",b.selection._groups[0][0].height.baseVal.value)})},_renderQuantileChart:function(a,b,c){var d=this,e=new Plottable.Plots.Line,f=new Plottable.Plots.Scatter,g=Infinity,k=-Infinity;a.forEach(function(a,c){var d=[],l=a.length;a.forEach(function(a,b){var e=\nY(a.getLowValue()),f=Y(zd(a));e<g&&(g=e);f>k&&(k=f);e=new je;e.bucket=a;e.datasetIndex=c;e.quantile=100*b/l;d.push(e)});if(0<a.length){var m=new ud;xd(m,zd(a[a.length-1]));yd(m,zd(a[a.length-1]));m.setSampleCount(a[a.length-1].getSampleCount());a=new je;a.bucket=m;a.datasetIndex=c;a.quantile=100;d.push(a)}e.addDataset(new Plottable.Dataset(d,{name:b[c]}));f.addDataset(new Plottable.Dataset(d,{name:b[c]}))});var l=isFinite(g)&&isFinite(k)?k===g?1:(k-g)/10:0,m=[];isFinite(g)&&(m.push(g-l),isFinite(k)&&\nm.push(k+l));c=this._getScale(c);0<m.length&&c.domain(m);m=this._getScale(!1).domain([-a.length+.5,1]);a=new Plottable.Axes.Numeric(c,\"bottom\");a.formatter(this._chartAxisScaleFormatter());e.x(function(a){return Y(a.bucket.getLowValue())},c).y(function(a){return-1*a.datasetIndex},m);f.x(function(a){return Y(a.bucket.getLowValue())},c).y(function(a){return-a.datasetIndex},m).size(function(a){return 50===a.quantile?15:8}).symbol(function(){return Plottable.SymbolFactories.cross()});e.attr(\"stroke\",\n\"gray\").attr(\"opacity\",this._chartAlpha);f.attr(\"fill\",function(a,b,c){return c.metadata().name},this.dataModel.getColorScale()).attr(\"opacity\",this._chartAlpha);m=new Plottable.Components.Group([e,f]);this._renderChart(m,a,null,null,null,function(a){return f.entitiesAt(a)},function(a){return a.quantile+\"%: \"+te(Y(a.bucket.getLowValue()),2).toLocaleString()},function(a){return new qe(d.feature,void 0,Y(a.bucket.getLowValue()),Y(zd(a.bucket)))},function(a){return a.append(\"circle\").attr(\"r\",3).attr(\"stroke\",\n\"black\").attr(\"fill\",\"none\").attr(\"stroke-width\",\"1px\")},function(a,b){return a.attr(\"cx\",b.position.x).attr(\"cy\",b.position.y)})},_renderBarChart:function(a,b,c,d){var e=this,f=we(a),g=new Plottable.Scales.Linear,k=new Plottable.Scales.Category,l=this._getScale(c);k.domain(f);var k=new Plottable.Axes.Category(k,\"bottom\"),m=new Plottable.Axes.Numeric(l,\"left\");m.formatter(this._chartAxisScaleFormatter());d&&(a=$e(a));var n=0;d=a.map(function(a,c){a.forEach(function(a){a=Y(a.getSampleCount());a>n&&\n(n=a)});var d=new He;d.name=b[c];d.rawBuckets=a;return d});this._tableData=Ke(d,f);var q=new Plottable.Plots.Bar;a.forEach(function(a,c){return q.addDataset(new Plottable.Dataset(a,{name:b[c]}))});q.x(function(a){return f.indexOf(xe(Fd(a)))},g).y(function(a){return e._getCountWithFloor(a,n,c)},l);q.attr(\"fill\",function(a,b,c){return c.metadata().name},this.dataModel.getColorScale()).attr(\"opacity\",this._chartAlpha);this._renderChart(q,k,m,null,null,function(a){return q.entitiesAt(a)},function(a){return xe(Fd(a))+\n\": \"+Y(a.getSampleCount()).toLocaleString()},function(a){return new qe(e.feature,Fd(a))},function(a){return a.append(\"rect\").attr(\"stroke\",\"black\").attr(\"fill\",\"none\").attr(\"stroke-width\",\"1px\")},function(a,b){return a.attr(\"x\",b.position.x-b.selection._groups[0][0].width.baseVal.value/2).attr(\"y\",b.position.y).attr(\"width\",b.selection._groups[0][0].width.baseVal.value).attr(\"height\",b.selection._groups[0][0].height.baseVal.value)})},_renderCdfChart:function(a,b,c){var d=this,e=b.map(function(a){a=\nd.dataModel.getFeatureCommonStats(d.feature,a);return null!=a?a.getNumNonMissing()*a.getAvgNumValues():0}),f=we(a),g={};f.forEach(function(a,b){g[a]=b});var k=(new Plottable.Scales.Linear).domain([0]);c=this._getScale(c).domain([0]);var l=new Plottable.Axes.Numeric(k,\"bottom\"),m=new Plottable.Axes.Numeric(c,\"left\"),n=new Plottable.Plots.Line;a=a.map(function(a,c){var d=[],k=[],l=[],m=-1;a.forEach(function(a){a=new a.constructor(Ma(a.toArray()));l.push(a)});0<c&&l.sort(function(a,b){return g[xe(Fd(a))]-\ng[xe(Fd(b))]});l.forEach(function(a,b){for(var l=g[xe(Fd(a))],n=m+1;n<l;n++){var p=new Cd;G(p,4,f[n]);G(p,1,n);G(p,2,n);0===d.length?p.setSampleCount(0):p.setSampleCount(d[d.length-1].getSampleCount());d.push(p);p=new Cd;G(p,4,f[n]);G(p,1,n);G(p,2,n);p.setSampleCount(0);k.push(p)}m=l;n=a.clone();k.push(n);0===b?a.setSampleCount(Y(a.getSampleCount())/e[c]):(b=0<l?l-1:b-1,a.setSampleCount(Y(a.getSampleCount())/e[c]+Y(d[b].getSampleCount())));G(a,1,l);G(a,2,l);d.push(a)});a=new He;a.name=b[c];a.percBuckets=\nd;a.rawBuckets=k;return a});this._tableData=Je(a);a.map(function(a){return n.addDataset(new Plottable.Dataset(a.percBuckets,{name:a.name}))});n.x(function(a){return Y(u(a,1,0))},k).y(function(a){return Y(a.getSampleCount())},c);n.attr(\"stroke\",function(a,b,c){return c.metadata().name},this.dataModel.getColorScale()).attr(\"opacity\",this._chartAlpha);this._renderChart(n,l,m,null,null,function(a){return n.entitiesAt(a)},function(a){return xe(Fd(a))+\": \"+te(Y(a.getSampleCount()),4).toLocaleString()},\nfunction(a){return new qe(d.feature,Fd(a))},function(a){return a.append(\"circle\").attr(\"r\",3).attr(\"stroke\",\"black\").attr(\"fill\",\"none\").attr(\"stroke-width\",\"1px\")},function(a,b){return a.attr(\"cx\",b.position.x).attr(\"cy\",b.position.y)})},_renderChart:function(a,b,c,d,e,f,g,k,l,m){var n=this;if(!this._showTable){var q=new Plottable.Components.Table([[e,c,a],[null,null,null]]),p=new Plottable.Components.Table([[null,null],[null,b]]);Plottable.RenderController.renderPolicy();var t=d3.select(this.$.chart),\nr=d3.select(this.$.xaxis),v=d3.select(this.$.tooltip);this.async(function(){t.selectAll(\".component\").remove();r.selectAll(\".component\").remove();q.renderTo(n.$.chart);n._selectionElem=l(a.foreground());n._updateSelectionVisibility(n.selection);n._onPointer=new Plottable.Interactions.Pointer;n._onPointerEnterFunction=function(a){a=f(a);0<a.length&&(a=a.map(function(a){return null==a.dataset.metadata().name||1===n.dataModel.getDatasetNames().length?g(a.datum):a.dataset.metadata().name+\": \"+g(a.datum)}).join(\"\\n\"),\nv.text(a),v.style(\"opacity\",\"1\"))};n._onPointer.onPointerMove(n._onPointerEnterFunction);n._onPointerExitFunction=function(){v.style(\"opacity\",\"0\")};n._onPointer.onPointerExit(n._onPointerExitFunction);n._onPointer.attachTo(a);n.chartSelection!==oe&&(n._onClick=new Plottable.Interactions.Click,n._onClickFunction=function(a){a=f(a);0<a.length&&(m(n._selectionElem,a[0]),a=k(a[0].datum),n._setSelection(a))},n._onClick.onClick(n._onClickFunction),n._onClick.attachTo(a));null!=c&&p.columnPadding(q.componentAt(1).width()+\n(q.componentAt(0)?q.componentAt(0).width():0));p.renderTo(n.$.xaxis)})}},_setSelection:function(a){a.equals(this.selection)&&a.clear();this.selection=a;this.fire(\"feature-select\",{selection:a})},_getBuckets:function(a,b,c){return ue(a,b,c)},_getScale:function(a){return a?new Plottable.Scales.ModifiedLog:new Plottable.Scales.Linear},_chartAxisScaleFormatter:function(){var a=Plottable.Formatters.shortScale();return function(b){return 1E3>Math.abs(b)?String(b):a(b)}},_getCountWithFloor:function(a,b,\nc){a=Y(a.getSampleCount());!c&&0<a&&a/b<this._minBarHeightRatio&&(a=b*this._minBarHeightRatio);return a},_updateSelectionVisibility:function(a){this._selectionElem&&this._selectionElem.style(\"display\",null==a||a.name!==this.feature?\"none\":\"inline\")},_toggleShowTable:function(){this._showTable=!this._showTable},_getChartClass:function(a){return a?\"hidechart\":\"showchart\"},_getShowTableButtonText:function(a){return a?\"show chart\":\"show raw data\"},_getChartSvgClass:function(a){return a?\"chart-big\":\"chart-small\"},\n_getXAxisSvgClass:function(a){return a?\"xaxis-big\":\"xaxis-small\"},_getTableDataClass:function(a){return a?\"data-list-big\":\"data-list-small\"},_rowClick:function(a){a=new qe(this.feature,a.currentTarget.dataValue);this._setSelection(a)},_getEntryRowValue:function(a){return a.value},_getEntryRowClass:function(a,b){var c=\"dialog-row\";null!=b&&b.name===this.feature&&b.stringValue===a.value&&(c+=\" selected\");return c},_getCountCellClass:function(a){return\"dailog-row-entry count-cell\"+(a?\" weighted-cell\":\n\"\")}});\n</script>\n\n\n<dom-module id=\"facets-overview-table\">\n  <template>\n    <style>\n      .feature-name {\n        font-weight: 500;\n        max-width: 480px;\n        word-wrap: break-word;\n        margin: 0 0 4px 4px;\n      }\n      .table-name {\n        font-weight: 500;\n        word-wrap:break-word;\n        padding: 4px 0 4px 8px;\n        background: rgba(61,140,207,0.3);\n        border: solid 0.5px rgba(0,0,0,0.1);\n      }\n      .feature-iron-list {\n        max-height: 800px;\n        overflow-x: hidden !important;\n      }\n      .chart-column {\n        width: 280px;\n        min-width: 280px;\n        text-align: center;\n      }\n      .chart-column.header-cell {\n        background: rgba(61,140,207,0.1);\n        border-top: solid 0.5px rgba(0,0,0,0.1);\n        border-bottom: solid 0.5px rgba(0,0,0,0.1);\n        border-right: solid 0.5px rgba(0,0,0,0.1);\n        padding-left: 8px;\n      }\n      .table-row {\n        display: table-row;\n      }\n      .table-cell {\n        display: table-cell;\n        vertical-align: top;\n        font-size: 14px;\n        line-height: 1.2em;\n      }\n      .chart-column.table-cell {\n        display: table-cell;\n        vertical-align: top;\n        padding: 10px 0 0 20px\n        margin-right: 10px;\n      }\n      .header-cell {\n        position: relative;\n        min-height: 60px;\n      }\n      paper-checkbox {\n        --paper-checkbox-size: 12px;\n        --paper-checkbox-label-spacing: 2px;\n      }\n      .control-holder {\n        position: absolute;\n        bottom: 0;\n        width: 100%;\n      }\n      .checkbox-holder {\n        display: flex;\n        padding-bottom: 2px;\n      }\n      .chart-checkbox {\n        padding-right: 8px;\n        font-size: 12px;\n      }\n      #weightbox {\n        font-style: italic;\n      }\n      paper-dropdown-menu {\n        display: block;\n        width: 150px;\n        --paper-input-container-label --paper-input-container-input: {\n          font-size: 14px;\n        }\n      }\n      .hidden {\n        display: none;\n      }\n    </style>\n    <div class$=\"[[_getTableWrapperClass(features)]]\">\n      <div class=\"header-row\">\n        <div class=\"header-cell table-cell\">\n          <div class=\"table-name\">[[_getTitle(numeric)]] Features ([[_getFeatureCountText(dataModel, numeric, features)]])\n          </div>\n          <facets-overview-row-legend type=\"[[_getFeatureTypeForList(features)]]\" show-weighted=\"[[_showWeighted]]\" has-custom=\"[[_hasCustomStats(dataModel)]]\" data-model=\"[[dataModel]]\">\n          </facets-overview-row-legend>\n        </div>\n        <div class=\"table-cell chart-column header-cell\">\n          <div class=\"control-holder\">\n            <paper-dropdown-menu label=\"Chart to show\">\n              <paper-listbox class=\"dropdown-content\" selected=\"{{_chartSelection}}\" attr-for-selected=\"value\">\n                <template is=\"dom-repeat\" items=\"[[_chartSelectionTypes]]\">\n                  <paper-item value=\"[[item]]\">[[item]]</paper-item>\n                </template>\n              </paper-listbox>\n            </paper-dropdown-menu>\n            <div class=\"checkbox-holder\">\n              <paper-checkbox class=\"chart-checkbox\" id=\"logbox\" checked=\"{{_logScale}}\">log</paper-checkbox>\n              <paper-checkbox class=\"chart-checkbox\" id=\"expandbox\" checked=\"{{_expandCharts}}\">expand</paper-checkbox>\n              <template is=\"dom-if\" if=\"[[_hasWeightedHistogram(features)]]\">\n                <paper-checkbox class=\"chart-checkbox\" id=\"weightbox\" checked=\"{{_showWeighted}}\">weighted</paper-checkbox>\n              </template>\n              <template is=\"dom-if\" if=\"[[_hasMultipleDatasets(dataModel)]]\">\n                <paper-checkbox class=\"chart-checkbox\" id=\"percentbox\" checked=\"{{_showPercentage}}\" disabled=\"[[_chartSelectionHasQuantiles(_chartSelection)]]\">percentages</paper-checkbox>\n              </template>\n            </div>\n          </div>\n        </div>\n      </div>\n      <iron-list items=\"[[features]]\" as=\"feature\" class=\"feature-iron-list\">\n        <template>\n          <div class=\"table-row\">\n            <div class=\"table-cell\">\n              <div class=\"feature-name\">[[_getFeatureName(feature)]]</div>\n              <template is=\"dom-repeat\" items=\"[[_getDatasets(dataModel)]]\" as=\"dataset\" index-as=\"datasetIndex\">\n                <div>\n                  <facets-overview-row-stats type=\"[[_getFeatureType(feature)]]\" stats=\"[[_getStats(dataModel, dataset, feature)]]\" custom-stats=\"[[_getAllCustomStats(dataModel, feature)]]\" show-weighted=\"[[_showWeighted]]\" has-custom=\"[[_hasCustomStats(dataModel)]]\" data-model=\"[[dataModel]]\" dataset-index=\"[[datasetIndex]]\" compare-mode=\"[[compareMode]]\">\n                  </facets-overview-row-stats>\n                </div>\n              </template>\n            </div>\n            <div class$=\"[[_getChartClass(_expandCharts)]]\">\n              <facets-overview-chart data=\"[[_getChartData(dataModel, feature)]]\" data-model=\"[[dataModel]]\" feature=\"[[_getFeatureName(feature)]]\" selection=\"{{featureSliceSelection}}\" log-scale=\"[[_logScale]]\" show-weighted=\"[[_showWeighted]]\" show-percentage=\"[[_showPercentage]]\" chart-selection=\"[[_chartSelection]]\" expand-chart=\"[[_expandCharts]]\">\n              </facets-overview-chart>\n            </div>\n          </div>\n        </template>\n      </iron-list>\n    </div>\n  </template>\n</dom-module>\n<script>//~~WEBPATH~~/facets-overview/components/facets-overview-table/facets-overview-table.js\nPolymer({is:\"facets-overview-table\",properties:{dataModel:{type:Object,observer:\"_handleResize\"},features:Array,featureSliceSelection:{type:Object,notify:!0},numeric:{type:Boolean,value:!1},compareMode:{type:Boolean,value:!1},_logScale:{type:Boolean,value:!1},_expandCharts:{type:Boolean,value:!1,observer:\"_handleResize\"},_showWeighted:{type:Boolean,value:!1},_showPercentage:{type:Boolean,value:!1},_chartSelection:{type:String,value:me},_enableLogScale:{type:Boolean,value:!0},_chartSelectionTypes:{type:Array,\ncomputed:\"_computeChartSelectionTypes(numeric, dataModel, features)\"}},_handleResize:function(){var a=this.$$(\"iron-list\");a&&a.fire(\"iron-resize\")},_computeChartSelectionTypes:function(a,b,c){var d=[me];a&&d.push(ne);if(a=0!==c.length)a:{if(a=this._getChartData(b,c[0]))for(var e=0;e<a.length;e++)if(a[e].histMap[oe]){a=!0;break a}a=!1}a&&d.push(oe);b.doesContainFeatureListLengthData()&&d.push(pe);return d.concat(b.getExtraHistogramNames(c))},attached:function(){var a=this;setTimeout(function(){a._handleResize()},\n1E3)},_chartSelectionHasQuantiles:function(a){return a===ne||a===oe||a===pe},_getTitle:function(a){return a?\"Numeric\":\"Categorical\"},_getFeatureName:function(a){return a.getName()},_getFeatureType:function(a){return this._getFeatureTypeForList([a])},_getFeatureTypeForList:function(a){return 0<a.length?a[0].getType()||0:0},_hasCustomStats:function(a){return null==a?!1:a.doesContainCustomStats()},_hasMultipleDatasets:function(a){return null==a?!1:1<a.getDatasetNames().length},_getAllCustomStats:function(a,\nb){var c=[],d={};Pb(a.getDatasetFeatureStatistics()).forEach(function(e){var f=a.getFeatureIndex(e.getName(),b.getName());null!=f&&(e=lc(Wb(e)[f]))&&e.forEach(function(a){d[a.getName()]||(d[a.getName()]=!0,c.push(a))})});return c},_getDatasets:function(a){return a?Pb(a.getDatasetFeatureStatistics()):null},_getStats:function(a,b,c){return a&&b&&c?a.getFeature(c.getName(),b.getName()):null},_getChartData:function(a,b){return a&&b?a.getDatasetHistogramsForFeature(b.getName()):[]},_getFeatureCountText:function(a,\nb,c){a=a?a.getNumUniqueFeaturesByType(b):0;c=c.length;return a===c?a.toLocaleString():c.toLocaleString()+\"/\"+a.toLocaleString()},_hasWeightedHistogram:function(a){return 0===a.length?!1:Ce(this._getChartData(this.dataModel,a[0]))},_hasQuantiles:function(a){if(0===a.length)a=!1;else{var b=this._getFeatureTypeForList(a);a=0===b||1===b?De(this._getChartData(this.dataModel,a[0])):!1}return a},_getChartClass:function(a){var b=\"chart-column \";a||(b+=\"table-cell \");return b},_getTableWrapperClass:function(a){return a&&\n0!==a.length?\"\":\"hidden\"}});\n</script>\n\n\n\n\n\n<script>//~~WEBPATH~~/iron-validator-behavior/iron-validator-behavior.html.js\nPolymer.IronValidatorBehavior={properties:{validatorType:{type:String,value:\"validator\"},validatorName:{type:String,value:function(){return this.is}}},ready:function(){new Polymer.IronMeta({type:this.validatorType,key:this.validatorName,value:this})},validate:function(){}};\n</script>\n\n\n<script>//~~WEBPATH~~/facets-overview/components/facets-overview/facets-overview-filter-validator.html.js\nPolymer({is:\"facets-overview-filter-validator\",behaviors:[Polymer.IronValidatorBehavior],validate:function(a){try{return new RegExp(a),!0}catch(b){return!1}}});\n</script>\n\n\n<dom-module id=\"facets-overview\">\n  <template>\n    <style>\n      :host {\n        @apply(--paper-font-common-base)\n        font-size: 10pt;\n      }\n      .controls {\n        background: rgba(234,234,234,0.2);\n        border-bottom: solid 0.5px rgba(0,0,0,0.2);\n        display: flex;\n        height: 60px;\n        padding-left: 20px;\n\n      }\n      .feature-checkboxes {\n        background: rgba(234,234,234,0.2);\n        border-bottom: solid 0.5px rgba(0,0,0,0.2);\n        display: flex;\n        padding:  8px 0 8px 20px;\n      }\n      .feature-checkbox {\n        display: flex;\n        padding: 0 0 0 16px;\n      }\n      paper-checkbox {\n        font-size: 14px;\n      }\n      .input-control {\n        --paper-input-container-label --paper-input-container-input: {\n          font-size: 14px;\n        };\n      }\n      .features-text {\n        line-height: 1;\n        padding: 1px 0 0 0;\n        font-size: 14px;\n      }\n      .left-dropdown {\n        padding: 0 10px 0 0;\n      }\n      .middle-checkbox {\n        margin-top: 30px;\n        padding: 0 10px;\n      }\n      .right-input {\n        width: 300px;\n        padding: 0 10px;\n      }\n      .feature-iron-list {\n        max-height: 800px;\n        overflow: auto;\n      }\n      .feature-column {\n        width: 200px;\n        max-width: 200px;\n        overflow-wrap: break-word;\n        text-align: left;\n      }\n      .legend-column {\n        width: 120px;\n      }\n      .stats-column {\n        width: 150px;\n        max-width: 150px;\n        overflow-wrap: break-word;\n        text-align: right;\n      }\n      .chart-column {\n        width: 580px;\n        text-align: center;\n      }\n      .table-row {\n        display: table-row;\n      }\n      .table-cell {\n        display: table-cell;\n        vertical-align: top;\n        padding: 10px 5px 0\n      }\n      .chart-column.table-cell {\n        display: table-cell;\n        vertical-align: top;\n        padding: 10px 0 0 20px\n      }\n      .header-row {\n        clear: both;\n      }\n      .header-row > .table-cell {\n        font-size: 14pt;\n        padding: 0 5px 0;\n        border-bottom: 1px solid black;\n      }\n      .stats-header-text {\n        text-align: right;\n      }\n      .chart-header-text {\n        text-align: center;\n      }\n      .table-holder {\n        display: flex;\n        flex-wrap: wrap;\n        overflow-x: auto;\n        margin-left: 30px;\n      }\n      .table-left {\n        margin: 20px 20px 0 0;\n      }\n      .table-right {\n        margin: 20px 0 0 0;\n      }\n      .hidden {\n        display: none;\n      }\n      .legend-holder {\n        display: flex;\n        margin: 8px 0 0 38px;\n      }\n      .legend-box {\n        width: 8px;\n        height: 8px;\n        margin-top: 6px;\n      }\n      .legend-row {\n        display: flex;\n      }\n      .legend-name {\n        margin: 3px 10px 0 5px;\n        font-size: 12px;\n      }\n      /* Give min height to placeholder in paper-input to get around colab embedding\n       * alignment issue.\n       */\n      ::content paper-input-container > .floated-label-placeholder {\n        min-height: 20px;\n      }\n    </style>\n    <template is=\"dom-if\" if=\"[[_dataModel]]\">\n      <div class$=\"[[_getControlsWrapperClass(_dataModel)]]\">\n        <div class=\"controls\">\n          <paper-dropdown-menu class=\"left-dropdown input-control\" label=\"Sort by\">\n            <paper-listbox class=\"dropdown-content\" selected=\"{{_sortOrder}}\">\n              <template is=\"dom-repeat\" items=\"[[_sortOptions]]\" as=\"option\">\n                <paper-item>[[option.name]]</paper-item>\n              </template>\n            </paper-listbox>\n          </paper-dropdown-menu>\n          <paper-checkbox noink class=\"middle-checkbox\" checked=\"{{_reverseOrder}}\">\n            Reverse order\n          </paper-checkbox>\n          <paper-input class=\"right-input input-control\" label=\"Feature search\" value=\"{{_searchString}}\" auto-validate=\"true\" validator=\"filter-validator\">\n            <facets-overview-filter-validator validator-name=\"filter-validator\">\n            </facets-overview-filter-validator>\n          </paper-input>\n        </div>\n        <div class=\"feature-checkboxes\">\n          <div class=\"features-text\">Features: </div>\n          <template is=\"dom-repeat\" items=\"[[_featureSpecArray]]\" as=\"specAndList\">\n          <div>\n            <paper-checkbox noink checked=\"true\" class=\"feature-checkbox\" id=\"[[_getSpecCheckboxId(specAndList)]]\" on-change=\"_featureSpecCheck\">\n              [[_getSpecCheckboxText(specAndList)]]\n            </paper-checkbox>\n          </div>\n        </template>\n        </div>\n      </div>\n      <template is=\"dom-if\" if=\"[[_hasMultipleDatasets(_dataModel)]]\">\n        <div class=\"legend-holder\">\n          <template is=\"dom-repeat\" items=\"[[_getDatasets(_dataModel)]]\" as=\"dataset\" index-as=\"datasetIndex\">\n            <div class=\"legend-row\">\n              <div class=\"legend-box\" style=\"[[_getLegendBoxStyle(_dataModel, datasetIndex)]]\"></div>\n              <div class=\"legend-name\">[[_getDatasetName(_dataModel, datasetIndex)]]</div>\n            </div>\n          </template>\n        </div>\n      </template>\n      <div class=\"table-holder\">\n        <facets-overview-table features=\"[[_getNumericFeatureListItems(_dataModel, _searchString, _sortOrder, _reverseOrder, _featureSpecCheckboxes)]]\" data-model=\"[[_dataModel]]\" feature-slice-selection=\"{{featureSliceSelection}}\" numeric=\"true\" class=\"table-left\" compare-mode=\"[[compareMode]]\">\n        </facets-overview-table>\n        <facets-overview-table features=\"[[_getNonNumericFeatureListItems(_dataModel, _searchString, _sortOrder, _reverseOrder, _featureSpecCheckboxes)]]\" data-model=\"[[_dataModel]]\" feature-slice-selection=\"{{featureSliceSelection}}\" class=\"table-right\" compare-mode=\"[[compareMode]]\">\n        </facets-overview-table>\n      </div>\n    </template>\n  </template>\n</dom-module>\n<script>//~~WEBPATH~~/facets-overview/components/facets-overview/facets-overview.js\nPolymer({is:\"facets-overview\",properties:{_searchString:String,_sortOptions:Array,_reverseOrder:Boolean,_sortOrder:{type:Number,value:0},protoInput:{type:Object,observer:\"_update\"},featureSliceSelection:{type:Object,notify:!0},compareMode:{type:Boolean,value:!1},_dataModel:{type:Object,value:null},_featureSpecArray:{type:Array,computed:\"_getFeatureSpecArray(_dataModel)\"},_featureSpecCheckboxes:Array},_getFeatureSpecArray:function(a){if(!a)return[];for(var b=[],c=0;13>c;c++)b.push(!0);this._featureSpecCheckboxes=\nb;return a.getNonEmptyFeatureSpecLists()},_getSpecCheckboxText:function(a){return Fe(a.spec)+\"(\"+a.features.length+\")\"},_getSpecCheckboxId:function(a){return String(a.spec)},_featureSpecCheck:function(a){if(a){for(var b=[],c=+a.target.id,d=0;13>d;d++)c===d?b.push(a.target.checked):b.push(this._featureSpecCheckboxes[d]);this._featureSpecCheckboxes=b}},_convertInputToProto:function(a){if(!a)return null;if(a instanceof Nb)return a;if(a instanceof Uint8Array)return Rb(a);if(\"string\"===typeof a||a instanceof\nString){a=atob(a);for(var b=new Uint8Array(a.length),c=0;c<a.length;c++)b[c]=a.charCodeAt(c);return Rb(b)}return null},_update:function(){var a=this;this.featureSliceSelection=null;var b=this._convertInputToProto(this.protoInput);if(b){var c=new bf(Ae(b));this.set(\"_sortOptions\",[{name:\"Feature order\",map:{}},{name:\"Non-uniformity\",map:{}},{name:\"Alphabetical\",map:{}},{name:\"Amount missing/zero\",map:{}}]);var d=Pb(c.getDatasetFeatureStatistics()),e=1<d.length;e&&this.push(\"_sortOptions\",{name:\"Distribution distance\",\nmap:{}});c.getUniqueFeatures().forEach(function(b,g){a._sortOptions[0].map[b.getName()]=g;g=c.getDatasetHistogramsForFeature(b.getName());a._sortOptions[1].map[b.getName()]=g.reduce(function(a,b){b=b.histMap[me]?re(b.histMap[me].getBucketsList()):1;return Math.min(a,b)},1);a._sortOptions[2].map[b.getName()]=b.getName();a._sortOptions[3].map[b.getName()]=d.reduce(function(d,e){var f=a._getStats(c,e,b);e=null;var g=0,k=0;f&&W(f)?(f=W(f),e=Pc(f),g+=Y(u(f,4,0))):f&&hc(f)?e=Pc(hc(f)):f&&jc(f)&&(e=Pc(jc(f)));\ne&&(k=Y(e.getNumMissing()),g+=k,k=Y(e.getNumNonMissing())+k);return Math.min(d,-1*(0===k?1:g/k))},0);e&&(a._sortOptions[4].map[b.getName()]=-1*ye(g))},this);this._dataModel=c}else this._dataModel=null},_getStats:function(a,b,c){return a&&b&&c?a.getFeature(c.getName(),b.getName()):null},_getSortFunction:function(a,b){var c=this._sortOptions[a].map,d=b?-1:1;return function(a,b){a=c[a.getName()];b=c[b.getName()];return\"undefined\"==typeof a||\"undefined\"==typeof b?0:d*(a<b?-1:1)}},_getFilter:function(a){if(a)try{var b=\nnew RegExp(a,\"i\");return function(a){return b.test(a.getName())}}catch(c){return null}else return null},_getNumericFeatureListItems:function(a,b,c,d,e){return this._getFeatureListItems(a,b,c,d,e,!0)},_getNonNumericFeatureListItems:function(a,b,c,d,e){return this._getFeatureListItems(a,b,c,d,e,!1)},_getFeatureListItems:function(a,b,c,d,e,f){if(!a)return[];var g=this._getFilter(b);b=a.getUniqueFeatures();b=g?b.filter(function(b){return g(b)&&e[a.getFeatureSpecForFeature(b.getName())]}):b.filter(function(b){return e[a.getFeatureSpecForFeature(b.getName())]});\nb=b.filter(function(a){return f?null!=W(a):null==W(a)});return b.slice().sort(this._getSortFunction(c,d))},_getControlsWrapperClass:function(a){return!a||1>=a.getUniqueFeatures().length?\"hidden\":\"\"},_getDatasetName:function(a,b){return a.getDatasetNames()[b]},_getLegendBoxStyle:function(a,b){return\"background-color:\"+a.getChartColorString(b)},_getDatasets:function(a){return a?Pb(a.getDatasetFeatureStatistics()):null},_hasMultipleDatasets:function(a){return null==a?!1:1<a.getDatasetNames().length},\ngetStatsProto:function(a){return ce(a)}});\n</script>\n\n\n\n\n<iron-iconset-svg name=\"icons\" size=\"24\">\n<svg><defs>\n<g id=\"3d-rotation\"><path d=\"M7.52 21.48C4.25 19.94 1.91 16.76 1.55 13H.05C.56 19.16 5.71 24 12 24l.66-.03-3.81-3.81-1.33 1.32zm.89-6.52c-.19 0-.37-.03-.52-.08-.16-.06-.29-.13-.4-.24-.11-.1-.2-.22-.26-.37-.06-.14-.09-.3-.09-.47h-1.3c0 .36.07.68.21.95.14.27.33.5.56.69.24.18.51.32.82.41.3.1.62.15.96.15.37 0 .72-.05 1.03-.15.32-.1.6-.25.83-.44s.42-.43.55-.72c.13-.29.2-.61.2-.97 0-.19-.02-.38-.07-.56-.05-.18-.12-.35-.23-.51-.1-.16-.24-.3-.4-.43-.17-.13-.37-.23-.61-.31.2-.09.37-.2.52-.33.15-.13.27-.27.37-.42.1-.15.17-.3.22-.46.05-.16.07-.32.07-.48 0-.36-.06-.68-.18-.96-.12-.28-.29-.51-.51-.69-.2-.19-.47-.33-.77-.43C9.1 8.05 8.76 8 8.39 8c-.36 0-.69.05-1 .16-.3.11-.57.26-.79.45-.21.19-.38.41-.51.67-.12.26-.18.54-.18.85h1.3c0-.17.03-.32.09-.45s.14-.25.25-.34c.11-.09.23-.17.38-.22.15-.05.3-.08.48-.08.4 0 .7.1.89.31.19.2.29.49.29.86 0 .18-.03.34-.08.49-.05.15-.14.27-.25.37-.11.1-.25.18-.41.24-.16.06-.36.09-.58.09H7.5v1.03h.77c.22 0 .42.02.6.07s.33.13.45.23c.12.11.22.24.29.4.07.16.1.35.1.57 0 .41-.12.72-.35.93-.23.23-.55.33-.95.33zm8.55-5.92c-.32-.33-.7-.59-1.14-.77-.43-.18-.92-.27-1.46-.27H12v8h2.3c.55 0 1.06-.09 1.51-.27.45-.18.84-.43 1.16-.76.32-.33.57-.73.74-1.19.17-.47.26-.99.26-1.57v-.4c0-.58-.09-1.1-.26-1.57-.18-.47-.43-.87-.75-1.2zm-.39 3.16c0 .42-.05.79-.14 1.13-.1.33-.24.62-.43.85-.19.23-.43.41-.71.53-.29.12-.62.18-.99.18h-.91V9.12h.97c.72 0 1.27.23 1.64.69.38.46.57 1.12.57 1.99v.4zM12 0l-.66.03 3.81 3.81 1.33-1.33c3.27 1.55 5.61 4.72 5.96 8.48h1.5C23.44 4.84 18.29 0 12 0z\" /></g>\n<g id=\"accessibility\"><path d=\"M12 2c1.1 0 2 .9 2 2s-.9 2-2 2-2-.9-2-2 .9-2 2-2zm9 7h-6v13h-2v-6h-2v6H9V9H3V7h18v2z\" /></g>\n<g id=\"accessible\"><circle cx=\"12\" cy=\"4\" r=\"2\" /><path d=\"M19 13v-2c-1.54.02-3.09-.75-4.07-1.83l-1.29-1.43c-.17-.19-.38-.34-.61-.45-.01 0-.01-.01-.02-.01H13c-.35-.2-.75-.3-1.19-.26C10.76 7.11 10 8.04 10 9.09V15c0 1.1.9 2 2 2h5v5h2v-5.5c0-1.1-.9-2-2-2h-3v-3.45c1.29 1.07 3.25 1.94 5 1.95zm-6.17 5c-.41 1.16-1.52 2-2.83 2-1.66 0-3-1.34-3-3 0-1.31.84-2.41 2-2.83V12.1c-2.28.46-4 2.48-4 4.9 0 2.76 2.24 5 5 5 2.42 0 4.44-1.72 4.9-4h-2.07z\" /></g>\n<g id=\"account-balance\"><path d=\"M4 10v7h3v-7H4zm6 0v7h3v-7h-3zM2 22h19v-3H2v3zm14-12v7h3v-7h-3zm-4.5-9L2 6v2h19V6l-9.5-5z\" /></g>\n<g id=\"account-balance-wallet\"><path d=\"M21 18v1c0 1.1-.9 2-2 2H5c-1.11 0-2-.9-2-2V5c0-1.1.89-2 2-2h14c1.1 0 2 .9 2 2v1h-9c-1.11 0-2 .9-2 2v8c0 1.1.89 2 2 2h9zm-9-2h10V8H12v8zm4-2.5c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5z\" /></g>\n<g id=\"account-box\"><path d=\"M3 5v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2H5c-1.11 0-2 .9-2 2zm12 4c0 1.66-1.34 3-3 3s-3-1.34-3-3 1.34-3 3-3 3 1.34 3 3zm-9 8c0-2 4-3.1 6-3.1s6 1.1 6 3.1v1H6v-1z\" /></g>\n<g id=\"account-circle\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 3c1.66 0 3 1.34 3 3s-1.34 3-3 3-3-1.34-3-3 1.34-3 3-3zm0 14.2c-2.5 0-4.71-1.28-6-3.22.03-1.99 4-3.08 6-3.08 1.99 0 5.97 1.09 6 3.08-1.29 1.94-3.5 3.22-6 3.22z\" /></g>\n<g id=\"add\"><path d=\"M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z\" /></g>\n<g id=\"add-alert\"><path d=\"M10.01 21.01c0 1.1.89 1.99 1.99 1.99s1.99-.89 1.99-1.99h-3.98zm8.87-4.19V11c0-3.25-2.25-5.97-5.29-6.69v-.72C13.59 2.71 12.88 2 12 2s-1.59.71-1.59 1.59v.72C7.37 5.03 5.12 7.75 5.12 11v5.82L3 18.94V20h18v-1.06l-2.12-2.12zM16 13.01h-3v3h-2v-3H8V11h3V8h2v3h3v2.01z\" /></g>\n<g id=\"add-box\"><path d=\"M19 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-2 10h-4v4h-2v-4H7v-2h4V7h2v4h4v2z\" /></g>\n<g id=\"add-circle\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm5 11h-4v4h-2v-4H7v-2h4V7h2v4h4v2z\" /></g>\n<g id=\"add-circle-outline\"><path d=\"M13 7h-2v4H7v2h4v4h2v-4h4v-2h-4V7zm-1-5C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z\" /></g>\n<g id=\"add-shopping-cart\"><path d=\"M11 9h2V6h3V4h-3V1h-2v3H8v2h3v3zm-4 9c-1.1 0-1.99.9-1.99 2S5.9 22 7 22s2-.9 2-2-.9-2-2-2zm10 0c-1.1 0-1.99.9-1.99 2s.89 2 1.99 2 2-.9 2-2-.9-2-2-2zm-9.83-3.25l.03-.12.9-1.63h7.45c.75 0 1.41-.41 1.75-1.03l3.86-7.01L19.42 4h-.01l-1.1 2-2.76 5H8.53l-.13-.27L6.16 6l-.95-2-.94-2H1v2h2l3.6 7.59-1.35 2.45c-.16.28-.25.61-.25.96 0 1.1.9 2 2 2h12v-2H7.42c-.13 0-.25-.11-.25-.25z\" /></g>\n<g id=\"alarm\"><path d=\"M22 5.72l-4.6-3.86-1.29 1.53 4.6 3.86L22 5.72zM7.88 3.39L6.6 1.86 2 5.71l1.29 1.53 4.59-3.85zM12.5 8H11v6l4.75 2.85.75-1.23-4-2.37V8zM12 4c-4.97 0-9 4.03-9 9s4.02 9 9 9c4.97 0 9-4.03 9-9s-4.03-9-9-9zm0 16c-3.87 0-7-3.13-7-7s3.13-7 7-7 7 3.13 7 7-3.13 7-7 7z\" /></g>\n<g id=\"alarm-add\"><path d=\"M7.88 3.39L6.6 1.86 2 5.71l1.29 1.53 4.59-3.85zM22 5.72l-4.6-3.86-1.29 1.53 4.6 3.86L22 5.72zM12 4c-4.97 0-9 4.03-9 9s4.02 9 9 9c4.97 0 9-4.03 9-9s-4.03-9-9-9zm0 16c-3.87 0-7-3.13-7-7s3.13-7 7-7 7 3.13 7 7-3.13 7-7 7zm1-11h-2v3H8v2h3v3h2v-3h3v-2h-3V9z\" /></g>\n<g id=\"alarm-off\"><path d=\"M12 6c3.87 0 7 3.13 7 7 0 .84-.16 1.65-.43 2.4l1.52 1.52c.58-1.19.91-2.51.91-3.92 0-4.97-4.03-9-9-9-1.41 0-2.73.33-3.92.91L9.6 6.43C10.35 6.16 11.16 6 12 6zm10-.28l-4.6-3.86-1.29 1.53 4.6 3.86L22 5.72zM2.92 2.29L1.65 3.57 2.98 4.9l-1.11.93 1.42 1.42 1.11-.94.8.8C3.83 8.69 3 10.75 3 13c0 4.97 4.02 9 9 9 2.25 0 4.31-.83 5.89-2.2l2.2 2.2 1.27-1.27L3.89 3.27l-.97-.98zm13.55 16.1C15.26 19.39 13.7 20 12 20c-3.87 0-7-3.13-7-7 0-1.7.61-3.26 1.61-4.47l9.86 9.86zM8.02 3.28L6.6 1.86l-.86.71 1.42 1.42.86-.71z\" /></g>\n<g id=\"alarm-on\"><path d=\"M22 5.72l-4.6-3.86-1.29 1.53 4.6 3.86L22 5.72zM7.88 3.39L6.6 1.86 2 5.71l1.29 1.53 4.59-3.85zM12 4c-4.97 0-9 4.03-9 9s4.02 9 9 9c4.97 0 9-4.03 9-9s-4.03-9-9-9zm0 16c-3.87 0-7-3.13-7-7s3.13-7 7-7 7 3.13 7 7-3.13 7-7 7zm-1.46-5.47L8.41 12.4l-1.06 1.06 3.18 3.18 6-6-1.06-1.06-4.93 4.95z\" /></g>\n<g id=\"all-out\"><path d=\"M16.21 4.16l4 4v-4zm4 12l-4 4h4zm-12 4l-4-4v4zm-4-12l4-4h-4zm12.95-.95c-2.73-2.73-7.17-2.73-9.9 0s-2.73 7.17 0 9.9 7.17 2.73 9.9 0 2.73-7.16 0-9.9zm-1.1 8.8c-2.13 2.13-5.57 2.13-7.7 0s-2.13-5.57 0-7.7 5.57-2.13 7.7 0 2.13 5.57 0 7.7z\" /></g>\n<g id=\"android\"><path d=\"M6 18c0 .55.45 1 1 1h1v3.5c0 .83.67 1.5 1.5 1.5s1.5-.67 1.5-1.5V19h2v3.5c0 .83.67 1.5 1.5 1.5s1.5-.67 1.5-1.5V19h1c.55 0 1-.45 1-1V8H6v10zM3.5 8C2.67 8 2 8.67 2 9.5v7c0 .83.67 1.5 1.5 1.5S5 17.33 5 16.5v-7C5 8.67 4.33 8 3.5 8zm17 0c-.83 0-1.5.67-1.5 1.5v7c0 .83.67 1.5 1.5 1.5s1.5-.67 1.5-1.5v-7c0-.83-.67-1.5-1.5-1.5zm-4.97-5.84l1.3-1.3c.2-.2.2-.51 0-.71-.2-.2-.51-.2-.71 0l-1.48 1.48C13.85 1.23 12.95 1 12 1c-.96 0-1.86.23-2.66.63L7.85.15c-.2-.2-.51-.2-.71 0-.2.2-.2.51 0 .71l1.31 1.31C6.97 3.26 6 5.01 6 7h12c0-1.99-.97-3.75-2.47-4.84zM10 5H9V4h1v1zm5 0h-1V4h1v1z\" /></g>\n<g id=\"announcement\"><path d=\"M20 2H4c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-7 9h-2V5h2v6zm0 4h-2v-2h2v2z\" /></g>\n<g id=\"apps\"><path d=\"M4 8h4V4H4v4zm6 12h4v-4h-4v4zm-6 0h4v-4H4v4zm0-6h4v-4H4v4zm6 0h4v-4h-4v4zm6-10v4h4V4h-4zm-6 4h4V4h-4v4zm6 6h4v-4h-4v4zm0 6h4v-4h-4v4z\" /></g>\n<g id=\"archive\"><path d=\"M20.54 5.23l-1.39-1.68C18.88 3.21 18.47 3 18 3H6c-.47 0-.88.21-1.16.55L3.46 5.23C3.17 5.57 3 6.02 3 6.5V19c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V6.5c0-.48-.17-.93-.46-1.27zM12 17.5L6.5 12H10v-2h4v2h3.5L12 17.5zM5.12 5l.81-1h12l.94 1H5.12z\" /></g>\n<g id=\"arrow-back\"><path d=\"M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2z\" /></g>\n<g id=\"arrow-downward\"><path d=\"M20 12l-1.41-1.41L13 16.17V4h-2v12.17l-5.58-5.59L4 12l8 8 8-8z\" /></g>\n<g id=\"arrow-drop-down\"><path d=\"M7 10l5 5 5-5z\" /></g>\n<g id=\"arrow-drop-down-circle\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 12l-4-4h8l-4 4z\" /></g>\n<g id=\"arrow-drop-up\"><path d=\"M7 14l5-5 5 5z\" /></g>\n<g id=\"arrow-forward\"><path d=\"M12 4l-1.41 1.41L16.17 11H4v2h12.17l-5.58 5.59L12 20l8-8z\" /></g>\n<g id=\"arrow-upward\"><path d=\"M4 12l1.41 1.41L11 7.83V20h2V7.83l5.58 5.59L20 12l-8-8-8 8z\" /></g>\n<g id=\"aspect-ratio\"><path d=\"M19 12h-2v3h-3v2h5v-5zM7 9h3V7H5v5h2V9zm14-6H3c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16.01H3V4.99h18v14.02z\" /></g>\n<g id=\"assessment\"><path d=\"M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM9 17H7v-7h2v7zm4 0h-2V7h2v10zm4 0h-2v-4h2v4z\" /></g>\n<g id=\"assignment\"><path d=\"M19 3h-4.18C14.4 1.84 13.3 1 12 1c-1.3 0-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-7 0c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm2 14H7v-2h7v2zm3-4H7v-2h10v2zm0-4H7V7h10v2z\" /></g>\n<g id=\"assignment-ind\"><path d=\"M19 3h-4.18C14.4 1.84 13.3 1 12 1c-1.3 0-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-7 0c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm0 4c1.66 0 3 1.34 3 3s-1.34 3-3 3-3-1.34-3-3 1.34-3 3-3zm6 12H6v-1.4c0-2 4-3.1 6-3.1s6 1.1 6 3.1V19z\" /></g>\n<g id=\"assignment-late\"><path d=\"M19 3h-4.18C14.4 1.84 13.3 1 12 1c-1.3 0-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-6 15h-2v-2h2v2zm0-4h-2V8h2v6zm-1-9c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1z\" /></g>\n<g id=\"assignment-return\"><path d=\"M19 3h-4.18C14.4 1.84 13.3 1 12 1c-1.3 0-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-7 0c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm4 12h-4v3l-5-5 5-5v3h4v4z\" /></g>\n<g id=\"assignment-returned\"><path d=\"M19 3h-4.18C14.4 1.84 13.3 1 12 1c-1.3 0-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-7 0c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm0 15l-5-5h3V9h4v4h3l-5 5z\" /></g>\n<g id=\"assignment-turned-in\"><path d=\"M19 3h-4.18C14.4 1.84 13.3 1 12 1c-1.3 0-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-7 0c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm-2 14l-4-4 1.41-1.41L10 14.17l6.59-6.59L18 9l-8 8z\" /></g>\n<g id=\"attachment\"><path d=\"M2 12.5C2 9.46 4.46 7 7.5 7H18c2.21 0 4 1.79 4 4s-1.79 4-4 4H9.5C8.12 15 7 13.88 7 12.5S8.12 10 9.5 10H17v2H9.41c-.55 0-.55 1 0 1H18c1.1 0 2-.9 2-2s-.9-2-2-2H7.5C5.57 9 4 10.57 4 12.5S5.57 16 7.5 16H17v2H7.5C4.46 18 2 15.54 2 12.5z\" /></g>\n<g id=\"autorenew\"><path d=\"M12 6v3l4-4-4-4v3c-4.42 0-8 3.58-8 8 0 1.57.46 3.03 1.24 4.26L6.7 14.8c-.45-.83-.7-1.79-.7-2.8 0-3.31 2.69-6 6-6zm6.76 1.74L17.3 9.2c.44.84.7 1.79.7 2.8 0 3.31-2.69 6-6 6v-3l-4 4 4 4v-3c4.42 0 8-3.58 8-8 0-1.57-.46-3.03-1.24-4.26z\" /></g>\n<g id=\"backspace\"><path d=\"M22 3H7c-.69 0-1.23.35-1.59.88L0 12l5.41 8.11c.36.53.9.89 1.59.89h15c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-3 12.59L17.59 17 14 13.41 10.41 17 9 15.59 12.59 12 9 8.41 10.41 7 14 10.59 17.59 7 19 8.41 15.41 12 19 15.59z\" /></g>\n<g id=\"backup\"><path d=\"M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM14 13v4h-4v-4H7l5-5 5 5h-3z\" /></g>\n<g id=\"block\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zM4 12c0-4.42 3.58-8 8-8 1.85 0 3.55.63 4.9 1.69L5.69 16.9C4.63 15.55 4 13.85 4 12zm8 8c-1.85 0-3.55-.63-4.9-1.69L18.31 7.1C19.37 8.45 20 10.15 20 12c0 4.42-3.58 8-8 8z\" /></g>\n<g id=\"book\"><path d=\"M18 2H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zM6 4h5v8l-2.5-1.5L6 12V4z\" /></g>\n<g id=\"bookmark\"><path d=\"M17 3H7c-1.1 0-1.99.9-1.99 2L5 21l7-3 7 3V5c0-1.1-.9-2-2-2z\" /></g>\n<g id=\"bookmark-border\"><path d=\"M17 3H7c-1.1 0-1.99.9-1.99 2L5 21l7-3 7 3V5c0-1.1-.9-2-2-2zm0 15l-5-2.18L7 18V5h10v13z\" /></g>\n<g id=\"bug-report\"><path d=\"M20 8h-2.81c-.45-.78-1.07-1.45-1.82-1.96L17 4.41 15.59 3l-2.17 2.17C12.96 5.06 12.49 5 12 5c-.49 0-.96.06-1.41.17L8.41 3 7 4.41l1.62 1.63C7.88 6.55 7.26 7.22 6.81 8H4v2h2.09c-.05.33-.09.66-.09 1v1H4v2h2v1c0 .34.04.67.09 1H4v2h2.81c1.04 1.79 2.97 3 5.19 3s4.15-1.21 5.19-3H20v-2h-2.09c.05-.33.09-.66.09-1v-1h2v-2h-2v-1c0-.34-.04-.67-.09-1H20V8zm-6 8h-4v-2h4v2zm0-4h-4v-2h4v2z\" /></g>\n<g id=\"build\"><path d=\"M22.7 19l-9.1-9.1c.9-2.3.4-5-1.5-6.9-2-2-5-2.4-7.4-1.3L9 6 6 9 1.6 4.7C.4 7.1.9 10.1 2.9 12.1c1.9 1.9 4.6 2.4 6.9 1.5l9.1 9.1c.4.4 1 .4 1.4 0l2.3-2.3c.5-.4.5-1.1.1-1.4z\" /></g>\n<g id=\"cached\"><path d=\"M19 8l-4 4h3c0 3.31-2.69 6-6 6-1.01 0-1.97-.25-2.8-.7l-1.46 1.46C8.97 19.54 10.43 20 12 20c4.42 0 8-3.58 8-8h3l-4-4zM6 12c0-3.31 2.69-6 6-6 1.01 0 1.97.25 2.8.7l1.46-1.46C15.03 4.46 13.57 4 12 4c-4.42 0-8 3.58-8 8H1l4 4 4-4H6z\" /></g>\n<g id=\"camera-enhance\"><path d=\"M9 3L7.17 5H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2h-3.17L15 3H9zm3 15c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-1l1.25-2.75L16 13l-2.75-1.25L12 9l-1.25 2.75L8 13l2.75 1.25z\" /></g>\n<g id=\"cancel\"><path d=\"M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm5 13.59L15.59 17 12 13.41 8.41 17 7 15.59 10.59 12 7 8.41 8.41 7 12 10.59 15.59 7 17 8.41 13.41 12 17 15.59z\" /></g>\n<g id=\"card-giftcard\"><path d=\"M20 6h-2.18c.11-.31.18-.65.18-1 0-1.66-1.34-3-3-3-1.05 0-1.96.54-2.5 1.35l-.5.67-.5-.68C10.96 2.54 10.05 2 9 2 7.34 2 6 3.34 6 5c0 .35.07.69.18 1H4c-1.11 0-1.99.89-1.99 2L2 19c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V8c0-1.11-.89-2-2-2zm-5-2c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zM9 4c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm11 15H4v-2h16v2zm0-5H4V8h5.08L7 10.83 8.62 12 11 8.76l1-1.36 1 1.36L15.38 12 17 10.83 14.92 8H20v6z\" /></g>\n<g id=\"card-membership\"><path d=\"M20 2H4c-1.11 0-2 .89-2 2v11c0 1.11.89 2 2 2h4v5l4-2 4 2v-5h4c1.11 0 2-.89 2-2V4c0-1.11-.89-2-2-2zm0 13H4v-2h16v2zm0-5H4V4h16v6z\" /></g>\n<g id=\"card-travel\"><path d=\"M20 6h-3V4c0-1.11-.89-2-2-2H9c-1.11 0-2 .89-2 2v2H4c-1.11 0-2 .89-2 2v11c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V8c0-1.11-.89-2-2-2zM9 4h6v2H9V4zm11 15H4v-2h16v2zm0-5H4V8h3v2h2V8h6v2h2V8h3v6z\" /></g>\n<g id=\"change-history\"><path d=\"M12 7.77L18.39 18H5.61L12 7.77M12 4L2 20h20L12 4z\" /></g>\n<g id=\"check\"><path d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\" /></g>\n<g id=\"check-box\"><path d=\"M19 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.11 0 2-.9 2-2V5c0-1.1-.89-2-2-2zm-9 14l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z\" /></g>\n<g id=\"check-box-outline-blank\"><path d=\"M19 5v14H5V5h14m0-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z\" /></g>\n<g id=\"check-circle\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z\" /></g>\n<g id=\"chevron-left\"><path d=\"M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z\" /></g>\n<g id=\"chevron-right\"><path d=\"M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z\" /></g>\n<g id=\"chrome-reader-mode\"><path d=\"M13 12h7v1.5h-7zm0-2.5h7V11h-7zm0 5h7V16h-7zM21 4H3c-1.1 0-2 .9-2 2v13c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 15h-9V6h9v13z\" /></g>\n<g id=\"class\"><path d=\"M18 2H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zM6 4h5v8l-2.5-1.5L6 12V4z\" /></g>\n<g id=\"clear\"><path d=\"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\" /></g>\n<g id=\"close\"><path d=\"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\" /></g>\n<g id=\"cloud\"><path d=\"M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96z\" /></g>\n<g id=\"cloud-circle\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm4.5 14H8c-1.66 0-3-1.34-3-3s1.34-3 3-3l.14.01C8.58 8.28 10.13 7 12 7c2.21 0 4 1.79 4 4h.5c1.38 0 2.5 1.12 2.5 2.5S17.88 16 16.5 16z\" /></g>\n<g id=\"cloud-done\"><path d=\"M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM10 17l-3.5-3.5 1.41-1.41L10 14.17 15.18 9l1.41 1.41L10 17z\" /></g>\n<g id=\"cloud-download\"><path d=\"M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM17 13l-5 5-5-5h3V9h4v4h3z\" /></g>\n<g id=\"cloud-off\"><path d=\"M19.35 10.04C18.67 6.59 15.64 4 12 4c-1.48 0-2.85.43-4.01 1.17l1.46 1.46C10.21 6.23 11.08 6 12 6c3.04 0 5.5 2.46 5.5 5.5v.5H19c1.66 0 3 1.34 3 3 0 1.13-.64 2.11-1.56 2.62l1.45 1.45C23.16 18.16 24 16.68 24 15c0-2.64-2.05-4.78-4.65-4.96zM3 5.27l2.75 2.74C2.56 8.15 0 10.77 0 14c0 3.31 2.69 6 6 6h11.73l2 2L21 20.73 4.27 4 3 5.27zM7.73 10l8 8H6c-2.21 0-4-1.79-4-4s1.79-4 4-4h1.73z\" /></g>\n<g id=\"cloud-queue\"><path d=\"M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM19 18H6c-2.21 0-4-1.79-4-4s1.79-4 4-4h.71C7.37 7.69 9.48 6 12 6c3.04 0 5.5 2.46 5.5 5.5v.5H19c1.66 0 3 1.34 3 3s-1.34 3-3 3z\" /></g>\n<g id=\"cloud-upload\"><path d=\"M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM14 13v4h-4v-4H7l5-5 5 5h-3z\" /></g>\n<g id=\"code\"><path d=\"M9.4 16.6L4.8 12l4.6-4.6L8 6l-6 6 6 6 1.4-1.4zm5.2 0l4.6-4.6-4.6-4.6L16 6l6 6-6 6-1.4-1.4z\" /></g>\n<g id=\"compare-arrows\"><path d=\"M9.01 14H2v2h7.01v3L13 15l-3.99-4v3zm5.98-1v-3H22V8h-7.01V5L11 9l3.99 4z\" /></g>\n<g id=\"content-copy\"><path d=\"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z\" /></g>\n<g id=\"content-cut\"><path d=\"M9.64 7.64c.23-.5.36-1.05.36-1.64 0-2.21-1.79-4-4-4S2 3.79 2 6s1.79 4 4 4c.59 0 1.14-.13 1.64-.36L10 12l-2.36 2.36C7.14 14.13 6.59 14 6 14c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4c0-.59-.13-1.14-.36-1.64L12 14l7 7h3v-1L9.64 7.64zM6 8c-1.1 0-2-.89-2-2s.9-2 2-2 2 .89 2 2-.9 2-2 2zm0 12c-1.1 0-2-.89-2-2s.9-2 2-2 2 .89 2 2-.9 2-2 2zm6-7.5c-.28 0-.5-.22-.5-.5s.22-.5.5-.5.5.22.5.5-.22.5-.5.5zM19 3l-6 6 2 2 7-7V3z\" /></g>\n<g id=\"content-paste\"><path d=\"M19 2h-4.18C14.4.84 13.3 0 12 0c-1.3 0-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-7 0c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm7 18H5V4h2v3h10V4h2v16z\" /></g>\n<g id=\"copyright\"><path d=\"M10.08 10.86c.05-.33.16-.62.3-.87s.34-.46.59-.62c.24-.15.54-.22.91-.23.23.01.44.05.63.13.2.09.38.21.52.36s.25.33.34.53.13.42.14.64h1.79c-.02-.47-.11-.9-.28-1.29s-.4-.73-.7-1.01-.66-.5-1.08-.66-.88-.23-1.39-.23c-.65 0-1.22.11-1.7.34s-.88.53-1.2.92-.56.84-.71 1.36S8 11.29 8 11.87v.27c0 .58.08 1.12.23 1.64s.39.97.71 1.35.72.69 1.2.91 1.05.34 1.7.34c.47 0 .91-.08 1.32-.23s.77-.36 1.08-.63.56-.58.74-.94.29-.74.3-1.15h-1.79c-.01.21-.06.4-.15.58s-.21.33-.36.46-.32.23-.52.3c-.19.07-.39.09-.6.1-.36-.01-.66-.08-.89-.23-.25-.16-.45-.37-.59-.62s-.25-.55-.3-.88-.08-.67-.08-1v-.27c0-.35.03-.68.08-1.01zM12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z\" /></g>\n<g id=\"create\"><path d=\"M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z\" /></g>\n<g id=\"create-new-folder\"><path d=\"M20 6h-8l-2-2H4c-1.11 0-1.99.89-1.99 2L2 18c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V8c0-1.11-.89-2-2-2zm-1 8h-3v3h-2v-3h-3v-2h3V9h2v3h3v2z\" /></g>\n<g id=\"credit-card\"><path d=\"M20 4H4c-1.11 0-1.99.89-1.99 2L2 18c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V6c0-1.11-.89-2-2-2zm0 14H4v-6h16v6zm0-10H4V6h16v2z\" /></g>\n<g id=\"dashboard\"><path d=\"M3 13h8V3H3v10zm0 8h8v-6H3v6zm10 0h8V11h-8v10zm0-18v6h8V3h-8z\" /></g>\n<g id=\"date-range\"><path d=\"M9 11H7v2h2v-2zm4 0h-2v2h2v-2zm4 0h-2v2h2v-2zm2-7h-1V2h-2v2H8V2H6v2H5c-1.11 0-1.99.9-1.99 2L3 20c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 16H5V9h14v11z\" /></g>\n<g id=\"delete\"><path d=\"M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z\" /></g>\n<g id=\"description\"><path d=\"M14 2H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6zm2 16H8v-2h8v2zm0-4H8v-2h8v2zm-3-5V3.5L18.5 9H13z\" /></g>\n<g id=\"dns\"><path d=\"M20 13H4c-.55 0-1 .45-1 1v6c0 .55.45 1 1 1h16c.55 0 1-.45 1-1v-6c0-.55-.45-1-1-1zM7 19c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zM20 3H4c-.55 0-1 .45-1 1v6c0 .55.45 1 1 1h16c.55 0 1-.45 1-1V4c0-.55-.45-1-1-1zM7 9c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2z\" /></g>\n<g id=\"done\"><path d=\"M9 16.2L4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4L9 16.2z\" /></g>\n<g id=\"done-all\"><path d=\"M18 7l-1.41-1.41-6.34 6.34 1.41 1.41L18 7zm4.24-1.41L11.66 16.17 7.48 12l-1.41 1.41L11.66 19l12-12-1.42-1.41zM.41 13.41L6 19l1.41-1.41L1.83 12 .41 13.41z\" /></g>\n<g id=\"donut-large\"><path d=\"M11 5.08V2c-5 .5-9 4.81-9 10s4 9.5 9 10v-3.08c-3-.48-6-3.4-6-6.92s3-6.44 6-6.92zM18.97 11H22c-.47-5-4-8.53-9-9v3.08C16 5.51 18.54 8 18.97 11zM13 18.92V22c5-.47 8.53-4 9-9h-3.03c-.43 3-2.97 5.49-5.97 5.92z\" /></g>\n<g id=\"donut-small\"><path d=\"M11 9.16V2c-5 .5-9 4.79-9 10s4 9.5 9 10v-7.16c-1-.41-2-1.52-2-2.84s1-2.43 2-2.84zM14.86 11H22c-.48-4.75-4-8.53-9-9v7.16c1 .3 1.52.98 1.86 1.84zM13 14.84V22c5-.47 8.52-4.25 9-9h-7.14c-.34.86-.86 1.54-1.86 1.84z\" /></g>\n<g id=\"drafts\"><path d=\"M21.99 8c0-.72-.37-1.35-.94-1.7L12 1 2.95 6.3C2.38 6.65 2 7.28 2 8v10c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2l-.01-10zM12 13L3.74 7.84 12 3l8.26 4.84L12 13z\" /></g>\n<g id=\"eject\"><path d=\"M5 17h14v2H5zm7-12L5.33 15h13.34z\" /></g>\n<g id=\"error\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z\" /></g>\n<g id=\"error-outline\"><path d=\"M11 15h2v2h-2zm0-8h2v6h-2zm.99-5C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z\" /></g>\n<g id=\"event\"><path d=\"M17 12h-5v5h5v-5zM16 1v2H8V1H6v2H5c-1.11 0-1.99.9-1.99 2L3 19c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2h-1V1h-2zm3 18H5V8h14v11z\" /></g>\n<g id=\"event-seat\"><path d=\"M4 18v3h3v-3h10v3h3v-6H4zm15-8h3v3h-3zM2 10h3v3H2zm15 3H7V5c0-1.1.9-2 2-2h6c1.1 0 2 .9 2 2v8z\" /></g>\n<g id=\"exit-to-app\"><path d=\"M10.09 15.59L11.5 17l5-5-5-5-1.41 1.41L12.67 11H3v2h9.67l-2.58 2.59zM19 3H5c-1.11 0-2 .9-2 2v4h2V5h14v14H5v-4H3v4c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z\" /></g>\n<g id=\"expand-less\"><path d=\"M12 8l-6 6 1.41 1.41L12 10.83l4.59 4.58L18 14z\" /></g>\n<g id=\"expand-more\"><path d=\"M16.59 8.59L12 13.17 7.41 8.59 6 10l6 6 6-6z\" /></g>\n<g id=\"explore\"><path d=\"M12 10.9c-.61 0-1.1.49-1.1 1.1s.49 1.1 1.1 1.1c.61 0 1.1-.49 1.1-1.1s-.49-1.1-1.1-1.1zM12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm2.19 12.19L6 18l3.81-8.19L18 6l-3.81 8.19z\" /></g>\n<g id=\"extension\"><path d=\"M20.5 11H19V7c0-1.1-.9-2-2-2h-4V3.5C13 2.12 11.88 1 10.5 1S8 2.12 8 3.5V5H4c-1.1 0-1.99.9-1.99 2v3.8H3.5c1.49 0 2.7 1.21 2.7 2.7s-1.21 2.7-2.7 2.7H2V20c0 1.1.9 2 2 2h3.8v-1.5c0-1.49 1.21-2.7 2.7-2.7 1.49 0 2.7 1.21 2.7 2.7V22H17c1.1 0 2-.9 2-2v-4h1.5c1.38 0 2.5-1.12 2.5-2.5S21.88 11 20.5 11z\" /></g>\n<g id=\"face\"><path d=\"M9 11.75c-.69 0-1.25.56-1.25 1.25s.56 1.25 1.25 1.25 1.25-.56 1.25-1.25-.56-1.25-1.25-1.25zm6 0c-.69 0-1.25.56-1.25 1.25s.56 1.25 1.25 1.25 1.25-.56 1.25-1.25-.56-1.25-1.25-1.25zM12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8 0-.29.02-.58.05-.86 2.36-1.05 4.23-2.98 5.21-5.37C11.07 8.33 14.05 10 17.42 10c.78 0 1.53-.09 2.25-.26.21.71.33 1.47.33 2.26 0 4.41-3.59 8-8 8z\" /></g>\n<g id=\"favorite\"><path d=\"M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z\" /></g>\n<g id=\"favorite-border\"><path d=\"M16.5 3c-1.74 0-3.41.81-4.5 2.09C10.91 3.81 9.24 3 7.5 3 4.42 3 2 5.42 2 8.5c0 3.78 3.4 6.86 8.55 11.54L12 21.35l1.45-1.32C18.6 15.36 22 12.28 22 8.5 22 5.42 19.58 3 16.5 3zm-4.4 15.55l-.1.1-.1-.1C7.14 14.24 4 11.39 4 8.5 4 6.5 5.5 5 7.5 5c1.54 0 3.04.99 3.57 2.36h1.87C13.46 5.99 14.96 5 16.5 5c2 0 3.5 1.5 3.5 3.5 0 2.89-3.14 5.74-7.9 10.05z\" /></g>\n<g id=\"feedback\"><path d=\"M20 2H4c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-7 12h-2v-2h2v2zm0-4h-2V6h2v4z\" /></g>\n<g id=\"file-download\"><path d=\"M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z\" /></g>\n<g id=\"file-upload\"><path d=\"M9 16h6v-6h4l-7-7-7 7h4zm-4 2h14v2H5z\" /></g>\n<g id=\"filter-list\"><path d=\"M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z\" /></g>\n<g id=\"find-in-page\"><path d=\"M20 19.59V8l-6-6H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c.45 0 .85-.15 1.19-.4l-4.43-4.43c-.8.52-1.74.83-2.76.83-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5c0 1.02-.31 1.96-.83 2.75L20 19.59zM9 13c0 1.66 1.34 3 3 3s3-1.34 3-3-1.34-3-3-3-3 1.34-3 3z\" /></g>\n<g id=\"find-replace\"><path d=\"M11 6c1.38 0 2.63.56 3.54 1.46L12 10h6V4l-2.05 2.05C14.68 4.78 12.93 4 11 4c-3.53 0-6.43 2.61-6.92 6H6.1c.46-2.28 2.48-4 4.9-4zm5.64 9.14c.66-.9 1.12-1.97 1.28-3.14H15.9c-.46 2.28-2.48 4-4.9 4-1.38 0-2.63-.56-3.54-1.46L10 12H4v6l2.05-2.05C7.32 17.22 9.07 18 11 18c1.55 0 2.98-.51 4.14-1.36L20 21.49 21.49 20l-4.85-4.86z\" /></g>\n<g id=\"fingerprint\"><path d=\"M17.81 4.47c-.08 0-.16-.02-.23-.06C15.66 3.42 14 3 12.01 3c-1.98 0-3.86.47-5.57 1.41-.24.13-.54.04-.68-.2-.13-.24-.04-.55.2-.68C7.82 2.52 9.86 2 12.01 2c2.13 0 3.99.47 6.03 1.52.25.13.34.43.21.67-.09.18-.26.28-.44.28zM3.5 9.72c-.1 0-.2-.03-.29-.09-.23-.16-.28-.47-.12-.7.99-1.4 2.25-2.5 3.75-3.27C9.98 4.04 14 4.03 17.15 5.65c1.5.77 2.76 1.86 3.75 3.25.16.22.11.54-.12.7-.23.16-.54.11-.7-.12-.9-1.26-2.04-2.25-3.39-2.94-2.87-1.47-6.54-1.47-9.4.01-1.36.7-2.5 1.7-3.4 2.96-.08.14-.23.21-.39.21zm6.25 12.07c-.13 0-.26-.05-.35-.15-.87-.87-1.34-1.43-2.01-2.64-.69-1.23-1.05-2.73-1.05-4.34 0-2.97 2.54-5.39 5.66-5.39s5.66 2.42 5.66 5.39c0 .28-.22.5-.5.5s-.5-.22-.5-.5c0-2.42-2.09-4.39-4.66-4.39-2.57 0-4.66 1.97-4.66 4.39 0 1.44.32 2.77.93 3.85.64 1.15 1.08 1.64 1.85 2.42.19.2.19.51 0 .71-.11.1-.24.15-.37.15zm7.17-1.85c-1.19 0-2.24-.3-3.1-.89-1.49-1.01-2.38-2.65-2.38-4.39 0-.28.22-.5.5-.5s.5.22.5.5c0 1.41.72 2.74 1.94 3.56.71.48 1.54.71 2.54.71.24 0 .64-.03 1.04-.1.27-.05.53.13.58.41.05.27-.13.53-.41.58-.57.11-1.07.12-1.21.12zM14.91 22c-.04 0-.09-.01-.13-.02-1.59-.44-2.63-1.03-3.72-2.1-1.4-1.39-2.17-3.24-2.17-5.22 0-1.62 1.38-2.94 3.08-2.94 1.7 0 3.08 1.32 3.08 2.94 0 1.07.93 1.94 2.08 1.94s2.08-.87 2.08-1.94c0-3.77-3.25-6.83-7.25-6.83-2.84 0-5.44 1.58-6.61 4.03-.39.81-.59 1.76-.59 2.8 0 .78.07 2.01.67 3.61.1.26-.03.55-.29.64-.26.1-.55-.04-.64-.29-.49-1.31-.73-2.61-.73-3.96 0-1.2.23-2.29.68-3.24 1.33-2.79 4.28-4.6 7.51-4.6 4.55 0 8.25 3.51 8.25 7.83 0 1.62-1.38 2.94-3.08 2.94s-3.08-1.32-3.08-2.94c0-1.07-.93-1.94-2.08-1.94s-2.08.87-2.08 1.94c0 1.71.66 3.31 1.87 4.51.95.94 1.86 1.46 3.27 1.85.27.07.42.35.35.61-.05.23-.26.38-.47.38z\" /></g>\n<g id=\"flag\"><path d=\"M14.4 6L14 4H5v17h2v-7h5.6l.4 2h7V6z\" /></g>\n<g id=\"flight-land\"><path d=\"M2.5 19h19v2h-19zm7.18-5.73l4.35 1.16 5.31 1.42c.8.21 1.62-.26 1.84-1.06.21-.8-.26-1.62-1.06-1.84l-5.31-1.42-2.76-9.02L10.12 2v8.28L5.15 8.95l-.93-2.32-1.45-.39v5.17l1.6.43 5.31 1.43z\" /></g>\n<g id=\"flight-takeoff\"><path d=\"M2.5 19h19v2h-19zm19.57-9.36c-.21-.8-1.04-1.28-1.84-1.06L14.92 10l-6.9-6.43-1.93.51 4.14 7.17-4.97 1.33-1.97-1.54-1.45.39 1.82 3.16.77 1.33 1.6-.43 5.31-1.42 4.35-1.16L21 11.49c.81-.23 1.28-1.05 1.07-1.85z\" /></g>\n<g id=\"flip-to-back\"><path d=\"M9 7H7v2h2V7zm0 4H7v2h2v-2zm0-8c-1.11 0-2 .9-2 2h2V3zm4 12h-2v2h2v-2zm6-12v2h2c0-1.1-.9-2-2-2zm-6 0h-2v2h2V3zM9 17v-2H7c0 1.1.89 2 2 2zm10-4h2v-2h-2v2zm0-4h2V7h-2v2zm0 8c1.1 0 2-.9 2-2h-2v2zM5 7H3v12c0 1.1.89 2 2 2h12v-2H5V7zm10-2h2V3h-2v2zm0 12h2v-2h-2v2z\" /></g>\n<g id=\"flip-to-front\"><path d=\"M3 13h2v-2H3v2zm0 4h2v-2H3v2zm2 4v-2H3c0 1.1.89 2 2 2zM3 9h2V7H3v2zm12 12h2v-2h-2v2zm4-18H9c-1.11 0-2 .9-2 2v10c0 1.1.89 2 2 2h10c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 12H9V5h10v10zm-8 6h2v-2h-2v2zm-4 0h2v-2H7v2z\" /></g>\n<g id=\"folder\"><path d=\"M10 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2h-8l-2-2z\" /></g>\n<g id=\"folder-open\"><path d=\"M20 6h-8l-2-2H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2zm0 12H4V8h16v10z\" /></g>\n<g id=\"folder-shared\"><path d=\"M20 6h-8l-2-2H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2zm-5 3c1.1 0 2 .9 2 2s-.9 2-2 2-2-.9-2-2 .9-2 2-2zm4 8h-8v-1c0-1.33 2.67-2 4-2s4 .67 4 2v1z\" /></g>\n<g id=\"font-download\"><path d=\"M9.93 13.5h4.14L12 7.98zM20 2H4c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-4.05 16.5l-1.14-3H9.17l-1.12 3H5.96l5.11-13h1.86l5.11 13h-2.09z\" /></g>\n<g id=\"forward\"><path d=\"M12 8V4l8 8-8 8v-4H4V8z\" /></g>\n<g id=\"fullscreen\"><path d=\"M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z\" /></g>\n<g id=\"fullscreen-exit\"><path d=\"M5 16h3v3h2v-5H5v2zm3-8H5v2h5V5H8v3zm6 11h2v-3h3v-2h-5v5zm2-11V5h-2v5h5V8h-3z\" /></g>\n<g id=\"gavel\"><path d=\"M1 21h12v2H1zM5.245 8.07l2.83-2.827 14.14 14.142-2.828 2.828zM12.317 1l5.657 5.656-2.83 2.83-5.654-5.66zM3.825 9.485l5.657 5.657-2.828 2.828-5.657-5.657z\" /></g>\n<g id=\"gesture\"><path d=\"M4.59 6.89c.7-.71 1.4-1.35 1.71-1.22.5.2 0 1.03-.3 1.52-.25.42-2.86 3.89-2.86 6.31 0 1.28.48 2.34 1.34 2.98.75.56 1.74.73 2.64.46 1.07-.31 1.95-1.4 3.06-2.77 1.21-1.49 2.83-3.44 4.08-3.44 1.63 0 1.65 1.01 1.76 1.79-3.78.64-5.38 3.67-5.38 5.37 0 1.7 1.44 3.09 3.21 3.09 1.63 0 4.29-1.33 4.69-6.1H21v-2.5h-2.47c-.15-1.65-1.09-4.2-4.03-4.2-2.25 0-4.18 1.91-4.94 2.84-.58.73-2.06 2.48-2.29 2.72-.25.3-.68.84-1.11.84-.45 0-.72-.83-.36-1.92.35-1.09 1.4-2.86 1.85-3.52.78-1.14 1.3-1.92 1.3-3.28C8.95 3.69 7.31 3 6.44 3 5.12 3 3.97 4 3.72 4.25c-.36.36-.66.66-.88.93l1.75 1.71zm9.29 11.66c-.31 0-.74-.26-.74-.72 0-.6.73-2.2 2.87-2.76-.3 2.69-1.43 3.48-2.13 3.48z\" /></g>\n<g id=\"get-app\"><path d=\"M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z\" /></g>\n<g id=\"gif\"><path d=\"M11.5 9H13v6h-1.5zM9 9H6c-.6 0-1 .5-1 1v4c0 .5.4 1 1 1h3c.6 0 1-.5 1-1v-2H8.5v1.5h-2v-3H10V10c0-.5-.4-1-1-1zm10 1.5V9h-4.5v6H16v-2h2v-1.5h-2v-1z\" /></g>\n<g id=\"grade\"><path d=\"M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z\" /></g>\n<g id=\"group-work\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zM8 17.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5zM9.5 8c0-1.38 1.12-2.5 2.5-2.5s2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5S9.5 9.38 9.5 8zm6.5 9.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z\" /></g>\n<g id=\"help\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 17h-2v-2h2v2zm2.07-7.75l-.9.92C13.45 12.9 13 13.5 13 15h-2v-.5c0-1.1.45-2.1 1.17-2.83l1.24-1.26c.37-.36.59-.86.59-1.41 0-1.1-.9-2-2-2s-2 .9-2 2H8c0-2.21 1.79-4 4-4s4 1.79 4 4c0 .88-.36 1.68-.93 2.25z\" /></g>\n<g id=\"help-outline\"><path d=\"M11 18h2v-2h-2v2zm1-16C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm0-14c-2.21 0-4 1.79-4 4h2c0-1.1.9-2 2-2s2 .9 2 2c0 2-3 1.75-3 5h2c0-2.25 3-2.5 3-5 0-2.21-1.79-4-4-4z\" /></g>\n<g id=\"highlight-off\"><path d=\"M14.59 8L12 10.59 9.41 8 8 9.41 10.59 12 8 14.59 9.41 16 12 13.41 14.59 16 16 14.59 13.41 12 16 9.41 14.59 8zM12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z\" /></g>\n<g id=\"history\"><path d=\"M13 3c-4.97 0-9 4.03-9 9H1l3.89 3.89.07.14L9 12H6c0-3.87 3.13-7 7-7s7 3.13 7 7-3.13 7-7 7c-1.93 0-3.68-.79-4.94-2.06l-1.42 1.42C8.27 19.99 10.51 21 13 21c4.97 0 9-4.03 9-9s-4.03-9-9-9zm-1 5v5l4.28 2.54.72-1.21-3.5-2.08V8H12z\" /></g>\n<g id=\"home\"><path d=\"M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z\" /></g>\n<g id=\"hourglass-empty\"><path d=\"M6 2v6h.01L6 8.01 10 12l-4 4 .01.01H6V22h12v-5.99h-.01L18 16l-4-4 4-3.99-.01-.01H18V2H6zm10 14.5V20H8v-3.5l4-4 4 4zm-4-5l-4-4V4h8v3.5l-4 4z\" /></g>\n<g id=\"hourglass-full\"><path d=\"M6 2v6h.01L6 8.01 10 12l-4 4 .01.01H6V22h12v-5.99h-.01L18 16l-4-4 4-3.99-.01-.01H18V2H6z\" /></g>\n<g id=\"http\"><path d=\"M4.5 11h-2V9H1v6h1.5v-2.5h2V15H6V9H4.5v2zm2.5-.5h1.5V15H10v-4.5h1.5V9H7v1.5zm5.5 0H14V15h1.5v-4.5H17V9h-4.5v1.5zm9-1.5H18v6h1.5v-2h2c.8 0 1.5-.7 1.5-1.5v-1c0-.8-.7-1.5-1.5-1.5zm0 2.5h-2v-1h2v1z\" /></g>\n<g id=\"https\"><path d=\"M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zm-6 9c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zm3.1-9H8.9V6c0-1.71 1.39-3.1 3.1-3.1 1.71 0 3.1 1.39 3.1 3.1v2z\" /></g>\n<g id=\"important-devices\"><path d=\"M23 11.01L18 11c-.55 0-1 .45-1 1v9c0 .55.45 1 1 1h5c.55 0 1-.45 1-1v-9c0-.55-.45-.99-1-.99zM23 20h-5v-7h5v7zM20 2H2C.89 2 0 2.89 0 4v12c0 1.1.89 2 2 2h7v2H7v2h8v-2h-2v-2h2v-2H2V4h18v5h2V4c0-1.11-.9-2-2-2zm-8.03 7L11 6l-.97 3H7l2.47 1.76-.94 2.91 2.47-1.8 2.47 1.8-.94-2.91L15 9h-3.03z\" /></g>\n<g id=\"inbox\"><path d=\"M19 3H4.99c-1.11 0-1.98.89-1.98 2L3 19c0 1.1.88 2 1.99 2H19c1.1 0 2-.9 2-2V5c0-1.11-.9-2-2-2zm0 12h-4c0 1.66-1.35 3-3 3s-3-1.34-3-3H4.99V5H19v10z\" /></g>\n<g id=\"indeterminate-check-box\"><path d=\"M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-2 10H7v-2h10v2z\" /></g>\n<g id=\"info\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z\" /></g>\n<g id=\"info-outline\"><path d=\"M11 17h2v-6h-2v6zm1-15C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zM11 9h2V7h-2v2z\" /></g>\n<g id=\"input\"><path d=\"M21 3.01H3c-1.1 0-2 .9-2 2V9h2V4.99h18v14.03H3V15H1v4.01c0 1.1.9 1.98 2 1.98h18c1.1 0 2-.88 2-1.98v-14c0-1.11-.9-2-2-2zM11 16l4-4-4-4v3H1v2h10v3z\" /></g>\n<g id=\"invert-colors\"><path d=\"M17.66 7.93L12 2.27 6.34 7.93c-3.12 3.12-3.12 8.19 0 11.31C7.9 20.8 9.95 21.58 12 21.58c2.05 0 4.1-.78 5.66-2.34 3.12-3.12 3.12-8.19 0-11.31zM12 19.59c-1.6 0-3.11-.62-4.24-1.76C6.62 16.69 6 15.19 6 13.59s.62-3.11 1.76-4.24L12 5.1v14.49z\" /></g>\n<g id=\"label\"><path d=\"M17.63 5.84C17.27 5.33 16.67 5 16 5L5 5.01C3.9 5.01 3 5.9 3 7v10c0 1.1.9 1.99 2 1.99L16 19c.67 0 1.27-.33 1.63-.84L22 12l-4.37-6.16z\" /></g>\n<g id=\"label-outline\"><path d=\"M17.63 5.84C17.27 5.33 16.67 5 16 5L5 5.01C3.9 5.01 3 5.9 3 7v10c0 1.1.9 1.99 2 1.99L16 19c.67 0 1.27-.33 1.63-.84L22 12l-4.37-6.16zM16 17H5V7h11l3.55 5L16 17z\" /></g>\n<g id=\"language\"><path d=\"M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zm6.93 6h-2.95c-.32-1.25-.78-2.45-1.38-3.56 1.84.63 3.37 1.91 4.33 3.56zM12 4.04c.83 1.2 1.48 2.53 1.91 3.96h-3.82c.43-1.43 1.08-2.76 1.91-3.96zM4.26 14C4.1 13.36 4 12.69 4 12s.1-1.36.26-2h3.38c-.08.66-.14 1.32-.14 2 0 .68.06 1.34.14 2H4.26zm.82 2h2.95c.32 1.25.78 2.45 1.38 3.56-1.84-.63-3.37-1.9-4.33-3.56zm2.95-8H5.08c.96-1.66 2.49-2.93 4.33-3.56C8.81 5.55 8.35 6.75 8.03 8zM12 19.96c-.83-1.2-1.48-2.53-1.91-3.96h3.82c-.43 1.43-1.08 2.76-1.91 3.96zM14.34 14H9.66c-.09-.66-.16-1.32-.16-2 0-.68.07-1.35.16-2h4.68c.09.65.16 1.32.16 2 0 .68-.07 1.34-.16 2zm.25 5.56c.6-1.11 1.06-2.31 1.38-3.56h2.95c-.96 1.65-2.49 2.93-4.33 3.56zM16.36 14c.08-.66.14-1.32.14-2 0-.68-.06-1.34-.14-2h3.38c.16.64.26 1.31.26 2s-.1 1.36-.26 2h-3.38z\" /></g>\n<g id=\"launch\"><path d=\"M19 19H5V5h7V3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2v-7h-2v7zM14 3v2h3.59l-9.83 9.83 1.41 1.41L19 6.41V10h2V3h-7z\" /></g>\n<g id=\"lightbulb-outline\"><path d=\"M9 21c0 .55.45 1 1 1h4c.55 0 1-.45 1-1v-1H9v1zm3-19C8.14 2 5 5.14 5 9c0 2.38 1.19 4.47 3 5.74V17c0 .55.45 1 1 1h6c.55 0 1-.45 1-1v-2.26c1.81-1.27 3-3.36 3-5.74 0-3.86-3.14-7-7-7zm2.85 11.1l-.85.6V16h-4v-2.3l-.85-.6C7.8 12.16 7 10.63 7 9c0-2.76 2.24-5 5-5s5 2.24 5 5c0 1.63-.8 3.16-2.15 4.1z\" /></g>\n<g id=\"line-style\"><path d=\"M3 16h5v-2H3v2zm6.5 0h5v-2h-5v2zm6.5 0h5v-2h-5v2zM3 20h2v-2H3v2zm4 0h2v-2H7v2zm4 0h2v-2h-2v2zm4 0h2v-2h-2v2zm4 0h2v-2h-2v2zM3 12h8v-2H3v2zm10 0h8v-2h-8v2zM3 4v4h18V4H3z\" /></g>\n<g id=\"line-weight\"><path d=\"M3 17h18v-2H3v2zm0 3h18v-1H3v1zm0-7h18v-3H3v3zm0-9v4h18V4H3z\" /></g>\n<g id=\"link\"><path d=\"M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z\" /></g>\n<g id=\"list\"><path d=\"M3 13h2v-2H3v2zm0 4h2v-2H3v2zm0-8h2V7H3v2zm4 4h14v-2H7v2zm0 4h14v-2H7v2zM7 7v2h14V7H7z\" /></g>\n<g id=\"lock\"><path d=\"M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zm-6 9c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zm3.1-9H8.9V6c0-1.71 1.39-3.1 3.1-3.1 1.71 0 3.1 1.39 3.1 3.1v2z\" /></g>\n<g id=\"lock-open\"><path d=\"M12 17c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm6-9h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6h1.9c0-1.71 1.39-3.1 3.1-3.1 1.71 0 3.1 1.39 3.1 3.1v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zm0 12H6V10h12v10z\" /></g>\n<g id=\"lock-outline\"><path d=\"M12 17c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm6-9h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zM8.9 6c0-1.71 1.39-3.1 3.1-3.1s3.1 1.39 3.1 3.1v2H8.9V6zM18 20H6V10h12v10z\" /></g>\n<g id=\"loyalty\"><path d=\"M21.41 11.58l-9-9C12.05 2.22 11.55 2 11 2H4c-1.1 0-2 .9-2 2v7c0 .55.22 1.05.59 1.42l9 9c.36.36.86.58 1.41.58.55 0 1.05-.22 1.41-.59l7-7c.37-.36.59-.86.59-1.41 0-.55-.23-1.06-.59-1.42zM5.5 7C4.67 7 4 6.33 4 5.5S4.67 4 5.5 4 7 4.67 7 5.5 6.33 7 5.5 7zm11.77 8.27L13 19.54l-4.27-4.27C8.28 14.81 8 14.19 8 13.5c0-1.38 1.12-2.5 2.5-2.5.69 0 1.32.28 1.77.74l.73.72.73-.73c.45-.45 1.08-.73 1.77-.73 1.38 0 2.5 1.12 2.5 2.5 0 .69-.28 1.32-.73 1.77z\" /></g>\n<g id=\"mail\"><path d=\"M20 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 4l-8 5-8-5V6l8 5 8-5v2z\" /></g>\n<g id=\"markunread\"><path d=\"M20 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 4l-8 5-8-5V6l8 5 8-5v2z\" /></g>\n<g id=\"markunread-mailbox\"><path d=\"M20 6H10v6H8V4h6V0H6v6H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2z\" /></g>\n<g id=\"menu\"><path d=\"M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z\" /></g>\n<g id=\"more-horiz\"><path d=\"M6 10c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm12 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm-6 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z\" /></g>\n<g id=\"more-vert\"><path d=\"M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z\" /></g>\n<g id=\"motorcycle\"><path d=\"M19.44 9.03L15.41 5H11v2h3.59l2 2H5c-2.8 0-5 2.2-5 5s2.2 5 5 5c2.46 0 4.45-1.69 4.9-4h1.65l2.77-2.77c-.21.54-.32 1.14-.32 1.77 0 2.8 2.2 5 5 5s5-2.2 5-5c0-2.65-1.97-4.77-4.56-4.97zM7.82 15C7.4 16.15 6.28 17 5 17c-1.63 0-3-1.37-3-3s1.37-3 3-3c1.28 0 2.4.85 2.82 2H5v2h2.82zM19 17c-1.66 0-3-1.34-3-3s1.34-3 3-3 3 1.34 3 3-1.34 3-3 3z\" /></g>\n<g id=\"move-to-inbox\"><path d=\"M19 3H4.99c-1.11 0-1.98.9-1.98 2L3 19c0 1.1.88 2 1.99 2H19c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 12h-4c0 1.66-1.35 3-3 3s-3-1.34-3-3H4.99V5H19v10zm-3-5h-2V7h-4v3H8l4 4 4-4z\" /></g>\n<g id=\"next-week\"><path d=\"M20 7h-4V5c0-.55-.22-1.05-.59-1.41C15.05 3.22 14.55 3 14 3h-4c-1.1 0-2 .9-2 2v2H4c-1.1 0-2 .9-2 2v11c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V9c0-1.1-.9-2-2-2zM10 5h4v2h-4V5zm1 13.5l-1-1 3-3-3-3 1-1 4 4-4 4z\" /></g>\n<g id=\"note-add\"><path d=\"M14 2H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6zm2 14h-3v3h-2v-3H8v-2h3v-3h2v3h3v2zm-3-7V3.5L18.5 9H13z\" /></g>\n<g id=\"offline-pin\"><path d=\"M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10 10-4.5 10-10S17.5 2 12 2zm5 16H7v-2h10v2zm-6.7-4L7 10.7l1.4-1.4 1.9 1.9 5.3-5.3L17 7.3 10.3 14z\" /></g>\n<g id=\"opacity\"><path d=\"M17.66 8L12 2.35 6.34 8C4.78 9.56 4 11.64 4 13.64s.78 4.11 2.34 5.67 3.61 2.35 5.66 2.35 4.1-.79 5.66-2.35S20 15.64 20 13.64 19.22 9.56 17.66 8zM6 14c.01-2 .62-3.27 1.76-4.4L12 5.27l4.24 4.38C17.38 10.77 17.99 12 18 14H6z\" /></g>\n<g id=\"open-in-browser\"><path d=\"M19 4H5c-1.11 0-2 .9-2 2v12c0 1.1.89 2 2 2h4v-2H5V8h14v10h-4v2h4c1.1 0 2-.9 2-2V6c0-1.1-.89-2-2-2zm-7 6l-4 4h3v6h2v-6h3l-4-4z\" /></g>\n<g id=\"open-in-new\"><path d=\"M19 19H5V5h7V3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2v-7h-2v7zM14 3v2h3.59l-9.83 9.83 1.41 1.41L19 6.41V10h2V3h-7z\" /></g>\n<g id=\"open-with\"><path d=\"M10 9h4V6h3l-5-5-5 5h3v3zm-1 1H6V7l-5 5 5 5v-3h3v-4zm14 2l-5-5v3h-3v4h3v3l5-5zm-9 3h-4v3H7l5 5 5-5h-3v-3z\" /></g>\n<g id=\"pageview\"><path d=\"M11.5 9C10.12 9 9 10.12 9 11.5s1.12 2.5 2.5 2.5 2.5-1.12 2.5-2.5S12.88 9 11.5 9zM20 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm-3.21 14.21l-2.91-2.91c-.69.44-1.51.7-2.39.7C9.01 16 7 13.99 7 11.5S9.01 7 11.5 7 16 9.01 16 11.5c0 .88-.26 1.69-.7 2.39l2.91 2.9-1.42 1.42z\" /></g>\n<g id=\"pan-tool\"><path d=\"M23 5.5V20c0 2.2-1.8 4-4 4h-7.3c-1.08 0-2.1-.43-2.85-1.19L1 14.83s1.26-1.23 1.3-1.25c.22-.19.49-.29.79-.29.22 0 .42.06.6.16.04.01 4.31 2.46 4.31 2.46V4c0-.83.67-1.5 1.5-1.5S11 3.17 11 4v7h1V1.5c0-.83.67-1.5 1.5-1.5S15 .67 15 1.5V11h1V2.5c0-.83.67-1.5 1.5-1.5s1.5.67 1.5 1.5V11h1V5.5c0-.83.67-1.5 1.5-1.5s1.5.67 1.5 1.5z\" /></g>\n<g id=\"payment\"><path d=\"M20 4H4c-1.11 0-1.99.89-1.99 2L2 18c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V6c0-1.11-.89-2-2-2zm0 14H4v-6h16v6zm0-10H4V6h16v2z\" /></g>\n<g id=\"perm-camera-mic\"><path d=\"M20 5h-3.17L15 3H9L7.17 5H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h7v-2.09c-2.83-.48-5-2.94-5-5.91h2c0 2.21 1.79 4 4 4s4-1.79 4-4h2c0 2.97-2.17 5.43-5 5.91V21h7c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm-6 8c0 1.1-.9 2-2 2s-2-.9-2-2V9c0-1.1.9-2 2-2s2 .9 2 2v4z\" /></g>\n<g id=\"perm-contact-calendar\"><path d=\"M19 3h-1V1h-2v2H8V1H6v2H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-7 3c1.66 0 3 1.34 3 3s-1.34 3-3 3-3-1.34-3-3 1.34-3 3-3zm6 12H6v-1c0-2 4-3.1 6-3.1s6 1.1 6 3.1v1z\" /></g>\n<g id=\"perm-data-setting\"><path d=\"M18.99 11.5c.34 0 .67.03 1 .07L20 0 0 20h11.56c-.04-.33-.07-.66-.07-1 0-4.14 3.36-7.5 7.5-7.5zm3.71 7.99c.02-.16.04-.32.04-.49 0-.17-.01-.33-.04-.49l1.06-.83c.09-.08.12-.21.06-.32l-1-1.73c-.06-.11-.19-.15-.31-.11l-1.24.5c-.26-.2-.54-.37-.85-.49l-.19-1.32c-.01-.12-.12-.21-.24-.21h-2c-.12 0-.23.09-.25.21l-.19 1.32c-.3.13-.59.29-.85.49l-1.24-.5c-.11-.04-.24 0-.31.11l-1 1.73c-.06.11-.04.24.06.32l1.06.83c-.02.16-.03.32-.03.49 0 .17.01.33.03.49l-1.06.83c-.09.08-.12.21-.06.32l1 1.73c.06.11.19.15.31.11l1.24-.5c.26.2.54.37.85.49l.19 1.32c.02.12.12.21.25.21h2c.12 0 .23-.09.25-.21l.19-1.32c.3-.13.59-.29.84-.49l1.25.5c.11.04.24 0 .31-.11l1-1.73c.06-.11.03-.24-.06-.32l-1.07-.83zm-3.71 1.01c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5z\" /></g>\n<g id=\"perm-device-information\"><path d=\"M13 7h-2v2h2V7zm0 4h-2v6h2v-6zm4-9.99L7 1c-1.1 0-2 .9-2 2v18c0 1.1.9 2 2 2h10c1.1 0 2-.9 2-2V3c0-1.1-.9-1.99-2-1.99zM17 19H7V5h10v14z\" /></g>\n<g id=\"perm-identity\"><path d=\"M12 5.9c1.16 0 2.1.94 2.1 2.1s-.94 2.1-2.1 2.1S9.9 9.16 9.9 8s.94-2.1 2.1-2.1m0 9c2.97 0 6.1 1.46 6.1 2.1v1.1H5.9V17c0-.64 3.13-2.1 6.1-2.1M12 4C9.79 4 8 5.79 8 8s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4zm0 9c-2.67 0-8 1.34-8 4v3h16v-3c0-2.66-5.33-4-8-4z\" /></g>\n<g id=\"perm-media\"><path d=\"M2 6H0v5h.01L0 20c0 1.1.9 2 2 2h18v-2H2V6zm20-2h-8l-2-2H6c-1.1 0-1.99.9-1.99 2L4 16c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zM7 15l4.5-6 3.5 4.51 2.5-3.01L21 15H7z\" /></g>\n<g id=\"perm-phone-msg\"><path d=\"M20 15.5c-1.25 0-2.45-.2-3.57-.57-.35-.11-.74-.03-1.02.24l-2.2 2.2c-2.83-1.44-5.15-3.75-6.59-6.58l2.2-2.21c.28-.27.36-.66.25-1.01C8.7 6.45 8.5 5.25 8.5 4c0-.55-.45-1-1-1H4c-.55 0-1 .45-1 1 0 9.39 7.61 17 17 17 .55 0 1-.45 1-1v-3.5c0-.55-.45-1-1-1zM12 3v10l3-3h6V3h-9z\" /></g>\n<g id=\"perm-scan-wifi\"><path d=\"M12 3C6.95 3 3.15 4.85 0 7.23L12 22 24 7.25C20.85 4.87 17.05 3 12 3zm1 13h-2v-6h2v6zm-2-8V6h2v2h-2z\" /></g>\n<g id=\"pets\"><circle cx=\"4.5\" cy=\"9.5\" r=\"2.5\" /><circle cx=\"9\" cy=\"5.5\" r=\"2.5\" /><circle cx=\"15\" cy=\"5.5\" r=\"2.5\" /><circle cx=\"19.5\" cy=\"9.5\" r=\"2.5\" /><path d=\"M17.34 14.86c-.87-1.02-1.6-1.89-2.48-2.91-.46-.54-1.05-1.08-1.75-1.32-.11-.04-.22-.07-.33-.09-.25-.04-.52-.04-.78-.04s-.53 0-.79.05c-.11.02-.22.05-.33.09-.7.24-1.28.78-1.75 1.32-.87 1.02-1.6 1.89-2.48 2.91-1.31 1.31-2.92 2.76-2.62 4.79.29 1.02 1.02 2.03 2.33 2.32.73.15 3.06-.44 5.54-.44h.18c2.48 0 4.81.58 5.54.44 1.31-.29 2.04-1.31 2.33-2.32.31-2.04-1.3-3.49-2.61-4.8z\" /></g>\n<g id=\"picture-in-picture\"><path d=\"M19 7h-8v6h8V7zm2-4H3c-1.1 0-2 .9-2 2v14c0 1.1.9 1.98 2 1.98h18c1.1 0 2-.88 2-1.98V5c0-1.1-.9-2-2-2zm0 16.01H3V4.98h18v14.03z\" /></g>\n<g id=\"picture-in-picture-alt\"><path d=\"M19 11h-8v6h8v-6zm4 8V4.98C23 3.88 22.1 3 21 3H3c-1.1 0-2 .88-2 1.98V19c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2zm-2 .02H3V4.97h18v14.05z\" /></g>\n<g id=\"play-for-work\"><path d=\"M11 5v5.59H7.5l4.5 4.5 4.5-4.5H13V5h-2zm-5 9c0 3.31 2.69 6 6 6s6-2.69 6-6h-2c0 2.21-1.79 4-4 4s-4-1.79-4-4H6z\" /></g>\n<g id=\"polymer\"><path d=\"M19 4h-4L7.11 16.63 4.5 12 9 4H5L.5 12 5 20h4l7.89-12.63L19.5 12 15 20h4l4.5-8z\" /></g>\n<g id=\"power-settings-new\"><path d=\"M13 3h-2v10h2V3zm4.83 2.17l-1.42 1.42C17.99 7.86 19 9.81 19 12c0 3.87-3.13 7-7 7s-7-3.13-7-7c0-2.19 1.01-4.14 2.58-5.42L6.17 5.17C4.23 6.82 3 9.26 3 12c0 4.97 4.03 9 9 9s9-4.03 9-9c0-2.74-1.23-5.18-3.17-6.83z\" /></g>\n<g id=\"pregnant-woman\"><path d=\"M9 4c0-1.11.89-2 2-2s2 .89 2 2-.89 2-2 2-2-.89-2-2zm7 9c-.01-1.34-.83-2.51-2-3 0-1.66-1.34-3-3-3s-3 1.34-3 3v7h2v5h3v-5h3v-4z\" /></g>\n<g id=\"print\"><path d=\"M19 8H5c-1.66 0-3 1.34-3 3v6h4v4h12v-4h4v-6c0-1.66-1.34-3-3-3zm-3 11H8v-5h8v5zm3-7c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm-1-9H6v4h12V3z\" /></g>\n<g id=\"query-builder\"><path d=\"M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zm.5-13H11v6l5.25 3.15.75-1.23-4.5-2.67z\" /></g>\n<g id=\"question-answer\"><path d=\"M21 6h-2v9H6v2c0 .55.45 1 1 1h11l4 4V7c0-.55-.45-1-1-1zm-4 6V3c0-.55-.45-1-1-1H3c-.55 0-1 .45-1 1v14l4-4h10c.55 0 1-.45 1-1z\" /></g>\n<g id=\"radio-button-checked\"><path d=\"M12 7c-2.76 0-5 2.24-5 5s2.24 5 5 5 5-2.24 5-5-2.24-5-5-5zm0-5C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z\" /></g>\n<g id=\"radio-button-unchecked\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z\" /></g>\n<g id=\"receipt\"><path d=\"M18 17H6v-2h12v2zm0-4H6v-2h12v2zm0-4H6V7h12v2zM3 22l1.5-1.5L6 22l1.5-1.5L9 22l1.5-1.5L12 22l1.5-1.5L15 22l1.5-1.5L18 22l1.5-1.5L21 22V2l-1.5 1.5L18 2l-1.5 1.5L15 2l-1.5 1.5L12 2l-1.5 1.5L9 2 7.5 3.5 6 2 4.5 3.5 3 2v20z\" /></g>\n<g id=\"record-voice-over\"><circle cx=\"9\" cy=\"9\" r=\"4\" /><path d=\"M9 15c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4zm7.76-9.64l-1.68 1.69c.84 1.18.84 2.71 0 3.89l1.68 1.69c2.02-2.02 2.02-5.07 0-7.27zM20.07 2l-1.63 1.63c2.77 3.02 2.77 7.56 0 10.74L20.07 16c3.9-3.89 3.91-9.95 0-14z\" /></g>\n<g id=\"redeem\"><path d=\"M20 6h-2.18c.11-.31.18-.65.18-1 0-1.66-1.34-3-3-3-1.05 0-1.96.54-2.5 1.35l-.5.67-.5-.68C10.96 2.54 10.05 2 9 2 7.34 2 6 3.34 6 5c0 .35.07.69.18 1H4c-1.11 0-1.99.89-1.99 2L2 19c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V8c0-1.11-.89-2-2-2zm-5-2c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zM9 4c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm11 15H4v-2h16v2zm0-5H4V8h5.08L7 10.83 8.62 12 11 8.76l1-1.36 1 1.36L15.38 12 17 10.83 14.92 8H20v6z\" /></g>\n<g id=\"redo\"><path d=\"M18.4 10.6C16.55 8.99 14.15 8 11.5 8c-4.65 0-8.58 3.03-9.96 7.22L3.9 16c1.05-3.19 4.05-5.5 7.6-5.5 1.95 0 3.73.72 5.12 1.88L13 16h9V7l-3.6 3.6z\" /></g>\n<g id=\"refresh\"><path d=\"M17.65 6.35C16.2 4.9 14.21 4 12 4c-4.42 0-7.99 3.58-7.99 8s3.57 8 7.99 8c3.73 0 6.84-2.55 7.73-6h-2.08c-.82 2.33-3.04 4-5.65 4-3.31 0-6-2.69-6-6s2.69-6 6-6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z\" /></g>\n<g id=\"remove\"><path d=\"M19 13H5v-2h14v2z\" /></g>\n<g id=\"remove-circle\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm5 11H7v-2h10v2z\" /></g>\n<g id=\"remove-circle-outline\"><path d=\"M7 11v2h10v-2H7zm5-9C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z\" /></g>\n<g id=\"reorder\"><path d=\"M3 15h18v-2H3v2zm0 4h18v-2H3v2zm0-8h18V9H3v2zm0-6v2h18V5H3z\" /></g>\n<g id=\"reply\"><path d=\"M10 9V5l-7 7 7 7v-4.1c5 0 8.5 1.6 11 5.1-1-5-4-10-11-11z\" /></g>\n<g id=\"reply-all\"><path d=\"M7 8V5l-7 7 7 7v-3l-4-4 4-4zm6 1V5l-7 7 7 7v-4.1c5 0 8.5 1.6 11 5.1-1-5-4-10-11-11z\" /></g>\n<g id=\"report\"><path d=\"M15.73 3H8.27L3 8.27v7.46L8.27 21h7.46L21 15.73V8.27L15.73 3zM12 17.3c-.72 0-1.3-.58-1.3-1.3 0-.72.58-1.3 1.3-1.3.72 0 1.3.58 1.3 1.3 0 .72-.58 1.3-1.3 1.3zm1-4.3h-2V7h2v6z\" /></g>\n<g id=\"report-problem\"><path d=\"M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z\" /></g>\n<g id=\"restore\"><path d=\"M13 3c-4.97 0-9 4.03-9 9H1l3.89 3.89.07.14L9 12H6c0-3.87 3.13-7 7-7s7 3.13 7 7-3.13 7-7 7c-1.93 0-3.68-.79-4.94-2.06l-1.42 1.42C8.27 19.99 10.51 21 13 21c4.97 0 9-4.03 9-9s-4.03-9-9-9zm-1 5v5l4.28 2.54.72-1.21-3.5-2.08V8H12z\" /></g>\n<g id=\"room\"><path d=\"M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z\" /></g>\n<g id=\"rounded-corner\"><path d=\"M19 19h2v2h-2v-2zm0-2h2v-2h-2v2zM3 13h2v-2H3v2zm0 4h2v-2H3v2zm0-8h2V7H3v2zm0-4h2V3H3v2zm4 0h2V3H7v2zm8 16h2v-2h-2v2zm-4 0h2v-2h-2v2zm4 0h2v-2h-2v2zm-8 0h2v-2H7v2zm-4 0h2v-2H3v2zM21 8c0-2.76-2.24-5-5-5h-5v2h5c1.65 0 3 1.35 3 3v5h2V8z\" /></g>\n<g id=\"rowing\"><path d=\"M8.5 14.5L4 19l1.5 1.5L9 17h2l-2.5-2.5zM15 1c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm6 20.01L18 24l-2.99-3.01V19.5l-7.1-7.09c-.31.05-.61.07-.91.07v-2.16c1.66.03 3.61-.87 4.67-2.04l1.4-1.55c.19-.21.43-.38.69-.5.29-.14.62-.23.96-.23h.03C15.99 6.01 17 7.02 17 8.26v5.75c0 .84-.35 1.61-.92 2.16l-3.58-3.58v-2.27c-.63.52-1.43 1.02-2.29 1.39L16.5 18H18l3 3.01z\" /></g>\n<g id=\"save\"><path d=\"M17 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V7l-4-4zm-5 16c-1.66 0-3-1.34-3-3s1.34-3 3-3 3 1.34 3 3-1.34 3-3 3zm3-10H5V5h10v4z\" /></g>\n<g id=\"schedule\"><path d=\"M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zm.5-13H11v6l5.25 3.15.75-1.23-4.5-2.67z\" /></g>\n<g id=\"search\"><path d=\"M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z\" /></g>\n<g id=\"select-all\"><path d=\"M3 5h2V3c-1.1 0-2 .9-2 2zm0 8h2v-2H3v2zm4 8h2v-2H7v2zM3 9h2V7H3v2zm10-6h-2v2h2V3zm6 0v2h2c0-1.1-.9-2-2-2zM5 21v-2H3c0 1.1.9 2 2 2zm-2-4h2v-2H3v2zM9 3H7v2h2V3zm2 18h2v-2h-2v2zm8-8h2v-2h-2v2zm0 8c1.1 0 2-.9 2-2h-2v2zm0-12h2V7h-2v2zm0 8h2v-2h-2v2zm-4 4h2v-2h-2v2zm0-16h2V3h-2v2zM7 17h10V7H7v10zm2-8h6v6H9V9z\" /></g>\n<g id=\"send\"><path d=\"M2.01 21L23 12 2.01 3 2 10l15 2-15 2z\" /></g>\n<g id=\"settings\"><path d=\"M19.43 12.98c.04-.32.07-.64.07-.98s-.03-.66-.07-.98l2.11-1.65c.19-.15.24-.42.12-.64l-2-3.46c-.12-.22-.39-.3-.61-.22l-2.49 1c-.52-.4-1.08-.73-1.69-.98l-.38-2.65C14.46 2.18 14.25 2 14 2h-4c-.25 0-.46.18-.49.42l-.38 2.65c-.61.25-1.17.59-1.69.98l-2.49-1c-.23-.09-.49 0-.61.22l-2 3.46c-.13.22-.07.49.12.64l2.11 1.65c-.04.32-.07.65-.07.98s.03.66.07.98l-2.11 1.65c-.19.15-.24.42-.12.64l2 3.46c.12.22.39.3.61.22l2.49-1c.52.4 1.08.73 1.69.98l.38 2.65c.03.24.24.42.49.42h4c.25 0 .46-.18.49-.42l.38-2.65c.61-.25 1.17-.59 1.69-.98l2.49 1c.23.09.49 0 .61-.22l2-3.46c.12-.22.07-.49-.12-.64l-2.11-1.65zM12 15.5c-1.93 0-3.5-1.57-3.5-3.5s1.57-3.5 3.5-3.5 3.5 1.57 3.5 3.5-1.57 3.5-3.5 3.5z\" /></g>\n<g id=\"settings-applications\"><path d=\"M12 10c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm7-7H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.11 0 2-.9 2-2V5c0-1.1-.89-2-2-2zm-1.75 9c0 .23-.02.46-.05.68l1.48 1.16c.13.11.17.3.08.45l-1.4 2.42c-.09.15-.27.21-.43.15l-1.74-.7c-.36.28-.76.51-1.18.69l-.26 1.85c-.03.17-.18.3-.35.3h-2.8c-.17 0-.32-.13-.35-.29l-.26-1.85c-.43-.18-.82-.41-1.18-.69l-1.74.7c-.16.06-.34 0-.43-.15l-1.4-2.42c-.09-.15-.05-.34.08-.45l1.48-1.16c-.03-.23-.05-.46-.05-.69 0-.23.02-.46.05-.68l-1.48-1.16c-.13-.11-.17-.3-.08-.45l1.4-2.42c.09-.15.27-.21.43-.15l1.74.7c.36-.28.76-.51 1.18-.69l.26-1.85c.03-.17.18-.3.35-.3h2.8c.17 0 .32.13.35.29l.26 1.85c.43.18.82.41 1.18.69l1.74-.7c.16-.06.34 0 .43.15l1.4 2.42c.09.15.05.34-.08.45l-1.48 1.16c.03.23.05.46.05.69z\" /></g>\n<g id=\"settings-backup-restore\"><path d=\"M14 12c0-1.1-.9-2-2-2s-2 .9-2 2 .9 2 2 2 2-.9 2-2zm-2-9c-4.97 0-9 4.03-9 9H0l4 4 4-4H5c0-3.87 3.13-7 7-7s7 3.13 7 7-3.13 7-7 7c-1.51 0-2.91-.49-4.06-1.3l-1.42 1.44C8.04 20.3 9.94 21 12 21c4.97 0 9-4.03 9-9s-4.03-9-9-9z\" /></g>\n<g id=\"settings-bluetooth\"><path d=\"M11 24h2v-2h-2v2zm-4 0h2v-2H7v2zm8 0h2v-2h-2v2zm2.71-18.29L12 0h-1v7.59L6.41 3 5 4.41 10.59 10 5 15.59 6.41 17 11 12.41V20h1l5.71-5.71-4.3-4.29 4.3-4.29zM13 3.83l1.88 1.88L13 7.59V3.83zm1.88 10.46L13 16.17v-3.76l1.88 1.88z\" /></g>\n<g id=\"settings-brightness\"><path d=\"M21 3H3c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16.01H3V4.99h18v14.02zM8 16h2.5l1.5 1.5 1.5-1.5H16v-2.5l1.5-1.5-1.5-1.5V8h-2.5L12 6.5 10.5 8H8v2.5L6.5 12 8 13.5V16zm4-7c1.66 0 3 1.34 3 3s-1.34 3-3 3V9z\" /></g>\n<g id=\"settings-cell\"><path d=\"M7 24h2v-2H7v2zm4 0h2v-2h-2v2zm4 0h2v-2h-2v2zM16 .01L8 0C6.9 0 6 .9 6 2v16c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V2c0-1.1-.9-1.99-2-1.99zM16 16H8V4h8v12z\" /></g>\n<g id=\"settings-ethernet\"><path d=\"M7.77 6.76L6.23 5.48.82 12l5.41 6.52 1.54-1.28L3.42 12l4.35-5.24zM7 13h2v-2H7v2zm10-2h-2v2h2v-2zm-6 2h2v-2h-2v2zm6.77-7.52l-1.54 1.28L20.58 12l-4.35 5.24 1.54 1.28L23.18 12l-5.41-6.52z\" /></g>\n<g id=\"settings-input-antenna\"><path d=\"M12 5c-3.87 0-7 3.13-7 7h2c0-2.76 2.24-5 5-5s5 2.24 5 5h2c0-3.87-3.13-7-7-7zm1 9.29c.88-.39 1.5-1.26 1.5-2.29 0-1.38-1.12-2.5-2.5-2.5S9.5 10.62 9.5 12c0 1.02.62 1.9 1.5 2.29v3.3L7.59 21 9 22.41l3-3 3 3L16.41 21 13 17.59v-3.3zM12 1C5.93 1 1 5.93 1 12h2c0-4.97 4.03-9 9-9s9 4.03 9 9h2c0-6.07-4.93-11-11-11z\" /></g>\n<g id=\"settings-input-component\"><path d=\"M5 2c0-.55-.45-1-1-1s-1 .45-1 1v4H1v6h6V6H5V2zm4 14c0 1.3.84 2.4 2 2.82V23h2v-4.18c1.16-.41 2-1.51 2-2.82v-2H9v2zm-8 0c0 1.3.84 2.4 2 2.82V23h2v-4.18C6.16 18.4 7 17.3 7 16v-2H1v2zM21 6V2c0-.55-.45-1-1-1s-1 .45-1 1v4h-2v6h6V6h-2zm-8-4c0-.55-.45-1-1-1s-1 .45-1 1v4H9v6h6V6h-2V2zm4 14c0 1.3.84 2.4 2 2.82V23h2v-4.18c1.16-.41 2-1.51 2-2.82v-2h-6v2z\" /></g>\n<g id=\"settings-input-composite\"><path d=\"M5 2c0-.55-.45-1-1-1s-1 .45-1 1v4H1v6h6V6H5V2zm4 14c0 1.3.84 2.4 2 2.82V23h2v-4.18c1.16-.41 2-1.51 2-2.82v-2H9v2zm-8 0c0 1.3.84 2.4 2 2.82V23h2v-4.18C6.16 18.4 7 17.3 7 16v-2H1v2zM21 6V2c0-.55-.45-1-1-1s-1 .45-1 1v4h-2v6h6V6h-2zm-8-4c0-.55-.45-1-1-1s-1 .45-1 1v4H9v6h6V6h-2V2zm4 14c0 1.3.84 2.4 2 2.82V23h2v-4.18c1.16-.41 2-1.51 2-2.82v-2h-6v2z\" /></g>\n<g id=\"settings-input-hdmi\"><path d=\"M18 7V4c0-1.1-.9-2-2-2H8c-1.1 0-2 .9-2 2v3H5v6l3 6v3h8v-3l3-6V7h-1zM8 4h8v3h-2V5h-1v2h-2V5h-1v2H8V4z\" /></g>\n<g id=\"settings-input-svideo\"><path d=\"M8 11.5c0-.83-.67-1.5-1.5-1.5S5 10.67 5 11.5 5.67 13 6.5 13 8 12.33 8 11.5zm7-5c0-.83-.67-1.5-1.5-1.5h-3C9.67 5 9 5.67 9 6.5S9.67 8 10.5 8h3c.83 0 1.5-.67 1.5-1.5zM8.5 15c-.83 0-1.5.67-1.5 1.5S7.67 18 8.5 18s1.5-.67 1.5-1.5S9.33 15 8.5 15zM12 1C5.93 1 1 5.93 1 12s4.93 11 11 11 11-4.93 11-11S18.07 1 12 1zm0 20c-4.96 0-9-4.04-9-9s4.04-9 9-9 9 4.04 9 9-4.04 9-9 9zm5.5-11c-.83 0-1.5.67-1.5 1.5s.67 1.5 1.5 1.5 1.5-.67 1.5-1.5-.67-1.5-1.5-1.5zm-2 5c-.83 0-1.5.67-1.5 1.5s.67 1.5 1.5 1.5 1.5-.67 1.5-1.5-.67-1.5-1.5-1.5z\" /></g>\n<g id=\"settings-overscan\"><path d=\"M12.01 5.5L10 8h4l-1.99-2.5zM18 10v4l2.5-1.99L18 10zM6 10l-2.5 2.01L6 14v-4zm8 6h-4l2.01 2.5L14 16zm7-13H3c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16.01H3V4.99h18v14.02z\" /></g>\n<g id=\"settings-phone\"><path d=\"M13 9h-2v2h2V9zm4 0h-2v2h2V9zm3 6.5c-1.25 0-2.45-.2-3.57-.57-.35-.11-.74-.03-1.02.24l-2.2 2.2c-2.83-1.44-5.15-3.75-6.59-6.58l2.2-2.21c.28-.27.36-.66.25-1.01C8.7 6.45 8.5 5.25 8.5 4c0-.55-.45-1-1-1H4c-.55 0-1 .45-1 1 0 9.39 7.61 17 17 17 .55 0 1-.45 1-1v-3.5c0-.55-.45-1-1-1zM19 9v2h2V9h-2z\" /></g>\n<g id=\"settings-power\"><path d=\"M7 24h2v-2H7v2zm4 0h2v-2h-2v2zm2-22h-2v10h2V2zm3.56 2.44l-1.45 1.45C16.84 6.94 18 8.83 18 11c0 3.31-2.69 6-6 6s-6-2.69-6-6c0-2.17 1.16-4.06 2.88-5.12L7.44 4.44C5.36 5.88 4 8.28 4 11c0 4.42 3.58 8 8 8s8-3.58 8-8c0-2.72-1.36-5.12-3.44-6.56zM15 24h2v-2h-2v2z\" /></g>\n<g id=\"settings-remote\"><path d=\"M15 9H9c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h6c.55 0 1-.45 1-1V10c0-.55-.45-1-1-1zm-3 6c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zM7.05 6.05l1.41 1.41C9.37 6.56 10.62 6 12 6s2.63.56 3.54 1.46l1.41-1.41C15.68 4.78 13.93 4 12 4s-3.68.78-4.95 2.05zM12 0C8.96 0 6.21 1.23 4.22 3.22l1.41 1.41C7.26 3.01 9.51 2 12 2s4.74 1.01 6.36 2.64l1.41-1.41C17.79 1.23 15.04 0 12 0z\" /></g>\n<g id=\"settings-voice\"><path d=\"M7 24h2v-2H7v2zm5-11c1.66 0 2.99-1.34 2.99-3L15 4c0-1.66-1.34-3-3-3S9 2.34 9 4v6c0 1.66 1.34 3 3 3zm-1 11h2v-2h-2v2zm4 0h2v-2h-2v2zm4-14h-1.7c0 3-2.54 5.1-5.3 5.1S6.7 13 6.7 10H5c0 3.41 2.72 6.23 6 6.72V20h2v-3.28c3.28-.49 6-3.31 6-6.72z\" /></g>\n<g id=\"shop\"><path d=\"M16 6V4c0-1.11-.89-2-2-2h-4c-1.11 0-2 .89-2 2v2H2v13c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V6h-6zm-6-2h4v2h-4V4zM9 18V9l7.5 4L9 18z\" /></g>\n<g id=\"shop-two\"><path d=\"M3 9H1v11c0 1.11.89 2 2 2h14c1.11 0 2-.89 2-2H3V9zm15-4V3c0-1.11-.89-2-2-2h-4c-1.11 0-2 .89-2 2v2H5v11c0 1.11.89 2 2 2h14c1.11 0 2-.89 2-2V5h-5zm-6-2h4v2h-4V3zm0 12V8l5.5 3-5.5 4z\" /></g>\n<g id=\"shopping-basket\"><path d=\"M17.21 9l-4.38-6.56c-.19-.28-.51-.42-.83-.42-.32 0-.64.14-.83.43L6.79 9H2c-.55 0-1 .45-1 1 0 .09.01.18.04.27l2.54 9.27c.23.84 1 1.46 1.92 1.46h13c.92 0 1.69-.62 1.93-1.46l2.54-9.27L23 10c0-.55-.45-1-1-1h-4.79zM9 9l3-4.4L15 9H9zm3 8c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2z\" /></g>\n<g id=\"shopping-cart\"><path d=\"M7 18c-1.1 0-1.99.9-1.99 2S5.9 22 7 22s2-.9 2-2-.9-2-2-2zM1 2v2h2l3.6 7.59-1.35 2.45c-.16.28-.25.61-.25.96 0 1.1.9 2 2 2h12v-2H7.42c-.14 0-.25-.11-.25-.25l.03-.12.9-1.63h7.45c.75 0 1.41-.41 1.75-1.03l3.58-6.49c.08-.14.12-.31.12-.48 0-.55-.45-1-1-1H5.21l-.94-2H1zm16 16c-1.1 0-1.99.9-1.99 2s.89 2 1.99 2 2-.9 2-2-.9-2-2-2z\" /></g>\n<g id=\"sort\"><path d=\"M3 18h6v-2H3v2zM3 6v2h18V6H3zm0 7h12v-2H3v2z\" /></g>\n<g id=\"speaker-notes\"><path d=\"M20 2H4c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zM8 14H6v-2h2v2zm0-3H6V9h2v2zm0-3H6V6h2v2zm7 6h-5v-2h5v2zm3-3h-8V9h8v2zm0-3h-8V6h8v2z\" /></g>\n<g id=\"spellcheck\"><path d=\"M12.45 16h2.09L9.43 3H7.57L2.46 16h2.09l1.12-3h5.64l1.14 3zm-6.02-5L8.5 5.48 10.57 11H6.43zm15.16.59l-8.09 8.09L9.83 16l-1.41 1.41 5.09 5.09L23 13l-1.41-1.41z\" /></g>\n<g id=\"star\"><path d=\"M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z\" /></g>\n<g id=\"star-border\"><path d=\"M22 9.24l-7.19-.62L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21 12 17.27 18.18 21l-1.63-7.03L22 9.24zM12 15.4l-3.76 2.27 1-4.28-3.32-2.88 4.38-.38L12 6.1l1.71 4.04 4.38.38-3.32 2.88 1 4.28L12 15.4z\" /></g>\n<g id=\"star-half\"><path d=\"M22 9.24l-7.19-.62L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21 12 17.27 18.18 21l-1.63-7.03L22 9.24zM12 15.4V6.1l1.71 4.04 4.38.38-3.32 2.88 1 4.28L12 15.4z\" /></g>\n<g id=\"stars\"><path d=\"M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zm4.24 16L12 15.45 7.77 18l1.12-4.81-3.73-3.23 4.92-.42L12 5l1.92 4.53 4.92.42-3.73 3.23L16.23 18z\" /></g>\n<g id=\"store\"><path d=\"M20 4H4v2h16V4zm1 10v-2l-1-5H4l-1 5v2h1v6h10v-6h4v6h2v-6h1zm-9 4H6v-4h6v4z\" /></g>\n<g id=\"subdirectory-arrow-left\"><path d=\"M11 9l1.42 1.42L8.83 14H18V4h2v12H8.83l3.59 3.58L11 21l-6-6 6-6z\" /></g>\n<g id=\"subdirectory-arrow-right\"><path d=\"M19 15l-6 6-1.42-1.42L15.17 16H4V4h2v10h9.17l-3.59-3.58L13 9l6 6z\" /></g>\n<g id=\"subject\"><path d=\"M14 17H4v2h10v-2zm6-8H4v2h16V9zM4 15h16v-2H4v2zM4 5v2h16V5H4z\" /></g>\n<g id=\"supervisor-account\"><path d=\"M16.5 12c1.38 0 2.49-1.12 2.49-2.5S17.88 7 16.5 7C15.12 7 14 8.12 14 9.5s1.12 2.5 2.5 2.5zM9 11c1.66 0 2.99-1.34 2.99-3S10.66 5 9 5C7.34 5 6 6.34 6 8s1.34 3 3 3zm7.5 3c-1.83 0-5.5.92-5.5 2.75V19h11v-2.25c0-1.83-3.67-2.75-5.5-2.75zM9 13c-2.33 0-7 1.17-7 3.5V19h7v-2.25c0-.85.33-2.34 2.37-3.47C10.5 13.1 9.66 13 9 13z\" /></g>\n<g id=\"swap-horiz\"><path d=\"M6.99 11L3 15l3.99 4v-3H14v-2H6.99v-3zM21 9l-3.99-4v3H10v2h7.01v3L21 9z\" /></g>\n<g id=\"swap-vert\"><path d=\"M16 17.01V10h-2v7.01h-3L15 21l4-3.99h-3zM9 3L5 6.99h3V14h2V6.99h3L9 3z\" /></g>\n<g id=\"swap-vertical-circle\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zM6.5 9L10 5.5 13.5 9H11v4H9V9H6.5zm11 6L14 18.5 10.5 15H13v-4h2v4h2.5z\" /></g>\n<g id=\"system-update-alt\"><path d=\"M12 16.5l4-4h-3v-9h-2v9H8l4 4zm9-13h-6v1.99h6v14.03H3V5.49h6V3.5H3c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2v-14c0-1.1-.9-2-2-2z\" /></g>\n<g id=\"tab\"><path d=\"M21 3H3c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H3V5h10v4h8v10z\" /></g>\n<g id=\"tab-unselected\"><path d=\"M1 9h2V7H1v2zm0 4h2v-2H1v2zm0-8h2V3c-1.1 0-2 .9-2 2zm8 16h2v-2H9v2zm-8-4h2v-2H1v2zm2 4v-2H1c0 1.1.9 2 2 2zM21 3h-8v6h10V5c0-1.1-.9-2-2-2zm0 14h2v-2h-2v2zM9 5h2V3H9v2zM5 21h2v-2H5v2zM5 5h2V3H5v2zm16 16c1.1 0 2-.9 2-2h-2v2zm0-8h2v-2h-2v2zm-8 8h2v-2h-2v2zm4 0h2v-2h-2v2z\" /></g>\n<g id=\"text-format\"><path d=\"M5 17v2h14v-2H5zm4.5-4.2h5l.9 2.2h2.1L12.75 4h-1.5L6.5 15h2.1l.9-2.2zM12 5.98L13.87 11h-3.74L12 5.98z\" /></g>\n<g id=\"theaters\"><path d=\"M18 3v2h-2V3H8v2H6V3H4v18h2v-2h2v2h8v-2h2v2h2V3h-2zM8 17H6v-2h2v2zm0-4H6v-2h2v2zm0-4H6V7h2v2zm10 8h-2v-2h2v2zm0-4h-2v-2h2v2zm0-4h-2V7h2v2z\" /></g>\n<g id=\"thumb-down\"><path d=\"M15 3H6c-.83 0-1.54.5-1.84 1.22l-3.02 7.05c-.09.23-.14.47-.14.73v1.91l.01.01L1 14c0 1.1.9 2 2 2h6.31l-.95 4.57-.03.32c0 .41.17.79.44 1.06L9.83 23l6.59-6.59c.36-.36.58-.86.58-1.41V5c0-1.1-.9-2-2-2zm4 0v12h4V3h-4z\" /></g>\n<g id=\"thumb-up\"><path d=\"M1 21h4V9H1v12zm22-11c0-1.1-.9-2-2-2h-6.31l.95-4.57.03-.32c0-.41-.17-.79-.44-1.06L14.17 1 7.59 7.59C7.22 7.95 7 8.45 7 9v10c0 1.1.9 2 2 2h9c.83 0 1.54-.5 1.84-1.22l3.02-7.05c.09-.23.14-.47.14-.73v-1.91l-.01-.01L23 10z\" /></g>\n<g id=\"thumbs-up-down\"><path d=\"M12 6c0-.55-.45-1-1-1H5.82l.66-3.18.02-.23c0-.31-.13-.59-.33-.8L5.38 0 .44 4.94C.17 5.21 0 5.59 0 6v6.5c0 .83.67 1.5 1.5 1.5h6.75c.62 0 1.15-.38 1.38-.91l2.26-5.29c.07-.17.11-.36.11-.55V6zm10.5 4h-6.75c-.62 0-1.15.38-1.38.91l-2.26 5.29c-.07.17-.11.36-.11.55V18c0 .55.45 1 1 1h5.18l-.66 3.18-.02.24c0 .31.13.59.33.8l.79.78 4.94-4.94c.27-.27.44-.65.44-1.06v-6.5c0-.83-.67-1.5-1.5-1.5z\" /></g>\n<g id=\"timeline\"><path d=\"M23 8c0 1.1-.9 2-2 2-.18 0-.35-.02-.51-.07l-3.56 3.55c.05.16.07.34.07.52 0 1.1-.9 2-2 2s-2-.9-2-2c0-.18.02-.36.07-.52l-2.55-2.55c-.16.05-.34.07-.52.07s-.36-.02-.52-.07l-4.55 4.56c.05.16.07.33.07.51 0 1.1-.9 2-2 2s-2-.9-2-2 .9-2 2-2c.18 0 .35.02.51.07l4.56-4.55C8.02 9.36 8 9.18 8 9c0-1.1.9-2 2-2s2 .9 2 2c0 .18-.02.36-.07.52l2.55 2.55c.16-.05.34-.07.52-.07s.36.02.52.07l3.55-3.56C19.02 8.35 19 8.18 19 8c0-1.1.9-2 2-2s2 .9 2 2z\" /></g>\n<g id=\"toc\"><path d=\"M3 9h14V7H3v2zm0 4h14v-2H3v2zm0 4h14v-2H3v2zm16 0h2v-2h-2v2zm0-10v2h2V7h-2zm0 6h2v-2h-2v2z\" /></g>\n<g id=\"today\"><path d=\"M19 3h-1V1h-2v2H8V1H6v2H5c-1.11 0-1.99.9-1.99 2L3 19c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V8h14v11zM7 10h5v5H7z\" /></g>\n<g id=\"toll\"><path d=\"M15 4c-4.42 0-8 3.58-8 8s3.58 8 8 8 8-3.58 8-8-3.58-8-8-8zm0 14c-3.31 0-6-2.69-6-6s2.69-6 6-6 6 2.69 6 6-2.69 6-6 6zM3 12c0-2.61 1.67-4.83 4-5.65V4.26C3.55 5.15 1 8.27 1 12s2.55 6.85 6 7.74v-2.09c-2.33-.82-4-3.04-4-5.65z\" /></g>\n<g id=\"touch-app\"><path d=\"M9 11.24V7.5C9 6.12 10.12 5 11.5 5S14 6.12 14 7.5v3.74c1.21-.81 2-2.18 2-3.74C16 5.01 13.99 3 11.5 3S7 5.01 7 7.5c0 1.56.79 2.93 2 3.74zm9.84 4.63l-4.54-2.26c-.17-.07-.35-.11-.54-.11H13v-6c0-.83-.67-1.5-1.5-1.5S10 6.67 10 7.5v10.74l-3.43-.72c-.08-.01-.15-.03-.24-.03-.31 0-.59.13-.79.33l-.79.8 4.94 4.94c.27.27.65.44 1.06.44h6.79c.75 0 1.33-.55 1.44-1.28l.75-5.27c.01-.07.02-.14.02-.2 0-.62-.38-1.16-.91-1.38z\" /></g>\n<g id=\"track-changes\"><path d=\"M19.07 4.93l-1.41 1.41C19.1 7.79 20 9.79 20 12c0 4.42-3.58 8-8 8s-8-3.58-8-8c0-4.08 3.05-7.44 7-7.93v2.02C8.16 6.57 6 9.03 6 12c0 3.31 2.69 6 6 6s6-2.69 6-6c0-1.66-.67-3.16-1.76-4.24l-1.41 1.41C15.55 9.9 16 10.9 16 12c0 2.21-1.79 4-4 4s-4-1.79-4-4c0-1.86 1.28-3.41 3-3.86v2.14c-.6.35-1 .98-1 1.72 0 1.1.9 2 2 2s2-.9 2-2c0-.74-.4-1.38-1-1.72V2h-1C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10c0-2.76-1.12-5.26-2.93-7.07z\" /></g>\n<g id=\"translate\"><path d=\"M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z\" /></g>\n<g id=\"trending-down\"><path d=\"M16 18l2.29-2.29-4.88-4.88-4 4L2 7.41 3.41 6l6 6 4-4 6.3 6.29L22 12v6z\" /></g>\n<g id=\"trending-flat\"><path d=\"M22 12l-4-4v3H3v2h15v3z\" /></g>\n<g id=\"trending-up\"><path d=\"M16 6l2.29 2.29-4.88 4.88-4-4L2 16.59 3.41 18l6-6 4 4 6.3-6.29L22 12V6z\" /></g>\n<g id=\"turned-in\"><path d=\"M17 3H7c-1.1 0-1.99.9-1.99 2L5 21l7-3 7 3V5c0-1.1-.9-2-2-2z\" /></g>\n<g id=\"turned-in-not\"><path d=\"M17 3H7c-1.1 0-1.99.9-1.99 2L5 21l7-3 7 3V5c0-1.1-.9-2-2-2zm0 15l-5-2.18L7 18V5h10v13z\" /></g>\n<g id=\"unarchive\"><path d=\"M20.55 5.22l-1.39-1.68C18.88 3.21 18.47 3 18 3H6c-.47 0-.88.21-1.15.55L3.46 5.22C3.17 5.57 3 6.01 3 6.5V19c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V6.5c0-.49-.17-.93-.45-1.28zM12 9.5l5.5 5.5H14v2h-4v-2H6.5L12 9.5zM5.12 5l.82-1h12l.93 1H5.12z\" /></g>\n<g id=\"undo\"><path d=\"M12.5 8c-2.65 0-5.05.99-6.9 2.6L2 7v9h9l-3.62-3.62c1.39-1.16 3.16-1.88 5.12-1.88 3.54 0 6.55 2.31 7.6 5.5l2.37-.78C21.08 11.03 17.15 8 12.5 8z\" /></g>\n<g id=\"unfold-less\"><path d=\"M7.41 18.59L8.83 20 12 16.83 15.17 20l1.41-1.41L12 14l-4.59 4.59zm9.18-13.18L15.17 4 12 7.17 8.83 4 7.41 5.41 12 10l4.59-4.59z\" /></g>\n<g id=\"unfold-more\"><path d=\"M12 5.83L15.17 9l1.41-1.41L12 3 7.41 7.59 8.83 9 12 5.83zm0 12.34L8.83 15l-1.41 1.41L12 21l4.59-4.59L15.17 15 12 18.17z\" /></g>\n<g id=\"update\"><path d=\"M21 10.12h-6.78l2.74-2.82c-2.73-2.7-7.15-2.8-9.88-.1-2.73 2.71-2.73 7.08 0 9.79 2.73 2.71 7.15 2.71 9.88 0C18.32 15.65 19 14.08 19 12.1h2c0 1.98-.88 4.55-2.64 6.29-3.51 3.48-9.21 3.48-12.72 0-3.5-3.47-3.53-9.11-.02-12.58 3.51-3.47 9.14-3.47 12.65 0L21 3v7.12zM12.5 8v4.25l3.5 2.08-.72 1.21L11 13V8h1.5z\" /></g>\n<g id=\"verified-user\"><path d=\"M12 1L3 5v6c0 5.55 3.84 10.74 9 12 5.16-1.26 9-6.45 9-12V5l-9-4zm-2 16l-4-4 1.41-1.41L10 14.17l6.59-6.59L18 9l-8 8z\" /></g>\n<g id=\"view-agenda\"><path d=\"M20 13H3c-.55 0-1 .45-1 1v6c0 .55.45 1 1 1h17c.55 0 1-.45 1-1v-6c0-.55-.45-1-1-1zm0-10H3c-.55 0-1 .45-1 1v6c0 .55.45 1 1 1h17c.55 0 1-.45 1-1V4c0-.55-.45-1-1-1z\" /></g>\n<g id=\"view-array\"><path d=\"M4 18h3V5H4v13zM18 5v13h3V5h-3zM8 18h9V5H8v13z\" /></g>\n<g id=\"view-carousel\"><path d=\"M7 19h10V4H7v15zm-5-2h4V6H2v11zM18 6v11h4V6h-4z\" /></g>\n<g id=\"view-column\"><path d=\"M10 18h5V5h-5v13zm-6 0h5V5H4v13zM16 5v13h5V5h-5z\" /></g>\n<g id=\"view-day\"><path d=\"M2 21h19v-3H2v3zM20 8H3c-.55 0-1 .45-1 1v6c0 .55.45 1 1 1h17c.55 0 1-.45 1-1V9c0-.55-.45-1-1-1zM2 3v3h19V3H2z\" /></g>\n<g id=\"view-headline\"><path d=\"M4 15h16v-2H4v2zm0 4h16v-2H4v2zm0-8h16V9H4v2zm0-6v2h16V5H4z\" /></g>\n<g id=\"view-list\"><path d=\"M4 14h4v-4H4v4zm0 5h4v-4H4v4zM4 9h4V5H4v4zm5 5h12v-4H9v4zm0 5h12v-4H9v4zM9 5v4h12V5H9z\" /></g>\n<g id=\"view-module\"><path d=\"M4 11h5V5H4v6zm0 7h5v-6H4v6zm6 0h5v-6h-5v6zm6 0h5v-6h-5v6zm-6-7h5V5h-5v6zm6-6v6h5V5h-5z\" /></g>\n<g id=\"view-quilt\"><path d=\"M10 18h5v-6h-5v6zm-6 0h5V5H4v13zm12 0h5v-6h-5v6zM10 5v6h11V5H10z\" /></g>\n<g id=\"view-stream\"><path d=\"M4 18h17v-6H4v6zM4 5v6h17V5H4z\" /></g>\n<g id=\"view-week\"><path d=\"M6 5H3c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h3c.55 0 1-.45 1-1V6c0-.55-.45-1-1-1zm14 0h-3c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h3c.55 0 1-.45 1-1V6c0-.55-.45-1-1-1zm-7 0h-3c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h3c.55 0 1-.45 1-1V6c0-.55-.45-1-1-1z\" /></g>\n<g id=\"visibility\"><path d=\"M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z\" /></g>\n<g id=\"visibility-off\"><path d=\"M12 7c2.76 0 5 2.24 5 5 0 .65-.13 1.26-.36 1.83l2.92 2.92c1.51-1.26 2.7-2.89 3.43-4.75-1.73-4.39-6-7.5-11-7.5-1.4 0-2.74.25-3.98.7l2.16 2.16C10.74 7.13 11.35 7 12 7zM2 4.27l2.28 2.28.46.46C3.08 8.3 1.78 10.02 1 12c1.73 4.39 6 7.5 11 7.5 1.55 0 3.03-.3 4.38-.84l.42.42L19.73 22 21 20.73 3.27 3 2 4.27zM7.53 9.8l1.55 1.55c-.05.21-.08.43-.08.65 0 1.66 1.34 3 3 3 .22 0 .44-.03.65-.08l1.55 1.55c-.67.33-1.41.53-2.2.53-2.76 0-5-2.24-5-5 0-.79.2-1.53.53-2.2zm4.31-.78l3.15 3.15.02-.16c0-1.66-1.34-3-3-3l-.17.01z\" /></g>\n<g id=\"warning\"><path d=\"M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z\" /></g>\n<g id=\"watch-later\"><path d=\"M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10 10-4.5 10-10S17.5 2 12 2zm4.2 14.2L11 13V7h1.5v5.2l4.5 2.7-.8 1.3z\" /></g>\n<g id=\"weekend\"><path d=\"M21 10c-1.1 0-2 .9-2 2v3H5v-3c0-1.1-.9-2-2-2s-2 .9-2 2v5c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2v-5c0-1.1-.9-2-2-2zm-3-5H6c-1.1 0-2 .9-2 2v2.15c1.16.41 2 1.51 2 2.82V14h12v-2.03c0-1.3.84-2.4 2-2.82V7c0-1.1-.9-2-2-2z\" /></g>\n<g id=\"work\"><path d=\"M20 6h-4V4c0-1.11-.89-2-2-2h-4c-1.11 0-2 .89-2 2v2H4c-1.11 0-1.99.89-1.99 2L2 19c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V8c0-1.11-.89-2-2-2zm-6 0h-4V4h4v2z\" /></g>\n<g id=\"youtube-searched-for\"><path d=\"M17.01 14h-.8l-.27-.27c.98-1.14 1.57-2.61 1.57-4.23 0-3.59-2.91-6.5-6.5-6.5s-6.5 3-6.5 6.5H2l3.84 4 4.16-4H6.51C6.51 7 8.53 5 11.01 5s4.5 2.01 4.5 4.5c0 2.48-2.02 4.5-4.5 4.5-.65 0-1.26-.14-1.82-.38L7.71 15.1c.97.57 2.09.9 3.3.9 1.61 0 3.08-.59 4.22-1.57l.27.27v.79l5.01 4.99L22 19l-4.99-5z\" /></g>\n<g id=\"zoom-in\"><path d=\"M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14zm2.5-4h-2v2H9v-2H7V9h2V7h1v2h2v1z\" /></g>\n<g id=\"zoom-out\"><path d=\"M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14zM7 9h5v1H7z\" /></g>\n</defs></svg>\n</iron-iconset-svg>\n\n\n\n\n\n<iron-iconset-svg name=\"av\" size=\"24\">\n<svg><defs>\n<g id=\"add-to-queue\"><path d=\"M21 3H3c-1.11 0-2 .89-2 2v12c0 1.1.89 2 2 2h5v2h8v-2h5c1.1 0 1.99-.9 1.99-2L23 5c0-1.11-.9-2-2-2zm0 14H3V5h18v12zm-5-7v2h-3v3h-2v-3H8v-2h3V7h2v3h3z\" /></g>\n<g id=\"airplay\"><path d=\"M6 22h12l-6-6zM21 3H3c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h4v-2H3V5h18v12h-4v2h4c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z\" /></g>\n<g id=\"album\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 14.5c-2.49 0-4.5-2.01-4.5-4.5S9.51 7.5 12 7.5s4.5 2.01 4.5 4.5-2.01 4.5-4.5 4.5zm0-5.5c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1z\" /></g>\n<g id=\"art-track\"><path d=\"M22 13h-8v-2h8v2zm0-6h-8v2h8V7zm-8 10h8v-2h-8v2zm-2-8v6c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V9c0-1.1.9-2 2-2h6c1.1 0 2 .9 2 2zm-1.5 6l-2.25-3-1.75 2.26-1.25-1.51L3.5 15h7z\" /></g>\n<g id=\"av-timer\"><path d=\"M11 17c0 .55.45 1 1 1s1-.45 1-1-.45-1-1-1-1 .45-1 1zm0-14v4h2V5.08c3.39.49 6 3.39 6 6.92 0 3.87-3.13 7-7 7s-7-3.13-7-7c0-1.68.59-3.22 1.58-4.42L12 13l1.41-1.41-6.8-6.8v.02C4.42 6.45 3 9.05 3 12c0 4.97 4.02 9 9 9 4.97 0 9-4.03 9-9s-4.03-9-9-9h-1zm7 9c0-.55-.45-1-1-1s-1 .45-1 1 .45 1 1 1 1-.45 1-1zM6 12c0 .55.45 1 1 1s1-.45 1-1-.45-1-1-1-1 .45-1 1z\" /></g>\n<g id=\"closed-caption\"><path d=\"M19 4H5c-1.11 0-2 .9-2 2v12c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm-8 7H9.5v-.5h-2v3h2V13H11v1c0 .55-.45 1-1 1H7c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1h3c.55 0 1 .45 1 1v1zm7 0h-1.5v-.5h-2v3h2V13H18v1c0 .55-.45 1-1 1h-3c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1h3c.55 0 1 .45 1 1v1z\" /></g>\n<g id=\"equalizer\"><path d=\"M10 20h4V4h-4v16zm-6 0h4v-8H4v8zM16 9v11h4V9h-4z\" /></g>\n<g id=\"explicit\"><path d=\"M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-4 6h-4v2h4v2h-4v2h4v2H9V7h6v2z\" /></g>\n<g id=\"fast-forward\"><path d=\"M4 18l8.5-6L4 6v12zm9-12v12l8.5-6L13 6z\" /></g>\n<g id=\"fast-rewind\"><path d=\"M11 18V6l-8.5 6 8.5 6zm.5-6l8.5 6V6l-8.5 6z\" /></g>\n<g id=\"fiber-dvr\"><path d=\"M17.5 10.5h2v1h-2zm-13 0h2v3h-2zM21 3H3c-1.11 0-2 .89-2 2v14c0 1.1.89 2 2 2h18c1.11 0 2-.9 2-2V5c0-1.11-.89-2-2-2zM8 13.5c0 .85-.65 1.5-1.5 1.5H3V9h3.5c.85 0 1.5.65 1.5 1.5v3zm4.62 1.5h-1.5L9.37 9h1.5l1 3.43 1-3.43h1.5l-1.75 6zM21 11.5c0 .6-.4 1.15-.9 1.4L21 15h-1.5l-.85-2H17.5v2H16V9h3.5c.85 0 1.5.65 1.5 1.5v1z\" /></g>\n<g id=\"fiber-manual-record\"><circle cx=\"12\" cy=\"12\" r=\"8\" /></g>\n<g id=\"fiber-new\"><path d=\"M20 4H4c-1.11 0-1.99.89-1.99 2L2 18c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V6c0-1.11-.89-2-2-2zM8.5 15H7.3l-2.55-3.5V15H3.5V9h1.25l2.5 3.5V9H8.5v6zm5-4.74H11v1.12h2.5v1.26H11v1.11h2.5V15h-4V9h4v1.26zm7 3.74c0 .55-.45 1-1 1h-4c-.55 0-1-.45-1-1V9h1.25v4.51h1.13V9.99h1.25v3.51h1.12V9h1.25v5z\" /></g>\n<g id=\"fiber-pin\"><path d=\"M5.5 10.5h2v1h-2zM20 4H4c-1.11 0-1.99.89-1.99 2L2 18c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V6c0-1.11-.89-2-2-2zM9 11.5c0 .85-.65 1.5-1.5 1.5h-2v2H4V9h3.5c.85 0 1.5.65 1.5 1.5v1zm3.5 3.5H11V9h1.5v6zm7.5 0h-1.2l-2.55-3.5V15H15V9h1.25l2.5 3.5V9H20v6z\" /></g>\n<g id=\"fiber-smart-record\"><g><circle cx=\"9\" cy=\"12\" r=\"8\" /><path d=\"M17 4.26v2.09c2.33.82 4 3.04 4 5.65s-1.67 4.83-4 5.65v2.09c3.45-.89 6-4.01 6-7.74s-2.55-6.85-6-7.74z\" /></g></g>\n<g id=\"forward-10\"><path d=\"M4 13c0 4.4 3.6 8 8 8s8-3.6 8-8h-2c0 3.3-2.7 6-6 6s-6-2.7-6-6 2.7-6 6-6v4l5-5-5-5v4c-4.4 0-8 3.6-8 8zm6.8 3H10v-3.3L9 13v-.7l1.8-.6h.1V16zm4.3-1.8c0 .3 0 .6-.1.8l-.3.6s-.3.3-.5.3-.4.1-.6.1-.4 0-.6-.1-.3-.2-.5-.3-.2-.3-.3-.6-.1-.5-.1-.8v-.7c0-.3 0-.6.1-.8l.3-.6s.3-.3.5-.3.4-.1.6-.1.4 0 .6.1.3.2.5.3.2.3.3.6.1.5.1.8v.7zm-.8-.8v-.5s-.1-.2-.1-.3-.1-.1-.2-.2-.2-.1-.3-.1-.2 0-.3.1l-.2.2s-.1.2-.1.3v2s.1.2.1.3.1.1.2.2.2.1.3.1.2 0 .3-.1l.2-.2s.1-.2.1-.3v-1.5z\" /></g>\n<g id=\"forward-30\"><path d=\"M9.6 13.5h.4c.2 0 .4-.1.5-.2s.2-.2.2-.4v-.2s-.1-.1-.1-.2-.1-.1-.2-.1h-.5s-.1.1-.2.1-.1.1-.1.2v.2h-1c0-.2 0-.3.1-.5s.2-.3.3-.4.3-.2.4-.2.4-.1.5-.1c.2 0 .4 0 .6.1s.3.1.5.2.2.2.3.4.1.3.1.5v.3s-.1.2-.1.3-.1.2-.2.2-.2.1-.3.2c.2.1.4.2.5.4s.2.4.2.6c0 .2 0 .4-.1.5s-.2.3-.3.4-.3.2-.5.2-.4.1-.6.1c-.2 0-.4 0-.5-.1s-.3-.1-.5-.2-.2-.2-.3-.4-.1-.4-.1-.6h.8v.2s.1.1.1.2.1.1.2.1h.5s.1-.1.2-.1.1-.1.1-.2v-.5s-.1-.1-.1-.2-.1-.1-.2-.1h-.6v-.7zm5.7.7c0 .3 0 .6-.1.8l-.3.6s-.3.3-.5.3-.4.1-.6.1-.4 0-.6-.1-.3-.2-.5-.3-.2-.3-.3-.6-.1-.5-.1-.8v-.7c0-.3 0-.6.1-.8l.3-.6s.3-.3.5-.3.4-.1.6-.1.4 0 .6.1.3.2.5.3.2.3.3.6.1.5.1.8v.7zm-.9-.8v-.5s-.1-.2-.1-.3-.1-.1-.2-.2-.2-.1-.3-.1-.2 0-.3.1l-.2.2s-.1.2-.1.3v2s.1.2.1.3.1.1.2.2.2.1.3.1.2 0 .3-.1l.2-.2s.1-.2.1-.3v-1.5zM4 13c0 4.4 3.6 8 8 8s8-3.6 8-8h-2c0 3.3-2.7 6-6 6s-6-2.7-6-6 2.7-6 6-6v4l5-5-5-5v4c-4.4 0-8 3.6-8 8z\" /></g>\n<g id=\"forward-5\"><path d=\"M4 13c0 4.4 3.6 8 8 8s8-3.6 8-8h-2c0 3.3-2.7 6-6 6s-6-2.7-6-6 2.7-6 6-6v4l5-5-5-5v4c-4.4 0-8 3.6-8 8zm6.7.9l.2-2.2h2.4v.7h-1.7l-.1.9s.1 0 .1-.1.1 0 .1-.1.1 0 .2 0h.2c.2 0 .4 0 .5.1s.3.2.4.3.2.3.3.5.1.4.1.6c0 .2 0 .4-.1.5s-.1.3-.3.5-.3.2-.5.3-.4.1-.6.1c-.2 0-.4 0-.5-.1s-.3-.1-.5-.2-.2-.2-.3-.4-.1-.3-.1-.5h.8c0 .2.1.3.2.4s.2.1.4.1c.1 0 .2 0 .3-.1l.2-.2s.1-.2.1-.3v-.6l-.1-.2-.2-.2s-.2-.1-.3-.1h-.2s-.1 0-.2.1-.1 0-.1.1-.1.1-.1.1h-.6z\" /></g>\n<g id=\"games\"><path d=\"M15 7.5V2H9v5.5l3 3 3-3zM7.5 9H2v6h5.5l3-3-3-3zM9 16.5V22h6v-5.5l-3-3-3 3zM16.5 9l-3 3 3 3H22V9h-5.5z\" /></g>\n<g id=\"hd\"><path d=\"M19 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-8 12H9.5v-2h-2v2H6V9h1.5v2.5h2V9H11v6zm2-6h4c.55 0 1 .45 1 1v4c0 .55-.45 1-1 1h-4V9zm1.5 4.5h2v-3h-2v3z\" /></g>\n<g id=\"hearing\"><path d=\"M17 20c-.29 0-.56-.06-.76-.15-.71-.37-1.21-.88-1.71-2.38-.51-1.56-1.47-2.29-2.39-3-.79-.61-1.61-1.24-2.32-2.53C9.29 10.98 9 9.93 9 9c0-2.8 2.2-5 5-5s5 2.2 5 5h2c0-3.93-3.07-7-7-7S7 5.07 7 9c0 1.26.38 2.65 1.07 3.9.91 1.65 1.98 2.48 2.85 3.15.81.62 1.39 1.07 1.71 2.05.6 1.82 1.37 2.84 2.73 3.55.51.23 1.07.35 1.64.35 2.21 0 4-1.79 4-4h-2c0 1.1-.9 2-2 2zM7.64 2.64L6.22 1.22C4.23 3.21 3 5.96 3 9s1.23 5.79 3.22 7.78l1.41-1.41C6.01 13.74 5 11.49 5 9s1.01-4.74 2.64-6.36zM11.5 9c0 1.38 1.12 2.5 2.5 2.5s2.5-1.12 2.5-2.5-1.12-2.5-2.5-2.5-2.5 1.12-2.5 2.5z\" /></g>\n<g id=\"high-quality\"><path d=\"M19 4H5c-1.11 0-2 .9-2 2v12c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm-8 11H9.5v-2h-2v2H6V9h1.5v2.5h2V9H11v6zm7-1c0 .55-.45 1-1 1h-.75v1.5h-1.5V15H14c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1h3c.55 0 1 .45 1 1v4zm-3.5-.5h2v-3h-2v3z\" /></g>\n<g id=\"library-add\"><path d=\"M4 6H2v14c0 1.1.9 2 2 2h14v-2H4V6zm16-4H8c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-1 9h-4v4h-2v-4H9V9h4V5h2v4h4v2z\" /></g>\n<g id=\"library-books\"><path d=\"M4 6H2v14c0 1.1.9 2 2 2h14v-2H4V6zm16-4H8c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-1 9H9V9h10v2zm-4 4H9v-2h6v2zm4-8H9V5h10v2z\" /></g>\n<g id=\"library-music\"><path d=\"M20 2H8c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-2 5h-3v5.5c0 1.38-1.12 2.5-2.5 2.5S10 13.88 10 12.5s1.12-2.5 2.5-2.5c.57 0 1.08.19 1.5.51V5h4v2zM4 6H2v14c0 1.1.9 2 2 2h14v-2H4V6z\" /></g>\n<g id=\"loop\"><path d=\"M12 4V1L8 5l4 4V6c3.31 0 6 2.69 6 6 0 1.01-.25 1.97-.7 2.8l1.46 1.46C19.54 15.03 20 13.57 20 12c0-4.42-3.58-8-8-8zm0 14c-3.31 0-6-2.69-6-6 0-1.01.25-1.97.7-2.8L5.24 7.74C4.46 8.97 4 10.43 4 12c0 4.42 3.58 8 8 8v3l4-4-4-4v3z\" /></g>\n<g id=\"mic\"><path d=\"M12 14c1.66 0 2.99-1.34 2.99-3L15 5c0-1.66-1.34-3-3-3S9 3.34 9 5v6c0 1.66 1.34 3 3 3zm5.3-3c0 3-2.54 5.1-5.3 5.1S6.7 14 6.7 11H5c0 3.41 2.72 6.23 6 6.72V21h2v-3.28c3.28-.48 6-3.3 6-6.72h-1.7z\" /></g>\n<g id=\"mic-none\"><path d=\"M12 14c1.66 0 2.99-1.34 2.99-3L15 5c0-1.66-1.34-3-3-3S9 3.34 9 5v6c0 1.66 1.34 3 3 3zm-1.2-9.1c0-.66.54-1.2 1.2-1.2.66 0 1.2.54 1.2 1.2l-.01 6.2c0 .66-.53 1.2-1.19 1.2-.66 0-1.2-.54-1.2-1.2V4.9zm6.5 6.1c0 3-2.54 5.1-5.3 5.1S6.7 14 6.7 11H5c0 3.41 2.72 6.23 6 6.72V21h2v-3.28c3.28-.48 6-3.3 6-6.72h-1.7z\" /></g>\n<g id=\"mic-off\"><path d=\"M19 11h-1.7c0 .74-.16 1.43-.43 2.05l1.23 1.23c.56-.98.9-2.09.9-3.28zm-4.02.17c0-.06.02-.11.02-.17V5c0-1.66-1.34-3-3-3S9 3.34 9 5v.18l5.98 5.99zM4.27 3L3 4.27l6.01 6.01V11c0 1.66 1.33 3 2.99 3 .22 0 .44-.03.65-.08l1.66 1.66c-.71.33-1.5.52-2.31.52-2.76 0-5.3-2.1-5.3-5.1H5c0 3.41 2.72 6.23 6 6.72V21h2v-3.28c.91-.13 1.77-.45 2.54-.9L19.73 21 21 19.73 4.27 3z\" /></g>\n<g id=\"movie\"><path d=\"M18 4l2 4h-3l-2-4h-2l2 4h-3l-2-4H8l2 4H7L5 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V4h-4z\" /></g>\n<g id=\"music-video\"><path d=\"M21 3H3c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H3V5h18v14zM8 15c0-1.66 1.34-3 3-3 .35 0 .69.07 1 .18V6h5v2h-3v7.03c-.02 1.64-1.35 2.97-3 2.97-1.66 0-3-1.34-3-3z\" /></g>\n<g id=\"new-releases\"><path d=\"M23 12l-2.44-2.78.34-3.68-3.61-.82-1.89-3.18L12 3 8.6 1.54 6.71 4.72l-3.61.81.34 3.68L1 12l2.44 2.78-.34 3.69 3.61.82 1.89 3.18L12 21l3.4 1.46 1.89-3.18 3.61-.82-.34-3.68L23 12zm-10 5h-2v-2h2v2zm0-4h-2V7h2v6z\" /></g>\n<g id=\"not-interested\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.42 0-8-3.58-8-8 0-1.85.63-3.55 1.69-4.9L16.9 18.31C15.55 19.37 13.85 20 12 20zm6.31-3.1L7.1 5.69C8.45 4.63 10.15 4 12 4c4.42 0 8 3.58 8 8 0 1.85-.63 3.55-1.69 4.9z\" /></g>\n<g id=\"pause\"><path d=\"M6 19h4V5H6v14zm8-14v14h4V5h-4z\" /></g>\n<g id=\"pause-circle-filled\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 14H9V8h2v8zm4 0h-2V8h2v8z\" /></g>\n<g id=\"pause-circle-outline\"><path d=\"M9 16h2V8H9v8zm3-14C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm1-4h2V8h-2v8z\" /></g>\n<g id=\"play-arrow\"><path d=\"M8 5v14l11-7z\" /></g>\n<g id=\"play-circle-filled\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 14.5v-9l6 4.5-6 4.5z\" /></g>\n<g id=\"play-circle-outline\"><path d=\"M10 16.5l6-4.5-6-4.5v9zM12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z\" /></g>\n<g id=\"playlist-add\"><path d=\"M14 10H2v2h12v-2zm0-4H2v2h12V6zm4 8v-4h-2v4h-4v2h4v4h2v-4h4v-2h-4zM2 16h8v-2H2v2z\" /></g>\n<g id=\"playlist-add-check\"><path d=\"M14 10H2v2h12v-2zm0-4H2v2h12V6zM2 16h8v-2H2v2zm19.5-4.5L23 13l-6.99 7-4.51-4.5L13 14l3.01 3 5.49-5.5z\" /></g>\n<g id=\"playlist-play\"><path d=\"M19 9H2v2h17V9zm0-4H2v2h17V5zM2 15h13v-2H2v2zm15-2v6l5-3-5-3z\" /></g>\n<g id=\"queue\"><path d=\"M4 6H2v14c0 1.1.9 2 2 2h14v-2H4V6zm16-4H8c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-1 9h-4v4h-2v-4H9V9h4V5h2v4h4v2z\" /></g>\n<g id=\"queue-music\"><path d=\"M15 6H3v2h12V6zm0 4H3v2h12v-2zM3 16h8v-2H3v2zM17 6v8.18c-.31-.11-.65-.18-1-.18-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3V8h3V6h-5z\" /></g>\n<g id=\"queue-play-next\"><path d=\"M21 3H3c-1.11 0-2 .89-2 2v12c0 1.1.89 2 2 2h5v2h8v-2h2v-2H3V5h18v8h2V5c0-1.11-.9-2-2-2zm-8 7V7h-2v3H8v2h3v3h2v-3h3v-2h-3zm11 8l-4.5 4.5L18 21l3-3-3-3 1.5-1.5L24 18z\" /></g>\n<g id=\"radio\"><path d=\"M3.24 6.15C2.51 6.43 2 7.17 2 8v12c0 1.1.89 2 2 2h16c1.11 0 2-.9 2-2V8c0-1.11-.89-2-2-2H8.3l8.26-3.34L15.88 1 3.24 6.15zM7 20c-1.66 0-3-1.34-3-3s1.34-3 3-3 3 1.34 3 3-1.34 3-3 3zm13-8h-2v-2h-2v2H4V8h16v4z\" /></g>\n<g id=\"recent-actors\"><path d=\"M21 5v14h2V5h-2zm-4 14h2V5h-2v14zM14 5H2c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V6c0-.55-.45-1-1-1zM8 7.75c1.24 0 2.25 1.01 2.25 2.25S9.24 12.25 8 12.25 5.75 11.24 5.75 10 6.76 7.75 8 7.75zM12.5 17h-9v-.75c0-1.5 3-2.25 4.5-2.25s4.5.75 4.5 2.25V17z\" /></g>\n<g id=\"remove-from-queue\"><path d=\"M21 3H3c-1.11 0-2 .89-2 2v12c0 1.1.89 2 2 2h5v2h8v-2h5c1.1 0 1.99-.9 1.99-2L23 5c0-1.11-.9-2-2-2zm0 14H3V5h18v12zm-5-7v2H8v-2h8z\" /></g>\n<g id=\"repeat\"><path d=\"M7 7h10v3l4-4-4-4v3H5v6h2V7zm10 10H7v-3l-4 4 4 4v-3h12v-6h-2v4z\" /></g>\n<g id=\"repeat-one\"><path d=\"M7 7h10v3l4-4-4-4v3H5v6h2V7zm10 10H7v-3l-4 4 4 4v-3h12v-6h-2v4zm-4-2V9h-1l-2 1v1h1.5v4H13z\" /></g>\n<g id=\"replay\"><path d=\"M12 5V1L7 6l5 5V7c3.31 0 6 2.69 6 6s-2.69 6-6 6-6-2.69-6-6H4c0 4.42 3.58 8 8 8s8-3.58 8-8-3.58-8-8-8z\" /></g>\n<g id=\"replay-10\"><path d=\"M12 5V1L7 6l5 5V7c3.3 0 6 2.7 6 6s-2.7 6-6 6-6-2.7-6-6H4c0 4.4 3.6 8 8 8s8-3.6 8-8-3.6-8-8-8zm-1.1 11H10v-3.3L9 13v-.7l1.8-.6h.1V16zm4.3-1.8c0 .3 0 .6-.1.8l-.3.6s-.3.3-.5.3-.4.1-.6.1-.4 0-.6-.1-.3-.2-.5-.3-.2-.3-.3-.6-.1-.5-.1-.8v-.7c0-.3 0-.6.1-.8l.3-.6s.3-.3.5-.3.4-.1.6-.1.4 0 .6.1c.2.1.3.2.5.3s.2.3.3.6.1.5.1.8v.7zm-.9-.8v-.5s-.1-.2-.1-.3-.1-.1-.2-.2-.2-.1-.3-.1-.2 0-.3.1l-.2.2s-.1.2-.1.3v2s.1.2.1.3.1.1.2.2.2.1.3.1.2 0 .3-.1l.2-.2s.1-.2.1-.3v-1.5z\" /></g>\n<g id=\"replay-30\"><path d=\"M12 5V1L7 6l5 5V7c3.3 0 6 2.7 6 6s-2.7 6-6 6-6-2.7-6-6H4c0 4.4 3.6 8 8 8s8-3.6 8-8-3.6-8-8-8zm-2.4 8.5h.4c.2 0 .4-.1.5-.2s.2-.2.2-.4v-.2s-.1-.1-.1-.2-.1-.1-.2-.1h-.5s-.1.1-.2.1-.1.1-.1.2v.2h-1c0-.2 0-.3.1-.5s.2-.3.3-.4.3-.2.4-.2.4-.1.5-.1c.2 0 .4 0 .6.1s.3.1.5.2.2.2.3.4.1.3.1.5v.3s-.1.2-.1.3-.1.2-.2.2-.2.1-.3.2c.2.1.4.2.5.4s.2.4.2.6c0 .2 0 .4-.1.5s-.2.3-.3.4-.3.2-.5.2-.4.1-.6.1c-.2 0-.4 0-.5-.1s-.3-.1-.5-.2-.2-.2-.3-.4-.1-.4-.1-.6h.8v.2s.1.1.1.2.1.1.2.1h.5s.1-.1.2-.1.1-.1.1-.2v-.5s-.1-.1-.1-.2-.1-.1-.2-.1h-.6v-.7zm5.7.7c0 .3 0 .6-.1.8l-.3.6s-.3.3-.5.3-.4.1-.6.1-.4 0-.6-.1-.3-.2-.5-.3-.2-.3-.3-.6-.1-.5-.1-.8v-.7c0-.3 0-.6.1-.8l.3-.6s.3-.3.5-.3.4-.1.6-.1.4 0 .6.1.3.2.5.3.2.3.3.6.1.5.1.8v.7zm-.8-.8v-.5c0-.1-.1-.2-.1-.3s-.1-.1-.2-.2-.2-.1-.3-.1-.2 0-.3.1l-.2.2s-.1.2-.1.3v2s.1.2.1.3.1.1.2.2.2.1.3.1.2 0 .3-.1l.2-.2s.1-.2.1-.3v-1.5z\" /></g>\n<g id=\"replay-5\"><path d=\"M12 5V1L7 6l5 5V7c3.3 0 6 2.7 6 6s-2.7 6-6 6-6-2.7-6-6H4c0 4.4 3.6 8 8 8s8-3.6 8-8-3.6-8-8-8zm-1.3 8.9l.2-2.2h2.4v.7h-1.7l-.1.9s.1 0 .1-.1.1 0 .1-.1.1 0 .2 0h.2c.2 0 .4 0 .5.1s.3.2.4.3.2.3.3.5.1.4.1.6c0 .2 0 .4-.1.5s-.1.3-.3.5-.3.2-.4.3-.4.1-.6.1c-.2 0-.4 0-.5-.1s-.3-.1-.5-.2-.2-.2-.3-.4-.1-.3-.1-.5h.8c0 .2.1.3.2.4s.2.1.4.1c.1 0 .2 0 .3-.1l.2-.2s.1-.2.1-.3v-.6l-.1-.2-.2-.2s-.2-.1-.3-.1h-.2s-.1 0-.2.1-.1 0-.1.1-.1.1-.1.1h-.7z\" /></g>\n<g id=\"shuffle\"><path d=\"M10.59 9.17L5.41 4 4 5.41l5.17 5.17 1.42-1.41zM14.5 4l2.04 2.04L4 18.59 5.41 20 17.96 7.46 20 9.5V4h-5.5zm.33 9.41l-1.41 1.41 3.13 3.13L14.5 20H20v-5.5l-2.04 2.04-3.13-3.13z\" /></g>\n<g id=\"skip-next\"><path d=\"M6 18l8.5-6L6 6v12zM16 6v12h2V6h-2z\" /></g>\n<g id=\"skip-previous\"><path d=\"M6 6h2v12H6zm3.5 6l8.5 6V6z\" /></g>\n<g id=\"slow-motion-video\"><path d=\"M13.05 9.79L10 7.5v9l3.05-2.29L16 12zm0 0L10 7.5v9l3.05-2.29L16 12zm0 0L10 7.5v9l3.05-2.29L16 12zM11 4.07V2.05c-2.01.2-3.84 1-5.32 2.21L7.1 5.69c1.11-.86 2.44-1.44 3.9-1.62zM5.69 7.1L4.26 5.68C3.05 7.16 2.25 8.99 2.05 11h2.02c.18-1.46.76-2.79 1.62-3.9zM4.07 13H2.05c.2 2.01 1 3.84 2.21 5.32l1.43-1.43c-.86-1.1-1.44-2.43-1.62-3.89zm1.61 6.74C7.16 20.95 9 21.75 11 21.95v-2.02c-1.46-.18-2.79-.76-3.9-1.62l-1.42 1.43zM22 12c0 5.16-3.92 9.42-8.95 9.95v-2.02C16.97 19.41 20 16.05 20 12s-3.03-7.41-6.95-7.93V2.05C18.08 2.58 22 6.84 22 12z\" /></g>\n<g id=\"snooze\"><path d=\"M7.88 3.39L6.6 1.86 2 5.71l1.29 1.53 4.59-3.85zM22 5.72l-4.6-3.86-1.29 1.53 4.6 3.86L22 5.72zM12 4c-4.97 0-9 4.03-9 9s4.02 9 9 9c4.97 0 9-4.03 9-9s-4.03-9-9-9zm0 16c-3.87 0-7-3.13-7-7s3.13-7 7-7 7 3.13 7 7-3.13 7-7 7zm-3-9h3.63L9 15.2V17h6v-2h-3.63L15 10.8V9H9v2z\" /></g>\n<g id=\"sort-by-alpha\"><path d=\"M14.94 4.66h-4.72l2.36-2.36zm-4.69 14.71h4.66l-2.33 2.33zM6.1 6.27L1.6 17.73h1.84l.92-2.45h5.11l.92 2.45h1.84L7.74 6.27H6.1zm-1.13 7.37l1.94-5.18 1.94 5.18H4.97zm10.76 2.5h6.12v1.59h-8.53v-1.29l5.92-8.56h-5.88v-1.6h8.3v1.26l-5.93 8.6z\" /></g>\n<g id=\"stop\"><path d=\"M6 6h12v12H6z\" /></g>\n<g id=\"subscriptions\"><path d=\"M20 8H4V6h16v2zm-2-6H6v2h12V2zm4 10v8c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2v-8c0-1.1.9-2 2-2h16c1.1 0 2 .9 2 2zm-6 4l-6-3.27v6.53L16 16z\" /></g>\n<g id=\"subtitles\"><path d=\"M20 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zM4 12h4v2H4v-2zm10 6H4v-2h10v2zm6 0h-4v-2h4v2zm0-4H10v-2h10v2z\" /></g>\n<g id=\"surround-sound\"><path d=\"M20 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zM7.76 16.24l-1.41 1.41C4.78 16.1 4 14.05 4 12c0-2.05.78-4.1 2.34-5.66l1.41 1.41C6.59 8.93 6 10.46 6 12s.59 3.07 1.76 4.24zM12 16c-2.21 0-4-1.79-4-4s1.79-4 4-4 4 1.79 4 4-1.79 4-4 4zm5.66 1.66l-1.41-1.41C17.41 15.07 18 13.54 18 12s-.59-3.07-1.76-4.24l1.41-1.41C19.22 7.9 20 9.95 20 12c0 2.05-.78 4.1-2.34 5.66zM12 10c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z\" /></g>\n<g id=\"video-library\"><path d=\"M4 6H2v14c0 1.1.9 2 2 2h14v-2H4V6zm16-4H8c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-8 12.5v-9l6 4.5-6 4.5z\" /></g>\n<g id=\"videocam\"><path d=\"M17 10.5V7c0-.55-.45-1-1-1H4c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h12c.55 0 1-.45 1-1v-3.5l4 4v-11l-4 4z\" /></g>\n<g id=\"videocam-off\"><path d=\"M21 6.5l-4 4V7c0-.55-.45-1-1-1H9.82L21 17.18V6.5zM3.27 2L2 3.27 4.73 6H4c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h12c.21 0 .39-.08.54-.18L19.73 21 21 19.73 3.27 2z\" /></g>\n<g id=\"volume-down\"><path d=\"M18.5 12c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02zM5 9v6h4l5 5V4L9 9H5z\" /></g>\n<g id=\"volume-mute\"><path d=\"M7 9v6h4l5 5V4l-5 5H7z\" /></g>\n<g id=\"volume-off\"><path d=\"M16.5 12c0-1.77-1.02-3.29-2.5-4.03v2.21l2.45 2.45c.03-.2.05-.41.05-.63zm2.5 0c0 .94-.2 1.82-.54 2.64l1.51 1.51C20.63 14.91 21 13.5 21 12c0-4.28-2.99-7.86-7-8.77v2.06c2.89.86 5 3.54 5 6.71zM4.27 3L3 4.27 7.73 9H3v6h4l5 5v-6.73l4.25 4.25c-.67.52-1.42.93-2.25 1.18v2.06c1.38-.31 2.63-.95 3.69-1.81L19.73 21 21 19.73l-9-9L4.27 3zM12 4L9.91 6.09 12 8.18V4z\" /></g>\n<g id=\"volume-up\"><path d=\"M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02zM14 3.23v2.06c2.89.86 5 3.54 5 6.71s-2.11 5.85-5 6.71v2.06c4.01-.91 7-4.49 7-8.77s-2.99-7.86-7-8.77z\" /></g>\n<g id=\"web\"><path d=\"M20 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm-5 14H4v-4h11v4zm0-5H4V9h11v4zm5 5h-4V9h4v9z\" /></g>\n<g id=\"web-asset\"><path d=\"M19 4H5c-1.11 0-2 .9-2 2v12c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V6c0-1.1-.89-2-2-2zm0 14H5V8h14v10z\" /></g>\n</defs></svg>\n</iron-iconset-svg>\n\n\n\n\n\n\n\n\n\n\n\n\n\n<dom-module id=\"paper-icon-button\">\n  <template strip-whitespace>\n    <style>\n      :host {\n        display: inline-block;\n        position: relative;\n        padding: 8px;\n        outline: none;\n        -webkit-user-select: none;\n        -moz-user-select: none;\n        -ms-user-select: none;\n        user-select: none;\n        cursor: pointer;\n        z-index: 0;\n        line-height: 1;\n\n        width: 40px;\n        height: 40px;\n\n        /* NOTE: Both values are needed, since some phones require the value to be `transparent`. */\n        -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n        -webkit-tap-highlight-color: transparent;\n\n        /* Because of polymer/2558, this style has lower specificity than * */\n        box-sizing: border-box !important;\n\n        @apply(--paper-icon-button);\n      }\n\n      :host #ink {\n        color: var(--paper-icon-button-ink-color, --primary-text-color);\n        opacity: 0.6;\n      }\n\n      :host([disabled]) {\n        color: var(--paper-icon-button-disabled-text, --disabled-text-color);\n        pointer-events: none;\n        cursor: auto;\n\n        @apply(--paper-icon-button-disabled);\n      }\n\n      :host(:hover) {\n        @apply(--paper-icon-button-hover);\n      }\n\n      iron-icon {\n        --iron-icon-width: 100%;\n        --iron-icon-height: 100%;\n      }\n    </style>\n\n    <iron-icon id=\"icon\" src=\"[[src]]\" icon=\"[[icon]]\" alt$=\"[[alt]]\"></iron-icon>\n  </template>\n\n  <script>//~~WEBPATH~~/paper-icon-button/paper-icon-button.html.js\nPolymer({is:\"paper-icon-button\",hostAttributes:{role:\"button\",tabindex:\"0\"},behaviors:[Polymer.PaperInkyFocusBehavior],properties:{src:{type:String},icon:{type:String},alt:{type:String,observer:\"_altChanged\"}},_altChanged:function(a,b){var c=this.getAttribute(\"aria-label\");c&&b!=c||this.setAttribute(\"aria-label\",a)}});\n</script>\n</dom-module>\n\n\n\n\n\n\n\n<dom-module id=\"paper-menu-shared-styles\">\r\n  <template>\r\n    <style>\r\n      /* need a wrapper element to make this higher specificity than the :host rule in paper-item */\r\n      .selectable-content > ::content > .iron-selected {\r\n        font-weight: bold;\r\n\r\n        @apply(--paper-menu-selected-item);\r\n      }\r\n\r\n      .selectable-content > ::content > [disabled] {\r\n        color: var(--paper-menu-disabled-color, --disabled-text-color);\r\n      }\r\n\r\n      .selectable-content > ::content > *:focus {\r\n        position: relative;\r\n        outline: 0;\r\n\r\n        @apply(--paper-menu-focused-item);\r\n      }\r\n\r\n      .selectable-content > ::content > *:focus:after {\r\n        @apply(--layout-fit);\r\n        background: currentColor;\r\n        opacity: var(--dark-divider-opacity);\r\n        content: '';\r\n        pointer-events: none;\r\n\r\n        @apply(--paper-menu-focused-item-after);\r\n      }\r\n\r\n      .selectable-content > ::content > *[colored]:focus:after {\r\n        opacity: 0.26;\r\n      }\r\n    </style>\r\n  </template>\r\n</dom-module>\r\n\n\n\n\n<dom-module id=\"paper-menu\">\n  <template>\n    <style include=\"paper-menu-shared-styles\"></style>\n    <style>\n      :host {\n        display: block;\n        padding: 8px 0;\n\n        background: var(--paper-menu-background-color, --primary-background-color);\n        color: var(--paper-menu-color, --primary-text-color);\n\n        @apply(--paper-menu);\n      }\n    </style>\n\n    <div class=\"selectable-content\">\n      <content></content>\n    </div>\n  </template>\n\n  <script>//~~WEBPATH~~/paper-menu/paper-menu.html.js\nPolymer({is:\"paper-menu\",behaviors:[Polymer.IronMenuBehavior]});\n</script>\n</dom-module>\n\n\n\n\n\n\n\n\n\n<dom-module id=\"iron-collapse\">\n\n  <template>\n\n    <style>\n      :host {\n        display: block;\n        transition-duration: var(--iron-collapse-transition-duration, 300ms);\n        /* Safari 10 needs this property prefixed to correctly apply the custom property */\n        -webkit-transition-duration: var(--iron-collapse-transition-duration, 300ms);\n        overflow: visible;\n      }\n\n      :host(.iron-collapse-closed) {\n        display: none;\n      }\n\n      :host(:not(.iron-collapse-opened)) {\n        overflow: hidden;\n      }\n    </style>\n\n    <slot></slot>\n\n  </template>\n\n</dom-module>\n\n<script>//~~WEBPATH~~/iron-collapse/iron-collapse.html.js\nPolymer({is:\"iron-collapse\",behaviors:[Polymer.IronResizableBehavior],properties:{horizontal:{type:Boolean,value:!1,observer:\"_horizontalChanged\"},opened:{type:Boolean,value:!1,notify:!0,observer:\"_openedChanged\"},transitioning:{type:Boolean,notify:!0,readOnly:!0},noAnimation:{type:Boolean},_desiredSize:{type:String,value:\"\"}},get dimension(){return this.horizontal?\"width\":\"height\"},get _dimensionMax(){return this.horizontal?\"maxWidth\":\"maxHeight\"},get _dimensionMaxCss(){return this.horizontal?\"max-width\":\n\"max-height\"},hostAttributes:{role:\"group\",\"aria-hidden\":\"true\",\"aria-expanded\":\"false\"},listeners:{transitionend:\"_onTransitionEnd\"},toggle:function(){this.opened=!this.opened},show:function(){this.opened=!0},hide:function(){this.opened=!1},updateSize:function(a,b){a=\"auto\"===a?\"\":a;b=b&&!this.noAnimation&&this.isAttached&&this._desiredSize!==a;this._desiredSize=a;this._updateTransition(!1);b&&(b=this._calcSize(),\"\"===a&&(this.style[this._dimensionMax]=\"\",a=this._calcSize()),this.style[this._dimensionMax]=\nb,this.scrollTop=this.scrollTop,this._updateTransition(!0),b=a!==b);this.style[this._dimensionMax]=a;b||this._transitionEnd()},enableTransition:function(a){Polymer.Base._warn(\"`enableTransition()` is deprecated, use `noAnimation` instead.\");this.noAnimation=!a},_updateTransition:function(a){this.style.transitionDuration=a&&!this.noAnimation?\"\":\"0s\"},_horizontalChanged:function(){this.style.transitionProperty=this._dimensionMaxCss;this.style[\"maxWidth\"===this._dimensionMax?\"maxHeight\":\"maxWidth\"]=\n\"\";this.updateSize(this.opened?\"auto\":\"0px\",!1)},_openedChanged:function(){this.setAttribute(\"aria-expanded\",this.opened);this.setAttribute(\"aria-hidden\",!this.opened);this._setTransitioning(!0);this.toggleClass(\"iron-collapse-closed\",!1);this.toggleClass(\"iron-collapse-opened\",!1);this.updateSize(this.opened?\"auto\":\"0px\",!0);this.opened&&this.focus()},_transitionEnd:function(){this.style[this._dimensionMax]=this._desiredSize;this.toggleClass(\"iron-collapse-closed\",!this.opened);this.toggleClass(\"iron-collapse-opened\",\nthis.opened);this._updateTransition(!1);this.notifyResize();this._setTransitioning(!1)},_onTransitionEnd:function(a){Polymer.dom(a).rootTarget===this&&this._transitionEnd()},_calcSize:function(){return this.getBoundingClientRect()[this.dimension]+\"px\"}});\n</script>\n\n\n\n\n\n\n\n\n<dom-module id=\"paper-submenu\">\n  <template>\n    <style include=\"paper-menu-shared-styles\"></style>\n\n    <div class=\"selectable-content\" on-tap=\"_onTap\">\n      <content id=\"trigger\" select=\".menu-trigger\"></content>\n    </div>\n    <iron-collapse id=\"collapse\" opened=\"{{opened}}\">\n      <content id=\"content\" select=\".menu-content\"></content>\n    </iron-collapse>\n  </template>\n\n  <script>//~~WEBPATH~~/paper-menu/paper-submenu.html.js\nPolymer({is:\"paper-submenu\",properties:{opened:{type:Boolean,value:!1,notify:!0,observer:\"_openedChanged\"}},behaviors:[Polymer.IronControlState],listeners:{focus:\"_onFocus\"},get __parent(){return Polymer.dom(this).parentNode},get __trigger(){return Polymer.dom(this.$.trigger).getDistributedNodes()[0]},get __content(){return Polymer.dom(this.$.content).getDistributedNodes()[0]},attached:function(){this.listen(this.__parent,\"iron-activate\",\"_onParentIronActivate\")},dettached:function(){this.unlisten(this.__parent,\n\"iron-activate\",\"_onParentIronActivate\")},open:function(){this.disabled||this._active||(this.$.collapse.show(),this._active=!0,this.__trigger&&this.__trigger.classList.add(\"iron-selected\"),this.__content&&this.__content.focus())},close:function(){this._active&&(this.$.collapse.hide(),this._active=!1,this.__trigger&&this.__trigger.classList.remove(\"iron-selected\"))},toggle:function(){this._active?this.close():this.open()},_onTap:function(){this.disabled||this.toggle()},_openedChanged:function(a,b){a?\nthis.fire(\"paper-submenu-open\"):null!=b&&this.fire(\"paper-submenu-close\")},_onParentIronActivate:function(a){var b=this.__parent;Polymer.dom(a).localTarget===b&&(a.detail.item===this||b.multi||this.close())},_disabledChanged:function(a){Polymer.IronControlState._disabledChanged.apply(this,arguments);a&&this._active&&this.close()},_onFocus:function(){this.__trigger&&this.__trigger.focus()}});\n</script>\n</dom-module>\n\n\n\n\n\n\n\n<dom-module id=\"paper-radio-button\">\n  <template strip-whitespace>\n    <style>\n      :host {\n        display: inline-block;\n        white-space: nowrap;\n        cursor: pointer;\n        @apply(--paper-font-common-base);\n      }\n\n      :host(:focus) {\n        outline: none;\n      }\n\n      #radioContainer {\n        display: inline-block;\n        position: relative;\n        width: 16px;\n        height: 16px;\n        vertical-align: middle;\n      }\n\n      #ink {\n        position: absolute;\n        top: -16px;\n        left: -16px;\n        width: 48px;\n        height: 48px;\n        color: var(--paper-radio-button-unchecked-ink-color, --primary-text-color);\n        opacity: 0.6;\n        pointer-events: none;\n      }\n\n      :host-context([dir=\"rtl\"]) #ink {\n        right: -15px;\n        left: auto;\n      }\n\n      #ink[checked] {\n        color: var(--paper-radio-button-checked-ink-color, --primary-color);\n      }\n\n      #offRadio {\n        position: absolute;\n        box-sizing: content-box;\n        top: 0px;\n        left: 0px;\n        right: 0px;\n        width: 12px;\n        height: 12px;\n        border-radius: 50%;\n        border: solid 2px;\n        background-color: var(--paper-radio-button-unchecked-background-color, transparent);\n        border-color: var(--paper-radio-button-unchecked-color, --primary-text-color);\n        transition: border-color 0.28s;\n      }\n\n      #onRadio {\n        position: absolute;\n        box-sizing: content-box;\n        top: 4px;\n        left: 4px;\n        right: 4px;\n        width: 8px;\n        height: 8px;\n        border-radius: 50%;\n        background-color: var(--paper-radio-button-checked-color, --primary-color);\n        -webkit-transform: scale(0);\n        transform: scale(0);\n        transition: -webkit-transform ease 0.28s;\n        transition: transform ease 0.28s;\n        will-change: transform;\n      }\n\n      :host([checked]) #offRadio {\n        border-color: var(--paper-radio-button-checked-color, --primary-color);\n      }\n\n      :host([checked]) #onRadio {\n        -webkit-transform: scale(1);\n        transform: scale(1);\n      }\n\n      #radioLabel {\n        position: relative;\n        display: inline-block;\n        vertical-align: middle;\n        margin-left: var(--paper-radio-button-label-spacing, 10px);\n        white-space: normal;\n        color: var(--paper-radio-button-label-color, --primary-text-color);\n      }\n\n      :host-context([dir=\"rtl\"]) #radioLabel {\n        margin-left: 0px;\n        margin-right: var(--paper-radio-button-label-spacing, 10px);\n      }\n\n      #radioLabel[hidden] {\n        display: none;\n      }\n\n      /* disabled state */\n\n      :host([disabled]) #offRadio {\n        border-color: var(--paper-radio-button-unchecked-color, --primary-text-color);\n        opacity: 0.5;\n      }\n\n      :host([disabled][checked]) #onRadio {\n        background-color: var(--paper-radio-button-unchecked-color, --primary-text-color);\n        opacity: 0.5;\n      }\n\n      :host([disabled]) #radioLabel {\n        /* slightly darker than the button, so that it's readable */\n        opacity: 0.65;\n      }\n    </style>\n\n    <div id=\"radioContainer\">\n      <div id=\"offRadio\"></div>\n      <div id=\"onRadio\"></div>\n    </div>\n\n    <div id=\"radioLabel\"><content></content></div>\n  </template>\n\n  <script>//~~WEBPATH~~/paper-radio-button/paper-radio-button.html.js\nPolymer({is:\"paper-radio-button\",behaviors:[Polymer.PaperCheckedElementBehavior],hostAttributes:{role:\"radio\",\"aria-checked\":!1,tabindex:0},properties:{ariaActiveAttribute:{type:String,value:\"aria-checked\"}},ready:function(){this._rippleContainer=this.$.radioContainer}});\n</script>\n</dom-module>\n\n\n\n\n\n\n\n\n<dom-module id=\"paper-radio-group\">\n  <template>\n    <style>\n      :host {\n        display: inline-block;\n      }\n\n      :host ::content > * {\n        padding: 12px;\n      }\n    </style>\n\n    <content id=\"items\" select=\"*\"></content>\n  </template>\n</dom-module>\n\n<script>//~~WEBPATH~~/paper-radio-group/paper-radio-group.html.js\nPolymer({is:\"paper-radio-group\",behaviors:[Polymer.IronA11yKeysBehavior,Polymer.IronSelectableBehavior],hostAttributes:{role:\"radiogroup\",tabindex:0},properties:{attrForSelected:{type:String,value:\"name\"},selectedAttribute:{type:String,value:\"checked\"},selectable:{type:String,value:\"paper-radio-button\"},allowEmptySelection:{type:Boolean,value:!1}},keyBindings:{\"left up\":\"selectPrevious\",\"right down\":\"selectNext\"},select:function(a){if(this.selected){var b=this._valueToItem(this.selected);if(this.selected==\na)if(this.allowEmptySelection)a=\"\";else{b&&(b.checked=!0);return}b&&(b.checked=!1)}Polymer.IronSelectableBehavior.select.apply(this,[a]);this.fire(\"paper-radio-group-changed\")},selectPrevious:function(){var a=this.items.length,b=Number(this._valueToIndex(this.selected));do b=(b-1+a)%a;while(this.items[b].disabled);this._itemActivate(this._indexToValue(b),this.items[b])},selectNext:function(){var a=this.items.length,b=Number(this._valueToIndex(this.selected));do b=(b+1+a)%a;while(this.items[b].disabled);\nthis._itemActivate(this._indexToValue(b),this.items[b])}});\n</script>\n\n\n\n\n\n\n\n<script>//~~WEBPATH~~/iron-range-behavior/iron-range-behavior.html.js\nPolymer.IronRangeBehavior={properties:{value:{type:Number,value:0,notify:!0,reflectToAttribute:!0},min:{type:Number,value:0,notify:!0},max:{type:Number,value:100,notify:!0},step:{type:Number,value:1,notify:!0},ratio:{type:Number,value:0,readOnly:!0,notify:!0}},observers:[\"_update(value, min, max, step)\"],_calcRatio:function(a){return(this._clampValue(a)-this.min)/(this.max-this.min)},_clampValue:function(a){return Math.min(this.max,Math.max(this.min,this._calcStep(a)))},_calcStep:function(a){a=parseFloat(a);\nreturn this.step?(Math.round((a+this.min)/this.step)-this.min/this.step)/(1/this.step):a},_validateValue:function(){var a=this._clampValue(this.value);this.value=this.oldValue=isNaN(a)?this.oldValue:a;return this.value!==a},_update:function(){this._validateValue();this._setRatio(100*this._calcRatio(this.value))}};\n</script>\n\n\n\n\n\n\n\n\n\n\n<dom-module id=\"paper-progress\">\n  <template>\n    <style>\n      :host {\n        display: block;\n        width: 200px;\n        position: relative;\n        overflow: hidden;\n      }\n\n      #progressContainer {\n        position: relative;\n      }\n\n      #progressContainer,\n      /* the stripe for the indeterminate animation*/\n      .indeterminate::after {\n        height: var(--paper-progress-height, 4px);\n      }\n\n      #primaryProgress,\n      #secondaryProgress,\n      .indeterminate::after {\n        @apply(--layout-fit);\n      }\n\n      #progressContainer,\n      .indeterminate::after {\n        background: var(--paper-progress-container-color, --google-grey-300);\n      }\n\n      :host(.transiting) #primaryProgress,\n      :host(.transiting) #secondaryProgress {\n        -webkit-transition-property: -webkit-transform;\n        transition-property: transform;\n\n        /* Duration */\n        -webkit-transition-duration: var(--paper-progress-transition-duration, 0.08s);\n        transition-duration: var(--paper-progress-transition-duration, 0.08s);\n\n        /* Timing function */\n        -webkit-transition-timing-function: var(--paper-progress-transition-timing-function, ease);\n        transition-timing-function: var(--paper-progress-transition-timing-function, ease);\n\n        /* Delay */\n        -webkit-transition-delay: var(--paper-progress-transition-delay, 0s);\n        transition-delay: var(--paper-progress-transition-delay, 0s);\n      }\n\n      #primaryProgress,\n      #secondaryProgress {\n        @apply(--layout-fit);\n        -webkit-transform-origin: left center;\n        transform-origin: left center;\n        -webkit-transform: scaleX(0);\n        transform: scaleX(0);\n        will-change: transform;\n      }\n\n      #primaryProgress {\n        background: var(--paper-progress-active-color, --google-green-500);\n      }\n\n      #secondaryProgress {\n        background: var(--paper-progress-secondary-color, --google-green-100);\n      }\n\n      :host([disabled]) #primaryProgress {\n        background: var(--paper-progress-disabled-active-color, --google-grey-500);\n      }\n\n      :host([disabled]) #secondaryProgress {\n        background: var(--paper-progress-disabled-secondary-color, --google-grey-300);\n      }\n\n      :host(:not([disabled])) #primaryProgress.indeterminate {\n        -webkit-transform-origin: right center;\n        transform-origin: right center;\n        -webkit-animation: indeterminate-bar 2s linear infinite;\n        animation: indeterminate-bar 2s linear infinite;\n      }\n\n      :host(:not([disabled])) #primaryProgress.indeterminate::after {\n        content: \"\";\n        -webkit-transform-origin: center center;\n        transform-origin: center center;\n\n        -webkit-animation: indeterminate-splitter 2s linear infinite;\n        animation: indeterminate-splitter 2s linear infinite;\n      }\n\n      @-webkit-keyframes indeterminate-bar {\n        0% {\n          -webkit-transform: scaleX(1) translateX(-100%);\n        }\n        50% {\n          -webkit-transform: scaleX(1) translateX(0%);\n        }\n        75% {\n          -webkit-transform: scaleX(1) translateX(0%);\n          -webkit-animation-timing-function: cubic-bezier(.28,.62,.37,.91);\n        }\n        100% {\n          -webkit-transform: scaleX(0) translateX(0%);\n        }\n      }\n\n      @-webkit-keyframes indeterminate-splitter {\n        0% {\n          -webkit-transform: scaleX(.75) translateX(-125%);\n        }\n        30% {\n          -webkit-transform: scaleX(.75) translateX(-125%);\n          -webkit-animation-timing-function: cubic-bezier(.42,0,.6,.8);\n        }\n        90% {\n          -webkit-transform: scaleX(.75) translateX(125%);\n        }\n        100% {\n          -webkit-transform: scaleX(.75) translateX(125%);\n        }\n      }\n\n      @keyframes indeterminate-bar {\n        0% {\n          transform: scaleX(1) translateX(-100%);\n        }\n        50% {\n          transform: scaleX(1) translateX(0%);\n        }\n        75% {\n          transform: scaleX(1) translateX(0%);\n          animation-timing-function: cubic-bezier(.28,.62,.37,.91);\n        }\n        100% {\n          transform: scaleX(0) translateX(0%);\n        }\n      }\n\n      @keyframes indeterminate-splitter {\n        0% {\n          transform: scaleX(.75) translateX(-125%);\n        }\n        30% {\n          transform: scaleX(.75) translateX(-125%);\n          animation-timing-function: cubic-bezier(.42,0,.6,.8);\n        }\n        90% {\n          transform: scaleX(.75) translateX(125%);\n        }\n        100% {\n          transform: scaleX(.75) translateX(125%);\n        }\n      }\n    </style>\n\n    <div id=\"progressContainer\">\n      <div id=\"secondaryProgress\" hidden$=\"[[_hideSecondaryProgress(secondaryRatio)]]\"></div>\n      <div id=\"primaryProgress\"></div>\n    </div>\n  </template>\n</dom-module>\n\n<script>//~~WEBPATH~~/paper-progress/paper-progress.html.js\nPolymer({is:\"paper-progress\",behaviors:[Polymer.IronRangeBehavior],properties:{secondaryProgress:{type:Number,value:0},secondaryRatio:{type:Number,value:0,readOnly:!0},indeterminate:{type:Boolean,value:!1,observer:\"_toggleIndeterminate\"},disabled:{type:Boolean,value:!1,reflectToAttribute:!0,observer:\"_disabledChanged\"}},observers:[\"_progressChanged(secondaryProgress, value, min, max)\"],hostAttributes:{role:\"progressbar\"},_toggleIndeterminate:function(a){this.toggleClass(\"indeterminate\",a,this.$.primaryProgress)},\n_transformProgress:function(a,b){a.style.transform=a.style.webkitTransform=\"scaleX(\"+b/100+\")\"},_mainRatioChanged:function(a){this._transformProgress(this.$.primaryProgress,a)},_progressChanged:function(a,b,c,d){a=this._clampValue(a);b=this._clampValue(b);var e=100*this._calcRatio(a),f=100*this._calcRatio(b);this._setSecondaryRatio(e);this._transformProgress(this.$.secondaryProgress,e);this._transformProgress(this.$.primaryProgress,f);this.secondaryProgress=a;this.setAttribute(\"aria-valuenow\",b);\nthis.setAttribute(\"aria-valuemin\",c);this.setAttribute(\"aria-valuemax\",d)},_disabledChanged:function(a){this.setAttribute(\"aria-disabled\",a?\"true\":\"false\")},_hideSecondaryProgress:function(a){return 0===a}});\n</script>\n\n\n\n\n\n<dom-module id=\"paper-slider\">\n  <template strip-whitespace>\n    <style>\n      :host {\n        @apply(--layout);\n        @apply(--layout-justified);\n        @apply(--layout-center);\n        width: 200px;\n        cursor: default;\n        -webkit-user-select: none;\n        -moz-user-select: none;\n        -ms-user-select: none;\n        user-select: none;\n        -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n        --paper-progress-active-color: var(--paper-slider-active-color, --google-blue-700);\n        --paper-progress-secondary-color: var(--paper-slider-secondary-color, --google-blue-300);\n        --paper-progress-disabled-active-color: var(--paper-slider-disabled-active-color, --paper-grey-400);\n        --paper-progress-disabled-secondary-color: var(--paper-slider-disabled-secondary-color, --paper-grey-400);\n        --calculated-paper-slider-height: var(--paper-slider-height, 2px);\n      }\n\n      /* focus shows the ripple */\n      :host(:focus) {\n        outline: none;\n      }\n\n      #sliderContainer {\n        position: relative;\n        width: 100%;\n        height: calc(30px + var(--calculated-paper-slider-height));\n        margin-left: calc(15px + var(--calculated-paper-slider-height)/2);\n        margin-right: calc(15px + var(--calculated-paper-slider-height)/2);\n      }\n\n      #sliderContainer:focus {\n        outline: 0;\n      }\n\n      #sliderContainer.editable {\n        margin-top: 12px;\n        margin-bottom: 12px;\n      }\n\n      .bar-container {\n        position: absolute;\n        top: 0;\n        bottom: 0;\n        left: 0;\n        right: 0;\n        overflow: hidden;\n      }\n\n      .ring > .bar-container {\n        left: calc(5px + var(--calculated-paper-slider-height)/2);\n        transition: left 0.18s ease;\n      }\n\n      .ring.expand.dragging > .bar-container {\n        transition: none;\n      }\n\n      .ring.expand:not(.pin) > .bar-container {\n        left: calc(8px + var(--calculated-paper-slider-height)/2);\n      }\n\n      #sliderBar {\n        padding: 15px 0;\n        width: 100%;\n        background-color: var(--paper-slider-bar-color, transparent);\n        --paper-progress-container-color: var(--paper-slider-container-color, --paper-grey-400);\n        --paper-progress-height: var(--calculated-paper-slider-height);\n      }\n\n      .slider-markers {\n        position: absolute;\n        top: calc(14px + var(--paper-slider-height,2px)/2);\n        height: var(--calculated-paper-slider-height);\n        left: 0;\n        right: -1px;\n        box-sizing: border-box;\n        pointer-events: none;\n        @apply(--layout-horizontal);\n      }\n\n      .slider-marker {\n        @apply(--layout-flex);\n      }\n      .slider-markers::after,\n      .slider-marker::after {\n        content: \"\";\n        display: block;\n        margin-left: -1px;\n        width: 2px;\n        height: var(--calculated-paper-slider-height);\n        border-radius: 50%;\n        background-color: var(--paper-slider-markers-color, #000);\n      }\n\n      .slider-knob {\n        position: absolute;\n        left: 0;\n        top: 0;\n        margin-left: calc(-15px - var(--calculated-paper-slider-height)/2);\n        width: calc(30px + var(--calculated-paper-slider-height));\n        height: calc(30px + var(--calculated-paper-slider-height));\n      }\n\n      .transiting > .slider-knob {\n        transition: left 0.08s ease;\n      }\n\n      .slider-knob:focus {\n        outline: none;\n      }\n\n      .slider-knob.dragging {\n        transition: none;\n      }\n\n      .snaps > .slider-knob.dragging {\n        transition: -webkit-transform 0.08s ease;\n        transition: transform 0.08s ease;\n      }\n\n      .slider-knob-inner {\n        margin: 10px;\n        width: calc(100% - 20px);\n        height: calc(100% - 20px);\n        background-color: var(--paper-slider-knob-color, --google-blue-700);\n        border: 2px solid var(--paper-slider-knob-color, --google-blue-700);\n        border-radius: 50%;\n\n        -moz-box-sizing: border-box;\n        box-sizing: border-box;\n\n        transition-property: -webkit-transform, background-color, border;\n        transition-property: transform, background-color, border;\n        transition-duration: 0.18s;\n        transition-timing-function: ease;\n      }\n\n      .expand:not(.pin) > .slider-knob > .slider-knob-inner {\n        -webkit-transform: scale(1.5);\n        transform: scale(1.5);\n      }\n\n      .ring > .slider-knob > .slider-knob-inner {\n        background-color: var(--paper-slider-knob-start-color, transparent);\n        border: 2px solid var(--paper-slider-knob-start-border-color, --paper-grey-400);\n      }\n\n      .slider-knob-inner::before {\n        background-color: var(--paper-slider-pin-color, --google-blue-700);\n      }\n\n      .pin > .slider-knob > .slider-knob-inner::before {\n        content: \"\";\n        position: absolute;\n        top: 0;\n        left: 50%;\n        margin-left: -13px;\n        width: 26px;\n        height: 26px;\n        border-radius: 50% 50% 50% 0;\n\n        -webkit-transform: rotate(-45deg) scale(0) translate(0);\n        transform: rotate(-45deg) scale(0) translate(0);\n      }\n\n      .slider-knob-inner::before,\n      .slider-knob-inner::after {\n        transition: -webkit-transform .18s ease, background-color .18s ease;\n        transition: transform .18s ease, background-color .18s ease;\n      }\n\n      .pin.ring > .slider-knob > .slider-knob-inner::before {\n        background-color: var(--paper-slider-pin-start-color, --paper-grey-400);\n      }\n\n      .pin.expand > .slider-knob > .slider-knob-inner::before {\n        -webkit-transform: rotate(-45deg) scale(1) translate(17px, -17px);\n        transform: rotate(-45deg) scale(1) translate(17px, -17px);\n      }\n\n      .pin > .slider-knob > .slider-knob-inner::after {\n        content: attr(value);\n        position: absolute;\n        top: 0;\n        left: 50%;\n        margin-left: -16px;\n        width: 32px;\n        height: 26px;\n        text-align: center;\n        color: var(--paper-slider-font-color, #fff);\n        font-size: 10px;\n\n        -webkit-transform: scale(0) translate(0);\n        transform: scale(0) translate(0);\n      }\n\n      .pin.expand > .slider-knob > .slider-knob-inner::after {\n        -webkit-transform: scale(1) translate(0, -17px);\n        transform: scale(1) translate(0, -17px);\n      }\n\n      /* paper-input */\n      .slider-input {\n        width: 50px;\n        overflow: hidden;\n        --paper-input-container-input: {\n          text-align: center;\n        };\n        @apply(--paper-slider-input);\n      }\n\n      /* disabled state */\n      #sliderContainer.disabled {\n        pointer-events: none;\n      }\n\n      .disabled > .slider-knob > .slider-knob-inner {\n        background-color: var(--paper-slider-disabled-knob-color, --paper-grey-400);\n        border: 2px solid var(--paper-slider-disabled-knob-color, --paper-grey-400);\n        -webkit-transform: scale3d(0.75, 0.75, 1);\n        transform: scale3d(0.75, 0.75, 1);\n      }\n\n      .disabled.ring > .slider-knob > .slider-knob-inner {\n        background-color: var(--paper-slider-knob-start-color, transparent);\n        border: 2px solid var(--paper-slider-knob-start-border-color, --paper-grey-400);\n      }\n\n      paper-ripple {\n        color: var(--paper-slider-knob-color, --google-blue-700);\n      }\n    </style>\n\n    <div id=\"sliderContainer\" class$=\"[[_getClassNames(disabled, pin, snaps, immediateValue, min, expand, dragging, transiting, editable)]]\">\n      <div class=\"bar-container\">\n        <paper-progress disabled$=\"[[disabled]]\" id=\"sliderBar\" aria-hidden=\"true\" min=\"[[min]]\" max=\"[[max]]\" step=\"[[step]]\" value=\"[[immediateValue]]\" secondary-progress=\"[[secondaryProgress]]\" on-down=\"_bardown\" on-up=\"_resetKnob\" on-track=\"_onTrack\">\n        </paper-progress>\n      </div>\n\n      <template is=\"dom-if\" if=\"[[snaps]]\">\n        <div class=\"slider-markers\">\n          <template is=\"dom-repeat\" items=\"[[markers]]\">\n            <div class=\"slider-marker\"></div>\n          </template>\n        </div>\n      </template>\n\n      <div id=\"sliderKnob\" class=\"slider-knob\" on-down=\"_knobdown\" on-up=\"_resetKnob\" on-track=\"_onTrack\" on-transitionend=\"_knobTransitionEnd\">\n          <div class=\"slider-knob-inner\" value$=\"[[immediateValue]]\"></div>\n      </div>\n    </div>\n\n    <template is=\"dom-if\" if=\"[[editable]]\">\n      <paper-input id=\"input\" type=\"number\" step=\"[[step]]\" min=\"[[min]]\" max=\"[[max]]\" class=\"slider-input\" disabled$=\"[[disabled]]\" value=\"[[immediateValue]]\" on-change=\"_changeValue\" on-keydown=\"_inputKeyDown\" no-label-float>\n      </paper-input>\n    </template>\n  </template>\n\n  <script>//~~WEBPATH~~/paper-slider/paper-slider.html.js\nPolymer({is:\"paper-slider\",behaviors:[Polymer.IronA11yKeysBehavior,Polymer.IronFormElementBehavior,Polymer.PaperInkyFocusBehavior,Polymer.IronRangeBehavior],properties:{snaps:{type:Boolean,value:!1,notify:!0},pin:{type:Boolean,value:!1,notify:!0},secondaryProgress:{type:Number,value:0,notify:!0,observer:\"_secondaryProgressChanged\"},editable:{type:Boolean,value:!1},immediateValue:{type:Number,value:0,readOnly:!0,notify:!0},maxMarkers:{type:Number,value:0,notify:!0},expand:{type:Boolean,value:!1,readOnly:!0},\ndragging:{type:Boolean,value:!1,readOnly:!0},transiting:{type:Boolean,value:!1,readOnly:!0},markers:{type:Array,readOnly:!0,value:function(){return[]}}},observers:[\"_updateKnob(value, min, max, snaps, step)\",\"_valueChanged(value)\",\"_immediateValueChanged(immediateValue)\",\"_updateMarkers(maxMarkers, min, max, snaps)\"],hostAttributes:{role:\"slider\",tabindex:0},keyBindings:{\"left down pagedown home\":\"_decrementKey\",\"right up pageup end\":\"_incrementKey\"},increment:function(){this.value=this._clampValue(this.value+\nthis.step)},decrement:function(){this.value=this._clampValue(this.value-this.step)},_updateKnob:function(a,b,c){this.setAttribute(\"aria-valuemin\",b);this.setAttribute(\"aria-valuemax\",c);this.setAttribute(\"aria-valuenow\",a);this._positionKnob(this._calcRatio(a))},_valueChanged:function(){this.fire(\"value-change\")},_immediateValueChanged:function(){this.dragging?this.fire(\"immediate-value-change\"):this.value=this.immediateValue},_secondaryProgressChanged:function(){this.secondaryProgress=this._clampValue(this.secondaryProgress)},\n_expandKnob:function(){this._setExpand(!0)},_resetKnob:function(){this.cancelDebouncer(\"expandKnob\");this._setExpand(!1)},_positionKnob:function(a){this._setImmediateValue(this._calcStep(this._calcKnobPosition(a)));this._setRatio(this._calcRatio(this.immediateValue));this.$.sliderKnob.style.left=100*this.ratio+\"%\";this.dragging&&(this._knobstartx=this.ratio*this._w,this.translate3d(0,0,0,this.$.sliderKnob))},_calcKnobPosition:function(a){return(this.max-this.min)*a+this.min},_onTrack:function(a){a.stopPropagation();\nswitch(a.detail.state){case \"start\":this._trackStart(a);break;case \"track\":this._trackX(a);break;case \"end\":this._trackEnd()}},_trackStart:function(){this._w=this.$.sliderBar.offsetWidth;this._knobstartx=this._startx=this._x=this.ratio*this._w;this._minx=-this._startx;this._maxx=this._w-this._startx;this.$.sliderKnob.classList.add(\"dragging\");this._setDragging(!0)},_trackX:function(a){this.dragging||this._trackStart(a);this._x=this._startx+Math.min(this._maxx,Math.max(this._minx,a.detail.dx));this._setImmediateValue(this._calcStep(this._calcKnobPosition(this._x/\nthis._w)));this.translate3d(this._calcRatio(this.immediateValue)*this._w-this._knobstartx+\"px\",0,0,this.$.sliderKnob)},_trackEnd:function(){var a=this.$.sliderKnob.style;this.$.sliderKnob.classList.remove(\"dragging\");this._setDragging(!1);this._resetKnob();this.value=this.immediateValue;a.transform=a.webkitTransform=\"\";this.fire(\"change\")},_knobdown:function(a){this._expandKnob();a.preventDefault();this.focus()},_bardown:function(a){this._w=this.$.sliderBar.offsetWidth;var b=this.$.sliderBar.getBoundingClientRect(),\nb=(a.detail.x-b.left)/this._w,c=this.ratio;this._setTransiting(!0);this._positionKnob(b);this.debounce(\"expandKnob\",this._expandKnob,60);c===this.ratio&&this._setTransiting(!1);this.async(function(){this.fire(\"change\")});a.preventDefault();this.focus()},_knobTransitionEnd:function(a){a.target===this.$.sliderKnob&&this._setTransiting(!1)},_updateMarkers:function(a,b,c,d){d||this._setMarkers([]);b=Math.round((c-b)/this.step);b>a&&(b=a);if(0>b||!isFinite(b))b=0;this._setMarkers(Array(b))},_mergeClasses:function(a){return Object.keys(a).filter(function(b){return a[b]}).join(\" \")},\n_getClassNames:function(){return this._mergeClasses({disabled:this.disabled,pin:this.pin,snaps:this.snaps,ring:this.immediateValue<=this.min,expand:this.expand,dragging:this.dragging,transiting:this.transiting,editable:this.editable})},_incrementKey:function(a){this.disabled||(\"end\"===a.detail.key?this.value=this.max:this.increment(),this.fire(\"change\"),a.preventDefault())},_decrementKey:function(a){this.disabled||(\"home\"===a.detail.key?this.value=this.min:this.decrement(),this.fire(\"change\"),a.preventDefault())},\n_changeValue:function(a){this.value=a.target.value;this.fire(\"change\")},_inputKeyDown:function(a){a.stopPropagation()},_createRipple:function(){this._rippleContainer=this.$.sliderKnob;return Polymer.PaperInkyFocusBehaviorImpl._createRipple.call(this)},_focusedChanged:function(a){a&&this.ensureRipple();this.hasRipple()&&(this._ripple.style.display=a?\"\":\"none\",this._ripple.holdDown=a)}});\n</script>\n</dom-module>\n\n\n\n\n\n\n\n\n<dom-module id=\"paper-tooltip\">\n  <template>\n    <style>\n      :host {\n        display: block;\n        position: absolute;\n        outline: none;\n        z-index: 1002;\n        -moz-user-select: none;\n        -ms-user-select: none;\n        -webkit-user-select: none;\n        user-select: none;\n        cursor: default;\n      }\n\n      #tooltip {\n        display: block;\n        outline: none;\n        @apply(--paper-font-common-base);\n        font-size: 10px;\n        line-height: 1;\n\n        background-color: var(--paper-tooltip-background, #616161);\n        opacity: var(--paper-tooltip-opacity, 0.9);\n        color: var(--paper-tooltip-text-color, white);\n\n        padding: 8px;\n        border-radius: 2px;\n\n        @apply(--paper-tooltip);\n      }\n\n      /* Thanks IE 10. */\n      .hidden {\n        display: none !important;\n      }\n    </style>\n\n    <div id=\"tooltip\" class=\"hidden\">\n      <content></content>\n    </div>\n  </template>\n\n  <script>//~~WEBPATH~~/paper-tooltip/paper-tooltip.html.js\nPolymer({is:\"paper-tooltip\",hostAttributes:{role:\"tooltip\",tabindex:-1},behaviors:[Polymer.NeonAnimationRunnerBehavior],properties:{for:{type:String,observer:\"_forChanged\"},manualMode:{type:Boolean,value:!1},position:{type:String,value:\"bottom\"},fitToVisibleBounds:{type:Boolean,value:!1},offset:{type:Number,value:14},marginTop:{type:Number,value:14},animationDelay:{type:Number,value:500},animationConfig:{type:Object,value:function(){return{entry:[{name:\"fade-in-animation\",node:this,timing:{delay:0}}],\nexit:[{name:\"fade-out-animation\",node:this}]}}},_showing:{type:Boolean,value:!1}},listeners:{\"neon-animation-finish\":\"_onAnimationFinish\",mouseenter:\"hide\"},get target(){var a=Polymer.dom(this).parentNode,b=Polymer.dom(this).getOwnerRoot();return this.for?Polymer.dom(b).querySelector(\"#\"+this.for):a.nodeType==Node.DOCUMENT_FRAGMENT_NODE?b.host:a},attached:function(){this._target=this.target;this.manualMode||(this.listen(this._target,\"mouseenter\",\"show\"),this.listen(this._target,\"focus\",\"show\"),this.listen(this._target,\n\"mouseleave\",\"hide\"),this.listen(this._target,\"blur\",\"hide\"),this.listen(this._target,\"tap\",\"hide\"))},detached:function(){this._target&&!this.manualMode&&(this.unlisten(this._target,\"mouseenter\",\"show\"),this.unlisten(this._target,\"focus\",\"show\"),this.unlisten(this._target,\"mouseleave\",\"hide\"),this.unlisten(this._target,\"blur\",\"hide\"),this.unlisten(this._target,\"tap\",\"hide\"))},show:function(){this._showing||\"\"===Polymer.dom(this).textContent.trim()||(this.cancelAnimation(),this._showing=!0,this.toggleClass(\"hidden\",\n!1,this.$.tooltip),this.updatePosition(),this.animationConfig.entry[0].timing.delay=this.animationDelay,this._animationPlaying=!0,this.playAnimation(\"entry\"))},hide:function(){this._showing&&(this._animationPlaying?(this.cancelAnimation(),this._showing=!1,this._onAnimationFinish()):(this._showing=!1,this._animationPlaying=!0,this.playAnimation(\"exit\")))},_forChanged:function(){this._target=this.target},updatePosition:function(){if(this._target&&this.offsetParent){var a=this.offset;14!=this.marginTop&&\n14==this.offset&&(a=this.marginTop);var b=this.offsetParent.getBoundingClientRect(),c=this._target.getBoundingClientRect(),d=this.getBoundingClientRect(),e=(c.width-d.width)/2,f=(c.height-d.height)/2,g=c.left-b.left,b=c.top-b.top;switch(this.position){case \"top\":var k=g+e;var l=b-d.height-a;break;case \"bottom\":k=g+e;l=b+c.height+a;break;case \"left\":k=g-d.width-a;l=b+f;break;case \"right\":k=g+c.width+a,l=b+f}this.fitToVisibleBounds?(k+d.width>window.innerWidth?(this.style.right=\"0px\",this.style.left=\n\"auto\"):(this.style.left=Math.max(0,k)+\"px\",this.style.right=\"auto\"),l+d.height>window.innerHeight?(this.style.bottom=\"0px\",this.style.top=\"auto\"):(this.style.top=Math.max(0,l)+\"px\",this.style.bottom=\"auto\")):(this.style.left=k+\"px\",this.style.top=l+\"px\")}},_onAnimationFinish:function(){this._animationPlaying=!1;this._showing||this.toggleClass(\"hidden\",!0,this.$.tooltip)}});\n</script>\n</dom-module>\n\n\n\n<script>//~~WEBPATH~~/facets-dive/lib/bounded-object.js\nvar cf,hf=cf||(cf={});hf[hf.Bottom=0]=\"Bottom\";hf[hf.Left=1]=\"Left\";hf[hf.Right=2]=\"Right\";hf[hf.Top=3]=\"Top\";\nvar jf=function(){function a(){}a.prototype.shouldBeVisible=function(a,c,d,e){if(void 0!==this.minScale)return this.scaleDown||c>=this.minScale;if(!this.boundingBox)return!0;var b=this.boundingBox;if(b.left>d.x+e.right||b.right<d.x+e.left||b.bottom>d.y+e.top||b.top<d.y+e.bottom)return!1;e=this.elementMargin||{bottom:0,left:0,right:0,top:0};d=void 0===this.width?a.getBoundingClientRect().width+e.left+e.right:this.width;a=void 0===this.height?a.getBoundingClientRect().height+e.top+e.bottom:this.height;\ne=isFinite(b.top)&&isFinite(b.bottom)?b.top-b.bottom:Infinity;return(isFinite(b.left)&&isFinite(b.right)?b.right-b.left:Infinity)*c>=d&&e*c>=a};return a}(),kf=cf;\n</script>\n\n<script>//~~WEBPATH~~/facets-dive/lib/sorting.js\nfunction lf(a,b){return null!==a&&void 0!==a||null!==b&&void 0!==b?null===a||void 0===a?-1:null===b||void 0===b?1:\"number\"===typeof a&&\"number\"===typeof b?isNaN(a)&&isNaN(b)?0:isNaN(a)?-1:isNaN(b)?1:a-b:\"string\"!==typeof a?-1:\"string\"!==typeof b?1:a.localeCompare(b):a===b?0:void 0===a?-1:1}\nfunction mf(a,b){return null!==a&&void 0!==a||null!==b&&void 0!==b?null===a||void 0===a?-1:null===b||void 0===b?1:\"number\"===typeof a&&\"number\"===typeof b?isNaN(a)&&isNaN(b)?0:isNaN(a)?-1:isNaN(b)?1:b-a:\"string\"!==typeof a?-1:\"string\"!==typeof b?1:-a.localeCompare(b):a===b?0:void 0===a?-1:1}\nfunction nf(a,b){return null!==a&&void 0!==a||null!==b&&void 0!==b?null===a||void 0===a?-1:null===b||void 0===b?1:\"string\"===typeof a&&\"string\"===typeof b?a.localeCompare(b):\"number\"!==typeof a?-1:\"number\"!==typeof b?1:isNaN(a)&&isNaN(b)?0:isNaN(a)?-1:isNaN(b)?1:a-b:a===b?0:void 0===a?-1:1};\n</script>\n\n<script>//~~WEBPATH~~/facets-dive/lib/grid.js\nfunction of(a,b,c,d){a=Math.floor(1E-6+c.minWidth/d.itemAspectRatio);return 1<a?b%a/(a-1):0}function pf(a,b,c,d){a=Math.floor(1E-6+c.minWidth/d.itemAspectRatio);c=Math.ceil(c.items.length/a);return 1<c?Math.floor(b/a)/(c-1):0}\nfunction qf(a,b){var c=\"right\"===b?1:\"middle\"===b?.5:0,d=\"top\"===a?1:\"middle\"===a?.5:0;return function(a,b,g,k){a=g.innerWidth-k.itemAspectRatio;var e=g.innerHeight-1;return{x:of(0,b,g,k)/a*(g.minWidth-k.itemAspectRatio)+c*(g.innerWidth-g.minWidth)/a,y:pf(0,b,g,k)/e*(g.minHeight-1)+d*(g.innerHeight-g.minHeight)/e}}}var rf=qf(\"bottom\",\"left\"),sf,tf=sf||(sf={});tf[tf.Tight=0]=\"Tight\";tf[tf.Uniform=1]=\"Uniform\";\nvar uf=function(){function a(a){this.items=a;this.cellMargin=this.itemAspectRatio=1;this.cellPadding={bottom:0,left:0,right:0,top:0};this.targetGridAspectRatio=1;this.minCellAspectRatio=0;this.maxCellAspectRatio=Infinity;this.verticalFacet=function(){return null};this.horizontalFacet=function(){return null};this.verticalKeyCompare=mf;this.horizontalKeyCompare=lf;this.verticalKeys=[];this.verticalKeysHash={};this.horizontalKeys=[];this.horizontalKeysHash={};this.cells={};this.height=this.width=this.longestCellLength=\n0;this.itemPositionSetter=function(a,b,e){a.x=b;a.y=e};this.computeItemPosition=rf;this.horizontalGridAlignment=this.verticalGridAlignment=sf.Tight;this.cellItemComparator=null}a.prototype.clear=function(){this.verticalKeys=[];this.verticalKeysHash={};this.horizontalKeys=[];this.horizontalKeysHash={};this.cells={};this.height=this.width=this.longestCellLength=0};a.prototype.arrange=function(){var a=this;this.facetItemsIntoCells();for(var c=this.computeOptimalCellAspectRatio(this.targetGridAspectRatio),\nd=Math.min(this.maxCellAspectRatio,Math.max(this.minCellAspectRatio,c)),c=[],e=[],f=0;f<this.verticalKeys.length;f++)for(var g=0;g<this.horizontalKeys.length;g++){var k=this.getOrCreateCell(this.verticalKeys[f],this.horizontalKeys[g]);var l=this.computeCellDimensions(d,k.items.length);k.minWidth=l[0];k.minHeight=l[1];c[f]=Math.max(c[f]||0,k.minHeight);e[g]=Math.max(e[g]||0,k.minWidth)}for(f=0;f<this.verticalKeys.length;f++)for(g=0;g<this.horizontalKeys.length;g++)k=this.getCell(this.verticalKeys[f],\nthis.horizontalKeys[g]),f<this.verticalKeys.length-1&&(k.siblings.above=this.getCell(this.verticalKeys[f+1],this.horizontalKeys[g])),0<f&&(k.siblings.below=this.getCell(this.verticalKeys[f-1],this.horizontalKeys[g])),0<g&&(k.siblings.left=this.getCell(this.verticalKeys[f],this.horizontalKeys[g-1])),g<this.horizontalKeys.length-1&&(k.siblings.right=this.getCell(this.verticalKeys[f],this.horizontalKeys[g+1]));if(this.verticalGridAlignment===sf.Uniform)for(g=Math.max.apply(Math,c),f=0;f<c.length;f++)c[f]=\ng;if(this.horizontalGridAlignment===sf.Uniform)for(f=Math.max.apply(Math,e),g=0;g<e.length;g++)e[g]=f;for(f=0;f<this.verticalKeys.length;f++)for(g=0;g<this.horizontalKeys.length;g++)k=this.getCell(this.verticalKeys[f],this.horizontalKeys[g]),k.height=c[f],k.width=e[g],k.innerHeight=k.height-this.cellPadding.top-this.cellPadding.bottom,k.innerWidth=k.width-this.cellPadding.left-this.cellPadding.right;d=this.cellMargin*this.itemAspectRatio;for(f=0;f<this.verticalKeys.length;f++)for(g=0;g<this.horizontalKeys.length;g++)k=\nthis.getCell(this.verticalKeys[f],this.horizontalKeys[g]),k.y=f?this.getCell(this.verticalKeys[f-1],this.horizontalKeys[g]).y+c[f-1]+d:0,k.contentY=k.y+this.cellPadding.bottom,k.x=g?this.getCell(this.verticalKeys[f],this.horizontalKeys[g-1]).x+e[g-1]+d:0,k.contentX=k.x+this.cellPadding.left;this.eachCell(function(b){a.width=Math.max(a.width,b.x+b.width);a.height=Math.max(a.height,b.y+b.height)});this.positionItems()};a.prototype.positionItems=function(){var a=this;this.eachCell(function(b){var c=\nMath.max(0,b.innerWidth-a.itemAspectRatio),e=Math.max(0,b.innerHeight-1),f=b.items.slice(0);a.cellItemComparator&&f.sort(a.cellItemComparator);for(var g=0;g<f.length;g++){var k=a.computeItemPosition(f[g],g,b,a);a.itemPositionSetter(f[g],b.contentX+(!k||isNaN(k.x)?0:Math.max(0,Math.min(1,k.x)))*c,b.contentY+(!k||isNaN(k.y)?0:Math.max(0,Math.min(1,k.y)))*e)}})};a.prototype.facetItemsIntoCells=function(){var a=this;this.clear();this.eachItem(function(b){var c=a.getOrCreateCell(a.verticalFacet(b),a.horizontalFacet(b));\nc.items.push(b);a.longestCellLength=Math.max(a.longestCellLength,c.items.length)});for(var c in this.verticalKeysHash)this.verticalKeys.push(this.verticalKeysHash[c]);this.verticalKeys.sort(this.verticalKeyCompare);for(c in this.horizontalKeysHash)this.horizontalKeys.push(this.horizontalKeysHash[c]);this.horizontalKeys.sort(this.horizontalKeyCompare)};a.prototype.eachItem=function(a){if(this.items)for(var b=0;b<this.items.length;b++)a.call(this,this.items[b])};a.prototype.eachCell=function(a){for(var b in this.cells)a.call(this,\nthis.cells[b])};a.prototype.getCompoundKey=function(a,c){return typeof a+\"\\u001f\"+a+\"\\u001e\"+typeof c+\"\\u001f\"+c};a.prototype.getCell=function(a,c){a=this.getCompoundKey(a,c);return a in this.cells?this.cells[a]:null};a.prototype.getCells=function(){var a=this;return Object.keys(this.cells).map(function(b){return a.cells[b]})};a.prototype.getOrCreateCell=function(a,c){var b=this.getCell(a,c);if(b)return b;this.addVerticalKey(a);this.addHorizontalKey(c);var e=this.getCompoundKey(a,c),b={verticalKey:a,\nhorizontalKey:c,compoundKey:e,items:[],siblings:{}};return this.cells[e]=b};a.prototype.getRow=function(a){for(var b=[],d=0;d<this.horizontalKeys.length;d++){var e=this.getCell(a,this.horizontalKeys[d]);e&&b.push(e)}return b};a.prototype.getColumn=function(a){for(var b=[],d=0;d<this.verticalKeys.length;d++){var e=this.getCell(this.verticalKeys[d],a);e&&b.push(e)}return b};a.prototype.addVerticalKey=function(a){var b=typeof a+\"\\u001f\"+a;b in this.verticalKeysHash||(this.verticalKeysHash[b]=a)};a.prototype.addHorizontalKey=\nfunction(a){var b=typeof a+\"\\u001f\"+a;b in this.horizontalKeysHash||(this.horizontalKeysHash[b]=a)};a.prototype.computeOptimalCellAspectRatio=function(a){var b=this.verticalKeys.length,d=this.horizontalKeys.length;if(!b||!d)return 1;for(var e=b/d,f=e,g=Infinity,k=0,l=Infinity,b=Math.min(20,Math.max(b,d,this.longestCellLength)),d=0;d<b;){d++;var m=this.computeGridAspectRatio(e),n=Math.abs(1-m/a);n<g&&(f=e,g=n);if(.001>n)break;m>a?(l=e,e-=(l-k)/2):(k=e,e=isFinite(l)?e+(l-k)/2:2*e)}return f};a.prototype.computeGridAspectRatio=\nfunction(a){for(var b=this.verticalKeys.length,d=this.horizontalKeys.length,e=-Infinity,f=-Infinity,g=-Infinity,k=-Infinity,l=[],m=0;m<b;m++){l[m]=[];for(var n=0;n<d;n++){var q=l[m][n]={width:n?l[m][n-1].width:0,height:m?l[m-1][n].height:0},p=this.getCell(this.verticalKeys[m],this.horizontalKeys[n]);if(p&&p.items&&p.items.length){var t=this.computeCellDimensions(a,p.items.length),p=t[0],t=t[1];q.width+=p;q.height+=t;e=Math.max(e,q.width);f=Math.max(f,t);g=Math.max(g,p);k=Math.max(k,q.height)}}}this.verticalGridAlignment===\nsf.Uniform&&(k=f*b);this.horizontalGridAlignment===sf.Uniform&&(e=g*d);a=this.cellMargin*this.itemAspectRatio;return(e+a*(d-1))/(k+a*(b-1))};a.prototype.computeCellDimensions=function(a,c){var b=[this.itemAspectRatio*(this.cellPadding.left+this.cellPadding.right),this.itemAspectRatio*(this.cellPadding.top+this.cellPadding.bottom)];if(!c)return b;a=Math.min(c,Math.ceil(Math.sqrt(a*c)/this.itemAspectRatio));b[0]+=this.itemAspectRatio*a;b[1]+=Math.ceil(c/a);return b};return a}(),vf=sf;\n</script>\n\n<script>//~~WEBPATH~~/facets-dive/lib/axis.js\nvar wf=this&&this.__extends||function(){var a=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(a,c){a.__proto__=c}||function(a,c){for(var b in c)c.hasOwnProperty(b)&&(a[b]=c[b])};return function(b,c){function d(){this.constructor=b}a(b,c);b.prototype=null===c?Object.create(c):(d.prototype=c.prototype,new d)}}(),xf=function(a){function b(b,d){var c=a.call(this)||this;c.side=b;c.cell=d;switch(b){case kf.Left:c.minScale=30/d.innerHeight;for(b=d.siblings.left;!(!b||b.items.length||b.siblings.above&&\nb.siblings.above.items.length);)b=b.siblings.left;b&&(c.minScale=Math.max(c.minScale,39.2/(d.contentX-(b.contentX+b.innerWidth))));break;case kf.Bottom:c.minScale=30/d.innerWidth;for(b=d.siblings.below;!(!b||b.items.length||b.siblings.right&&b.siblings.right.items.length);)b=b.siblings.below;b&&(c.minScale=Math.max(c.minScale,39.2/(d.contentY-(b.contentY+b.innerHeight))));break;default:throw Error(\"Axes for specified side are not implemented.\");}return c}wf(b,a);b.prototype.strokeWidth=function(a){return 1.2/\na};b.prototype.path=function(a){var b=4/a;var c=6/a;if(this.side===kf.Left){var f=this.cell.contentX-b-c;b=this.cell.contentY+.6/a;return\"M \"+f+\",\"+b+\" h \"+c+\" v \"+(this.cell.innerHeight-1.2/a)+\" h -\"+c}return this.side===kf.Bottom?(f=this.cell.contentX+.6/a,b=this.cell.contentY-b-c,\"M \"+f+\",\"+b+\" v \"+c+\" h \"+(this.cell.innerWidth-1.2/a)+\" v -\"+c):\"\"};b.prototype.key=function(){return this.cell.compoundKey+\"-\"+this.side};return b}(jf);\n</script>\n\n\n<script>//~~WEBPATH~~/facets-dive/lib/data-example.js\n</script>\n\n\n\n<script>//~~WEBPATH~~/facets-dive/lib/label.js\n</script>\n\n<script>//~~WEBPATH~~/facets-dive/lib/layout.js\nvar yf=function(){function a(){this.grid={bottom:0,left:0,right:0,top:0};this.viewport={height:0,width:0};this.padding={bottom:0,left:0,right:0,top:0}}a.prototype.computeScale=function(){var a=this.viewport.width-this.padding.left-this.padding.right,c=this.viewport.height-this.padding.top-this.padding.bottom;if(isNaN(a)||0>=a||isNaN(c)||0>=c)return NaN;var d=this.grid.right-this.grid.left,e=this.grid.top-this.grid.bottom;return isNaN(d)||0>=d||isNaN(e)||0>=e?NaN:a/c>d/e?c/e:a/d};a.prototype.computeCamera=\nfunction(){var a=this.computeScale();if(isNaN(a)||0>=a)return{position:{x:NaN,y:NaN},frustum:{bottom:NaN,left:NaN,right:NaN,top:NaN}};var c=this.viewport.width/a,d=this.viewport.height/a;return{position:{x:this.grid.left-(c-(this.padding.left+this.padding.right)/a-(this.grid.right-this.grid.left))/2-this.padding.left/a,y:this.grid.top+(d-(this.padding.top+this.padding.bottom)/a-(this.grid.top-this.grid.bottom))/2+this.padding.top/a},frustum:{bottom:-d,left:0,right:c,top:0}}};a.prototype.reducePaddingToFitWidth=\nfunction(a){if(200>a)this.padding.left=0,this.padding.right=0;else if(this.padding.left+this.padding.right+200>a){var b=this.padding.left+this.padding.right;a-=200;this.padding.left=this.padding.left/b*a||0;this.padding.right=this.padding.right/b*a||0}};a.prototype.reducePaddingToFitHeight=function(a){if(200>a)this.padding.top=0,this.padding.bottom=0;else if(this.padding.top+this.padding.bottom+200>a){var b=this.padding.top+this.padding.bottom;a-=200;this.padding.top=this.padding.top/b*a||0;this.padding.bottom=\nthis.padding.bottom/b*a||0}};return a}();\n</script>\n\n\n<script>//~~WEBPATH~~/facets-dive/lib/text.js\nvar zf,Af=zf||(zf={});Af[Af.Left=0]=\"Left\";Af[Af.Right=1]=\"Right\";Af[Af.Center=2]=\"Center\";var Bf,Cf=Bf||(Bf={});Cf[Cf.Top=0]=\"Top\";Cf[Cf.Bottom=1]=\"Bottom\";Cf[Cf.Middle=2]=\"Middle\";\nvar Df={x:0,y:0,glyphAspectRatio:.6,lineHeight:1.1,horizontalAlign:zf.Center,verticalAlign:Bf.Middle},Ef=function(){function a(a){this.settings=Object.assign({},Df,a)}a.prototype.fit=function(a){a=a.trim();var b=this.split(a),d=b.segments,e=this.computeCutoff(d,a.length,b.max),f=e.height;a=e.width*this.settings.glyphAspectRatio;a=a/f>this.settings.width/this.settings.height?this.settings.width/a:this.settings.height/f;for(var b=this.settings.horizontalAlign===zf.Left?0:this.settings.horizontalAlign===\nzf.Right?1:.5,f=Math.max(0,this.settings.height-f*a)*(this.settings.verticalAlign===Bf.Top?0:this.settings.verticalAlign===Bf.Bottom?1:.5),e=this.wrapLines(d,e.cutoff),g=[],k=0;k<e.length;k++){for(var l=e[k],m=l.endPos,n=\"\",l=l.startPos;l<m;l++)n+=d[l].text;g.push({text:n,x:this.settings.x+b*Math.max(0,this.settings.width-n.length*this.settings.glyphAspectRatio*a),y:this.settings.y+f+k*this.settings.lineHeight*a})}return{lines:g,fontSize:a}};a.prototype.split=function(a){for(var b=[],d=1,e=/\\s/.test(a.charAt(0)),\nf=0,g=0;d<=a.length;){var k=a.charAt(d),l=/\\s/.test(k);k.length&&e===l||(g=Math.max(g,d-f),b.push({text:a.substring(f,d),whitespace:e}),f=d);e=l;d++}return{max:g,segments:b}};a.prototype.computeTextRect=function(a,c){for(var b=0,e=0,f=0,g=1,k=0;k<a.length;k++){var l=a[k],m=l.whitespace,l=l.text.length;if(!m||b)m?b+l<=c?b+=l:(e=b=0,g+=this.settings.lineHeight):b+l<=c?e=b+=l:(e?b=e=l:(f=Math.max(f,l),b=e=0),g+=this.settings.lineHeight),f=Math.max(f,e)}return{width:f,height:g}};a.prototype.computeCutoff=\nfunction(a,c,d){for(var b=this.settings.width/this.settings.height,f=d+(c-d)/2,g=f,k=null,l=Infinity,m=Math.min(20,(a.length+1)/2),n=0;n<m;){n++;var q=this.computeTextRect(a,f),p=q.width/q.height*this.settings.glyphAspectRatio,t=Math.abs(1-p/b);t<l&&(g=f,k=q,l=t);if(.01>t)break;p>b?c=f:d=f;f=d+(c-d)/2}return{cutoff:g,width:k.width,height:k.height}};a.prototype.wrapLines=function(a,c){for(var b=[],e=0,f=0,g=0,k=0,l=0;l<a.length;l++){var m=a[l],n=m.whitespace,m=m.text.length;n&&!g?e=f=l+1:n?g+m<=c?\ng+=m:(b.push({startPos:e,endPos:f,textLength:k}),g=k=0,e=f=l+1):g+m<=c?(k=g+=m,f=l+1):k?(b.push({startPos:e,endPos:f,textLength:k}),g=k=m,e=l,f=l+1):(b.push({startPos:l,endPos:l+1,textLength:m}),g=k=0,e=f=l+1)}f>e&&b.push({startPos:e,endPos:f,textLength:k});return b};return a}();\n</script>\n\n<script>//~~WEBPATH~~/tf-imports/three.js\nvar Z={REVISION:\"77\"};\"function\"===typeof define&&define.amd?define(\"three\",Z):\"undefined\"!==typeof exports&&\"undefined\"!==typeof module&&(module.exports=Z);void 0===Number.EPSILON&&(Number.EPSILON=Math.pow(2,-52));void 0===Math.sign&&(Math.sign=function(a){return 0>a?-1:0<a?1:+a});void 0===Function.prototype.name&&Object.defineProperty(Function.prototype,\"name\",{get:function(){return this.toString().match(/^\\s*function\\s*(\\S*)\\s*\\(/)[1]}});\nvoid 0===Object.assign&&(Object.assign=function(a){if(void 0===a||null===a)throw new TypeError(\"Cannot convert undefined or null to object\");for(var b=Object(a),c=1;c<arguments.length;c++){var d=arguments[c];if(void 0!==d&&null!==d)for(var e in d)Object.prototype.hasOwnProperty.call(d,e)&&(b[e]=d[e])}return b});\nObject.assign(Z,{MOUSE:{LEFT:0,MIDDLE:1,RIGHT:2},CullFaceNone:0,CullFaceBack:1,CullFaceFront:2,CullFaceFrontBack:3,FrontFaceDirectionCW:0,FrontFaceDirectionCCW:1,BasicShadowMap:0,PCFShadowMap:1,PCFSoftShadowMap:2,FrontSide:0,BackSide:1,DoubleSide:2,FlatShading:1,SmoothShading:2,NoColors:0,FaceColors:1,VertexColors:2,NoBlending:0,NormalBlending:1,AdditiveBlending:2,SubtractiveBlending:3,MultiplyBlending:4,CustomBlending:5,AddEquation:100,SubtractEquation:101,ReverseSubtractEquation:102,MinEquation:103,\nMaxEquation:104,ZeroFactor:200,OneFactor:201,SrcColorFactor:202,OneMinusSrcColorFactor:203,SrcAlphaFactor:204,OneMinusSrcAlphaFactor:205,DstAlphaFactor:206,OneMinusDstAlphaFactor:207,DstColorFactor:208,OneMinusDstColorFactor:209,SrcAlphaSaturateFactor:210,NeverDepth:0,AlwaysDepth:1,LessDepth:2,LessEqualDepth:3,EqualDepth:4,GreaterEqualDepth:5,GreaterDepth:6,NotEqualDepth:7,MultiplyOperation:0,MixOperation:1,AddOperation:2,NoToneMapping:0,LinearToneMapping:1,ReinhardToneMapping:2,Uncharted2ToneMapping:3,\nCineonToneMapping:4,UVMapping:300,CubeReflectionMapping:301,CubeRefractionMapping:302,EquirectangularReflectionMapping:303,EquirectangularRefractionMapping:304,SphericalReflectionMapping:305,CubeUVReflectionMapping:306,CubeUVRefractionMapping:307,RepeatWrapping:1E3,ClampToEdgeWrapping:1001,MirroredRepeatWrapping:1002,NearestFilter:1003,NearestMipMapNearestFilter:1004,NearestMipMapLinearFilter:1005,LinearFilter:1006,LinearMipMapNearestFilter:1007,LinearMipMapLinearFilter:1008,UnsignedByteType:1009,\nByteType:1010,ShortType:1011,UnsignedShortType:1012,IntType:1013,UnsignedIntType:1014,FloatType:1015,HalfFloatType:1025,UnsignedShort4444Type:1016,UnsignedShort5551Type:1017,UnsignedShort565Type:1018,AlphaFormat:1019,RGBFormat:1020,RGBAFormat:1021,LuminanceFormat:1022,LuminanceAlphaFormat:1023,RGBEFormat:Z.RGBAFormat,DepthFormat:1026,RGB_S3TC_DXT1_Format:2001,RGBA_S3TC_DXT1_Format:2002,RGBA_S3TC_DXT3_Format:2003,RGBA_S3TC_DXT5_Format:2004,RGB_PVRTC_4BPPV1_Format:2100,RGB_PVRTC_2BPPV1_Format:2101,\nRGBA_PVRTC_4BPPV1_Format:2102,RGBA_PVRTC_2BPPV1_Format:2103,RGB_ETC1_Format:2151,LoopOnce:2200,LoopRepeat:2201,LoopPingPong:2202,InterpolateDiscrete:2300,InterpolateLinear:2301,InterpolateSmooth:2302,ZeroCurvatureEnding:2400,ZeroSlopeEnding:2401,WrapAroundEnding:2402,TrianglesDrawMode:0,TriangleStripDrawMode:1,TriangleFanDrawMode:2,LinearEncoding:3E3,sRGBEncoding:3001,GammaEncoding:3007,RGBEEncoding:3002,LogLuvEncoding:3003,RGBM7Encoding:3004,RGBM16Encoding:3005,RGBDEncoding:3006,BasicDepthPacking:3200,\nRGBADepthPacking:3201});Z.Color=function(a,b,c){void 0===b&&void 0===c?a=this.set(a):(this.r=a,this.g=b,this.b=c,a=this);return a};\nZ.Color.prototype={constructor:Z.Color,r:1,g:1,b:1,set:function(a){a instanceof Z.Color?this.copy(a):\"number\"===typeof a?Ff(this,a):\"string\"===typeof a&&Gf(this,a);return this},setScalar:function(a){this.b=this.g=this.r=a},setHSL:function(){function a(a,c,d){0>d&&(d+=1);1<d&&--d;return d<1/6?a+6*(c-a)*d:.5>d?c:d<2/3?a+6*(c-a)*(2/3-d):a}return function(b,c,d){b=Z.Math.euclideanModulo(b,1);c=Z.Math.clamp(c,0,1);d=Z.Math.clamp(d,0,1);0===c?this.r=this.g=this.b=d:(c=.5>=d?d*(1+c):d+c-d*c,d=2*d-c,this.r=\na(d,c,b+1/3),this.g=a(d,c,b),this.b=a(d,c,b-1/3));return this}}(),clone:function(){return new this.constructor(this.r,this.g,this.b)},copy:function(a){this.r=a.r;this.g=a.g;this.b=a.b;return this},copyGammaToLinear:function(a,b){void 0===b&&(b=2);this.r=Math.pow(a.r,b);this.g=Math.pow(a.g,b);this.b=Math.pow(a.b,b);return this},copyLinearToGamma:function(a,b){void 0===b&&(b=2);b=0<b?1/b:1;this.r=Math.pow(a.r,b);this.g=Math.pow(a.g,b);this.b=Math.pow(a.b,b);return this},convertGammaToLinear:function(){var a=\nthis.r,b=this.g,c=this.b;this.r=a*a;this.g=b*b;this.b=c*c;return this},convertLinearToGamma:function(){this.r=Math.sqrt(this.r);this.g=Math.sqrt(this.g);this.b=Math.sqrt(this.b);return this},getHexString:function(){return(\"000000\"+Hf(this).toString(16)).slice(-6)},getStyle:function(){return\"rgb(\"+(255*this.r|0)+\",\"+(255*this.g|0)+\",\"+(255*this.b|0)+\")\"},offsetHSL:function(a,b,c){var d=0,e=0,f=0,d=this.r,e=this.g,g=this.b,k=Math.max(d,e,g),l=Math.min(d,e,g),m,f=(l+k)/2;if(l===k)l=m=0;else{var n=k-\nl,l=.5>=f?n/(k+l):n/(2-k-l);switch(k){case d:m=(e-g)/n+(e<g?6:0);break;case e:m=(g-d)/n+2;break;case g:m=(d-e)/n+4}m/=6}d=m+a;e=l+b;f+=c;this.setHSL(d,e,f);return this},add:function(a){this.r+=a.r;this.g+=a.g;this.b+=a.b;return this},addColors:function(a,b){this.r=a.r+b.r;this.g=a.g+b.g;this.b=a.b+b.b;return this},addScalar:function(a){this.r+=a;this.g+=a;this.b+=a;return this},multiply:function(a){this.r*=a.r;this.g*=a.g;this.b*=a.b;return this},multiplyScalar:function(a){this.r*=a;this.g*=a;this.b*=\na;return this},lerp:function(a,b){this.r+=(a.r-this.r)*b;this.g+=(a.g-this.g)*b;this.b+=(a.b-this.b)*b;return this},equals:function(a){return a.r===this.r&&a.g===this.g&&a.b===this.b},fromArray:function(a,b){void 0===b&&(b=0);this.r=a[b];this.g=a[b+1];this.b=a[b+2];return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this.r;a[b+1]=this.g;a[b+2]=this.b;return a}};function Hf(a){return 255*a.r<<16^255*a.g<<8^255*a.b<<0}\nfunction Gf(a,b){function c(a){void 0!==a&&1>parseFloat(a)&&console.warn(\"THREE.Color: Alpha component of \"+b+\" will be ignored.\")}var d;if(d=/^((?:rgb|hsl)a?)\\(\\s*([^\\)]*)\\)/.exec(b)){var e=d[2];switch(d[1]){case \"rgb\":case \"rgba\":if(d=/^(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*(,\\s*([0-9]*\\.?[0-9]+)\\s*)?$/.exec(e)){a.r=Math.min(255,parseInt(d[1],10))/255;a.g=Math.min(255,parseInt(d[2],10))/255;a.b=Math.min(255,parseInt(d[3],10))/255;c(d[5]);return}if(d=/^(\\d+)\\%\\s*,\\s*(\\d+)\\%\\s*,\\s*(\\d+)\\%\\s*(,\\s*([0-9]*\\.?[0-9]+)\\s*)?$/.exec(e)){a.r=\nMath.min(100,parseInt(d[1],10))/100;a.g=Math.min(100,parseInt(d[2],10))/100;a.b=Math.min(100,parseInt(d[3],10))/100;c(d[5]);return}break;case \"hsl\":case \"hsla\":if(d=/^([0-9]*\\.?[0-9]+)\\s*,\\s*(\\d+)\\%\\s*,\\s*(\\d+)\\%\\s*(,\\s*([0-9]*\\.?[0-9]+)\\s*)?$/.exec(e)){var e=parseFloat(d[1])/360,f=parseInt(d[2],10)/100,g=parseInt(d[3],10)/100;c(d[5]);a.setHSL(e,f,g);return}}}else if(d=/^\\#([A-Fa-f0-9]+)$/.exec(b)){d=d[1];e=d.length;if(3===e){a.r=parseInt(d.charAt(0)+d.charAt(0),16)/255;a.g=parseInt(d.charAt(1)+d.charAt(1),\n16)/255;a.b=parseInt(d.charAt(2)+d.charAt(2),16)/255;return}if(6===e){a.r=parseInt(d.charAt(0)+d.charAt(1),16)/255;a.g=parseInt(d.charAt(2)+d.charAt(3),16)/255;a.b=parseInt(d.charAt(4)+d.charAt(5),16)/255;return}}b&&0<b.length&&(d=Z.ColorKeywords[b],void 0!==d?Ff(a,d):console.warn(\"THREE.Color: Unknown color \"+b))}function Ff(a,b){b=Math.floor(b);a.r=(b>>16&255)/255;a.g=(b>>8&255)/255;a.b=(b&255)/255}\nZ.ColorKeywords={aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,\ndarkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,\ngrey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,\nlime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,\npalegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,\ntomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074};Z.Quaternion=function(a,b,c,d){this._x=a||0;this._y=b||0;this._z=c||0;this._w=void 0!==d?d:1};\nZ.Quaternion.prototype={constructor:Z.Quaternion,get x(){return this._x},set x(a){this._x=a;this.onChangeCallback()},get y(){return this._y},set y(a){this._y=a;this.onChangeCallback()},get z(){return this._z},set z(a){this._z=a;this.onChangeCallback()},get w(){return this._w},set w(a){this._w=a;this.onChangeCallback()},set:function(a,b,c,d){this._x=a;this._y=b;this._z=c;this._w=d;this.onChangeCallback();return this},clone:function(){return new this.constructor(this._x,this._y,this._z,this._w)},copy:function(a){this._x=\na.x;this._y=a.y;this._z=a.z;this._w=a.w;this.onChangeCallback();return this},setFromRotationMatrix:function(a){var b=a.elements,c=b[0];a=b[4];var d=b[8],e=b[1],f=b[5],g=b[9],k=b[2],l=b[6],b=b[10],m=c+f+b;0<m?(c=.5/Math.sqrt(m+1),this._w=.25/c,this._x=(l-g)*c,this._y=(d-k)*c,this._z=(e-a)*c):c>f&&c>b?(c=2*Math.sqrt(1+c-f-b),this._w=(l-g)/c,this._x=.25*c,this._y=(a+e)/c,this._z=(d+k)/c):f>b?(c=2*Math.sqrt(1+f-c-b),this._w=(d-k)/c,this._x=(a+e)/c,this._y=.25*c,this._z=(g+l)/c):(c=2*Math.sqrt(1+b-c-f),\nthis._w=(e-a)/c,this._x=(d+k)/c,this._y=(g+l)/c,this._z=.25*c);this.onChangeCallback();return this},setFromUnitVectors:function(){var a,b;return function(c,d){void 0===a&&(a=new Z.Vector3);b=c.dot(d)+1;1E-6>b?(b=0,Math.abs(c.x)>Math.abs(c.z)?a.set(-c.y,c.x,0):a.set(0,-c.z,c.y)):If(a,c,d);this._x=a.x;this._y=a.y;this._z=a.z;this._w=b;return this.normalize()}}(),inverse:function(){this._x*=-1;this._y*=-1;this._z*=-1;this.onChangeCallback();return this.normalize()},dot:function(a){return this._x*a._x+\nthis._y*a._y+this._z*a._z+this._w*a._w},lengthSq:function(){return this._x*this._x+this._y*this._y+this._z*this._z+this._w*this._w},length:function(){return Math.sqrt(this._x*this._x+this._y*this._y+this._z*this._z+this._w*this._w)},normalize:function(){var a=this.length();0===a?(this._z=this._y=this._x=0,this._w=1):(a=1/a,this._x*=a,this._y*=a,this._z*=a,this._w*=a);this.onChangeCallback();return this},multiply:function(a,b){return void 0!==b?(console.warn(\"THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead.\"),\nJf(this,a,b)):Jf(this,this,a)},premultiply:function(a){return Jf(this,a,this)},slerp:function(a,b){if(0===b)return this;if(1===b)return this.copy(a);var c=this._x,d=this._y,e=this._z,f=this._w,g=f*a._w+c*a._x+d*a._y+e*a._z;0>g?(this._w=-a._w,this._x=-a._x,this._y=-a._y,this._z=-a._z,g=-g):this.copy(a);if(1<=g)return this._w=f,this._x=c,this._y=d,this._z=e,this;a=Math.sqrt(1-g*g);if(.001>Math.abs(a))return this._w=.5*(f+this._w),this._x=.5*(c+this._x),this._y=.5*(d+this._y),this._z=.5*(e+this._z),\nthis;var k=Math.atan2(a,g),g=Math.sin((1-b)*k)/a;b=Math.sin(b*k)/a;this._w=f*g+this._w*b;this._x=c*g+this._x*b;this._y=d*g+this._y*b;this._z=e*g+this._z*b;this.onChangeCallback();return this},equals:function(a){return a._x===this._x&&a._y===this._y&&a._z===this._z&&a._w===this._w},fromArray:function(a,b){void 0===b&&(b=0);this._x=a[b];this._y=a[b+1];this._z=a[b+2];this._w=a[b+3];this.onChangeCallback();return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this._x;a[b+1]=this._y;\na[b+2]=this._z;a[b+3]=this._w;return a},onChange:function(a){this.onChangeCallback=a;return this},onChangeCallback:function(){}};function Jf(a,b,c){var d=b._x,e=b._y,f=b._z;b=b._w;var g=c._x,k=c._y,l=c._z;c=c._w;a._x=d*c+b*g+e*l-f*k;a._y=e*c+b*k+f*g-d*l;a._z=f*c+b*l+d*k-e*g;a._w=b*c-d*g-e*k-f*l;a.onChangeCallback();return a}function Kf(a,b,c){c/=2;var d=Math.sin(c);a._x=b.x*d;a._y=b.y*d;a._z=b.z*d;a._w=Math.cos(c);a.onChangeCallback();return a}\nfunction Lf(a,b,c){if(!1===b instanceof Z.Euler)throw Error(\"THREE.Quaternion: .setFromEuler() now expects a Euler rotation rather than a Vector3 and order.\");var d=Math.cos(b._x/2),e=Math.cos(b._y/2),f=Math.cos(b._z/2),g=Math.sin(b._x/2),k=Math.sin(b._y/2),l=Math.sin(b._z/2);b=b.order;\"XYZ\"===b?(a._x=g*e*f+d*k*l,a._y=d*k*f-g*e*l,a._z=d*e*l+g*k*f,a._w=d*e*f-g*k*l):\"YXZ\"===b?(a._x=g*e*f+d*k*l,a._y=d*k*f-g*e*l,a._z=d*e*l-g*k*f,a._w=d*e*f+g*k*l):\"ZXY\"===b?(a._x=g*e*f-d*k*l,a._y=d*k*f+g*e*l,a._z=d*e*\nl+g*k*f,a._w=d*e*f-g*k*l):\"ZYX\"===b?(a._x=g*e*f-d*k*l,a._y=d*k*f+g*e*l,a._z=d*e*l-g*k*f,a._w=d*e*f+g*k*l):\"YZX\"===b?(a._x=g*e*f+d*k*l,a._y=d*k*f+g*e*l,a._z=d*e*l-g*k*f,a._w=d*e*f-g*k*l):\"XZY\"===b&&(a._x=g*e*f-d*k*l,a._y=d*k*f-g*e*l,a._z=d*e*l+g*k*f,a._w=d*e*f+g*k*l);if(!1!==c)a.onChangeCallback();return a}\nObject.assign(Z.Quaternion,{slerp:function(a,b,c,d){return c.copy(a).slerp(b,d)},slerpFlat:function(a,b,c,d,e,f,g){var k=c[d+0],l=c[d+1],m=c[d+2];c=c[d+3];d=e[f+0];var n=e[f+1],q=e[f+2];e=e[f+3];if(c!==e||k!==d||l!==n||m!==q){f=1-g;var p=k*d+l*n+m*q+c*e,t=0<=p?1:-1,r=1-p*p;r>Number.EPSILON&&(r=Math.sqrt(r),p=Math.atan2(r,p*t),f=Math.sin(f*p)/r,g=Math.sin(g*p)/r);t*=g;k=k*f+d*t;l=l*f+n*t;m=m*f+q*t;c=c*f+e*t;f===1-g&&(g=1/Math.sqrt(k*k+l*l+m*m+c*c),k*=g,l*=g,m*=g,c*=g)}a[b]=k;a[b+1]=l;a[b+2]=m;a[b+\n3]=c}});Z.Vector2=function(a,b){this.x=a||0;this.y=b||0};\nZ.Vector2.prototype={constructor:Z.Vector2,get width(){return this.x},set width(a){this.x=a},get height(){return this.y},set height(a){this.y=a},set:function(a,b){this.x=a;this.y=b;return this},setScalar:function(a){this.y=this.x=a;return this},setX:function(a){this.x=a;return this},setY:function(a){this.y=a;return this},setComponent:function(a,b){switch(a){case 0:this.x=b;break;case 1:this.y=b;break;default:throw Error(\"index is out of range: \"+a);}},getComponent:function(a){switch(a){case 0:return this.x;\ncase 1:return this.y;default:throw Error(\"index is out of range: \"+a);}},clone:function(){return new this.constructor(this.x,this.y)},copy:function(a){this.x=a.x;this.y=a.y;return this},add:function(a,b){if(void 0!==b)return console.warn(\"THREE.Vector2: .add() now only accepts one argument. Use .addVectors( a, b ) instead.\"),this.addVectors(a,b);this.x+=a.x;this.y+=a.y;return this},addScalar:function(a){this.x+=a;this.y+=a;return this},addVectors:function(a,b){this.x=a.x+b.x;this.y=a.y+b.y;return this},\naddScaledVector:function(a,b){this.x+=a.x*b;this.y+=a.y*b;return this},sub:function(a,b){if(void 0!==b)return console.warn(\"THREE.Vector2: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.\"),this.subVectors(a,b);this.x-=a.x;this.y-=a.y;return this},subScalar:function(a){this.x-=a;this.y-=a;return this},subVectors:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;return this},multiply:function(a){this.x*=a.x;this.y*=a.y;return this},multiplyScalar:function(a){isFinite(a)?(this.x*=a,\nthis.y*=a):this.y=this.x=0;return this},divide:function(a){this.x/=a.x;this.y/=a.y;return this},divideScalar:function(a){return this.multiplyScalar(1/a)},min:function(a){this.x=Math.min(this.x,a.x);this.y=Math.min(this.y,a.y);return this},max:function(a){this.x=Math.max(this.x,a.x);this.y=Math.max(this.y,a.y);return this},clamp:function(a,b){this.x=Math.max(a.x,Math.min(b.x,this.x));this.y=Math.max(a.y,Math.min(b.y,this.y));return this},clampScalar:function(){var a,b;return function(c,d){void 0===\na&&(a=new Z.Vector2,b=new Z.Vector2);a.set(c,c);b.set(d,d);return this.clamp(a,b)}}(),clampLength:function(a,b){var c=this.length();return this.multiplyScalar(Math.max(a,Math.min(b,c))/c)},floor:function(){this.x=Math.floor(this.x);this.y=Math.floor(this.y);return this},ceil:function(){this.x=Math.ceil(this.x);this.y=Math.ceil(this.y);return this},round:function(){this.x=Math.round(this.x);this.y=Math.round(this.y);return this},roundToZero:function(){this.x=0>this.x?Math.ceil(this.x):Math.floor(this.x);\nthis.y=0>this.y?Math.ceil(this.y):Math.floor(this.y);return this},negate:function(){this.x=-this.x;this.y=-this.y;return this},dot:function(a){return this.x*a.x+this.y*a.y},lengthSq:function(){return this.x*this.x+this.y*this.y},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y)},lengthManhattan:function(){return Math.abs(this.x)+Math.abs(this.y)},normalize:function(){return this.divideScalar(this.length())},angle:function(){var a=Math.atan2(this.y,this.x);0>a&&(a+=2*Math.PI);return a},\ndistanceTo:function(a){return Math.sqrt(this.distanceToSquared(a))},distanceToSquared:function(a){var b=this.x-a.x;a=this.y-a.y;return b*b+a*a},setLength:function(a){return this.multiplyScalar(a/this.length())},lerp:function(a,b){this.x+=(a.x-this.x)*b;this.y+=(a.y-this.y)*b;return this},lerpVectors:function(a,b,c){return this.subVectors(b,a).multiplyScalar(c).add(a)},equals:function(a){return a.x===this.x&&a.y===this.y},fromArray:function(a,b){void 0===b&&(b=0);this.x=a[b];this.y=a[b+1];return this},\ntoArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this.x;a[b+1]=this.y;return a},fromAttribute:function(a,b,c){void 0===c&&(c=0);b=b*a.itemSize+c;this.x=a.array[b];this.y=a.array[b+1];return this},rotateAround:function(a,b){var c=Math.cos(b);b=Math.sin(b);var d=this.x-a.x,e=this.y-a.y;this.x=d*c-e*b+a.x;this.y=d*b+e*c+a.y;return this}};Z.Vector3=function(a,b,c){this.x=a||0;this.y=b||0;this.z=c||0};\nZ.Vector3.prototype={constructor:Z.Vector3,set:function(a,b,c){this.x=a;this.y=b;this.z=c;return this},setScalar:function(a){this.z=this.y=this.x=a;return this},setX:function(a){this.x=a;return this},setY:function(a){this.y=a;return this},setZ:function(a){this.z=a;return this},setComponent:function(a,b){switch(a){case 0:this.x=b;break;case 1:this.y=b;break;case 2:this.z=b;break;default:throw Error(\"index is out of range: \"+a);}},getComponent:function(a){switch(a){case 0:return this.x;case 1:return this.y;\ncase 2:return this.z;default:throw Error(\"index is out of range: \"+a);}},clone:function(){return new this.constructor(this.x,this.y,this.z)},copy:function(a){this.x=a.x;this.y=a.y;this.z=a.z;return this},add:function(a,b){if(void 0!==b)return console.warn(\"THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead.\"),this.addVectors(a,b);this.x+=a.x;this.y+=a.y;this.z+=a.z;return this},addScalar:function(a){this.x+=a;this.y+=a;this.z+=a;return this},addVectors:function(a,\nb){this.x=a.x+b.x;this.y=a.y+b.y;this.z=a.z+b.z;return this},addScaledVector:function(a,b){this.x+=a.x*b;this.y+=a.y*b;this.z+=a.z*b;return this},sub:function(a,b){if(void 0!==b)return console.warn(\"THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.\"),this.subVectors(a,b);this.x-=a.x;this.y-=a.y;this.z-=a.z;return this},subScalar:function(a){this.x-=a;this.y-=a;this.z-=a;return this},subVectors:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;this.z=a.z-b.z;return this},\nmultiply:function(a,b){if(void 0!==b)return console.warn(\"THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead.\"),this.x=a.x*b.x,this.y=a.y*b.y,this.z=a.z*b.z,this;this.x*=a.x;this.y*=a.y;this.z*=a.z;return this},multiplyScalar:function(a){isFinite(a)?(this.x*=a,this.y*=a,this.z*=a):this.z=this.y=this.x=0;return this},applyEuler:function(){var a;return function(b){!1===b instanceof Z.Euler&&console.error(\"THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order.\");\nvoid 0===a&&(a=new Z.Quaternion);return Mf(this,Lf(a,b))}}(),applyAxisAngle:function(){var a;return function(b,c){void 0===a&&(a=new Z.Quaternion);return Mf(this,Kf(a,b,c))}}(),applyMatrix4:function(a){var b=this.x,c=this.y,d=this.z;a=a.elements;this.x=a[0]*b+a[4]*c+a[8]*d+a[12];this.y=a[1]*b+a[5]*c+a[9]*d+a[13];this.z=a[2]*b+a[6]*c+a[10]*d+a[14];return this},project:function(){var a;return function(b){void 0===a&&(a=new Z.Matrix4);Nf(a,b.projectionMatrix,a.getInverse(b.matrixWorld));return Of(this,\na)}}(),unproject:function(){var a;return function(b){void 0===a&&(a=new Z.Matrix4);Nf(a,b.matrixWorld,a.getInverse(b.projectionMatrix));return Of(this,a)}}(),divide:function(a){this.x/=a.x;this.y/=a.y;this.z/=a.z;return this},divideScalar:function(a){return this.multiplyScalar(1/a)},min:function(a){this.x=Math.min(this.x,a.x);this.y=Math.min(this.y,a.y);this.z=Math.min(this.z,a.z);return this},max:function(a){this.x=Math.max(this.x,a.x);this.y=Math.max(this.y,a.y);this.z=Math.max(this.z,a.z);return this},\nclamp:function(a,b){this.x=Math.max(a.x,Math.min(b.x,this.x));this.y=Math.max(a.y,Math.min(b.y,this.y));this.z=Math.max(a.z,Math.min(b.z,this.z));return this},clampScalar:function(){var a,b;return function(c,d){void 0===a&&(a=new Z.Vector3,b=new Z.Vector3);a.set(c,c,c);b.set(d,d,d);return this.clamp(a,b)}}(),clampLength:function(a,b){var c=this.length();return this.multiplyScalar(Math.max(a,Math.min(b,c))/c)},floor:function(){this.x=Math.floor(this.x);this.y=Math.floor(this.y);this.z=Math.floor(this.z);\nreturn this},ceil:function(){this.x=Math.ceil(this.x);this.y=Math.ceil(this.y);this.z=Math.ceil(this.z);return this},round:function(){this.x=Math.round(this.x);this.y=Math.round(this.y);this.z=Math.round(this.z);return this},roundToZero:function(){this.x=0>this.x?Math.ceil(this.x):Math.floor(this.x);this.y=0>this.y?Math.ceil(this.y):Math.floor(this.y);this.z=0>this.z?Math.ceil(this.z):Math.floor(this.z);return this},negate:function(){this.x=-this.x;this.y=-this.y;this.z=-this.z;return this},dot:function(a){return this.x*\na.x+this.y*a.y+this.z*a.z},lengthSq:function(){return this.x*this.x+this.y*this.y+this.z*this.z},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z)},lengthManhattan:function(){return Math.abs(this.x)+Math.abs(this.y)+Math.abs(this.z)},normalize:function(){return this.divideScalar(this.length())},setLength:function(a){return this.multiplyScalar(a/this.length())},lerp:function(a,b){this.x+=(a.x-this.x)*b;this.y+=(a.y-this.y)*b;this.z+=(a.z-this.z)*b;return this},lerpVectors:function(a,\nb,c){return this.subVectors(b,a).multiplyScalar(c).add(a)},cross:function(a,b){if(void 0!==b)return console.warn(\"THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead.\"),If(this,a,b);b=this.x;var c=this.y,d=this.z;this.x=c*a.z-d*a.y;this.y=d*a.x-b*a.z;this.z=b*a.y-c*a.x;return this},projectOnVector:function(){var a,b;return function(c){void 0===a&&(a=new Z.Vector3);a.copy(c).normalize();b=this.dot(a);return this.copy(a).multiplyScalar(b)}}(),projectOnPlane:function(){var a;\nreturn function(b){void 0===a&&(a=new Z.Vector3);a.copy(this).projectOnVector(b);return this.sub(a)}}(),reflect:function(){var a;return function(b){void 0===a&&(a=new Z.Vector3);return this.sub(a.copy(b).multiplyScalar(2*this.dot(b)))}}(),angleTo:function(a){return Math.acos(Z.Math.clamp(this.dot(a)/Math.sqrt(this.lengthSq()*a.lengthSq()),-1,1))},distanceTo:function(a){return Math.sqrt(this.distanceToSquared(a))},distanceToSquared:function(a){var b=this.x-a.x,c=this.y-a.y;a=this.z-a.z;return b*b+\nc*c+a*a},equals:function(a){return a.x===this.x&&a.y===this.y&&a.z===this.z},fromArray:function(a,b){void 0===b&&(b=0);this.x=a[b];this.y=a[b+1];this.z=a[b+2];return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this.x;a[b+1]=this.y;a[b+2]=this.z;return a},fromAttribute:function(a,b,c){void 0===c&&(c=0);b=b*a.itemSize+c;this.x=a.array[b];this.y=a.array[b+1];this.z=a.array[b+2];return this}};\nfunction Pf(a,b,c){if(\"number\"===typeof b){console.warn(\"THREE.Vector3: setFromMatrixColumn now expects ( matrix, index ).\");var d=b;b=c;c=d}return a.fromArray(b.elements,4*c)}function Qf(a,b){return Pf(a,b,3)}function If(a,b,c){var d=b.x,e=b.y;b=b.z;var f=c.x,g=c.y;c=c.z;a.x=e*c-b*g;a.y=b*f-d*c;a.z=d*g-e*f;return a}function Rf(a,b){var c=a.x,d=a.y,e=a.z;b=b.elements;a.x=b[0]*c+b[4]*d+b[8]*e;a.y=b[1]*c+b[5]*d+b[9]*e;a.z=b[2]*c+b[6]*d+b[10]*e;a.normalize()}\nfunction Mf(a,b){var c=a.x,d=a.y,e=a.z,f=b.x,g=b.y,k=b.z;b=b.w;var l=b*c+g*e-k*d,m=b*d+k*c-f*e,n=b*e+f*d-g*c,c=-f*c-g*d-k*e;a.x=l*b+c*-f+m*-k-n*-g;a.y=m*b+c*-g+n*-f-l*-k;a.z=n*b+c*-k+l*-g-m*-f;return a}function Of(a,b){var c=a.x,d=a.y,e=a.z;b=b.elements;var f=1/(b[3]*c+b[7]*d+b[11]*e+b[15]);a.x=(b[0]*c+b[4]*d+b[8]*e+b[12])*f;a.y=(b[1]*c+b[5]*d+b[9]*e+b[13])*f;a.z=(b[2]*c+b[6]*d+b[10]*e+b[14])*f;return a}\nfunction Sf(a,b){var c=a.x,d=a.y,e=a.z;b=b.elements;a.x=b[0]*c+b[3]*d+b[6]*e;a.y=b[1]*c+b[4]*d+b[7]*e;a.z=b[2]*c+b[5]*d+b[8]*e;return a}Z.Vector4=function(a,b,c,d){this.x=a||0;this.y=b||0;this.z=c||0;this.w=void 0!==d?d:1};\nZ.Vector4.prototype={constructor:Z.Vector4,set:function(a,b,c,d){this.x=a;this.y=b;this.z=c;this.w=d;return this},setScalar:function(a){this.w=this.z=this.y=this.x=a;return this},setX:function(a){this.x=a;return this},setY:function(a){this.y=a;return this},setZ:function(a){this.z=a;return this},setW:function(a){this.w=a;return this},setComponent:function(a,b){switch(a){case 0:this.x=b;break;case 1:this.y=b;break;case 2:this.z=b;break;case 3:this.w=b;break;default:throw Error(\"index is out of range: \"+\na);}},getComponent:function(a){switch(a){case 0:return this.x;case 1:return this.y;case 2:return this.z;case 3:return this.w;default:throw Error(\"index is out of range: \"+a);}},clone:function(){return new this.constructor(this.x,this.y,this.z,this.w)},copy:function(a){this.x=a.x;this.y=a.y;this.z=a.z;this.w=void 0!==a.w?a.w:1;return this},add:function(a,b){if(void 0!==b)return console.warn(\"THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead.\"),this.addVectors(a,b);\nthis.x+=a.x;this.y+=a.y;this.z+=a.z;this.w+=a.w;return this},addScalar:function(a){this.x+=a;this.y+=a;this.z+=a;this.w+=a;return this},addVectors:function(a,b){this.x=a.x+b.x;this.y=a.y+b.y;this.z=a.z+b.z;this.w=a.w+b.w;return this},addScaledVector:function(a,b){this.x+=a.x*b;this.y+=a.y*b;this.z+=a.z*b;this.w+=a.w*b;return this},sub:function(a,b){if(void 0!==b)return console.warn(\"THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.\"),this.subVectors(a,b);this.x-=\na.x;this.y-=a.y;this.z-=a.z;this.w-=a.w;return this},subScalar:function(a){this.x-=a;this.y-=a;this.z-=a;this.w-=a;return this},subVectors:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;this.z=a.z-b.z;this.w=a.w-b.w;return this},multiplyScalar:function(a){isFinite(a)?(this.x*=a,this.y*=a,this.z*=a,this.w*=a):this.w=this.z=this.y=this.x=0;return this},applyMatrix4:function(a){var b=this.x,c=this.y,d=this.z,e=this.w;a=a.elements;this.x=a[0]*b+a[4]*c+a[8]*d+a[12]*e;this.y=a[1]*b+a[5]*c+a[9]*d+a[13]*e;this.z=\na[2]*b+a[6]*c+a[10]*d+a[14]*e;this.w=a[3]*b+a[7]*c+a[11]*d+a[15]*e;return this},divideScalar:function(a){return this.multiplyScalar(1/a)},setAxisAngleFromQuaternion:function(a){this.w=2*Math.acos(a.w);var b=Math.sqrt(1-a.w*a.w);1E-4>b?(this.x=1,this.z=this.y=0):(this.x=a.x/b,this.y=a.y/b,this.z=a.z/b);return this},setAxisAngleFromRotationMatrix:function(a){a=a.elements;var b=a[0];var c=a[4];var d=a[8],e=a[1],f=a[5],g=a[9];var k=a[2];var l=a[6];var m=a[10];if(.01>Math.abs(c-e)&&.01>Math.abs(d-k)&&\n.01>Math.abs(g-l)){if(.1>Math.abs(c+e)&&.1>Math.abs(d+k)&&.1>Math.abs(g+l)&&.1>Math.abs(b+f+m-3))return this.set(1,0,0,0),this;a=Math.PI;b=(b+1)/2;f=(f+1)/2;m=(m+1)/2;c=(c+e)/4;d=(d+k)/4;g=(g+l)/4;b>f&&b>m?.01>b?(l=0,c=k=.707106781):(l=Math.sqrt(b),k=c/l,c=d/l):f>m?.01>f?(l=.707106781,k=0,c=.707106781):(k=Math.sqrt(f),l=c/k,c=g/k):.01>m?(k=l=.707106781,c=0):(c=Math.sqrt(m),l=d/c,k=g/c);this.set(l,k,c,a);return this}a=Math.sqrt((l-g)*(l-g)+(d-k)*(d-k)+(e-c)*(e-c));.001>Math.abs(a)&&(a=1);this.x=(l-\ng)/a;this.y=(d-k)/a;this.z=(e-c)/a;this.w=Math.acos((b+f+m-1)/2);return this},min:function(a){this.x=Math.min(this.x,a.x);this.y=Math.min(this.y,a.y);this.z=Math.min(this.z,a.z);this.w=Math.min(this.w,a.w);return this},max:function(a){this.x=Math.max(this.x,a.x);this.y=Math.max(this.y,a.y);this.z=Math.max(this.z,a.z);this.w=Math.max(this.w,a.w);return this},clamp:function(a,b){this.x=Math.max(a.x,Math.min(b.x,this.x));this.y=Math.max(a.y,Math.min(b.y,this.y));this.z=Math.max(a.z,Math.min(b.z,this.z));\nthis.w=Math.max(a.w,Math.min(b.w,this.w));return this},clampScalar:function(){var a,b;return function(c,d){void 0===a&&(a=new Z.Vector4,b=new Z.Vector4);a.set(c,c,c,c);b.set(d,d,d,d);return this.clamp(a,b)}}(),floor:function(){this.x=Math.floor(this.x);this.y=Math.floor(this.y);this.z=Math.floor(this.z);this.w=Math.floor(this.w);return this},ceil:function(){this.x=Math.ceil(this.x);this.y=Math.ceil(this.y);this.z=Math.ceil(this.z);this.w=Math.ceil(this.w);return this},round:function(){this.x=Math.round(this.x);\nthis.y=Math.round(this.y);this.z=Math.round(this.z);this.w=Math.round(this.w);return this},roundToZero:function(){this.x=0>this.x?Math.ceil(this.x):Math.floor(this.x);this.y=0>this.y?Math.ceil(this.y):Math.floor(this.y);this.z=0>this.z?Math.ceil(this.z):Math.floor(this.z);this.w=0>this.w?Math.ceil(this.w):Math.floor(this.w);return this},negate:function(){this.x=-this.x;this.y=-this.y;this.z=-this.z;this.w=-this.w;return this},dot:function(a){return this.x*a.x+this.y*a.y+this.z*a.z+this.w*a.w},lengthSq:function(){return this.x*\nthis.x+this.y*this.y+this.z*this.z+this.w*this.w},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w)},lengthManhattan:function(){return Math.abs(this.x)+Math.abs(this.y)+Math.abs(this.z)+Math.abs(this.w)},normalize:function(){return this.divideScalar(this.length())},setLength:function(a){return this.multiplyScalar(a/this.length())},lerp:function(a,b){this.x+=(a.x-this.x)*b;this.y+=(a.y-this.y)*b;this.z+=(a.z-this.z)*b;this.w+=(a.w-this.w)*b;return this},lerpVectors:function(a,\nb,c){return this.subVectors(b,a).multiplyScalar(c).add(a)},equals:function(a){return a.x===this.x&&a.y===this.y&&a.z===this.z&&a.w===this.w},fromArray:function(a,b){void 0===b&&(b=0);this.x=a[b];this.y=a[b+1];this.z=a[b+2];this.w=a[b+3];return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this.x;a[b+1]=this.y;a[b+2]=this.z;a[b+3]=this.w;return a},fromAttribute:function(a,b,c){void 0===c&&(c=0);b=b*a.itemSize+c;this.x=a.array[b];this.y=a.array[b+1];this.z=a.array[b+2];this.w=\na.array[b+3];return this}};Z.Euler=function(a,b,c,d){this._x=a||0;this._y=b||0;this._z=c||0;this._order=d||Z.Euler.DefaultOrder};Z.Euler.RotationOrders=\"XYZ YZX ZXY XZY YXZ ZYX\".split(\" \");Z.Euler.DefaultOrder=\"XYZ\";\nZ.Euler.prototype={constructor:Z.Euler,get x(){return this._x},set x(a){this._x=a;this.onChangeCallback()},get y(){return this._y},set y(a){this._y=a;this.onChangeCallback()},get z(){return this._z},set z(a){this._z=a;this.onChangeCallback()},get order(){return this._order},set order(a){this._order=a;this.onChangeCallback()},set:function(a,b,c,d){this._x=a;this._y=b;this._z=c;this._order=d||this._order;this.onChangeCallback();return this},clone:function(){return new this.constructor(this._x,this._y,\nthis._z,this._order)},copy:function(a){this._x=a._x;this._y=a._y;this._z=a._z;this._order=a._order;this.onChangeCallback();return this},setFromRotationMatrix:function(a,b,c){var d=Z.Math.clamp,e=a.elements;a=e[0];var f=e[4],g=e[8],k=e[1],l=e[5],m=e[9],n=e[2],q=e[6],e=e[10];b=b||this._order;\"XYZ\"===b?(this._y=Math.asin(d(g,-1,1)),.99999>Math.abs(g)?(this._x=Math.atan2(-m,e),this._z=Math.atan2(-f,a)):(this._x=Math.atan2(q,l),this._z=0)):\"YXZ\"===b?(this._x=Math.asin(-d(m,-1,1)),.99999>Math.abs(m)?(this._y=\nMath.atan2(g,e),this._z=Math.atan2(k,l)):(this._y=Math.atan2(-n,a),this._z=0)):\"ZXY\"===b?(this._x=Math.asin(d(q,-1,1)),.99999>Math.abs(q)?(this._y=Math.atan2(-n,e),this._z=Math.atan2(-f,l)):(this._y=0,this._z=Math.atan2(k,a))):\"ZYX\"===b?(this._y=Math.asin(-d(n,-1,1)),.99999>Math.abs(n)?(this._x=Math.atan2(q,e),this._z=Math.atan2(k,a)):(this._x=0,this._z=Math.atan2(-f,l))):\"YZX\"===b?(this._z=Math.asin(d(k,-1,1)),.99999>Math.abs(k)?(this._x=Math.atan2(-m,l),this._y=Math.atan2(-n,a)):(this._x=0,this._y=\nMath.atan2(g,e))):\"XZY\"===b?(this._z=Math.asin(-d(f,-1,1)),.99999>Math.abs(f)?(this._x=Math.atan2(q,l),this._y=Math.atan2(g,a)):(this._x=Math.atan2(-m,e),this._y=0)):console.warn(\"THREE.Euler: .setFromRotationMatrix() given unsupported order: \"+b);this._order=b;if(!1!==c)this.onChangeCallback();return this},setFromQuaternion:function(){var a;return function(b,c,d){void 0===a&&(a=new Z.Matrix4);Tf(a,b);return this.setFromRotationMatrix(a,c,d)}}(),setFromVector3:function(a,b){return this.set(a.x,a.y,\na.z,b||this._order)},reorder:function(){var a=new Z.Quaternion;return function(b){Lf(a,this);return this.setFromQuaternion(a,b)}}(),equals:function(a){return a._x===this._x&&a._y===this._y&&a._z===this._z&&a._order===this._order},fromArray:function(a){this._x=a[0];this._y=a[1];this._z=a[2];void 0!==a[3]&&(this._order=a[3]);this.onChangeCallback();return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this._x;a[b+1]=this._y;a[b+2]=this._z;a[b+3]=this._order;return a},toVector3:function(a){return a?\na.set(this._x,this._y,this._z):new Z.Vector3(this._x,this._y,this._z)},onChange:function(a){this.onChangeCallback=a;return this},onChangeCallback:function(){}};Z.Line3=function(a,b){this.start=void 0!==a?a:new Z.Vector3;this.end=void 0!==b?b:new Z.Vector3};\nZ.Line3.prototype={constructor:Z.Line3,set:function(a,b){this.start.copy(a);this.end.copy(b);return this},clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.start.copy(a.start);this.end.copy(a.end);return this},center:function(a){return(a||new Z.Vector3).addVectors(this.start,this.end).multiplyScalar(.5)},distanceSq:function(){return this.start.distanceToSquared(this.end)},distance:function(){return this.start.distanceTo(this.end)},at:function(a,b){return Uf(this,b||new Z.Vector3).multiplyScalar(a).add(this.start)},\nclosestPointToPointParameter:function(){var a=new Z.Vector3,b=new Z.Vector3;return function(c,d){a.subVectors(c,this.start);b.subVectors(this.end,this.start);c=b.dot(a)/b.dot(b);d&&(c=Z.Math.clamp(c,0,1));return c}}(),closestPointToPoint:function(a,b,c){a=this.closestPointToPointParameter(a,b);return Uf(this,c||new Z.Vector3).multiplyScalar(a).add(this.start)},applyMatrix4:function(a){this.start.applyMatrix4(a);this.end.applyMatrix4(a);return this},equals:function(a){return a.start.equals(this.start)&&\na.end.equals(this.end)}};function Uf(a,b){return(b||new Z.Vector3).subVectors(a.end,a.start)}Z.Box2=function(a,b){this.min=void 0!==a?a:new Z.Vector2(Infinity,Infinity);this.max=void 0!==b?b:new Z.Vector2(-Infinity,-Infinity)};\nZ.Box2.prototype={constructor:Z.Box2,set:function(a,b){this.min.copy(a);this.max.copy(b);return this},setFromPoints:function(a){this.makeEmpty();for(var b=0,c=a.length;b<c;b++)this.expandByPoint(a[b]);return this},setFromCenterAndSize:function(){var a=new Z.Vector2;return function(b,c){c=a.copy(c).multiplyScalar(.5);this.min.copy(b).sub(c);this.max.copy(b).add(c);return this}}(),clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.min.copy(a.min);this.max.copy(a.max);return this},\nmakeEmpty:function(){this.min.x=this.min.y=Infinity;this.max.x=this.max.y=-Infinity;return this},isEmpty:function(){return this.max.x<this.min.x||this.max.y<this.min.y},center:function(a){return(a||new Z.Vector2).addVectors(this.min,this.max).multiplyScalar(.5)},size:function(a){return(a||new Z.Vector2).subVectors(this.max,this.min)},expandByPoint:function(a){this.min.min(a);this.max.max(a);return this},expandByVector:function(a){this.min.sub(a);this.max.add(a);return this},expandByScalar:function(a){this.min.addScalar(-a);\nthis.max.addScalar(a);return this},containsPoint:function(a){return a.x<this.min.x||a.x>this.max.x||a.y<this.min.y||a.y>this.max.y?!1:!0},containsBox:function(a){return this.min.x<=a.min.x&&a.max.x<=this.max.x&&this.min.y<=a.min.y&&a.max.y<=this.max.y?!0:!1},getParameter:function(a,b){return(b||new Z.Vector2).set((a.x-this.min.x)/(this.max.x-this.min.x),(a.y-this.min.y)/(this.max.y-this.min.y))},intersectsBox:function(a){return a.max.x<this.min.x||a.min.x>this.max.x||a.max.y<this.min.y||a.min.y>this.max.y?\n!1:!0},clampPoint:function(a,b){return(b||new Z.Vector2).copy(a).clamp(this.min,this.max)},distanceToPoint:function(){var a=new Z.Vector2;return function(b){return a.copy(b).clamp(this.min,this.max).sub(b).length()}}(),intersect:function(a){this.min.max(a.min);this.max.min(a.max);return this},union:function(a){this.min.min(a.min);this.max.max(a.max);return this},translate:function(a){this.min.add(a);this.max.add(a);return this},equals:function(a){return a.min.equals(this.min)&&a.max.equals(this.max)}};\nZ.Box3=function(a,b){this.min=void 0!==a?a:new Z.Vector3(Infinity,Infinity,Infinity);this.max=void 0!==b?b:new Z.Vector3(-Infinity,-Infinity,-Infinity)};\nZ.Box3.prototype={constructor:Z.Box3,set:function(a,b){this.min.copy(a);this.max.copy(b);return this},setFromPoints:function(a){this.makeEmpty();for(var b=0,c=a.length;b<c;b++)this.expandByPoint(a[b]);return this},setFromCenterAndSize:function(){var a=new Z.Vector3;return function(b,c){c=a.copy(c).multiplyScalar(.5);this.min.copy(b).sub(c);this.max.copy(b).add(c);return this}}(),setFromObject:function(){var a=new Z.Vector3;return function(b){var c=this;b.updateMatrixWorld(!0);this.makeEmpty();b.traverse(function(b){var d=\nb.geometry;if(void 0!==d)if(d instanceof Z.Geometry)for(var f=d.vertices,d=0,g=f.length;d<g;d++)a.copy(f[d]),a.applyMatrix4(b.matrixWorld),c.expandByPoint(a);else if(d instanceof Z.BufferGeometry&&void 0!==d.attributes.position)for(f=d.attributes.position.array,d=0,g=f.length;d<g;d+=3)a.fromArray(f,d),a.applyMatrix4(b.matrixWorld),c.expandByPoint(a)});return this}}(),clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.min.copy(a.min);this.max.copy(a.max);return this},makeEmpty:function(){this.min.x=\nthis.min.y=this.min.z=Infinity;this.max.x=this.max.y=this.max.z=-Infinity;return this},isEmpty:function(){return this.max.x<this.min.x||this.max.y<this.min.y||this.max.z<this.min.z},center:function(a){return(a||new Z.Vector3).addVectors(this.min,this.max).multiplyScalar(.5)},size:function(a){return(a||new Z.Vector3).subVectors(this.max,this.min)},expandByPoint:function(a){this.min.min(a);this.max.max(a);return this},expandByVector:function(a){this.min.sub(a);this.max.add(a);return this},expandByScalar:function(a){this.min.addScalar(-a);\nthis.max.addScalar(a);return this},containsPoint:function(a){return a.x<this.min.x||a.x>this.max.x||a.y<this.min.y||a.y>this.max.y||a.z<this.min.z||a.z>this.max.z?!1:!0},containsBox:function(a){return this.min.x<=a.min.x&&a.max.x<=this.max.x&&this.min.y<=a.min.y&&a.max.y<=this.max.y&&this.min.z<=a.min.z&&a.max.z<=this.max.z?!0:!1},getParameter:function(a,b){return(b||new Z.Vector3).set((a.x-this.min.x)/(this.max.x-this.min.x),(a.y-this.min.y)/(this.max.y-this.min.y),(a.z-this.min.z)/(this.max.z-this.min.z))},\nintersectsBox:function(a){return a.max.x<this.min.x||a.min.x>this.max.x||a.max.y<this.min.y||a.min.y>this.max.y||a.max.z<this.min.z||a.min.z>this.max.z?!1:!0},intersectsSphere:function(){var a;return function(b){void 0===a&&(a=new Z.Vector3);this.clampPoint(b.center,a);return a.distanceToSquared(b.center)<=b.radius*b.radius}}(),intersectsPlane:function(a){if(0<a.normal.x){var b=a.normal.x*this.min.x;var c=a.normal.x*this.max.x}else b=a.normal.x*this.max.x,c=a.normal.x*this.min.x;0<a.normal.y?(b+=\na.normal.y*this.min.y,c+=a.normal.y*this.max.y):(b+=a.normal.y*this.max.y,c+=a.normal.y*this.min.y);0<a.normal.z?(b+=a.normal.z*this.min.z,c+=a.normal.z*this.max.z):(b+=a.normal.z*this.max.z,c+=a.normal.z*this.min.z);return b<=a.constant&&c>=a.constant},clampPoint:function(a,b){return(b||new Z.Vector3).copy(a).clamp(this.min,this.max)},distanceToPoint:function(){var a=new Z.Vector3;return function(b){return a.copy(b).clamp(this.min,this.max).sub(b).length()}}(),getBoundingSphere:function(){var a=\nnew Z.Vector3;return function(b){b=b||new Z.Sphere;b.center=this.center();b.radius=.5*this.size(a).length();return b}}(),intersect:function(a){this.min.max(a.min);this.max.min(a.max);this.isEmpty()&&this.makeEmpty();return this},union:function(a){this.min.min(a.min);this.max.max(a.max);return this},applyMatrix4:function(){var a=[new Z.Vector3,new Z.Vector3,new Z.Vector3,new Z.Vector3,new Z.Vector3,new Z.Vector3,new Z.Vector3,new Z.Vector3];return function(b){if(this.isEmpty())return this;a[0].set(this.min.x,\nthis.min.y,this.min.z).applyMatrix4(b);a[1].set(this.min.x,this.min.y,this.max.z).applyMatrix4(b);a[2].set(this.min.x,this.max.y,this.min.z).applyMatrix4(b);a[3].set(this.min.x,this.max.y,this.max.z).applyMatrix4(b);a[4].set(this.max.x,this.min.y,this.min.z).applyMatrix4(b);a[5].set(this.max.x,this.min.y,this.max.z).applyMatrix4(b);a[6].set(this.max.x,this.max.y,this.min.z).applyMatrix4(b);a[7].set(this.max.x,this.max.y,this.max.z).applyMatrix4(b);this.setFromPoints(a);return this}}(),translate:function(a){this.min.add(a);\nthis.max.add(a);return this},equals:function(a){return a.min.equals(this.min)&&a.max.equals(this.max)}};function Vf(a,b){for(var c=Infinity,d=Infinity,e=Infinity,f=-Infinity,g=-Infinity,k=-Infinity,l=0,m=b.length;l<m;l+=3){var n=b[l],q=b[l+1],p=b[l+2];n<c&&(c=n);q<d&&(d=q);p<e&&(e=p);n>f&&(f=n);q>g&&(g=q);p>k&&(k=p)}a.min.set(c,d,e);a.max.set(f,g,k)}Z.Matrix3=function(){this.elements=new Float32Array([1,0,0,0,1,0,0,0,1]);0<arguments.length&&console.error(\"THREE.Matrix3: the constructor no longer reads arguments. use .set() instead.\")};\nZ.Matrix3.prototype={constructor:Z.Matrix3,set:function(a,b,c,d,e,f,g,k,l){var m=this.elements;m[0]=a;m[1]=d;m[2]=g;m[3]=b;m[4]=e;m[5]=k;m[6]=c;m[7]=f;m[8]=l;return this},identity:function(){this.set(1,0,0,0,1,0,0,0,1);return this},clone:function(){return(new this.constructor).fromArray(this.elements)},copy:function(a){a=a.elements;this.set(a[0],a[3],a[6],a[1],a[4],a[7],a[2],a[5],a[8]);return this},applyToVector3Array:function(){var a;return function(b,c,d){void 0===a&&(a=new Z.Vector3);void 0===\nc&&(c=0);void 0===d&&(d=b.length);for(var e=0;e<d;e+=3,c+=3)a.fromArray(b,c),Sf(a,this),a.toArray(b,c);return b}}(),applyToBuffer:function(){var a;return function(b,c,d){void 0===a&&(a=new Z.Vector3);void 0===c&&(c=0);void 0===d&&(d=b.length/b.itemSize);for(var e=0;e<d;e++,c++)a.x=b.getX(c),a.y=b.getY(c),a.z=b.getZ(c),Sf(a,this),b.setXYZ(a.x,a.y,a.z);return b}}(),multiplyScalar:function(a){var b=this.elements;b[0]*=a;b[3]*=a;b[6]*=a;b[1]*=a;b[4]*=a;b[7]*=a;b[2]*=a;b[5]*=a;b[8]*=a;return this},determinant:function(){var a=\nthis.elements,b=a[0],c=a[1],d=a[2],e=a[3],f=a[4],g=a[5],k=a[6],l=a[7],a=a[8];return b*f*a-b*g*l-c*e*a+c*g*k+d*e*l-d*f*k},getInverse:function(a,b){a instanceof Z.Matrix4&&console.error(\"THREE.Matrix3.getInverse no longer takes a Matrix4 argument.\");var c=a.elements;a=this.elements;var d=c[0],e=c[1],f=c[2],g=c[3],k=c[4],l=c[5],m=c[6],n=c[7],c=c[8],q=c*k-l*n,p=l*m-c*g,t=n*g-k*m,r=d*q+e*p+f*t;if(0===r){if(b)throw Error(\"THREE.Matrix3.getInverse(): can't invert matrix, determinant is 0\");console.warn(\"THREE.Matrix3.getInverse(): can't invert matrix, determinant is 0\");\nreturn this.identity()}b=1/r;a[0]=q*b;a[1]=(f*n-c*e)*b;a[2]=(l*e-f*k)*b;a[3]=p*b;a[4]=(c*d-f*m)*b;a[5]=(f*g-l*d)*b;a[6]=t*b;a[7]=(e*m-n*d)*b;a[8]=(k*d-e*g)*b;return this},transpose:function(){var a=this.elements;var b=a[1];a[1]=a[3];a[3]=b;b=a[2];a[2]=a[6];a[6]=b;b=a[5];a[5]=a[7];a[7]=b;return this},flattenToArrayOffset:function(a,b){console.warn(\"THREE.Matrix3: .flattenToArrayOffset is deprecated - just use .toArray instead.\");return this.toArray(a,b)},transposeIntoArray:function(a){var b=this.elements;\na[0]=b[0];a[1]=b[3];a[2]=b[6];a[3]=b[1];a[4]=b[4];a[5]=b[7];a[6]=b[2];a[7]=b[5];a[8]=b[8];return this},fromArray:function(a){this.elements.set(a);return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);var c=this.elements;a[b]=c[0];a[b+1]=c[1];a[b+2]=c[2];a[b+3]=c[3];a[b+4]=c[4];a[b+5]=c[5];a[b+6]=c[6];a[b+7]=c[7];a[b+8]=c[8];return a}};function Wf(a,b){b=b.elements;a.set(b[0],b[4],b[8],b[1],b[5],b[9],b[2],b[6],b[10]);return a.getInverse(a).transpose()}\nZ.Matrix4=function(){this.elements=new Float32Array([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]);0<arguments.length&&console.error(\"THREE.Matrix4: the constructor no longer reads arguments. use .set() instead.\")};\nZ.Matrix4.prototype={constructor:Z.Matrix4,set:function(a,b,c,d,e,f,g,k,l,m,n,q,p,t,r,v){var w=this.elements;w[0]=a;w[4]=b;w[8]=c;w[12]=d;w[1]=e;w[5]=f;w[9]=g;w[13]=k;w[2]=l;w[6]=m;w[10]=n;w[14]=q;w[3]=p;w[7]=t;w[11]=r;w[15]=v;return this},identity:function(){this.set(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1);return this},clone:function(){return(new Z.Matrix4).fromArray(this.elements)},copy:function(a){this.elements.set(a.elements);return this},extractBasis:function(a,b,c){Pf(a,this,0);Pf(b,this,1);Pf(c,this,\n2);return this},makeBasis:function(a,b,c){this.set(a.x,b.x,c.x,0,a.y,b.y,c.y,0,a.z,b.z,c.z,0,0,0,0,1);return this},extractRotation:function(){var a;return function(b){void 0===a&&(a=new Z.Vector3);var c=this.elements,d=b.elements,e=1/Pf(a,b,0).length(),f=1/Pf(a,b,1).length();b=1/Pf(a,b,2).length();c[0]=d[0]*e;c[1]=d[1]*e;c[2]=d[2]*e;c[4]=d[4]*f;c[5]=d[5]*f;c[6]=d[6]*f;c[8]=d[8]*b;c[9]=d[9]*b;c[10]=d[10]*b;return this}}(),makeRotationFromEuler:function(a){!1===a instanceof Z.Euler&&console.error(\"THREE.Matrix: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.\");\nvar b=this.elements,c=a.x,d=a.y,e=a.z,f=Math.cos(c),c=Math.sin(c),g=Math.cos(d),d=Math.sin(d),k=Math.cos(e),e=Math.sin(e);if(\"XYZ\"===a.order){var l=f*k;var m=f*e;var n=c*k;a=c*e;b[0]=g*k;b[4]=-g*e;b[8]=d;b[1]=m+n*d;b[5]=l-a*d;b[9]=-c*g;b[2]=a-l*d;b[6]=n+m*d;b[10]=f*g}else\"YXZ\"===a.order?(l=g*k,m=g*e,n=d*k,a=d*e,b[0]=l+a*c,b[4]=n*c-m,b[8]=f*d,b[1]=f*e,b[5]=f*k,b[9]=-c,b[2]=m*c-n,b[6]=a+l*c,b[10]=f*g):\"ZXY\"===a.order?(l=g*k,m=g*e,n=d*k,a=d*e,b[0]=l-a*c,b[4]=-f*e,b[8]=n+m*c,b[1]=m+n*c,b[5]=f*k,b[9]=\na-l*c,b[2]=-f*d,b[6]=c,b[10]=f*g):\"ZYX\"===a.order?(l=f*k,m=f*e,n=c*k,a=c*e,b[0]=g*k,b[4]=n*d-m,b[8]=l*d+a,b[1]=g*e,b[5]=a*d+l,b[9]=m*d-n,b[2]=-d,b[6]=c*g,b[10]=f*g):\"YZX\"===a.order?(l=f*g,m=f*d,n=c*g,a=c*d,b[0]=g*k,b[4]=a-l*e,b[8]=n*e+m,b[1]=e,b[5]=f*k,b[9]=-c*k,b[2]=-d*k,b[6]=m*e+n,b[10]=l-a*e):\"XZY\"===a.order&&(l=f*g,m=f*d,n=c*g,a=c*d,b[0]=g*k,b[4]=-e,b[8]=d*k,b[1]=l*e+a,b[5]=f*k,b[9]=m*e-n,b[2]=n*e-m,b[6]=c*k,b[10]=a*e+l);b[3]=0;b[7]=0;b[11]=0;b[12]=0;b[13]=0;b[14]=0;b[15]=1;return this},lookAt:function(){var a,\nb,c;return function(d,e,f){void 0===a&&(a=new Z.Vector3,b=new Z.Vector3,c=new Z.Vector3);var g=this.elements;c.subVectors(d,e).normalize();0===c.lengthSq()&&(c.z=1);If(a,f,c).normalize();0===a.lengthSq()&&(c.z+=1E-4,If(a,f,c).normalize());If(b,c,a);g[0]=a.x;g[4]=b.x;g[8]=c.x;g[1]=a.y;g[5]=b.y;g[9]=c.y;g[2]=a.z;g[6]=b.z;g[10]=c.z;return this}}(),multiply:function(a,b){return void 0!==b?(console.warn(\"THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead.\"),\nNf(this,a,b)):Nf(this,this,a)},premultiply:function(a){return Nf(this,a,this)},multiplyToArray:function(a,b,c){var d=this.elements;Nf(this,a,b);c[0]=d[0];c[1]=d[1];c[2]=d[2];c[3]=d[3];c[4]=d[4];c[5]=d[5];c[6]=d[6];c[7]=d[7];c[8]=d[8];c[9]=d[9];c[10]=d[10];c[11]=d[11];c[12]=d[12];c[13]=d[13];c[14]=d[14];c[15]=d[15];return this},multiplyScalar:function(a){var b=this.elements;b[0]*=a;b[4]*=a;b[8]*=a;b[12]*=a;b[1]*=a;b[5]*=a;b[9]*=a;b[13]*=a;b[2]*=a;b[6]*=a;b[10]*=a;b[14]*=a;b[3]*=a;b[7]*=a;b[11]*=a;\nb[15]*=a;return this},applyToVector3Array:function(){var a;return function(b,c,d){void 0===a&&(a=new Z.Vector3);void 0===c&&(c=0);void 0===d&&(d=b.length);for(var e=0;e<d;e+=3,c+=3)a.fromArray(b,c),a.applyMatrix4(this),a.toArray(b,c);return b}}(),applyToBuffer:function(){var a;return function(b,c,d){void 0===a&&(a=new Z.Vector3);void 0===c&&(c=0);void 0===d&&(d=b.length/b.itemSize);for(var e=0;e<d;e++,c++)a.x=b.getX(c),a.y=b.getY(c),a.z=b.getZ(c),a.applyMatrix4(this),b.setXYZ(a.x,a.y,a.z);return b}}(),\ndeterminant:function(){var a=this.elements,b=a[0],c=a[4],d=a[8],e=a[12],f=a[1],g=a[5],k=a[9],l=a[13],m=a[2],n=a[6],q=a[10],p=a[14];return a[3]*(+e*k*n-d*l*n-e*g*q+c*l*q+d*g*p-c*k*p)+a[7]*(+b*k*p-b*l*q+e*f*q-d*f*p+d*l*m-e*k*m)+a[11]*(+b*l*n-b*g*p-e*f*n+c*f*p+e*g*m-c*l*m)+a[15]*(-d*g*m-b*k*n+b*g*q+d*f*n-c*f*q+c*k*m)},transpose:function(){var a=this.elements;var b=a[1];a[1]=a[4];a[4]=b;b=a[2];a[2]=a[8];a[8]=b;b=a[6];a[6]=a[9];a[9]=b;b=a[3];a[3]=a[12];a[12]=b;b=a[7];a[7]=a[13];a[13]=b;b=a[11];a[11]=a[14];\na[14]=b;return this},flattenToArrayOffset:function(a,b){console.warn(\"THREE.Matrix3: .flattenToArrayOffset is deprecated - just use .toArray instead.\");return this.toArray(a,b)},getPosition:function(){var a;return function(){void 0===a&&(a=new Z.Vector3);console.warn(\"THREE.Matrix4: .getPosition() has been removed. Use Vector3.setFromMatrixPosition( matrix ) instead.\");return Pf(a,this,3)}}(),setPosition:function(a){var b=this.elements;b[12]=a.x;b[13]=a.y;b[14]=a.z;return this},getInverse:function(a,\nb){var c=this.elements,d=a.elements;a=d[0];var e=d[1],f=d[2],g=d[3],k=d[4],l=d[5],m=d[6],n=d[7],q=d[8],p=d[9],t=d[10],r=d[11],v=d[12],w=d[13],z=d[14],d=d[15],y=p*z*n-w*t*n+w*m*r-l*z*r-p*m*d+l*t*d,B=v*t*n-q*z*n-v*m*r+k*z*r+q*m*d-k*t*d,A=q*w*n-v*p*n+v*l*r-k*w*r-q*l*d+k*p*d,D=v*p*m-q*w*m-v*l*t+k*w*t+q*l*z-k*p*z,E=a*y+e*B+f*A+g*D;if(0===E){if(b)throw Error(\"THREE.Matrix4.getInverse(): can't invert matrix, determinant is 0\");console.warn(\"THREE.Matrix4.getInverse(): can't invert matrix, determinant is 0\");\nreturn this.identity()}b=1/E;c[0]=y*b;c[1]=(w*t*g-p*z*g-w*f*r+e*z*r+p*f*d-e*t*d)*b;c[2]=(l*z*g-w*m*g+w*f*n-e*z*n-l*f*d+e*m*d)*b;c[3]=(p*m*g-l*t*g-p*f*n+e*t*n+l*f*r-e*m*r)*b;c[4]=B*b;c[5]=(q*z*g-v*t*g+v*f*r-a*z*r-q*f*d+a*t*d)*b;c[6]=(v*m*g-k*z*g-v*f*n+a*z*n+k*f*d-a*m*d)*b;c[7]=(k*t*g-q*m*g+q*f*n-a*t*n-k*f*r+a*m*r)*b;c[8]=A*b;c[9]=(v*p*g-q*w*g-v*e*r+a*w*r+q*e*d-a*p*d)*b;c[10]=(k*w*g-v*l*g+v*e*n-a*w*n-k*e*d+a*l*d)*b;c[11]=(q*l*g-k*p*g-q*e*n+a*p*n+k*e*r-a*l*r)*b;c[12]=D*b;c[13]=(q*w*f-v*p*f+v*e*t-a*w*\nt-q*e*z+a*p*z)*b;c[14]=(v*l*f-k*w*f-v*e*m+a*w*m+k*e*z-a*l*z)*b;c[15]=(k*p*f-q*l*f+q*e*m-a*p*m-k*e*t+a*l*t)*b;return this},scale:function(a){var b=this.elements,c=a.x,d=a.y;a=a.z;b[0]*=c;b[4]*=d;b[8]*=a;b[1]*=c;b[5]*=d;b[9]*=a;b[2]*=c;b[6]*=d;b[10]*=a;b[3]*=c;b[7]*=d;b[11]*=a;return this},decompose:function(){var a,b;return function(c,d,e){void 0===a&&(a=new Z.Vector3,b=new Z.Matrix4);var f=this.elements,g=a.set(f[0],f[1],f[2]).length(),k=a.set(f[4],f[5],f[6]).length(),l=a.set(f[8],f[9],f[10]).length();\n0>this.determinant()&&(g=-g);c.x=f[12];c.y=f[13];c.z=f[14];b.elements.set(this.elements);c=1/g;var f=1/k,m=1/l;b.elements[0]*=c;b.elements[1]*=c;b.elements[2]*=c;b.elements[4]*=f;b.elements[5]*=f;b.elements[6]*=f;b.elements[8]*=m;b.elements[9]*=m;b.elements[10]*=m;d.setFromRotationMatrix(b);e.x=g;e.y=k;e.z=l;return this}}(),makePerspective:function(a,b,c,d){a=c*Math.tan(Z.Math.DEG2RAD*a*.5);var e=-a;return Xf(this,e*b,a*b,e,a,c,d)},equals:function(a){var b=this.elements;a=a.elements;for(var c=0;16>\nc;c++)if(b[c]!==a[c])return!1;return!0},fromArray:function(a){this.elements.set(a);return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);var c=this.elements;a[b]=c[0];a[b+1]=c[1];a[b+2]=c[2];a[b+3]=c[3];a[b+4]=c[4];a[b+5]=c[5];a[b+6]=c[6];a[b+7]=c[7];a[b+8]=c[8];a[b+9]=c[9];a[b+10]=c[10];a[b+11]=c[11];a[b+12]=c[12];a[b+13]=c[13];a[b+14]=c[14];a[b+15]=c[15];return a}};\nfunction Xf(a,b,c,d,e,f,g){var k=a.elements;k[0]=2*f/(c-b);k[4]=0;k[8]=(c+b)/(c-b);k[12]=0;k[1]=0;k[5]=2*f/(e-d);k[9]=(e+d)/(e-d);k[13]=0;k[2]=0;k[6]=0;k[10]=-(g+f)/(g-f);k[14]=-2*g*f/(g-f);k[3]=0;k[7]=0;k[11]=-1;k[15]=0;return a}function Yf(a,b,c){var d=Math.cos(c);c=Math.sin(c);var e=1-d,f=b.x,g=b.y;b=b.z;var k=e*f,l=e*g;a.set(k*f+d,k*g-c*b,k*b+c*g,0,k*g+c*b,l*g+d,l*b-c*f,0,k*b-c*g,l*b+c*f,e*b*b+d,0,0,0,0,1);return a}\nfunction Zf(a,b){var c=Math.cos(b);b=Math.sin(b);a.set(c,-b,0,0,b,c,0,0,0,0,1,0,0,0,0,1)}function $f(a,b){var c=Math.cos(b);b=Math.sin(b);a.set(c,0,b,0,0,1,0,0,-b,0,c,0,0,0,0,1)}function ag(a,b){var c=Math.cos(b);b=Math.sin(b);a.set(1,0,0,0,0,c,-b,0,0,b,c,0,0,0,0,1)}\nfunction Nf(a,b,c){var d=b.elements,e=c.elements;c=a.elements;b=d[0];var f=d[4],g=d[8],k=d[12],l=d[1],m=d[5],n=d[9],q=d[13],p=d[2],t=d[6],r=d[10],v=d[14],w=d[3],z=d[7],y=d[11],d=d[15],B=e[0],A=e[4],D=e[8],E=e[12],F=e[1],I=e[5],H=e[9],C=e[13],J=e[2],M=e[6],T=e[10],U=e[14],L=e[3],S=e[7],R=e[11],e=e[15];c[0]=b*B+f*F+g*J+k*L;c[4]=b*A+f*I+g*M+k*S;c[8]=b*D+f*H+g*T+k*R;c[12]=b*E+f*C+g*U+k*e;c[1]=l*B+m*F+n*J+q*L;c[5]=l*A+m*I+n*M+q*S;c[9]=l*D+m*H+n*T+q*R;c[13]=l*E+m*C+n*U+q*e;c[2]=p*B+t*F+r*J+v*L;c[6]=p*A+\nt*I+r*M+v*S;c[10]=p*D+t*H+r*T+v*R;c[14]=p*E+t*C+r*U+v*e;c[3]=w*B+z*F+y*J+d*L;c[7]=w*A+z*I+y*M+d*S;c[11]=w*D+z*H+y*T+d*R;c[15]=w*E+z*C+y*U+d*e;return a}function Tf(a,b){var c=a.elements,d=b.x,e=b.y,f=b.z,g=b.w,k=d+d,l=e+e,m=f+f;b=d*k;var n=d*l,d=d*m,q=e*l,e=e*m,f=f*m,k=g*k,l=g*l,g=g*m;c[0]=1-(q+f);c[4]=n-g;c[8]=d+l;c[1]=n+g;c[5]=1-(b+f);c[9]=e-k;c[2]=d-l;c[6]=e+k;c[10]=1-(b+q);c[3]=0;c[7]=0;c[11]=0;c[12]=0;c[13]=0;c[14]=0;c[15]=1;return a}\nZ.Ray=function(a,b){this.origin=void 0!==a?a:new Z.Vector3;this.direction=void 0!==b?b:new Z.Vector3};\nZ.Ray.prototype={constructor:Z.Ray,set:function(a,b){this.origin.copy(a);this.direction.copy(b);return this},clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.origin.copy(a.origin);this.direction.copy(a.direction);return this},at:function(a,b){return(b||new Z.Vector3).copy(this.direction).multiplyScalar(a).add(this.origin)},lookAt:function(a){this.direction.copy(a).sub(this.origin).normalize();return this},recast:function(){var a=new Z.Vector3;return function(b){this.origin.copy(this.at(b,\na));return this}}(),closestPointToPoint:function(a,b){b=b||new Z.Vector3;b.subVectors(a,this.origin);a=b.dot(this.direction);return 0>a?b.copy(this.origin):b.copy(this.direction).multiplyScalar(a).add(this.origin)},distanceToPoint:function(a){return Math.sqrt(this.distanceSqToPoint(a))},distanceSqToPoint:function(){var a=new Z.Vector3;return function(b){var c=a.subVectors(b,this.origin).dot(this.direction);if(0>c)return this.origin.distanceToSquared(b);a.copy(this.direction).multiplyScalar(c).add(this.origin);\nreturn a.distanceToSquared(b)}}(),distanceSqToSegment:function(){var a=new Z.Vector3,b=new Z.Vector3,c=new Z.Vector3;return function(d,e,f,g){a.copy(d).add(e).multiplyScalar(.5);b.copy(e).sub(d).normalize();c.copy(this.origin).sub(a);var k=.5*d.distanceTo(e),l=-this.direction.dot(b),m=c.dot(this.direction),n=-c.dot(b),q=c.lengthSq(),p=Math.abs(1-l*l);if(0<p){d=l*n-m;e=l*m-n;var t=k*p;0<=d?e>=-t?e<=t?(k=1/p,d*=k,e*=k,l=d*(d+l*e+2*m)+e*(l*d+e+2*n)+q):(e=k,d=Math.max(0,-(l*e+m)),l=-d*d+e*(e+2*n)+q):\n(e=-k,d=Math.max(0,-(l*e+m)),l=-d*d+e*(e+2*n)+q):e<=-t?(d=Math.max(0,-(-l*k+m)),e=0<d?-k:Math.min(Math.max(-k,-n),k),l=-d*d+e*(e+2*n)+q):e<=t?(d=0,e=Math.min(Math.max(-k,-n),k),l=e*(e+2*n)+q):(d=Math.max(0,-(l*k+m)),e=0<d?k:Math.min(Math.max(-k,-n),k),l=-d*d+e*(e+2*n)+q)}else e=0<l?-k:k,d=Math.max(0,-(l*e+m)),l=-d*d+e*(e+2*n)+q;f&&f.copy(this.direction).multiplyScalar(d).add(this.origin);g&&g.copy(b).multiplyScalar(e).add(a);return l}}(),intersectSphere:function(){var a=new Z.Vector3;return function(b,\nc){a.subVectors(b.center,this.origin);var d=a.dot(this.direction),e=a.dot(a)-d*d;b=b.radius*b.radius;if(e>b)return null;b=Math.sqrt(b-e);e=d-b;d+=b;return 0>e&&0>d?null:0>e?this.at(d,c):this.at(e,c)}}(),intersectsSphere:function(a){return this.distanceToPoint(a.center)<=a.radius},intersectPlane:function(a,b){var c=a.normal.dot(this.direction);0===c?a=0===a.distanceToPoint(this.origin)?0:null:(a=-(this.origin.dot(a.normal)+a.constant)/c,a=0<=a?a:null);return null===a?null:this.at(a,b)},intersectsPlane:function(a){var b=\na.distanceToPoint(this.origin);return 0===b||0>a.normal.dot(this.direction)*b?!0:!1},intersectsBox:function(){var a=new Z.Vector3;return function(b){var c=1/this.direction.x;var d=1/this.direction.y;var e=1/this.direction.z,f=this.origin;if(0<=c){var g=(b.min.x-f.x)*c;c*=b.max.x-f.x}else g=(b.max.x-f.x)*c,c*=b.min.x-f.x;if(0<=d){var k=(b.min.y-f.y)*d;d*=b.max.y-f.y}else k=(b.max.y-f.y)*d,d*=b.min.y-f.y;if(g>d||k>c)g=null;else{if(k>g||g!==g)g=k;if(d<c||c!==c)c=d;0<=e?(k=(b.min.z-f.z)*e,b=(b.max.z-\nf.z)*e):(k=(b.max.z-f.z)*e,b=(b.min.z-f.z)*e);if(g>b||k>c)g=null;else{if(k>g||g!==g)g=k;if(b<c||c!==c)c=b;g=0>c?null:this.at(0<=g?g:c,a)}}return null!==g}}(),intersectTriangle:function(){var a=new Z.Vector3,b=new Z.Vector3,c=new Z.Vector3,d=new Z.Vector3;return function(e,f,g,k,l){b.subVectors(f,e);c.subVectors(g,e);If(d,b,c);f=this.direction.dot(d);if(0<f){if(k)return null;k=1}else if(0>f)k=-1,f=-f;else return null;a.subVectors(this.origin,e);e=k*this.direction.dot(If(c,a,c));if(0>e)return null;\ng=k*this.direction.dot(b.cross(a));if(0>g||e+g>f)return null;e=-k*a.dot(d);return 0>e?null:this.at(e/f,l)}}(),applyMatrix4:function(a){this.direction.add(this.origin).applyMatrix4(a);this.origin.applyMatrix4(a);this.direction.sub(this.origin);this.direction.normalize();return this},equals:function(a){return a.origin.equals(this.origin)&&a.direction.equals(this.direction)}};Z.Sphere=function(a,b){this.center=void 0!==a?a:new Z.Vector3;this.radius=void 0!==b?b:0};\nZ.Sphere.prototype={constructor:Z.Sphere,set:function(a,b){this.center.copy(a);this.radius=b;return this},setFromPoints:function(){var a=new Z.Box3;return function(b,c){var d=this.center;void 0!==c?d.copy(c):a.setFromPoints(b).center(d);for(var e=c=0,f=b.length;e<f;e++)c=Math.max(c,d.distanceToSquared(b[e]));this.radius=Math.sqrt(c);return this}}(),clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.center.copy(a.center);this.radius=a.radius;return this},empty:function(){return 0>=\nthis.radius},containsPoint:function(a){return a.distanceToSquared(this.center)<=this.radius*this.radius},distanceToPoint:function(a){return a.distanceTo(this.center)-this.radius},intersectsSphere:function(a){var b=this.radius+a.radius;return a.center.distanceToSquared(this.center)<=b*b},intersectsBox:function(a){return a.intersectsSphere(this)},intersectsPlane:function(a){return Math.abs(this.center.dot(a.normal)-a.constant)<=this.radius},clampPoint:function(a,b){var c=this.center.distanceToSquared(a);\nb=b||new Z.Vector3;b.copy(a);c>this.radius*this.radius&&(b.sub(this.center).normalize(),b.multiplyScalar(this.radius).add(this.center));return b},getBoundingBox:function(a){a=a||new Z.Box3;a.set(this.center,this.center);a.expandByScalar(this.radius);return a},applyMatrix4:function(a){this.center.applyMatrix4(a);a=a.elements;this.radius*=Math.sqrt(Math.max(a[0]*a[0]+a[1]*a[1]+a[2]*a[2],a[4]*a[4]+a[5]*a[5]+a[6]*a[6],a[8]*a[8]+a[9]*a[9]+a[10]*a[10]));return this},translate:function(a){this.center.add(a);\nreturn this},equals:function(a){return a.center.equals(this.center)&&a.radius===this.radius}};Z.Frustum=function(a,b,c,d,e,f){this.planes=[void 0!==a?a:new Z.Plane,void 0!==b?b:new Z.Plane,void 0!==c?c:new Z.Plane,void 0!==d?d:new Z.Plane,void 0!==e?e:new Z.Plane,void 0!==f?f:new Z.Plane]};\nZ.Frustum.prototype={constructor:Z.Frustum,set:function(a,b,c,d,e,f){var g=this.planes;g[0].copy(a);g[1].copy(b);g[2].copy(c);g[3].copy(d);g[4].copy(e);g[5].copy(f);return this},clone:function(){return(new this.constructor).copy(this)},copy:function(a){for(var b=this.planes,c=0;6>c;c++)b[c].copy(a.planes[c]);return this},intersectsObject:function(){var a=new Z.Sphere;return function(b){var c=b.geometry;null===c.boundingSphere&&c.computeBoundingSphere();a.copy(c.boundingSphere).applyMatrix4(b.matrixWorld);\nreturn this.intersectsSphere(a)}}(),intersectsSprite:function(){var a=new Z.Sphere;return function(b){a.center.set(0,0,0);a.radius=.7071067811865476;a.applyMatrix4(b.matrixWorld);return this.intersectsSphere(a)}}(),intersectsSphere:function(a){var b=this.planes,c=a.center;a=-a.radius;for(var d=0;6>d;d++)if(b[d].distanceToPoint(c)<a)return!1;return!0},intersectsBox:function(){var a=new Z.Vector3,b=new Z.Vector3;return function(c){for(var d=this.planes,e=0;6>e;e++){var f=d[e];a.x=0<f.normal.x?c.min.x:\nc.max.x;b.x=0<f.normal.x?c.max.x:c.min.x;a.y=0<f.normal.y?c.min.y:c.max.y;b.y=0<f.normal.y?c.max.y:c.min.y;a.z=0<f.normal.z?c.min.z:c.max.z;b.z=0<f.normal.z?c.max.z:c.min.z;var g=f.distanceToPoint(a),f=f.distanceToPoint(b);if(0>g&&0>f)return!1}return!0}}(),containsPoint:function(a){for(var b=this.planes,c=0;6>c;c++)if(0>b[c].distanceToPoint(a))return!1;return!0}};\nfunction bg(a,b){a=a.planes;var c=b.elements;b=c[0];var d=c[1],e=c[2],f=c[3],g=c[4],k=c[5],l=c[6],m=c[7],n=c[8],q=c[9],p=c[10],t=c[11],r=c[12],v=c[13],w=c[14],c=c[15];cg(a[0],f-b,m-g,t-n,c-r).normalize();cg(a[1],f+b,m+g,t+n,c+r).normalize();cg(a[2],f+d,m+k,t+q,c+v).normalize();cg(a[3],f-d,m-k,t-q,c-v).normalize();cg(a[4],f-e,m-l,t-p,c-w).normalize();cg(a[5],f+e,m+l,t+p,c+w).normalize()}Z.Plane=function(a,b){this.normal=void 0!==a?a:new Z.Vector3(1,0,0);this.constant=void 0!==b?b:0};\nZ.Plane.prototype={constructor:Z.Plane,set:function(a,b){this.normal.copy(a);this.constant=b;return this},setFromCoplanarPoints:function(){var a=new Z.Vector3,b=new Z.Vector3;return function(c,d,e){d=a.subVectors(e,d).cross(b.subVectors(c,d)).normalize();this.normal.copy(d);this.constant=-c.dot(this.normal);return this}}(),clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.normal.copy(a.normal);this.constant=a.constant;return this},normalize:function(){var a=1/this.normal.length();\nthis.normal.multiplyScalar(a);this.constant*=a;return this},negate:function(){this.constant*=-1;this.normal.negate();return this},distanceToPoint:function(a){return this.normal.dot(a)+this.constant},distanceToSphere:function(a){return this.distanceToPoint(a.center)-a.radius},intersectLine:function(){var a=new Z.Vector3;return function(b,c){c=c||new Z.Vector3;var d=Uf(b,a),e=this.normal.dot(d);if(0===e){if(0===this.distanceToPoint(b.start))return c.copy(b.start)}else if(e=-(b.start.dot(this.normal)+\nthis.constant)/e,!(0>e||1<e))return c.copy(d).multiplyScalar(e).add(b.start)}}(),intersectsBox:function(a){return a.intersectsPlane(this)},intersectsSphere:function(a){return a.intersectsPlane(this)},applyMatrix4:function(){var a=new Z.Vector3,b=new Z.Matrix3;return function(c,d){var e=(a||new Z.Vector3).copy(this.normal).multiplyScalar(-this.constant).applyMatrix4(c);c=d||Wf(b,c);c=Sf(this.normal,c).normalize();this.constant=-e.dot(c);return this}}(),translate:function(a){this.constant-=a.dot(this.normal);\nreturn this},equals:function(a){return a.normal.equals(this.normal)&&a.constant===this.constant}};function cg(a,b,c,d,e){a.normal.set(b,c,d);a.constant=e;return a}Z.Spherical=function(a,b,c){this.radius=void 0!==a?a:1;this.phi=void 0!==b?b:0;this.theta=void 0!==c?c:0;return this};\nZ.Spherical.prototype={constructor:Z.Spherical,set:function(a,b,c){this.radius=a;this.phi=b;this.theta=c;return this},clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.radius.copy(a.radius);this.phi.copy(a.phi);this.theta.copy(a.theta);return this},setFromVector3:function(a){this.radius=a.length();0===this.radius?this.phi=this.theta=0:(this.theta=Math.atan2(a.x,a.z),this.phi=Math.acos(Z.Math.clamp(a.y/this.radius,-1,1)));return this}};\nZ.Math={DEG2RAD:Math.PI/180,RAD2DEG:180/Math.PI,generateUUID:function(){var a=\"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\".split(\"\"),b=Array(36),c=0,d;return function(){for(var e=0;36>e;e++)8===e||13===e||18===e||23===e?b[e]=\"-\":14===e?b[e]=\"4\":(2>=c&&(c=33554432+16777216*Math.random()|0),d=c&15,c>>=4,b[e]=a[19===e?d&3|8:d]);return b.join(\"\")}}(),clamp:function(a,b,c){return Math.max(b,Math.min(c,a))},euclideanModulo:function(a,b){return(a%b+b)%b},mapLinear:function(a,b,c,d,e){return d+\n(a-b)*(e-d)/(c-b)},smoothstep:function(a,b,c){if(a<=b)return 0;if(a>=c)return 1;a=(a-b)/(c-b);return a*a*(3-2*a)},smootherstep:function(a,b,c){if(a<=b)return 0;if(a>=c)return 1;a=(a-b)/(c-b);return a*a*a*(a*(6*a-15)+10)},random16:function(){console.warn(\"THREE.Math.random16() has been deprecated. Use Math.random() instead.\");return Math.random()},randInt:function(a,b){return a+Math.floor(Math.random()*(b-a+1))},randFloat:function(a,b){return a+Math.random()*(b-a)},randFloatSpread:function(a){return a*\n(.5-Math.random())},degToRad:function(a){return a*Z.Math.DEG2RAD},radToDeg:function(a){return a*Z.Math.RAD2DEG},isPowerOfTwo:function(a){return 0===(a&a-1)&&0!==a},nearestPowerOfTwo:function(a){return Math.pow(2,Math.round(Math.log(a)/Math.LN2))},nextPowerOfTwo:function(a){a--;a|=a>>1;a|=a>>2;a|=a>>4;a|=a>>8;a|=a>>16;a++;return a}};\nZ.Spline=function(a){function b(a,b,c,d,e,f,g){a=.5*(c-a);d=.5*(d-b);return(2*(b-c)+a+d)*g+(-3*(b-c)-2*a-d)*f+a*e+b}this.points=a;var c=[],d={x:0,y:0,z:0},e,f,g,k,l,m,n,q,p;this.initFromArray=function(a){this.points=[];for(var b=0;b<a.length;b++)this.points[b]={x:a[b][0],y:a[b][1],z:a[b][2]}};this.getPoint=function(a){e=(this.points.length-1)*a;f=Math.floor(e);g=e-f;c[0]=0===f?f:f-1;c[1]=f;c[2]=f>this.points.length-2?this.points.length-1:f+1;c[3]=f>this.points.length-3?this.points.length-1:f+2;m=\nthis.points[c[0]];n=this.points[c[1]];q=this.points[c[2]];p=this.points[c[3]];k=g*g;l=g*k;d.x=b(m.x,n.x,q.x,p.x,g,k,l);d.y=b(m.y,n.y,q.y,p.y,g,k,l);d.z=b(m.z,n.z,q.z,p.z,g,k,l);return d};this.getControlPointsArray=function(){var a,b=this.points.length,c=[];for(a=0;a<b;a++){var d=this.points[a];c[a]=[d.x,d.y,d.z]}return c};this.getLength=function(a){var b=0,c=new Z.Vector3,d=new Z.Vector3,e=[],f=0;e[0]=0;a||(a=100);var g=this.points.length*a;c.copy(this.points[0]);for(a=1;a<g;a++){var k=a/g;var l=\nthis.getPoint(k);d.copy(l);f+=d.distanceTo(c);c.copy(l);k*=this.points.length-1;k=Math.floor(k);k!==b&&(e[k]=f,b=k)}e[e.length]=f;return{chunks:e,total:f}};this.reparametrizeByArcLength=function(a){var b,c=[],d=new Z.Vector3,e=this.getLength();c.push(d.copy(this.points[0]).clone());for(b=1;b<this.points.length;b++){var f=e.chunks[b]-e.chunks[b-1];var g=Math.ceil(a*f/e.total);var k=(b-1)/(this.points.length-1);var l=b/(this.points.length-1);for(f=1;f<g-1;f++){var m=k+1/g*f*(l-k);m=this.getPoint(m);\nc.push(d.copy(m).clone())}c.push(d.copy(this.points[b]).clone())}this.points=c}};Z.Triangle=function(a,b,c){this.a=void 0!==a?a:new Z.Vector3;this.b=void 0!==b?b:new Z.Vector3;this.c=void 0!==c?c:new Z.Vector3};Z.Triangle.normal=function(){var a=new Z.Vector3;return function(b,c,d,e){e=e||new Z.Vector3;e.subVectors(d,c);a.subVectors(b,c);e.cross(a);b=e.lengthSq();return 0<b?e.multiplyScalar(1/Math.sqrt(b)):e.set(0,0,0)}}();\nZ.Triangle.barycoordFromPoint=function(){var a=new Z.Vector3,b=new Z.Vector3,c=new Z.Vector3;return function(d,e,f,g,k){a.subVectors(g,e);b.subVectors(f,e);c.subVectors(d,e);d=a.dot(a);e=a.dot(b);f=a.dot(c);var l=b.dot(b);g=b.dot(c);var m=d*l-e*e;k=k||new Z.Vector3;if(0===m)return k.set(-2,-1,-1);m=1/m;l=(l*f-e*g)*m;d=(d*g-e*f)*m;return k.set(1-l-d,d,l)}}();\nZ.Triangle.containsPoint=function(){var a=new Z.Vector3;return function(b,c,d,e){b=Z.Triangle.barycoordFromPoint(b,c,d,e,a);return 0<=b.x&&0<=b.y&&1>=b.x+b.y}}();\nZ.Triangle.prototype={constructor:Z.Triangle,set:function(a,b,c){this.a.copy(a);this.b.copy(b);this.c.copy(c);return this},setFromPointsAndIndices:function(a,b,c,d){this.a.copy(a[b]);this.b.copy(a[c]);this.c.copy(a[d]);return this},clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.a.copy(a.a);this.b.copy(a.b);this.c.copy(a.c);return this},area:function(){var a=new Z.Vector3,b=new Z.Vector3;return function(){a.subVectors(this.c,this.b);b.subVectors(this.a,this.b);return.5*\na.cross(b).length()}}(),midpoint:function(a){return(a||new Z.Vector3).addVectors(this.a,this.b).add(this.c).multiplyScalar(1/3)},normal:function(a){return Z.Triangle.normal(this.a,this.b,this.c,a)},plane:function(a){return(a||new Z.Plane).setFromCoplanarPoints(this.a,this.b,this.c)},barycoordFromPoint:function(a,b){return Z.Triangle.barycoordFromPoint(a,this.a,this.b,this.c,b)},containsPoint:function(a){return Z.Triangle.containsPoint(a,this.a,this.b,this.c)},closestPointToPoint:function(){var a,\nb,c,d;return function(e,f){void 0===a&&(a=new Z.Plane,b=[new Z.Line3,new Z.Line3,new Z.Line3],c=new Z.Vector3,d=new Z.Vector3);f=f||new Z.Vector3;var g=Infinity;a.setFromCoplanarPoints(this.a,this.b,this.c);var k=a,l=c,m=k.distanceToPoint(e);(l||new Z.Vector3).copy(k.normal).multiplyScalar(m).sub(e).negate();if(!0===this.containsPoint(c))f.copy(c);else for(b[0].set(this.a,this.b),b[1].set(this.b,this.c),b[2].set(this.c,this.a),e=0;e<b.length;e++)b[e].closestPointToPoint(c,!0,d),k=c.distanceToSquared(d),\nk<g&&(g=k,f.copy(d));return f}}(),equals:function(a){return a.a.equals(this.a)&&a.b.equals(this.b)&&a.c.equals(this.c)}};Z.Interpolant=function(a,b,c,d){this.parameterPositions=a;this._cachedIndex=0;this.resultBuffer=void 0!==d?d:new b.constructor(c);this.sampleValues=b;this.valueSize=c};\nZ.Interpolant.prototype={constructor:Z.Interpolant,evaluate:function(a){var b=this.parameterPositions,c=this._cachedIndex,d=b[c],e=b[c-1];a:{b:{c:{d:if(!(a<d)){for(var f=c+2;;){if(void 0===d){if(a<e)break d;this._cachedIndex=c=b.length;return this.afterEnd_(c-1,a,e)}if(c===f)break;e=d;d=b[++c];if(a<d)break b}d=b.length;break c}if(a>=e)break a;else{f=b[1];a<f&&(c=2,e=f);for(f=c-2;;){if(void 0===e)return this._cachedIndex=0,this.beforeStart_(0,a,d);if(c===f)break;d=e;e=b[--c-1];if(a>=e)break b}d=c;\nc=0}}for(;c<d;)e=c+d>>>1,a<b[e]?d=e:c=e+1;d=b[c];e=b[c-1];if(void 0===e)return this._cachedIndex=0,this.beforeStart_(0,a,d);if(void 0===d)return this._cachedIndex=c=b.length,this.afterEnd_(c-1,e,a)}this._cachedIndex=c;this.intervalChanged_(c,e,d)}return this.interpolate_(c,e,a,d)},settings:null,DefaultSettings_:{},copySampleValue_:function(a){var b=this.resultBuffer,c=this.sampleValues,d=this.valueSize;a*=d;for(var e=0;e!==d;++e)b[e]=c[a+e];return b},interpolate_:function(){throw Error(\"call to abstract method\");\n},intervalChanged_:function(){}};Object.assign(Z.Interpolant.prototype,{beforeStart_:Z.Interpolant.prototype.copySampleValue_,afterEnd_:Z.Interpolant.prototype.copySampleValue_});Z.CubicInterpolant=function(a,b,c,d){Z.Interpolant.call(this,a,b,c,d);this._offsetNext=this._weightNext=this._offsetPrev=this._weightPrev=-0};\nZ.CubicInterpolant.prototype=Object.assign(Object.create(Z.Interpolant.prototype),{constructor:Z.CubicInterpolant,DefaultSettings_:{endingStart:Z.ZeroCurvatureEnding,endingEnd:Z.ZeroCurvatureEnding},intervalChanged_:function(a,b,c){var d=this.parameterPositions,e=a-2,f=a+1,g=d[e],k=d[f];if(void 0===g)switch((this.settings||this.DefaultSettings_).endingStart){case Z.ZeroSlopeEnding:e=a;g=2*b-c;break;case Z.WrapAroundEnding:e=d.length-2;g=b+d[e]-d[e+1];break;default:e=a,g=c}if(void 0===k)switch((this.settings||\nthis.DefaultSettings_).endingEnd){case Z.ZeroSlopeEnding:f=a;k=2*c-b;break;case Z.WrapAroundEnding:f=1;k=c+d[1]-d[0];break;default:f=a-1,k=b}a=.5*(c-b);d=this.valueSize;this._weightPrev=a/(b-g);this._weightNext=a/(k-c);this._offsetPrev=e*d;this._offsetNext=f*d},interpolate_:function(a,b,c,d){var e=this.resultBuffer,f=this.sampleValues,g=this.valueSize;a*=g;var k=a-g,l=this._offsetPrev,m=this._offsetNext,n=this._weightPrev,q=this._weightNext,p=(c-b)/(d-b);c=p*p;d=c*p;b=-n*d+2*n*c-n*p;n=(1+n)*d+(-1.5-\n2*n)*c+(-.5+n)*p+1;p=(-1-q)*d+(1.5+q)*c+.5*p;q=q*d-q*c;for(c=0;c!==g;++c)e[c]=b*f[l+c]+n*f[k+c]+p*f[a+c]+q*f[m+c];return e}});Z.DiscreteInterpolant=function(a,b,c,d){Z.Interpolant.call(this,a,b,c,d)};Z.DiscreteInterpolant.prototype=Object.assign(Object.create(Z.Interpolant.prototype),{constructor:Z.DiscreteInterpolant,interpolate_:function(a){return this.copySampleValue_(a-1)}});Z.LinearInterpolant=function(a,b,c,d){Z.Interpolant.call(this,a,b,c,d)};\nZ.LinearInterpolant.prototype=Object.assign(Object.create(Z.Interpolant.prototype),{constructor:Z.LinearInterpolant,interpolate_:function(a,b,c,d){var e=this.resultBuffer,f=this.sampleValues,g=this.valueSize;a*=g;var k=a-g;b=(c-b)/(d-b);c=1-b;for(d=0;d!==g;++d)e[d]=f[k+d]*c+f[a+d]*b;return e}});Z.QuaternionLinearInterpolant=function(a,b,c,d){Z.Interpolant.call(this,a,b,c,d)};\nZ.QuaternionLinearInterpolant.prototype=Object.assign(Object.create(Z.Interpolant.prototype),{constructor:Z.QuaternionLinearInterpolant,interpolate_:function(a,b,c,d){var e=this.resultBuffer,f=this.sampleValues,g=this.valueSize;a*=g;b=(c-b)/(d-b);for(c=a+g;a!==c;a+=4)Z.Quaternion.slerpFlat(e,0,f,a-g,f,a,b);return e}});Z.Clock=function(a){this.autoStart=void 0!==a?a:!0;this.elapsedTime=this.oldTime=this.startTime=0;this.running=!1};\nZ.Clock.prototype={constructor:Z.Clock,start:function(){this.oldTime=this.startTime=(performance||Date).now();this.running=!0},stop:function(){this.autoStart&&!this.running&&this.start();if(this.running){var a=(performance||Date).now();var b=(a-this.oldTime)/1E3;this.oldTime=a;this.elapsedTime+=b}this.running=!1}};Z.EventDispatcher=function(){};\nObject.assign(Z.EventDispatcher.prototype,{addEventListener:function(a,b){void 0===this._listeners&&(this._listeners={});var c=this._listeners;void 0===c[a]&&(c[a]=[]);-1===c[a].indexOf(b)&&c[a].push(b)},hasEventListener:function(a,b){if(void 0===this._listeners)return!1;var c=this._listeners;return void 0!==c[a]&&-1!==c[a].indexOf(b)?!0:!1},removeEventListener:function(a,b){void 0!==this._listeners&&(a=this._listeners[a],void 0!==a&&(b=a.indexOf(b),-1!==b&&a.splice(b,1)))},dispatchEvent:function(a){if(void 0!==\nthis._listeners){var b=this._listeners[a.type];if(void 0!==b){a.target=this;var c=[],d,e=b.length;for(d=0;d<e;d++)c[d]=b[d];for(d=0;d<e;d++)c[d].call(this,a)}}}});Z.Layers=function(){this.mask=1};Z.Layers.prototype={constructor:Z.Layers,set:function(a){this.mask=1<<a},enable:function(a){this.mask|=1<<a},toggle:function(a){this.mask^=1<<a},disable:function(a){this.mask&=~(1<<a)},test:function(a){return 0!==(this.mask&a.mask)}};\n(function(a){function b(a,b){return a.distance-b.distance}function c(a,b,f,g){if(!1!==a.visible&&(a.raycast(b,f),!0===g)){a=a.children;g=0;for(var d=a.length;g<d;g++)c(a[g],b,f,!0)}}a.Raycaster=function(b,c,f,g){this.ray=new a.Ray(b,c);this.near=f||0;this.far=g||Infinity;this.params={Mesh:{},Line:{},LOD:{},Points:{threshold:1},Sprite:{}};Object.defineProperties(this.params,{PointCloud:{get:function(){console.warn(\"THREE.Raycaster: params.PointCloud has been renamed to params.Points.\");return this.Points}}})};\na.Raycaster.prototype={constructor:a.Raycaster,linePrecision:1,set:function(a,b){this.ray.set(a,b)},setFromCamera:function(b,c){c instanceof a.PerspectiveCamera?(Qf(this.ray.origin,c.matrixWorld),this.ray.direction.set(b.x,b.y,.5).unproject(c).sub(this.ray.origin).normalize()):c instanceof a.OrthographicCamera?(this.ray.origin.set(b.x,b.y,-1).unproject(c),Rf(this.ray.direction.set(0,0,-1),c.matrixWorld)):console.error(\"THREE.Raycaster: Unsupported camera type.\")},intersectObject:function(a,e){var d=\n[];c(a,this,d,e);d.sort(b);return d},intersectObjects:function(a,e){var d=[];if(!1===Array.isArray(a))return console.warn(\"THREE.Raycaster.intersectObjects: objects is not an Array.\"),d;for(var g=0,k=a.length;g<k;g++)c(a[g],this,d,e);d.sort(b);return d}}})(Z);\nZ.Object3D=function(){Object.defineProperty(this,\"id\",{value:Z.Object3DIdCount++});this.uuid=Z.Math.generateUUID();this.name=\"\";this.type=\"Object3D\";this.parent=null;this.children=[];this.up=Z.Object3D.DefaultUp.clone();var a=new Z.Vector3,b=new Z.Euler,c=new Z.Quaternion,d=new Z.Vector3(1,1,1);b.onChange(function(){Lf(c,b,!1)});c.onChange(function(){b.setFromQuaternion(c,void 0,!1)});Object.defineProperties(this,{position:{enumerable:!0,value:a},rotation:{enumerable:!0,value:b},quaternion:{enumerable:!0,\nvalue:c},scale:{enumerable:!0,value:d},modelViewMatrix:{value:new Z.Matrix4},normalMatrix:{value:new Z.Matrix3}});this.matrix=new Z.Matrix4;this.matrixWorld=new Z.Matrix4;this.matrixAutoUpdate=Z.Object3D.DefaultMatrixAutoUpdate;this.matrixWorldNeedsUpdate=!1;this.layers=new Z.Layers;this.visible=!0;this.receiveShadow=this.castShadow=!1;this.frustumCulled=!0;this.renderOrder=0;this.userData={}};Z.Object3D.DefaultUp=new Z.Vector3(0,1,0);Z.Object3D.DefaultMatrixAutoUpdate=!0;\nObject.assign(Z.Object3D.prototype,Z.EventDispatcher.prototype,{applyMatrix:function(a){Nf(this.matrix,a,this.matrix);this.matrix.decompose(this.position,this.quaternion,this.scale)},setRotationFromAxisAngle:function(a,b){Kf(this.quaternion,a,b)},setRotationFromEuler:function(a){Lf(this.quaternion,a,!0)},setRotationFromMatrix:function(a){this.quaternion.setFromRotationMatrix(a)},setRotationFromQuaternion:function(a){this.quaternion.copy(a)},rotateOnAxis:function(){var a=new Z.Quaternion;return function(b,\nc){Kf(a,b,c);this.quaternion.multiply(a);return this}}(),rotateX:function(){var a=new Z.Vector3(1,0,0);return function(b){return this.rotateOnAxis(a,b)}}(),rotateY:function(){var a=new Z.Vector3(0,1,0);return function(b){return this.rotateOnAxis(a,b)}}(),rotateZ:function(){var a=new Z.Vector3(0,0,1);return function(b){return this.rotateOnAxis(a,b)}}(),translateOnAxis:function(){var a=new Z.Vector3;return function(b,c){Mf(a.copy(b),this.quaternion);this.position.add(a.multiplyScalar(c));return this}}(),\ntranslateX:function(){var a=new Z.Vector3(1,0,0);return function(b){return this.translateOnAxis(a,b)}}(),translateY:function(){var a=new Z.Vector3(0,1,0);return function(b){return this.translateOnAxis(a,b)}}(),translateZ:function(){var a=new Z.Vector3(0,0,1);return function(b){return this.translateOnAxis(a,b)}}(),localToWorld:function(a){return a.applyMatrix4(this.matrixWorld)},worldToLocal:function(){var a=new Z.Matrix4;return function(b){return b.applyMatrix4(a.getInverse(this.matrixWorld))}}(),\nlookAt:function(){var a=new Z.Matrix4;return function(b){a.lookAt(b,this.position,this.up);this.quaternion.setFromRotationMatrix(a)}}(),add:function(a){if(1<arguments.length){for(var b=0;b<arguments.length;b++)this.add(arguments[b]);return this}if(a===this)return console.error(\"THREE.Object3D.add: object can't be added as a child of itself.\",a),this;a instanceof Z.Object3D?(null!==a.parent&&a.parent.remove(a),a.parent=this,a.dispatchEvent({type:\"added\"}),this.children.push(a)):console.error(\"THREE.Object3D.add: object not an instance of THREE.Object3D.\",\na);return this},remove:function(a){if(1<arguments.length)for(var b=0;b<arguments.length;b++)this.remove(arguments[b]);b=this.children.indexOf(a);-1!==b&&(a.parent=null,a.dispatchEvent({type:\"removed\"}),this.children.splice(b,1))},getObjectById:function(a){return this.getObjectByProperty(\"id\",a)},getObjectByName:function(a){return this.getObjectByProperty(\"name\",a)},getObjectByProperty:function(a,b){if(this[a]===b)return this;for(var c=0,d=this.children.length;c<d;c++){var e=this.children[c].getObjectByProperty(a,\nb);if(void 0!==e)return e}},getWorldPosition:function(a){a=a||new Z.Vector3;this.updateMatrixWorld(!0);return Qf(a,this.matrixWorld)},getWorldQuaternion:function(){var a=new Z.Vector3,b=new Z.Vector3;return function(c){c=c||new Z.Quaternion;this.updateMatrixWorld(!0);this.matrixWorld.decompose(a,c,b);return c}}(),getWorldRotation:function(){var a=new Z.Quaternion;return function(b){b=b||new Z.Euler;this.getWorldQuaternion(a);return b.setFromQuaternion(a,this.rotation.order,!1)}}(),getWorldScale:function(){var a=\nnew Z.Vector3,b=new Z.Quaternion;return function(c){c=c||new Z.Vector3;this.updateMatrixWorld(!0);this.matrixWorld.decompose(a,b,c);return c}}(),getWorldDirection:function(){var a=new Z.Quaternion;return function(b){b=b||new Z.Vector3;this.getWorldQuaternion(a);return Mf(b.set(0,0,1),a)}}(),raycast:function(){},traverse:function(a){a(this);for(var b=this.children,c=0,d=b.length;c<d;c++)b[c].traverse(a)},traverseVisible:function(a){if(!1!==this.visible){a(this);for(var b=this.children,c=0,d=b.length;c<\nd;c++)b[c].traverseVisible(a)}},traverseAncestors:function(a){var b=this.parent;null!==b&&(a(b),b.traverseAncestors(a))},updateMatrix:function(){var a=this.matrix,b=this.position,c=this.scale;Tf(a,this.quaternion);a.scale(c);a.setPosition(b);this.matrixWorldNeedsUpdate=!0},updateMatrixWorld:function(a){!0===this.matrixAutoUpdate&&this.updateMatrix();if(!0===this.matrixWorldNeedsUpdate||!0===a)null===this.parent?this.matrixWorld.copy(this.matrix):Nf(this.matrixWorld,this.parent.matrixWorld,this.matrix),\nthis.matrixWorldNeedsUpdate=!1,a=!0;for(var b=0,c=this.children.length;b<c;b++)this.children[b].updateMatrixWorld(a)},toJSON:function(a){function b(a){var b=[],c;for(c in a){var d=a[c];delete d.metadata;b.push(d)}return b}var c=void 0===a||\"\"===a,d={};c&&(a={geometries:{},materials:{},textures:{},images:{}},d.metadata={version:4.4,type:\"Object\",generator:\"Object3D.toJSON\"});var e={};e.uuid=this.uuid;e.type=this.type;\"\"!==this.name&&(e.name=this.name);\"{}\"!==JSON.stringify(this.userData)&&(e.userData=\nthis.userData);!0===this.castShadow&&(e.castShadow=!0);!0===this.receiveShadow&&(e.receiveShadow=!0);!1===this.visible&&(e.visible=!1);e.matrix=this.matrix.toArray();void 0!==this.geometry&&(void 0===a.geometries[this.geometry.uuid]&&(a.geometries[this.geometry.uuid]=this.geometry.toJSON(a)),e.geometry=this.geometry.uuid);void 0!==this.material&&(void 0===a.materials[this.material.uuid]&&(a.materials[this.material.uuid]=this.material.toJSON(a)),e.material=this.material.uuid);if(0<this.children.length){e.children=\n[];for(var f=0;f<this.children.length;f++)e.children.push(this.children[f].toJSON(a).object)}if(c){var c=b(a.geometries),f=b(a.materials),g=b(a.textures);a=b(a.images);0<c.length&&(d.geometries=c);0<f.length&&(d.materials=f);0<g.length&&(d.textures=g);0<a.length&&(d.images=a)}d.object=e;return d},clone:function(a){return(new this.constructor).copy(this,a)},copy:function(a,b){void 0===b&&(b=!0);this.name=a.name;this.up.copy(a.up);this.position.copy(a.position);this.quaternion.copy(a.quaternion);this.scale.copy(a.scale);\nthis.matrix.copy(a.matrix);this.matrixWorld.copy(a.matrixWorld);this.matrixAutoUpdate=a.matrixAutoUpdate;this.matrixWorldNeedsUpdate=a.matrixWorldNeedsUpdate;this.visible=a.visible;this.castShadow=a.castShadow;this.receiveShadow=a.receiveShadow;this.frustumCulled=a.frustumCulled;this.renderOrder=a.renderOrder;this.userData=JSON.parse(JSON.stringify(a.userData));if(!0===b)for(b=0;b<a.children.length;b++)this.add(a.children[b].clone());return this}});Z.Object3DIdCount=0;\nZ.Face3=function(a,b,c,d,e,f){this.a=a;this.b=b;this.c=c;this.normal=d instanceof Z.Vector3?d:new Z.Vector3;this.vertexNormals=Array.isArray(d)?d:[];this.color=e instanceof Z.Color?e:new Z.Color;this.vertexColors=Array.isArray(e)?e:[];this.materialIndex=void 0!==f?f:0};\nZ.Face3.prototype={constructor:Z.Face3,clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.a=a.a;this.b=a.b;this.c=a.c;this.normal.copy(a.normal);this.color.copy(a.color);this.materialIndex=a.materialIndex;for(var b=0,c=a.vertexNormals.length;b<c;b++)this.vertexNormals[b]=a.vertexNormals[b].clone();b=0;for(c=a.vertexColors.length;b<c;b++)this.vertexColors[b]=a.vertexColors[b].clone();return this}};\nZ.BufferAttribute=function(a,b,c){this.uuid=Z.Math.generateUUID();this.array=a;this.itemSize=b;this.dynamic=!1;this.updateRange={offset:0,count:-1};this.version=0;this.normalized=!0===c};\nZ.BufferAttribute.prototype={constructor:Z.BufferAttribute,get count(){return this.array.length/this.itemSize},set needsUpdate(a){!0===a&&this.version++},setDynamic:function(a){this.dynamic=a;return this},copy:function(a){this.array=new a.array.constructor(a.array);this.itemSize=a.itemSize;this.dynamic=a.dynamic;return this},copyAt:function(a,b,c){a*=this.itemSize;c*=b.itemSize;for(var d=0,e=this.itemSize;d<e;d++)this.array[a+d]=b.array[c+d];return this},set:function(a,b){void 0===b&&(b=0);this.array.set(a,\nb);return this},getX:function(a){return this.array[a*this.itemSize]},setX:function(a,b){this.array[a*this.itemSize]=b;return this},getY:function(a){return this.array[a*this.itemSize+1]},setY:function(a,b){this.array[a*this.itemSize+1]=b;return this},getZ:function(a){return this.array[a*this.itemSize+2]},setZ:function(a,b){this.array[a*this.itemSize+2]=b;return this},getW:function(a){return this.array[a*this.itemSize+3]},setW:function(a,b){this.array[a*this.itemSize+3]=b;return this},setXY:function(a,\nb,c){a*=this.itemSize;this.array[a+0]=b;this.array[a+1]=c;return this},setXYZ:function(a,b,c,d){a*=this.itemSize;this.array[a+0]=b;this.array[a+1]=c;this.array[a+2]=d;return this},setXYZW:function(a,b,c,d,e){a*=this.itemSize;this.array[a+0]=b;this.array[a+1]=c;this.array[a+2]=d;this.array[a+3]=e;return this},clone:function(){return(new this.constructor).copy(this)}};\nfunction dg(a,b){for(var c=a.array,d=0,e=0,f=b.length;e<f;e++){var g=b[e];void 0===g&&(console.warn(\"THREE.BufferAttribute.copyVector4sArray(): vector is undefined\",e),g=new Z.Vector4);c[d++]=g.x;c[d++]=g.y;c[d++]=g.z;c[d++]=g.w}return a}function eg(a,b){for(var c=a.array,d=0,e=0,f=b.length;e<f;e++){var g=b[e];void 0===g&&(console.warn(\"THREE.BufferAttribute.copyVector3sArray(): vector is undefined\",e),g=new Z.Vector3);c[d++]=g.x;c[d++]=g.y;c[d++]=g.z}return a}\nfunction fg(a,b){for(var c=a.array,d=0,e=0,f=b.length;e<f;e++){var g=b[e];void 0===g&&(console.warn(\"THREE.BufferAttribute.copyVector2sArray(): vector is undefined\",e),g=new Z.Vector2);c[d++]=g.x;c[d++]=g.y}return a}function gg(a,b){for(var c=a.array,d=0,e=0,f=b.length;e<f;e++){var g=b[e];c[d++]=g.a;c[d++]=g.b;c[d++]=g.c}return a}\nfunction hg(a,b){for(var c=a.array,d=0,e=0,f=b.length;e<f;e++){var g=b[e];void 0===g&&(console.warn(\"THREE.BufferAttribute.copyColorsArray(): color is undefined\",e),g=new Z.Color);c[d++]=g.r;c[d++]=g.g;c[d++]=g.b}return a}function ig(a,b){a.array.set(b);return a}Z.Int8Attribute=function(a,b){return new Z.BufferAttribute(new Int8Array(a),b)};Z.Uint8Attribute=function(a,b){return new Z.BufferAttribute(new Uint8Array(a),b)};\nZ.Uint8ClampedAttribute=function(a,b){return new Z.BufferAttribute(new Uint8ClampedArray(a),b)};Z.Int16Attribute=function(a,b){return new Z.BufferAttribute(new Int16Array(a),b)};Z.Uint16Attribute=function(a,b){return new Z.BufferAttribute(new Uint16Array(a),b)};Z.Int32Attribute=function(a,b){return new Z.BufferAttribute(new Int32Array(a),b)};Z.Uint32Attribute=function(a,b){return new Z.BufferAttribute(new Uint32Array(a),b)};\nZ.Float32Attribute=function(a,b){return new Z.BufferAttribute(new Float32Array(a),b)};Z.Float64Attribute=function(a,b){return new Z.BufferAttribute(new Float64Array(a),b)};Z.DynamicBufferAttribute=function(a,b){console.warn(\"THREE.DynamicBufferAttribute has been removed. Use new THREE.BufferAttribute().setDynamic( true ) instead.\");return(new Z.BufferAttribute(a,b)).setDynamic(!0)};Z.InstancedBufferAttribute=function(a,b,c){Z.BufferAttribute.call(this,a,b);this.meshPerAttribute=c||1};\nZ.InstancedBufferAttribute.prototype=Object.create(Z.BufferAttribute.prototype);Z.InstancedBufferAttribute.prototype.constructor=Z.InstancedBufferAttribute;Z.InstancedBufferAttribute.prototype.copy=function(a){Z.BufferAttribute.prototype.copy.call(this,a);this.meshPerAttribute=a.meshPerAttribute;return this};Z.InterleavedBuffer=function(a,b){this.uuid=Z.Math.generateUUID();this.array=a;this.stride=b;this.dynamic=!1;this.updateRange={offset:0,count:-1};this.version=0};\nZ.InterleavedBuffer.prototype={constructor:Z.InterleavedBuffer,get length(){return this.array.length},get count(){return this.array.length/this.stride},set needsUpdate(a){!0===a&&this.version++},setDynamic:function(a){this.dynamic=a;return this},copy:function(a){this.array=new a.array.constructor(a.array);this.stride=a.stride;this.dynamic=a.dynamic;return this},copyAt:function(a,b,c){a*=this.stride;c*=b.stride;for(var d=0,e=this.stride;d<e;d++)this.array[a+d]=b.array[c+d];return this},set:function(a,\nb){void 0===b&&(b=0);this.array.set(a,b);return this},clone:function(){return(new this.constructor).copy(this)}};Z.InstancedInterleavedBuffer=function(a,b,c){Z.InterleavedBuffer.call(this,a,b);this.meshPerAttribute=c||1};Z.InstancedInterleavedBuffer.prototype=Object.create(Z.InterleavedBuffer.prototype);Z.InstancedInterleavedBuffer.prototype.constructor=Z.InstancedInterleavedBuffer;\nZ.InstancedInterleavedBuffer.prototype.copy=function(a){Z.InterleavedBuffer.prototype.copy.call(this,a);this.meshPerAttribute=a.meshPerAttribute;return this};Z.InterleavedBufferAttribute=function(a,b,c){this.uuid=Z.Math.generateUUID();this.data=a;this.itemSize=b;this.offset=c};\nZ.InterleavedBufferAttribute.prototype={constructor:Z.InterleavedBufferAttribute,get length(){console.warn(\"THREE.BufferAttribute: .length has been deprecated. Please use .count.\");return this.array.length},get count(){return this.data.count},setX:function(a,b){this.data.array[a*this.data.stride+this.offset]=b;return this},setY:function(a,b){this.data.array[a*this.data.stride+this.offset+1]=b;return this},setZ:function(a,b){this.data.array[a*this.data.stride+this.offset+2]=b;return this},setW:function(a,\nb){this.data.array[a*this.data.stride+this.offset+3]=b;return this},getX:function(a){return this.data.array[a*this.data.stride+this.offset]},getY:function(a){return this.data.array[a*this.data.stride+this.offset+1]},getZ:function(a){return this.data.array[a*this.data.stride+this.offset+2]},getW:function(a){return this.data.array[a*this.data.stride+this.offset+3]},setXY:function(a,b,c){a=a*this.data.stride+this.offset;this.data.array[a+0]=b;this.data.array[a+1]=c;return this},setXYZ:function(a,b,c,\nd){a=a*this.data.stride+this.offset;this.data.array[a+0]=b;this.data.array[a+1]=c;this.data.array[a+2]=d;return this},setXYZW:function(a,b,c,d,e){a=a*this.data.stride+this.offset;this.data.array[a+0]=b;this.data.array[a+1]=c;this.data.array[a+2]=d;this.data.array[a+3]=e;return this}};\nZ.Geometry=function(){Object.defineProperty(this,\"id\",{value:Z.GeometryIdCount++});this.uuid=Z.Math.generateUUID();this.name=\"\";this.type=\"Geometry\";this.vertices=[];this.colors=[];this.faces=[];this.faceVertexUvs=[[]];this.morphTargets=[];this.morphNormals=[];this.skinWeights=[];this.skinIndices=[];this.lineDistances=[];this.boundingSphere=this.boundingBox=null;this.groupsNeedUpdate=this.lineDistancesNeedUpdate=this.colorsNeedUpdate=this.normalsNeedUpdate=this.uvsNeedUpdate=this.elementsNeedUpdate=\nthis.verticesNeedUpdate=!1};\nObject.assign(Z.Geometry.prototype,Z.EventDispatcher.prototype,{applyMatrix:function(a){for(var b=Wf(new Z.Matrix3,a),c=0,d=this.vertices.length;c<d;c++)this.vertices[c].applyMatrix4(a);c=0;for(d=this.faces.length;c<d;c++){a=this.faces[c];Sf(a.normal,b).normalize();for(var e=0,f=a.vertexNormals.length;e<f;e++)Sf(a.vertexNormals[e],b).normalize()}null!==this.boundingBox&&this.computeBoundingBox();null!==this.boundingSphere&&this.computeBoundingSphere();this.normalsNeedUpdate=this.verticesNeedUpdate=\n!0;return this},rotateX:function(){var a;return function(b){void 0===a&&(a=new Z.Matrix4);ag(a,b);this.applyMatrix(a);return this}}(),rotateY:function(){var a;return function(b){void 0===a&&(a=new Z.Matrix4);$f(a,b);this.applyMatrix(a);return this}}(),rotateZ:function(){var a;return function(b){void 0===a&&(a=new Z.Matrix4);Zf(a,b);this.applyMatrix(a);return this}}(),translate:function(){var a;return function(b,c,d){void 0===a&&(a=new Z.Matrix4);a.set(1,0,0,b,0,1,0,c,0,0,1,d,0,0,0,1);this.applyMatrix(a);\nreturn this}}(),scale:function(){var a;return function(b,c,d){void 0===a&&(a=new Z.Matrix4);a.set(b,0,0,0,0,c,0,0,0,0,d,0,0,0,0,1);this.applyMatrix(a);return this}}(),lookAt:function(){var a;return function(b){void 0===a&&(a=new Z.Object3D);a.lookAt(b);a.updateMatrix();this.applyMatrix(a.matrix)}}(),fromBufferGeometry:function(a){function b(a,b,d,e){var f=void 0!==g?[n[a].clone(),n[b].clone(),n[d].clone()]:[],r=void 0!==k?[c.colors[a].clone(),c.colors[b].clone(),c.colors[d].clone()]:[];e=new Z.Face3(a,\nb,d,f,r,e);c.faces.push(e);void 0!==l&&c.faceVertexUvs[0].push([q[a].clone(),q[b].clone(),q[d].clone()]);void 0!==m&&c.faceVertexUvs[1].push([p[a].clone(),p[b].clone(),p[d].clone()])}var c=this,d=null!==a.index?a.index.array:void 0,e=a.attributes,f=e.position.array,g=void 0!==e.normal?e.normal.array:void 0,k=void 0!==e.color?e.color.array:void 0,l=void 0!==e.uv?e.uv.array:void 0,m=void 0!==e.uv2?e.uv2.array:void 0;void 0!==m&&(this.faceVertexUvs[1]=[]);for(var n=[],q=[],p=[],t=e=0;e<f.length;e+=3,\nt+=2)c.vertices.push(new Z.Vector3(f[e],f[e+1],f[e+2])),void 0!==g&&n.push(new Z.Vector3(g[e],g[e+1],g[e+2])),void 0!==k&&c.colors.push(new Z.Color(k[e],k[e+1],k[e+2])),void 0!==l&&q.push(new Z.Vector2(l[t],l[t+1])),void 0!==m&&p.push(new Z.Vector2(m[t],m[t+1]));if(void 0!==d)if(f=a.groups,0<f.length)for(e=0;e<f.length;e++)for(var r=f[e],v=r.start,w=r.count,t=v,v=v+w;t<v;t+=3)b(d[t],d[t+1],d[t+2],r.materialIndex);else for(e=0;e<d.length;e+=3)b(d[e],d[e+1],d[e+2]);else for(e=0;e<f.length/3;e+=3)b(e,\ne+1,e+2);this.computeFaceNormals();null!==a.boundingBox&&(this.boundingBox=a.boundingBox.clone());null!==a.boundingSphere&&(this.boundingSphere=a.boundingSphere.clone());return this},center:function(){this.computeBoundingBox();var a=this.boundingBox.center().negate();this.translate(a.x,a.y,a.z);return a},normalize:function(){this.computeBoundingSphere();var a=this.boundingSphere.center,b=this.boundingSphere.radius,b=0===b?1:1/b,c=new Z.Matrix4;c.set(b,0,0,-b*a.x,0,b,0,-b*a.y,0,0,b,-b*a.z,0,0,0,1);\nthis.applyMatrix(c);return this},computeFaceNormals:function(){for(var a=new Z.Vector3,b=new Z.Vector3,c=0,d=this.faces.length;c<d;c++){var e=this.faces[c],f=this.vertices[e.a],g=this.vertices[e.b];a.subVectors(this.vertices[e.c],g);b.subVectors(f,g);a.cross(b);a.normalize();e.normal.copy(a)}},computeVertexNormals:function(a){void 0===a&&(a=!0);var b;var c=Array(this.vertices.length);var d=0;for(b=this.vertices.length;d<b;d++)c[d]=new Z.Vector3;if(a){var e=new Z.Vector3,f=new Z.Vector3;a=0;for(d=\nthis.faces.length;a<d;a++){b=this.faces[a];var g=this.vertices[b.a];var k=this.vertices[b.b];var l=this.vertices[b.c];e.subVectors(l,k);f.subVectors(g,k);e.cross(f);c[b.a].add(e);c[b.b].add(e);c[b.c].add(e)}}else for(a=0,d=this.faces.length;a<d;a++)b=this.faces[a],c[b.a].add(b.normal),c[b.b].add(b.normal),c[b.c].add(b.normal);d=0;for(b=this.vertices.length;d<b;d++)c[d].normalize();a=0;for(d=this.faces.length;a<d;a++)b=this.faces[a],g=b.vertexNormals,3===g.length?(g[0].copy(c[b.a]),g[1].copy(c[b.b]),\ng[2].copy(c[b.c])):(g[0]=c[b.a].clone(),g[1]=c[b.b].clone(),g[2]=c[b.c].clone());0<this.faces.length&&(this.normalsNeedUpdate=!0)},computeMorphNormals:function(){var a,b;var c=0;for(b=this.faces.length;c<b;c++){var d=this.faces[c];d.__originalFaceNormal?d.__originalFaceNormal.copy(d.normal):d.__originalFaceNormal=d.normal.clone();d.__originalVertexNormals||(d.__originalVertexNormals=[]);var e=0;for(a=d.vertexNormals.length;e<a;e++)d.__originalVertexNormals[e]?d.__originalVertexNormals[e].copy(d.vertexNormals[e]):\nd.__originalVertexNormals[e]=d.vertexNormals[e].clone()}var f=new Z.Geometry;f.faces=this.faces;e=0;for(a=this.morphTargets.length;e<a;e++){if(!this.morphNormals[e]){this.morphNormals[e]={};this.morphNormals[e].faceNormals=[];this.morphNormals[e].vertexNormals=[];d=this.morphNormals[e].faceNormals;var g=this.morphNormals[e].vertexNormals;c=0;for(b=this.faces.length;c<b;c++){var k=new Z.Vector3;var l={a:new Z.Vector3,b:new Z.Vector3,c:new Z.Vector3};d.push(k);g.push(l)}}g=this.morphNormals[e];f.vertices=\nthis.morphTargets[e].vertices;f.computeFaceNormals();f.computeVertexNormals();c=0;for(b=this.faces.length;c<b;c++)d=this.faces[c],k=g.faceNormals[c],l=g.vertexNormals[c],k.copy(d.normal),l.a.copy(d.vertexNormals[0]),l.b.copy(d.vertexNormals[1]),l.c.copy(d.vertexNormals[2])}c=0;for(b=this.faces.length;c<b;c++)d=this.faces[c],d.normal=d.__originalFaceNormal,d.vertexNormals=d.__originalVertexNormals},computeTangents:function(){console.warn(\"THREE.Geometry: .computeTangents() has been removed.\")},computeLineDistances:function(){for(var a=\n0,b=this.vertices,c=0,d=b.length;c<d;c++)0<c&&(a+=b[c].distanceTo(b[c-1])),this.lineDistances[c]=a},computeBoundingBox:function(){null===this.boundingBox&&(this.boundingBox=new Z.Box3);this.boundingBox.setFromPoints(this.vertices)},computeBoundingSphere:function(){null===this.boundingSphere&&(this.boundingSphere=new Z.Sphere);this.boundingSphere.setFromPoints(this.vertices)},merge:function(a,b,c){if(!1===a instanceof Z.Geometry)console.error(\"THREE.Geometry.merge(): geometry not an instance of THREE.Geometry.\",\na);else{var d,e=this.vertices.length,f=this.vertices,g=a.vertices,k=this.faces,l=a.faces,m=this.faceVertexUvs[0];a=a.faceVertexUvs[0];void 0===c&&(c=0);void 0!==b&&(d=Wf(new Z.Matrix3,b));for(var n=0,q=g.length;n<q;n++){var p=g[n].clone();void 0!==b&&p.applyMatrix4(b);f.push(p)}n=0;for(q=l.length;n<q;n++){var g=l[n],t=g.vertexNormals,r=g.vertexColors,p=new Z.Face3(g.a+e,g.b+e,g.c+e);p.normal.copy(g.normal);void 0!==d&&Sf(p.normal,d).normalize();b=0;for(f=t.length;b<f;b++){var v=t[b].clone();void 0!==\nd&&Sf(v,d).normalize();p.vertexNormals.push(v)}p.color.copy(g.color);b=0;for(f=r.length;b<f;b++)v=r[b],p.vertexColors.push(v.clone());p.materialIndex=g.materialIndex+c;k.push(p)}n=0;for(q=a.length;n<q;n++)if(c=a[n],d=[],void 0!==c){b=0;for(f=c.length;b<f;b++)d.push(c[b].clone());m.push(d)}}},mergeMesh:function(a){!1===a instanceof Z.Mesh?console.error(\"THREE.Geometry.mergeMesh(): mesh not an instance of THREE.Mesh.\",a):(a.matrixAutoUpdate&&a.updateMatrix(),this.merge(a.geometry,a.matrix))},mergeVertices:function(){var a=\n{},b=[],c=[],d=Math.pow(10,4),e;var f=0;for(e=this.vertices.length;f<e;f++){var g=this.vertices[f];g=Math.round(g.x*d)+\"_\"+Math.round(g.y*d)+\"_\"+Math.round(g.z*d);void 0===a[g]?(a[g]=f,b.push(this.vertices[f]),c[f]=b.length-1):c[f]=c[a[g]]}a=[];f=0;for(e=this.faces.length;f<e;f++)for(d=this.faces[f],d.a=c[d.a],d.b=c[d.b],d.c=c[d.c],d=[d.a,d.b,d.c],g=0;3>g;g++)if(d[g]===d[(g+1)%3]){a.push(f);break}for(f=a.length-1;0<=f;f--)for(d=a[f],this.faces.splice(d,1),c=0,e=this.faceVertexUvs.length;c<e;c++)this.faceVertexUvs[c].splice(d,\n1);f=this.vertices.length-b.length;this.vertices=b;return f},sortFacesByMaterialIndex:function(){for(var a=this.faces,b=a.length,c=0;c<b;c++)a[c]._id=c;a.sort(function(a,b){return a.materialIndex-b.materialIndex});var d=this.faceVertexUvs[0],e=this.faceVertexUvs[1],f,g;d&&d.length===b&&(f=[]);e&&e.length===b&&(g=[]);for(c=0;c<b;c++){var k=a[c]._id;f&&f.push(d[k]);g&&g.push(e[k])}f&&(this.faceVertexUvs[0]=f);g&&(this.faceVertexUvs[1]=g)},toJSON:function(){function a(a,b,c){return c?a|1<<b:a&~(1<<b)}\nfunction b(a){var b=a.x.toString()+a.y.toString()+a.z.toString();if(void 0!==m[b])return m[b];m[b]=l.length/3;l.push(a.x,a.y,a.z);return m[b]}function c(a){var b=a.r.toString()+a.g.toString()+a.b.toString();if(void 0!==q[b])return q[b];q[b]=n.length;n.push(Hf(a));return q[b]}function d(a){var b=a.x.toString()+a.y.toString();if(void 0!==t[b])return t[b];t[b]=p.length/2;p.push(a.x,a.y);return t[b]}var e={metadata:{version:4.4,type:\"Geometry\",generator:\"Geometry.toJSON\"}};e.uuid=this.uuid;e.type=this.type;\n\"\"!==this.name&&(e.name=this.name);if(void 0!==this.parameters){var f=this.parameters,g;for(g in f)void 0!==f[g]&&(e[g]=f[g]);return e}f=[];for(g=0;g<this.vertices.length;g++){var k=this.vertices[g];f.push(k.x,k.y,k.z)}var k=[],l=[],m={},n=[],q={},p=[],t={};for(g=0;g<this.faces.length;g++){var r=this.faces[g],v=void 0!==this.faceVertexUvs[0][g],w=0<r.normal.length(),z=0<r.vertexNormals.length,y=1!==r.color.r||1!==r.color.g||1!==r.color.b,B=0<r.vertexColors.length,A=0,A=a(A,0,0),A=a(A,1,!0),A=a(A,\n2,!1),A=a(A,3,v),A=a(A,4,w),A=a(A,5,z),A=a(A,6,y),A=a(A,7,B);k.push(A);k.push(r.a,r.b,r.c);k.push(r.materialIndex);v&&(v=this.faceVertexUvs[0][g],k.push(d(v[0]),d(v[1]),d(v[2])));w&&k.push(b(r.normal));z&&(w=r.vertexNormals,k.push(b(w[0]),b(w[1]),b(w[2])));y&&k.push(c(r.color));B&&(r=r.vertexColors,k.push(c(r[0]),c(r[1]),c(r[2])))}e.data={};e.data.vertices=f;e.data.normals=l;0<n.length&&(e.data.colors=n);0<p.length&&(e.data.uvs=[p]);e.data.faces=k;return e},clone:function(){return(new Z.Geometry).copy(this)},\ncopy:function(a){this.vertices=[];this.faces=[];this.faceVertexUvs=[[]];for(var b=a.vertices,c=0,d=b.length;c<d;c++)this.vertices.push(b[c].clone());b=a.faces;c=0;for(d=b.length;c<d;c++)this.faces.push(b[c].clone());c=0;for(d=a.faceVertexUvs.length;c<d;c++){b=a.faceVertexUvs[c];void 0===this.faceVertexUvs[c]&&(this.faceVertexUvs[c]=[]);for(var e=0,f=b.length;e<f;e++){for(var g=b[e],k=[],l=0,m=g.length;l<m;l++)k.push(g[l].clone());this.faceVertexUvs[c].push(k)}}return this},dispose:function(){this.dispatchEvent({type:\"dispose\"})}});\nZ.GeometryIdCount=0;Z.DirectGeometry=function(){Object.defineProperty(this,\"id\",{value:Z.GeometryIdCount++});this.uuid=Z.Math.generateUUID();this.name=\"\";this.type=\"DirectGeometry\";this.indices=[];this.vertices=[];this.normals=[];this.colors=[];this.uvs=[];this.uvs2=[];this.groups=[];this.morphTargets={};this.skinWeights=[];this.skinIndices=[];this.boundingSphere=this.boundingBox=null;this.groupsNeedUpdate=this.uvsNeedUpdate=this.colorsNeedUpdate=this.normalsNeedUpdate=this.verticesNeedUpdate=!1};\nObject.assign(Z.DirectGeometry.prototype,Z.EventDispatcher.prototype,{computeBoundingBox:Z.Geometry.prototype.computeBoundingBox,computeBoundingSphere:Z.Geometry.prototype.computeBoundingSphere,computeFaceNormals:function(){console.warn(\"THREE.DirectGeometry: computeFaceNormals() is not a method of this type of geometry.\")},computeVertexNormals:function(){console.warn(\"THREE.DirectGeometry: computeVertexNormals() is not a method of this type of geometry.\")},computeGroups:function(a){var b=[];a=a.faces;\nfor(var c=0;c<a.length;c++){var d=a[c];if(d.materialIndex!==e){var e=d.materialIndex;void 0!==f&&(f.count=3*c-f.start,b.push(f));var f={start:3*c,materialIndex:e}}}void 0!==f&&(f.count=3*c-f.start,b.push(f));this.groups=b},fromGeometry:function(a){var b=a.faces,c=a.vertices,d=a.faceVertexUvs,e=d[0]&&0<d[0].length,f=d[1]&&0<d[1].length,g=a.morphTargets,k=g.length;if(0<k){var l=[];for(var m=0;m<k;m++)l[m]=[];this.morphTargets.position=l}var n=a.morphNormals,q=n.length;if(0<q){var p=[];for(m=0;m<q;m++)p[m]=\n[];this.morphTargets.normal=p}for(var t=a.skinIndices,r=a.skinWeights,v=t.length===c.length,w=r.length===c.length,m=0;m<b.length;m++){var z=b[m];this.vertices.push(c[z.a],c[z.b],c[z.c]);var y=z.vertexNormals;3===y.length?this.normals.push(y[0],y[1],y[2]):(y=z.normal,this.normals.push(y,y,y));y=z.vertexColors;3===y.length?this.colors.push(y[0],y[1],y[2]):(y=z.color,this.colors.push(y,y,y));!0===e&&(y=d[0][m],void 0!==y?this.uvs.push(y[0],y[1],y[2]):(console.warn(\"THREE.DirectGeometry.fromGeometry(): Undefined vertexUv \",\nm),this.uvs.push(new Z.Vector2,new Z.Vector2,new Z.Vector2)));!0===f&&(y=d[1][m],void 0!==y?this.uvs2.push(y[0],y[1],y[2]):(console.warn(\"THREE.DirectGeometry.fromGeometry(): Undefined vertexUv2 \",m),this.uvs2.push(new Z.Vector2,new Z.Vector2,new Z.Vector2)));for(y=0;y<k;y++){var B=g[y].vertices;l[y].push(B[z.a],B[z.b],B[z.c])}for(y=0;y<q;y++)B=n[y].vertexNormals[m],p[y].push(B.a,B.b,B.c);v&&this.skinIndices.push(t[z.a],t[z.b],t[z.c]);w&&this.skinWeights.push(r[z.a],r[z.b],r[z.c])}this.computeGroups(a);\nthis.verticesNeedUpdate=a.verticesNeedUpdate;this.normalsNeedUpdate=a.normalsNeedUpdate;this.colorsNeedUpdate=a.colorsNeedUpdate;this.uvsNeedUpdate=a.uvsNeedUpdate;this.groupsNeedUpdate=a.groupsNeedUpdate;return this},dispose:function(){this.dispatchEvent({type:\"dispose\"})}});\nZ.BufferGeometry=function(){Object.defineProperty(this,\"id\",{value:Z.GeometryIdCount++});this.uuid=Z.Math.generateUUID();this.name=\"\";this.type=\"BufferGeometry\";this.index=null;this.attributes={};this.morphAttributes={};this.groups=[];this.boundingSphere=this.boundingBox=null;this.drawRange={start:0,count:Infinity}};\nObject.assign(Z.BufferGeometry.prototype,Z.EventDispatcher.prototype,{getIndex:function(){return this.index},setIndex:function(a){this.index=a},addAttribute:function(a,b,c){if(!1===b instanceof Z.BufferAttribute&&!1===b instanceof Z.InterleavedBufferAttribute)console.warn(\"THREE.BufferGeometry: .addAttribute() now expects ( name, attribute ).\"),this.addAttribute(a,new Z.BufferAttribute(b,c));else if(\"index\"===a)console.warn(\"THREE.BufferGeometry.addAttribute: Use .setIndex() for index attribute.\"),\nthis.setIndex(b);else return this.attributes[a]=b,this},getAttribute:function(a){return this.attributes[a]},removeAttribute:function(a){delete this.attributes[a];return this},addGroup:function(a,b,c){this.groups.push({start:a,count:b,materialIndex:void 0!==c?c:0})},clearGroups:function(){this.groups=[]},setDrawRange:function(a,b){this.drawRange.start=a;this.drawRange.count=b},applyMatrix:function(a){var b=this.attributes.position;void 0!==b&&(a.applyToVector3Array(b.array),b.needsUpdate=!0);b=this.attributes.normal;\nvoid 0!==b&&(Wf(new Z.Matrix3,a).applyToVector3Array(b.array),b.needsUpdate=!0);null!==this.boundingBox&&this.computeBoundingBox();null!==this.boundingSphere&&this.computeBoundingSphere();return this},rotateX:function(){var a;return function(b){void 0===a&&(a=new Z.Matrix4);ag(a,b);this.applyMatrix(a);return this}}(),rotateY:function(){var a;return function(b){void 0===a&&(a=new Z.Matrix4);$f(a,b);this.applyMatrix(a);return this}}(),rotateZ:function(){var a;return function(b){void 0===a&&(a=new Z.Matrix4);\nZf(a,b);this.applyMatrix(a);return this}}(),translate:function(){var a;return function(b,c,d){void 0===a&&(a=new Z.Matrix4);a.set(1,0,0,b,0,1,0,c,0,0,1,d,0,0,0,1);this.applyMatrix(a);return this}}(),scale:function(){var a;return function(b,c,d){void 0===a&&(a=new Z.Matrix4);a.set(b,0,0,0,0,c,0,0,0,0,d,0,0,0,0,1);this.applyMatrix(a);return this}}(),lookAt:function(){var a;return function(b){void 0===a&&(a=new Z.Object3D);a.lookAt(b);a.updateMatrix();this.applyMatrix(a.matrix)}}(),center:function(){this.computeBoundingBox();\nvar a=this.boundingBox.center().negate();this.translate(a.x,a.y,a.z);return a},setFromObject:function(a){var b=a.geometry;if(a instanceof Z.Points||a instanceof Z.Line){a=new Z.Float32Attribute(3*b.vertices.length,3);var c=new Z.Float32Attribute(3*b.colors.length,3);this.addAttribute(\"position\",eg(a,b.vertices));this.addAttribute(\"color\",hg(c,b.colors));b.lineDistances&&b.lineDistances.length===b.vertices.length&&(a=new Z.Float32Attribute(b.lineDistances.length,1),this.addAttribute(\"lineDistance\",\nig(a,b.lineDistances)));null!==b.boundingSphere&&(this.boundingSphere=b.boundingSphere.clone());null!==b.boundingBox&&(this.boundingBox=b.boundingBox.clone())}else a instanceof Z.Mesh&&b instanceof Z.Geometry&&this.fromGeometry(b);return this},updateFromObject:function(a){var b=a.geometry;if(a instanceof Z.Mesh){var c=b.__directGeometry;if(void 0===c)return this.fromGeometry(b);c.verticesNeedUpdate=b.verticesNeedUpdate;c.normalsNeedUpdate=b.normalsNeedUpdate;c.colorsNeedUpdate=b.colorsNeedUpdate;\nc.uvsNeedUpdate=b.uvsNeedUpdate;c.groupsNeedUpdate=b.groupsNeedUpdate;b.verticesNeedUpdate=!1;b.normalsNeedUpdate=!1;b.colorsNeedUpdate=!1;b.uvsNeedUpdate=!1;b.groupsNeedUpdate=!1;b=c}!0===b.verticesNeedUpdate&&(c=this.attributes.position,void 0!==c&&(eg(c,b.vertices),c.needsUpdate=!0),b.verticesNeedUpdate=!1);!0===b.normalsNeedUpdate&&(c=this.attributes.normal,void 0!==c&&(eg(c,b.normals),c.needsUpdate=!0),b.normalsNeedUpdate=!1);!0===b.colorsNeedUpdate&&(c=this.attributes.color,void 0!==c&&(hg(c,\nb.colors),c.needsUpdate=!0),b.colorsNeedUpdate=!1);b.uvsNeedUpdate&&(c=this.attributes.uv,void 0!==c&&(fg(c,b.uvs),c.needsUpdate=!0),b.uvsNeedUpdate=!1);b.lineDistancesNeedUpdate&&(c=this.attributes.lineDistance,void 0!==c&&(ig(c,b.lineDistances),c.needsUpdate=!0),b.lineDistancesNeedUpdate=!1);b.groupsNeedUpdate&&(b.computeGroups(a.geometry),this.groups=b.groups,b.groupsNeedUpdate=!1);return this},fromGeometry:function(a){a.__directGeometry=(new Z.DirectGeometry).fromGeometry(a);return this.fromDirectGeometry(a.__directGeometry)},\nfromDirectGeometry:function(a){this.addAttribute(\"position\",eg(new Z.BufferAttribute(new Float32Array(3*a.vertices.length),3),a.vertices));0<a.normals.length&&this.addAttribute(\"normal\",eg(new Z.BufferAttribute(new Float32Array(3*a.normals.length),3),a.normals));0<a.colors.length&&this.addAttribute(\"color\",hg(new Z.BufferAttribute(new Float32Array(3*a.colors.length),3),a.colors));0<a.uvs.length&&this.addAttribute(\"uv\",fg(new Z.BufferAttribute(new Float32Array(2*a.uvs.length),2),a.uvs));0<a.uvs2.length&&\nthis.addAttribute(\"uv2\",fg(new Z.BufferAttribute(new Float32Array(2*a.uvs2.length),2),a.uvs2));0<a.indices.length&&this.setIndex(gg(new Z.BufferAttribute(new (65535<a.vertices.length?Uint32Array:Uint16Array)(3*a.indices.length),1),a.indices));this.groups=a.groups;for(var b in a.morphTargets){for(var c=[],d=a.morphTargets[b],e=0,f=d.length;e<f;e++){var g=d[e],k=new Z.Float32Attribute(3*g.length,3);c.push(eg(k,g))}this.morphAttributes[b]=c}0<a.skinIndices.length&&(b=new Z.Float32Attribute(4*a.skinIndices.length,\n4),this.addAttribute(\"skinIndex\",dg(b,a.skinIndices)));0<a.skinWeights.length&&(b=new Z.Float32Attribute(4*a.skinWeights.length,4),this.addAttribute(\"skinWeight\",dg(b,a.skinWeights)));null!==a.boundingSphere&&(this.boundingSphere=a.boundingSphere.clone());null!==a.boundingBox&&(this.boundingBox=a.boundingBox.clone());return this},computeBoundingBox:function(){null===this.boundingBox&&(this.boundingBox=new Z.Box3);var a=this.attributes.position.array;void 0!==a?Vf(this.boundingBox,a):this.boundingBox.makeEmpty();\n(isNaN(this.boundingBox.min.x)||isNaN(this.boundingBox.min.y)||isNaN(this.boundingBox.min.z))&&console.error('THREE.BufferGeometry.computeBoundingBox: Computed min/max have NaN values. The \"position\" attribute is likely to have NaN values.',this)},computeBoundingSphere:function(){var a=new Z.Box3,b=new Z.Vector3;return function(){null===this.boundingSphere&&(this.boundingSphere=new Z.Sphere);var c=this.attributes.position.array;if(c){var d=this.boundingSphere.center;Vf(a,c);a.center(d);for(var e=\n0,f=0,g=c.length;f<g;f+=3)b.fromArray(c,f),e=Math.max(e,d.distanceToSquared(b));this.boundingSphere.radius=Math.sqrt(e);isNaN(this.boundingSphere.radius)&&console.error('THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The \"position\" attribute is likely to have NaN values.',this)}}}(),computeFaceNormals:function(){},computeVertexNormals:function(){var a=this.index,b=this.attributes,c=this.groups;if(b.position){var d=b.position.array;if(void 0===b.normal)this.addAttribute(\"normal\",\nnew Z.BufferAttribute(new Float32Array(d.length),3));else for(var e=b.normal.array,f=0,g=e.length;f<g;f++)e[f]=0;var e=b.normal.array,k=new Z.Vector3,l=new Z.Vector3,m=new Z.Vector3,n=new Z.Vector3,q=new Z.Vector3;if(a){a=a.array;0===c.length&&this.addGroup(0,a.length);for(var p=0,t=c.length;p<t;++p){f=c[p];g=f.start;var r=f.count;f=g;for(g+=r;f<g;f+=3){r=3*a[f+0];var v=3*a[f+1];var w=3*a[f+2];k.fromArray(d,r);l.fromArray(d,v);m.fromArray(d,w);n.subVectors(m,l);q.subVectors(k,l);n.cross(q);e[r]+=\nn.x;e[r+1]+=n.y;e[r+2]+=n.z;e[v]+=n.x;e[v+1]+=n.y;e[v+2]+=n.z;e[w]+=n.x;e[w+1]+=n.y;e[w+2]+=n.z}}}else for(f=0,g=d.length;f<g;f+=9)k.fromArray(d,f),l.fromArray(d,f+3),m.fromArray(d,f+6),n.subVectors(m,l),q.subVectors(k,l),n.cross(q),e[f]=n.x,e[f+1]=n.y,e[f+2]=n.z,e[f+3]=n.x,e[f+4]=n.y,e[f+5]=n.z,e[f+6]=n.x,e[f+7]=n.y,e[f+8]=n.z;this.normalizeNormals();b.normal.needsUpdate=!0}},merge:function(a,b){if(!1===a instanceof Z.BufferGeometry)console.error(\"THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.\",\na);else{void 0===b&&(b=0);var c=this.attributes,d;for(d in c)if(void 0!==a.attributes[d])for(var e=c[d].array,f=a.attributes[d],g=f.array,k=0,f=f.itemSize*b;k<g.length;k++,f++)e[f]=g[k];return this}},normalizeNormals:function(){for(var a=this.attributes.normal.array,b,c,d,e=0,f=a.length;e<f;e+=3)b=a[e],c=a[e+1],d=a[e+2],b=1/Math.sqrt(b*b+c*c+d*d),a[e]*=b,a[e+1]*=b,a[e+2]*=b},toNonIndexed:function(){if(null===this.index)return console.warn(\"THREE.BufferGeometry.toNonIndexed(): Geometry is already non-indexed.\"),\nthis;var a=new Z.BufferGeometry,b=this.index.array,c=this.attributes,d;for(d in c){for(var e=c[d],f=e.array,e=e.itemSize,g=new f.constructor(b.length*e),k,l=0,m=0,n=b.length;m<n;m++){k=b[m]*e;for(var q=0;q<e;q++)g[l++]=f[k++]}a.addAttribute(d,new Z.BufferAttribute(g,e))}return a},toJSON:function(){var a={metadata:{version:4.4,type:\"BufferGeometry\",generator:\"BufferGeometry.toJSON\"}};a.uuid=this.uuid;a.type=this.type;\"\"!==this.name&&(a.name=this.name);if(void 0!==this.parameters){var b=this.parameters;\nfor(var c in b)void 0!==b[c]&&(a[c]=b[c]);return a}a.data={attributes:{}};var d=this.index;null!==d&&(b=Array.prototype.slice.call(d.array),a.data.index={type:d.array.constructor.name,array:b});var e=this.attributes;for(c in e)d=e[c],b=Array.prototype.slice.call(d.array),a.data.attributes[c]={itemSize:d.itemSize,type:d.array.constructor.name,array:b,normalized:d.normalized};c=this.groups;0<c.length&&(a.data.groups=JSON.parse(JSON.stringify(c)));c=this.boundingSphere;null!==c&&(a.data.boundingSphere=\n{center:c.center.toArray(),radius:c.radius});return a},clone:function(){return(new Z.BufferGeometry).copy(this)},copy:function(a){var b=a.index;null!==b&&this.setIndex(b.clone());var b=a.attributes;for(c in b)this.addAttribute(c,b[c].clone());a=a.groups;var c=0;for(b=a.length;c<b;c++){var d=a[c];this.addGroup(d.start,d.count,d.materialIndex)}return this},dispose:function(){this.dispatchEvent({type:\"dispose\"})}});Z.BufferGeometry.MaxIndex=65535;\nZ.InstancedBufferGeometry=function(){Z.BufferGeometry.call(this);this.type=\"InstancedBufferGeometry\";this.maxInstancedCount=void 0};Z.InstancedBufferGeometry.prototype=Object.create(Z.BufferGeometry.prototype);Z.InstancedBufferGeometry.prototype.constructor=Z.InstancedBufferGeometry;Z.InstancedBufferGeometry.prototype.addGroup=function(a,b,c){this.groups.push({start:a,count:b,instances:c})};\nZ.InstancedBufferGeometry.prototype.copy=function(a){var b=a.index;null!==b&&this.setIndex(b.clone());var b=a.attributes;for(c in b)this.addAttribute(c,b[c].clone());a=a.groups;var c=0;for(b=a.length;c<b;c++){var d=a[c];this.addGroup(d.start,d.count,d.instances)}return this};Z.Uniform=function(a,b){\"string\"===typeof a&&(console.warn(\"THREE.Uniform: Type parameter is no longer needed.\"),a=b);this.value=a;this.dynamic=!1};\nZ.Uniform.prototype={constructor:Z.Uniform,onUpdate:function(a){this.dynamic=!0;this.onUpdateCallback=a;return this}};Z.AnimationAction=function(){throw Error(\"THREE.AnimationAction: Use mixer.clipAction for construction.\");};\nZ.AnimationAction._new=function(a,b,c){this._mixer=a;this._clip=b;this._localRoot=c||null;a=b.tracks;b=a.length;c=Array(b);for(var d={endingStart:Z.ZeroCurvatureEnding,endingEnd:Z.ZeroCurvatureEnding},e=0;e!==b;++e){var f=a[e].createInterpolant(null);c[e]=f;f.settings=d}this._interpolantSettings=d;this._interpolants=c;this._propertyBindings=Array(b);this._weightInterpolant=this._timeScaleInterpolant=this._byClipCacheIndex=this._cacheIndex=null;this.loop=Z.LoopRepeat;this._loopCount=-1;this._startTime=\nnull;this.time=0;this._effectiveWeight=this.weight=this._effectiveTimeScale=this.timeScale=1;this.repetitions=Infinity;this.paused=!1;this.enabled=!0;this.clampWhenFinished=!1;this.zeroSlopeAtEnd=this.zeroSlopeAtStart=!0};\nZ.AnimationAction._new.prototype={constructor:Z.AnimationAction._new,play:function(){this._mixer._activateAction(this);return this},stop:function(){this._mixer._deactivateAction(this);return this.reset()},reset:function(){this.paused=!1;this.enabled=!0;this.time=0;this._loopCount=-1;this._startTime=null;return jg(kg(this))},isRunning:function(){return this.enabled&&!this.paused&&0!==this.timeScale&&null===this._startTime&&this._mixer._isActiveAction(this)},isScheduled:function(){return this._mixer._isActiveAction(this)},\nstartAt:function(a){this._startTime=a;return this},setLoop:function(a,b){this.loop=a;this.repetitions=b;return this},setEffectiveWeight:function(a){this.weight=a;this._effectiveWeight=this.enabled?a:0;return kg(this)},getEffectiveWeight:function(){return this._effectiveWeight},crossFadeTo:function(a,b,c){lg(this,b,1,0);lg(a,b,0,1);if(c){c=a._clip.duration;var d=this._clip.duration,e=c/d;mg(this,1,d/c,b);mg(a,e,1,b)}return a},setEffectiveTimeScale:function(a){this.timeScale=a;this._effectiveTimeScale=\nthis.paused?0:a;return jg(this)},getEffectiveTimeScale:function(){return this._effectiveTimeScale},setDuration:function(a){this.timeScale=this._clip.duration/a;return jg(this)},syncWith:function(a){this.time=a.time;this.timeScale=a.timeScale;return jg(this)},halt:function(a){return mg(this,this._effectiveTimeScale,0,a)},getMixer:function(){return this._mixer},getClip:function(){return this._clip},getRoot:function(){return this._localRoot||this._mixer._root},_update:function(a,b,c,d){var e=this._startTime;\nif(null!==e){b=(a-e)*c;if(0>b||0===c)return;this._startTime=null;b*=c}c=b;b=0;if(!this.paused&&(b=this.timeScale,e=this._timeScaleInterpolant,null!==e)){var f=e.evaluate(a)[0];b*=f;a>e.parameterPositions[1]&&(jg(this),0===b?this.paused=!0:this.timeScale=b)}this._effectiveTimeScale=b;a:if(f=c*b,c=this.time+f,0!==f){b=this._clip.duration;var g=this.loop,e=this._loopCount;if(g===Z.LoopOnce)b:{if(-1===e&&(this.loopCount=0,ng(this,!0,!0,!1)),c>=b)c=b;else if(0>c)c=0;else break b;this.clampWhenFinished?\nthis.paused=!0:this.enabled=!1;this._mixer.dispatchEvent({type:\"finished\",action:this,direction:0>f?-1:1})}else{g=g===Z.LoopPingPong;-1===e&&(0<=f?(e=0,ng(this,!0,0===this.repetitions,g)):ng(this,0===this.repetitions,!0,g));if(c>=b||0>c){var k=Math.floor(c/b);c-=b*k;var e=e+Math.abs(k),l=this.repetitions-e;0>l?(this.clampWhenFinished?this.paused=!0:this.enabled=!1,c=0<f?b:0,this._mixer.dispatchEvent({type:\"finished\",action:this,direction:0<f?1:-1})):(0===l?(f=0>f,ng(this,f,!f,g)):ng(this,!1,!1,g),\nthis._loopCount=e,this._mixer.dispatchEvent({type:\"loop\",action:this,loopDelta:k}))}if(g&&1===(e&1)){this.time=c;c=b-c;break a}}this.time=c}b=0;this.enabled&&(b=this.weight,e=this._weightInterpolant,null!==e&&(f=e.evaluate(a)[0],b*=f,a>e.parameterPositions[1]&&(kg(this),0===f&&(this.enabled=!1))));a=this._effectiveWeight=b;if(0<a)for(b=this._interpolants,e=this._propertyBindings,f=0,g=b.length;f!==g;++f){b[f].evaluate(c);var k=e[f],l=a,m=k.buffer,n=k.valueSize,q=d*n+n,p=k.cumulativeWeight;if(0===\np){for(p=0;p!==n;++p)m[q+p]=m[p];p=l}else p+=l,k._mixBufferRegion(m,q,0,l/p,n);k.cumulativeWeight=p}}};function lg(a,b,c,d){var e=a._mixer,f=e.time,g=a._weightInterpolant;null===g&&(g=e._lendControlInterpolant(),a._weightInterpolant=g);a=g.parameterPositions;g=g.sampleValues;a[0]=f;g[0]=c;a[1]=f+b;g[1]=d}\nfunction ng(a,b,c,d){var e=a._interpolantSettings;d?(e.endingStart=Z.ZeroSlopeEnding,e.endingEnd=Z.ZeroSlopeEnding):(e.endingStart=b?a.zeroSlopeAtStart?Z.ZeroSlopeEnding:Z.ZeroCurvatureEnding:Z.WrapAroundEnding,e.endingEnd=c?a.zeroSlopeAtEnd?Z.ZeroSlopeEnding:Z.ZeroCurvatureEnding:Z.WrapAroundEnding)}function jg(a){var b=a._timeScaleInterpolant;null!==b&&(a._timeScaleInterpolant=null,a._mixer._takeBackControlInterpolant(b));return a}\nfunction mg(a,b,c,d){var e=a._mixer,f=e.time,g=a._timeScaleInterpolant,k=a.timeScale;null===g&&(g=e._lendControlInterpolant(),a._timeScaleInterpolant=g);e=g.parameterPositions;g=g.sampleValues;e[0]=f;e[1]=f+d;g[0]=b/k;g[1]=c/k;return a}function kg(a){var b=a._weightInterpolant;null!==b&&(a._weightInterpolant=null,a._mixer._takeBackControlInterpolant(b));return a}\nZ.AnimationClip=function(a,b,c){this.name=a;this.tracks=c;this.duration=void 0!==b?b:-1;this.uuid=Z.Math.generateUUID();if(0>this.duration){b=a=0;for(c=this.tracks.length;b!==c;++b){var d=this.tracks[b];a=Math.max(a,d.times[d.times.length-1])}this.duration=a}this.trim();this.optimize()};\nZ.AnimationClip.prototype={constructor:Z.AnimationClip,trim:function(){for(var a=0;a<this.tracks.length;a++)this.tracks[a].trim(0,this.duration);return this},optimize:function(){for(var a=0;a<this.tracks.length;a++)this.tracks[a].optimize();return this}};\nObject.assign(Z.AnimationClip,{parse:function(a){for(var b=[],c=a.tracks,d=1/(a.fps||1),e=0,f=c.length;e!==f;++e)b.push(Z.KeyframeTrack.parse(c[e]).scale(d));return new Z.AnimationClip(a.name,a.duration,b)},toJSON:function(a){var b=[],c=a.tracks;a={name:a.name,duration:a.duration,tracks:b};for(var d=0,e=c.length;d!==e;++d)b.push(Z.KeyframeTrack.toJSON(c[d]));return a},CreateFromMorphTargetSequence:function(a,b,c,d){for(var e=b.length,f=[],g=0;g<e;g++){var k=[],l=[];k.push((g+e-1)%e,g,(g+1)%e);l.push(0,\n1,0);var m=Z.AnimationUtils.getKeyframeOrder(k),k=Z.AnimationUtils.sortedArray(k,1,m),l=Z.AnimationUtils.sortedArray(l,1,m);d||0!==k[0]||(k.push(e),l.push(l[0]));f.push((new Z.NumberKeyframeTrack(\".morphTargetInfluences[\"+b[g].name+\"]\",k,l)).scale(1/c))}return new Z.AnimationClip(a,-1,f)},findByName:function(a,b){var c=a;Array.isArray(a)||(c=a.geometry&&a.geometry.animations||a.animations);for(a=0;a<c.length;a++)if(c[a].name===b)return c[a];return null},CreateClipsFromMorphTargetSequences:function(a,\nb,c){for(var d,e,f={},g=/^([\\w-]*?)([\\d]+)$/,k=0,l=a.length;k<l;k++){var m=a[k];(d=m.name.match(g))&&1<d.length&&(e=d[1],(d=f[e])||(f[e]=d=[]),d.push(m))}a=[];for(e in f)a.push(Z.AnimationClip.CreateFromMorphTargetSequence(e,f[e],b,c));return a},parseAnimation:function(a,b){function c(a,b,c,d,e){if(0!==c.length){var f=[],g=[];Z.AnimationUtils.flattenJSON(c,f,g,d);0!==f.length&&e.push(new a(b,f,g))}}if(!a)return console.error(\"  no animation in JSONLoader data\"),null;var d=[],e=a.name||\"default\",f=\na.length||-1,g=a.fps||30;a=a.hierarchy||[];for(var k=0;k<a.length;k++){var l=a[k].keys;if(l&&0!==l.length)if(l[0].morphTargets){for(var f={},m=0;m<l.length;m++)if(l[m].morphTargets)for(var n=0;n<l[m].morphTargets.length;n++)f[l[m].morphTargets[n]]=-1;for(var q in f){for(var p=[],t=[],n=0;n!==l[m].morphTargets.length;++n){var r=l[m];p.push(r.time);t.push(r.morphTarget===q?1:0)}d.push(new Z.NumberKeyframeTrack(\".morphTargetInfluence[\"+q+\"]\",p,t))}f=f.length*(g||1)}else m=\".bones[\"+b[k].name+\"]\",c(Z.VectorKeyframeTrack,\nm+\".position\",l,\"pos\",d),c(Z.QuaternionKeyframeTrack,m+\".quaternion\",l,\"rot\",d),c(Z.VectorKeyframeTrack,m+\".scale\",l,\"scl\",d)}return 0===d.length?null:new Z.AnimationClip(e,f,d)}});Z.AnimationMixer=function(a){this._root=a;this._initMemoryManager();this.time=this._accuIndex=0;this.timeScale=1};\nObject.assign(Z.AnimationMixer.prototype,Z.EventDispatcher.prototype,{clipAction:function(a,b){var c=b||this._root,d=c.uuid,c=\"string\"===typeof a?Z.AnimationClip.findByName(c,a):a;a=null!==c?c.uuid:a;var e=this._actionsByClip[a],f=null;if(void 0!==e){f=e.actionByRoot[d];if(void 0!==f)return f;f=e.knownActions[0];null===c&&(c=f._clip)}if(null===c)return null;b=new Z.AnimationMixer._Action(this,c,b);this._bindAction(b,f);this._addInactiveAction(b,a,d);return b},existingAction:function(a,b){var c=b||\nthis._root;b=c.uuid;c=\"string\"===typeof a?Z.AnimationClip.findByName(c,a):a;a=this._actionsByClip[c?c.uuid:a];return void 0!==a?a.actionByRoot[b]||null:null},stopAllAction:function(){for(var a=this._actions,b=this._nActiveActions,c=this._bindings,d=this._nActiveBindings,e=this._nActiveBindings=this._nActiveActions=0;e!==b;++e)a[e].reset();for(e=0;e!==d;++e)c[e].useCount=0;return this},update:function(a){a*=this.timeScale;for(var b=this._actions,c=this._nActiveActions,d=this.time+=a,e=Math.sign(a),\nf=this._accuIndex^=1,g=0;g!==c;++g){var k=b[g];k.enabled&&k._update(d,a,e,f)}a=this._bindings;b=this._nActiveBindings;for(g=0;g!==b;++g)a[g].apply(f);return this},getRoot:function(){return this._root},uncacheClip:function(a){var b=this._actions;a=a.uuid;var c=this._actionsByClip,d=c[a];if(void 0!==d){for(var d=d.knownActions,e=0,f=d.length;e!==f;++e){var g=d[e];this._deactivateAction(g);var k=g._cacheIndex,l=b[b.length-1];g._cacheIndex=null;g._byClipCacheIndex=null;l._cacheIndex=k;b[k]=l;b.pop();\nthis._removeInactiveBindingsForAction(g)}delete c[a]}},uncacheRoot:function(a){a=a.uuid;var b=this._actionsByClip;for(d in b){var c=b[d].actionByRoot[a];void 0!==c&&(this._deactivateAction(c),this._removeInactiveAction(c))}var d=this._bindingsByRootAndName[a];if(void 0!==d)for(var e in d)a=d[e],a.binding.setValue(a.buffer,3*a.valueSize),this._removeInactiveBinding(a)},uncacheAction:function(a,b){a=this.existingAction(a,b);null!==a&&(this._deactivateAction(a),this._removeInactiveAction(a))}});\nZ.AnimationMixer._Action=Z.AnimationAction._new;\nObject.assign(Z.AnimationMixer.prototype,{_bindAction:function(a,b){var c=a._localRoot||this._root,d=a._clip.tracks,e=d.length,f=a._propertyBindings;a=a._interpolants;var g=c.uuid,k=this._bindingsByRootAndName,l=k[g];void 0===l&&(l={},k[g]=l);for(k=0;k!==e;++k){var m=d[k],n=m.name,q=l[n];if(void 0===q){q=f[k];if(void 0!==q){null===q._cacheIndex&&(++q.referenceCount,this._addInactiveBinding(q,g,n));continue}q=new Z.PropertyMixer(Z.PropertyBinding.create(c,n,b&&b._propertyBindings[k].binding.parsedPath),\nm.ValueTypeName,og(m));++q.referenceCount;this._addInactiveBinding(q,g,n)}f[k]=q;a[k].resultBuffer=q.buffer}},_activateAction:function(a){if(!this._isActiveAction(a)){if(null===a._cacheIndex){var b=(a._localRoot||this._root).uuid,c=a._clip.uuid,d=this._actionsByClip[c];this._bindAction(a,d&&d.knownActions[0]);this._addInactiveAction(a,c,b)}b=a._propertyBindings;c=0;for(d=b.length;c!==d;++c){var e=b[c];if(0===e.useCount++){this._lendBinding(e);var f=e.buffer,g=e.valueSize,k=3*g;e.binding.getValue(f,\nk);for(var l=g;l!==k;++l)f[l]=f[k+l%g];e.cumulativeWeight=0}}this._lendAction(a)}},_deactivateAction:function(a){if(this._isActiveAction(a)){for(var b=a._propertyBindings,c=0,d=b.length;c!==d;++c){var e=b[c];0===--e.useCount&&(e.binding.setValue(e.buffer,3*e.valueSize),this._takeBackBinding(e))}this._takeBackAction(a)}},_initMemoryManager:function(){this._actions=[];this._nActiveActions=0;this._actionsByClip={};this._bindings=[];this._nActiveBindings=0;this._bindingsByRootAndName={};this._controlInterpolants=\n[];this._nActiveControlInterpolants=0;var a=this;this.stats={actions:{get total(){return a._actions.length},get inUse(){return a._nActiveActions}},bindings:{get total(){return a._bindings.length},get inUse(){return a._nActiveBindings}},controlInterpolants:{get total(){return a._controlInterpolants.length},get inUse(){return a._nActiveControlInterpolants}}}},_isActiveAction:function(a){a=a._cacheIndex;return null!==a&&a<this._nActiveActions},_addInactiveAction:function(a,b,c){var d=this._actions,e=\nthis._actionsByClip,f=e[b];void 0===f?(f={knownActions:[a],actionByRoot:{}},a._byClipCacheIndex=0,e[b]=f):(b=f.knownActions,a._byClipCacheIndex=b.length,b.push(a));a._cacheIndex=d.length;d.push(a);f.actionByRoot[c]=a},_removeInactiveAction:function(a){var b=this._actions,c=b[b.length-1],d=a._cacheIndex;c._cacheIndex=d;b[d]=c;b.pop();a._cacheIndex=null;var c=a._clip.uuid,d=this._actionsByClip,e=d[c],f=e.knownActions,g=f[f.length-1],k=a._byClipCacheIndex;g._byClipCacheIndex=k;f[k]=g;f.pop();a._byClipCacheIndex=\nnull;delete e.actionByRoot[(b._localRoot||this._root).uuid];0===f.length&&delete d[c];this._removeInactiveBindingsForAction(a)},_removeInactiveBindingsForAction:function(a){a=a._propertyBindings;for(var b=0,c=a.length;b!==c;++b){var d=a[b];0===--d.referenceCount&&this._removeInactiveBinding(d)}},_lendAction:function(a){var b=this._actions,c=a._cacheIndex,d=this._nActiveActions++,e=b[d];a._cacheIndex=d;b[d]=a;e._cacheIndex=c;b[c]=e},_takeBackAction:function(a){var b=this._actions,c=a._cacheIndex,d=\n--this._nActiveActions,e=b[d];a._cacheIndex=d;b[d]=a;e._cacheIndex=c;b[c]=e},_addInactiveBinding:function(a,b,c){var d=this._bindingsByRootAndName,e=d[b],f=this._bindings;void 0===e&&(e={},d[b]=e);e[c]=a;a._cacheIndex=f.length;f.push(a)},_removeInactiveBinding:function(a){var b=this._bindings,c=a.binding,d=c.rootNode.uuid,c=c.path,e=this._bindingsByRootAndName,f=e[d],g=b[b.length-1];a=a._cacheIndex;g._cacheIndex=a;b[a]=g;b.pop();delete f[c];a:{for(var k in f)break a;delete e[d]}},_lendBinding:function(a){var b=\nthis._bindings,c=a._cacheIndex,d=this._nActiveBindings++,e=b[d];a._cacheIndex=d;b[d]=a;e._cacheIndex=c;b[c]=e},_takeBackBinding:function(a){var b=this._bindings,c=a._cacheIndex,d=--this._nActiveBindings,e=b[d];a._cacheIndex=d;b[d]=a;e._cacheIndex=c;b[c]=e},_lendControlInterpolant:function(){var a=this._controlInterpolants,b=this._nActiveControlInterpolants++,c=a[b];void 0===c&&(c=new Z.LinearInterpolant(new Float32Array(2),new Float32Array(2),1,this._controlInterpolantsResultBuffer),c.__cacheIndex=\nb,a[b]=c);return c},_takeBackControlInterpolant:function(a){var b=this._controlInterpolants,c=a.__cacheIndex,d=--this._nActiveControlInterpolants,e=b[d];a.__cacheIndex=d;b[d]=a;e.__cacheIndex=c;b[c]=e},_controlInterpolantsResultBuffer:new Float32Array(1)});\nZ.AnimationObjectGroup=function(a){this.uuid=Z.Math.generateUUID();this._objects=Array.prototype.slice.call(arguments);this.nCachedObjects_=0;var b={};this._indicesByUUID=b;for(var c=0,d=arguments.length;c!==d;++c)b[arguments[c].uuid]=c;this._paths=[];this._parsedPaths=[];this._bindings=[];this._bindingsIndicesByPath={};var e=this;this.stats={objects:{get total(){return e._objects.length},get inUse(){return this.total-e.nCachedObjects_}},get bindingsPerObject(){return e._bindings.length}}};\nZ.AnimationObjectGroup.prototype={constructor:Z.AnimationObjectGroup,add:function(a){for(var b,c,d=this._objects,e=d.length,f=this.nCachedObjects_,g=this._indicesByUUID,k=this._paths,l=this._parsedPaths,m=this._bindings,n=m.length,q=0,p=arguments.length;q!==p;++q){var t=arguments[q],r=t.uuid;b=g[r];if(void 0===b){b=e++;g[r]=b;d.push(t);for(var r=0,v=n;r!==v;++r)m[r].push(new Z.PropertyBinding(t,k[r],l[r]))}else if(b<f){c=d[b];var w=--f,v=d[w];g[v.uuid]=b;d[b]=v;g[r]=w;d[w]=t;r=0;for(v=n;r!==v;++r){var z=\nm[r],y=z[b];z[b]=z[w];void 0===y&&(y=new Z.PropertyBinding(t,k[r],l[r]));z[w]=y}}else d[b]!==c&&console.error(\"Different objects with the same UUID detected. Clean the caches or recreate your infrastructure when reloading scenes...\")}this.nCachedObjects_=f},remove:function(a){for(var b=this._objects,c=this.nCachedObjects_,d=this._indicesByUUID,e=this._bindings,f=e.length,g=0,k=arguments.length;g!==k;++g){var l=arguments[g],m=l.uuid,n=d[m];if(void 0!==n&&n>=c){var q=c++,p=b[q];d[p.uuid]=n;b[n]=p;d[m]=\nq;b[q]=l;l=0;for(m=f;l!==m;++l){var p=e[l],t=p[n];p[n]=p[q];p[q]=t}}}this.nCachedObjects_=c},uncache:function(a){for(var b,c,d=this._objects,e=d.length,f=this.nCachedObjects_,g=this._indicesByUUID,k=this._bindings,l=k.length,m=0,n=arguments.length;m!==n;++m){c=arguments[m].uuid;var q=g[c];if(void 0!==q)if(delete g[c],q<f){var p=--f,t=d[p];c=--e;b=d[c];g[t.uuid]=q;d[q]=t;g[b.uuid]=p;d[p]=b;d.pop();for(var t=0,r=l;t!==r;++t){b=k[t];var v=b[c];b[q]=b[p];b[p]=v;b.pop()}}else for(c=--e,b=d[c],g[b.uuid]=\nq,d[q]=b,d.pop(),t=0,r=l;t!==r;++t)b=k[t],b[q]=b[c],b.pop()}this.nCachedObjects_=f},unsubscribe_:function(a){var b=this._bindingsIndicesByPath,c=b[a];if(void 0!==c){var d=this._paths,e=this._parsedPaths,f=this._bindings,g=f.length-1,k=f[g];b[a[g]]=c;f[c]=k;f.pop();e[c]=e[g];e.pop();d[c]=d[g];d.pop()}}};\nZ.AnimationUtils={arraySlice:function(a,b,c){return Z.AnimationUtils.isTypedArray(a)?new a.constructor(a.subarray(b,c)):a.slice(b,c)},convertArray:function(a,b,c){return!a||!c&&a.constructor===b?a:\"number\"===typeof b.BYTES_PER_ELEMENT?new b(a):Array.prototype.slice.call(a)},isTypedArray:function(a){return ArrayBuffer.isView(a)&&!(a instanceof DataView)},getKeyframeOrder:function(a){for(var b=a.length,c=Array(b),d=0;d!==b;++d)c[d]=d;c.sort(function(b,c){return a[b]-a[c]});return c},sortedArray:function(a,\nb,c){for(var d=a.length,e=new a.constructor(d),f=0,g=0;g!==d;++f)for(var k=c[f]*b,l=0;l!==b;++l)e[g++]=a[k+l];return e},flattenJSON:function(a,b,c,d){for(var e=1,f=a[0];void 0!==f&&void 0===f[d];)f=a[e++];if(void 0!==f){var g=f[d];if(void 0!==g)if(Array.isArray(g)){do g=f[d],void 0!==g&&(b.push(f.time),c.push.apply(c,g)),f=a[e++];while(void 0!==f)}else if(void 0!==g.toArray){do g=f[d],void 0!==g&&(b.push(f.time),g.toArray(c,c.length)),f=a[e++];while(void 0!==f)}else{do g=f[d],void 0!==g&&(b.push(f.time),\nc.push(g)),f=a[e++];while(void 0!==f)}}}};Z.KeyframeTrack=function(a,b,c,d){if(void 0===a)throw Error(\"track name is undefined\");if(void 0===b||0===b.length)throw Error(\"no keyframes in track named \"+a);this.name=a;this.times=Z.AnimationUtils.convertArray(b,this.TimeBufferType);this.values=Z.AnimationUtils.convertArray(c,this.ValueBufferType);pg(this,d||this.DefaultInterpolation);this.validate();this.optimize()};\nZ.KeyframeTrack.prototype={constructor:Z.KeyframeTrack,TimeBufferType:Float32Array,ValueBufferType:Float32Array,DefaultInterpolation:Z.InterpolateLinear,InterpolantFactoryMethodDiscrete:function(a){return new Z.DiscreteInterpolant(this.times,this.values,og(this),a)},InterpolantFactoryMethodLinear:function(a){return new Z.LinearInterpolant(this.times,this.values,og(this),a)},InterpolantFactoryMethodSmooth:function(a){return new Z.CubicInterpolant(this.times,this.values,og(this),a)},shift:function(a){if(0!==\na)for(var b=this.times,c=0,d=b.length;c!==d;++c)b[c]+=a;return this},scale:function(a){if(1!==a)for(var b=this.times,c=0,d=b.length;c!==d;++c)b[c]*=a;return this},trim:function(a,b){for(var c=this.times,d=c.length,e=0,f=d-1;e!==d&&c[e]<a;)++e;for(;-1!==f&&c[f]>b;)--f;++f;if(0!==e||f!==d)e>=f&&(f=Math.max(f,1),e=f-1),a=og(this),this.times=Z.AnimationUtils.arraySlice(c,e,f),this.values=Z.AnimationUtils.arraySlice(this.values,e*a,f*a);return this},validate:function(){var a=!0,b=og(this);0!==b-Math.floor(b)&&\n(console.error(\"invalid value size in track\",this),a=!1);var c=this.times,b=this.values,d=c.length;0===d&&(console.error(\"track is empty\",this),a=!1);for(var e=null,f=0;f!==d;f++){var g=c[f];if(\"number\"===typeof g&&isNaN(g)){console.error(\"time is not a valid number\",this,f,g);a=!1;break}if(null!==e&&e>g){console.error(\"out of order keys\",this,f,g,e);a=!1;break}e=g}if(void 0!==b&&Z.AnimationUtils.isTypedArray(b))for(f=0,c=b.length;f!==c;++f)if(d=b[f],isNaN(d)){console.error(\"value is not a valid number\",\nthis,f,d);a=!1;break}return a},optimize:function(){for(var a=this.times,b=this.values,c=og(this),d=1,e=1,f=a.length-1;e<=f;++e){var g=!1,k=a[e];if(k!==a[e+1]&&(1!==e||k!==k[0]))for(var l=e*c,m=l-c,n=l+c,k=0;k!==c;++k){var q=b[l+k];if(q!==b[m+k]||q!==b[n+k]){g=!0;break}}if(g){if(e!==d)for(a[d]=a[e],g=e*c,l=d*c,k=0;k!==c;++k)b[l+k]=b[g+k];++d}}d!==a.length&&(this.times=Z.AnimationUtils.arraySlice(a,0,d),this.values=Z.AnimationUtils.arraySlice(b,0,d*c));return this}};\nfunction og(a){return a.values.length/a.times.length}\nfunction pg(a,b){switch(b){case Z.InterpolateDiscrete:var c=a.InterpolantFactoryMethodDiscrete;break;case Z.InterpolateLinear:c=a.InterpolantFactoryMethodLinear;break;case Z.InterpolateSmooth:c=a.InterpolantFactoryMethodSmooth}if(void 0===c){c=\"unsupported interpolation for \"+a.ValueTypeName+\" keyframe track named \"+a.name;if(void 0===a.createInterpolant)if(b!==a.DefaultInterpolation)pg(a,a.DefaultInterpolation);else throw Error(c);console.warn(c)}else a.createInterpolant=c}\nObject.assign(Z.KeyframeTrack,{parse:function(a){if(void 0===a.type)throw Error(\"track type undefined, can not parse\");var b=Z.KeyframeTrack._getTrackTypeForValueTypeName(a.type);if(void 0===a.times){var c=[],d=[];Z.AnimationUtils.flattenJSON(a.keys,c,d,\"value\");a.times=c;a.values=d}return void 0!==b.parse?b.parse(a):new b(a.name,a.times,a.values,a.interpolation)},toJSON:function(a){var b=a.constructor;if(void 0!==b.toJSON)b=b.toJSON(a);else{var b={name:a.name,times:Z.AnimationUtils.convertArray(a.times,\nArray),values:Z.AnimationUtils.convertArray(a.values,Array)};a:{switch(a.createInterpolant){case a.InterpolantFactoryMethodDiscrete:var c=Z.InterpolateDiscrete;break a;case a.InterpolantFactoryMethodLinear:c=Z.InterpolateLinear;break a;case a.InterpolantFactoryMethodSmooth:c=Z.InterpolateSmooth;break a}c=void 0}c!==a.DefaultInterpolation&&(b.interpolation=c)}b.type=a.ValueTypeName;return b},_getTrackTypeForValueTypeName:function(a){switch(a.toLowerCase()){case \"scalar\":case \"double\":case \"float\":case \"number\":case \"integer\":return Z.NumberKeyframeTrack;\ncase \"vector\":case \"vector2\":case \"vector3\":case \"vector4\":return Z.VectorKeyframeTrack;case \"color\":return Z.ColorKeyframeTrack;case \"quaternion\":return Z.QuaternionKeyframeTrack;case \"bool\":case \"boolean\":return Z.BooleanKeyframeTrack;case \"string\":return Z.StringKeyframeTrack}throw Error(\"Unsupported typeName: \"+a);}});\nZ.PropertyBinding=function(a,b,c){this.path=b;this.parsedPath=c||Z.PropertyBinding.parseTrackName(b);this.node=Z.PropertyBinding.findNode(a,this.parsedPath.nodeName)||a;this.rootNode=a};\nZ.PropertyBinding.prototype={constructor:Z.PropertyBinding,getValue:function(a,b){this.bind();this.getValue(a,b)},setValue:function(a,b){this.bind();this.setValue(a,b)},bind:function(){var a=this.node,b=this.parsedPath,c=b.objectName,d=b.propertyName,e=b.propertyIndex;a||(this.node=a=Z.PropertyBinding.findNode(this.rootNode,b.nodeName)||this.rootNode);this.getValue=this._getValue_unavailable;this.setValue=this._setValue_unavailable;if(a){if(c){var f=b.objectIndex;switch(c){case \"materials\":if(!a.material){console.error(\"  can not bind to material as node does not have a material\",\nthis);return}if(!a.material.materials){console.error(\"  can not bind to material.materials as node.material does not have a materials array\",this);return}a=a.material.materials;break;case \"bones\":if(!a.skeleton){console.error(\"  can not bind to bones as node does not have a skeleton\",this);return}a=a.skeleton.bones;for(c=0;c<a.length;c++)if(a[c].name===f){f=c;break}break;default:if(void 0===a[c]){console.error(\"  can not bind to objectName of node, undefined\",this);return}a=a[c]}if(void 0!==f){if(void 0===\na[f]){console.error(\"  trying to bind to objectIndex of objectName, but is undefined:\",this,a);return}a=a[f]}}if(f=a[d]){b=this.Versioning.None;void 0!==a.needsUpdate?(b=this.Versioning.NeedsUpdate,this.targetObject=a):void 0!==a.matrixWorldNeedsUpdate&&(b=this.Versioning.MatrixWorldNeedsUpdate,this.targetObject=a);c=this.BindingType.Direct;if(void 0!==e){if(\"morphTargetInfluences\"===d){if(!a.geometry){console.error(\"  can not bind to morphTargetInfluences becasuse node does not have a geometry\",\nthis);return}if(!a.geometry.morphTargets){console.error(\"  can not bind to morphTargetInfluences becasuse node does not have a geometry.morphTargets\",this);return}for(c=0;c<this.node.geometry.morphTargets.length;c++)if(a.geometry.morphTargets[c].name===e){e=c;break}}c=this.BindingType.ArrayElement;this.resolvedProperty=f;this.propertyIndex=e}else void 0!==f.fromArray&&void 0!==f.toArray?(c=this.BindingType.HasFromToArray,this.resolvedProperty=f):void 0!==f.length?(c=this.BindingType.EntireArray,this.resolvedProperty=\nf):this.propertyName=d;this.getValue=this.GetterByBindingType[c];this.setValue=this.SetterByBindingTypeAndVersioning[c][b]}else console.error(\"  trying to update property for track: \"+b.nodeName+\".\"+d+\" but it wasn't found.\",a)}else console.error(\"  trying to update node for track: \"+this.path+\" but it wasn't found.\")},unbind:function(){this.node=null;this.getValue=this._getValue_unbound;this.setValue=this._setValue_unbound}};\nObject.assign(Z.PropertyBinding.prototype,{_getValue_unavailable:function(){},_setValue_unavailable:function(){},_getValue_unbound:Z.PropertyBinding.prototype.getValue,_setValue_unbound:Z.PropertyBinding.prototype.setValue,BindingType:{Direct:0,EntireArray:1,ArrayElement:2,HasFromToArray:3},Versioning:{None:0,NeedsUpdate:1,MatrixWorldNeedsUpdate:2},GetterByBindingType:[function(a,b){a[b]=this.node[this.propertyName]},function(a,b){for(var c=this.resolvedProperty,d=0,e=c.length;d!==e;++d)a[b++]=c[d]},\nfunction(a,b){a[b]=this.resolvedProperty[this.propertyIndex]},function(a,b){this.resolvedProperty.toArray(a,b)}],SetterByBindingTypeAndVersioning:[[function(a,b){this.node[this.propertyName]=a[b]},function(a,b){this.node[this.propertyName]=a[b];this.targetObject.needsUpdate=!0},function(a,b){this.node[this.propertyName]=a[b];this.targetObject.matrixWorldNeedsUpdate=!0}],[function(a,b){for(var c=this.resolvedProperty,d=0,e=c.length;d!==e;++d)c[d]=a[b++]},function(a,b){for(var c=this.resolvedProperty,\nd=0,e=c.length;d!==e;++d)c[d]=a[b++];this.targetObject.needsUpdate=!0},function(a,b){for(var c=this.resolvedProperty,d=0,e=c.length;d!==e;++d)c[d]=a[b++];this.targetObject.matrixWorldNeedsUpdate=!0}],[function(a,b){this.resolvedProperty[this.propertyIndex]=a[b]},function(a,b){this.resolvedProperty[this.propertyIndex]=a[b];this.targetObject.needsUpdate=!0},function(a,b){this.resolvedProperty[this.propertyIndex]=a[b];this.targetObject.matrixWorldNeedsUpdate=!0}],[function(a,b){this.resolvedProperty.fromArray(a,\nb)},function(a,b){this.resolvedProperty.fromArray(a,b);this.targetObject.needsUpdate=!0},function(a,b){this.resolvedProperty.fromArray(a,b);this.targetObject.matrixWorldNeedsUpdate=!0}]]});\nZ.PropertyBinding.Composite=function(a,b,c){c=c||Z.PropertyBinding.parseTrackName(b);this._targetGroup=a;var d=a._bindingsIndicesByPath,e=d[b],f=a._bindings;if(void 0!==e)b=f[e];else{var g=a._paths,k=a._parsedPaths,l=a._objects,m=a.nCachedObjects_;a=Array(l.length);e=f.length;d[b]=e;g.push(b);k.push(c);f.push(a);d=m;for(e=l.length;d!==e;++d)a[d]=new Z.PropertyBinding(l[d],b,c);b=a}this._bindings=b};\nZ.PropertyBinding.Composite.prototype={constructor:Z.PropertyBinding.Composite,getValue:function(a,b){this.bind();var c=this._bindings[this._targetGroup.nCachedObjects_];void 0!==c&&c.getValue(a,b)},setValue:function(a,b){for(var c=this._bindings,d=this._targetGroup.nCachedObjects_,e=c.length;d!==e;++d)c[d].setValue(a,b)},bind:function(){for(var a=this._bindings,b=this._targetGroup.nCachedObjects_,c=a.length;b!==c;++b)a[b].bind()},unbind:function(){for(var a=this._bindings,b=this._targetGroup.nCachedObjects_,\nc=a.length;b!==c;++b)a[b].unbind()}};Z.PropertyBinding.create=function(a,b,c){return a instanceof Z.AnimationObjectGroup?new Z.PropertyBinding.Composite(a,b,c):new Z.PropertyBinding(a,b,c)};\nZ.PropertyBinding.parseTrackName=function(a){var b=/^(([\\w]+\\/)*)([\\w-\\d]+)?(\\.([\\w]+)(\\[([\\w\\d\\[\\]\\_.:\\- ]+)\\])?)?(\\.([\\w.]+)(\\[([\\w\\d\\[\\]\\_. ]+)\\])?)$/,c=b.exec(a);if(!c)throw Error(\"cannot parse trackName at all: \"+a);c.index===b.lastIndex&&b.lastIndex++;b={nodeName:c[3],objectName:c[5],objectIndex:c[7],propertyName:c[9],propertyIndex:c[11]};if(null===b.propertyName||0===b.propertyName.length)throw Error(\"can not parse propertyName from trackName: \"+a);return b};\nZ.PropertyBinding.findNode=function(a,b){if(!b||\"\"===b||\"root\"===b||\".\"===b||-1===b||b===a.name||b===a.uuid)return a;if(a.skeleton){var c=function(a){for(var c=0;c<a.bones.length;c++){var d=a.bones[c];if(d.name===b)return d}return null}(a.skeleton);if(c)return c}if(a.children){var d=function(a){for(var c=0;c<a.length;c++){var e=a[c];if(e.name===b||e.uuid===b)return e;if(e=d(e.children))return e}return null};if(a=d(a.children))return a}return null};\nZ.PropertyMixer=function(a,b,c){this.binding=a;this.valueSize=c;a=Float64Array;switch(b){case \"quaternion\":b=this._slerp;break;case \"string\":case \"bool\":a=Array;b=this._select;break;default:b=this._lerp}this.buffer=new a(4*c);this._mixBufferRegion=b;this.referenceCount=this.useCount=this.cumulativeWeight=0};\nZ.PropertyMixer.prototype={constructor:Z.PropertyMixer,apply:function(a){var b=this.valueSize,c=this.buffer;a=a*b+b;var d=this.cumulativeWeight,e=this.binding;this.cumulativeWeight=0;1>d&&this._mixBufferRegion(c,a,3*b,1-d,b);for(var d=b,f=b+b;d!==f;++d)if(c[d]!==c[d+b]){e.setValue(c,a);break}},_select:function(a,b,c,d,e){if(.5<=d)for(d=0;d!==e;++d)a[b+d]=a[c+d]},_slerp:function(a,b,c,d){Z.Quaternion.slerpFlat(a,b,a,b,a,c,d)},_lerp:function(a,b,c,d,e){for(var f=1-d,g=0;g!==e;++g){var k=b+g;a[k]=a[k]*\nf+a[c+g]*d}}};Z.BooleanKeyframeTrack=function(a,b,c){Z.KeyframeTrack.call(this,a,b,c)};Z.BooleanKeyframeTrack.prototype=Object.assign(Object.create(Z.KeyframeTrack.prototype),{constructor:Z.BooleanKeyframeTrack,ValueTypeName:\"bool\",ValueBufferType:Array,DefaultInterpolation:Z.InterpolateDiscrete,InterpolantFactoryMethodLinear:void 0,InterpolantFactoryMethodSmooth:void 0});Z.ColorKeyframeTrack=function(a,b,c,d){Z.KeyframeTrack.call(this,a,b,c,d)};\nZ.ColorKeyframeTrack.prototype=Object.assign(Object.create(Z.KeyframeTrack.prototype),{constructor:Z.ColorKeyframeTrack,ValueTypeName:\"color\"});Z.NumberKeyframeTrack=function(a,b,c,d){Z.KeyframeTrack.call(this,a,b,c,d)};Z.NumberKeyframeTrack.prototype=Object.assign(Object.create(Z.KeyframeTrack.prototype),{constructor:Z.NumberKeyframeTrack,ValueTypeName:\"number\"});Z.QuaternionKeyframeTrack=function(a,b,c,d){Z.KeyframeTrack.call(this,a,b,c,d)};\nZ.QuaternionKeyframeTrack.prototype=Object.assign(Object.create(Z.KeyframeTrack.prototype),{constructor:Z.QuaternionKeyframeTrack,ValueTypeName:\"quaternion\",DefaultInterpolation:Z.InterpolateLinear,InterpolantFactoryMethodLinear:function(a){return new Z.QuaternionLinearInterpolant(this.times,this.values,og(this),a)},InterpolantFactoryMethodSmooth:void 0});Z.StringKeyframeTrack=function(a,b,c,d){Z.KeyframeTrack.call(this,a,b,c,d)};\nZ.StringKeyframeTrack.prototype=Object.assign(Object.create(Z.KeyframeTrack.prototype),{constructor:Z.StringKeyframeTrack,ValueTypeName:\"string\",ValueBufferType:Array,DefaultInterpolation:Z.InterpolateDiscrete,InterpolantFactoryMethodLinear:void 0,InterpolantFactoryMethodSmooth:void 0});Z.VectorKeyframeTrack=function(a,b,c,d){Z.KeyframeTrack.call(this,a,b,c,d)};Z.VectorKeyframeTrack.prototype=Object.assign(Object.create(Z.KeyframeTrack.prototype),{constructor:Z.VectorKeyframeTrack,ValueTypeName:\"vector\"});\nZ.Audio=function(a){Z.Object3D.call(this);this.type=\"Audio\";this.context=a.context;this.source=this.context.createBufferSource();this.source.onended=this.onEnded.bind(this);this.gain=this.context.createGain();this.gain.connect(a.getInput());this.autoplay=!1;this.startTime=0;this.playbackRate=1;this.isPlaying=!1;this.hasPlaybackControl=!0;this.sourceType=\"empty\";this.filters=[]};\nZ.Audio.prototype=Object.assign(Object.create(Z.Object3D.prototype),{constructor:Z.Audio,getOutput:function(){return this.gain},setNodeSource:function(a){this.hasPlaybackControl=!1;this.sourceType=\"audioNode\";this.source=a;this.connect();return this},setBuffer:function(a){this.source.buffer=a;this.sourceType=\"buffer\";this.autoplay&&this.play();return this},play:function(){if(!0===this.isPlaying)console.warn(\"THREE.Audio: Audio is already playing.\");else if(!1===this.hasPlaybackControl)console.warn(\"THREE.Audio: this Audio has no playback control.\");\nelse{var a=this.context.createBufferSource();a.buffer=this.source.buffer;a.loop=this.source.loop;a.onended=this.source.onended;a.start(0,this.startTime);a.playbackRate.value=this.playbackRate;this.isPlaying=!0;this.source=a;return this.connect()}},pause:function(){if(!1===this.hasPlaybackControl)console.warn(\"THREE.Audio: this Audio has no playback control.\");else return this.source.stop(),this.startTime=this.context.currentTime,this},stop:function(){if(!1===this.hasPlaybackControl)console.warn(\"THREE.Audio: this Audio has no playback control.\");\nelse return this.source.stop(),this.startTime=0,this},connect:function(){if(0<this.filters.length){this.source.connect(this.filters[0]);for(var a=1,b=this.filters.length;a<b;a++)this.filters[a-1].connect(this.filters[a]);this.filters[this.filters.length-1].connect(this.getOutput())}else this.source.connect(this.getOutput());return this},disconnect:function(){if(0<this.filters.length){this.source.disconnect(this.filters[0]);for(var a=1,b=this.filters.length;a<b;a++)this.filters[a-1].disconnect(this.filters[a]);\nthis.filters[this.filters.length-1].disconnect(this.getOutput())}else this.source.disconnect(this.getOutput());return this},getFilters:function(){return this.filters},setFilters:function(a){a||(a=[]);!0===this.isPlaying?(this.disconnect(),this.filters=a,this.connect()):this.filters=a;return this},getFilter:function(){return this.getFilters()[0]},setFilter:function(a){return this.setFilters(a?[a]:[])},setPlaybackRate:function(a){if(!1===this.hasPlaybackControl)console.warn(\"THREE.Audio: this Audio has no playback control.\");\nelse return this.playbackRate=a,!0===this.isPlaying&&(this.source.playbackRate.value=this.playbackRate),this},getPlaybackRate:function(){return this.playbackRate},onEnded:function(){this.isPlaying=!1},getLoop:function(){return!1===this.hasPlaybackControl?(console.warn(\"THREE.Audio: this Audio has no playback control.\"),!1):this.source.loop},setLoop:function(a){!1===this.hasPlaybackControl?console.warn(\"THREE.Audio: this Audio has no playback control.\"):this.source.loop=a},getVolume:function(){return this.gain.gain.value},\nsetVolume:function(a){this.gain.gain.value=a;return this}});Z.AudioAnalyser=function(a,b){this.analyser=a.context.createAnalyser();this.analyser.fftSize=void 0!==b?b:2048;this.data=new Uint8Array(this.analyser.frequencyBinCount);a.getOutput().connect(this.analyser)};\nObject.assign(Z.AudioAnalyser.prototype,{getFrequencyData:function(){this.analyser.getByteFrequencyData(this.data);return this.data},getAverageFrequency:function(){for(var a=0,b=this.getFrequencyData(),c=0;c<b.length;c++)a+=b[c];return a/b.length}});Object.defineProperty(Z,\"AudioContext\",{get:function(){var a;return function(){void 0===a&&(a=new (window.AudioContext||window.webkitAudioContext));return a}}()});\nZ.PositionalAudio=function(a){Z.Audio.call(this,a);this.panner=this.context.createPanner();this.panner.connect(this.gain)};\nZ.PositionalAudio.prototype=Object.assign(Object.create(Z.Audio.prototype),{constructor:Z.PositionalAudio,getOutput:function(){return this.panner},getRefDistance:function(){return this.panner.refDistance},setRefDistance:function(a){this.panner.refDistance=a},getRolloffFactor:function(){return this.panner.rolloffFactor},setRolloffFactor:function(a){this.panner.rolloffFactor=a},getDistanceModel:function(){return this.panner.distanceModel},setDistanceModel:function(a){this.panner.distanceModel=a},getMaxDistance:function(){return this.panner.maxDistance},\nsetMaxDistance:function(a){this.panner.maxDistance=a},updateMatrixWorld:function(){var a=new Z.Vector3;return function(b){Z.Object3D.prototype.updateMatrixWorld.call(this,b);Qf(a,this.matrixWorld);this.panner.setPosition(a.x,a.y,a.z)}}()});Z.AudioListener=function(){Z.Object3D.call(this);this.type=\"AudioListener\";this.context=Z.AudioContext;this.gain=this.context.createGain();this.gain.connect(this.context.destination);this.filter=null};\nZ.AudioListener.prototype=Object.assign(Object.create(Z.Object3D.prototype),{constructor:Z.AudioListener,getInput:function(){return this.gain},removeFilter:function(){null!==this.filter&&(this.gain.disconnect(this.filter),this.filter.disconnect(this.context.destination),this.gain.connect(this.context.destination),this.filter=null)},getFilter:function(){return this.filter},setFilter:function(a){null!==this.filter?(this.gain.disconnect(this.filter),this.filter.disconnect(this.context.destination)):\nthis.gain.disconnect(this.context.destination);this.filter=a;this.gain.connect(this.filter);this.filter.connect(this.context.destination)},getMasterVolume:function(){return this.gain.gain.value},setMasterVolume:function(a){this.gain.gain.value=a},updateMatrixWorld:function(){var a=new Z.Vector3,b=new Z.Quaternion,c=new Z.Vector3,d=new Z.Vector3;return function(e){Z.Object3D.prototype.updateMatrixWorld.call(this,e);e=this.context.listener;var f=this.up;this.matrixWorld.decompose(a,b,c);Mf(d.set(0,\n0,-1),b);e.setPosition(a.x,a.y,a.z);e.setOrientation(d.x,d.y,d.z,f.x,f.y,f.z)}}()});Z.Camera=function(){Z.Object3D.call(this);this.type=\"Camera\";this.matrixWorldInverse=new Z.Matrix4;this.projectionMatrix=new Z.Matrix4};Z.Camera.prototype=Object.create(Z.Object3D.prototype);h=Z.Camera.prototype;h.constructor=Z.Camera;h.getWorldDirection=function(){var a=new Z.Quaternion;return function(b){b=b||new Z.Vector3;this.getWorldQuaternion(a);return Mf(b.set(0,0,-1),a)}}();\nh.lookAt=function(){var a=new Z.Matrix4;return function(b){a.lookAt(this.position,b,this.up);this.quaternion.setFromRotationMatrix(a)}}();h.clone=function(){return(new this.constructor).copy(this)};h.copy=function(a){Z.Object3D.prototype.copy.call(this,a);this.matrixWorldInverse.copy(a.matrixWorldInverse);this.projectionMatrix.copy(a.projectionMatrix);return this};\nZ.CubeCamera=function(a,b,c){Z.Object3D.call(this);this.type=\"CubeCamera\";var d=new Z.PerspectiveCamera(90,1,a,b);d.up.set(0,-1,0);d.lookAt(new Z.Vector3(1,0,0));this.add(d);var e=new Z.PerspectiveCamera(90,1,a,b);e.up.set(0,-1,0);e.lookAt(new Z.Vector3(-1,0,0));this.add(e);var f=new Z.PerspectiveCamera(90,1,a,b);f.up.set(0,0,1);f.lookAt(new Z.Vector3(0,1,0));this.add(f);var g=new Z.PerspectiveCamera(90,1,a,b);g.up.set(0,0,-1);g.lookAt(new Z.Vector3(0,-1,0));this.add(g);var k=new Z.PerspectiveCamera(90,\n1,a,b);k.up.set(0,-1,0);k.lookAt(new Z.Vector3(0,0,1));this.add(k);var l=new Z.PerspectiveCamera(90,1,a,b);l.up.set(0,-1,0);l.lookAt(new Z.Vector3(0,0,-1));this.add(l);this.renderTarget=new Z.WebGLRenderTargetCube(c,c,{format:Z.RGBFormat,magFilter:Z.LinearFilter,minFilter:Z.LinearFilter});this.updateCubeMap=function(a,b){null===this.parent&&this.updateMatrixWorld();var c=this.renderTarget,m=c.texture.generateMipmaps;c.texture.generateMipmaps=!1;c.activeCubeFace=0;a.render(b,d,c);c.activeCubeFace=\n1;a.render(b,e,c);c.activeCubeFace=2;a.render(b,f,c);c.activeCubeFace=3;a.render(b,g,c);c.activeCubeFace=4;a.render(b,k,c);c.texture.generateMipmaps=m;c.activeCubeFace=5;a.render(b,l,c);a.setRenderTarget(null)}};Z.CubeCamera.prototype=Object.create(Z.Object3D.prototype);Z.CubeCamera.prototype.constructor=Z.CubeCamera;\nZ.OrthographicCamera=function(a,b,c,d,e,f){Z.Camera.call(this);this.type=\"OrthographicCamera\";this.zoom=1;this.left=a;this.right=b;this.top=c;this.bottom=d;this.near=void 0!==e?e:.1;this.far=void 0!==f?f:2E3;this.updateProjectionMatrix()};\nZ.OrthographicCamera.prototype=Object.assign(Object.create(Z.Camera.prototype),{constructor:Z.OrthographicCamera,copy:function(a){Z.Camera.prototype.copy.call(this,a);this.left=a.left;this.right=a.right;this.top=a.top;this.bottom=a.bottom;this.near=a.near;this.far=a.far;this.zoom=a.zoom;return this},updateProjectionMatrix:function(){var a=(this.right-this.left)/(2*this.zoom),b=(this.top-this.bottom)/(2*this.zoom),c=(this.right+this.left)/2,d=(this.top+this.bottom)/2,e=c-a,a=c+a,c=d+b,b=d-b,d=this.near,\nf=this.far,g=this.projectionMatrix.elements,k=1/(a-e),l=1/(c-b),m=1/(f-d);g[0]=2*k;g[4]=0;g[8]=0;g[12]=-((a+e)*k);g[1]=0;g[5]=2*l;g[9]=0;g[13]=-((c+b)*l);g[2]=0;g[6]=0;g[10]=-2*m;g[14]=-((f+d)*m);g[3]=0;g[7]=0;g[11]=0;g[15]=1},toJSON:function(a){a=Z.Object3D.prototype.toJSON.call(this,a);a.object.zoom=this.zoom;a.object.left=this.left;a.object.right=this.right;a.object.top=this.top;a.object.bottom=this.bottom;a.object.near=this.near;a.object.far=this.far;return a}});\nZ.PerspectiveCamera=function(a,b,c,d){Z.Camera.call(this);this.type=\"PerspectiveCamera\";this.fov=void 0!==a?a:50;this.zoom=1;this.near=void 0!==c?c:.1;this.far=void 0!==d?d:2E3;this.focus=10;this.aspect=void 0!==b?b:1;this.view=null;this.filmGauge=35;this.filmOffset=0;this.updateProjectionMatrix()};\nZ.PerspectiveCamera.prototype=Object.assign(Object.create(Z.Camera.prototype),{constructor:Z.PerspectiveCamera,copy:function(a){Z.Camera.prototype.copy.call(this,a);this.fov=a.fov;this.zoom=a.zoom;this.near=a.near;this.far=a.far;this.focus=a.focus;this.aspect=a.aspect;this.view=null===a.view?null:Object.assign({},a.view);this.filmGauge=a.filmGauge;this.filmOffset=a.filmOffset;return this},setFocalLength:function(a){this.fov=2*Z.Math.RAD2DEG*Math.atan(.5*this.getFilmHeight()/a);this.updateProjectionMatrix()},\ngetFocalLength:function(){return.5*this.getFilmHeight()/Math.tan(.5*Z.Math.DEG2RAD*this.fov)},getEffectiveFOV:function(){return 2*Z.Math.RAD2DEG*Math.atan(Math.tan(.5*Z.Math.DEG2RAD*this.fov)/this.zoom)},getFilmWidth:function(){return this.filmGauge*Math.min(this.aspect,1)},getFilmHeight:function(){return this.filmGauge/Math.max(this.aspect,1)},setViewOffset:function(a,b,c,d,e,f){this.aspect=a/b;this.view={fullWidth:a,fullHeight:b,offsetX:c,offsetY:d,width:e,height:f};this.updateProjectionMatrix()},\nclearViewOffset:function(){this.view=null;this.updateProjectionMatrix()},updateProjectionMatrix:function(){var a=this.near,b=a*Math.tan(.5*Z.Math.DEG2RAD*this.fov)/this.zoom,c=2*b,d=this.aspect*c,e=-.5*d,f=this.view;if(null!==f)var g=f.fullWidth,k=f.fullHeight,e=e+f.offsetX*d/g,b=b-f.offsetY*c/k,d=f.width/g*d,c=f.height/k*c;f=this.filmOffset;0!==f&&(e+=a*f/this.getFilmWidth());Xf(this.projectionMatrix,e,e+d,b-c,b,a,this.far)},toJSON:function(a){a=Z.Object3D.prototype.toJSON.call(this,a);a.object.fov=\nthis.fov;a.object.zoom=this.zoom;a.object.near=this.near;a.object.far=this.far;a.object.focus=this.focus;a.object.aspect=this.aspect;null!==this.view&&(a.object.view=Object.assign({},this.view));a.object.filmGauge=this.filmGauge;a.object.filmOffset=this.filmOffset;return a}});\nZ.StereoCamera=function(){this.type=\"StereoCamera\";this.aspect=1;this.cameraL=new Z.PerspectiveCamera;this.cameraL.layers.enable(1);this.cameraL.matrixAutoUpdate=!1;this.cameraR=new Z.PerspectiveCamera;this.cameraR.layers.enable(2);this.cameraR.matrixAutoUpdate=!1};\nObject.assign(Z.StereoCamera.prototype,{update:function(){var a,b,c,d,e,f=new Z.Matrix4,g=new Z.Matrix4;return function(k){if(a!==k.focus||b!==k.fov||c!==k.aspect*this.aspect||d!==k.near||e!==k.far){a=k.focus;b=k.fov;c=k.aspect*this.aspect;d=k.near;e=k.far;var l=k.projectionMatrix.clone(),m=.032*d/a,n=d*Math.tan(Z.Math.DEG2RAD*b*.5);g.elements[12]=-.032;f.elements[12]=.032;var q=-n*c+m;var p=n*c+m;l.elements[0]=2*d/(p-q);l.elements[8]=(p+q)/(p-q);this.cameraL.projectionMatrix.copy(l);q=-n*c-m;p=n*\nc-m;l.elements[0]=2*d/(p-q);l.elements[8]=(p+q)/(p-q);this.cameraR.projectionMatrix.copy(l)}this.cameraL.matrixWorld.copy(k.matrixWorld).multiply(g);this.cameraR.matrixWorld.copy(k.matrixWorld).multiply(f)}}()});Z.Light=function(a,b){Z.Object3D.call(this);this.type=\"Light\";this.color=new Z.Color(a);this.intensity=void 0!==b?b:1;this.receiveShadow=void 0};\nZ.Light.prototype=Object.assign(Object.create(Z.Object3D.prototype),{constructor:Z.Light,copy:function(a){Z.Object3D.prototype.copy.call(this,a);this.color.copy(a.color);this.intensity=a.intensity;return this},toJSON:function(a){a=Z.Object3D.prototype.toJSON.call(this,a);a.object.color=Hf(this.color);a.object.intensity=this.intensity;void 0!==this.groundColor&&(a.object.groundColor=Hf(this.groundColor));void 0!==this.distance&&(a.object.distance=this.distance);void 0!==this.angle&&(a.object.angle=\nthis.angle);void 0!==this.decay&&(a.object.decay=this.decay);void 0!==this.penumbra&&(a.object.penumbra=this.penumbra);return a}});Z.LightShadow=function(a){this.camera=a;this.bias=0;this.radius=1;this.mapSize=new Z.Vector2(512,512);this.map=null;this.matrix=new Z.Matrix4};Object.assign(Z.LightShadow.prototype,{copy:function(a){this.camera=a.camera.clone();this.bias=a.bias;this.radius=a.radius;this.mapSize.copy(a.mapSize);return this},clone:function(){return(new this.constructor).copy(this)}});\nZ.AmbientLight=function(a,b){Z.Light.call(this,a,b);this.type=\"AmbientLight\";this.castShadow=void 0};Z.AmbientLight.prototype=Object.assign(Object.create(Z.Light.prototype),{constructor:Z.AmbientLight});Z.DirectionalLight=function(a,b){Z.Light.call(this,a,b);this.type=\"DirectionalLight\";this.position.set(0,1,0);this.updateMatrix();this.target=new Z.Object3D;this.shadow=new Z.DirectionalLightShadow};\nZ.DirectionalLight.prototype=Object.assign(Object.create(Z.Light.prototype),{constructor:Z.DirectionalLight,copy:function(a){Z.Light.prototype.copy.call(this,a);this.target=a.target.clone();this.shadow=a.shadow.clone();return this}});Z.DirectionalLightShadow=function(){Z.LightShadow.call(this,new Z.OrthographicCamera(-5,5,5,-5,.5,500))};Z.DirectionalLightShadow.prototype=Object.assign(Object.create(Z.LightShadow.prototype),{constructor:Z.DirectionalLightShadow});\nZ.HemisphereLight=function(a,b,c){Z.Light.call(this,a,c);this.type=\"HemisphereLight\";this.castShadow=void 0;this.position.set(0,1,0);this.updateMatrix();this.groundColor=new Z.Color(b)};Z.HemisphereLight.prototype=Object.assign(Object.create(Z.Light.prototype),{constructor:Z.HemisphereLight,copy:function(a){Z.Light.prototype.copy.call(this,a);this.groundColor.copy(a.groundColor);return this}});\nZ.PointLight=function(a,b,c,d){Z.Light.call(this,a,b);this.type=\"PointLight\";Object.defineProperty(this,\"power\",{get:function(){return 4*this.intensity*Math.PI},set:function(a){this.intensity=a/(4*Math.PI)}});this.distance=void 0!==c?c:0;this.decay=void 0!==d?d:1;this.shadow=new Z.LightShadow(new Z.PerspectiveCamera(90,1,.5,500))};\nZ.PointLight.prototype=Object.assign(Object.create(Z.Light.prototype),{constructor:Z.PointLight,copy:function(a){Z.Light.prototype.copy.call(this,a);this.distance=a.distance;this.decay=a.decay;this.shadow=a.shadow.clone();return this}});\nZ.SpotLight=function(a,b,c,d,e,f){Z.Light.call(this,a,b);this.type=\"SpotLight\";this.position.set(0,1,0);this.updateMatrix();this.target=new Z.Object3D;Object.defineProperty(this,\"power\",{get:function(){return this.intensity*Math.PI},set:function(a){this.intensity=a/Math.PI}});this.distance=void 0!==c?c:0;this.angle=void 0!==d?d:Math.PI/3;this.penumbra=void 0!==e?e:0;this.decay=void 0!==f?f:1;this.shadow=new Z.SpotLightShadow};\nZ.SpotLight.prototype=Object.assign(Object.create(Z.Light.prototype),{constructor:Z.SpotLight,copy:function(a){Z.Light.prototype.copy.call(this,a);this.distance=a.distance;this.angle=a.angle;this.penumbra=a.penumbra;this.decay=a.decay;this.target=a.target.clone();this.shadow=a.shadow.clone();return this}});Z.SpotLightShadow=function(){Z.LightShadow.call(this,new Z.PerspectiveCamera(50,1,.5,500))};\nZ.SpotLightShadow.prototype=Object.assign(Object.create(Z.LightShadow.prototype),{constructor:Z.SpotLightShadow,update:function(a){var b=2*Z.Math.RAD2DEG*a.angle,c=this.mapSize.width/this.mapSize.height;a=a.distance||500;var d=this.camera;if(b!==d.fov||c!==d.aspect||a!==d.far)d.fov=b,d.aspect=c,d.far=a,d.updateProjectionMatrix()}});Z.AudioLoader=function(a){this.manager=void 0!==a?a:Z.DefaultLoadingManager};\nZ.AudioLoader.prototype={constructor:Z.AudioLoader,load:function(a,b,c,d){var e=new Z.XHRLoader(this.manager);qg(e);e.load(a,function(a){Z.AudioContext.decodeAudioData(a,function(a){b(a)})},c,d)}};Z.Cache={enabled:!1,files:{},add:function(a,b){!1!==this.enabled&&(this.files[a]=b)},get:function(a){if(!1!==this.enabled)return this.files[a]},remove:function(a){delete this.files[a]},clear:function(){this.files={}}};\nZ.Loader=function(){this.onLoadStart=function(){};this.onLoadProgress=function(){};this.onLoadComplete=function(){}};\nZ.Loader.prototype={constructor:Z.Loader,crossOrigin:void 0,createMaterial:function(){var a,b,c;return function(d,e,f){function g(a,c,d,g,l){a=e+a;var m=Z.Loader.Handlers.get(a);null!==m?a=m.load(a):(b.setCrossOrigin(f),a=b.load(a));void 0!==c&&(a.repeat.fromArray(c),1!==c[0]&&(a.wrapS=Z.RepeatWrapping),1!==c[1]&&(a.wrapT=Z.RepeatWrapping));void 0!==d&&a.offset.fromArray(d);void 0!==g&&(\"repeat\"===g[0]&&(a.wrapS=Z.RepeatWrapping),\"mirror\"===g[0]&&(a.wrapS=Z.MirroredRepeatWrapping),\"repeat\"===g[1]&&\n(a.wrapT=Z.RepeatWrapping),\"mirror\"===g[1]&&(a.wrapT=Z.MirroredRepeatWrapping));void 0!==l&&(a.anisotropy=l);c=Z.Math.generateUUID();k[c]=a;return c}void 0===a&&(a=new Z.Color);void 0===b&&(b=new Z.TextureLoader);void 0===c&&(c=new Z.MaterialLoader);var k={},l={uuid:Z.Math.generateUUID(),type:\"MeshLambertMaterial\"},m;for(m in d){var n=d[m];switch(m){case \"DbgColor\":case \"DbgIndex\":case \"opticalDensity\":case \"illumination\":break;case \"DbgName\":l.name=n;break;case \"blending\":l.blending=Z[n];break;case \"colorAmbient\":case \"mapAmbient\":console.warn(\"THREE.Loader.createMaterial:\",\nm,\"is no longer supported.\");break;case \"colorDiffuse\":l.color=Hf(a.fromArray(n));break;case \"colorSpecular\":l.specular=Hf(a.fromArray(n));break;case \"colorEmissive\":l.emissive=Hf(a.fromArray(n));break;case \"specularCoef\":l.shininess=n;break;case \"shading\":\"basic\"===n.toLowerCase()&&(l.type=\"MeshBasicMaterial\");\"phong\"===n.toLowerCase()&&(l.type=\"MeshPhongMaterial\");break;case \"mapDiffuse\":l.map=g(n,d.mapDiffuseRepeat,d.mapDiffuseOffset,d.mapDiffuseWrap,d.mapDiffuseAnisotropy);break;case \"mapDiffuseRepeat\":case \"mapDiffuseOffset\":case \"mapDiffuseWrap\":case \"mapDiffuseAnisotropy\":break;\ncase \"mapLight\":l.lightMap=g(n,d.mapLightRepeat,d.mapLightOffset,d.mapLightWrap,d.mapLightAnisotropy);break;case \"mapLightRepeat\":case \"mapLightOffset\":case \"mapLightWrap\":case \"mapLightAnisotropy\":break;case \"mapAO\":l.aoMap=g(n,d.mapAORepeat,d.mapAOOffset,d.mapAOWrap,d.mapAOAnisotropy);break;case \"mapAORepeat\":case \"mapAOOffset\":case \"mapAOWrap\":case \"mapAOAnisotropy\":break;case \"mapBump\":l.bumpMap=g(n,d.mapBumpRepeat,d.mapBumpOffset,d.mapBumpWrap,d.mapBumpAnisotropy);break;case \"mapBumpScale\":l.bumpScale=\nn;break;case \"mapBumpRepeat\":case \"mapBumpOffset\":case \"mapBumpWrap\":case \"mapBumpAnisotropy\":break;case \"mapNormal\":l.normalMap=g(n,d.mapNormalRepeat,d.mapNormalOffset,d.mapNormalWrap,d.mapNormalAnisotropy);break;case \"mapNormalFactor\":l.normalScale=[n,n];break;case \"mapNormalRepeat\":case \"mapNormalOffset\":case \"mapNormalWrap\":case \"mapNormalAnisotropy\":break;case \"mapSpecular\":l.specularMap=g(n,d.mapSpecularRepeat,d.mapSpecularOffset,d.mapSpecularWrap,d.mapSpecularAnisotropy);break;case \"mapSpecularRepeat\":case \"mapSpecularOffset\":case \"mapSpecularWrap\":case \"mapSpecularAnisotropy\":break;\ncase \"mapAlpha\":l.alphaMap=g(n,d.mapAlphaRepeat,d.mapAlphaOffset,d.mapAlphaWrap,d.mapAlphaAnisotropy);break;case \"mapAlphaRepeat\":case \"mapAlphaOffset\":case \"mapAlphaWrap\":case \"mapAlphaAnisotropy\":break;case \"flipSided\":l.side=Z.BackSide;break;case \"doubleSided\":l.side=Z.DoubleSide;break;case \"transparency\":console.warn(\"THREE.Loader.createMaterial: transparency has been renamed to opacity\");l.opacity=n;break;case \"depthTest\":case \"depthWrite\":case \"colorWrite\":case \"opacity\":case \"reflectivity\":case \"transparent\":case \"visible\":case \"wireframe\":l[m]=\nn;break;case \"vertexColors\":!0===n&&(l.vertexColors=Z.VertexColors);\"face\"===n&&(l.vertexColors=Z.FaceColors);break;default:console.error(\"THREE.Loader.createMaterial: Unsupported\",m,n)}}\"MeshBasicMaterial\"===l.type&&delete l.emissive;\"MeshPhongMaterial\"!==l.type&&delete l.specular;1>l.opacity&&(l.transparent=!0);c.textures=k;return c.parse(l)}}()};function rg(a,b,c){for(var d=Z.Loader.prototype,e=[],f=0;f<a.length;++f)e[f]=d.createMaterial(a[f],b,c);return e}\nfunction sg(a){a=a.split(\"/\");if(1===a.length)return\"./\";a.pop();return a.join(\"/\")+\"/\"}Z.Loader.Handlers={handlers:[],add:function(a,b){this.handlers.push(a,b)},get:function(a){for(var b=this.handlers,c=0,d=b.length;c<d;c+=2){var e=b[c+1];if(b[c].test(a))return e}return null}};Z.XHRLoader=function(a){this.manager=void 0!==a?a:Z.DefaultLoadingManager};\nZ.XHRLoader.prototype={constructor:Z.XHRLoader,load:function(a,b,c,d){void 0!==this.path&&(a=this.path+a);var e=this,f=Z.Cache.get(a);if(void 0!==f)return b&&setTimeout(function(){b(f)},0),f;var g=new XMLHttpRequest;g.overrideMimeType(\"text/plain\");g.open(\"GET\",a,!0);g.addEventListener(\"load\",function(c){var f=c.target.response;Z.Cache.add(a,f);200===this.status?(b&&b(f),e.manager.itemEnd(a)):0===this.status?(console.warn(\"THREE.XHRLoader: HTTP Status 0 received.\"),b&&b(f),e.manager.itemEnd(a)):(d&&\nd(c),e.manager.itemError(a))},!1);void 0!==c&&g.addEventListener(\"progress\",function(a){c(a)},!1);g.addEventListener(\"error\",function(b){d&&d(b);e.manager.itemError(a)},!1);void 0!==this.responseType&&(g.responseType=this.responseType);void 0!==this.withCredentials&&(g.withCredentials=this.withCredentials);g.send(null);e.manager.itemStart(a);return g},setPath:function(a){this.path=a}};function qg(a){a.responseType=\"arraybuffer\"}Z.FontLoader=function(a){this.manager=void 0!==a?a:Z.DefaultLoadingManager};\nZ.FontLoader.prototype={constructor:Z.FontLoader,load:function(a,b,c,d){var e=this;(new Z.XHRLoader(this.manager)).load(a,function(a){try{var c=JSON.parse(a)}catch(k){console.warn(\"THREE.FontLoader: typeface.js support is being deprecated. Use typeface.json instead.\"),c=JSON.parse(a.substring(65,a.length-2))}a=e.parse(c);b&&b(a)},c,d)},parse:function(a){return new Z.Font(a)}};Z.ImageLoader=function(a){this.manager=void 0!==a?a:Z.DefaultLoadingManager};\nZ.ImageLoader.prototype={constructor:Z.ImageLoader,load:function(a,b,c,d){void 0!==this.path&&(a=this.path+a);var e=this,f=Z.Cache.get(a);if(void 0!==f)return e.manager.itemStart(a),b?setTimeout(function(){b(f);e.manager.itemEnd(a)},0):e.manager.itemEnd(a),f;var g=document.createElement(\"img\");g.addEventListener(\"load\",function(){Z.Cache.add(a,this);b&&b(this);e.manager.itemEnd(a)},!1);void 0!==c&&g.addEventListener(\"progress\",function(a){c(a)},!1);g.addEventListener(\"error\",function(b){d&&d(b);e.manager.itemError(a)},\n!1);void 0!==this.crossOrigin&&(g.crossOrigin=this.crossOrigin);e.manager.itemStart(a);g.src=a;return g},setCrossOrigin:function(a){this.crossOrigin=a},setPath:function(a){this.path=a}};Z.JSONLoader=function(a){\"boolean\"===typeof a&&(console.warn(\"THREE.JSONLoader: showStatus parameter has been removed from constructor.\"),a=void 0);this.manager=void 0!==a?a:Z.DefaultLoadingManager;this.withCredentials=!1};\nZ.JSONLoader.prototype={constructor:Z.JSONLoader,get statusDomElement(){void 0===this._statusDomElement&&(this._statusDomElement=document.createElement(\"div\"));console.warn(\"THREE.JSONLoader: .statusDomElement has been removed.\");return this._statusDomElement},load:function(a,b,c,d){var e=this,f=this.texturePath&&\"string\"===typeof this.texturePath?this.texturePath:sg(a),g=new Z.XHRLoader(this.manager);g.withCredentials=this.withCredentials;g.load(a,function(c){c=JSON.parse(c);var d=c.metadata;if(void 0!==\nd&&(d=d.type,void 0!==d)){if(\"object\"===d.toLowerCase()){console.error(\"THREE.JSONLoader: \"+a+\" should be loaded with THREE.ObjectLoader instead.\");return}if(\"scene\"===d.toLowerCase()){console.error(\"THREE.JSONLoader: \"+a+\" should be loaded with THREE.SceneLoader instead.\");return}}c=e.parse(c,f);b(c.geometry,c.materials)},c,d)},setTexturePath:function(a){this.texturePath=a},parse:function(a,b){var c=new Z.Geometry,d=void 0!==a.scale?1/a.scale:1;(function(b){var d,e,k,l=a.faces;var m=a.vertices;var n=\na.normals,q=a.colors,p=0;if(void 0!==a.uvs){for(d=0;d<a.uvs.length;d++)a.uvs[d].length&&p++;for(d=0;d<p;d++)c.faceVertexUvs[d]=[]}var t=0;for(k=m.length;t<k;)d=new Z.Vector3,d.x=m[t++]*b,d.y=m[t++]*b,d.z=m[t++]*b,c.vertices.push(d);t=0;for(k=l.length;t<k;){b=l[t++];var r=b&1;var v=b&2;d=b&8;var w=b&16;var z=b&32;m=b&64;b&=128;if(r){r=new Z.Face3;r.a=l[t];r.b=l[t+1];r.c=l[t+3];var y=new Z.Face3;y.a=l[t+1];y.b=l[t+2];y.c=l[t+3];t+=4;v&&(v=l[t++],r.materialIndex=v,y.materialIndex=v);v=c.faces.length;\nif(d)for(d=0;d<p;d++){var B=a.uvs[d];c.faceVertexUvs[d][v]=[];c.faceVertexUvs[d][v+1]=[];for(e=0;4>e;e++){var A=l[t++];var D=B[2*A];A=B[2*A+1];D=new Z.Vector2(D,A);2!==e&&c.faceVertexUvs[d][v].push(D);0!==e&&c.faceVertexUvs[d][v+1].push(D)}}w&&(w=3*l[t++],r.normal.set(n[w++],n[w++],n[w]),y.normal.copy(r.normal));if(z)for(d=0;4>d;d++)w=3*l[t++],z=new Z.Vector3(n[w++],n[w++],n[w]),2!==d&&r.vertexNormals.push(z),0!==d&&y.vertexNormals.push(z);m&&(m=l[t++],m=q[m],Ff(r.color,m),Ff(y.color,m));if(b)for(d=\n0;4>d;d++)m=l[t++],m=q[m],2!==d&&r.vertexColors.push(new Z.Color(m)),0!==d&&y.vertexColors.push(new Z.Color(m));c.faces.push(r);c.faces.push(y)}else{r=new Z.Face3;r.a=l[t++];r.b=l[t++];r.c=l[t++];v&&(v=l[t++],r.materialIndex=v);v=c.faces.length;if(d)for(d=0;d<p;d++)for(B=a.uvs[d],c.faceVertexUvs[d][v]=[],e=0;3>e;e++)A=l[t++],D=B[2*A],A=B[2*A+1],D=new Z.Vector2(D,A),c.faceVertexUvs[d][v].push(D);w&&(w=3*l[t++],r.normal.set(n[w++],n[w++],n[w]));if(z)for(d=0;3>d;d++)w=3*l[t++],z=new Z.Vector3(n[w++],\nn[w++],n[w]),r.vertexNormals.push(z);m&&(m=l[t++],Ff(r.color,q[m]));if(b)for(d=0;3>d;d++)m=l[t++],r.vertexColors.push(new Z.Color(q[m]));c.faces.push(r)}}})(d);(function(){var b=void 0!==a.influencesPerVertex?a.influencesPerVertex:2;if(a.skinWeights)for(var d=0,g=a.skinWeights.length;d<g;d+=b)c.skinWeights.push(new Z.Vector4(a.skinWeights[d],1<b?a.skinWeights[d+1]:0,2<b?a.skinWeights[d+2]:0,3<b?a.skinWeights[d+3]:0));if(a.skinIndices)for(d=0,g=a.skinIndices.length;d<g;d+=b)c.skinIndices.push(new Z.Vector4(a.skinIndices[d],\n1<b?a.skinIndices[d+1]:0,2<b?a.skinIndices[d+2]:0,3<b?a.skinIndices[d+3]:0));c.bones=a.bones;c.bones&&0<c.bones.length&&(c.skinWeights.length!==c.skinIndices.length||c.skinIndices.length!==c.vertices.length)&&console.warn(\"When skinning, number of vertices (\"+c.vertices.length+\"), skinIndices (\"+c.skinIndices.length+\"), and skinWeights (\"+c.skinWeights.length+\") should match.\")})();(function(b){if(void 0!==a.morphTargets)for(var d=0,e=a.morphTargets.length;d<e;d++){c.morphTargets[d]={};c.morphTargets[d].name=\na.morphTargets[d].name;c.morphTargets[d].vertices=[];for(var k=c.morphTargets[d].vertices,l=a.morphTargets[d].vertices,m=0,n=l.length;m<n;m+=3){var q=new Z.Vector3;q.x=l[m]*b;q.y=l[m+1]*b;q.z=l[m+2]*b;k.push(q)}}if(void 0!==a.morphColors&&0<a.morphColors.length)for(console.warn('THREE.JSONLoader: \"morphColors\" no longer supported. Using them as face colors.'),b=c.faces,k=a.morphColors[0].colors,d=0,e=b.length;d<e;d++)b[d].color.fromArray(k,3*d)})(d);(function(){var b=[],d=[];void 0!==a.animation&&\nd.push(a.animation);void 0!==a.animations&&(a.animations.length?d=d.concat(a.animations):d.push(a.animations));for(var g=0;g<d.length;g++){var k=Z.AnimationClip.parseAnimation(d[g],c.bones);k&&b.push(k)}c.morphTargets&&(d=Z.AnimationClip.CreateClipsFromMorphTargetSequences(c.morphTargets,10),b=b.concat(d));0<b.length&&(c.animations=b)})();c.computeFaceNormals();c.computeBoundingSphere();if(void 0===a.materials||0===a.materials.length)return{geometry:c};b=rg(a.materials,b,this.crossOrigin);return{geometry:c,\nmaterials:b}}};Z.LoadingManager=function(a){var b=this,c=!1,d=0,e=0;this.onStart=void 0;this.onLoad=a;this.onError=this.onProgress=void 0;this.itemStart=function(a){e++;if(!1===c&&void 0!==b.onStart)b.onStart(a,d,e);c=!0};this.itemEnd=function(a){d++;if(void 0!==b.onProgress)b.onProgress(a,d,e);if(d===e&&(c=!1,void 0!==b.onLoad))b.onLoad()};this.itemError=function(a){if(void 0!==b.onError)b.onError(a)}};Z.DefaultLoadingManager=new Z.LoadingManager;\nZ.BufferGeometryLoader=function(a){this.manager=void 0!==a?a:Z.DefaultLoadingManager};\nZ.BufferGeometryLoader.prototype={constructor:Z.BufferGeometryLoader,load:function(a,b,c,d){var e=this;(new Z.XHRLoader(e.manager)).load(a,function(a){b(e.parse(JSON.parse(a)))},c,d)},parse:function(a){var b=new Z.BufferGeometry;var c=a.data.index;var d={Int8Array:Int8Array,Uint8Array:Uint8Array,Uint8ClampedArray:Uint8ClampedArray,Int16Array:Int16Array,Uint16Array:Uint16Array,Int32Array:Int32Array,Uint32Array:Uint32Array,Float32Array:Float32Array,Float64Array:Float64Array};if(void 0!==c){var e=new d[c.type](c.array);\nb.setIndex(new Z.BufferAttribute(e,1))}var f=a.data.attributes;for(g in f)c=f[g],e=new d[c.type](c.array),b.addAttribute(g,new Z.BufferAttribute(e,c.itemSize,c.normalized));d=a.data.groups||a.data.drawcalls||a.data.offsets;if(void 0!==d){var g=0;for(c=d.length;g!==c;++g)e=d[g],b.addGroup(e.start,e.count,e.materialIndex)}a=a.data.boundingSphere;void 0!==a&&(d=new Z.Vector3,void 0!==a.center&&d.fromArray(a.center),b.boundingSphere=new Z.Sphere(d,a.radius));return b}};\nZ.MaterialLoader=function(a){this.manager=void 0!==a?a:Z.DefaultLoadingManager;this.textures={}};\nZ.MaterialLoader.prototype={constructor:Z.MaterialLoader,load:function(a,b,c,d){var e=this;(new Z.XHRLoader(e.manager)).load(a,function(a){b(e.parse(JSON.parse(a)))},c,d)},parse:function(a){var b=new Z[a.type];void 0!==a.uuid&&(b.uuid=a.uuid);void 0!==a.name&&(b.name=a.name);void 0!==a.color&&Ff(b.color,a.color);void 0!==a.roughness&&(b.roughness=a.roughness);void 0!==a.metalness&&(b.metalness=a.metalness);void 0!==a.emissive&&Ff(b.emissive,a.emissive);void 0!==a.specular&&Ff(b.specular,a.specular);\nvoid 0!==a.shininess&&(b.shininess=a.shininess);void 0!==a.uniforms&&(b.uniforms=a.uniforms);void 0!==a.vertexShader&&(b.vertexShader=a.vertexShader);void 0!==a.fragmentShader&&(b.fragmentShader=a.fragmentShader);void 0!==a.vertexColors&&(b.vertexColors=a.vertexColors);void 0!==a.shading&&(b.shading=a.shading);void 0!==a.blending&&(b.blending=a.blending);void 0!==a.side&&(b.side=a.side);void 0!==a.opacity&&(b.opacity=a.opacity);void 0!==a.transparent&&(b.transparent=a.transparent);void 0!==a.alphaTest&&\n(b.alphaTest=a.alphaTest);void 0!==a.depthTest&&(b.depthTest=a.depthTest);void 0!==a.depthWrite&&(b.depthWrite=a.depthWrite);void 0!==a.colorWrite&&(b.colorWrite=a.colorWrite);void 0!==a.wireframe&&(b.wireframe=a.wireframe);void 0!==a.wireframeLinewidth&&(b.wireframeLinewidth=a.wireframeLinewidth);void 0!==a.size&&(b.size=a.size);void 0!==a.sizeAttenuation&&(b.sizeAttenuation=a.sizeAttenuation);void 0!==a.map&&(b.map=tg(this,a.map));void 0!==a.alphaMap&&(b.alphaMap=tg(this,a.alphaMap),b.transparent=\n!0);void 0!==a.bumpMap&&(b.bumpMap=tg(this,a.bumpMap));void 0!==a.bumpScale&&(b.bumpScale=a.bumpScale);void 0!==a.normalMap&&(b.normalMap=tg(this,a.normalMap));if(void 0!==a.normalScale){var c=a.normalScale;!1===Array.isArray(c)&&(c=[c,c]);b.normalScale=(new Z.Vector2).fromArray(c)}void 0!==a.displacementMap&&(b.displacementMap=tg(this,a.displacementMap));void 0!==a.displacementScale&&(b.displacementScale=a.displacementScale);void 0!==a.displacementBias&&(b.displacementBias=a.displacementBias);void 0!==\na.roughnessMap&&(b.roughnessMap=tg(this,a.roughnessMap));void 0!==a.metalnessMap&&(b.metalnessMap=tg(this,a.metalnessMap));void 0!==a.emissiveMap&&(b.emissiveMap=tg(this,a.emissiveMap));void 0!==a.emissiveIntensity&&(b.emissiveIntensity=a.emissiveIntensity);void 0!==a.specularMap&&(b.specularMap=tg(this,a.specularMap));void 0!==a.envMap&&(b.envMap=tg(this,a.envMap),b.combine=Z.MultiplyOperation);a.reflectivity&&(b.reflectivity=a.reflectivity);void 0!==a.lightMap&&(b.lightMap=tg(this,a.lightMap));\nvoid 0!==a.lightMapIntensity&&(b.lightMapIntensity=a.lightMapIntensity);void 0!==a.aoMap&&(b.aoMap=tg(this,a.aoMap));void 0!==a.aoMapIntensity&&(b.aoMapIntensity=a.aoMapIntensity);if(void 0!==a.materials)for(var c=0,d=a.materials.length;c<d;c++)b.materials.push(this.parse(a.materials[c]));return b}};function tg(a,b){a=a.textures;void 0===a[b]&&console.warn(\"THREE.MaterialLoader: Undefined texture\",b);return a[b]}\nZ.ObjectLoader=function(a){this.manager=void 0!==a?a:Z.DefaultLoadingManager;this.texturePath=\"\"};\nZ.ObjectLoader.prototype={constructor:Z.ObjectLoader,load:function(a,b,c,d){\"\"===this.texturePath&&(this.texturePath=a.substring(0,a.lastIndexOf(\"/\")+1));var e=this;(new Z.XHRLoader(e.manager)).load(a,function(a){e.parse(JSON.parse(a),b)},c,d)},setTexturePath:function(a){this.texturePath=a},setCrossOrigin:function(a){this.crossOrigin=a},parse:function(a,b){var c=ug(this,a.geometries),d=vg(this,a.images,function(){void 0!==b&&b(e)}),d=wg(a.textures,d),d=xg(a.materials,d),e=this.parseObject(a.object,\nc,d);a.animations&&(e.animations=yg(a.animations));void 0!==a.images&&0!==a.images.length||void 0===b||b(e);return e},parseObject:function(){var a=new Z.Matrix4;return function(b,c,d){function e(a){void 0===c[a]&&console.warn(\"THREE.ObjectLoader: Undefined geometry\",a);return c[a]}function f(a){if(void 0!==a)return void 0===d[a]&&console.warn(\"THREE.ObjectLoader: Undefined material\",a),d[a]}switch(b.type){case \"Scene\":var g=new Z.Scene;break;case \"PerspectiveCamera\":g=new Z.PerspectiveCamera(b.fov,\nb.aspect,b.near,b.far);void 0!==b.focus&&(g.focus=b.focus);void 0!==b.zoom&&(g.zoom=b.zoom);void 0!==b.filmGauge&&(g.filmGauge=b.filmGauge);void 0!==b.filmOffset&&(g.filmOffset=b.filmOffset);void 0!==b.view&&(g.view=Object.assign({},b.view));break;case \"OrthographicCamera\":g=new Z.OrthographicCamera(b.left,b.right,b.top,b.bottom,b.near,b.far);break;case \"AmbientLight\":g=new Z.AmbientLight(b.color,b.intensity);break;case \"DirectionalLight\":g=new Z.DirectionalLight(b.color,b.intensity);break;case \"PointLight\":g=\nnew Z.PointLight(b.color,b.intensity,b.distance,b.decay);break;case \"SpotLight\":g=new Z.SpotLight(b.color,b.intensity,b.distance,b.angle,b.penumbra,b.decay);break;case \"HemisphereLight\":g=new Z.HemisphereLight(b.color,b.groundColor,b.intensity);break;case \"Mesh\":g=e(b.geometry);var k=f(b.material);g=g.bones&&0<g.bones.length?new Z.SkinnedMesh(g,k):new Z.Mesh(g,k);break;case \"LOD\":g=new Z.LOD;break;case \"Line\":g=new Z.Line(e(b.geometry),f(b.material),b.mode);break;case \"PointCloud\":case \"Points\":g=\nnew Z.Points(e(b.geometry),f(b.material));break;case \"Sprite\":g=new Z.Sprite(f(b.material));break;case \"Group\":g=new Z.Group;break;default:g=new Z.Object3D}g.uuid=b.uuid;void 0!==b.name&&(g.name=b.name);void 0!==b.matrix?(a.fromArray(b.matrix),a.decompose(g.position,g.quaternion,g.scale)):(void 0!==b.position&&g.position.fromArray(b.position),void 0!==b.rotation&&g.rotation.fromArray(b.rotation),void 0!==b.scale&&g.scale.fromArray(b.scale));void 0!==b.castShadow&&(g.castShadow=b.castShadow);void 0!==\nb.receiveShadow&&(g.receiveShadow=b.receiveShadow);void 0!==b.visible&&(g.visible=b.visible);void 0!==b.userData&&(g.userData=b.userData);if(void 0!==b.children)for(m in b.children)g.add(this.parseObject(b.children[m],c,d));if(\"LOD\"===b.type){b=b.levels;for(var l=0;l<b.length;l++){k=b[l];var m=g.getObjectByProperty(\"uuid\",k.object);void 0!==m&&g.addLevel(m,k.distance)}}return g}}()};\nfunction wg(a,b){function c(a){if(\"number\"===typeof a)return a;console.warn(\"THREE.ObjectLoader.parseTexture: Constant should be in numeric form.\",a);return Z[a]}var d={};if(void 0!==a)for(var e=0,f=a.length;e<f;e++){var g=a[e];void 0===g.image&&console.warn('THREE.ObjectLoader: No \"image\" specified for',g.uuid);void 0===b[g.image]&&console.warn(\"THREE.ObjectLoader: Undefined image\",g.image);var k=new Z.Texture(b[g.image]);k.needsUpdate=!0;k.uuid=g.uuid;void 0!==g.name&&(k.name=g.name);void 0!==g.mapping&&\n(k.mapping=c(g.mapping));void 0!==g.offset&&(k.offset=new Z.Vector2(g.offset[0],g.offset[1]));void 0!==g.repeat&&(k.repeat=new Z.Vector2(g.repeat[0],g.repeat[1]));void 0!==g.minFilter&&(k.minFilter=c(g.minFilter));void 0!==g.magFilter&&(k.magFilter=c(g.magFilter));void 0!==g.anisotropy&&(k.anisotropy=g.anisotropy);Array.isArray(g.wrap)&&(k.wrapS=c(g.wrap[0]),k.wrapT=c(g.wrap[1]));d[g.uuid]=k}return d}\nfunction vg(a,b,c){function d(a){e.manager.itemStart(a);return g.load(a,function(){e.manager.itemEnd(a)})}var e=a,f={};if(void 0!==b&&0<b.length){c=new Z.LoadingManager(c);var g=new Z.ImageLoader(c);g.setCrossOrigin(a.crossOrigin);a=0;for(c=b.length;a<c;a++){var k=b[a],l=/^(\\/\\/)|([a-z]+:(\\/\\/)?)/i.test(k.url)?k.url:e.texturePath+k.url;f[k.uuid]=d(l)}}return f}function yg(a){for(var b=[],c=0;c<a.length;c++){var d=Z.AnimationClip.parse(a[c]);b.push(d)}return b}\nfunction xg(a,b){var c={};if(void 0!==a){var d=new Z.MaterialLoader;d.textures=b;b=0;for(var e=a.length;b<e;b++){var f=d.parse(a[b]);c[f.uuid]=f}}return c}\nfunction ug(a,b){var c={};if(void 0!==b)for(var d=new Z.JSONLoader,e=new Z.BufferGeometryLoader,f=0,g=b.length;f<g;f++){var k=b[f];switch(k.type){case \"PlaneGeometry\":case \"PlaneBufferGeometry\":var l=new Z[k.type](k.width,k.height,k.widthSegments,k.heightSegments);break;case \"BoxGeometry\":case \"BoxBufferGeometry\":case \"CubeGeometry\":l=new Z[k.type](k.width,k.height,k.depth,k.widthSegments,k.heightSegments,k.depthSegments);break;case \"CircleGeometry\":case \"CircleBufferGeometry\":l=new Z[k.type](k.radius,\nk.segments,k.thetaStart,k.thetaLength);break;case \"CylinderGeometry\":case \"CylinderBufferGeometry\":l=new Z[k.type](k.radiusTop,k.radiusBottom,k.height,k.radialSegments,k.heightSegments,k.openEnded,k.thetaStart,k.thetaLength);break;case \"ConeGeometry\":case \"ConeBufferGeometry\":l=new Z[k.type](k.radius,k.height,k.radialSegments,k.heightSegments,k.openEnded,k.thetaStart,k.thetaLength);break;case \"SphereGeometry\":case \"SphereBufferGeometry\":l=new Z[k.type](k.radius,k.widthSegments,k.heightSegments,k.phiStart,\nk.phiLength,k.thetaStart,k.thetaLength);break;case \"DodecahedronGeometry\":case \"IcosahedronGeometry\":case \"OctahedronGeometry\":case \"TetrahedronGeometry\":l=new Z[k.type](k.radius,k.detail);break;case \"RingGeometry\":case \"RingBufferGeometry\":l=new Z[k.type](k.innerRadius,k.outerRadius,k.thetaSegments,k.phiSegments,k.thetaStart,k.thetaLength);break;case \"TorusGeometry\":case \"TorusBufferGeometry\":l=new Z[k.type](k.radius,k.tube,k.radialSegments,k.tubularSegments,k.arc);break;case \"TorusKnotGeometry\":case \"TorusKnotBufferGeometry\":l=\nnew Z[k.type](k.radius,k.tube,k.tubularSegments,k.radialSegments,k.p,k.q);break;case \"LatheGeometry\":case \"LatheBufferGeometry\":l=new Z[k.type](k.points,k.segments,k.phiStart,k.phiLength);break;case \"BufferGeometry\":l=e.parse(k);break;case \"Geometry\":l=d.parse(k.data,a.texturePath).geometry;break;default:console.warn('THREE.ObjectLoader: Unsupported geometry type \"'+k.type+'\"');continue}l.uuid=k.uuid;void 0!==k.name&&(l.name=k.name);c[k.uuid]=l}return c}\nZ.TextureLoader=function(a){this.manager=void 0!==a?a:Z.DefaultLoadingManager};Z.TextureLoader.prototype={constructor:Z.TextureLoader,load:function(a,b,c,d){var e=new Z.Texture,f=new Z.ImageLoader(this.manager);f.setCrossOrigin(this.crossOrigin);f.setPath(this.path);f.load(a,function(a){e.image=a;e.needsUpdate=!0;void 0!==b&&b(e)},c,d);return e},setCrossOrigin:function(a){this.crossOrigin=a},setPath:function(a){this.path=a}};Z.CubeTextureLoader=function(a){this.manager=void 0!==a?a:Z.DefaultLoadingManager};\nZ.CubeTextureLoader.prototype={constructor:Z.CubeTextureLoader,load:function(a,b,c,d){function e(c){g.load(a[c],function(a){f.images[c]=a;k++;6===k&&(f.needsUpdate=!0,b&&b(f))},void 0,d)}var f=new Z.CubeTexture,g=new Z.ImageLoader(this.manager);g.setCrossOrigin(this.crossOrigin);g.setPath(this.path);var k=0;for(c=0;c<a.length;++c)e(c);return f},setCrossOrigin:function(a){this.crossOrigin=a},setPath:function(a){this.path=a}};\nZ.DataTextureLoader=Z.BinaryTextureLoader=function(a){this.manager=void 0!==a?a:Z.DefaultLoadingManager;this._parser=null};\nZ.BinaryTextureLoader.prototype={constructor:Z.BinaryTextureLoader,load:function(a,b,c,d){var e=this,f=new Z.DataTexture,g=new Z.XHRLoader(this.manager);qg(g);g.load(a,function(a){if(a=e._parser(a))void 0!==a.image?f.image=a.image:void 0!==a.data&&(f.image.width=a.width,f.image.height=a.height,f.image.data=a.data),f.wrapS=void 0!==a.wrapS?a.wrapS:Z.ClampToEdgeWrapping,f.wrapT=void 0!==a.wrapT?a.wrapT:Z.ClampToEdgeWrapping,f.magFilter=void 0!==a.magFilter?a.magFilter:Z.LinearFilter,f.minFilter=void 0!==\na.minFilter?a.minFilter:Z.LinearMipMapLinearFilter,f.anisotropy=void 0!==a.anisotropy?a.anisotropy:1,void 0!==a.format&&(f.format=a.format),void 0!==a.type&&(f.type=a.type),void 0!==a.mipmaps&&(f.mipmaps=a.mipmaps),1===a.mipmapCount&&(f.minFilter=Z.LinearFilter),f.needsUpdate=!0,b&&b(f,a)},c,d);return f}};Z.CompressedTextureLoader=function(a){this.manager=void 0!==a?a:Z.DefaultLoadingManager;this._parser=null};\nZ.CompressedTextureLoader.prototype={constructor:Z.CompressedTextureLoader,load:function(a,b,c,d){function e(e){m.load(a[e],function(a){a=g._parser(a,!0);k[e]={width:a.width,height:a.height,format:a.format,mipmaps:a.mipmaps};f+=1;6===f&&(1===a.mipmapCount&&(l.minFilter=Z.LinearFilter),l.format=a.format,l.needsUpdate=!0,b&&b(l))},c,d)}var f,g=this,k=[],l=new Z.CompressedTexture;l.image=k;var m=new Z.XHRLoader(this.manager);m.setPath(this.path);qg(m);if(Array.isArray(a))for(var n=f=0,q=a.length;n<q;++n)e(n);\nelse m.load(a,function(a){a=g._parser(a,!0);if(a.isCubemap)for(var c=a.mipmaps.length/a.mipmapCount,d=0;d<c;d++){k[d]={mipmaps:[]};for(var e=0;e<a.mipmapCount;e++)k[d].mipmaps.push(a.mipmaps[d*a.mipmapCount+e]),k[d].format=a.format,k[d].width=a.width,k[d].height=a.height}else l.image.width=a.width,l.image.height=a.height,l.mipmaps=a.mipmaps;1===a.mipmapCount&&(l.minFilter=Z.LinearFilter);l.format=a.format;l.needsUpdate=!0;b&&b(l)},c,d);return l},setPath:function(a){this.path=a}};\nZ.Material=function(){Object.defineProperty(this,\"id\",{value:Z.MaterialIdCount++});this.uuid=Z.Math.generateUUID();this.name=\"\";this.type=\"Material\";this.lights=this.fog=!0;this.blending=Z.NormalBlending;this.side=Z.FrontSide;this.shading=Z.SmoothShading;this.vertexColors=Z.NoColors;this.opacity=1;this.transparent=!1;this.blendSrc=Z.SrcAlphaFactor;this.blendDst=Z.OneMinusSrcAlphaFactor;this.blendEquation=Z.AddEquation;this.blendEquationAlpha=this.blendDstAlpha=this.blendSrcAlpha=null;this.depthFunc=\nZ.LessEqualDepth;this.depthWrite=this.depthTest=!0;this.clippingPlanes=null;this.clipShadows=!1;this.colorWrite=!0;this.precision=null;this.polygonOffset=!1;this.alphaTest=this.polygonOffsetUnits=this.polygonOffsetFactor=0;this.premultipliedAlpha=!1;this.overdraw=0;this._needsUpdate=this.visible=!0};\nZ.Material.prototype={constructor:Z.Material,get needsUpdate(){return this._needsUpdate},set needsUpdate(a){!0===a&&this.update();this._needsUpdate=a},toJSON:function(a){function b(a){var b=[],c;for(c in a){var d=a[c];delete d.metadata;b.push(d)}return b}var c=void 0===a;c&&(a={textures:{},images:{}});var d={metadata:{version:4.4,type:\"Material\",generator:\"Material.toJSON\"}};d.uuid=this.uuid;d.type=this.type;\"\"!==this.name&&(d.name=this.name);this.color instanceof Z.Color&&(d.color=Hf(this.color));\n.5!==this.roughness&&(d.roughness=this.roughness);.5!==this.metalness&&(d.metalness=this.metalness);this.emissive instanceof Z.Color&&(d.emissive=Hf(this.emissive));this.specular instanceof Z.Color&&(d.specular=Hf(this.specular));void 0!==this.shininess&&(d.shininess=this.shininess);this.map instanceof Z.Texture&&(d.map=this.map.toJSON(a).uuid);this.alphaMap instanceof Z.Texture&&(d.alphaMap=this.alphaMap.toJSON(a).uuid);this.lightMap instanceof Z.Texture&&(d.lightMap=this.lightMap.toJSON(a).uuid);\nthis.bumpMap instanceof Z.Texture&&(d.bumpMap=this.bumpMap.toJSON(a).uuid,d.bumpScale=this.bumpScale);this.normalMap instanceof Z.Texture&&(d.normalMap=this.normalMap.toJSON(a).uuid,d.normalScale=this.normalScale.toArray());this.displacementMap instanceof Z.Texture&&(d.displacementMap=this.displacementMap.toJSON(a).uuid,d.displacementScale=this.displacementScale,d.displacementBias=this.displacementBias);this.roughnessMap instanceof Z.Texture&&(d.roughnessMap=this.roughnessMap.toJSON(a).uuid);this.metalnessMap instanceof\nZ.Texture&&(d.metalnessMap=this.metalnessMap.toJSON(a).uuid);this.emissiveMap instanceof Z.Texture&&(d.emissiveMap=this.emissiveMap.toJSON(a).uuid);this.specularMap instanceof Z.Texture&&(d.specularMap=this.specularMap.toJSON(a).uuid);this.envMap instanceof Z.Texture&&(d.envMap=this.envMap.toJSON(a).uuid,d.reflectivity=this.reflectivity);void 0!==this.size&&(d.size=this.size);void 0!==this.sizeAttenuation&&(d.sizeAttenuation=this.sizeAttenuation);this.blending!==Z.NormalBlending&&(d.blending=this.blending);\nthis.shading!==Z.SmoothShading&&(d.shading=this.shading);this.side!==Z.FrontSide&&(d.side=this.side);this.vertexColors!==Z.NoColors&&(d.vertexColors=this.vertexColors);1>this.opacity&&(d.opacity=this.opacity);!0===this.transparent&&(d.transparent=this.transparent);0<this.alphaTest&&(d.alphaTest=this.alphaTest);!0===this.premultipliedAlpha&&(d.premultipliedAlpha=this.premultipliedAlpha);!0===this.wireframe&&(d.wireframe=this.wireframe);1<this.wireframeLinewidth&&(d.wireframeLinewidth=this.wireframeLinewidth);\nc&&(c=b(a.textures),a=b(a.images),0<c.length&&(d.textures=c),0<a.length&&(d.images=a));return d},clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.name=a.name;this.fog=a.fog;this.lights=a.lights;this.blending=a.blending;this.side=a.side;this.vertexColors=a.vertexColors;this.opacity=a.opacity;this.transparent=a.transparent;this.blendSrc=a.blendSrc;this.blendDst=a.blendDst;this.blendEquation=a.blendEquation;this.blendSrcAlpha=a.blendSrcAlpha;this.blendDstAlpha=a.blendDstAlpha;\nthis.blendEquationAlpha=a.blendEquationAlpha;this.depthFunc=a.depthFunc;this.depthTest=a.depthTest;this.depthWrite=a.depthWrite;this.colorWrite=a.colorWrite;this.precision=a.precision;this.polygonOffset=a.polygonOffset;this.polygonOffsetFactor=a.polygonOffsetFactor;this.polygonOffsetUnits=a.polygonOffsetUnits;this.alphaTest=a.alphaTest;this.premultipliedAlpha=a.premultipliedAlpha;this.overdraw=a.overdraw;this.visible=a.visible;this.clipShadows=a.clipShadows;a=a.clippingPlanes;var b=null;if(null!==\na)for(var c=a.length,b=Array(c),d=0;d!==c;++d)b[d]=a[d].clone();this.clippingPlanes=b;return this},update:function(){this.dispatchEvent({type:\"update\"})},dispose:function(){this.dispatchEvent({type:\"dispose\"})}};\nfunction zg(a,b){if(void 0!==b)for(var c in b){var d=b[c];if(void 0===d)console.warn(\"THREE.Material: '\"+c+\"' parameter is undefined.\");else{var e=a[c];void 0===e?console.warn(\"THREE.\"+a.type+\": '\"+c+\"' is not a property of this material.\"):e instanceof Z.Color?e.set(d):e instanceof Z.Vector3&&d instanceof Z.Vector3?e.copy(d):a[c]=\"overdraw\"===c?Number(d):d}}}Object.assign(Z.Material.prototype,Z.EventDispatcher.prototype);Z.MaterialIdCount=0;\nZ.LineBasicMaterial=function(a){Z.Material.call(this);this.type=\"LineBasicMaterial\";this.color=new Z.Color(16777215);this.linewidth=1;this.linejoin=this.linecap=\"round\";this.lights=!1;zg(this,a)};Z.LineBasicMaterial.prototype=Object.create(Z.Material.prototype);Z.LineBasicMaterial.prototype.constructor=Z.LineBasicMaterial;\nZ.LineBasicMaterial.prototype.copy=function(a){Z.Material.prototype.copy.call(this,a);this.color.copy(a.color);this.linewidth=a.linewidth;this.linecap=a.linecap;this.linejoin=a.linejoin;return this};Z.LineDashedMaterial=function(a){Z.Material.call(this);this.type=\"LineDashedMaterial\";this.color=new Z.Color(16777215);this.scale=this.linewidth=1;this.dashSize=3;this.gapSize=1;this.lights=!1;zg(this,a)};Z.LineDashedMaterial.prototype=Object.create(Z.Material.prototype);\nZ.LineDashedMaterial.prototype.constructor=Z.LineDashedMaterial;Z.LineDashedMaterial.prototype.copy=function(a){Z.Material.prototype.copy.call(this,a);this.color.copy(a.color);this.linewidth=a.linewidth;this.scale=a.scale;this.dashSize=a.dashSize;this.gapSize=a.gapSize;return this};\nZ.MeshBasicMaterial=function(a){Z.Material.call(this);this.type=\"MeshBasicMaterial\";this.color=new Z.Color(16777215);this.aoMap=this.map=null;this.aoMapIntensity=1;this.envMap=this.alphaMap=this.specularMap=null;this.combine=Z.MultiplyOperation;this.reflectivity=1;this.refractionRatio=.98;this.wireframe=!1;this.wireframeLinewidth=1;this.wireframeLinejoin=this.wireframeLinecap=\"round\";this.lights=this.morphTargets=this.skinning=!1;zg(this,a)};Z.MeshBasicMaterial.prototype=Object.create(Z.Material.prototype);\nZ.MeshBasicMaterial.prototype.constructor=Z.MeshBasicMaterial;\nZ.MeshBasicMaterial.prototype.copy=function(a){Z.Material.prototype.copy.call(this,a);this.color.copy(a.color);this.map=a.map;this.aoMap=a.aoMap;this.aoMapIntensity=a.aoMapIntensity;this.specularMap=a.specularMap;this.alphaMap=a.alphaMap;this.envMap=a.envMap;this.combine=a.combine;this.reflectivity=a.reflectivity;this.refractionRatio=a.refractionRatio;this.wireframe=a.wireframe;this.wireframeLinewidth=a.wireframeLinewidth;this.wireframeLinecap=a.wireframeLinecap;this.wireframeLinejoin=a.wireframeLinejoin;\nthis.skinning=a.skinning;this.morphTargets=a.morphTargets;return this};Z.MeshDepthMaterial=function(a){Z.Material.call(this);this.type=\"MeshDepthMaterial\";this.depthPacking=Z.BasicDepthPacking;this.morphTargets=this.skinning=!1;this.displacementMap=this.alphaMap=this.map=null;this.displacementScale=1;this.displacementBias=0;this.wireframe=!1;this.wireframeLinewidth=1;this.lights=this.fog=!1;zg(this,a)};Z.MeshDepthMaterial.prototype=Object.create(Z.Material.prototype);\nZ.MeshDepthMaterial.prototype.constructor=Z.MeshDepthMaterial;Z.MeshDepthMaterial.prototype.copy=function(a){Z.Material.prototype.copy.call(this,a);this.depthPacking=a.depthPacking;this.skinning=a.skinning;this.morphTargets=a.morphTargets;this.map=a.map;this.alphaMap=a.alphaMap;this.displacementMap=a.displacementMap;this.displacementScale=a.displacementScale;this.displacementBias=a.displacementBias;this.wireframe=a.wireframe;this.wireframeLinewidth=a.wireframeLinewidth;return this};\nZ.MeshLambertMaterial=function(a){Z.Material.call(this);this.type=\"MeshLambertMaterial\";this.color=new Z.Color(16777215);this.lightMap=this.map=null;this.lightMapIntensity=1;this.aoMap=null;this.aoMapIntensity=1;this.emissive=new Z.Color(0);this.emissiveIntensity=1;this.envMap=this.alphaMap=this.specularMap=this.emissiveMap=null;this.combine=Z.MultiplyOperation;this.reflectivity=1;this.refractionRatio=.98;this.wireframe=!1;this.wireframeLinewidth=1;this.wireframeLinejoin=this.wireframeLinecap=\"round\";\nthis.morphNormals=this.morphTargets=this.skinning=!1;zg(this,a)};Z.MeshLambertMaterial.prototype=Object.create(Z.Material.prototype);Z.MeshLambertMaterial.prototype.constructor=Z.MeshLambertMaterial;\nZ.MeshLambertMaterial.prototype.copy=function(a){Z.Material.prototype.copy.call(this,a);this.color.copy(a.color);this.map=a.map;this.lightMap=a.lightMap;this.lightMapIntensity=a.lightMapIntensity;this.aoMap=a.aoMap;this.aoMapIntensity=a.aoMapIntensity;this.emissive.copy(a.emissive);this.emissiveMap=a.emissiveMap;this.emissiveIntensity=a.emissiveIntensity;this.specularMap=a.specularMap;this.alphaMap=a.alphaMap;this.envMap=a.envMap;this.combine=a.combine;this.reflectivity=a.reflectivity;this.refractionRatio=\na.refractionRatio;this.wireframe=a.wireframe;this.wireframeLinewidth=a.wireframeLinewidth;this.wireframeLinecap=a.wireframeLinecap;this.wireframeLinejoin=a.wireframeLinejoin;this.skinning=a.skinning;this.morphTargets=a.morphTargets;this.morphNormals=a.morphNormals;return this};Z.MeshNormalMaterial=function(a){Z.Material.call(this);this.type=\"MeshNormalMaterial\";this.wireframe=!1;this.wireframeLinewidth=1;this.morphTargets=this.lights=this.fog=!1;zg(this,a)};Z.MeshNormalMaterial.prototype=Object.create(Z.Material.prototype);\nZ.MeshNormalMaterial.prototype.constructor=Z.MeshNormalMaterial;Z.MeshNormalMaterial.prototype.copy=function(a){Z.Material.prototype.copy.call(this,a);this.wireframe=a.wireframe;this.wireframeLinewidth=a.wireframeLinewidth;return this};\nZ.MeshPhongMaterial=function(a){Z.Material.call(this);this.type=\"MeshPhongMaterial\";this.color=new Z.Color(16777215);this.specular=new Z.Color(1118481);this.shininess=30;this.lightMap=this.map=null;this.lightMapIntensity=1;this.aoMap=null;this.aoMapIntensity=1;this.emissive=new Z.Color(0);this.emissiveIntensity=1;this.bumpMap=this.emissiveMap=null;this.bumpScale=1;this.normalMap=null;this.normalScale=new Z.Vector2(1,1);this.displacementMap=null;this.displacementScale=1;this.displacementBias=0;this.envMap=\nthis.alphaMap=this.specularMap=null;this.combine=Z.MultiplyOperation;this.reflectivity=1;this.refractionRatio=.98;this.wireframe=!1;this.wireframeLinewidth=1;this.wireframeLinejoin=this.wireframeLinecap=\"round\";this.morphNormals=this.morphTargets=this.skinning=!1;zg(this,a)};Z.MeshPhongMaterial.prototype=Object.create(Z.Material.prototype);Z.MeshPhongMaterial.prototype.constructor=Z.MeshPhongMaterial;\nZ.MeshPhongMaterial.prototype.copy=function(a){Z.Material.prototype.copy.call(this,a);this.color.copy(a.color);this.specular.copy(a.specular);this.shininess=a.shininess;this.map=a.map;this.lightMap=a.lightMap;this.lightMapIntensity=a.lightMapIntensity;this.aoMap=a.aoMap;this.aoMapIntensity=a.aoMapIntensity;this.emissive.copy(a.emissive);this.emissiveMap=a.emissiveMap;this.emissiveIntensity=a.emissiveIntensity;this.bumpMap=a.bumpMap;this.bumpScale=a.bumpScale;this.normalMap=a.normalMap;this.normalScale.copy(a.normalScale);\nthis.displacementMap=a.displacementMap;this.displacementScale=a.displacementScale;this.displacementBias=a.displacementBias;this.specularMap=a.specularMap;this.alphaMap=a.alphaMap;this.envMap=a.envMap;this.combine=a.combine;this.reflectivity=a.reflectivity;this.refractionRatio=a.refractionRatio;this.wireframe=a.wireframe;this.wireframeLinewidth=a.wireframeLinewidth;this.wireframeLinecap=a.wireframeLinecap;this.wireframeLinejoin=a.wireframeLinejoin;this.skinning=a.skinning;this.morphTargets=a.morphTargets;\nthis.morphNormals=a.morphNormals;return this};\nZ.MeshStandardMaterial=function(a){Z.Material.call(this);this.defines={STANDARD:\"\"};this.type=\"MeshStandardMaterial\";this.color=new Z.Color(16777215);this.metalness=this.roughness=.5;this.lightMap=this.map=null;this.lightMapIntensity=1;this.aoMap=null;this.aoMapIntensity=1;this.emissive=new Z.Color(0);this.emissiveIntensity=1;this.bumpMap=this.emissiveMap=null;this.bumpScale=1;this.normalMap=null;this.normalScale=new Z.Vector2(1,1);this.displacementMap=null;this.displacementScale=1;this.displacementBias=\n0;this.envMap=this.alphaMap=this.metalnessMap=this.roughnessMap=null;this.envMapIntensity=1;this.refractionRatio=.98;this.wireframe=!1;this.wireframeLinewidth=1;this.wireframeLinejoin=this.wireframeLinecap=\"round\";this.morphNormals=this.morphTargets=this.skinning=!1;zg(this,a)};Z.MeshStandardMaterial.prototype=Object.create(Z.Material.prototype);Z.MeshStandardMaterial.prototype.constructor=Z.MeshStandardMaterial;\nZ.MeshStandardMaterial.prototype.copy=function(a){Z.Material.prototype.copy.call(this,a);this.defines={STANDARD:\"\"};this.color.copy(a.color);this.roughness=a.roughness;this.metalness=a.metalness;this.map=a.map;this.lightMap=a.lightMap;this.lightMapIntensity=a.lightMapIntensity;this.aoMap=a.aoMap;this.aoMapIntensity=a.aoMapIntensity;this.emissive.copy(a.emissive);this.emissiveMap=a.emissiveMap;this.emissiveIntensity=a.emissiveIntensity;this.bumpMap=a.bumpMap;this.bumpScale=a.bumpScale;this.normalMap=\na.normalMap;this.normalScale.copy(a.normalScale);this.displacementMap=a.displacementMap;this.displacementScale=a.displacementScale;this.displacementBias=a.displacementBias;this.roughnessMap=a.roughnessMap;this.metalnessMap=a.metalnessMap;this.alphaMap=a.alphaMap;this.envMap=a.envMap;this.envMapIntensity=a.envMapIntensity;this.refractionRatio=a.refractionRatio;this.wireframe=a.wireframe;this.wireframeLinewidth=a.wireframeLinewidth;this.wireframeLinecap=a.wireframeLinecap;this.wireframeLinejoin=a.wireframeLinejoin;\nthis.skinning=a.skinning;this.morphTargets=a.morphTargets;this.morphNormals=a.morphNormals;return this};Z.MeshPhysicalMaterial=function(a){Z.MeshStandardMaterial.call(this);this.defines={PHYSICAL:\"\"};this.type=\"MeshPhysicalMaterial\";this.reflectivity=.5;zg(this,a)};Z.MeshPhysicalMaterial.prototype=Object.create(Z.MeshStandardMaterial.prototype);Z.MeshPhysicalMaterial.prototype.constructor=Z.MeshPhysicalMaterial;\nZ.MeshPhysicalMaterial.prototype.copy=function(a){Z.MeshStandardMaterial.prototype.copy.call(this,a);this.defines={PHYSICAL:\"\"};this.reflectivity=a.reflectivity;return this};Z.MultiMaterial=function(a){this.uuid=Z.Math.generateUUID();this.type=\"MultiMaterial\";this.materials=a instanceof Array?a:[];this.visible=!0};\nZ.MultiMaterial.prototype={constructor:Z.MultiMaterial,toJSON:function(a){for(var b={metadata:{version:4.2,type:\"material\",generator:\"MaterialExporter\"},uuid:this.uuid,type:this.type,materials:[]},c=this.materials,d=0,e=c.length;d<e;d++){var f=c[d].toJSON(a);delete f.metadata;b.materials.push(f)}b.visible=this.visible;return b},clone:function(){for(var a=new this.constructor,b=0;b<this.materials.length;b++)a.materials.push(this.materials[b].clone());a.visible=this.visible;return a}};\nZ.PointsMaterial=function(a){Z.Material.call(this);this.type=\"PointsMaterial\";this.color=new Z.Color(16777215);this.map=null;this.size=1;this.sizeAttenuation=!0;this.lights=!1;zg(this,a)};Z.PointsMaterial.prototype=Object.create(Z.Material.prototype);Z.PointsMaterial.prototype.constructor=Z.PointsMaterial;Z.PointsMaterial.prototype.copy=function(a){Z.Material.prototype.copy.call(this,a);this.color.copy(a.color);this.map=a.map;this.size=a.size;this.sizeAttenuation=a.sizeAttenuation;return this};\nZ.ShaderMaterial=function(a){Z.Material.call(this);this.type=\"ShaderMaterial\";this.defines={};this.uniforms={};this.vertexShader=\"void main() {\\n\\tgl_Position \\x3d projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\\n}\";this.fragmentShader=\"void main() {\\n\\tgl_FragColor \\x3d vec4( 1.0, 0.0, 0.0, 1.0 );\\n}\";this.linewidth=1;this.wireframe=!1;this.wireframeLinewidth=1;this.morphNormals=this.morphTargets=this.skinning=this.clipping=this.lights=this.fog=!1;this.extensions={derivatives:!1,fragDepth:!1,\ndrawBuffers:!1,shaderTextureLOD:!1};this.defaultAttributeValues={color:[1,1,1],uv:[0,0],uv2:[0,0]};this.index0AttributeName=void 0;void 0!==a&&(void 0!==a.attributes&&console.error(\"THREE.ShaderMaterial: attributes should now be defined in THREE.BufferGeometry instead.\"),zg(this,a))};Z.ShaderMaterial.prototype=Object.create(Z.Material.prototype);Z.ShaderMaterial.prototype.constructor=Z.ShaderMaterial;\nZ.ShaderMaterial.prototype.copy=function(a){Z.Material.prototype.copy.call(this,a);this.fragmentShader=a.fragmentShader;this.vertexShader=a.vertexShader;this.uniforms=Z.UniformsUtils.clone(a.uniforms);this.defines=a.defines;this.wireframe=a.wireframe;this.wireframeLinewidth=a.wireframeLinewidth;this.lights=a.lights;this.clipping=a.clipping;this.skinning=a.skinning;this.morphTargets=a.morphTargets;this.morphNormals=a.morphNormals;this.extensions=a.extensions;return this};\nZ.ShaderMaterial.prototype.toJSON=function(a){a=Z.Material.prototype.toJSON.call(this,a);a.uniforms=this.uniforms;a.vertexShader=this.vertexShader;a.fragmentShader=this.fragmentShader;return a};Z.RawShaderMaterial=function(a){Z.ShaderMaterial.call(this,a);this.type=\"RawShaderMaterial\"};Z.RawShaderMaterial.prototype=Object.create(Z.ShaderMaterial.prototype);Z.RawShaderMaterial.prototype.constructor=Z.RawShaderMaterial;\nZ.SpriteMaterial=function(a){Z.Material.call(this);this.type=\"SpriteMaterial\";this.color=new Z.Color(16777215);this.map=null;this.rotation=0;this.lights=this.fog=!1;zg(this,a)};Z.SpriteMaterial.prototype=Object.create(Z.Material.prototype);Z.SpriteMaterial.prototype.constructor=Z.SpriteMaterial;Z.SpriteMaterial.prototype.copy=function(a){Z.Material.prototype.copy.call(this,a);this.color.copy(a.color);this.map=a.map;this.rotation=a.rotation;return this};\nZ.ShadowMaterial=function(){Z.ShaderMaterial.call(this,{uniforms:Z.UniformsUtils.merge([Z.UniformsLib.lights,{opacity:{value:1}}]),vertexShader:Z.ShaderChunk.shadow_vert,fragmentShader:Z.ShaderChunk.shadow_frag});this.transparent=this.lights=!0;Object.defineProperties(this,{opacity:{enumerable:!0,get:function(){return this.uniforms.opacity.value},set:function(a){this.uniforms.opacity.value=a}}})};Z.ShadowMaterial.prototype=Object.create(Z.ShaderMaterial.prototype);\nZ.ShadowMaterial.prototype.constructor=Z.ShadowMaterial;\nZ.Texture=function(a,b,c,d,e,f,g,k,l,m){Object.defineProperty(this,\"id\",{value:Z.TextureIdCount++});this.uuid=Z.Math.generateUUID();this.sourceFile=this.name=\"\";this.image=void 0!==a?a:Z.Texture.DEFAULT_IMAGE;this.mipmaps=[];this.mapping=void 0!==b?b:Z.Texture.DEFAULT_MAPPING;this.wrapS=void 0!==c?c:Z.ClampToEdgeWrapping;this.wrapT=void 0!==d?d:Z.ClampToEdgeWrapping;this.magFilter=void 0!==e?e:Z.LinearFilter;this.minFilter=void 0!==f?f:Z.LinearMipMapLinearFilter;this.anisotropy=void 0!==l?l:1;this.format=\nvoid 0!==g?g:Z.RGBAFormat;this.type=void 0!==k?k:Z.UnsignedByteType;this.offset=new Z.Vector2(0,0);this.repeat=new Z.Vector2(1,1);this.generateMipmaps=!0;this.premultiplyAlpha=!1;this.flipY=!0;this.unpackAlignment=4;this.encoding=void 0!==m?m:Z.LinearEncoding;this.version=0;this.onUpdate=null};Z.Texture.DEFAULT_IMAGE=void 0;Z.Texture.DEFAULT_MAPPING=Z.UVMapping;\nZ.Texture.prototype={constructor:Z.Texture,set needsUpdate(a){!0===a&&this.version++},clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.image=a.image;this.mipmaps=a.mipmaps.slice(0);this.mapping=a.mapping;this.wrapS=a.wrapS;this.wrapT=a.wrapT;this.magFilter=a.magFilter;this.minFilter=a.minFilter;this.anisotropy=a.anisotropy;this.format=a.format;this.type=a.type;this.offset.copy(a.offset);this.repeat.copy(a.repeat);this.generateMipmaps=a.generateMipmaps;this.premultiplyAlpha=\na.premultiplyAlpha;this.flipY=a.flipY;this.unpackAlignment=a.unpackAlignment;this.encoding=a.encoding;return this},toJSON:function(a){if(void 0!==a.textures[this.uuid])return a.textures[this.uuid];var b={metadata:{version:4.4,type:\"Texture\",generator:\"Texture.toJSON\"},uuid:this.uuid,name:this.name,mapping:this.mapping,repeat:[this.repeat.x,this.repeat.y],offset:[this.offset.x,this.offset.y],wrap:[this.wrapS,this.wrapT],minFilter:this.minFilter,magFilter:this.magFilter,anisotropy:this.anisotropy};\nif(void 0!==this.image){var c=this.image;void 0===c.uuid&&(c.uuid=Z.Math.generateUUID());if(void 0===a.images[c.uuid]){var d=a.images,e=c.uuid,f=c.uuid;if(void 0!==c.toDataURL)var g=c;else g=document.createElement(\"canvas\"),g.width=c.width,g.height=c.height,g.getContext(\"2d\").drawImage(c,0,0,c.width,c.height);g=2048<g.width||2048<g.height?g.toDataURL(\"image/jpeg\",.6):g.toDataURL(\"image/png\");d[e]={uuid:f,url:g}}b.image=c.uuid}return a.textures[this.uuid]=b},dispose:function(){this.dispatchEvent({type:\"dispose\"})},\ntransformUv:function(a){if(this.mapping===Z.UVMapping){a.multiply(this.repeat);a.add(this.offset);if(0>a.x||1<a.x)switch(this.wrapS){case Z.RepeatWrapping:a.x-=Math.floor(a.x);break;case Z.ClampToEdgeWrapping:a.x=0>a.x?0:1;break;case Z.MirroredRepeatWrapping:a.x=1===Math.abs(Math.floor(a.x)%2)?Math.ceil(a.x)-a.x:a.x-Math.floor(a.x)}if(0>a.y||1<a.y)switch(this.wrapT){case Z.RepeatWrapping:a.y-=Math.floor(a.y);break;case Z.ClampToEdgeWrapping:a.y=0>a.y?0:1;break;case Z.MirroredRepeatWrapping:a.y=1===\nMath.abs(Math.floor(a.y)%2)?Math.ceil(a.y)-a.y:a.y-Math.floor(a.y)}this.flipY&&(a.y=1-a.y)}}};Object.assign(Z.Texture.prototype,Z.EventDispatcher.prototype);Z.TextureIdCount=0;Z.DepthTexture=function(a,b,c,d,e,f,g,k,l){Z.Texture.call(this,null,d,e,f,g,k,Z.DepthFormat,c,l);this.image={width:a,height:b};this.type=void 0!==c?c:Z.UnsignedShortType;this.magFilter=void 0!==g?g:Z.NearestFilter;this.minFilter=void 0!==k?k:Z.NearestFilter;this.generateMipmaps=this.flipY=!1};Z.DepthTexture.prototype=Object.create(Z.Texture.prototype);\nZ.DepthTexture.prototype.constructor=Z.DepthTexture;Z.CanvasTexture=function(a,b,c,d,e,f,g,k,l){Z.Texture.call(this,a,b,c,d,e,f,g,k,l);this.needsUpdate=!0};Z.CanvasTexture.prototype=Object.create(Z.Texture.prototype);Z.CanvasTexture.prototype.constructor=Z.CanvasTexture;Z.CubeTexture=function(a,b,c,d,e,f,g,k,l,m){a=void 0!==a?a:[];b=void 0!==b?b:Z.CubeReflectionMapping;Z.Texture.call(this,a,b,c,d,e,f,g,k,l,m);this.flipY=!1};Z.CubeTexture.prototype=Object.create(Z.Texture.prototype);\nZ.CubeTexture.prototype.constructor=Z.CubeTexture;Object.defineProperty(Z.CubeTexture.prototype,\"images\",{get:function(){return this.image},set:function(a){this.image=a}});Z.CompressedTexture=function(a,b,c,d,e,f,g,k,l,m,n,q){Z.Texture.call(this,null,f,g,k,l,m,d,e,n,q);this.image={width:b,height:c};this.mipmaps=a;this.generateMipmaps=this.flipY=!1};Z.CompressedTexture.prototype=Object.create(Z.Texture.prototype);Z.CompressedTexture.prototype.constructor=Z.CompressedTexture;\nZ.DataTexture=function(a,b,c,d,e,f,g,k,l,m,n,q){Z.Texture.call(this,null,f,g,k,l,m,d,e,n,q);this.image={data:a,width:b,height:c};this.magFilter=void 0!==l?l:Z.NearestFilter;this.minFilter=void 0!==m?m:Z.NearestFilter;this.generateMipmaps=this.flipY=!1};Z.DataTexture.prototype=Object.create(Z.Texture.prototype);Z.DataTexture.prototype.constructor=Z.DataTexture;\nZ.VideoTexture=function(a,b,c,d,e,f,g,k,l){function m(){requestAnimationFrame(m);a.readyState>=a.HAVE_CURRENT_DATA&&(n.needsUpdate=!0)}Z.Texture.call(this,a,b,c,d,e,f,g,k,l);this.generateMipmaps=!1;var n=this;m()};Z.VideoTexture.prototype=Object.create(Z.Texture.prototype);Z.VideoTexture.prototype.constructor=Z.VideoTexture;Z.Group=function(){Z.Object3D.call(this);this.type=\"Group\"};Z.Group.prototype=Object.assign(Object.create(Z.Object3D.prototype),{constructor:Z.Group});\nZ.Points=function(a,b){Z.Object3D.call(this);this.type=\"Points\";this.geometry=void 0!==a?a:new Z.BufferGeometry;this.material=void 0!==b?b:new Z.PointsMaterial({color:16777215*Math.random()})};\nZ.Points.prototype=Object.assign(Object.create(Z.Object3D.prototype),{constructor:Z.Points,raycast:function(){var a=new Z.Matrix4,b=new Z.Ray,c=new Z.Sphere;return function(d,e){function f(a,c){var f=b.distanceSqToPoint(a);if(f<n){a=b.closestPointToPoint(a);a.applyMatrix4(l);var k=d.ray.origin.distanceTo(a);k<d.near||k>d.far||e.push({distance:k,distanceToRay:Math.sqrt(f),point:a.clone(),index:c,face:null,object:g})}}var g=this,k=this.geometry,l=this.matrixWorld,m=d.params.Points.threshold;null===\nk.boundingSphere&&k.computeBoundingSphere();c.copy(k.boundingSphere);c.applyMatrix4(l);if(!1!==d.ray.intersectsSphere(c)){a.getInverse(l);b.copy(d.ray).applyMatrix4(a);var m=m/((this.scale.x+this.scale.y+this.scale.z)/3),n=m*m,m=new Z.Vector3;if(k instanceof Z.BufferGeometry){var q=k.index,k=k.attributes.position.array;if(null!==q)for(var p=q.array,q=0,t=p.length;q<t;q++){var r=p[q];m.fromArray(k,3*r);f(m,r)}else for(q=0,p=k.length/3;q<p;q++)m.fromArray(k,3*q),f(m,q)}else for(m=k.vertices,q=0,p=m.length;q<\np;q++)f(m[q],q)}}}(),clone:function(){return(new this.constructor(this.geometry,this.material)).copy(this)}});Z.Line=function(a,b,c){if(1===c)return console.warn(\"THREE.Line: parameter THREE.LinePieces no longer supported. Created THREE.LineSegments instead.\"),new Z.LineSegments(a,b);Z.Object3D.call(this);this.type=\"Line\";this.geometry=void 0!==a?a:new Z.BufferGeometry;this.material=void 0!==b?b:new Z.LineBasicMaterial({color:16777215*Math.random()})};\nZ.Line.prototype=Object.assign(Object.create(Z.Object3D.prototype),{constructor:Z.Line,raycast:function(){var a=new Z.Matrix4,b=new Z.Ray,c=new Z.Sphere;return function(d,e){var f=d.linePrecision,f=f*f,g=this.geometry,k=this.matrixWorld;null===g.boundingSphere&&g.computeBoundingSphere();c.copy(g.boundingSphere);c.applyMatrix4(k);if(!1!==d.ray.intersectsSphere(c)){a.getInverse(k);b.copy(d.ray).applyMatrix4(a);var l=new Z.Vector3;var m=new Z.Vector3,k=new Z.Vector3,n=new Z.Vector3,q=this instanceof\nZ.LineSegments?2:1;if(g instanceof Z.BufferGeometry){var p=g.index;var t=g.attributes.position.array;if(null!==p)for(var r=p.array,g=0,v=r.length-1;g<v;g+=q)p=r[g+1],l.fromArray(t,3*r[g]),m.fromArray(t,3*p),p=b.distanceSqToSegment(l,m,n,k),p>f||(n.applyMatrix4(this.matrixWorld),p=d.ray.origin.distanceTo(n),p<d.near||p>d.far||e.push({distance:p,point:k.clone().applyMatrix4(this.matrixWorld),index:g,face:null,faceIndex:null,object:this}));else for(g=0,v=t.length/3-1;g<v;g+=q)l.fromArray(t,3*g),m.fromArray(t,\n3*g+3),p=b.distanceSqToSegment(l,m,n,k),p>f||(n.applyMatrix4(this.matrixWorld),p=d.ray.origin.distanceTo(n),p<d.near||p>d.far||e.push({distance:p,point:k.clone().applyMatrix4(this.matrixWorld),index:g,face:null,faceIndex:null,object:this}))}else if(g instanceof Z.Geometry)for(l=g.vertices,m=l.length,g=0;g<m-1;g+=q)p=b.distanceSqToSegment(l[g],l[g+1],n,k),p>f||(n.applyMatrix4(this.matrixWorld),p=d.ray.origin.distanceTo(n),p<d.near||p>d.far||e.push({distance:p,point:k.clone().applyMatrix4(this.matrixWorld),\nindex:g,face:null,faceIndex:null,object:this}))}}}(),clone:function(){return(new this.constructor(this.geometry,this.material)).copy(this)}});Z.LineSegments=function(a,b){Z.Line.call(this,a,b);this.type=\"LineSegments\"};Z.LineSegments.prototype=Object.assign(Object.create(Z.Line.prototype),{constructor:Z.LineSegments});\nZ.Mesh=function(a,b){Z.Object3D.call(this);this.type=\"Mesh\";this.geometry=void 0!==a?a:new Z.BufferGeometry;this.material=void 0!==b?b:new Z.MeshBasicMaterial({color:16777215*Math.random()});this.drawMode=Z.TrianglesDrawMode;this.updateMorphTargets()};\nZ.Mesh.prototype=Object.assign(Object.create(Z.Object3D.prototype),{constructor:Z.Mesh,setDrawMode:function(a){this.drawMode=a},updateMorphTargets:function(){if(void 0!==this.geometry.morphTargets&&0<this.geometry.morphTargets.length){this.morphTargetBase=-1;this.morphTargetInfluences=[];this.morphTargetDictionary={};for(var a=0,b=this.geometry.morphTargets.length;a<b;a++)this.morphTargetInfluences.push(0),this.morphTargetDictionary[this.geometry.morphTargets[a].name]=a}},getMorphTargetIndexByName:function(a){if(void 0!==\nthis.morphTargetDictionary[a])return this.morphTargetDictionary[a];console.warn(\"THREE.Mesh.getMorphTargetIndexByName: morph target \"+a+\" does not exist. Returning 0.\");return 0},raycast:function(){function a(a,b,c,d,e,f,g){Z.Triangle.barycoordFromPoint(a,b,c,d,v);e.multiplyScalar(v.x);f.multiplyScalar(v.y);g.multiplyScalar(v.z);e.add(f).add(g);return e.clone()}function b(a,b,c,d,e,f,g){var k=a.material;if(null===(k.side===Z.BackSide?c.intersectTriangle(f,e,d,!0,g):c.intersectTriangle(d,e,f,k.side!==\nZ.DoubleSide,g)))return null;z.copy(g);z.applyMatrix4(a.matrixWorld);c=b.ray.origin.distanceTo(z);return c<b.near||c>b.far?null:{distance:c,point:z.clone(),object:a}}function c(c,d,e,f,m,n,q,v){g.fromArray(f,3*n);k.fromArray(f,3*q);l.fromArray(f,3*v);if(c=b(c,d,e,g,k,l,w))m&&(p.fromArray(m,2*n),t.fromArray(m,2*q),r.fromArray(m,2*v),c.uv=a(w,g,k,l,p,t,r)),c.face=new Z.Face3(n,q,v,Z.Triangle.normal(g,k,l)),c.faceIndex=n;return c}var d=new Z.Matrix4,e=new Z.Ray,f=new Z.Sphere,g=new Z.Vector3,k=new Z.Vector3,\nl=new Z.Vector3,m=new Z.Vector3,n=new Z.Vector3,q=new Z.Vector3,p=new Z.Vector2,t=new Z.Vector2,r=new Z.Vector2,v=new Z.Vector3,w=new Z.Vector3,z=new Z.Vector3;return function(v,z){var y=this.geometry,B=this.material,E=this.matrixWorld;if(void 0!==B&&(null===y.boundingSphere&&y.computeBoundingSphere(),f.copy(y.boundingSphere),f.applyMatrix4(E),!1!==v.ray.intersectsSphere(f)&&(d.getInverse(E),e.copy(v.ray).applyMatrix4(d),null===y.boundingBox||!1!==e.intersectsBox(y.boundingBox)))){var F;if(y instanceof\nZ.BufferGeometry){var B=y.index,E=y.attributes,y=E.position.array;if(void 0!==E.uv)var I=E.uv.array;if(null!==B)for(var E=B.array,H=0,C=E.length;H<C;H+=3){B=E[H];var J=E[H+1];var M=E[H+2];if(F=c(this,v,e,y,I,B,J,M))F.faceIndex=Math.floor(H/3),z.push(F)}else for(H=0,C=y.length;H<C;H+=9)if(B=H/3,J=B+1,M=B+2,F=c(this,v,e,y,I,B,J,M))F.index=B,z.push(F)}else if(y instanceof Z.Geometry){var E=B instanceof Z.MultiMaterial,H=!0===E?B.materials:null,C=y.vertices;J=y.faces;M=y.faceVertexUvs[0];0<M.length&&\n(I=M);for(var T=0,U=J.length;T<U;T++){var L=J[T];F=!0===E?H[L.materialIndex]:B;if(void 0!==F){M=C[L.a];var S=C[L.b];var R=C[L.c];if(!0===F.morphTargets){F=y.morphTargets;var K=this.morphTargetInfluences;g.set(0,0,0);k.set(0,0,0);l.set(0,0,0);for(var N=0,Q=F.length;N<Q;N++){var la=K[N];if(0!==la){var sa=F[N].vertices;g.addScaledVector(m.subVectors(sa[L.a],M),la);k.addScaledVector(n.subVectors(sa[L.b],S),la);l.addScaledVector(q.subVectors(sa[L.c],R),la)}}g.add(M);k.add(S);l.add(R);M=g;S=k;R=l}if(F=\nb(this,v,e,M,S,R,w))I&&(K=I[T],p.copy(K[0]),t.copy(K[1]),r.copy(K[2]),F.uv=a(w,M,S,R,p,t,r)),F.face=L,F.faceIndex=T,z.push(F)}}}}}}(),clone:function(){return(new this.constructor(this.geometry,this.material)).copy(this)}});Z.Bone=function(a){Z.Object3D.call(this);this.type=\"Bone\";this.skin=a};Z.Bone.prototype=Object.assign(Object.create(Z.Object3D.prototype),{constructor:Z.Bone,copy:function(a){Z.Object3D.prototype.copy.call(this,a);this.skin=a.skin;return this}});\nZ.Skeleton=function(a,b,c){this.useVertexTexture=void 0!==c?c:!0;this.identityMatrix=new Z.Matrix4;a=a||[];this.bones=a.slice(0);this.useVertexTexture?(a=Math.sqrt(4*this.bones.length),a=Z.Math.nextPowerOfTwo(Math.ceil(a)),this.boneTextureHeight=this.boneTextureWidth=a=Math.max(a,4),this.boneMatrices=new Float32Array(this.boneTextureWidth*this.boneTextureHeight*4),this.boneTexture=new Z.DataTexture(this.boneMatrices,this.boneTextureWidth,this.boneTextureHeight,Z.RGBAFormat,Z.FloatType)):this.boneMatrices=\nnew Float32Array(16*this.bones.length);if(void 0===b)this.calculateInverses();else if(this.bones.length===b.length)this.boneInverses=b.slice(0);else for(console.warn(\"THREE.Skeleton bonInverses is the wrong length.\"),this.boneInverses=[],b=0,a=this.bones.length;b<a;b++)this.boneInverses.push(new Z.Matrix4)};\nObject.assign(Z.Skeleton.prototype,{calculateInverses:function(){this.boneInverses=[];for(var a=0,b=this.bones.length;a<b;a++){var c=new Z.Matrix4;this.bones[a]&&c.getInverse(this.bones[a].matrixWorld);this.boneInverses.push(c)}},pose:function(){for(var a,b=0,c=this.bones.length;b<c;b++)(a=this.bones[b])&&a.matrixWorld.getInverse(this.boneInverses[b]);b=0;for(c=this.bones.length;b<c;b++)if(a=this.bones[b])a.parent?(a.matrix.getInverse(a.parent.matrixWorld),a.matrix.multiply(a.matrixWorld)):a.matrix.copy(a.matrixWorld),\na.matrix.decompose(a.position,a.quaternion,a.scale)},update:function(){var a=new Z.Matrix4;return function(){for(var b=0,c=this.bones.length;b<c;b++)Nf(a,this.bones[b]?this.bones[b].matrixWorld:this.identityMatrix,this.boneInverses[b]),a.toArray(this.boneMatrices,16*b);this.useVertexTexture&&(this.boneTexture.needsUpdate=!0)}}(),clone:function(){return new Z.Skeleton(this.bones,this.boneInverses,this.useVertexTexture)}});\nZ.SkinnedMesh=function(a,b,c){Z.Mesh.call(this,a,b);this.type=\"SkinnedMesh\";this.bindMode=\"attached\";this.bindMatrix=new Z.Matrix4;this.bindMatrixInverse=new Z.Matrix4;a=[];if(this.geometry&&void 0!==this.geometry.bones){for(var d,e=0,f=this.geometry.bones.length;e<f;++e)d=this.geometry.bones[e],b=new Z.Bone(this),a.push(b),b.name=d.name,b.position.fromArray(d.pos),b.quaternion.fromArray(d.rotq),void 0!==d.scl&&b.scale.fromArray(d.scl);e=0;for(f=this.geometry.bones.length;e<f;++e)d=this.geometry.bones[e],\n-1!==d.parent&&null!==d.parent&&void 0!==a[d.parent]?a[d.parent].add(a[e]):this.add(a[e])}this.normalizeSkinWeights();this.updateMatrixWorld(!0);this.bind(new Z.Skeleton(a,void 0,c),this.matrixWorld)};\nZ.SkinnedMesh.prototype=Object.assign(Object.create(Z.Mesh.prototype),{constructor:Z.SkinnedMesh,bind:function(a,b){this.skeleton=a;void 0===b&&(this.updateMatrixWorld(!0),this.skeleton.calculateInverses(),b=this.matrixWorld);this.bindMatrix.copy(b);this.bindMatrixInverse.getInverse(b)},pose:function(){this.skeleton.pose()},normalizeSkinWeights:function(){if(this.geometry instanceof Z.Geometry)for(var a=0;a<this.geometry.skinWeights.length;a++){var b=this.geometry.skinWeights[a];var c=1/b.lengthManhattan();\nInfinity!==c?b.multiplyScalar(c):b.set(1,0,0,0)}else if(this.geometry instanceof Z.BufferGeometry){b=new Z.Vector4;for(var d=this.geometry.attributes.skinWeight,a=0;a<d.count;a++)b.x=d.getX(a),b.y=d.getY(a),b.z=d.getZ(a),b.w=d.getW(a),c=1/b.lengthManhattan(),Infinity!==c?b.multiplyScalar(c):b.set(1,0,0,0),d.setXYZW(a,b.x,b.y,b.z,b.w)}},updateMatrixWorld:function(){Z.Mesh.prototype.updateMatrixWorld.call(this,!0);\"attached\"===this.bindMode?this.bindMatrixInverse.getInverse(this.matrixWorld):\"detached\"===\nthis.bindMode?this.bindMatrixInverse.getInverse(this.bindMatrix):console.warn(\"THREE.SkinnedMesh unrecognized bindMode: \"+this.bindMode)},clone:function(){return(new this.constructor(this.geometry,this.material,this.useVertexTexture)).copy(this)}});Z.LOD=function(){Z.Object3D.call(this);this.type=\"LOD\";Object.defineProperties(this,{levels:{enumerable:!0,value:[]}})};\nZ.LOD.prototype=Object.assign(Object.create(Z.Object3D.prototype),{constructor:Z.LOD,copy:function(a){Z.Object3D.prototype.copy.call(this,a,!1);a=a.levels;for(var b=0,c=a.length;b<c;b++){var d=a[b];this.addLevel(d.object.clone(),d.distance)}return this},addLevel:function(a,b){void 0===b&&(b=0);b=Math.abs(b);for(var c=this.levels,d=0;d<c.length&&!(b<c[d].distance);d++);c.splice(d,0,{distance:b,object:a});this.add(a)},getObjectForDistance:function(a){for(var b=this.levels,c=1,d=b.length;c<d&&!(a<b[c].distance);c++);\nreturn b[c-1].object},raycast:function(){var a=new Z.Vector3;return function(b,c){Qf(a,this.matrixWorld);this.getObjectForDistance(b.ray.origin.distanceTo(a)).raycast(b,c)}}(),update:function(){var a=new Z.Vector3,b=new Z.Vector3;return function(c){var d=this.levels;if(1<d.length){Qf(a,c.matrixWorld);Qf(b,this.matrixWorld);c=a.distanceTo(b);d[0].object.visible=!0;for(var e=1,f=d.length;e<f;e++)if(c>=d[e].distance)d[e-1].object.visible=!1,d[e].object.visible=!0;else break;for(;e<f;e++)d[e].object.visible=\n!1}}}(),toJSON:function(a){a=Z.Object3D.prototype.toJSON.call(this,a);a.object.levels=[];for(var b=this.levels,c=0,d=b.length;c<d;c++){var e=b[c];a.object.levels.push({object:e.object.uuid,distance:e.distance})}return a}});Z.Sprite=function(a){Z.Object3D.call(this);this.type=\"Sprite\";this.material=void 0!==a?a:new Z.SpriteMaterial};\nZ.Sprite.prototype=Object.assign(Object.create(Z.Object3D.prototype),{constructor:Z.Sprite,raycast:function(){var a=new Z.Vector3;return function(b,c){Qf(a,this.matrixWorld);b=b.ray.distanceSqToPoint(a);b>this.scale.x*this.scale.y/4||c.push({distance:Math.sqrt(b),point:this.position,face:null,object:this})}}(),clone:function(){return(new this.constructor(this.material)).copy(this)}});\nZ.LensFlare=function(a,b,c,d,e){Z.Object3D.call(this);this.lensFlares=[];this.positionScreen=new Z.Vector3;this.customUpdateCallback=void 0;void 0!==a&&this.add(a,b,c,d,e)};\nZ.LensFlare.prototype=Object.assign(Object.create(Z.Object3D.prototype),{constructor:Z.LensFlare,copy:function(a){Z.Object3D.prototype.copy.call(this,a);this.positionScreen.copy(a.positionScreen);this.customUpdateCallback=a.customUpdateCallback;for(var b=0,c=a.lensFlares.length;b<c;b++)this.lensFlares.push(a.lensFlares[b]);return this},add:function(a,b,c,d,e,f){void 0===b&&(b=-1);void 0===c&&(c=0);void 0===f&&(f=1);void 0===e&&(e=new Z.Color(16777215));void 0===d&&(d=Z.NormalBlending);c=Math.min(c,\nMath.max(0,c));this.lensFlares.push({texture:a,size:b,distance:c,x:0,y:0,z:0,scale:1,rotation:0,opacity:f,color:e,blending:d})},updateLensFlares:function(){var a,b=this.lensFlares.length,c=2*-this.positionScreen.x,d=2*-this.positionScreen.y;for(a=0;a<b;a++){var e=this.lensFlares[a];e.x=this.positionScreen.x+c*e.distance;e.y=this.positionScreen.y+d*e.distance;e.wantedRotation=e.x*Math.PI*.25;e.rotation+=.25*(e.wantedRotation-e.rotation)}}});\nZ.Scene=function(){Z.Object3D.call(this);this.type=\"Scene\";this.overrideMaterial=this.fog=null;this.autoUpdate=!0};Z.Scene.prototype=Object.create(Z.Object3D.prototype);Z.Scene.prototype.constructor=Z.Scene;Z.Scene.prototype.copy=function(a,b){Z.Object3D.prototype.copy.call(this,a,b);null!==a.fog&&(this.fog=a.fog.clone());null!==a.overrideMaterial&&(this.overrideMaterial=a.overrideMaterial.clone());this.autoUpdate=a.autoUpdate;this.matrixAutoUpdate=a.matrixAutoUpdate;return this};\nZ.Fog=function(a,b,c){this.name=\"\";this.color=new Z.Color(a);this.near=void 0!==b?b:1;this.far=void 0!==c?c:1E3};Z.Fog.prototype.clone=function(){return new Z.Fog(Hf(this.color),this.near,this.far)};Z.FogExp2=function(a,b){this.name=\"\";this.color=new Z.Color(a);this.density=void 0!==b?b:2.5E-4};Z.FogExp2.prototype.clone=function(){return new Z.FogExp2(Hf(this.color),this.density)};Z.ShaderChunk={};Z.ShaderChunk.alphamap_fragment=\"#ifdef USE_ALPHAMAP\\n\\tdiffuseColor.a *\\x3d texture2D( alphaMap, vUv ).g;\\n#endif\\n\";\nZ.ShaderChunk.alphamap_pars_fragment=\"#ifdef USE_ALPHAMAP\\n\\tuniform sampler2D alphaMap;\\n#endif\\n\";Z.ShaderChunk.alphatest_fragment=\"#ifdef ALPHATEST\\n\\tif ( diffuseColor.a \\x3c ALPHATEST ) discard;\\n#endif\\n\";Z.ShaderChunk.aomap_fragment=\"#ifdef USE_AOMAP\\n\\tfloat ambientOcclusion \\x3d ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0;\\n\\treflectedLight.indirectDiffuse *\\x3d ambientOcclusion;\\n\\t#if defined( USE_ENVMAP ) \\x26\\x26 defined( PHYSICAL )\\n\\t\\tfloat dotNV \\x3d saturate( dot( geometry.normal, geometry.viewDir ) );\\n\\t\\treflectedLight.indirectSpecular *\\x3d computeSpecularOcclusion( dotNV, ambientOcclusion, material.specularRoughness );\\n\\t#endif\\n#endif\\n\";\nZ.ShaderChunk.aomap_pars_fragment=\"#ifdef USE_AOMAP\\n\\tuniform sampler2D aoMap;\\n\\tuniform float aoMapIntensity;\\n#endif\";Z.ShaderChunk.begin_vertex=\"\\nvec3 transformed \\x3d vec3( position );\\n\";Z.ShaderChunk.beginnormal_vertex=\"\\nvec3 objectNormal \\x3d vec3( normal );\\n\";Z.ShaderChunk.bsdfs=\"bool testLightInRange( const in float lightDistance, const in float cutoffDistance ) {\\n\\treturn any( bvec2( cutoffDistance \\x3d\\x3d 0.0, lightDistance \\x3c cutoffDistance ) );\\n}\\nfloat punctualLightIntensityToIrradianceFactor( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\\n\\t\\tif( decayExponent \\x3e 0.0 ) {\\n#if defined ( PHYSICALLY_CORRECT_LIGHTS )\\n\\t\\t\\tfloat distanceFalloff \\x3d 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\\n\\t\\t\\tfloat maxDistanceCutoffFactor \\x3d pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\\n\\t\\t\\treturn distanceFalloff * maxDistanceCutoffFactor;\\n#else\\n\\t\\t\\treturn pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent );\\n#endif\\n\\t\\t}\\n\\t\\treturn 1.0;\\n}\\nvec3 BRDF_Diffuse_Lambert( const in vec3 diffuseColor ) {\\n\\treturn RECIPROCAL_PI * diffuseColor;\\n}\\nvec3 F_Schlick( const in vec3 specularColor, const in float dotLH ) {\\n\\tfloat fresnel \\x3d exp2( ( -5.55473 * dotLH - 6.98316 ) * dotLH );\\n\\treturn ( 1.0 - specularColor ) * fresnel + specularColor;\\n}\\nfloat G_GGX_Smith( const in float alpha, const in float dotNL, const in float dotNV ) {\\n\\tfloat a2 \\x3d pow2( alpha );\\n\\tfloat gl \\x3d dotNL + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\\n\\tfloat gv \\x3d dotNV + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\\n\\treturn 1.0 / ( gl * gv );\\n}\\nfloat G_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\\n\\tfloat a2 \\x3d pow2( alpha );\\n\\tfloat gv \\x3d dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\\n\\tfloat gl \\x3d dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\\n\\treturn 0.5 / max( gv + gl, EPSILON );\\n}\\nfloat D_GGX( const in float alpha, const in float dotNH ) {\\n\\tfloat a2 \\x3d pow2( alpha );\\n\\tfloat denom \\x3d pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\\n\\treturn RECIPROCAL_PI * a2 / pow2( denom );\\n}\\nvec3 BRDF_Specular_GGX( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) {\\n\\tfloat alpha \\x3d pow2( roughness );\\n\\tvec3 halfDir \\x3d normalize( incidentLight.direction + geometry.viewDir );\\n\\tfloat dotNL \\x3d saturate( dot( geometry.normal, incidentLight.direction ) );\\n\\tfloat dotNV \\x3d saturate( dot( geometry.normal, geometry.viewDir ) );\\n\\tfloat dotNH \\x3d saturate( dot( geometry.normal, halfDir ) );\\n\\tfloat dotLH \\x3d saturate( dot( incidentLight.direction, halfDir ) );\\n\\tvec3 F \\x3d F_Schlick( specularColor, dotLH );\\n\\tfloat G \\x3d G_GGX_SmithCorrelated( alpha, dotNL, dotNV );\\n\\tfloat D \\x3d D_GGX( alpha, dotNH );\\n\\treturn F * ( G * D );\\n}\\nvec3 BRDF_Specular_GGX_Environment( const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) {\\n\\tfloat dotNV \\x3d saturate( dot( geometry.normal, geometry.viewDir ) );\\n\\tconst vec4 c0 \\x3d vec4( - 1, - 0.0275, - 0.572, 0.022 );\\n\\tconst vec4 c1 \\x3d vec4( 1, 0.0425, 1.04, - 0.04 );\\n\\tvec4 r \\x3d roughness * c0 + c1;\\n\\tfloat a004 \\x3d min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;\\n\\tvec2 AB \\x3d vec2( -1.04, 1.04 ) * a004 + r.zw;\\n\\treturn specularColor * AB.x + AB.y;\\n}\\nfloat G_BlinnPhong_Implicit( ) {\\n\\treturn 0.25;\\n}\\nfloat D_BlinnPhong( const in float shininess, const in float dotNH ) {\\n\\treturn RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess );\\n}\\nvec3 BRDF_Specular_BlinnPhong( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float shininess ) {\\n\\tvec3 halfDir \\x3d normalize( incidentLight.direction + geometry.viewDir );\\n\\tfloat dotNH \\x3d saturate( dot( geometry.normal, halfDir ) );\\n\\tfloat dotLH \\x3d saturate( dot( incidentLight.direction, halfDir ) );\\n\\tvec3 F \\x3d F_Schlick( specularColor, dotLH );\\n\\tfloat G \\x3d G_BlinnPhong_Implicit( );\\n\\tfloat D \\x3d D_BlinnPhong( shininess, dotNH );\\n\\treturn F * ( G * D );\\n}\\nfloat GGXRoughnessToBlinnExponent( const in float ggxRoughness ) {\\n\\treturn ( 2.0 / pow2( ggxRoughness + 0.0001 ) - 2.0 );\\n}\\nfloat BlinnExponentToGGXRoughness( const in float blinnExponent ) {\\n\\treturn sqrt( 2.0 / ( blinnExponent + 2.0 ) );\\n}\\n\";\nZ.ShaderChunk.bumpmap_pars_fragment=\"#ifdef USE_BUMPMAP\\n\\tuniform sampler2D bumpMap;\\n\\tuniform float bumpScale;\\n\\tvec2 dHdxy_fwd() {\\n\\t\\tvec2 dSTdx \\x3d dFdx( vUv );\\n\\t\\tvec2 dSTdy \\x3d dFdy( vUv );\\n\\t\\tfloat Hll \\x3d bumpScale * texture2D( bumpMap, vUv ).x;\\n\\t\\tfloat dBx \\x3d bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;\\n\\t\\tfloat dBy \\x3d bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;\\n\\t\\treturn vec2( dBx, dBy );\\n\\t}\\n\\tvec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy ) {\\n\\t\\tvec3 vSigmaX \\x3d dFdx( surf_pos );\\n\\t\\tvec3 vSigmaY \\x3d dFdy( surf_pos );\\n\\t\\tvec3 vN \\x3d surf_norm;\\n\\t\\tvec3 R1 \\x3d cross( vSigmaY, vN );\\n\\t\\tvec3 R2 \\x3d cross( vN, vSigmaX );\\n\\t\\tfloat fDet \\x3d dot( vSigmaX, R1 );\\n\\t\\tvec3 vGrad \\x3d sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );\\n\\t\\treturn normalize( abs( fDet ) * surf_norm - vGrad );\\n\\t}\\n#endif\\n\";\nZ.ShaderChunk.clipping_planes_fragment=\"#if NUM_CLIPPING_PLANES \\x3e 0\\n\\tfor ( int i \\x3d 0; i \\x3c NUM_CLIPPING_PLANES; ++ i ) {\\n\\t\\tvec4 plane \\x3d clippingPlanes[ i ];\\n\\t\\tif ( dot( vViewPosition, plane.xyz ) \\x3e plane.w ) discard;\\n\\t}\\n#endif\\n\";Z.ShaderChunk.clipping_planes_pars_fragment=\"#if NUM_CLIPPING_PLANES \\x3e 0\\n\\t#if ! defined( PHYSICAL ) \\x26\\x26 ! defined( PHONG )\\n\\t\\tvarying vec3 vViewPosition;\\n\\t#endif\\n\\tuniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\\n#endif\\n\";\nZ.ShaderChunk.clipping_planes_pars_vertex=\"#if NUM_CLIPPING_PLANES \\x3e 0 \\x26\\x26 ! defined( PHYSICAL ) \\x26\\x26 ! defined( PHONG )\\n\\tvarying vec3 vViewPosition;\\n#endif\\n\";Z.ShaderChunk.clipping_planes_vertex=\"#if NUM_CLIPPING_PLANES \\x3e 0 \\x26\\x26 ! defined( PHYSICAL ) \\x26\\x26 ! defined( PHONG )\\n\\tvViewPosition \\x3d - mvPosition.xyz;\\n#endif\\n\";Z.ShaderChunk.color_fragment=\"#ifdef USE_COLOR\\n\\tdiffuseColor.rgb *\\x3d vColor;\\n#endif\";Z.ShaderChunk.color_pars_fragment=\"#ifdef USE_COLOR\\n\\tvarying vec3 vColor;\\n#endif\\n\";\nZ.ShaderChunk.color_pars_vertex=\"#ifdef USE_COLOR\\n\\tvarying vec3 vColor;\\n#endif\";Z.ShaderChunk.color_vertex=\"#ifdef USE_COLOR\\n\\tvColor.xyz \\x3d color.xyz;\\n#endif\";Z.ShaderChunk.common=\"#define PI 3.14159265359\\n#define PI2 6.28318530718\\n#define RECIPROCAL_PI 0.31830988618\\n#define RECIPROCAL_PI2 0.15915494\\n#define LOG2 1.442695\\n#define EPSILON 1e-6\\n#define saturate(a) clamp( a, 0.0, 1.0 )\\n#define whiteCompliment(a) ( 1.0 - saturate( a ) )\\nfloat pow2( const in float x ) { return x*x; }\\nfloat pow3( const in float x ) { return x*x*x; }\\nfloat pow4( const in float x ) { float x2 \\x3d x*x; return x2*x2; }\\nfloat average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); }\\nhighp float rand( const in vec2 uv ) {\\n\\tconst highp float a \\x3d 12.9898, b \\x3d 78.233, c \\x3d 43758.5453;\\n\\thighp float dt \\x3d dot( uv.xy, vec2( a,b ) ), sn \\x3d mod( dt, PI );\\n\\treturn fract(sin(sn) * c);\\n}\\nstruct IncidentLight {\\n\\tvec3 color;\\n\\tvec3 direction;\\n\\tbool visible;\\n};\\nstruct ReflectedLight {\\n\\tvec3 directDiffuse;\\n\\tvec3 directSpecular;\\n\\tvec3 indirectDiffuse;\\n\\tvec3 indirectSpecular;\\n};\\nstruct GeometricContext {\\n\\tvec3 position;\\n\\tvec3 normal;\\n\\tvec3 viewDir;\\n};\\nvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\\n\\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\\n}\\nvec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {\\n\\treturn normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );\\n}\\nvec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\\n\\tfloat distance \\x3d dot( planeNormal, point - pointOnPlane );\\n\\treturn - distance * planeNormal + point;\\n}\\nfloat sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\\n\\treturn sign( dot( point - pointOnPlane, planeNormal ) );\\n}\\nvec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) {\\n\\treturn lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine;\\n}\\n\";\nZ.ShaderChunk.cube_uv_reflection_fragment=\"#ifdef ENVMAP_TYPE_CUBE_UV\\n#define cubeUV_textureSize (1024.0)\\nint getFaceFromDirection(vec3 direction) {\\n\\tvec3 absDirection \\x3d abs(direction);\\n\\tint face \\x3d -1;\\n\\tif( absDirection.x \\x3e absDirection.z ) {\\n\\t\\tif(absDirection.x \\x3e absDirection.y )\\n\\t\\t\\tface \\x3d direction.x \\x3e 0.0 ? 0 : 3;\\n\\t\\telse\\n\\t\\t\\tface \\x3d direction.y \\x3e 0.0 ? 1 : 4;\\n\\t}\\n\\telse {\\n\\t\\tif(absDirection.z \\x3e absDirection.y )\\n\\t\\t\\tface \\x3d direction.z \\x3e 0.0 ? 2 : 5;\\n\\t\\telse\\n\\t\\t\\tface \\x3d direction.y \\x3e 0.0 ? 1 : 4;\\n\\t}\\n\\treturn face;\\n}\\n#define cubeUV_maxLods1  (log2(cubeUV_textureSize*0.25) - 1.0)\\n#define cubeUV_rangeClamp (exp2((6.0 - 1.0) * 2.0))\\nvec2 MipLevelInfo( vec3 vec, float roughnessLevel, float roughness ) {\\n\\tfloat scale \\x3d exp2(cubeUV_maxLods1 - roughnessLevel);\\n\\tfloat dxRoughness \\x3d dFdx(roughness);\\n\\tfloat dyRoughness \\x3d dFdy(roughness);\\n\\tvec3 dx \\x3d dFdx( vec * scale * dxRoughness );\\n\\tvec3 dy \\x3d dFdy( vec * scale * dyRoughness );\\n\\tfloat d \\x3d max( dot( dx, dx ), dot( dy, dy ) );\\n\\td \\x3d clamp(d, 1.0, cubeUV_rangeClamp);\\n\\tfloat mipLevel \\x3d 0.5 * log2(d);\\n\\treturn vec2(floor(mipLevel), fract(mipLevel));\\n}\\n#define cubeUV_maxLods2 (log2(cubeUV_textureSize*0.25) - 2.0)\\n#define cubeUV_rcpTextureSize (1.0 / cubeUV_textureSize)\\nvec2 getCubeUV(vec3 direction, float roughnessLevel, float mipLevel) {\\n\\tmipLevel \\x3d roughnessLevel \\x3e cubeUV_maxLods2 - 3.0 ? 0.0 : mipLevel;\\n\\tfloat a \\x3d 16.0 * cubeUV_rcpTextureSize;\\n\\tvec2 exp2_packed \\x3d exp2( vec2( roughnessLevel, mipLevel ) );\\n\\tvec2 rcp_exp2_packed \\x3d vec2( 1.0 ) / exp2_packed;\\n\\tfloat powScale \\x3d exp2_packed.x * exp2_packed.y;\\n\\tfloat scale \\x3d rcp_exp2_packed.x * rcp_exp2_packed.y * 0.25;\\n\\tfloat mipOffset \\x3d 0.75*(1.0 - rcp_exp2_packed.y) * rcp_exp2_packed.x;\\n\\tbool bRes \\x3d mipLevel \\x3d\\x3d 0.0;\\n\\tscale \\x3d  bRes \\x26\\x26 (scale \\x3c a) ? a : scale;\\n\\tvec3 r;\\n\\tvec2 offset;\\n\\tint face \\x3d getFaceFromDirection(direction);\\n\\tfloat rcpPowScale \\x3d 1.0 / powScale;\\n\\tif( face \\x3d\\x3d 0) {\\n\\t\\tr \\x3d vec3(direction.x, -direction.z, direction.y);\\n\\t\\toffset \\x3d vec2(0.0+mipOffset,0.75 * rcpPowScale);\\n\\t\\toffset.y \\x3d bRes \\x26\\x26 (offset.y \\x3c 2.0*a) ?  a : offset.y;\\n\\t}\\n\\telse if( face \\x3d\\x3d 1) {\\n\\t\\tr \\x3d vec3(direction.y, direction.x, direction.z);\\n\\t\\toffset \\x3d vec2(scale+mipOffset, 0.75 * rcpPowScale);\\n\\t\\toffset.y \\x3d bRes \\x26\\x26 (offset.y \\x3c 2.0*a) ?  a : offset.y;\\n\\t}\\n\\telse if( face \\x3d\\x3d 2) {\\n\\t\\tr \\x3d vec3(direction.z, direction.x, direction.y);\\n\\t\\toffset \\x3d vec2(2.0*scale+mipOffset, 0.75 * rcpPowScale);\\n\\t\\toffset.y \\x3d bRes \\x26\\x26 (offset.y \\x3c 2.0*a) ?  a : offset.y;\\n\\t}\\n\\telse if( face \\x3d\\x3d 3) {\\n\\t\\tr \\x3d vec3(direction.x, direction.z, direction.y);\\n\\t\\toffset \\x3d vec2(0.0+mipOffset,0.5 * rcpPowScale);\\n\\t\\toffset.y \\x3d bRes \\x26\\x26 (offset.y \\x3c 2.0*a) ?  0.0 : offset.y;\\n\\t}\\n\\telse if( face \\x3d\\x3d 4) {\\n\\t\\tr \\x3d vec3(direction.y, direction.x, -direction.z);\\n\\t\\toffset \\x3d vec2(scale+mipOffset, 0.5 * rcpPowScale);\\n\\t\\toffset.y \\x3d bRes \\x26\\x26 (offset.y \\x3c 2.0*a) ?  0.0 : offset.y;\\n\\t}\\n\\telse {\\n\\t\\tr \\x3d vec3(direction.z, -direction.x, direction.y);\\n\\t\\toffset \\x3d vec2(2.0*scale+mipOffset, 0.5 * rcpPowScale);\\n\\t\\toffset.y \\x3d bRes \\x26\\x26 (offset.y \\x3c 2.0*a) ?  0.0 : offset.y;\\n\\t}\\n\\tr \\x3d normalize(r);\\n\\tfloat texelOffset \\x3d 0.5 * cubeUV_rcpTextureSize;\\n\\tvec2 s \\x3d ( r.yz / abs( r.x ) + vec2( 1.0 ) ) * 0.5;\\n\\tvec2 base \\x3d offset + vec2( texelOffset );\\n\\treturn base + s * ( scale - 2.0 * texelOffset );\\n}\\n#define cubeUV_maxLods3 (log2(cubeUV_textureSize*0.25) - 3.0)\\nvec4 textureCubeUV(vec3 reflectedDirection, float roughness ) {\\n\\tfloat roughnessVal \\x3d roughness* cubeUV_maxLods3;\\n\\tfloat r1 \\x3d floor(roughnessVal);\\n\\tfloat r2 \\x3d r1 + 1.0;\\n\\tfloat t \\x3d fract(roughnessVal);\\n\\tvec2 mipInfo \\x3d MipLevelInfo(reflectedDirection, r1, roughness);\\n\\tfloat s \\x3d mipInfo.y;\\n\\tfloat level0 \\x3d mipInfo.x;\\n\\tfloat level1 \\x3d level0 + 1.0;\\n\\tlevel1 \\x3d level1 \\x3e 5.0 ? 5.0 : level1;\\n\\tlevel0 +\\x3d min( floor( s + 0.5 ), 5.0 );\\n\\tvec2 uv_10 \\x3d getCubeUV(reflectedDirection, r1, level0);\\n\\tvec4 color10 \\x3d envMapTexelToLinear(texture2D(envMap, uv_10));\\n\\tvec2 uv_20 \\x3d getCubeUV(reflectedDirection, r2, level0);\\n\\tvec4 color20 \\x3d envMapTexelToLinear(texture2D(envMap, uv_20));\\n\\tvec4 result \\x3d mix(color10, color20, t);\\n\\treturn vec4(result.rgb, 1.0);\\n}\\n#endif\\n\";\nZ.ShaderChunk.defaultnormal_vertex=\"#ifdef FLIP_SIDED\\n\\tobjectNormal \\x3d -objectNormal;\\n#endif\\nvec3 transformedNormal \\x3d normalMatrix * objectNormal;\\n\";Z.ShaderChunk.displacementmap_vertex=\"#ifdef USE_DISPLACEMENTMAP\\n\\ttransformed +\\x3d normal * ( texture2D( displacementMap, uv ).x * displacementScale + displacementBias );\\n#endif\\n\";Z.ShaderChunk.displacementmap_pars_vertex=\"#ifdef USE_DISPLACEMENTMAP\\n\\tuniform sampler2D displacementMap;\\n\\tuniform float displacementScale;\\n\\tuniform float displacementBias;\\n#endif\\n\";\nZ.ShaderChunk.emissivemap_fragment=\"#ifdef USE_EMISSIVEMAP\\n\\tvec4 emissiveColor \\x3d texture2D( emissiveMap, vUv );\\n\\temissiveColor.rgb \\x3d emissiveMapTexelToLinear( emissiveColor ).rgb;\\n\\ttotalEmissiveRadiance *\\x3d emissiveColor.rgb;\\n#endif\\n\";Z.ShaderChunk.emissivemap_pars_fragment=\"#ifdef USE_EMISSIVEMAP\\n\\tuniform sampler2D emissiveMap;\\n#endif\\n\";Z.ShaderChunk.encodings_pars_fragment=\"\\nvec4 LinearToLinear( in vec4 value ) {\\n  return value;\\n}\\nvec4 GammaToLinear( in vec4 value, in float gammaFactor ) {\\n  return vec4( pow( value.xyz, vec3( gammaFactor ) ), value.w );\\n}\\nvec4 LinearToGamma( in vec4 value, in float gammaFactor ) {\\n  return vec4( pow( value.xyz, vec3( 1.0 / gammaFactor ) ), value.w );\\n}\\nvec4 sRGBToLinear( in vec4 value ) {\\n  return vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, vec3( lessThanEqual( value.rgb, vec3( 0.04045 ) ) ) ), value.w );\\n}\\nvec4 LinearTosRGB( in vec4 value ) {\\n  return vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.w );\\n}\\nvec4 RGBEToLinear( in vec4 value ) {\\n  return vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 );\\n}\\nvec4 LinearToRGBE( in vec4 value ) {\\n  float maxComponent \\x3d max( max( value.r, value.g ), value.b );\\n  float fExp \\x3d clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 );\\n  return vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 );\\n}\\nvec4 RGBMToLinear( in vec4 value, in float maxRange ) {\\n  return vec4( value.xyz * value.w * maxRange, 1.0 );\\n}\\nvec4 LinearToRGBM( in vec4 value, in float maxRange ) {\\n  float maxRGB \\x3d max( value.x, max( value.g, value.b ) );\\n  float M      \\x3d clamp( maxRGB / maxRange, 0.0, 1.0 );\\n  M            \\x3d ceil( M * 255.0 ) / 255.0;\\n  return vec4( value.rgb / ( M * maxRange ), M );\\n}\\nvec4 RGBDToLinear( in vec4 value, in float maxRange ) {\\n    return vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 );\\n}\\nvec4 LinearToRGBD( in vec4 value, in float maxRange ) {\\n    float maxRGB \\x3d max( value.x, max( value.g, value.b ) );\\n    float D      \\x3d max( maxRange / maxRGB, 1.0 );\\n    D            \\x3d min( floor( D ) / 255.0, 1.0 );\\n    return vec4( value.rgb * ( D * ( 255.0 / maxRange ) ), D );\\n}\\nconst mat3 cLogLuvM \\x3d mat3( 0.2209, 0.3390, 0.4184, 0.1138, 0.6780, 0.7319, 0.0102, 0.1130, 0.2969 );\\nvec4 LinearToLogLuv( in vec4 value )  {\\n  vec3 Xp_Y_XYZp \\x3d value.rgb * cLogLuvM;\\n  Xp_Y_XYZp \\x3d max(Xp_Y_XYZp, vec3(1e-6, 1e-6, 1e-6));\\n  vec4 vResult;\\n  vResult.xy \\x3d Xp_Y_XYZp.xy / Xp_Y_XYZp.z;\\n  float Le \\x3d 2.0 * log2(Xp_Y_XYZp.y) + 127.0;\\n  vResult.w \\x3d fract(Le);\\n  vResult.z \\x3d (Le - (floor(vResult.w*255.0))/255.0)/255.0;\\n  return vResult;\\n}\\nconst mat3 cLogLuvInverseM \\x3d mat3( 6.0014, -2.7008, -1.7996, -1.3320, 3.1029, -5.7721, 0.3008, -1.0882, 5.6268 );\\nvec4 LogLuvToLinear( in vec4 value ) {\\n  float Le \\x3d value.z * 255.0 + value.w;\\n  vec3 Xp_Y_XYZp;\\n  Xp_Y_XYZp.y \\x3d exp2((Le - 127.0) / 2.0);\\n  Xp_Y_XYZp.z \\x3d Xp_Y_XYZp.y / value.y;\\n  Xp_Y_XYZp.x \\x3d value.x * Xp_Y_XYZp.z;\\n  vec3 vRGB \\x3d Xp_Y_XYZp.rgb * cLogLuvInverseM;\\n  return vec4( max(vRGB, 0.0), 1.0 );\\n}\\n\";\nZ.ShaderChunk.encodings_fragment=\"  gl_FragColor \\x3d linearToOutputTexel( gl_FragColor );\\n\";Z.ShaderChunk.envmap_fragment=\"#ifdef USE_ENVMAP\\n\\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\\n\\t\\tvec3 cameraToVertex \\x3d normalize( vWorldPosition - cameraPosition );\\n\\t\\tvec3 worldNormal \\x3d inverseTransformDirection( normal, viewMatrix );\\n\\t\\t#ifdef ENVMAP_MODE_REFLECTION\\n\\t\\t\\tvec3 reflectVec \\x3d reflect( cameraToVertex, worldNormal );\\n\\t\\t#else\\n\\t\\t\\tvec3 reflectVec \\x3d refract( cameraToVertex, worldNormal, refractionRatio );\\n\\t\\t#endif\\n\\t#else\\n\\t\\tvec3 reflectVec \\x3d vReflect;\\n\\t#endif\\n\\t#ifdef DOUBLE_SIDED\\n\\t\\tfloat flipNormal \\x3d ( float( gl_FrontFacing ) * 2.0 - 1.0 );\\n\\t#else\\n\\t\\tfloat flipNormal \\x3d 1.0;\\n\\t#endif\\n\\t#ifdef ENVMAP_TYPE_CUBE\\n\\t\\tvec4 envColor \\x3d textureCube( envMap, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\\n\\t#elif defined( ENVMAP_TYPE_EQUIREC )\\n\\t\\tvec2 sampleUV;\\n\\t\\tsampleUV.y \\x3d saturate( flipNormal * reflectVec.y * 0.5 + 0.5 );\\n\\t\\tsampleUV.x \\x3d atan( flipNormal * reflectVec.z, flipNormal * reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\\n\\t\\tvec4 envColor \\x3d texture2D( envMap, sampleUV );\\n\\t#elif defined( ENVMAP_TYPE_SPHERE )\\n\\t\\tvec3 reflectView \\x3d flipNormal * normalize((viewMatrix * vec4( reflectVec, 0.0 )).xyz + vec3(0.0,0.0,1.0));\\n\\t\\tvec4 envColor \\x3d texture2D( envMap, reflectView.xy * 0.5 + 0.5 );\\n\\t#endif\\n\\tenvColor \\x3d envMapTexelToLinear( envColor );\\n\\t#ifdef ENVMAP_BLENDING_MULTIPLY\\n\\t\\toutgoingLight \\x3d mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );\\n\\t#elif defined( ENVMAP_BLENDING_MIX )\\n\\t\\toutgoingLight \\x3d mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );\\n\\t#elif defined( ENVMAP_BLENDING_ADD )\\n\\t\\toutgoingLight +\\x3d envColor.xyz * specularStrength * reflectivity;\\n\\t#endif\\n#endif\\n\";\nZ.ShaderChunk.envmap_pars_fragment=\"#if defined( USE_ENVMAP ) || defined( PHYSICAL )\\n\\tuniform float reflectivity;\\n\\tuniform float envMapIntenstiy;\\n#endif\\n#ifdef USE_ENVMAP\\n\\t#if ! defined( PHYSICAL ) \\x26\\x26 ( defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) )\\n\\t\\tvarying vec3 vWorldPosition;\\n\\t#endif\\n\\t#ifdef ENVMAP_TYPE_CUBE\\n\\t\\tuniform samplerCube envMap;\\n\\t#else\\n\\t\\tuniform sampler2D envMap;\\n\\t#endif\\n\\tuniform float flipEnvMap;\\n\\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( PHYSICAL )\\n\\t\\tuniform float refractionRatio;\\n\\t#else\\n\\t\\tvarying vec3 vReflect;\\n\\t#endif\\n#endif\\n\";\nZ.ShaderChunk.envmap_pars_vertex=\"#ifdef USE_ENVMAP\\n\\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\\n\\t\\tvarying vec3 vWorldPosition;\\n\\t#else\\n\\t\\tvarying vec3 vReflect;\\n\\t\\tuniform float refractionRatio;\\n\\t#endif\\n#endif\\n\";Z.ShaderChunk.envmap_vertex=\"#ifdef USE_ENVMAP\\n\\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\\n\\t\\tvWorldPosition \\x3d worldPosition.xyz;\\n\\t#else\\n\\t\\tvec3 cameraToVertex \\x3d normalize( worldPosition.xyz - cameraPosition );\\n\\t\\tvec3 worldNormal \\x3d inverseTransformDirection( transformedNormal, viewMatrix );\\n\\t\\t#ifdef ENVMAP_MODE_REFLECTION\\n\\t\\t\\tvReflect \\x3d reflect( cameraToVertex, worldNormal );\\n\\t\\t#else\\n\\t\\t\\tvReflect \\x3d refract( cameraToVertex, worldNormal, refractionRatio );\\n\\t\\t#endif\\n\\t#endif\\n#endif\\n\";\nZ.ShaderChunk.fog_fragment=\"#ifdef USE_FOG\\n\\t#ifdef USE_LOGDEPTHBUF_EXT\\n\\t\\tfloat depth \\x3d gl_FragDepthEXT / gl_FragCoord.w;\\n\\t#else\\n\\t\\tfloat depth \\x3d gl_FragCoord.z / gl_FragCoord.w;\\n\\t#endif\\n\\t#ifdef FOG_EXP2\\n\\t\\tfloat fogFactor \\x3d whiteCompliment( exp2( - fogDensity * fogDensity * depth * depth * LOG2 ) );\\n\\t#else\\n\\t\\tfloat fogFactor \\x3d smoothstep( fogNear, fogFar, depth );\\n\\t#endif\\n\\tgl_FragColor.rgb \\x3d mix( gl_FragColor.rgb, fogColor, fogFactor );\\n#endif\\n\";\nZ.ShaderChunk.fog_pars_fragment=\"#ifdef USE_FOG\\n\\tuniform vec3 fogColor;\\n\\t#ifdef FOG_EXP2\\n\\t\\tuniform float fogDensity;\\n\\t#else\\n\\t\\tuniform float fogNear;\\n\\t\\tuniform float fogFar;\\n\\t#endif\\n#endif\";Z.ShaderChunk.lightmap_fragment=\"#ifdef USE_LIGHTMAP\\n\\treflectedLight.indirectDiffuse +\\x3d PI * texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\\n#endif\\n\";Z.ShaderChunk.lightmap_pars_fragment=\"#ifdef USE_LIGHTMAP\\n\\tuniform sampler2D lightMap;\\n\\tuniform float lightMapIntensity;\\n#endif\";\nZ.ShaderChunk.lights_lambert_vertex=\"vec3 diffuse \\x3d vec3( 1.0 );\\nGeometricContext geometry;\\ngeometry.position \\x3d mvPosition.xyz;\\ngeometry.normal \\x3d normalize( transformedNormal );\\ngeometry.viewDir \\x3d normalize( -mvPosition.xyz );\\nGeometricContext backGeometry;\\nbackGeometry.position \\x3d geometry.position;\\nbackGeometry.normal \\x3d -geometry.normal;\\nbackGeometry.viewDir \\x3d geometry.viewDir;\\nvLightFront \\x3d vec3( 0.0 );\\n#ifdef DOUBLE_SIDED\\n\\tvLightBack \\x3d vec3( 0.0 );\\n#endif\\nIncidentLight directLight;\\nfloat dotNL;\\nvec3 directLightColor_Diffuse;\\n#if NUM_POINT_LIGHTS \\x3e 0\\n\\tfor ( int i \\x3d 0; i \\x3c NUM_POINT_LIGHTS; i ++ ) {\\n\\t\\tgetPointDirectLightIrradiance( pointLights[ i ], geometry, directLight );\\n\\t\\tdotNL \\x3d dot( geometry.normal, directLight.direction );\\n\\t\\tdirectLightColor_Diffuse \\x3d PI * directLight.color;\\n\\t\\tvLightFront +\\x3d saturate( dotNL ) * directLightColor_Diffuse;\\n\\t\\t#ifdef DOUBLE_SIDED\\n\\t\\t\\tvLightBack +\\x3d saturate( -dotNL ) * directLightColor_Diffuse;\\n\\t\\t#endif\\n\\t}\\n#endif\\n#if NUM_SPOT_LIGHTS \\x3e 0\\n\\tfor ( int i \\x3d 0; i \\x3c NUM_SPOT_LIGHTS; i ++ ) {\\n\\t\\tgetSpotDirectLightIrradiance( spotLights[ i ], geometry, directLight );\\n\\t\\tdotNL \\x3d dot( geometry.normal, directLight.direction );\\n\\t\\tdirectLightColor_Diffuse \\x3d PI * directLight.color;\\n\\t\\tvLightFront +\\x3d saturate( dotNL ) * directLightColor_Diffuse;\\n\\t\\t#ifdef DOUBLE_SIDED\\n\\t\\t\\tvLightBack +\\x3d saturate( -dotNL ) * directLightColor_Diffuse;\\n\\t\\t#endif\\n\\t}\\n#endif\\n#if NUM_DIR_LIGHTS \\x3e 0\\n\\tfor ( int i \\x3d 0; i \\x3c NUM_DIR_LIGHTS; i ++ ) {\\n\\t\\tgetDirectionalDirectLightIrradiance( directionalLights[ i ], geometry, directLight );\\n\\t\\tdotNL \\x3d dot( geometry.normal, directLight.direction );\\n\\t\\tdirectLightColor_Diffuse \\x3d PI * directLight.color;\\n\\t\\tvLightFront +\\x3d saturate( dotNL ) * directLightColor_Diffuse;\\n\\t\\t#ifdef DOUBLE_SIDED\\n\\t\\t\\tvLightBack +\\x3d saturate( -dotNL ) * directLightColor_Diffuse;\\n\\t\\t#endif\\n\\t}\\n#endif\\n#if NUM_HEMI_LIGHTS \\x3e 0\\n\\tfor ( int i \\x3d 0; i \\x3c NUM_HEMI_LIGHTS; i ++ ) {\\n\\t\\tvLightFront +\\x3d getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\\n\\t\\t#ifdef DOUBLE_SIDED\\n\\t\\t\\tvLightBack +\\x3d getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometry );\\n\\t\\t#endif\\n\\t}\\n#endif\\n\";\nZ.ShaderChunk.lights_pars=\"uniform vec3 ambientLightColor;\\nvec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {\\n\\tvec3 irradiance \\x3d ambientLightColor;\\n\\t#ifndef PHYSICALLY_CORRECT_LIGHTS\\n\\t\\tirradiance *\\x3d PI;\\n\\t#endif\\n\\treturn irradiance;\\n}\\n#if NUM_DIR_LIGHTS \\x3e 0\\n\\tstruct DirectionalLight {\\n\\t\\tvec3 direction;\\n\\t\\tvec3 color;\\n\\t\\tint shadow;\\n\\t\\tfloat shadowBias;\\n\\t\\tfloat shadowRadius;\\n\\t\\tvec2 shadowMapSize;\\n\\t};\\n\\tuniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];\\n\\tvoid getDirectionalDirectLightIrradiance( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight directLight ) {\\n\\t\\tdirectLight.color \\x3d directionalLight.color;\\n\\t\\tdirectLight.direction \\x3d directionalLight.direction;\\n\\t\\tdirectLight.visible \\x3d true;\\n\\t}\\n#endif\\n#if NUM_POINT_LIGHTS \\x3e 0\\n\\tstruct PointLight {\\n\\t\\tvec3 position;\\n\\t\\tvec3 color;\\n\\t\\tfloat distance;\\n\\t\\tfloat decay;\\n\\t\\tint shadow;\\n\\t\\tfloat shadowBias;\\n\\t\\tfloat shadowRadius;\\n\\t\\tvec2 shadowMapSize;\\n\\t};\\n\\tuniform PointLight pointLights[ NUM_POINT_LIGHTS ];\\n\\tvoid getPointDirectLightIrradiance( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight directLight ) {\\n\\t\\tvec3 lVector \\x3d pointLight.position - geometry.position;\\n\\t\\tdirectLight.direction \\x3d normalize( lVector );\\n\\t\\tfloat lightDistance \\x3d length( lVector );\\n\\t\\tif ( testLightInRange( lightDistance, pointLight.distance ) ) {\\n\\t\\t\\tdirectLight.color \\x3d pointLight.color;\\n\\t\\t\\tdirectLight.color *\\x3d punctualLightIntensityToIrradianceFactor( lightDistance, pointLight.distance, pointLight.decay );\\n\\t\\t\\tdirectLight.visible \\x3d true;\\n\\t\\t} else {\\n\\t\\t\\tdirectLight.color \\x3d vec3( 0.0 );\\n\\t\\t\\tdirectLight.visible \\x3d false;\\n\\t\\t}\\n\\t}\\n#endif\\n#if NUM_SPOT_LIGHTS \\x3e 0\\n\\tstruct SpotLight {\\n\\t\\tvec3 position;\\n\\t\\tvec3 direction;\\n\\t\\tvec3 color;\\n\\t\\tfloat distance;\\n\\t\\tfloat decay;\\n\\t\\tfloat coneCos;\\n\\t\\tfloat penumbraCos;\\n\\t\\tint shadow;\\n\\t\\tfloat shadowBias;\\n\\t\\tfloat shadowRadius;\\n\\t\\tvec2 shadowMapSize;\\n\\t};\\n\\tuniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];\\n\\tvoid getSpotDirectLightIrradiance( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight directLight  ) {\\n\\t\\tvec3 lVector \\x3d spotLight.position - geometry.position;\\n\\t\\tdirectLight.direction \\x3d normalize( lVector );\\n\\t\\tfloat lightDistance \\x3d length( lVector );\\n\\t\\tfloat angleCos \\x3d dot( directLight.direction, spotLight.direction );\\n\\t\\tif ( all( bvec2( angleCos \\x3e spotLight.coneCos, testLightInRange( lightDistance, spotLight.distance ) ) ) ) {\\n\\t\\t\\tfloat spotEffect \\x3d smoothstep( spotLight.coneCos, spotLight.penumbraCos, angleCos );\\n\\t\\t\\tdirectLight.color \\x3d spotLight.color;\\n\\t\\t\\tdirectLight.color *\\x3d spotEffect * punctualLightIntensityToIrradianceFactor( lightDistance, spotLight.distance, spotLight.decay );\\n\\t\\t\\tdirectLight.visible \\x3d true;\\n\\t\\t} else {\\n\\t\\t\\tdirectLight.color \\x3d vec3( 0.0 );\\n\\t\\t\\tdirectLight.visible \\x3d false;\\n\\t\\t}\\n\\t}\\n#endif\\n#if NUM_HEMI_LIGHTS \\x3e 0\\n\\tstruct HemisphereLight {\\n\\t\\tvec3 direction;\\n\\t\\tvec3 skyColor;\\n\\t\\tvec3 groundColor;\\n\\t};\\n\\tuniform HemisphereLight hemisphereLights[ NUM_HEMI_LIGHTS ];\\n\\tvec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in GeometricContext geometry ) {\\n\\t\\tfloat dotNL \\x3d dot( geometry.normal, hemiLight.direction );\\n\\t\\tfloat hemiDiffuseWeight \\x3d 0.5 * dotNL + 0.5;\\n\\t\\tvec3 irradiance \\x3d mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );\\n\\t\\t#ifndef PHYSICALLY_CORRECT_LIGHTS\\n\\t\\t\\tirradiance *\\x3d PI;\\n\\t\\t#endif\\n\\t\\treturn irradiance;\\n\\t}\\n#endif\\n#if defined( USE_ENVMAP ) \\x26\\x26 defined( PHYSICAL )\\n\\tvec3 getLightProbeIndirectIrradiance( const in GeometricContext geometry, const in int maxMIPLevel ) {\\n\\t\\t#ifdef DOUBLE_SIDED\\n\\t\\t\\tfloat flipNormal \\x3d ( float( gl_FrontFacing ) * 2.0 - 1.0 );\\n\\t\\t#else\\n\\t\\t\\tfloat flipNormal \\x3d 1.0;\\n\\t\\t#endif\\n\\t\\tvec3 worldNormal \\x3d inverseTransformDirection( geometry.normal, viewMatrix );\\n\\t\\t#ifdef ENVMAP_TYPE_CUBE\\n\\t\\t\\tvec3 queryVec \\x3d flipNormal * vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\\n\\t\\t\\t#ifdef TEXTURE_LOD_EXT\\n\\t\\t\\t\\tvec4 envMapColor \\x3d textureCubeLodEXT( envMap, queryVec, float( maxMIPLevel ) );\\n\\t\\t\\t#else\\n\\t\\t\\t\\tvec4 envMapColor \\x3d textureCube( envMap, queryVec, float( maxMIPLevel ) );\\n\\t\\t\\t#endif\\n\\t\\t\\tenvMapColor.rgb \\x3d envMapTexelToLinear( envMapColor ).rgb;\\n\\t\\t#elif defined( ENVMAP_TYPE_CUBE_UV )\\n\\t\\t\\tvec3 queryVec \\x3d flipNormal * vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\\n\\t\\t\\tvec4 envMapColor \\x3d textureCubeUV( queryVec, 1.0 );\\n\\t\\t#else\\n\\t\\t\\tvec4 envMapColor \\x3d vec4( 0.0 );\\n\\t\\t#endif\\n\\t\\treturn PI * envMapColor.rgb * envMapIntensity;\\n\\t}\\n\\tfloat getSpecularMIPLevel( const in float blinnShininessExponent, const in int maxMIPLevel ) {\\n\\t\\tfloat maxMIPLevelScalar \\x3d float( maxMIPLevel );\\n\\t\\tfloat desiredMIPLevel \\x3d maxMIPLevelScalar - 0.79248 - 0.5 * log2( pow2( blinnShininessExponent ) + 1.0 );\\n\\t\\treturn clamp( desiredMIPLevel, 0.0, maxMIPLevelScalar );\\n\\t}\\n\\tvec3 getLightProbeIndirectRadiance( const in GeometricContext geometry, const in float blinnShininessExponent, const in int maxMIPLevel ) {\\n\\t\\t#ifdef ENVMAP_MODE_REFLECTION\\n\\t\\t\\tvec3 reflectVec \\x3d reflect( -geometry.viewDir, geometry.normal );\\n\\t\\t#else\\n\\t\\t\\tvec3 reflectVec \\x3d refract( -geometry.viewDir, geometry.normal, refractionRatio );\\n\\t\\t#endif\\n\\t\\t#ifdef DOUBLE_SIDED\\n\\t\\t\\tfloat flipNormal \\x3d ( float( gl_FrontFacing ) * 2.0 - 1.0 );\\n\\t\\t#else\\n\\t\\t\\tfloat flipNormal \\x3d 1.0;\\n\\t\\t#endif\\n\\t\\treflectVec \\x3d inverseTransformDirection( reflectVec, viewMatrix );\\n\\t\\tfloat specularMIPLevel \\x3d getSpecularMIPLevel( blinnShininessExponent, maxMIPLevel );\\n\\t\\t#ifdef ENVMAP_TYPE_CUBE\\n\\t\\t\\tvec3 queryReflectVec \\x3d flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\\n\\t\\t\\t#ifdef TEXTURE_LOD_EXT\\n\\t\\t\\t\\tvec4 envMapColor \\x3d textureCubeLodEXT( envMap, queryReflectVec, specularMIPLevel );\\n\\t\\t\\t#else\\n\\t\\t\\t\\tvec4 envMapColor \\x3d textureCube( envMap, queryReflectVec, specularMIPLevel );\\n\\t\\t\\t#endif\\n\\t\\t\\tenvMapColor.rgb \\x3d envMapTexelToLinear( envMapColor ).rgb;\\n\\t\\t#elif defined( ENVMAP_TYPE_CUBE_UV )\\n\\t\\t\\tvec3 queryReflectVec \\x3d flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\\n\\t\\t\\tvec4 envMapColor \\x3d textureCubeUV(queryReflectVec, BlinnExponentToGGXRoughness(blinnShininessExponent));\\n\\t\\t#elif defined( ENVMAP_TYPE_EQUIREC )\\n\\t\\t\\tvec2 sampleUV;\\n\\t\\t\\tsampleUV.y \\x3d saturate( flipNormal * reflectVec.y * 0.5 + 0.5 );\\n\\t\\t\\tsampleUV.x \\x3d atan( flipNormal * reflectVec.z, flipNormal * reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\\n\\t\\t\\t#ifdef TEXTURE_LOD_EXT\\n\\t\\t\\t\\tvec4 envMapColor \\x3d texture2DLodEXT( envMap, sampleUV, specularMIPLevel );\\n\\t\\t\\t#else\\n\\t\\t\\t\\tvec4 envMapColor \\x3d texture2D( envMap, sampleUV, specularMIPLevel );\\n\\t\\t\\t#endif\\n\\t\\t\\tenvMapColor.rgb \\x3d envMapTexelToLinear( envMapColor ).rgb;\\n\\t\\t#elif defined( ENVMAP_TYPE_SPHERE )\\n\\t\\t\\tvec3 reflectView \\x3d flipNormal * normalize((viewMatrix * vec4( reflectVec, 0.0 )).xyz + vec3(0.0,0.0,1.0));\\n\\t\\t\\t#ifdef TEXTURE_LOD_EXT\\n\\t\\t\\t\\tvec4 envMapColor \\x3d texture2DLodEXT( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\\n\\t\\t\\t#else\\n\\t\\t\\t\\tvec4 envMapColor \\x3d texture2D( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\\n\\t\\t\\t#endif\\n\\t\\t\\tenvMapColor.rgb \\x3d envMapTexelToLinear( envMapColor ).rgb;\\n\\t\\t#endif\\n\\t\\treturn envMapColor.rgb * envMapIntensity;\\n\\t}\\n#endif\\n\";\nZ.ShaderChunk.lights_phong_fragment=\"BlinnPhongMaterial material;\\nmaterial.diffuseColor \\x3d diffuseColor.rgb;\\nmaterial.specularColor \\x3d specular;\\nmaterial.specularShininess \\x3d shininess;\\nmaterial.specularStrength \\x3d specularStrength;\\n\";Z.ShaderChunk.lights_phong_pars_fragment=\"varying vec3 vViewPosition;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\nstruct BlinnPhongMaterial {\\n\\tvec3\\tdiffuseColor;\\n\\tvec3\\tspecularColor;\\n\\tfloat\\tspecularShininess;\\n\\tfloat\\tspecularStrength;\\n};\\nvoid RE_Direct_BlinnPhong( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\\n\\tfloat dotNL \\x3d saturate( dot( geometry.normal, directLight.direction ) );\\n\\tvec3 irradiance \\x3d dotNL * directLight.color;\\n\\t#ifndef PHYSICALLY_CORRECT_LIGHTS\\n\\t\\tirradiance *\\x3d PI;\\n\\t#endif\\n\\treflectedLight.directDiffuse +\\x3d irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\\n\\treflectedLight.directSpecular +\\x3d irradiance * BRDF_Specular_BlinnPhong( directLight, geometry, material.specularColor, material.specularShininess ) * material.specularStrength;\\n}\\nvoid RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\\n\\treflectedLight.indirectDiffuse +\\x3d irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\\n}\\n#define RE_Direct\\t\\t\\t\\tRE_Direct_BlinnPhong\\n#define RE_IndirectDiffuse\\t\\tRE_IndirectDiffuse_BlinnPhong\\n#define Material_LightProbeLOD( material )\\t(0)\\n\";\nZ.ShaderChunk.lights_physical_fragment=\"PhysicalMaterial material;\\nmaterial.diffuseColor \\x3d diffuseColor.rgb * ( 1.0 - metalnessFactor );\\nmaterial.specularRoughness \\x3d clamp( roughnessFactor, 0.04, 1.0 );\\n#ifdef STANDARD\\n\\tmaterial.specularColor \\x3d mix( vec3( 0.04 ), diffuseColor.rgb, metalnessFactor );\\n#else\\n\\tmaterial.specularColor \\x3d mix( vec3( 0.16 * pow2( reflectivity ) ), diffuseColor.rgb, metalnessFactor );\\n#endif\\n\";Z.ShaderChunk.lights_physical_pars_fragment=\"struct PhysicalMaterial {\\n\\tvec3\\tdiffuseColor;\\n\\tfloat\\tspecularRoughness;\\n\\tvec3\\tspecularColor;\\n\\t#ifndef STANDARD\\n\\t#endif\\n};\\nvoid RE_Direct_Physical( const in IncidentLight directLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\\n\\tfloat dotNL \\x3d saturate( dot( geometry.normal, directLight.direction ) );\\n\\tvec3 irradiance \\x3d dotNL * directLight.color;\\n\\t#ifndef PHYSICALLY_CORRECT_LIGHTS\\n\\t\\tirradiance *\\x3d PI;\\n\\t#endif\\n\\treflectedLight.directDiffuse +\\x3d irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\\n\\treflectedLight.directSpecular +\\x3d irradiance * BRDF_Specular_GGX( directLight, geometry, material.specularColor, material.specularRoughness );\\n}\\nvoid RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\\n\\treflectedLight.indirectDiffuse +\\x3d irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\\n}\\nvoid RE_IndirectSpecular_Physical( const in vec3 radiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\\n\\treflectedLight.indirectSpecular +\\x3d radiance * BRDF_Specular_GGX_Environment( geometry, material.specularColor, material.specularRoughness );\\n}\\n#define RE_Direct\\t\\t\\t\\tRE_Direct_Physical\\n#define RE_IndirectDiffuse\\t\\tRE_IndirectDiffuse_Physical\\n#define RE_IndirectSpecular\\t\\tRE_IndirectSpecular_Physical\\n#define Material_BlinnShininessExponent( material )   GGXRoughnessToBlinnExponent( material.specularRoughness )\\nfloat computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) {\\n\\treturn saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion );\\n}\\n\";\nZ.ShaderChunk.lights_template=\"\\nGeometricContext geometry;\\ngeometry.position \\x3d - vViewPosition;\\ngeometry.normal \\x3d normal;\\ngeometry.viewDir \\x3d normalize( vViewPosition );\\nIncidentLight directLight;\\n#if ( NUM_POINT_LIGHTS \\x3e 0 ) \\x26\\x26 defined( RE_Direct )\\n\\tPointLight pointLight;\\n\\tfor ( int i \\x3d 0; i \\x3c NUM_POINT_LIGHTS; i ++ ) {\\n\\t\\tpointLight \\x3d pointLights[ i ];\\n\\t\\tgetPointDirectLightIrradiance( pointLight, geometry, directLight );\\n\\t\\t#ifdef USE_SHADOWMAP\\n\\t\\tdirectLight.color *\\x3d all( bvec2( pointLight.shadow, directLight.visible ) ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ] ) : 1.0;\\n\\t\\t#endif\\n\\t\\tRE_Direct( directLight, geometry, material, reflectedLight );\\n\\t}\\n#endif\\n#if ( NUM_SPOT_LIGHTS \\x3e 0 ) \\x26\\x26 defined( RE_Direct )\\n\\tSpotLight spotLight;\\n\\tfor ( int i \\x3d 0; i \\x3c NUM_SPOT_LIGHTS; i ++ ) {\\n\\t\\tspotLight \\x3d spotLights[ i ];\\n\\t\\tgetSpotDirectLightIrradiance( spotLight, geometry, directLight );\\n\\t\\t#ifdef USE_SHADOWMAP\\n\\t\\tdirectLight.color *\\x3d all( bvec2( spotLight.shadow, directLight.visible ) ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\\n\\t\\t#endif\\n\\t\\tRE_Direct( directLight, geometry, material, reflectedLight );\\n\\t}\\n#endif\\n#if ( NUM_DIR_LIGHTS \\x3e 0 ) \\x26\\x26 defined( RE_Direct )\\n\\tDirectionalLight directionalLight;\\n\\tfor ( int i \\x3d 0; i \\x3c NUM_DIR_LIGHTS; i ++ ) {\\n\\t\\tdirectionalLight \\x3d directionalLights[ i ];\\n\\t\\tgetDirectionalDirectLightIrradiance( directionalLight, geometry, directLight );\\n\\t\\t#ifdef USE_SHADOWMAP\\n\\t\\tdirectLight.color *\\x3d all( bvec2( directionalLight.shadow, directLight.visible ) ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\\n\\t\\t#endif\\n\\t\\tRE_Direct( directLight, geometry, material, reflectedLight );\\n\\t}\\n#endif\\n#if defined( RE_IndirectDiffuse )\\n\\tvec3 irradiance \\x3d getAmbientLightIrradiance( ambientLightColor );\\n\\t#ifdef USE_LIGHTMAP\\n\\t\\tvec3 lightMapIrradiance \\x3d texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\\n\\t\\t#ifndef PHYSICALLY_CORRECT_LIGHTS\\n\\t\\t\\tlightMapIrradiance *\\x3d PI;\\n\\t\\t#endif\\n\\t\\tirradiance +\\x3d lightMapIrradiance;\\n\\t#endif\\n\\t#if ( NUM_HEMI_LIGHTS \\x3e 0 )\\n\\t\\tfor ( int i \\x3d 0; i \\x3c NUM_HEMI_LIGHTS; i ++ ) {\\n\\t\\t\\tirradiance +\\x3d getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\\n\\t\\t}\\n\\t#endif\\n\\t#if defined( USE_ENVMAP ) \\x26\\x26 defined( PHYSICAL ) \\x26\\x26 defined( ENVMAP_TYPE_CUBE_UV )\\n\\t \\tirradiance +\\x3d getLightProbeIndirectIrradiance( geometry, 8 );\\n\\t#endif\\n\\tRE_IndirectDiffuse( irradiance, geometry, material, reflectedLight );\\n#endif\\n#if defined( USE_ENVMAP ) \\x26\\x26 defined( RE_IndirectSpecular )\\n\\tvec3 radiance \\x3d getLightProbeIndirectRadiance( geometry, Material_BlinnShininessExponent( material ), 8 );\\n\\tRE_IndirectSpecular( radiance, geometry, material, reflectedLight );\\n#endif\\n\";\nZ.ShaderChunk.logdepthbuf_fragment=\"#if defined(USE_LOGDEPTHBUF) \\x26\\x26 defined(USE_LOGDEPTHBUF_EXT)\\n\\tgl_FragDepthEXT \\x3d log2(vFragDepth) * logDepthBufFC * 0.5;\\n#endif\";Z.ShaderChunk.logdepthbuf_pars_fragment=\"#ifdef USE_LOGDEPTHBUF\\n\\tuniform float logDepthBufFC;\\n\\t#ifdef USE_LOGDEPTHBUF_EXT\\n\\t\\tvarying float vFragDepth;\\n\\t#endif\\n#endif\\n\";Z.ShaderChunk.logdepthbuf_pars_vertex=\"#ifdef USE_LOGDEPTHBUF\\n\\t#ifdef USE_LOGDEPTHBUF_EXT\\n\\t\\tvarying float vFragDepth;\\n\\t#endif\\n\\tuniform float logDepthBufFC;\\n#endif\";\nZ.ShaderChunk.logdepthbuf_vertex=\"#ifdef USE_LOGDEPTHBUF\\n\\tgl_Position.z \\x3d log2(max( EPSILON, gl_Position.w + 1.0 )) * logDepthBufFC;\\n\\t#ifdef USE_LOGDEPTHBUF_EXT\\n\\t\\tvFragDepth \\x3d 1.0 + gl_Position.w;\\n\\t#else\\n\\t\\tgl_Position.z \\x3d (gl_Position.z - 1.0) * gl_Position.w;\\n\\t#endif\\n#endif\\n\";Z.ShaderChunk.map_fragment=\"#ifdef USE_MAP\\n\\tvec4 texelColor \\x3d texture2D( map, vUv );\\n\\ttexelColor \\x3d mapTexelToLinear( texelColor );\\n\\tdiffuseColor *\\x3d texelColor;\\n#endif\\n\";\nZ.ShaderChunk.map_pars_fragment=\"#ifdef USE_MAP\\n\\tuniform sampler2D map;\\n#endif\\n\";Z.ShaderChunk.map_particle_fragment=\"#ifdef USE_MAP\\n\\tvec4 mapTexel \\x3d texture2D( map, vec2( gl_PointCoord.x, 1.0 - gl_PointCoord.y ) * offsetRepeat.zw + offsetRepeat.xy );\\n\\tdiffuseColor *\\x3d mapTexelToLinear( mapTexel );\\n#endif\\n\";Z.ShaderChunk.map_particle_pars_fragment=\"#ifdef USE_MAP\\n\\tuniform vec4 offsetRepeat;\\n\\tuniform sampler2D map;\\n#endif\\n\";Z.ShaderChunk.metalnessmap_fragment=\"float metalnessFactor \\x3d metalness;\\n#ifdef USE_METALNESSMAP\\n\\tvec4 texelMetalness \\x3d texture2D( metalnessMap, vUv );\\n\\tmetalnessFactor *\\x3d texelMetalness.r;\\n#endif\\n\";\nZ.ShaderChunk.metalnessmap_pars_fragment=\"#ifdef USE_METALNESSMAP\\n\\tuniform sampler2D metalnessMap;\\n#endif\";Z.ShaderChunk.morphnormal_vertex=\"#ifdef USE_MORPHNORMALS\\n\\tobjectNormal +\\x3d ( morphNormal0 - normal ) * morphTargetInfluences[ 0 ];\\n\\tobjectNormal +\\x3d ( morphNormal1 - normal ) * morphTargetInfluences[ 1 ];\\n\\tobjectNormal +\\x3d ( morphNormal2 - normal ) * morphTargetInfluences[ 2 ];\\n\\tobjectNormal +\\x3d ( morphNormal3 - normal ) * morphTargetInfluences[ 3 ];\\n#endif\\n\";\nZ.ShaderChunk.morphtarget_pars_vertex=\"#ifdef USE_MORPHTARGETS\\n\\t#ifndef USE_MORPHNORMALS\\n\\tuniform float morphTargetInfluences[ 8 ];\\n\\t#else\\n\\tuniform float morphTargetInfluences[ 4 ];\\n\\t#endif\\n#endif\";Z.ShaderChunk.morphtarget_vertex=\"#ifdef USE_MORPHTARGETS\\n\\ttransformed +\\x3d ( morphTarget0 - position ) * morphTargetInfluences[ 0 ];\\n\\ttransformed +\\x3d ( morphTarget1 - position ) * morphTargetInfluences[ 1 ];\\n\\ttransformed +\\x3d ( morphTarget2 - position ) * morphTargetInfluences[ 2 ];\\n\\ttransformed +\\x3d ( morphTarget3 - position ) * morphTargetInfluences[ 3 ];\\n\\t#ifndef USE_MORPHNORMALS\\n\\ttransformed +\\x3d ( morphTarget4 - position ) * morphTargetInfluences[ 4 ];\\n\\ttransformed +\\x3d ( morphTarget5 - position ) * morphTargetInfluences[ 5 ];\\n\\ttransformed +\\x3d ( morphTarget6 - position ) * morphTargetInfluences[ 6 ];\\n\\ttransformed +\\x3d ( morphTarget7 - position ) * morphTargetInfluences[ 7 ];\\n\\t#endif\\n#endif\\n\";\nZ.ShaderChunk.normal_fragment=\"#ifdef FLAT_SHADED\\n\\tvec3 fdx \\x3d vec3( dFdx( vViewPosition.x ), dFdx( vViewPosition.y ), dFdx( vViewPosition.z ) );\\n\\tvec3 fdy \\x3d vec3( dFdy( vViewPosition.x ), dFdy( vViewPosition.y ), dFdy( vViewPosition.z ) );\\n\\tvec3 normal \\x3d normalize( cross( fdx, fdy ) );\\n#else\\n\\tvec3 normal \\x3d normalize( vNormal );\\n\\t#ifdef DOUBLE_SIDED\\n\\t\\tnormal \\x3d normal * ( -1.0 + 2.0 * float( gl_FrontFacing ) );\\n\\t#endif\\n#endif\\n#ifdef USE_NORMALMAP\\n\\tnormal \\x3d perturbNormal2Arb( -vViewPosition, normal );\\n#elif defined( USE_BUMPMAP )\\n\\tnormal \\x3d perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\\n#endif\\n\";\nZ.ShaderChunk.normalmap_pars_fragment=\"#ifdef USE_NORMALMAP\\n\\tuniform sampler2D normalMap;\\n\\tuniform vec2 normalScale;\\n\\tvec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm ) {\\n\\t\\tvec3 q0 \\x3d dFdx( eye_pos.xyz );\\n\\t\\tvec3 q1 \\x3d dFdy( eye_pos.xyz );\\n\\t\\tvec2 st0 \\x3d dFdx( vUv.st );\\n\\t\\tvec2 st1 \\x3d dFdy( vUv.st );\\n\\t\\tvec3 S \\x3d normalize( q0 * st1.t - q1 * st0.t );\\n\\t\\tvec3 T \\x3d normalize( -q0 * st1.s + q1 * st0.s );\\n\\t\\tvec3 N \\x3d normalize( surf_norm );\\n\\t\\tvec3 mapN \\x3d texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\\n\\t\\tmapN.xy \\x3d normalScale * mapN.xy;\\n\\t\\tmat3 tsn \\x3d mat3( S, T, N );\\n\\t\\treturn normalize( tsn * mapN );\\n\\t}\\n#endif\\n\";\nZ.ShaderChunk.packing=\"vec3 packNormalToRGB( const in vec3 normal ) {\\n  return normalize( normal ) * 0.5 + 0.5;\\n}\\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\\n  return 1.0 - 2.0 * rgb.xyz;\\n}\\nconst float PackUpscale \\x3d 256. / 255.;const float UnpackDownscale \\x3d 255. / 256.;\\nconst vec3 PackFactors \\x3d vec3( 256. * 256. * 256., 256. * 256.,  256. );\\nconst vec4 UnpackFactors \\x3d UnpackDownscale / vec4( PackFactors, 1. );\\nconst float ShiftRight8 \\x3d 1. / 256.;\\nvec4 packDepthToRGBA( const in float v ) {\\n\\tvec4 r \\x3d vec4( fract( v * PackFactors ), v );\\n\\tr.yzw -\\x3d r.xyz * ShiftRight8;\\treturn r * PackUpscale;\\n}\\nfloat unpackRGBAToDepth( const in vec4 v ) {\\n\\treturn dot( v, UnpackFactors );\\n}\\nfloat viewZToOrthoDepth( const in float viewZ, const in float near, const in float far ) {\\n  return ( viewZ + near ) / ( near - far );\\n}\\nfloat OrthoDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) {\\n  return linearClipZ * ( near - far ) - near;\\n}\\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\\n  return (( near + viewZ ) * far ) / (( far - near ) * viewZ );\\n}\\nfloat perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) {\\n  return ( near * far ) / ( ( far - near ) * invClipZ - far );\\n}\\n\";\nZ.ShaderChunk.premultiplied_alpha_fragment=\"#ifdef PREMULTIPLIED_ALPHA\\n\\tgl_FragColor.rgb *\\x3d gl_FragColor.a;\\n#endif\\n\";Z.ShaderChunk.project_vertex=\"#ifdef USE_SKINNING\\n\\tvec4 mvPosition \\x3d modelViewMatrix * skinned;\\n#else\\n\\tvec4 mvPosition \\x3d modelViewMatrix * vec4( transformed, 1.0 );\\n#endif\\ngl_Position \\x3d projectionMatrix * mvPosition;\\n\";Z.ShaderChunk.roughnessmap_fragment=\"float roughnessFactor \\x3d roughness;\\n#ifdef USE_ROUGHNESSMAP\\n\\tvec4 texelRoughness \\x3d texture2D( roughnessMap, vUv );\\n\\troughnessFactor *\\x3d texelRoughness.r;\\n#endif\\n\";\nZ.ShaderChunk.roughnessmap_pars_fragment=\"#ifdef USE_ROUGHNESSMAP\\n\\tuniform sampler2D roughnessMap;\\n#endif\";Z.ShaderChunk.shadowmap_pars_fragment=\"#ifdef USE_SHADOWMAP\\n\\t#if NUM_DIR_LIGHTS \\x3e 0\\n\\t\\tuniform sampler2D directionalShadowMap[ NUM_DIR_LIGHTS ];\\n\\t\\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHTS ];\\n\\t#endif\\n\\t#if NUM_SPOT_LIGHTS \\x3e 0\\n\\t\\tuniform sampler2D spotShadowMap[ NUM_SPOT_LIGHTS ];\\n\\t\\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHTS ];\\n\\t#endif\\n\\t#if NUM_POINT_LIGHTS \\x3e 0\\n\\t\\tuniform sampler2D pointShadowMap[ NUM_POINT_LIGHTS ];\\n\\t\\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHTS ];\\n\\t#endif\\n\\tfloat texture2DCompare( sampler2D depths, vec2 uv, float compare ) {\\n\\t\\treturn step( compare, unpackRGBAToDepth( texture2D( depths, uv ) ) );\\n\\t}\\n\\tfloat texture2DShadowLerp( sampler2D depths, vec2 size, vec2 uv, float compare ) {\\n\\t\\tconst vec2 offset \\x3d vec2( 0.0, 1.0 );\\n\\t\\tvec2 texelSize \\x3d vec2( 1.0 ) / size;\\n\\t\\tvec2 centroidUV \\x3d floor( uv * size + 0.5 ) / size;\\n\\t\\tfloat lb \\x3d texture2DCompare( depths, centroidUV + texelSize * offset.xx, compare );\\n\\t\\tfloat lt \\x3d texture2DCompare( depths, centroidUV + texelSize * offset.xy, compare );\\n\\t\\tfloat rb \\x3d texture2DCompare( depths, centroidUV + texelSize * offset.yx, compare );\\n\\t\\tfloat rt \\x3d texture2DCompare( depths, centroidUV + texelSize * offset.yy, compare );\\n\\t\\tvec2 f \\x3d fract( uv * size + 0.5 );\\n\\t\\tfloat a \\x3d mix( lb, lt, f.y );\\n\\t\\tfloat b \\x3d mix( rb, rt, f.y );\\n\\t\\tfloat c \\x3d mix( a, b, f.x );\\n\\t\\treturn c;\\n\\t}\\n\\tfloat getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\\n\\t\\tshadowCoord.xyz /\\x3d shadowCoord.w;\\n\\t\\tshadowCoord.z +\\x3d shadowBias;\\n\\t\\tbvec4 inFrustumVec \\x3d bvec4 ( shadowCoord.x \\x3e\\x3d 0.0, shadowCoord.x \\x3c\\x3d 1.0, shadowCoord.y \\x3e\\x3d 0.0, shadowCoord.y \\x3c\\x3d 1.0 );\\n\\t\\tbool inFrustum \\x3d all( inFrustumVec );\\n\\t\\tbvec2 frustumTestVec \\x3d bvec2( inFrustum, shadowCoord.z \\x3c\\x3d 1.0 );\\n\\t\\tbool frustumTest \\x3d all( frustumTestVec );\\n\\t\\tif ( frustumTest ) {\\n\\t\\t#if defined( SHADOWMAP_TYPE_PCF )\\n\\t\\t\\tvec2 texelSize \\x3d vec2( 1.0 ) / shadowMapSize;\\n\\t\\t\\tfloat dx0 \\x3d - texelSize.x * shadowRadius;\\n\\t\\t\\tfloat dy0 \\x3d - texelSize.y * shadowRadius;\\n\\t\\t\\tfloat dx1 \\x3d + texelSize.x * shadowRadius;\\n\\t\\t\\tfloat dy1 \\x3d + texelSize.y * shadowRadius;\\n\\t\\t\\treturn (\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\\n\\t\\t\\t) * ( 1.0 / 9.0 );\\n\\t\\t#elif defined( SHADOWMAP_TYPE_PCF_SOFT )\\n\\t\\t\\tvec2 texelSize \\x3d vec2( 1.0 ) / shadowMapSize;\\n\\t\\t\\tfloat dx0 \\x3d - texelSize.x * shadowRadius;\\n\\t\\t\\tfloat dy0 \\x3d - texelSize.y * shadowRadius;\\n\\t\\t\\tfloat dx1 \\x3d + texelSize.x * shadowRadius;\\n\\t\\t\\tfloat dy1 \\x3d + texelSize.y * shadowRadius;\\n\\t\\t\\treturn (\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy, shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\\n\\t\\t\\t) * ( 1.0 / 9.0 );\\n\\t\\t#else\\n\\t\\t\\treturn texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z );\\n\\t\\t#endif\\n\\t\\t}\\n\\t\\treturn 1.0;\\n\\t}\\n\\tvec2 cubeToUV( vec3 v, float texelSizeY ) {\\n\\t\\tvec3 absV \\x3d abs( v );\\n\\t\\tfloat scaleToCube \\x3d 1.0 / max( absV.x, max( absV.y, absV.z ) );\\n\\t\\tabsV *\\x3d scaleToCube;\\n\\t\\tv *\\x3d scaleToCube * ( 1.0 - 2.0 * texelSizeY );\\n\\t\\tvec2 planar \\x3d v.xy;\\n\\t\\tfloat almostATexel \\x3d 1.5 * texelSizeY;\\n\\t\\tfloat almostOne \\x3d 1.0 - almostATexel;\\n\\t\\tif ( absV.z \\x3e\\x3d almostOne ) {\\n\\t\\t\\tif ( v.z \\x3e 0.0 )\\n\\t\\t\\t\\tplanar.x \\x3d 4.0 - v.x;\\n\\t\\t} else if ( absV.x \\x3e\\x3d almostOne ) {\\n\\t\\t\\tfloat signX \\x3d sign( v.x );\\n\\t\\t\\tplanar.x \\x3d v.z * signX + 2.0 * signX;\\n\\t\\t} else if ( absV.y \\x3e\\x3d almostOne ) {\\n\\t\\t\\tfloat signY \\x3d sign( v.y );\\n\\t\\t\\tplanar.x \\x3d v.x + 2.0 * signY + 2.0;\\n\\t\\t\\tplanar.y \\x3d v.z * signY - 2.0;\\n\\t\\t}\\n\\t\\treturn vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 );\\n\\t}\\n\\tfloat getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\\n\\t\\tvec2 texelSize \\x3d vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) );\\n\\t\\tvec3 lightToPosition \\x3d shadowCoord.xyz;\\n\\t\\tvec3 bd3D \\x3d normalize( lightToPosition );\\n\\t\\tfloat dp \\x3d ( length( lightToPosition ) - shadowBias ) / 1000.0;\\n\\t\\t#if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT )\\n\\t\\t\\tvec2 offset \\x3d vec2( - 1, 1 ) * shadowRadius * texelSize.y;\\n\\t\\t\\treturn (\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyy, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyy, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyx, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyx, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxy, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxy, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxx, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxx, texelSize.y ), dp )\\n\\t\\t\\t) * ( 1.0 / 9.0 );\\n\\t\\t#else\\n\\t\\t\\treturn texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp );\\n\\t\\t#endif\\n\\t}\\n#endif\\n\";\nZ.ShaderChunk.shadowmap_pars_vertex=\"#ifdef USE_SHADOWMAP\\n\\t#if NUM_DIR_LIGHTS \\x3e 0\\n\\t\\tuniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHTS ];\\n\\t\\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHTS ];\\n\\t#endif\\n\\t#if NUM_SPOT_LIGHTS \\x3e 0\\n\\t\\tuniform mat4 spotShadowMatrix[ NUM_SPOT_LIGHTS ];\\n\\t\\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHTS ];\\n\\t#endif\\n\\t#if NUM_POINT_LIGHTS \\x3e 0\\n\\t\\tuniform mat4 pointShadowMatrix[ NUM_POINT_LIGHTS ];\\n\\t\\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHTS ];\\n\\t#endif\\n#endif\\n\";\nZ.ShaderChunk.shadowmap_vertex=\"#ifdef USE_SHADOWMAP\\n\\t#if NUM_DIR_LIGHTS \\x3e 0\\n\\tfor ( int i \\x3d 0; i \\x3c NUM_DIR_LIGHTS; i ++ ) {\\n\\t\\tvDirectionalShadowCoord[ i ] \\x3d directionalShadowMatrix[ i ] * worldPosition;\\n\\t}\\n\\t#endif\\n\\t#if NUM_SPOT_LIGHTS \\x3e 0\\n\\tfor ( int i \\x3d 0; i \\x3c NUM_SPOT_LIGHTS; i ++ ) {\\n\\t\\tvSpotShadowCoord[ i ] \\x3d spotShadowMatrix[ i ] * worldPosition;\\n\\t}\\n\\t#endif\\n\\t#if NUM_POINT_LIGHTS \\x3e 0\\n\\tfor ( int i \\x3d 0; i \\x3c NUM_POINT_LIGHTS; i ++ ) {\\n\\t\\tvPointShadowCoord[ i ] \\x3d pointShadowMatrix[ i ] * worldPosition;\\n\\t}\\n\\t#endif\\n#endif\\n\";\nZ.ShaderChunk.shadowmask_pars_fragment=\"float getShadowMask() {\\n\\tfloat shadow \\x3d 1.0;\\n\\t#ifdef USE_SHADOWMAP\\n\\t#if NUM_DIR_LIGHTS \\x3e 0\\n\\tDirectionalLight directionalLight;\\n\\tfor ( int i \\x3d 0; i \\x3c NUM_DIR_LIGHTS; i ++ ) {\\n\\t\\tdirectionalLight \\x3d directionalLights[ i ];\\n\\t\\tshadow *\\x3d bool( directionalLight.shadow ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\\n\\t}\\n\\t#endif\\n\\t#if NUM_SPOT_LIGHTS \\x3e 0\\n\\tSpotLight spotLight;\\n\\tfor ( int i \\x3d 0; i \\x3c NUM_SPOT_LIGHTS; i ++ ) {\\n\\t\\tspotLight \\x3d spotLights[ i ];\\n\\t\\tshadow *\\x3d bool( spotLight.shadow ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\\n\\t}\\n\\t#endif\\n\\t#if NUM_POINT_LIGHTS \\x3e 0\\n\\tPointLight pointLight;\\n\\tfor ( int i \\x3d 0; i \\x3c NUM_POINT_LIGHTS; i ++ ) {\\n\\t\\tpointLight \\x3d pointLights[ i ];\\n\\t\\tshadow *\\x3d bool( pointLight.shadow ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ] ) : 1.0;\\n\\t}\\n\\t#endif\\n\\t#endif\\n\\treturn shadow;\\n}\\n\";\nZ.ShaderChunk.skinbase_vertex=\"#ifdef USE_SKINNING\\n\\tmat4 boneMatX \\x3d getBoneMatrix( skinIndex.x );\\n\\tmat4 boneMatY \\x3d getBoneMatrix( skinIndex.y );\\n\\tmat4 boneMatZ \\x3d getBoneMatrix( skinIndex.z );\\n\\tmat4 boneMatW \\x3d getBoneMatrix( skinIndex.w );\\n#endif\";Z.ShaderChunk.skinning_pars_vertex=\"#ifdef USE_SKINNING\\n\\tuniform mat4 bindMatrix;\\n\\tuniform mat4 bindMatrixInverse;\\n\\t#ifdef BONE_TEXTURE\\n\\t\\tuniform sampler2D boneTexture;\\n\\t\\tuniform int boneTextureWidth;\\n\\t\\tuniform int boneTextureHeight;\\n\\t\\tmat4 getBoneMatrix( const in float i ) {\\n\\t\\t\\tfloat j \\x3d i * 4.0;\\n\\t\\t\\tfloat x \\x3d mod( j, float( boneTextureWidth ) );\\n\\t\\t\\tfloat y \\x3d floor( j / float( boneTextureWidth ) );\\n\\t\\t\\tfloat dx \\x3d 1.0 / float( boneTextureWidth );\\n\\t\\t\\tfloat dy \\x3d 1.0 / float( boneTextureHeight );\\n\\t\\t\\ty \\x3d dy * ( y + 0.5 );\\n\\t\\t\\tvec4 v1 \\x3d texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) );\\n\\t\\t\\tvec4 v2 \\x3d texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) );\\n\\t\\t\\tvec4 v3 \\x3d texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) );\\n\\t\\t\\tvec4 v4 \\x3d texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) );\\n\\t\\t\\tmat4 bone \\x3d mat4( v1, v2, v3, v4 );\\n\\t\\t\\treturn bone;\\n\\t\\t}\\n\\t#else\\n\\t\\tuniform mat4 boneMatrices[ MAX_BONES ];\\n\\t\\tmat4 getBoneMatrix( const in float i ) {\\n\\t\\t\\tmat4 bone \\x3d boneMatrices[ int(i) ];\\n\\t\\t\\treturn bone;\\n\\t\\t}\\n\\t#endif\\n#endif\\n\";\nZ.ShaderChunk.skinning_vertex=\"#ifdef USE_SKINNING\\n\\tvec4 skinVertex \\x3d bindMatrix * vec4( transformed, 1.0 );\\n\\tvec4 skinned \\x3d vec4( 0.0 );\\n\\tskinned +\\x3d boneMatX * skinVertex * skinWeight.x;\\n\\tskinned +\\x3d boneMatY * skinVertex * skinWeight.y;\\n\\tskinned +\\x3d boneMatZ * skinVertex * skinWeight.z;\\n\\tskinned +\\x3d boneMatW * skinVertex * skinWeight.w;\\n\\tskinned  \\x3d bindMatrixInverse * skinned;\\n#endif\\n\";Z.ShaderChunk.skinnormal_vertex=\"#ifdef USE_SKINNING\\n\\tmat4 skinMatrix \\x3d mat4( 0.0 );\\n\\tskinMatrix +\\x3d skinWeight.x * boneMatX;\\n\\tskinMatrix +\\x3d skinWeight.y * boneMatY;\\n\\tskinMatrix +\\x3d skinWeight.z * boneMatZ;\\n\\tskinMatrix +\\x3d skinWeight.w * boneMatW;\\n\\tskinMatrix  \\x3d bindMatrixInverse * skinMatrix * bindMatrix;\\n\\tobjectNormal \\x3d vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz;\\n#endif\\n\";\nZ.ShaderChunk.specularmap_fragment=\"float specularStrength;\\n#ifdef USE_SPECULARMAP\\n\\tvec4 texelSpecular \\x3d texture2D( specularMap, vUv );\\n\\tspecularStrength \\x3d texelSpecular.r;\\n#else\\n\\tspecularStrength \\x3d 1.0;\\n#endif\";Z.ShaderChunk.specularmap_pars_fragment=\"#ifdef USE_SPECULARMAP\\n\\tuniform sampler2D specularMap;\\n#endif\";Z.ShaderChunk.tonemapping_fragment=\"#if defined( TONE_MAPPING )\\n  gl_FragColor.rgb \\x3d toneMapping( gl_FragColor.rgb );\\n#endif\\n\";\nZ.ShaderChunk.tonemapping_pars_fragment=\"#define saturate(a) clamp( a, 0.0, 1.0 )\\nuniform float toneMappingExposure;\\nuniform float toneMappingWhitePoint;\\nvec3 LinearToneMapping( vec3 color ) {\\n  return toneMappingExposure * color;\\n}\\nvec3 ReinhardToneMapping( vec3 color ) {\\n  color *\\x3d toneMappingExposure;\\n  return saturate( color / ( vec3( 1.0 ) + color ) );\\n}\\n#define Uncharted2Helper( x ) max( ( ( x * ( 0.15 * x + 0.10 * 0.50 ) + 0.20 * 0.02 ) / ( x * ( 0.15 * x + 0.50 ) + 0.20 * 0.30 ) ) - 0.02 / 0.30, vec3( 0.0 ) )\\nvec3 Uncharted2ToneMapping( vec3 color ) {\\n  color *\\x3d toneMappingExposure;\\n  return saturate( Uncharted2Helper( color ) / Uncharted2Helper( vec3( toneMappingWhitePoint ) ) );\\n}\\nvec3 OptimizedCineonToneMapping( vec3 color ) {\\n  color *\\x3d toneMappingExposure;\\n  color \\x3d max( vec3( 0.0 ), color - 0.004 );\\n  return pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\\n}\\n\";\nZ.ShaderChunk.uv2_pars_fragment=\"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\\n\\tvarying vec2 vUv2;\\n#endif\";Z.ShaderChunk.uv2_pars_vertex=\"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\\n\\tattribute vec2 uv2;\\n\\tvarying vec2 vUv2;\\n#endif\";Z.ShaderChunk.uv2_vertex=\"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\\n\\tvUv2 \\x3d uv2;\\n#endif\";Z.ShaderChunk.uv_pars_fragment=\"#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\\n\\tvarying vec2 vUv;\\n#endif\";\nZ.ShaderChunk.uv_pars_vertex=\"#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\\n\\tvarying vec2 vUv;\\n\\tuniform vec4 offsetRepeat;\\n#endif\\n\";Z.ShaderChunk.uv_vertex=\"#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\\n\\tvUv \\x3d uv * offsetRepeat.zw + offsetRepeat.xy;\\n#endif\";\nZ.ShaderChunk.worldpos_vertex=\"#if defined( USE_ENVMAP ) || defined( PHONG ) || defined( PHYSICAL ) || defined( LAMBERT ) || defined ( USE_SHADOWMAP )\\n\\t#ifdef USE_SKINNING\\n\\t\\tvec4 worldPosition \\x3d modelMatrix * skinned;\\n\\t#else\\n\\t\\tvec4 worldPosition \\x3d modelMatrix * vec4( transformed, 1.0 );\\n\\t#endif\\n#endif\\n\";\nZ.UniformsUtils={merge:function(a){for(var b={},c=0;c<a.length;c++){var d=this.clone(a[c]),e;for(e in d)b[e]=d[e]}return b},clone:function(a){var b={},c;for(c in a){b[c]={};for(var d in a[c]){var e=a[c][d];b[c][d]=e instanceof Z.Color||e instanceof Z.Vector2||e instanceof Z.Vector3||e instanceof Z.Vector4||e instanceof Z.Matrix3||e instanceof Z.Matrix4||e instanceof Z.Texture?e.clone():Array.isArray(e)?e.slice():e}}return b}};\nZ.UniformsLib={common:{diffuse:{type:\"c\",value:new Z.Color(15658734)},opacity:{type:\"1f\",value:1},map:{type:\"t\",value:null},offsetRepeat:{type:\"v4\",value:new Z.Vector4(0,0,1,1)},specularMap:{type:\"t\",value:null},alphaMap:{type:\"t\",value:null},envMap:{type:\"t\",value:null},flipEnvMap:{type:\"1f\",value:-1},reflectivity:{type:\"1f\",value:1},refractionRatio:{type:\"1f\",value:.98}},aomap:{aoMap:{type:\"t\",value:null},aoMapIntensity:{type:\"1f\",value:1}},lightmap:{lightMap:{type:\"t\",value:null},lightMapIntensity:{type:\"1f\",\nvalue:1}},emissivemap:{emissiveMap:{type:\"t\",value:null}},bumpmap:{bumpMap:{type:\"t\",value:null},bumpScale:{type:\"1f\",value:1}},normalmap:{normalMap:{type:\"t\",value:null},normalScale:{type:\"v2\",value:new Z.Vector2(1,1)}},displacementmap:{displacementMap:{type:\"t\",value:null},displacementScale:{type:\"1f\",value:1},displacementBias:{type:\"1f\",value:0}},roughnessmap:{roughnessMap:{type:\"t\",value:null}},metalnessmap:{metalnessMap:{type:\"t\",value:null}},fog:{fogDensity:{type:\"1f\",value:2.5E-4},fogNear:{type:\"1f\",\nvalue:1},fogFar:{type:\"1f\",value:2E3},fogColor:{type:\"c\",value:new Z.Color(16777215)}},lights:{ambientLightColor:{type:\"3fv\",value:[]},directionalLights:{type:\"sa\",value:[],properties:{direction:{type:\"v3\"},color:{type:\"c\"},shadow:{type:\"1i\"},shadowBias:{type:\"1f\"},shadowRadius:{type:\"1f\"},shadowMapSize:{type:\"v2\"}}},directionalShadowMap:{type:\"tv\",value:[]},directionalShadowMatrix:{type:\"m4v\",value:[]},spotLights:{type:\"sa\",value:[],properties:{color:{type:\"c\"},position:{type:\"v3\"},direction:{type:\"v3\"},\ndistance:{type:\"1f\"},coneCos:{type:\"1f\"},penumbraCos:{type:\"1f\"},decay:{type:\"1f\"},shadow:{type:\"1i\"},shadowBias:{type:\"1f\"},shadowRadius:{type:\"1f\"},shadowMapSize:{type:\"v2\"}}},spotShadowMap:{type:\"tv\",value:[]},spotShadowMatrix:{type:\"m4v\",value:[]},pointLights:{type:\"sa\",value:[],properties:{color:{type:\"c\"},position:{type:\"v3\"},decay:{type:\"1f\"},distance:{type:\"1f\"},shadow:{type:\"1i\"},shadowBias:{type:\"1f\"},shadowRadius:{type:\"1f\"},shadowMapSize:{type:\"v2\"}}},pointShadowMap:{type:\"tv\",value:[]},\npointShadowMatrix:{type:\"m4v\",value:[]},hemisphereLights:{type:\"sa\",value:[],properties:{direction:{type:\"v3\"},skyColor:{type:\"c\"},groundColor:{type:\"c\"}}}},points:{diffuse:{type:\"c\",value:new Z.Color(15658734)},opacity:{type:\"1f\",value:1},size:{type:\"1f\",value:1},scale:{type:\"1f\",value:1},map:{type:\"t\",value:null},offsetRepeat:{type:\"v4\",value:new Z.Vector4(0,0,1,1)}}};Z.ShaderChunk.cube_frag=\"uniform samplerCube tCube;\\nuniform float tFlip;\\nvarying vec3 vWorldPosition;\\n#include \\x3ccommon\\x3e\\n#include \\x3clogdepthbuf_pars_fragment\\x3e\\n#include \\x3cclipping_planes_pars_fragment\\x3e\\nvoid main() {\\n\\t#include \\x3cclipping_planes_fragment\\x3e\\n\\tgl_FragColor \\x3d textureCube( tCube, vec3( tFlip * vWorldPosition.x, vWorldPosition.yz ) );\\n\\t#include \\x3clogdepthbuf_fragment\\x3e\\n}\\n\";\nZ.ShaderChunk.cube_vert=\"varying vec3 vWorldPosition;\\n#include \\x3ccommon\\x3e\\n#include \\x3clogdepthbuf_pars_vertex\\x3e\\n#include \\x3cclipping_planes_pars_vertex\\x3e\\nvoid main() {\\n\\tvWorldPosition \\x3d transformDirection( position, modelMatrix );\\n\\t#include \\x3cbegin_vertex\\x3e\\n\\t#include \\x3cproject_vertex\\x3e\\n\\t#include \\x3clogdepthbuf_vertex\\x3e\\n\\t#include \\x3cclipping_planes_vertex\\x3e\\n}\\n\";Z.ShaderChunk.depth_frag=\"#if DEPTH_PACKING \\x3d\\x3d 3200\\n\\tuniform float opacity;\\n#endif\\n#include \\x3ccommon\\x3e\\n#include \\x3cpacking\\x3e\\n#include \\x3cuv_pars_fragment\\x3e\\n#include \\x3cmap_pars_fragment\\x3e\\n#include \\x3calphamap_pars_fragment\\x3e\\n#include \\x3clogdepthbuf_pars_fragment\\x3e\\n#include \\x3cclipping_planes_pars_fragment\\x3e\\nvoid main() {\\n\\t#include \\x3cclipping_planes_fragment\\x3e\\n\\tvec4 diffuseColor \\x3d vec4( 1.0 );\\n\\t#if DEPTH_PACKING \\x3d\\x3d 3200\\n\\t\\tdiffuseColor.a \\x3d opacity;\\n\\t#endif\\n\\t#include \\x3cmap_fragment\\x3e\\n\\t#include \\x3calphamap_fragment\\x3e\\n\\t#include \\x3calphatest_fragment\\x3e\\n\\t#include \\x3clogdepthbuf_fragment\\x3e\\n\\t#if DEPTH_PACKING \\x3d\\x3d 3200\\n\\t\\tgl_FragColor \\x3d vec4( vec3( gl_FragCoord.z ), opacity );\\n\\t#elif DEPTH_PACKING \\x3d\\x3d 3201\\n\\t\\tgl_FragColor \\x3d packDepthToRGBA( gl_FragCoord.z );\\n\\t#endif\\n}\\n\";\nZ.ShaderChunk.depth_vert=\"#include \\x3ccommon\\x3e\\n#include \\x3cuv_pars_vertex\\x3e\\n#include \\x3cdisplacementmap_pars_vertex\\x3e\\n#include \\x3cmorphtarget_pars_vertex\\x3e\\n#include \\x3cskinning_pars_vertex\\x3e\\n#include \\x3clogdepthbuf_pars_vertex\\x3e\\n#include \\x3cclipping_planes_pars_vertex\\x3e\\nvoid main() {\\n\\t#include \\x3cuv_vertex\\x3e\\n\\t#include \\x3cskinbase_vertex\\x3e\\n\\t#include \\x3cbegin_vertex\\x3e\\n\\t#include \\x3cdisplacementmap_vertex\\x3e\\n\\t#include \\x3cmorphtarget_vertex\\x3e\\n\\t#include \\x3cskinning_vertex\\x3e\\n\\t#include \\x3cproject_vertex\\x3e\\n\\t#include \\x3clogdepthbuf_vertex\\x3e\\n\\t#include \\x3cclipping_planes_vertex\\x3e\\n}\\n\";\nZ.ShaderChunk.distanceRGBA_frag=\"uniform vec3 lightPos;\\nvarying vec4 vWorldPosition;\\n#include \\x3ccommon\\x3e\\n#include \\x3cpacking\\x3e\\n#include \\x3cclipping_planes_pars_fragment\\x3e\\nvoid main () {\\n\\t#include \\x3cclipping_planes_fragment\\x3e\\n\\tgl_FragColor \\x3d packDepthToRGBA( length( vWorldPosition.xyz - lightPos.xyz ) / 1000.0 );\\n}\\n\";Z.ShaderChunk.distanceRGBA_vert=\"varying vec4 vWorldPosition;\\n#include \\x3ccommon\\x3e\\n#include \\x3cmorphtarget_pars_vertex\\x3e\\n#include \\x3cskinning_pars_vertex\\x3e\\n#include \\x3cclipping_planes_pars_vertex\\x3e\\nvoid main() {\\n\\t#include \\x3cskinbase_vertex\\x3e\\n\\t#include \\x3cbegin_vertex\\x3e\\n\\t#include \\x3cmorphtarget_vertex\\x3e\\n\\t#include \\x3cskinning_vertex\\x3e\\n\\t#include \\x3cproject_vertex\\x3e\\n\\t#include \\x3cworldpos_vertex\\x3e\\n\\t#include \\x3cclipping_planes_vertex\\x3e\\n\\tvWorldPosition \\x3d worldPosition;\\n}\\n\";\nZ.ShaderChunk.equirect_frag=\"uniform sampler2D tEquirect;\\nuniform float tFlip;\\nvarying vec3 vWorldPosition;\\n#include \\x3ccommon\\x3e\\n#include \\x3clogdepthbuf_pars_fragment\\x3e\\n#include \\x3cclipping_planes_pars_fragment\\x3e\\nvoid main() {\\n\\t#include \\x3cclipping_planes_fragment\\x3e\\n\\tvec3 direction \\x3d normalize( vWorldPosition );\\n\\tvec2 sampleUV;\\n\\tsampleUV.y \\x3d saturate( tFlip * direction.y * -0.5 + 0.5 );\\n\\tsampleUV.x \\x3d atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;\\n\\tgl_FragColor \\x3d texture2D( tEquirect, sampleUV );\\n\\t#include \\x3clogdepthbuf_fragment\\x3e\\n}\\n\";\nZ.ShaderChunk.equirect_vert=\"varying vec3 vWorldPosition;\\n#include \\x3ccommon\\x3e\\n#include \\x3clogdepthbuf_pars_vertex\\x3e\\n#include \\x3cclipping_planes_pars_vertex\\x3e\\nvoid main() {\\n\\tvWorldPosition \\x3d transformDirection( position, modelMatrix );\\n\\t#include \\x3cbegin_vertex\\x3e\\n\\t#include \\x3cproject_vertex\\x3e\\n\\t#include \\x3clogdepthbuf_vertex\\x3e\\n\\t#include \\x3cclipping_planes_vertex\\x3e\\n}\\n\";Z.ShaderChunk.linedashed_frag=\"uniform vec3 diffuse;\\nuniform float opacity;\\nuniform float dashSize;\\nuniform float totalSize;\\nvarying float vLineDistance;\\n#include \\x3ccommon\\x3e\\n#include \\x3ccolor_pars_fragment\\x3e\\n#include \\x3cfog_pars_fragment\\x3e\\n#include \\x3clogdepthbuf_pars_fragment\\x3e\\n#include \\x3cclipping_planes_pars_fragment\\x3e\\nvoid main() {\\n\\t#include \\x3cclipping_planes_fragment\\x3e\\n\\tif ( mod( vLineDistance, totalSize ) \\x3e dashSize ) {\\n\\t\\tdiscard;\\n\\t}\\n\\tvec3 outgoingLight \\x3d vec3( 0.0 );\\n\\tvec4 diffuseColor \\x3d vec4( diffuse, opacity );\\n\\t#include \\x3clogdepthbuf_fragment\\x3e\\n\\t#include \\x3ccolor_fragment\\x3e\\n\\toutgoingLight \\x3d diffuseColor.rgb;\\n\\tgl_FragColor \\x3d vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\x3cpremultiplied_alpha_fragment\\x3e\\n\\t#include \\x3ctonemapping_fragment\\x3e\\n\\t#include \\x3cencodings_fragment\\x3e\\n\\t#include \\x3cfog_fragment\\x3e\\n}\\n\";\nZ.ShaderChunk.linedashed_vert=\"uniform float scale;\\nattribute float lineDistance;\\nvarying float vLineDistance;\\n#include \\x3ccommon\\x3e\\n#include \\x3ccolor_pars_vertex\\x3e\\n#include \\x3clogdepthbuf_pars_vertex\\x3e\\n#include \\x3cclipping_planes_pars_vertex\\x3e\\nvoid main() {\\n\\t#include \\x3ccolor_vertex\\x3e\\n\\tvLineDistance \\x3d scale * lineDistance;\\n\\tvec4 mvPosition \\x3d modelViewMatrix * vec4( position, 1.0 );\\n\\tgl_Position \\x3d projectionMatrix * mvPosition;\\n\\t#include \\x3clogdepthbuf_vertex\\x3e\\n\\t#include \\x3cclipping_planes_vertex\\x3e\\n}\\n\";\nZ.ShaderChunk.meshbasic_frag=\"uniform vec3 diffuse;\\nuniform float opacity;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\x3ccommon\\x3e\\n#include \\x3ccolor_pars_fragment\\x3e\\n#include \\x3cuv_pars_fragment\\x3e\\n#include \\x3cuv2_pars_fragment\\x3e\\n#include \\x3cmap_pars_fragment\\x3e\\n#include \\x3calphamap_pars_fragment\\x3e\\n#include \\x3caomap_pars_fragment\\x3e\\n#include \\x3cenvmap_pars_fragment\\x3e\\n#include \\x3cfog_pars_fragment\\x3e\\n#include \\x3cspecularmap_pars_fragment\\x3e\\n#include \\x3clogdepthbuf_pars_fragment\\x3e\\n#include \\x3cclipping_planes_pars_fragment\\x3e\\nvoid main() {\\n\\t#include \\x3cclipping_planes_fragment\\x3e\\n\\tvec4 diffuseColor \\x3d vec4( diffuse, opacity );\\n\\t#include \\x3clogdepthbuf_fragment\\x3e\\n\\t#include \\x3cmap_fragment\\x3e\\n\\t#include \\x3ccolor_fragment\\x3e\\n\\t#include \\x3calphamap_fragment\\x3e\\n\\t#include \\x3calphatest_fragment\\x3e\\n\\t#include \\x3cspecularmap_fragment\\x3e\\n\\tReflectedLight reflectedLight;\\n\\treflectedLight.directDiffuse \\x3d vec3( 0.0 );\\n\\treflectedLight.directSpecular \\x3d vec3( 0.0 );\\n\\treflectedLight.indirectDiffuse \\x3d diffuseColor.rgb;\\n\\treflectedLight.indirectSpecular \\x3d vec3( 0.0 );\\n\\t#include \\x3caomap_fragment\\x3e\\n\\tvec3 outgoingLight \\x3d reflectedLight.indirectDiffuse;\\n\\t#include \\x3cenvmap_fragment\\x3e\\n\\tgl_FragColor \\x3d vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\x3cpremultiplied_alpha_fragment\\x3e\\n\\t#include \\x3ctonemapping_fragment\\x3e\\n\\t#include \\x3cencodings_fragment\\x3e\\n\\t#include \\x3cfog_fragment\\x3e\\n}\\n\";\nZ.ShaderChunk.meshbasic_vert=\"#include \\x3ccommon\\x3e\\n#include \\x3cuv_pars_vertex\\x3e\\n#include \\x3cuv2_pars_vertex\\x3e\\n#include \\x3cenvmap_pars_vertex\\x3e\\n#include \\x3ccolor_pars_vertex\\x3e\\n#include \\x3cmorphtarget_pars_vertex\\x3e\\n#include \\x3cskinning_pars_vertex\\x3e\\n#include \\x3clogdepthbuf_pars_vertex\\x3e\\n#include \\x3cclipping_planes_pars_vertex\\x3e\\nvoid main() {\\n\\t#include \\x3cuv_vertex\\x3e\\n\\t#include \\x3cuv2_vertex\\x3e\\n\\t#include \\x3ccolor_vertex\\x3e\\n\\t#include \\x3cskinbase_vertex\\x3e\\n\\t#ifdef USE_ENVMAP\\n\\t#include \\x3cbeginnormal_vertex\\x3e\\n\\t#include \\x3cmorphnormal_vertex\\x3e\\n\\t#include \\x3cskinnormal_vertex\\x3e\\n\\t#include \\x3cdefaultnormal_vertex\\x3e\\n\\t#endif\\n\\t#include \\x3cbegin_vertex\\x3e\\n\\t#include \\x3cmorphtarget_vertex\\x3e\\n\\t#include \\x3cskinning_vertex\\x3e\\n\\t#include \\x3cproject_vertex\\x3e\\n\\t#include \\x3clogdepthbuf_vertex\\x3e\\n\\t#include \\x3cworldpos_vertex\\x3e\\n\\t#include \\x3cclipping_planes_vertex\\x3e\\n\\t#include \\x3cenvmap_vertex\\x3e\\n}\\n\";\nZ.ShaderChunk.meshlambert_frag=\"uniform vec3 diffuse;\\nuniform vec3 emissive;\\nuniform float opacity;\\nvarying vec3 vLightFront;\\n#ifdef DOUBLE_SIDED\\n\\tvarying vec3 vLightBack;\\n#endif\\n#include \\x3ccommon\\x3e\\n#include \\x3cpacking\\x3e\\n#include \\x3ccolor_pars_fragment\\x3e\\n#include \\x3cuv_pars_fragment\\x3e\\n#include \\x3cuv2_pars_fragment\\x3e\\n#include \\x3cmap_pars_fragment\\x3e\\n#include \\x3calphamap_pars_fragment\\x3e\\n#include \\x3caomap_pars_fragment\\x3e\\n#include \\x3clightmap_pars_fragment\\x3e\\n#include \\x3cemissivemap_pars_fragment\\x3e\\n#include \\x3cenvmap_pars_fragment\\x3e\\n#include \\x3cbsdfs\\x3e\\n#include \\x3clights_pars\\x3e\\n#include \\x3cfog_pars_fragment\\x3e\\n#include \\x3cshadowmap_pars_fragment\\x3e\\n#include \\x3cshadowmask_pars_fragment\\x3e\\n#include \\x3cspecularmap_pars_fragment\\x3e\\n#include \\x3clogdepthbuf_pars_fragment\\x3e\\n#include \\x3cclipping_planes_pars_fragment\\x3e\\nvoid main() {\\n\\t#include \\x3cclipping_planes_fragment\\x3e\\n\\tvec4 diffuseColor \\x3d vec4( diffuse, opacity );\\n\\tReflectedLight reflectedLight \\x3d ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\\n\\tvec3 totalEmissiveRadiance \\x3d emissive;\\n\\t#include \\x3clogdepthbuf_fragment\\x3e\\n\\t#include \\x3cmap_fragment\\x3e\\n\\t#include \\x3ccolor_fragment\\x3e\\n\\t#include \\x3calphamap_fragment\\x3e\\n\\t#include \\x3calphatest_fragment\\x3e\\n\\t#include \\x3cspecularmap_fragment\\x3e\\n\\t#include \\x3cemissivemap_fragment\\x3e\\n\\treflectedLight.indirectDiffuse \\x3d getAmbientLightIrradiance( ambientLightColor );\\n\\t#include \\x3clightmap_fragment\\x3e\\n\\treflectedLight.indirectDiffuse *\\x3d BRDF_Diffuse_Lambert( diffuseColor.rgb );\\n\\t#ifdef DOUBLE_SIDED\\n\\t\\treflectedLight.directDiffuse \\x3d ( gl_FrontFacing ) ? vLightFront : vLightBack;\\n\\t#else\\n\\t\\treflectedLight.directDiffuse \\x3d vLightFront;\\n\\t#endif\\n\\treflectedLight.directDiffuse *\\x3d BRDF_Diffuse_Lambert( diffuseColor.rgb ) * getShadowMask();\\n\\t#include \\x3caomap_fragment\\x3e\\n\\tvec3 outgoingLight \\x3d reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\\n\\t#include \\x3cenvmap_fragment\\x3e\\n\\tgl_FragColor \\x3d vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\x3cpremultiplied_alpha_fragment\\x3e\\n\\t#include \\x3ctonemapping_fragment\\x3e\\n\\t#include \\x3cencodings_fragment\\x3e\\n\\t#include \\x3cfog_fragment\\x3e\\n}\\n\";\nZ.ShaderChunk.meshlambert_vert=\"#define LAMBERT\\nvarying vec3 vLightFront;\\n#ifdef DOUBLE_SIDED\\n\\tvarying vec3 vLightBack;\\n#endif\\n#include \\x3ccommon\\x3e\\n#include \\x3cuv_pars_vertex\\x3e\\n#include \\x3cuv2_pars_vertex\\x3e\\n#include \\x3cenvmap_pars_vertex\\x3e\\n#include \\x3cbsdfs\\x3e\\n#include \\x3clights_pars\\x3e\\n#include \\x3ccolor_pars_vertex\\x3e\\n#include \\x3cmorphtarget_pars_vertex\\x3e\\n#include \\x3cskinning_pars_vertex\\x3e\\n#include \\x3cshadowmap_pars_vertex\\x3e\\n#include \\x3clogdepthbuf_pars_vertex\\x3e\\n#include \\x3cclipping_planes_pars_vertex\\x3e\\nvoid main() {\\n\\t#include \\x3cuv_vertex\\x3e\\n\\t#include \\x3cuv2_vertex\\x3e\\n\\t#include \\x3ccolor_vertex\\x3e\\n\\t#include \\x3cbeginnormal_vertex\\x3e\\n\\t#include \\x3cmorphnormal_vertex\\x3e\\n\\t#include \\x3cskinbase_vertex\\x3e\\n\\t#include \\x3cskinnormal_vertex\\x3e\\n\\t#include \\x3cdefaultnormal_vertex\\x3e\\n\\t#include \\x3cbegin_vertex\\x3e\\n\\t#include \\x3cmorphtarget_vertex\\x3e\\n\\t#include \\x3cskinning_vertex\\x3e\\n\\t#include \\x3cproject_vertex\\x3e\\n\\t#include \\x3clogdepthbuf_vertex\\x3e\\n\\t#include \\x3cclipping_planes_vertex\\x3e\\n\\t#include \\x3cworldpos_vertex\\x3e\\n\\t#include \\x3cenvmap_vertex\\x3e\\n\\t#include \\x3clights_lambert_vertex\\x3e\\n\\t#include \\x3cshadowmap_vertex\\x3e\\n}\\n\";\nZ.ShaderChunk.meshphong_frag=\"#define PHONG\\nuniform vec3 diffuse;\\nuniform vec3 emissive;\\nuniform vec3 specular;\\nuniform float shininess;\\nuniform float opacity;\\n#include \\x3ccommon\\x3e\\n#include \\x3cpacking\\x3e\\n#include \\x3ccolor_pars_fragment\\x3e\\n#include \\x3cuv_pars_fragment\\x3e\\n#include \\x3cuv2_pars_fragment\\x3e\\n#include \\x3cmap_pars_fragment\\x3e\\n#include \\x3calphamap_pars_fragment\\x3e\\n#include \\x3caomap_pars_fragment\\x3e\\n#include \\x3clightmap_pars_fragment\\x3e\\n#include \\x3cemissivemap_pars_fragment\\x3e\\n#include \\x3cenvmap_pars_fragment\\x3e\\n#include \\x3cfog_pars_fragment\\x3e\\n#include \\x3cbsdfs\\x3e\\n#include \\x3clights_pars\\x3e\\n#include \\x3clights_phong_pars_fragment\\x3e\\n#include \\x3cshadowmap_pars_fragment\\x3e\\n#include \\x3cbumpmap_pars_fragment\\x3e\\n#include \\x3cnormalmap_pars_fragment\\x3e\\n#include \\x3cspecularmap_pars_fragment\\x3e\\n#include \\x3clogdepthbuf_pars_fragment\\x3e\\n#include \\x3cclipping_planes_pars_fragment\\x3e\\nvoid main() {\\n\\t#include \\x3cclipping_planes_fragment\\x3e\\n\\tvec4 diffuseColor \\x3d vec4( diffuse, opacity );\\n\\tReflectedLight reflectedLight \\x3d ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\\n\\tvec3 totalEmissiveRadiance \\x3d emissive;\\n\\t#include \\x3clogdepthbuf_fragment\\x3e\\n\\t#include \\x3cmap_fragment\\x3e\\n\\t#include \\x3ccolor_fragment\\x3e\\n\\t#include \\x3calphamap_fragment\\x3e\\n\\t#include \\x3calphatest_fragment\\x3e\\n\\t#include \\x3cspecularmap_fragment\\x3e\\n\\t#include \\x3cnormal_fragment\\x3e\\n\\t#include \\x3cemissivemap_fragment\\x3e\\n\\t#include \\x3clights_phong_fragment\\x3e\\n\\t#include \\x3clights_template\\x3e\\n\\t#include \\x3caomap_fragment\\x3e\\n\\tvec3 outgoingLight \\x3d reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\\n\\t#include \\x3cenvmap_fragment\\x3e\\n\\tgl_FragColor \\x3d vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\x3cpremultiplied_alpha_fragment\\x3e\\n\\t#include \\x3ctonemapping_fragment\\x3e\\n\\t#include \\x3cencodings_fragment\\x3e\\n\\t#include \\x3cfog_fragment\\x3e\\n}\\n\";\nZ.ShaderChunk.meshphong_vert=\"#define PHONG\\nvarying vec3 vViewPosition;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\x3ccommon\\x3e\\n#include \\x3cuv_pars_vertex\\x3e\\n#include \\x3cuv2_pars_vertex\\x3e\\n#include \\x3cdisplacementmap_pars_vertex\\x3e\\n#include \\x3cenvmap_pars_vertex\\x3e\\n#include \\x3ccolor_pars_vertex\\x3e\\n#include \\x3cmorphtarget_pars_vertex\\x3e\\n#include \\x3cskinning_pars_vertex\\x3e\\n#include \\x3cshadowmap_pars_vertex\\x3e\\n#include \\x3clogdepthbuf_pars_vertex\\x3e\\n#include \\x3cclipping_planes_pars_vertex\\x3e\\nvoid main() {\\n\\t#include \\x3cuv_vertex\\x3e\\n\\t#include \\x3cuv2_vertex\\x3e\\n\\t#include \\x3ccolor_vertex\\x3e\\n\\t#include \\x3cbeginnormal_vertex\\x3e\\n\\t#include \\x3cmorphnormal_vertex\\x3e\\n\\t#include \\x3cskinbase_vertex\\x3e\\n\\t#include \\x3cskinnormal_vertex\\x3e\\n\\t#include \\x3cdefaultnormal_vertex\\x3e\\n#ifndef FLAT_SHADED\\n\\tvNormal \\x3d normalize( transformedNormal );\\n#endif\\n\\t#include \\x3cbegin_vertex\\x3e\\n\\t#include \\x3cdisplacementmap_vertex\\x3e\\n\\t#include \\x3cmorphtarget_vertex\\x3e\\n\\t#include \\x3cskinning_vertex\\x3e\\n\\t#include \\x3cproject_vertex\\x3e\\n\\t#include \\x3clogdepthbuf_vertex\\x3e\\n\\t#include \\x3cclipping_planes_vertex\\x3e\\n\\tvViewPosition \\x3d - mvPosition.xyz;\\n\\t#include \\x3cworldpos_vertex\\x3e\\n\\t#include \\x3cenvmap_vertex\\x3e\\n\\t#include \\x3cshadowmap_vertex\\x3e\\n}\\n\";\nZ.ShaderChunk.meshphysical_frag=\"#define PHYSICAL\\nuniform vec3 diffuse;\\nuniform vec3 emissive;\\nuniform float roughness;\\nuniform float metalness;\\nuniform float opacity;\\nuniform float envMapIntensity;\\nvarying vec3 vViewPosition;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\x3ccommon\\x3e\\n#include \\x3cpacking\\x3e\\n#include \\x3ccolor_pars_fragment\\x3e\\n#include \\x3cuv_pars_fragment\\x3e\\n#include \\x3cuv2_pars_fragment\\x3e\\n#include \\x3cmap_pars_fragment\\x3e\\n#include \\x3calphamap_pars_fragment\\x3e\\n#include \\x3caomap_pars_fragment\\x3e\\n#include \\x3clightmap_pars_fragment\\x3e\\n#include \\x3cemissivemap_pars_fragment\\x3e\\n#include \\x3cenvmap_pars_fragment\\x3e\\n#include \\x3cfog_pars_fragment\\x3e\\n#include \\x3cbsdfs\\x3e\\n#include \\x3ccube_uv_reflection_fragment\\x3e\\n#include \\x3clights_pars\\x3e\\n#include \\x3clights_physical_pars_fragment\\x3e\\n#include \\x3cshadowmap_pars_fragment\\x3e\\n#include \\x3cbumpmap_pars_fragment\\x3e\\n#include \\x3cnormalmap_pars_fragment\\x3e\\n#include \\x3croughnessmap_pars_fragment\\x3e\\n#include \\x3cmetalnessmap_pars_fragment\\x3e\\n#include \\x3clogdepthbuf_pars_fragment\\x3e\\n#include \\x3cclipping_planes_pars_fragment\\x3e\\nvoid main() {\\n\\t#include \\x3cclipping_planes_fragment\\x3e\\n\\tvec4 diffuseColor \\x3d vec4( diffuse, opacity );\\n\\tReflectedLight reflectedLight \\x3d ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\\n\\tvec3 totalEmissiveRadiance \\x3d emissive;\\n\\t#include \\x3clogdepthbuf_fragment\\x3e\\n\\t#include \\x3cmap_fragment\\x3e\\n\\t#include \\x3ccolor_fragment\\x3e\\n\\t#include \\x3calphamap_fragment\\x3e\\n\\t#include \\x3calphatest_fragment\\x3e\\n\\t#include \\x3cspecularmap_fragment\\x3e\\n\\t#include \\x3croughnessmap_fragment\\x3e\\n\\t#include \\x3cmetalnessmap_fragment\\x3e\\n\\t#include \\x3cnormal_fragment\\x3e\\n\\t#include \\x3cemissivemap_fragment\\x3e\\n\\t#include \\x3clights_physical_fragment\\x3e\\n\\t#include \\x3clights_template\\x3e\\n\\t#include \\x3caomap_fragment\\x3e\\n\\tvec3 outgoingLight \\x3d reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\\n\\tgl_FragColor \\x3d vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\x3cpremultiplied_alpha_fragment\\x3e\\n\\t#include \\x3ctonemapping_fragment\\x3e\\n\\t#include \\x3cencodings_fragment\\x3e\\n\\t#include \\x3cfog_fragment\\x3e\\n}\\n\";\nZ.ShaderChunk.meshphysical_vert=\"#define PHYSICAL\\nvarying vec3 vViewPosition;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\x3ccommon\\x3e\\n#include \\x3cuv_pars_vertex\\x3e\\n#include \\x3cuv2_pars_vertex\\x3e\\n#include \\x3cdisplacementmap_pars_vertex\\x3e\\n#include \\x3ccolor_pars_vertex\\x3e\\n#include \\x3cmorphtarget_pars_vertex\\x3e\\n#include \\x3cskinning_pars_vertex\\x3e\\n#include \\x3cshadowmap_pars_vertex\\x3e\\n#include \\x3cspecularmap_pars_fragment\\x3e\\n#include \\x3clogdepthbuf_pars_vertex\\x3e\\n#include \\x3cclipping_planes_pars_vertex\\x3e\\nvoid main() {\\n\\t#include \\x3cuv_vertex\\x3e\\n\\t#include \\x3cuv2_vertex\\x3e\\n\\t#include \\x3ccolor_vertex\\x3e\\n\\t#include \\x3cbeginnormal_vertex\\x3e\\n\\t#include \\x3cmorphnormal_vertex\\x3e\\n\\t#include \\x3cskinbase_vertex\\x3e\\n\\t#include \\x3cskinnormal_vertex\\x3e\\n\\t#include \\x3cdefaultnormal_vertex\\x3e\\n#ifndef FLAT_SHADED\\n\\tvNormal \\x3d normalize( transformedNormal );\\n#endif\\n\\t#include \\x3cbegin_vertex\\x3e\\n\\t#include \\x3cdisplacementmap_vertex\\x3e\\n\\t#include \\x3cmorphtarget_vertex\\x3e\\n\\t#include \\x3cskinning_vertex\\x3e\\n\\t#include \\x3cproject_vertex\\x3e\\n\\t#include \\x3clogdepthbuf_vertex\\x3e\\n\\t#include \\x3cclipping_planes_vertex\\x3e\\n\\tvViewPosition \\x3d - mvPosition.xyz;\\n\\t#include \\x3cworldpos_vertex\\x3e\\n\\t#include \\x3cshadowmap_vertex\\x3e\\n}\\n\";\nZ.ShaderChunk.normal_frag=\"uniform float opacity;\\nvarying vec3 vNormal;\\n#include \\x3ccommon\\x3e\\n#include \\x3cpacking\\x3e\\n#include \\x3clogdepthbuf_pars_fragment\\x3e\\n#include \\x3cclipping_planes_pars_fragment\\x3e\\nvoid main() {\\n\\t#include \\x3cclipping_planes_fragment\\x3e\\n\\tgl_FragColor \\x3d vec4( packNormalToRGB( vNormal ), opacity );\\n\\t#include \\x3clogdepthbuf_fragment\\x3e\\n}\\n\";Z.ShaderChunk.normal_vert=\"varying vec3 vNormal;\\n#include \\x3ccommon\\x3e\\n#include \\x3cmorphtarget_pars_vertex\\x3e\\n#include \\x3clogdepthbuf_pars_vertex\\x3e\\n#include \\x3cclipping_planes_pars_vertex\\x3e\\nvoid main() {\\n\\tvNormal \\x3d normalize( normalMatrix * normal );\\n\\t#include \\x3cbegin_vertex\\x3e\\n\\t#include \\x3cmorphtarget_vertex\\x3e\\n\\t#include \\x3cproject_vertex\\x3e\\n\\t#include \\x3clogdepthbuf_vertex\\x3e\\n\\t#include \\x3cclipping_planes_vertex\\x3e\\n}\\n\";\nZ.ShaderChunk.points_frag=\"uniform vec3 diffuse;\\nuniform float opacity;\\n#include \\x3ccommon\\x3e\\n#include \\x3ccolor_pars_fragment\\x3e\\n#include \\x3cmap_particle_pars_fragment\\x3e\\n#include \\x3cfog_pars_fragment\\x3e\\n#include \\x3cshadowmap_pars_fragment\\x3e\\n#include \\x3clogdepthbuf_pars_fragment\\x3e\\n#include \\x3cclipping_planes_pars_fragment\\x3e\\nvoid main() {\\n\\t#include \\x3cclipping_planes_fragment\\x3e\\n\\tvec3 outgoingLight \\x3d vec3( 0.0 );\\n\\tvec4 diffuseColor \\x3d vec4( diffuse, opacity );\\n\\t#include \\x3clogdepthbuf_fragment\\x3e\\n\\t#include \\x3cmap_particle_fragment\\x3e\\n\\t#include \\x3ccolor_fragment\\x3e\\n\\t#include \\x3calphatest_fragment\\x3e\\n\\toutgoingLight \\x3d diffuseColor.rgb;\\n\\tgl_FragColor \\x3d vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\x3cpremultiplied_alpha_fragment\\x3e\\n\\t#include \\x3ctonemapping_fragment\\x3e\\n\\t#include \\x3cencodings_fragment\\x3e\\n\\t#include \\x3cfog_fragment\\x3e\\n}\\n\";\nZ.ShaderChunk.points_vert=\"uniform float size;\\nuniform float scale;\\n#include \\x3ccommon\\x3e\\n#include \\x3ccolor_pars_vertex\\x3e\\n#include \\x3cshadowmap_pars_vertex\\x3e\\n#include \\x3clogdepthbuf_pars_vertex\\x3e\\n#include \\x3cclipping_planes_pars_vertex\\x3e\\nvoid main() {\\n\\t#include \\x3ccolor_vertex\\x3e\\n\\t#include \\x3cbegin_vertex\\x3e\\n\\t#include \\x3cproject_vertex\\x3e\\n\\t#ifdef USE_SIZEATTENUATION\\n\\t\\tgl_PointSize \\x3d size * ( scale / - mvPosition.z );\\n\\t#else\\n\\t\\tgl_PointSize \\x3d size;\\n\\t#endif\\n\\t#include \\x3clogdepthbuf_vertex\\x3e\\n\\t#include \\x3cclipping_planes_vertex\\x3e\\n\\t#include \\x3cworldpos_vertex\\x3e\\n\\t#include \\x3cshadowmap_vertex\\x3e\\n}\\n\";\nZ.ShaderChunk.shadow_frag=\"uniform float opacity;\\n#include \\x3ccommon\\x3e\\n#include \\x3cpacking\\x3e\\n#include \\x3cbsdfs\\x3e\\n#include \\x3clights_pars\\x3e\\n#include \\x3cshadowmap_pars_fragment\\x3e\\n#include \\x3cshadowmask_pars_fragment\\x3e\\nvoid main() {\\n\\tgl_FragColor \\x3d vec4( 0.0, 0.0, 0.0, opacity * ( 1.0  - getShadowMask() ) );\\n}\\n\";Z.ShaderChunk.shadow_vert=\"#include \\x3cshadowmap_pars_vertex\\x3e\\nvoid main() {\\n\\t#include \\x3cbegin_vertex\\x3e\\n\\t#include \\x3cproject_vertex\\x3e\\n\\t#include \\x3cworldpos_vertex\\x3e\\n\\t#include \\x3cshadowmap_vertex\\x3e\\n}\\n\";\nZ.ShaderLib={basic:{uniforms:Z.UniformsUtils.merge([Z.UniformsLib.common,Z.UniformsLib.aomap,Z.UniformsLib.fog]),vertexShader:Z.ShaderChunk.meshbasic_vert,fragmentShader:Z.ShaderChunk.meshbasic_frag},lambert:{uniforms:Z.UniformsUtils.merge([Z.UniformsLib.common,Z.UniformsLib.aomap,Z.UniformsLib.lightmap,Z.UniformsLib.emissivemap,Z.UniformsLib.fog,Z.UniformsLib.lights,{emissive:{type:\"c\",value:new Z.Color(0)}}]),vertexShader:Z.ShaderChunk.meshlambert_vert,fragmentShader:Z.ShaderChunk.meshlambert_frag},\nphong:{uniforms:Z.UniformsUtils.merge([Z.UniformsLib.common,Z.UniformsLib.aomap,Z.UniformsLib.lightmap,Z.UniformsLib.emissivemap,Z.UniformsLib.bumpmap,Z.UniformsLib.normalmap,Z.UniformsLib.displacementmap,Z.UniformsLib.fog,Z.UniformsLib.lights,{emissive:{type:\"c\",value:new Z.Color(0)},specular:{type:\"c\",value:new Z.Color(1118481)},shininess:{type:\"1f\",value:30}}]),vertexShader:Z.ShaderChunk.meshphong_vert,fragmentShader:Z.ShaderChunk.meshphong_frag},standard:{uniforms:Z.UniformsUtils.merge([Z.UniformsLib.common,\nZ.UniformsLib.aomap,Z.UniformsLib.lightmap,Z.UniformsLib.emissivemap,Z.UniformsLib.bumpmap,Z.UniformsLib.normalmap,Z.UniformsLib.displacementmap,Z.UniformsLib.roughnessmap,Z.UniformsLib.metalnessmap,Z.UniformsLib.fog,Z.UniformsLib.lights,{emissive:{type:\"c\",value:new Z.Color(0)},roughness:{type:\"1f\",value:.5},metalness:{type:\"1f\",value:0},envMapIntensity:{type:\"1f\",value:1}}]),vertexShader:Z.ShaderChunk.meshphysical_vert,fragmentShader:Z.ShaderChunk.meshphysical_frag},points:{uniforms:Z.UniformsUtils.merge([Z.UniformsLib.points,\nZ.UniformsLib.fog]),vertexShader:Z.ShaderChunk.points_vert,fragmentShader:Z.ShaderChunk.points_frag},dashed:{uniforms:Z.UniformsUtils.merge([Z.UniformsLib.common,Z.UniformsLib.fog,{scale:{type:\"1f\",value:1},dashSize:{type:\"1f\",value:1},totalSize:{type:\"1f\",value:2}}]),vertexShader:Z.ShaderChunk.linedashed_vert,fragmentShader:Z.ShaderChunk.linedashed_frag},depth:{uniforms:Z.UniformsUtils.merge([Z.UniformsLib.common,Z.UniformsLib.displacementmap]),vertexShader:Z.ShaderChunk.depth_vert,fragmentShader:Z.ShaderChunk.depth_frag},\nnormal:{uniforms:{opacity:{type:\"1f\",value:1}},vertexShader:Z.ShaderChunk.normal_vert,fragmentShader:Z.ShaderChunk.normal_frag},cube:{uniforms:{tCube:{type:\"t\",value:null},tFlip:{type:\"1f\",value:-1}},vertexShader:Z.ShaderChunk.cube_vert,fragmentShader:Z.ShaderChunk.cube_frag},equirect:{uniforms:{tEquirect:{type:\"t\",value:null},tFlip:{type:\"1f\",value:-1}},vertexShader:Z.ShaderChunk.equirect_vert,fragmentShader:Z.ShaderChunk.equirect_frag},distanceRGBA:{uniforms:{lightPos:{type:\"v3\",value:new Z.Vector3}},\nvertexShader:Z.ShaderChunk.distanceRGBA_vert,fragmentShader:Z.ShaderChunk.distanceRGBA_frag}};Z.ShaderLib.physical={uniforms:Z.UniformsUtils.merge([Z.ShaderLib.standard.uniforms,{}]),vertexShader:Z.ShaderChunk.meshphysical_vert,fragmentShader:Z.ShaderChunk.meshphysical_frag};\nZ.WebGLRenderer=function(a){function b(a,b,c,d){!0===S&&(a*=d,b*=d,c*=d);P.clearColor(a,b,c,d)}function c(){P.init();P.scissor(Vc.copy(Hd).multiplyScalar($a));P.viewport(Ac.copy(Bc).multiplyScalar($a));b(ab.r,ab.g,ab.b,bc)}function d(){Kb=Cc=null;Dc=\"\";Va=-1;P.reset()}function e(a){a.preventDefault();d();c();ca.clear()}function f(a){a=a.target;a.removeEventListener(\"dispose\",f);a:{var b=ca.get(a);if(a.image&&b.__image__webglTextureCube)x.deleteTexture(b.__image__webglTextureCube);else{if(void 0===\nb.__webglInit)break a;x.deleteTexture(b.__webglTexture)}ca.delete(a)}cc.textures--}function g(a){a=a.target;a.removeEventListener(\"dispose\",g);var b=ca.get(a),c=ca.get(a.texture);if(a){void 0!==c.__webglTexture&&x.deleteTexture(c.__webglTexture);a.depthTexture&&a.depthTexture.dispose();if(a instanceof Z.WebGLRenderTargetCube)for(c=0;6>c;c++)x.deleteFramebuffer(b.__webglFramebuffer[c]),b.__webglDepthbuffer&&x.deleteRenderbuffer(b.__webglDepthbuffer[c]);else x.deleteFramebuffer(b.__webglFramebuffer),\nb.__webglDepthbuffer&&x.deleteRenderbuffer(b.__webglDepthbuffer);ca.delete(a.texture);ca.delete(a)}cc.textures--}function k(a){a=a.target;a.removeEventListener(\"dispose\",k);l(a);ca.delete(a)}function l(a){var b=ca.get(a).program;a.program=void 0;void 0!==b&&Ec.releaseProgram(b)}function m(a,b){return Math.abs(b[0])-Math.abs(a[0])}function n(a,b){return a.object.renderOrder!==b.object.renderOrder?a.object.renderOrder-b.object.renderOrder:a.material.id!==b.material.id?a.material.id-b.material.id:a.z!==\nb.z?a.z-b.z:a.id-b.id}function q(a,b){return a.object.renderOrder!==b.object.renderOrder?a.object.renderOrder-b.object.renderOrder:a.z!==b.z?b.z-a.z:a.id-b.id}function p(a,b,c,d){if(c.transparent){var e=la;var f=++sa}else e=N,f=++Q;f=e[f];void 0!==f?(f.id=a.id,f.object=a,f.geometry=b,f.material=c,f.z=Qa.z,f.group=d):(f={id:a.id,object:a,geometry:b,material:c,z:Qa.z,group:d},e.push(f))}function t(a){if(!df.intersectsSphere(a))return!1;var b=ob.numPlanes;if(0===b)return!0;var c=oa.clippingPlanes,d=\na.center;a=-a.radius;var e=0;do if(c[e].distanceToPoint(d)<a)return!1;while(++e!==b);return!0}function r(a,b){if(!1!==a.visible){if(a.layers.test(b.layers))if(a instanceof Z.Light)K.push(a);else if(a instanceof Z.Sprite){var c;if(c=!1!==a.frustumCulled)dc.center.set(0,0,0),dc.radius=.7071067811865476,dc.applyMatrix4(a.matrixWorld),c=!0!==t(dc);c||La.push(a)}else if(a instanceof Z.LensFlare)Id.push(a);else if(a instanceof Z.ImmediateRenderObject)!0===oa.sortObjects&&(Qf(Qa,a.matrixWorld),Of(Qa,Wc)),\np(a,null,a.material,null);else if(a instanceof Z.Mesh||a instanceof Z.Line||a instanceof Z.Points)if(a instanceof Z.SkinnedMesh&&a.skeleton.update(),(c=!1===a.frustumCulled)||(c=a.geometry,null===c.boundingSphere&&c.computeBoundingSphere(),dc.copy(c.boundingSphere).applyMatrix4(a.matrixWorld),c=!0===t(dc)),c){var d=a.material;if(!0===d.visible)if(!0===oa.sortObjects&&(Qf(Qa,a.matrixWorld),Of(Qa,Wc)),c=Fc.update(a),d instanceof Z.MultiMaterial)for(var e=c.groups,f=d.materials,d=0,g=e.length;d<g;d++){var k=\ne[d],l=f[k.materialIndex];!0===l.visible&&p(a,c,l,k)}else p(a,c,d,null)}a=a.children;d=0;for(g=a.length;d<g;d++)r(a[d],b)}}function v(a,b,c,d){for(var e=0,f=a.length;e<f;e++){var g=a[e],k=g.object,l=g.geometry,m=void 0===d?g.material:d,g=g.group;Nf(k.modelViewMatrix,b.matrixWorldInverse,k.matrixWorld);Wf(k.normalMatrix,k.modelViewMatrix);if(k instanceof Z.ImmediateRenderObject){w(m);var n=z(b,c,m,k);Dc=\"\";k.render(function(a){oa.renderBufferImmediate(a,n,m)})}else oa.renderBufferDirect(b,c,l,m,k,\ng)}}function w(a){a.side!==Z.DoubleSide?P.enable(x.CULL_FACE):P.disable(x.CULL_FACE);P.setFlipSided(a.side===Z.BackSide);!0===a.transparent?P.setBlending(a.blending,a.blendEquation,a.blendSrc,a.blendDst,a.blendEquationAlpha,a.blendSrcAlpha,a.blendDstAlpha,a.premultipliedAlpha):P.setBlending(Z.NoBlending);P.setDepthFunc(a.depthFunc);P.setDepthTest(a.depthTest);P.setDepthWrite(a.depthWrite);P.setColorWrite(a.colorWrite);P.setPolygonOffset(a.polygonOffset,a.polygonOffsetFactor,a.polygonOffsetUnits)}\nfunction z(a,b,c,d){Jd=0;var e=ca.get(c);Xc&&((Kd||a!==Kb)&&ob.setState(c.clippingPlanes,c.clipShadows,a,e,a===Kb&&c.id===Va),void 0!==e.numClippingPlanes&&e.numClippingPlanes!==ob.numPlanes&&(c.needsUpdate=!0));void 0===e.program&&(c.needsUpdate=!0);void 0!==e.lightsHash&&e.lightsHash!==X.hash&&(c.needsUpdate=!0);if(c.needsUpdate){a:{var f=ca.get(c),g=Ec.getParameters(c,X,b,ob.numPlanes,d),m=Ec.getProgramCode(c,g),n=f.program,p=!0;if(void 0===n)c.addEventListener(\"dispose\",k);else if(n.code!==m)l(c);\nelse{if(void 0!==g.shaderID)break a;p=!1}p&&(g.shaderID?(n=Z.ShaderLib[g.shaderID],f.__webglShader={name:c.type,uniforms:Z.UniformsUtils.clone(n.uniforms),vertexShader:n.vertexShader,fragmentShader:n.fragmentShader}):f.__webglShader={name:c.type,uniforms:c.uniforms,vertexShader:c.vertexShader,fragmentShader:c.fragmentShader},c.__webglShader=f.__webglShader,n=Ec.acquireProgram(c,g,m),f.program=n,c.program=n);g=n.getAttributes();if(c.morphTargets)for(m=c.numSupportedMorphTargets=0;m<oa.maxMorphTargets;m++)0<=\ng[\"morphTarget\"+m]&&c.numSupportedMorphTargets++;if(c.morphNormals)for(m=c.numSupportedMorphNormals=0;m<oa.maxMorphNormals;m++)0<=g[\"morphNormal\"+m]&&c.numSupportedMorphNormals++;g=f.__webglShader.uniforms;(c instanceof Z.ShaderMaterial||c instanceof Z.RawShaderMaterial)&&!0!==c.clipping||(f.numClippingPlanes=ob.numPlanes,g.clippingPlanes=ob.uniform);c.lights&&(f.lightsHash=X.hash,g.ambientLightColor.value=X.ambient,g.directionalLights.value=X.directional,g.spotLights.value=X.spot,g.pointLights.value=\nX.point,g.hemisphereLights.value=X.hemi,g.directionalShadowMap.value=X.directionalShadowMap,g.directionalShadowMatrix.value=X.directionalShadowMatrix,g.spotShadowMap.value=X.spotShadowMap,g.spotShadowMatrix.value=X.spotShadowMatrix,g.pointShadowMap.value=X.pointShadowMap,g.pointShadowMatrix.value=X.pointShadowMatrix);m=f.program.getUniforms();m=Z.WebGLUniforms.seqWithValue(m.seq,g);f.uniformsList=m;f.dynamicUniforms=Z.WebGLUniforms.splitDynamic(m,g)}c.needsUpdate=!1}var q=!1,p=n=!1,f=e.program,m=\nf.getUniforms(),g=e.__webglShader.uniforms;f.id!==Cc&&(x.useProgram(f.program),Cc=f.id,p=n=q=!0);c.id!==Va&&(Va=c.id,n=!0);if(q||a!==Kb){m.set(x,a,\"projectionMatrix\");pb.logarithmicDepthBuffer&&m.setValue(x,\"logDepthBufFC\",2/(Math.log(a.far+1)/Math.LN2));a!==Kb&&(Kb=a,p=n=!0);if(c instanceof Z.ShaderMaterial||c instanceof Z.MeshPhongMaterial||c instanceof Z.MeshStandardMaterial||c.envMap)q=m.map.cameraPosition,void 0!==q&&q.setValue(x,Qf(Qa,a.matrixWorld));(c instanceof Z.MeshPhongMaterial||c instanceof\nZ.MeshLambertMaterial||c instanceof Z.MeshBasicMaterial||c instanceof Z.MeshStandardMaterial||c instanceof Z.ShaderMaterial||c.skinning)&&m.setValue(x,\"viewMatrix\",a.matrixWorldInverse);m.set(x,oa,\"toneMappingExposure\");m.set(x,oa,\"toneMappingWhitePoint\")}c.skinning&&(m.setOptional(x,d,\"bindMatrix\"),m.setOptional(x,d,\"bindMatrixInverse\"),q=d.skeleton)&&(pb.floatVertexTextures&&q.useVertexTexture?(m.set(x,q,\"boneTexture\"),m.set(x,q,\"boneTextureWidth\"),m.set(x,q,\"boneTextureHeight\")):m.setOptional(x,\nq,\"boneMatrices\"));if(n){c.lights&&(n=p,g.ambientLightColor.needsUpdate=n,g.directionalLights.needsUpdate=n,g.pointLights.needsUpdate=n,g.spotLights.needsUpdate=n,g.hemisphereLights.needsUpdate=n);b&&c.fog&&(g.fogColor.value=b.color,b instanceof Z.Fog?(g.fogNear.value=b.near,g.fogFar.value=b.far):b instanceof Z.FogExp2&&(g.fogDensity.value=b.density));if(c instanceof Z.MeshBasicMaterial||c instanceof Z.MeshLambertMaterial||c instanceof Z.MeshPhongMaterial||c instanceof Z.MeshStandardMaterial||c instanceof\nZ.MeshDepthMaterial){g.opacity.value=c.opacity;g.diffuse.value=c.color;c.emissive&&g.emissive.value.copy(c.emissive).multiplyScalar(c.emissiveIntensity);g.map.value=c.map;g.specularMap.value=c.specularMap;g.alphaMap.value=c.alphaMap;c.aoMap&&(g.aoMap.value=c.aoMap,g.aoMapIntensity.value=c.aoMapIntensity);if(c.map)var r=c.map;else c.specularMap?r=c.specularMap:c.displacementMap?r=c.displacementMap:c.normalMap?r=c.normalMap:c.bumpMap?r=c.bumpMap:c.roughnessMap?r=c.roughnessMap:c.metalnessMap?r=c.metalnessMap:\nc.alphaMap?r=c.alphaMap:c.emissiveMap&&(r=c.emissiveMap);void 0!==r&&(r instanceof Z.WebGLRenderTarget&&(r=r.texture),b=r.offset,r=r.repeat,g.offsetRepeat.value.set(b.x,b.y,r.x,r.y));g.envMap.value=c.envMap;g.flipEnvMap.value=c.envMap instanceof Z.CubeTexture?-1:1;g.reflectivity.value=c.reflectivity;g.refractionRatio.value=c.refractionRatio}c instanceof Z.LineBasicMaterial?(g.diffuse.value=c.color,g.opacity.value=c.opacity):c instanceof Z.LineDashedMaterial?(g.diffuse.value=c.color,g.opacity.value=\nc.opacity,g.dashSize.value=c.dashSize,g.totalSize.value=c.dashSize+c.gapSize,g.scale.value=c.scale):c instanceof Z.PointsMaterial?(g.diffuse.value=c.color,g.opacity.value=c.opacity,g.size.value=c.size*$a,g.scale.value=.5*C.clientHeight,g.map.value=c.map,null!==c.map&&(r=c.map.offset,c=c.map.repeat,g.offsetRepeat.value.set(r.x,r.y,c.x,c.y))):c instanceof Z.MeshLambertMaterial?(c.lightMap&&(g.lightMap.value=c.lightMap,g.lightMapIntensity.value=c.lightMapIntensity),c.emissiveMap&&(g.emissiveMap.value=\nc.emissiveMap)):c instanceof Z.MeshPhongMaterial?(g.specular.value=c.specular,g.shininess.value=Math.max(c.shininess,1E-4),c.lightMap&&(g.lightMap.value=c.lightMap,g.lightMapIntensity.value=c.lightMapIntensity),c.emissiveMap&&(g.emissiveMap.value=c.emissiveMap),c.bumpMap&&(g.bumpMap.value=c.bumpMap,g.bumpScale.value=c.bumpScale),c.normalMap&&(g.normalMap.value=c.normalMap,g.normalScale.value.copy(c.normalScale)),c.displacementMap&&(g.displacementMap.value=c.displacementMap,g.displacementScale.value=\nc.displacementScale,g.displacementBias.value=c.displacementBias)):c instanceof Z.MeshPhysicalMaterial?y(g,c):c instanceof Z.MeshStandardMaterial?y(g,c):c instanceof Z.MeshDepthMaterial?c.displacementMap&&(g.displacementMap.value=c.displacementMap,g.displacementScale.value=c.displacementScale,g.displacementBias.value=c.displacementBias):c instanceof Z.MeshNormalMaterial&&(g.opacity.value=c.opacity);Z.WebGLUniforms.upload(x,e.uniformsList,g,oa)}m.set(x,d,\"modelViewMatrix\");m.set(x,d,\"normalMatrix\");\nm.setValue(x,\"modelMatrix\",d.matrixWorld);e=e.dynamicUniforms;null!==e&&(Z.WebGLUniforms.evalDynamic(e,g,d,a),Z.WebGLUniforms.upload(x,e,g,oa));return f}function y(a,b){a.roughness.value=b.roughness;a.metalness.value=b.metalness;b.roughnessMap&&(a.roughnessMap.value=b.roughnessMap);b.metalnessMap&&(a.metalnessMap.value=b.metalnessMap);b.lightMap&&(a.lightMap.value=b.lightMap,a.lightMapIntensity.value=b.lightMapIntensity);b.emissiveMap&&(a.emissiveMap.value=b.emissiveMap);b.bumpMap&&(a.bumpMap.value=\nb.bumpMap,a.bumpScale.value=b.bumpScale);b.normalMap&&(a.normalMap.value=b.normalMap,a.normalScale.value.copy(b.normalScale));b.displacementMap&&(a.displacementMap.value=b.displacementMap,a.displacementScale.value=b.displacementScale,a.displacementBias.value=b.displacementBias);b.envMap&&(a.envMapIntensity.value=b.envMapIntensity)}function B(a,b,c){c?(x.texParameteri(a,x.TEXTURE_WRAP_S,H(b.wrapS)),x.texParameteri(a,x.TEXTURE_WRAP_T,H(b.wrapT)),x.texParameteri(a,x.TEXTURE_MAG_FILTER,H(b.magFilter)),\nx.texParameteri(a,x.TEXTURE_MIN_FILTER,H(b.minFilter))):(x.texParameteri(a,x.TEXTURE_WRAP_S,x.CLAMP_TO_EDGE),x.texParameteri(a,x.TEXTURE_WRAP_T,x.CLAMP_TO_EDGE),b.wrapS===Z.ClampToEdgeWrapping&&b.wrapT===Z.ClampToEdgeWrapping||console.warn(\"THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping.\",b),x.texParameteri(a,x.TEXTURE_MAG_FILTER,I(b.magFilter)),x.texParameteri(a,x.TEXTURE_MIN_FILTER,I(b.minFilter)),b.minFilter!==Z.NearestFilter&&\nb.minFilter!==Z.LinearFilter&&console.warn(\"THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter.\",b));!(c=ja.get(\"EXT_texture_filter_anisotropic\"))||b.type===Z.FloatType&&null===ja.get(\"OES_texture_float_linear\")||b.type===Z.HalfFloatType&&null===ja.get(\"OES_texture_half_float_linear\")||!(1<b.anisotropy||ca.get(b).__currentAnisotropy)||(x.texParameterf(a,c.TEXTURE_MAX_ANISOTROPY_EXT,Math.min(b.anisotropy,oa.getMaxAnisotropy())),\nca.get(b).__currentAnisotropy=b.anisotropy)}function A(a,b){if(a.width>b||a.height>b){b/=Math.max(a.width,a.height);var c=document.createElement(\"canvas\");c.width=Math.floor(a.width*b);c.height=Math.floor(a.height*b);c.getContext(\"2d\").drawImage(a,0,0,a.width,a.height,0,0,c.width,c.height);console.warn(\"THREE.WebGLRenderer: image is too big (\"+a.width+\"x\"+a.height+\"). Resized to \"+c.width+\"x\"+c.height,a);return c}return a}function D(a){return Z.Math.isPowerOfTwo(a.width)&&Z.Math.isPowerOfTwo(a.height)}\nfunction E(a,b,c,d){var e=H(b.texture.format),f=H(b.texture.type);P.texImage2D(d,0,e,b.width,b.height,0,e,f,null);x.bindFramebuffer(x.FRAMEBUFFER,a);x.framebufferTexture2D(x.FRAMEBUFFER,c,d,ca.get(b.texture).__webglTexture,0);x.bindFramebuffer(x.FRAMEBUFFER,null)}function F(a,b){x.bindRenderbuffer(x.RENDERBUFFER,a);b.depthBuffer&&!b.stencilBuffer?(x.renderbufferStorage(x.RENDERBUFFER,x.DEPTH_COMPONENT16,b.width,b.height),x.framebufferRenderbuffer(x.FRAMEBUFFER,x.DEPTH_ATTACHMENT,x.RENDERBUFFER,a)):\nb.depthBuffer&&b.stencilBuffer?(x.renderbufferStorage(x.RENDERBUFFER,x.DEPTH_STENCIL,b.width,b.height),x.framebufferRenderbuffer(x.FRAMEBUFFER,x.DEPTH_STENCIL_ATTACHMENT,x.RENDERBUFFER,a)):x.renderbufferStorage(x.RENDERBUFFER,x.RGBA4,b.width,b.height);x.bindRenderbuffer(x.RENDERBUFFER,null)}function I(a){return a===Z.NearestFilter||a===Z.NearestMipMapNearestFilter||a===Z.NearestMipMapLinearFilter?x.NEAREST:x.LINEAR}function H(a){if(a===Z.RepeatWrapping)return x.REPEAT;if(a===Z.ClampToEdgeWrapping)return x.CLAMP_TO_EDGE;\nif(a===Z.MirroredRepeatWrapping)return x.MIRRORED_REPEAT;if(a===Z.NearestFilter)return x.NEAREST;if(a===Z.NearestMipMapNearestFilter)return x.NEAREST_MIPMAP_NEAREST;if(a===Z.NearestMipMapLinearFilter)return x.NEAREST_MIPMAP_LINEAR;if(a===Z.LinearFilter)return x.LINEAR;if(a===Z.LinearMipMapNearestFilter)return x.LINEAR_MIPMAP_NEAREST;if(a===Z.LinearMipMapLinearFilter)return x.LINEAR_MIPMAP_LINEAR;if(a===Z.UnsignedByteType)return x.UNSIGNED_BYTE;if(a===Z.UnsignedShort4444Type)return x.UNSIGNED_SHORT_4_4_4_4;\nif(a===Z.UnsignedShort5551Type)return x.UNSIGNED_SHORT_5_5_5_1;if(a===Z.UnsignedShort565Type)return x.UNSIGNED_SHORT_5_6_5;if(a===Z.ByteType)return x.BYTE;if(a===Z.ShortType)return x.SHORT;if(a===Z.UnsignedShortType)return x.UNSIGNED_SHORT;if(a===Z.IntType)return x.INT;if(a===Z.UnsignedIntType)return x.UNSIGNED_INT;if(a===Z.FloatType)return x.FLOAT;var b=ja.get(\"OES_texture_half_float\");if(null!==b&&a===Z.HalfFloatType)return b.HALF_FLOAT_OES;if(a===Z.AlphaFormat)return x.ALPHA;if(a===Z.RGBFormat)return x.RGB;\nif(a===Z.RGBAFormat)return x.RGBA;if(a===Z.LuminanceFormat)return x.LUMINANCE;if(a===Z.LuminanceAlphaFormat)return x.LUMINANCE_ALPHA;if(a===Z.DepthFormat)return x.DEPTH_COMPONENT;if(a===Z.AddEquation)return x.FUNC_ADD;if(a===Z.SubtractEquation)return x.FUNC_SUBTRACT;if(a===Z.ReverseSubtractEquation)return x.FUNC_REVERSE_SUBTRACT;if(a===Z.ZeroFactor)return x.ZERO;if(a===Z.OneFactor)return x.ONE;if(a===Z.SrcColorFactor)return x.SRC_COLOR;if(a===Z.OneMinusSrcColorFactor)return x.ONE_MINUS_SRC_COLOR;\nif(a===Z.SrcAlphaFactor)return x.SRC_ALPHA;if(a===Z.OneMinusSrcAlphaFactor)return x.ONE_MINUS_SRC_ALPHA;if(a===Z.DstAlphaFactor)return x.DST_ALPHA;if(a===Z.OneMinusDstAlphaFactor)return x.ONE_MINUS_DST_ALPHA;if(a===Z.DstColorFactor)return x.DST_COLOR;if(a===Z.OneMinusDstColorFactor)return x.ONE_MINUS_DST_COLOR;if(a===Z.SrcAlphaSaturateFactor)return x.SRC_ALPHA_SATURATE;b=ja.get(\"WEBGL_compressed_texture_s3tc\");if(null!==b){if(a===Z.RGB_S3TC_DXT1_Format)return b.COMPRESSED_RGB_S3TC_DXT1_EXT;if(a===\nZ.RGBA_S3TC_DXT1_Format)return b.COMPRESSED_RGBA_S3TC_DXT1_EXT;if(a===Z.RGBA_S3TC_DXT3_Format)return b.COMPRESSED_RGBA_S3TC_DXT3_EXT;if(a===Z.RGBA_S3TC_DXT5_Format)return b.COMPRESSED_RGBA_S3TC_DXT5_EXT}b=ja.get(\"WEBGL_compressed_texture_pvrtc\");if(null!==b){if(a===Z.RGB_PVRTC_4BPPV1_Format)return b.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;if(a===Z.RGB_PVRTC_2BPPV1_Format)return b.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;if(a===Z.RGBA_PVRTC_4BPPV1_Format)return b.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;if(a===Z.RGBA_PVRTC_2BPPV1_Format)return b.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG}b=\nja.get(\"WEBGL_compressed_texture_etc1\");if(null!==b&&a===Z.RGB_ETC1_Format)return b.COMPRESSED_RGB_ETC1_WEBGL;b=ja.get(\"EXT_blend_minmax\");if(null!==b){if(a===Z.MinEquation)return b.MIN_EXT;if(a===Z.MaxEquation)return b.MAX_EXT}return 0}console.log(\"THREE.WebGLRenderer\",Z.REVISION);a=a||{};var C=void 0!==a.canvas?a.canvas:document.createElement(\"canvas\"),J=void 0!==a.context?a.context:null,M=void 0!==a.alpha?a.alpha:!1,T=void 0!==a.depth?a.depth:!0,U=void 0!==a.stencil?a.stencil:!0,L=void 0!==a.antialias?\na.antialias:!1,S=void 0!==a.premultipliedAlpha?a.premultipliedAlpha:!0,R=void 0!==a.preserveDrawingBuffer?a.preserveDrawingBuffer:!1,K=[],N=[],Q=-1,la=[],sa=-1,fa=new Float32Array(8),La=[],Id=[];this.domElement=C;this.context=null;this.sortObjects=this.autoClearStencil=this.autoClearDepth=this.autoClearColor=this.autoClear=!0;this.clippingPlanes=[];this.localClippingEnabled=!1;this.gammaFactor=2;this.physicallyCorrectLights=this.gammaOutput=this.gammaInput=!1;this.toneMapping=Z.LinearToneMapping;\nthis.toneMappingWhitePoint=this.toneMappingExposure=1;this.maxMorphTargets=8;this.maxMorphNormals=4;this.autoScaleCubemaps=!0;var oa=this,Cc=null,Db=null,ec=null,Va=-1,Dc=\"\",Kb=null,Vc=new Z.Vector4,Ld=null,Ac=new Z.Vector4,Jd=0,ab=new Z.Color(0),bc=0,Yc=C.width,Zc=C.height,$a=1,Hd=new Z.Vector4(0,0,Yc,Zc),ef=!1,Bc=new Z.Vector4(0,0,Yc,Zc),df=new Z.Frustum,ob=new Z.WebGLClipping,Xc=!1,Kd=!1,dc=new Z.Sphere,Wc=new Z.Matrix4,Qa=new Z.Vector3,X={hash:\"\",ambient:[0,0,0],directional:[],directionalShadowMap:[],\ndirectionalShadowMatrix:[],spot:[],spotShadowMap:[],spotShadowMatrix:[],point:[],pointShadowMap:[],pointShadowMatrix:[],hemi:[],shadows:[]},cc={geometries:0,textures:0},Lb={calls:0,vertices:0,faces:0,points:0};this.info={render:Lb,memory:cc,programs:null};try{M={alpha:M,depth:T,stencil:U,antialias:L,premultipliedAlpha:S,preserveDrawingBuffer:R};var x=J||C.getContext(\"webgl\",M)||C.getContext(\"experimental-webgl\",M);if(null===x){if(null!==C.getContext(\"webgl\"))throw\"Error creating WebGL context with your selected attributes.\";\nthrow\"Error creating WebGL context.\";}void 0===x.getShaderPrecisionFormat&&(x.getShaderPrecisionFormat=function(){return{rangeMin:1,rangeMax:1,precision:1}});C.addEventListener(\"webglcontextlost\",e,!1)}catch(Ng){console.error(\"THREE.WebGLRenderer: \"+Ng)}var ff=\"undefined\"!==typeof WebGL2RenderingContext&&x instanceof WebGL2RenderingContext,ja=new Z.WebGLExtensions(x);ja.get(\"WEBGL_depth_texture\");ja.get(\"OES_texture_float\");ja.get(\"OES_texture_float_linear\");ja.get(\"OES_texture_half_float\");ja.get(\"OES_texture_half_float_linear\");\nja.get(\"OES_standard_derivatives\");ja.get(\"ANGLE_instanced_arrays\");ja.get(\"OES_element_index_uint\")&&(Z.BufferGeometry.MaxIndex=4294967296);var pb=new Z.WebGLCapabilities(x,ja,a),P=new Z.WebGLState(x,ja,H),ca=new Z.WebGLProperties,Fc=new Z.WebGLObjects(x,ca,this.info),Ec=new Z.WebGLPrograms(this,pb),$c=new Z.WebGLLights;this.info.programs=Ec.programs;var Og=new Z.WebGLBufferRenderer(x,ja,Lb),Pg=new Z.WebGLIndexedBufferRenderer(x,ja,Lb);c();this.context=x;this.capabilities=pb;this.extensions=ja;this.properties=\nca;this.state=P;var gf=new Z.WebGLShadowMap(this,X,Fc);this.shadowMap=gf;var Qg=new Z.SpritePlugin(this,La),Rg=new Z.LensFlarePlugin(this,Id);this.getContext=function(){return x};this.getContextAttributes=function(){return x.getContextAttributes()};this.forceContextLoss=function(){ja.get(\"WEBGL_lose_context\").loseContext()};this.getMaxAnisotropy=function(){var a;return function(){if(void 0!==a)return a;var b=ja.get(\"EXT_texture_filter_anisotropic\");return a=null!==b?x.getParameter(b.MAX_TEXTURE_MAX_ANISOTROPY_EXT):\n0}}();this.getPrecision=function(){return pb.precision};this.getPixelRatio=function(){return $a};this.setPixelRatio=function(){var a=window.devicePixelRatio;void 0!==a&&($a=a,this.setSize(Bc.z,Bc.w,!1))};this.getSize=function(){return{width:Yc,height:Zc}};this.setSize=function(a,b,c){Yc=a;Zc=b;C.width=a*$a;C.height=b*$a;!1!==c&&(C.style.width=a+\"px\",C.style.height=b+\"px\");this.setViewport(a,b)};this.setViewport=function(a,b){P.viewport(Bc.set(0,0,a,b))};this.setScissor=function(a,b,c,d){P.scissor(Hd.set(a,\nb,c,d))};this.setScissorTest=function(a){P.setScissorTest(ef=a)};this.getClearColor=function(){return ab};this.setClearColor=function(a,c){ab.set(a);bc=void 0!==c?c:1;b(ab.r,ab.g,ab.b,bc)};this.getClearAlpha=function(){return bc};this.setClearAlpha=function(a){bc=a;b(ab.r,ab.g,ab.b,bc)};this.clear=function(a,b,c){var d=0;if(void 0===a||a)d|=x.COLOR_BUFFER_BIT;if(void 0===b||b)d|=x.DEPTH_BUFFER_BIT;if(void 0===c||c)d|=x.STENCIL_BUFFER_BIT;x.clear(d)};this.clearColor=function(){this.clear(!0,!1,!1)};\nthis.clearDepth=function(){this.clear(!1,!0,!1)};this.clearStencil=function(){this.clear(!1,!1,!0)};this.clearTarget=function(a,b,c,d){this.setRenderTarget(a);this.clear(b,c,d)};this.resetGLState=d;this.dispose=function(){C.removeEventListener(\"webglcontextlost\",e,!1)};this.renderBufferImmediate=function(a,b,c){P.initAttributes();var d=ca.get(a);a.hasPositions&&!d.position&&(d.position=x.createBuffer());a.hasNormals&&!d.normal&&(d.normal=x.createBuffer());a.hasUvs&&!d.uv&&(d.uv=x.createBuffer());\na.hasColors&&!d.color&&(d.color=x.createBuffer());b=b.getAttributes();a.hasPositions&&(x.bindBuffer(x.ARRAY_BUFFER,d.position),x.bufferData(x.ARRAY_BUFFER,a.positionArray,x.DYNAMIC_DRAW),P.enableAttribute(b.position),x.vertexAttribPointer(b.position,3,x.FLOAT,!1,0,0));if(a.hasNormals){x.bindBuffer(x.ARRAY_BUFFER,d.normal);if(\"MeshPhongMaterial\"!==c.type&&\"MeshStandardMaterial\"!==c.type&&\"MeshPhysicalMaterial\"!==c.type&&c.shading===Z.FlatShading)for(var e=0,f=3*a.count;e<f;e+=9){var g=a.normalArray,\nk=(g[e+0]+g[e+3]+g[e+6])/3,l=(g[e+1]+g[e+4]+g[e+7])/3,m=(g[e+2]+g[e+5]+g[e+8])/3;g[e+0]=k;g[e+1]=l;g[e+2]=m;g[e+3]=k;g[e+4]=l;g[e+5]=m;g[e+6]=k;g[e+7]=l;g[e+8]=m}x.bufferData(x.ARRAY_BUFFER,a.normalArray,x.DYNAMIC_DRAW);P.enableAttribute(b.normal);x.vertexAttribPointer(b.normal,3,x.FLOAT,!1,0,0)}a.hasUvs&&c.map&&(x.bindBuffer(x.ARRAY_BUFFER,d.uv),x.bufferData(x.ARRAY_BUFFER,a.uvArray,x.DYNAMIC_DRAW),P.enableAttribute(b.uv),x.vertexAttribPointer(b.uv,2,x.FLOAT,!1,0,0));a.hasColors&&c.vertexColors!==\nZ.NoColors&&(x.bindBuffer(x.ARRAY_BUFFER,d.color),x.bufferData(x.ARRAY_BUFFER,a.colorArray,x.DYNAMIC_DRAW),P.enableAttribute(b.color),x.vertexAttribPointer(b.color,3,x.FLOAT,!1,0,0));P.disableUnusedAttributes();x.drawArrays(x.TRIANGLES,0,a.count);a.count=0};this.renderBufferDirect=function(a,b,c,d,e,f){w(d);var g=z(a,b,d,e),k=!1;a=c.id+\"_\"+g.id+\"_\"+d.wireframe;a!==Dc&&(Dc=a,k=!0);var l=e.morphTargetInfluences;if(void 0!==l){a=[];for(var n=0,k=l.length;n<k;n++)b=l[n],a.push([b,n]);a.sort(m);8<a.length&&\n(a.length=8);l=c.morphAttributes;n=0;for(k=a.length;n<k;n++)b=a[n],fa[n]=b[0],0!==b[0]?(b=b[1],!0===d.morphTargets&&l.position&&c.addAttribute(\"morphTarget\"+n,l.position[b]),!0===d.morphNormals&&l.normal&&c.addAttribute(\"morphNormal\"+n,l.normal[b])):(!0===d.morphTargets&&c.removeAttribute(\"morphTarget\"+n),!0===d.morphNormals&&c.removeAttribute(\"morphNormal\"+n));g.getUniforms().setValue(x,\"morphTargetInfluences\",fa);k=!0}b=c.index;n=c.attributes.position;!0===d.wireframe&&(b=Fc.getWireframeAttribute(c));\nnull!==b?(a=Pg,a.setIndex(b)):a=Og;if(k){a:{var p;if(c instanceof Z.InstancedBufferGeometry){var q=ja.get(\"ANGLE_instanced_arrays\");if(null===q){console.error(\"THREE.WebGLRenderer.setupVertexAttributes: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.\");break a}}void 0===p&&(p=0);P.initAttributes();var k=c.attributes,g=g.getAttributes(),l=d.defaultAttributeValues;for(N in g){var r=g[N];if(0<=r){var t=k[N];if(void 0!==t){var v=x.FLOAT,y=t.array,A=\nt.normalized;y instanceof Float32Array?v=x.FLOAT:y instanceof Float64Array?console.warn(\"Unsupported data buffer format: Float64Array\"):y instanceof Uint16Array?v=x.UNSIGNED_SHORT:y instanceof Int16Array?v=x.SHORT:y instanceof Uint32Array?v=x.UNSIGNED_INT:y instanceof Int32Array?v=x.INT:y instanceof Int8Array?v=x.BYTE:y instanceof Uint8Array&&(v=x.UNSIGNED_BYTE);var y=t.itemSize,L=Fc.getAttributeBuffer(t);if(t instanceof Z.InterleavedBufferAttribute){var B=t.data,K=B.stride,t=t.offset;B instanceof\nZ.InstancedInterleavedBuffer?(P.enableAttributeAndDivisor(r,B.meshPerAttribute,q),void 0===c.maxInstancedCount&&(c.maxInstancedCount=B.meshPerAttribute*B.count)):P.enableAttribute(r);x.bindBuffer(x.ARRAY_BUFFER,L);x.vertexAttribPointer(r,y,v,A,K*B.array.BYTES_PER_ELEMENT,(p*K+t)*B.array.BYTES_PER_ELEMENT)}else t instanceof Z.InstancedBufferAttribute?(P.enableAttributeAndDivisor(r,t.meshPerAttribute,q),void 0===c.maxInstancedCount&&(c.maxInstancedCount=t.meshPerAttribute*t.count)):P.enableAttribute(r),\nx.bindBuffer(x.ARRAY_BUFFER,L),x.vertexAttribPointer(r,y,v,A,0,p*y*t.array.BYTES_PER_ELEMENT)}else if(void 0!==l&&(v=l[N],void 0!==v))switch(v.length){case 2:x.vertexAttrib2fv(r,v);break;case 3:x.vertexAttrib3fv(r,v);break;case 4:x.vertexAttrib4fv(r,v);break;default:x.vertexAttrib1fv(r,v)}}}P.disableUnusedAttributes()}null!==b&&x.bindBuffer(x.ELEMENT_ARRAY_BUFFER,Fc.getAttributeBuffer(b))}p=Infinity;null!==b?p=b.count:void 0!==n&&(p=n.count);var N=c.drawRange.start;b=null!==f?f.start:0;q=Math.max(0,\nN,b);f=Math.max(0,Math.min(0+p,N+c.drawRange.count,b+(null!==f?f.count:Infinity))-1-q+1);if(e instanceof Z.Mesh)if(!0===d.wireframe)P.setLineWidth(d.wireframeLinewidth*(null===Db?$a:1)),a.setMode(x.LINES);else switch(e.drawMode){case Z.TrianglesDrawMode:a.setMode(x.TRIANGLES);break;case Z.TriangleStripDrawMode:a.setMode(x.TRIANGLE_STRIP);break;case Z.TriangleFanDrawMode:a.setMode(x.TRIANGLE_FAN)}else e instanceof Z.Line?(d=d.linewidth,void 0===d&&(d=1),P.setLineWidth(d*(null===Db?$a:1)),e instanceof\nZ.LineSegments?a.setMode(x.LINES):a.setMode(x.LINE_STRIP)):e instanceof Z.Points&&a.setMode(x.POINTS);c instanceof Z.InstancedBufferGeometry?0<c.maxInstancedCount&&a.renderInstances(c,q,f):a.render(q,f)};this.render=function(a,b,c,d){if(!1===b instanceof Z.Camera)console.error(\"THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.\");else{var e=a.fog;Dc=\"\";Va=-1;Kb=null;!0===a.autoUpdate&&a.updateMatrixWorld();null===b.parent&&b.updateMatrixWorld();b.matrixWorldInverse.getInverse(b.matrixWorld);\nNf(Wc,b.projectionMatrix,b.matrixWorldInverse);bg(df,Wc);K.length=0;sa=Q=-1;La.length=0;Id.length=0;Kd=this.localClippingEnabled;Xc=ob.init(this.clippingPlanes,Kd,b);r(a,b);N.length=Q+1;la.length=sa+1;!0===oa.sortObjects&&(N.sort(n),la.sort(q));Xc&&ob.beginShadows();for(var f=K,g=0,k=0,l=f.length;k<l;k++){var m=f[k];m.castShadow&&(X.shadows[g++]=m)}X.shadows.length=g;gf.render(a,b);for(var f=K,p=0,t=0,w=0,y,z,A,L,B=b.matrixWorldInverse,E=0,F=0,C=0,J=0,k=0,l=f.length;k<l;k++)if(m=f[k],y=m.color,z=\nm.intensity,A=m.distance,L=m.shadow&&m.shadow.map?m.shadow.map.texture:null,m instanceof Z.AmbientLight)p+=y.r*z,t+=y.g*z,w+=y.b*z;else if(m instanceof Z.DirectionalLight){g=$c.get(m);g.color.copy(m.color).multiplyScalar(m.intensity);Qf(g.direction,m.matrixWorld);Qf(Qa,m.target.matrixWorld);g.direction.sub(Qa);Rf(g.direction,B);if(g.shadow=m.castShadow)g.shadowBias=m.shadow.bias,g.shadowRadius=m.shadow.radius,g.shadowMapSize=m.shadow.mapSize;X.directionalShadowMap[E]=L;X.directionalShadowMatrix[E]=\nm.shadow.matrix;X.directional[E++]=g}else if(m instanceof Z.SpotLight){g=$c.get(m);Qf(g.position,m.matrixWorld);g.position.applyMatrix4(B);g.color.copy(y).multiplyScalar(z);g.distance=A;Qf(g.direction,m.matrixWorld);Qf(Qa,m.target.matrixWorld);g.direction.sub(Qa);Rf(g.direction,B);g.coneCos=Math.cos(m.angle);g.penumbraCos=Math.cos(m.angle*(1-m.penumbra));g.decay=0===m.distance?0:m.decay;if(g.shadow=m.castShadow)g.shadowBias=m.shadow.bias,g.shadowRadius=m.shadow.radius,g.shadowMapSize=m.shadow.mapSize;\nX.spotShadowMap[C]=L;X.spotShadowMatrix[C]=m.shadow.matrix;X.spot[C++]=g}else if(m instanceof Z.PointLight){g=$c.get(m);Qf(g.position,m.matrixWorld);g.position.applyMatrix4(B);g.color.copy(m.color).multiplyScalar(m.intensity);g.distance=m.distance;g.decay=0===m.distance?0:m.decay;if(g.shadow=m.castShadow)g.shadowBias=m.shadow.bias,g.shadowRadius=m.shadow.radius,g.shadowMapSize=m.shadow.mapSize;X.pointShadowMap[F]=L;void 0===X.pointShadowMatrix[F]&&(X.pointShadowMatrix[F]=new Z.Matrix4);Qf(Qa,m.matrixWorld).negate();\nX.pointShadowMatrix[F].identity().setPosition(Qa);X.point[F++]=g}else m instanceof Z.HemisphereLight&&(g=$c.get(m),Qf(g.direction,m.matrixWorld),Rf(g.direction,B),g.direction.normalize(),g.skyColor.copy(m.color).multiplyScalar(z),g.groundColor.copy(m.groundColor).multiplyScalar(z),X.hemi[J++]=g);X.ambient[0]=p;X.ambient[1]=t;X.ambient[2]=w;X.directional.length=E;X.spot.length=C;X.point.length=F;X.hemi.length=J;X.hash=E+\",\"+F+\",\"+C+\",\"+J+\",\"+X.shadows.length;Xc&&ob.endShadows();Lb.calls=0;Lb.vertices=\n0;Lb.faces=0;Lb.points=0;void 0===c&&(c=null);this.setRenderTarget(c);(this.autoClear||d)&&this.clear(this.autoClearColor,this.autoClearDepth,this.autoClearStencil);a.overrideMaterial?(d=a.overrideMaterial,v(N,b,e,d),v(la,b,e,d)):(P.setBlending(Z.NoBlending),v(N,b,e),v(la,b,e));Qg.render(a,b);Rg.render(a,b,Ac);c&&(a=c.texture,a.generateMipmaps&&D(c)&&a.minFilter!==Z.NearestFilter&&a.minFilter!==Z.LinearFilter&&(a=c instanceof Z.WebGLRenderTargetCube?x.TEXTURE_CUBE_MAP:x.TEXTURE_2D,c=ca.get(c.texture).__webglTexture,\nP.bindTexture(a,c),x.generateMipmap(a),P.bindTexture(a,null)));P.setDepthTest(!0);P.setDepthWrite(!0);P.setColorWrite(!0)}};this.setFaceCulling=function(a,b){P.setCullFace(a);P.setFlipSided(b===Z.FrontFaceDirectionCW)};this.allocTextureUnit=function(){var a=Jd;a>=pb.maxTextures&&console.warn(\"WebGLRenderer: trying to use \"+a+\" texture units while this GPU supports only \"+pb.maxTextures);Jd+=1;return a};this.setTexture2D=function(){var a=!1;return function(b,c){b instanceof Z.WebGLRenderTarget&&(a||\n(console.warn(\"THREE.WebGLRenderer.setTexture2D: don't use render targets as textures. Use their .texture property instead.\"),a=!0),b=b.texture);var d=ca.get(b);if(0<b.version&&d.__version!==b.version){var e=b.image;if(void 0===e)console.warn(\"THREE.WebGLRenderer: Texture marked for update but image is undefined\",b);else if(!1===e.complete)console.warn(\"THREE.WebGLRenderer: Texture marked for update but image is incomplete\",b);else{void 0===d.__webglInit&&(d.__webglInit=!0,b.addEventListener(\"dispose\",\nf),d.__webglTexture=x.createTexture(),cc.textures++);P.activeTexture(x.TEXTURE0+c);P.bindTexture(x.TEXTURE_2D,d.__webglTexture);x.pixelStorei(x.UNPACK_FLIP_Y_WEBGL,b.flipY);x.pixelStorei(x.UNPACK_PREMULTIPLY_ALPHA_WEBGL,b.premultiplyAlpha);x.pixelStorei(x.UNPACK_ALIGNMENT,b.unpackAlignment);var g=A(b.image,pb.maxTextureSize);(b.wrapS!==Z.ClampToEdgeWrapping||b.wrapT!==Z.ClampToEdgeWrapping||b.minFilter!==Z.NearestFilter&&b.minFilter!==Z.LinearFilter)&&!1===D(g)&&(c=g,c instanceof HTMLImageElement||\nc instanceof HTMLCanvasElement?(e=document.createElement(\"canvas\"),e.width=Z.Math.nearestPowerOfTwo(c.width),e.height=Z.Math.nearestPowerOfTwo(c.height),e.getContext(\"2d\").drawImage(c,0,0,e.width,e.height),console.warn(\"THREE.WebGLRenderer: image is not power of two (\"+c.width+\"x\"+c.height+\"). Resized to \"+e.width+\"x\"+e.height,c),g=e):g=c);c=D(g);var e=H(b.format),k=H(b.type);B(x.TEXTURE_2D,b,c);var l=b.mipmaps;if(b instanceof Z.DepthTexture){l=x.DEPTH_COMPONENT;if(b.type===Z.FloatType){if(!ff)throw Error(\"Float Depth Texture only supported in WebGL2.0\");\nl=x.DEPTH_COMPONENT32F}else ff&&(l=x.DEPTH_COMPONENT16);P.texImage2D(x.TEXTURE_2D,0,l,g.width,g.height,0,e,k,null)}else if(b instanceof Z.DataTexture)if(0<l.length&&c){for(var m=0,n=l.length;m<n;m++)g=l[m],P.texImage2D(x.TEXTURE_2D,m,e,g.width,g.height,0,e,k,g.data);b.generateMipmaps=!1}else P.texImage2D(x.TEXTURE_2D,0,e,g.width,g.height,0,e,k,g.data);else if(b instanceof Z.CompressedTexture)for(m=0,n=l.length;m<n;m++)g=l[m],b.format!==Z.RGBAFormat&&b.format!==Z.RGBFormat?-1<P.getCompressedTextureFormats().indexOf(e)?\nP.compressedTexImage2D(x.TEXTURE_2D,m,e,g.width,g.height,0,g.data):console.warn(\"THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()\"):P.texImage2D(x.TEXTURE_2D,m,e,g.width,g.height,0,e,k,g.data);else if(0<l.length&&c){m=0;for(n=l.length;m<n;m++)g=l[m],P.texImage2D(x.TEXTURE_2D,m,e,e,k,g);b.generateMipmaps=!1}else P.texImage2D(x.TEXTURE_2D,0,e,e,k,g);b.generateMipmaps&&c&&x.generateMipmap(x.TEXTURE_2D);d.__version=b.version;if(b.onUpdate)b.onUpdate(b)}}else P.activeTexture(x.TEXTURE0+\nc),P.bindTexture(x.TEXTURE_2D,d.__webglTexture)}}();this.setTexture=function(){var a=!1;return function(b,c){a||(console.warn(\"THREE.WebGLRenderer: .setTexture is deprecated, use setTexture2D instead.\"),a=!0);oa.setTexture2D(b,c)}}();this.setTextureCube=function(){var a=!1;return function(b,c){b instanceof Z.WebGLRenderTargetCube&&(a||(console.warn(\"THREE.WebGLRenderer.setTextureCube: don't use cube render targets as textures. Use their .texture property instead.\"),a=!0),b=b.texture);if(b instanceof\nZ.CubeTexture||Array.isArray(b.image)&&6===b.image.length){var d=ca.get(b);if(6===b.image.length)if(0<b.version&&d.__version!==b.version){d.__image__webglTextureCube||(b.addEventListener(\"dispose\",f),d.__image__webglTextureCube=x.createTexture(),cc.textures++);P.activeTexture(x.TEXTURE0+c);P.bindTexture(x.TEXTURE_CUBE_MAP,d.__image__webglTextureCube);x.pixelStorei(x.UNPACK_FLIP_Y_WEBGL,b.flipY);c=b instanceof Z.CompressedTexture;for(var e=b.image[0]instanceof Z.DataTexture,g=[],k=0;6>k;k++)g[k]=!oa.autoScaleCubemaps||\nc||e?e?b.image[k].image:b.image[k]:A(b.image[k],pb.maxCubemapSize);var l=D(g[0]),m=H(b.format),n=H(b.type);B(x.TEXTURE_CUBE_MAP,b,l);for(k=0;6>k;k++)if(c)for(var p,q=g[k].mipmaps,r=0,t=q.length;r<t;r++)p=q[r],b.format!==Z.RGBAFormat&&b.format!==Z.RGBFormat?-1<P.getCompressedTextureFormats().indexOf(m)?P.compressedTexImage2D(x.TEXTURE_CUBE_MAP_POSITIVE_X+k,r,m,p.width,p.height,0,p.data):console.warn(\"THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setTextureCube()\"):\nP.texImage2D(x.TEXTURE_CUBE_MAP_POSITIVE_X+k,r,m,p.width,p.height,0,m,n,p.data);else e?P.texImage2D(x.TEXTURE_CUBE_MAP_POSITIVE_X+k,0,m,g[k].width,g[k].height,0,m,n,g[k].data):P.texImage2D(x.TEXTURE_CUBE_MAP_POSITIVE_X+k,0,m,m,n,g[k]);b.generateMipmaps&&l&&x.generateMipmap(x.TEXTURE_CUBE_MAP);d.__version=b.version;if(b.onUpdate)b.onUpdate(b)}else P.activeTexture(x.TEXTURE0+c),P.bindTexture(x.TEXTURE_CUBE_MAP,d.__image__webglTextureCube)}else P.activeTexture(x.TEXTURE0+c),P.bindTexture(x.TEXTURE_CUBE_MAP,\nca.get(b).__webglTexture)}}();this.getCurrentRenderTarget=function(){return Db};this.setRenderTarget=function(a){if((Db=a)&&void 0===ca.get(a).__webglFramebuffer){var b=ca.get(a),c=ca.get(a.texture);a.addEventListener(\"dispose\",g);c.__webglTexture=x.createTexture();cc.textures++;var d=a instanceof Z.WebGLRenderTargetCube,e=Z.Math.isPowerOfTwo(a.width)&&Z.Math.isPowerOfTwo(a.height);if(d){b.__webglFramebuffer=[];for(var f=0;6>f;f++)b.__webglFramebuffer[f]=x.createFramebuffer()}else b.__webglFramebuffer=\nx.createFramebuffer();if(d){P.bindTexture(x.TEXTURE_CUBE_MAP,c.__webglTexture);B(x.TEXTURE_CUBE_MAP,a.texture,e);for(f=0;6>f;f++)E(b.__webglFramebuffer[f],a,x.COLOR_ATTACHMENT0,x.TEXTURE_CUBE_MAP_POSITIVE_X+f);a.texture.generateMipmaps&&e&&x.generateMipmap(x.TEXTURE_CUBE_MAP);P.bindTexture(x.TEXTURE_CUBE_MAP,null)}else P.bindTexture(x.TEXTURE_2D,c.__webglTexture),B(x.TEXTURE_2D,a.texture,e),E(b.__webglFramebuffer,a,x.COLOR_ATTACHMENT0,x.TEXTURE_2D),a.texture.generateMipmaps&&e&&x.generateMipmap(x.TEXTURE_2D),\nP.bindTexture(x.TEXTURE_2D,null);if(a.depthBuffer){b=ca.get(a);c=a instanceof Z.WebGLRenderTargetCube;if(a.depthTexture){if(c)throw Error(\"target.depthTexture not supported in Cube render targets\");if(a instanceof Z.WebGLRenderTargetCube)throw Error(\"Depth Texture with cube render targets is not supported!\");x.bindFramebuffer(x.FRAMEBUFFER,b.__webglFramebuffer);if(!(a.depthTexture instanceof Z.DepthTexture))throw Error(\"renderTarget.depthTexture must be an instance of THREE.DepthTexture\");ca.get(a.depthTexture).__webglTexture&&\na.depthTexture.image.width===a.width&&a.depthTexture.image.height===a.height||(a.depthTexture.image.width=a.width,a.depthTexture.image.height=a.height,a.depthTexture.needsUpdate=!0);oa.setTexture2D(a.depthTexture,0);b=ca.get(a.depthTexture).__webglTexture;x.framebufferTexture2D(x.FRAMEBUFFER,x.DEPTH_ATTACHMENT,x.TEXTURE_2D,b,0)}else if(c)for(b.__webglDepthbuffer=[],c=0;6>c;c++)x.bindFramebuffer(x.FRAMEBUFFER,b.__webglFramebuffer[c]),b.__webglDepthbuffer[c]=x.createRenderbuffer(),F(b.__webglDepthbuffer[c],\na);else x.bindFramebuffer(x.FRAMEBUFFER,b.__webglFramebuffer),b.__webglDepthbuffer=x.createRenderbuffer(),F(b.__webglDepthbuffer,a);x.bindFramebuffer(x.FRAMEBUFFER,null)}}b=a instanceof Z.WebGLRenderTargetCube;a?(c=ca.get(a),c=b?c.__webglFramebuffer[a.activeCubeFace]:c.__webglFramebuffer,Vc.copy(a.scissor),Ld=a.scissorTest,Ac.copy(a.viewport)):(c=null,Vc.copy(Hd).multiplyScalar($a),Ld=ef,Ac.copy(Bc).multiplyScalar($a));ec!==c&&(x.bindFramebuffer(x.FRAMEBUFFER,c),ec=c);P.scissor(Vc);P.setScissorTest(Ld);\nP.viewport(Ac);b&&(b=ca.get(a.texture),x.framebufferTexture2D(x.FRAMEBUFFER,x.COLOR_ATTACHMENT0,x.TEXTURE_CUBE_MAP_POSITIVE_X+a.activeCubeFace,b.__webglTexture,a.activeMipMapLevel))};this.readRenderTargetPixels=function(a,b,c,d,e,f){if(!1===a instanceof Z.WebGLRenderTarget)console.error(\"THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.\");else{var g=ca.get(a).__webglFramebuffer;if(g){var k=!1;g!==ec&&(x.bindFramebuffer(x.FRAMEBUFFER,g),k=!0);try{var l=a.texture;\nl.format!==Z.RGBAFormat&&H(l.format)!==x.getParameter(x.IMPLEMENTATION_COLOR_READ_FORMAT)?console.error(\"THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format.\"):l.type===Z.UnsignedByteType||H(l.type)===x.getParameter(x.IMPLEMENTATION_COLOR_READ_TYPE)||l.type===Z.FloatType&&ja.get(\"WEBGL_color_buffer_float\")||l.type===Z.HalfFloatType&&ja.get(\"EXT_color_buffer_half_float\")?x.checkFramebufferStatus(x.FRAMEBUFFER)===x.FRAMEBUFFER_COMPLETE?0<=b&&b<=a.width-\nd&&0<=c&&c<=a.height-e&&x.readPixels(b,c,d,e,H(l.format),H(l.type),f):console.error(\"THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.\"):console.error(\"THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.\")}finally{k&&x.bindFramebuffer(x.FRAMEBUFFER,ec)}}}}};\nZ.WebGLRenderTarget=function(a,b,c){this.uuid=Z.Math.generateUUID();this.width=a;this.height=b;this.scissor=new Z.Vector4(0,0,a,b);this.scissorTest=!1;this.viewport=new Z.Vector4(0,0,a,b);c=c||{};void 0===c.minFilter&&(c.minFilter=Z.LinearFilter);this.texture=new Z.Texture(void 0,void 0,c.wrapS,c.wrapT,c.magFilter,c.minFilter,c.format,c.type,c.anisotropy,c.encoding);this.depthBuffer=void 0!==c.depthBuffer?c.depthBuffer:!0;this.stencilBuffer=void 0!==c.stencilBuffer?c.stencilBuffer:!0;this.depthTexture=\nnull};\nObject.assign(Z.WebGLRenderTarget.prototype,Z.EventDispatcher.prototype,{setSize:function(a,b){if(this.width!==a||this.height!==b)this.width=a,this.height=b,this.dispose();this.viewport.set(0,0,a,b);this.scissor.set(0,0,a,b)},clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.width=a.width;this.height=a.height;this.viewport.copy(a.viewport);this.texture=a.texture.clone();this.depthBuffer=a.depthBuffer;this.stencilBuffer=a.stencilBuffer;this.depthTexture=a.depthTexture;return this},\ndispose:function(){this.dispatchEvent({type:\"dispose\"})}});Z.WebGLRenderTargetCube=function(a,b,c){Z.WebGLRenderTarget.call(this,a,b,c);this.activeMipMapLevel=this.activeCubeFace=0};Z.WebGLRenderTargetCube.prototype=Object.create(Z.WebGLRenderTarget.prototype);Z.WebGLRenderTargetCube.prototype.constructor=Z.WebGLRenderTargetCube;\nZ.WebGLBufferRenderer=function(a,b,c){var d;this.setMode=function(a){d=a};this.render=function(b,f){a.drawArrays(d,b,f);c.calls++;c.vertices+=f;d===a.TRIANGLES&&(c.faces+=f/3)};this.renderInstances=function(e){var f=b.get(\"ANGLE_instanced_arrays\");if(null===f)console.error(\"THREE.WebGLBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.\");else{var g=e.attributes.position,g=g instanceof Z.InterleavedBufferAttribute?g.data.count:g.count;\nf.drawArraysInstancedANGLE(d,0,g,e.maxInstancedCount);c.calls++;c.vertices+=g*e.maxInstancedCount;d===a.TRIANGLES&&(c.faces+=e.maxInstancedCount*g/3)}}};\nZ.WebGLClipping=function(){function a(){m.value!==d&&(m.value=d,m.needsUpdate=0<e);c.numPlanes=e}function b(a,b,d,e){var f=null!==a?a.length:0,g=null;if(0!==f){g=m.value;if(!0!==e||null===g){e=d+4*f;b=b.matrixWorldInverse;Wf(l,b);if(null===g||g.length<e)g=new Float32Array(e);for(e=0;e!==f;++e,d+=4)k.copy(a[e]).applyMatrix4(b,l),k.normal.toArray(g,d),g[d+3]=k.constant}m.value=g;m.needsUpdate=!0}c.numPlanes=f;return g}var c=this,d=null,e=0,f=!1,g=!1,k=new Z.Plane,l=new Z.Matrix3,m={value:null,needsUpdate:!1};\nthis.uniform=m;this.numPlanes=0;this.init=function(a,c,g){var k=0!==a.length||c||0!==e||f;f=c;d=b(a,g,0);e=a.length;return k};this.beginShadows=function(){g=!0;b(null)};this.endShadows=function(){g=!1;a()};this.setState=function(c,k,l,t,r){if(!f||null===c||0===c.length||g&&!k)g?b(null):a();else{k=g?0:e;var n=4*k,p=t.clippingState||null;m.value=p;p=b(c,l,n,r);for(c=0;c!==n;++c)p[c]=d[c];t.clippingState=p;this.numPlanes+=k}}};\nZ.WebGLIndexedBufferRenderer=function(a,b,c){var d,e,f;this.setMode=function(a){d=a};this.setIndex=function(c){c.array instanceof Uint32Array&&b.get(\"OES_element_index_uint\")?(e=a.UNSIGNED_INT,f=4):(e=a.UNSIGNED_SHORT,f=2)};this.render=function(b,k){a.drawElements(d,k,e,b*f);c.calls++;c.vertices+=k;d===a.TRIANGLES&&(c.faces+=k/3)};this.renderInstances=function(g,k,l){var m=b.get(\"ANGLE_instanced_arrays\");null===m?console.error(\"THREE.WebGLBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.\"):\n(m.drawElementsInstancedANGLE(d,l,e,k*f,g.maxInstancedCount),c.calls++,c.vertices+=l*g.maxInstancedCount,d===a.TRIANGLES&&(c.faces+=g.maxInstancedCount*l/3))}};\nZ.WebGLExtensions=function(a){var b={};this.get=function(c){if(void 0!==b[c])return b[c];switch(c){case \"WEBGL_depth_texture\":var d=a.getExtension(\"WEBGL_depth_texture\")||a.getExtension(\"MOZ_WEBGL_depth_texture\")||a.getExtension(\"WEBKIT_WEBGL_depth_texture\");break;case \"EXT_texture_filter_anisotropic\":d=a.getExtension(\"EXT_texture_filter_anisotropic\")||a.getExtension(\"MOZ_EXT_texture_filter_anisotropic\")||a.getExtension(\"WEBKIT_EXT_texture_filter_anisotropic\");break;case \"WEBGL_compressed_texture_s3tc\":d=\na.getExtension(\"WEBGL_compressed_texture_s3tc\")||a.getExtension(\"MOZ_WEBGL_compressed_texture_s3tc\")||a.getExtension(\"WEBKIT_WEBGL_compressed_texture_s3tc\");break;case \"WEBGL_compressed_texture_pvrtc\":d=a.getExtension(\"WEBGL_compressed_texture_pvrtc\")||a.getExtension(\"WEBKIT_WEBGL_compressed_texture_pvrtc\");break;case \"WEBGL_compressed_texture_etc1\":d=a.getExtension(\"WEBGL_compressed_texture_etc1\");break;default:d=a.getExtension(c)}null===d&&console.warn(\"THREE.WebGLRenderer: \"+c+\" extension not supported.\");\nreturn b[c]=d}};\nZ.WebGLCapabilities=function(a,b,c){function d(b){if(\"highp\"===b){if(0<a.getShaderPrecisionFormat(a.VERTEX_SHADER,a.HIGH_FLOAT).precision&&0<a.getShaderPrecisionFormat(a.FRAGMENT_SHADER,a.HIGH_FLOAT).precision)return\"highp\";b=\"mediump\"}return\"mediump\"===b&&0<a.getShaderPrecisionFormat(a.VERTEX_SHADER,a.MEDIUM_FLOAT).precision&&0<a.getShaderPrecisionFormat(a.FRAGMENT_SHADER,a.MEDIUM_FLOAT).precision?\"mediump\":\"lowp\"}this.getMaxPrecision=d;this.precision=void 0!==c.precision?c.precision:\"highp\";this.logarithmicDepthBuffer=\nvoid 0!==c.logarithmicDepthBuffer?c.logarithmicDepthBuffer:!1;this.maxTextures=a.getParameter(a.MAX_TEXTURE_IMAGE_UNITS);this.maxVertexTextures=a.getParameter(a.MAX_VERTEX_TEXTURE_IMAGE_UNITS);this.maxTextureSize=a.getParameter(a.MAX_TEXTURE_SIZE);this.maxCubemapSize=a.getParameter(a.MAX_CUBE_MAP_TEXTURE_SIZE);this.maxAttributes=a.getParameter(a.MAX_VERTEX_ATTRIBS);this.maxVertexUniforms=a.getParameter(a.MAX_VERTEX_UNIFORM_VECTORS);this.maxVaryings=a.getParameter(a.MAX_VARYING_VECTORS);this.maxFragmentUniforms=\na.getParameter(a.MAX_FRAGMENT_UNIFORM_VECTORS);this.vertexTextures=0<this.maxVertexTextures;this.floatFragmentTextures=!!b.get(\"OES_texture_float\");this.floatVertexTextures=this.vertexTextures&&this.floatFragmentTextures;c=d(this.precision);c!==this.precision&&(console.warn(\"THREE.WebGLRenderer:\",this.precision,\"not supported, using\",c,\"instead.\"),this.precision=c);this.logarithmicDepthBuffer&&(this.logarithmicDepthBuffer=!!b.get(\"EXT_frag_depth\"))};\nZ.WebGLGeometries=function(a,b,c){function d(a){var g=a.target;a=f[g.id];null!==a.index&&e(a.index);var l=a.attributes;for(m in l)e(l[m]);g.removeEventListener(\"dispose\",d);delete f[g.id];var m=b.get(g);m.wireframe&&e(m.wireframe);b.delete(g);g=b.get(a);g.wireframe&&e(g.wireframe);b.delete(a);c.memory.geometries--}function e(c){var d=c instanceof Z.InterleavedBufferAttribute?b.get(c.data).__webglBuffer:b.get(c).__webglBuffer;void 0!==d&&(a.deleteBuffer(d),c instanceof Z.InterleavedBufferAttribute?\nb.delete(c.data):b.delete(c))}var f={};this.get=function(a){var b=a.geometry;if(void 0!==f[b.id])return f[b.id];b.addEventListener(\"dispose\",d);if(b instanceof Z.BufferGeometry)var e=b;else b instanceof Z.Geometry&&(void 0===b._bufferGeometry&&(b._bufferGeometry=(new Z.BufferGeometry).setFromObject(a)),e=b._bufferGeometry);f[b.id]=e;c.memory.geometries++;return e}};\nZ.WebGLLights=function(){var a={};this.get=function(b){if(void 0!==a[b.id])return a[b.id];switch(b.type){case \"DirectionalLight\":var c={direction:new Z.Vector3,color:new Z.Color,shadow:!1,shadowBias:0,shadowRadius:1,shadowMapSize:new Z.Vector2};break;case \"SpotLight\":c={position:new Z.Vector3,direction:new Z.Vector3,color:new Z.Color,distance:0,coneCos:0,penumbraCos:0,decay:0,shadow:!1,shadowBias:0,shadowRadius:1,shadowMapSize:new Z.Vector2};break;case \"PointLight\":c={position:new Z.Vector3,color:new Z.Color,\ndistance:0,decay:0,shadow:!1,shadowBias:0,shadowRadius:1,shadowMapSize:new Z.Vector2};break;case \"HemisphereLight\":c={direction:new Z.Vector3,skyColor:new Z.Color,groundColor:new Z.Color}}return a[b.id]=c}};\nZ.WebGLObjects=function(a,b,c){function d(c,d){c=c instanceof Z.InterleavedBufferAttribute?c.data:c;var e=b.get(c);void 0===e.__webglBuffer?(e.__webglBuffer=a.createBuffer(),a.bindBuffer(d,e.__webglBuffer),a.bufferData(d,c.array,c.dynamic?a.DYNAMIC_DRAW:a.STATIC_DRAW),e.version=c.version):e.version!==c.version&&(a.bindBuffer(d,e.__webglBuffer),!1===c.dynamic||-1===c.updateRange.count?a.bufferSubData(d,0,c.array):0===c.updateRange.count?console.error(\"THREE.WebGLObjects.updateBuffer: dynamic THREE.BufferAttribute marked as needsUpdate but updateRange.count is 0, ensure you are using set methods or updating manually.\"):\n(a.bufferSubData(d,c.updateRange.offset*c.array.BYTES_PER_ELEMENT,c.array.subarray(c.updateRange.offset,c.updateRange.offset+c.updateRange.count)),c.updateRange.count=0),e.version=c.version)}function e(a,b,c){if(b>c){var d=b;b=c;c=d}d=a[b];return void 0===d?(a[b]=[c],!0):-1===d.indexOf(c)?(d.push(c),!0):!1}var f=new Z.WebGLGeometries(a,b,c);this.getAttributeBuffer=function(a){return a instanceof Z.InterleavedBufferAttribute?b.get(a.data).__webglBuffer:b.get(a).__webglBuffer};this.getWireframeAttribute=\nfunction(c){var f=b.get(c);if(void 0!==f.wireframe)return f.wireframe;var g=[];var m=c.index;var n=c.attributes;c=n.position;if(null!==m){n={};var q=m.array;for(var p=0,t=q.length;p<t;p+=3){var r=q[p+0];var v=q[p+1];m=q[p+2];e(n,r,v)&&g.push(r,v);e(n,v,m)&&g.push(v,m);e(n,m,r)&&g.push(m,r)}}else for(q=n.position.array,p=0,t=q.length/3-1;p<t;p+=3)r=p+0,v=p+1,m=p+2,g.push(r,v,v,m,m,r);g=new Z.BufferAttribute(new (65535<c.count?Uint32Array:Uint16Array)(g),1);d(g,a.ELEMENT_ARRAY_BUFFER);return f.wireframe=\ng};this.update=function(b){var c=f.get(b);b.geometry instanceof Z.Geometry&&c.updateFromObject(b);b=c.index;var e=c.attributes;null!==b&&d(b,a.ELEMENT_ARRAY_BUFFER);for(var g in e)d(e[g],a.ARRAY_BUFFER);b=c.morphAttributes;for(g in b)for(var e=b[g],n=0,q=e.length;n<q;n++)d(e[n],a.ARRAY_BUFFER);return c}};\nZ.WebGLProgram=function(){function a(a){switch(a){case Z.LinearEncoding:return[\"Linear\",\"( value )\"];case Z.sRGBEncoding:return[\"sRGB\",\"( value )\"];case Z.RGBEEncoding:return[\"RGBE\",\"( value )\"];case Z.RGBM7Encoding:return[\"RGBM\",\"( value, 7.0 )\"];case Z.RGBM16Encoding:return[\"RGBM\",\"( value, 16.0 )\"];case Z.RGBDEncoding:return[\"RGBD\",\"( value, 256.0 )\"];case Z.GammaEncoding:return[\"Gamma\",\"( value, float( GAMMA_FACTOR ) )\"];default:throw Error(\"unsupported encoding: \"+a);}}function b(b,c){c=a(c);\nreturn\"vec4 \"+b+\"( vec4 value ) { return \"+c[0]+\"ToLinear\"+c[1]+\"; }\"}function c(b){b=a(b);return\"vec4 linearToOutputTexel( vec4 value ) { return LinearTo\"+b[0]+b[1]+\"; }\"}function d(a){switch(a){case Z.LinearToneMapping:a=\"Linear\";break;case Z.ReinhardToneMapping:a=\"Reinhard\";break;case Z.Uncharted2ToneMapping:a=\"Uncharted2\";break;case Z.CineonToneMapping:a=\"OptimizedCineon\";break;default:throw Error(\"unsupported toneMapping: \"+a);}return\"vec3 toneMapping( vec3 color ) { return \"+a+\"ToneMapping( color ); }\"}\nfunction e(a,b,c){a=a||{};return[a.derivatives||b.envMapCubeUV||b.bumpMap||b.normalMap||b.flatShading?\"#extension GL_OES_standard_derivatives : enable\":\"\",(a.fragDepth||b.logarithmicDepthBuffer)&&c.get(\"EXT_frag_depth\")?\"#extension GL_EXT_frag_depth : enable\":\"\",a.drawBuffers&&c.get(\"WEBGL_draw_buffers\")?\"#extension GL_EXT_draw_buffers : require\":\"\",(a.shaderTextureLOD||b.envMap)&&c.get(\"EXT_shader_texture_lod\")?\"#extension GL_EXT_shader_texture_lod : enable\":\"\"].filter(g).join(\"\\n\")}function f(a){var b=\n[],c;for(c in a){var d=a[c];!1!==d&&b.push(\"#define \"+c+\" \"+d)}return b.join(\"\\n\")}function g(a){return\"\"!==a}function k(a,b){return a.replace(/NUM_DIR_LIGHTS/g,b.numDirLights).replace(/NUM_SPOT_LIGHTS/g,b.numSpotLights).replace(/NUM_POINT_LIGHTS/g,b.numPointLights).replace(/NUM_HEMI_LIGHTS/g,b.numHemiLights)}function l(a){return a.replace(/#include +<([\\w\\d.]+)>/g,function(a,b){a=Z.ShaderChunk[b];if(void 0===a)throw Error(\"Can not resolve #include \\x3c\"+b+\"\\x3e\");return l(a)})}function m(a){return a.replace(/for \\( int i \\= (\\d+)\\; i < (\\d+)\\; i \\+\\+ \\) \\{([\\s\\S]+?)(?=\\})\\}/g,\nfunction(a,b,c,d){a=\"\";for(b=parseInt(b);b<parseInt(c);b++)a+=d.replace(/\\[ i \\]/g,\"[ \"+b+\" ]\");return a})}var n=0;return function(a,p,t,r){var q=a.context,w=t.extensions,z=t.defines,y=t.__webglShader.vertexShader,B=t.__webglShader.fragmentShader,A=\"SHADOWMAP_TYPE_BASIC\";r.shadowMapType===Z.PCFShadowMap?A=\"SHADOWMAP_TYPE_PCF\":r.shadowMapType===Z.PCFSoftShadowMap&&(A=\"SHADOWMAP_TYPE_PCF_SOFT\");var D=\"ENVMAP_TYPE_CUBE\",E=\"ENVMAP_MODE_REFLECTION\",F=\"ENVMAP_BLENDING_MULTIPLY\";if(r.envMap){switch(t.envMap.mapping){case Z.CubeReflectionMapping:case Z.CubeRefractionMapping:D=\n\"ENVMAP_TYPE_CUBE\";break;case Z.CubeUVReflectionMapping:case Z.CubeUVRefractionMapping:D=\"ENVMAP_TYPE_CUBE_UV\";break;case Z.EquirectangularReflectionMapping:case Z.EquirectangularRefractionMapping:D=\"ENVMAP_TYPE_EQUIREC\";break;case Z.SphericalReflectionMapping:D=\"ENVMAP_TYPE_SPHERE\"}switch(t.envMap.mapping){case Z.CubeRefractionMapping:case Z.EquirectangularRefractionMapping:E=\"ENVMAP_MODE_REFRACTION\"}switch(t.combine){case Z.MultiplyOperation:F=\"ENVMAP_BLENDING_MULTIPLY\";break;case Z.MixOperation:F=\n\"ENVMAP_BLENDING_MIX\";break;case Z.AddOperation:F=\"ENVMAP_BLENDING_ADD\"}}var I=0<a.gammaFactor?a.gammaFactor:1,w=e(w,r,a.extensions),H=f(z),C=q.createProgram();t instanceof Z.RawShaderMaterial?A=z=\"\":(z=[\"precision \"+r.precision+\" float;\",\"precision \"+r.precision+\" int;\",\"#define SHADER_NAME \"+t.__webglShader.name,H,r.supportsVertexTextures?\"#define VERTEX_TEXTURES\":\"\",\"#define GAMMA_FACTOR \"+I,\"#define MAX_BONES \"+r.maxBones,r.map?\"#define USE_MAP\":\"\",r.envMap?\"#define USE_ENVMAP\":\"\",r.envMap?\"#define \"+\nE:\"\",r.lightMap?\"#define USE_LIGHTMAP\":\"\",r.aoMap?\"#define USE_AOMAP\":\"\",r.emissiveMap?\"#define USE_EMISSIVEMAP\":\"\",r.bumpMap?\"#define USE_BUMPMAP\":\"\",r.normalMap?\"#define USE_NORMALMAP\":\"\",r.displacementMap&&r.supportsVertexTextures?\"#define USE_DISPLACEMENTMAP\":\"\",r.specularMap?\"#define USE_SPECULARMAP\":\"\",r.roughnessMap?\"#define USE_ROUGHNESSMAP\":\"\",r.metalnessMap?\"#define USE_METALNESSMAP\":\"\",r.alphaMap?\"#define USE_ALPHAMAP\":\"\",r.vertexColors?\"#define USE_COLOR\":\"\",r.flatShading?\"#define FLAT_SHADED\":\n\"\",r.skinning?\"#define USE_SKINNING\":\"\",r.useVertexTexture?\"#define BONE_TEXTURE\":\"\",r.morphTargets?\"#define USE_MORPHTARGETS\":\"\",r.morphNormals&&!1===r.flatShading?\"#define USE_MORPHNORMALS\":\"\",r.doubleSided?\"#define DOUBLE_SIDED\":\"\",r.flipSided?\"#define FLIP_SIDED\":\"\",\"#define NUM_CLIPPING_PLANES \"+r.numClippingPlanes,r.shadowMapEnabled?\"#define USE_SHADOWMAP\":\"\",r.shadowMapEnabled?\"#define \"+A:\"\",r.sizeAttenuation?\"#define USE_SIZEATTENUATION\":\"\",r.logarithmicDepthBuffer?\"#define USE_LOGDEPTHBUF\":\n\"\",r.logarithmicDepthBuffer&&a.extensions.get(\"EXT_frag_depth\")?\"#define USE_LOGDEPTHBUF_EXT\":\"\",\"uniform mat4 modelMatrix;\",\"uniform mat4 modelViewMatrix;\",\"uniform mat4 projectionMatrix;\",\"uniform mat4 viewMatrix;\",\"uniform mat3 normalMatrix;\",\"uniform vec3 cameraPosition;\",\"attribute vec3 position;\",\"attribute vec3 normal;\",\"attribute vec2 uv;\",\"#ifdef USE_COLOR\",\"\\tattribute vec3 color;\",\"#endif\",\"#ifdef USE_MORPHTARGETS\",\"\\tattribute vec3 morphTarget0;\",\"\\tattribute vec3 morphTarget1;\",\"\\tattribute vec3 morphTarget2;\",\n\"\\tattribute vec3 morphTarget3;\",\"\\t#ifdef USE_MORPHNORMALS\",\"\\t\\tattribute vec3 morphNormal0;\",\"\\t\\tattribute vec3 morphNormal1;\",\"\\t\\tattribute vec3 morphNormal2;\",\"\\t\\tattribute vec3 morphNormal3;\",\"\\t#else\",\"\\t\\tattribute vec3 morphTarget4;\",\"\\t\\tattribute vec3 morphTarget5;\",\"\\t\\tattribute vec3 morphTarget6;\",\"\\t\\tattribute vec3 morphTarget7;\",\"\\t#endif\",\"#endif\",\"#ifdef USE_SKINNING\",\"\\tattribute vec4 skinIndex;\",\"\\tattribute vec4 skinWeight;\",\"#endif\",\"\\n\"].filter(g).join(\"\\n\"),A=[w,\"precision \"+\nr.precision+\" float;\",\"precision \"+r.precision+\" int;\",\"#define SHADER_NAME \"+t.__webglShader.name,H,r.alphaTest?\"#define ALPHATEST \"+r.alphaTest:\"\",\"#define GAMMA_FACTOR \"+I,r.useFog&&r.fog?\"#define USE_FOG\":\"\",r.useFog&&r.fogExp?\"#define FOG_EXP2\":\"\",r.map?\"#define USE_MAP\":\"\",r.envMap?\"#define USE_ENVMAP\":\"\",r.envMap?\"#define \"+D:\"\",r.envMap?\"#define \"+E:\"\",r.envMap?\"#define \"+F:\"\",r.lightMap?\"#define USE_LIGHTMAP\":\"\",r.aoMap?\"#define USE_AOMAP\":\"\",r.emissiveMap?\"#define USE_EMISSIVEMAP\":\"\",r.bumpMap?\n\"#define USE_BUMPMAP\":\"\",r.normalMap?\"#define USE_NORMALMAP\":\"\",r.specularMap?\"#define USE_SPECULARMAP\":\"\",r.roughnessMap?\"#define USE_ROUGHNESSMAP\":\"\",r.metalnessMap?\"#define USE_METALNESSMAP\":\"\",r.alphaMap?\"#define USE_ALPHAMAP\":\"\",r.vertexColors?\"#define USE_COLOR\":\"\",r.flatShading?\"#define FLAT_SHADED\":\"\",r.doubleSided?\"#define DOUBLE_SIDED\":\"\",r.flipSided?\"#define FLIP_SIDED\":\"\",\"#define NUM_CLIPPING_PLANES \"+r.numClippingPlanes,r.shadowMapEnabled?\"#define USE_SHADOWMAP\":\"\",r.shadowMapEnabled?\n\"#define \"+A:\"\",r.premultipliedAlpha?\"#define PREMULTIPLIED_ALPHA\":\"\",r.physicallyCorrectLights?\"#define PHYSICALLY_CORRECT_LIGHTS\":\"\",r.logarithmicDepthBuffer?\"#define USE_LOGDEPTHBUF\":\"\",r.logarithmicDepthBuffer&&a.extensions.get(\"EXT_frag_depth\")?\"#define USE_LOGDEPTHBUF_EXT\":\"\",r.envMap&&a.extensions.get(\"EXT_shader_texture_lod\")?\"#define TEXTURE_LOD_EXT\":\"\",\"uniform mat4 viewMatrix;\",\"uniform vec3 cameraPosition;\",r.toneMapping!==Z.NoToneMapping?\"#define TONE_MAPPING\":\"\",r.toneMapping!==Z.NoToneMapping?\nZ.ShaderChunk.tonemapping_pars_fragment:\"\",r.toneMapping!==Z.NoToneMapping?d(r.toneMapping):\"\",r.outputEncoding||r.mapEncoding||r.envMapEncoding||r.emissiveMapEncoding?Z.ShaderChunk.encodings_pars_fragment:\"\",r.mapEncoding?b(\"mapTexelToLinear\",r.mapEncoding):\"\",r.envMapEncoding?b(\"envMapTexelToLinear\",r.envMapEncoding):\"\",r.emissiveMapEncoding?b(\"emissiveMapTexelToLinear\",r.emissiveMapEncoding):\"\",r.outputEncoding?c(r.outputEncoding):\"\",r.depthPacking?\"#define DEPTH_PACKING \"+t.depthPacking:\"\",\"\\n\"].filter(g).join(\"\\n\"));\ny=l(y);y=k(y,r);B=l(B);B=k(B,r);!1===t instanceof Z.ShaderMaterial&&(y=m(y),B=m(B));B=A+B;y=Z.WebGLShader(q,q.VERTEX_SHADER,z+y);B=Z.WebGLShader(q,q.FRAGMENT_SHADER,B);q.attachShader(C,y);q.attachShader(C,B);void 0!==t.index0AttributeName?q.bindAttribLocation(C,0,t.index0AttributeName):!0===r.morphTargets&&q.bindAttribLocation(C,0,\"position\");q.linkProgram(C);r=q.getProgramInfoLog(C);D=q.getShaderInfoLog(y);E=q.getShaderInfoLog(B);I=F=!0;if(!1===q.getProgramParameter(C,q.LINK_STATUS))F=!1,console.error(\"THREE.WebGLProgram: shader error: \",\nq.getError(),\"gl.VALIDATE_STATUS\",q.getProgramParameter(C,q.VALIDATE_STATUS),\"gl.getProgramInfoLog\",r,D,E);else if(\"\"!==r)console.warn(\"THREE.WebGLProgram: gl.getProgramInfoLog()\",r);else if(\"\"===D||\"\"===E)I=!1;I&&(this.diagnostics={runnable:F,material:t,programLog:r,vertexShader:{log:D,prefix:z},fragmentShader:{log:E,prefix:A}});q.deleteShader(y);q.deleteShader(B);var J;this.getUniforms=function(){void 0===J&&(J=new Z.WebGLUniforms(q,C,a));return J};var M;this.getAttributes=function(){if(void 0===\nM){for(var a={},b=q.getProgramParameter(C,q.ACTIVE_ATTRIBUTES),c=0;c<b;c++){var d=q.getActiveAttrib(C,c).name;a[d]=q.getAttribLocation(C,d)}M=a}return M};this.destroy=function(){q.deleteProgram(C);this.program=void 0};Object.defineProperties(this,{uniforms:{get:function(){console.warn(\"THREE.WebGLProgram: .uniforms is now .getUniforms().\");return this.getUniforms()}},attributes:{get:function(){console.warn(\"THREE.WebGLProgram: .attributes is now .getAttributes().\");return this.getAttributes()}}});\nthis.id=n++;this.code=p;this.usedTimes=1;this.program=C;this.vertexShader=y;this.fragmentShader=B;return this}}();\nZ.WebGLPrograms=function(a,b){function c(a,b){if(a)a instanceof Z.Texture?c=a.encoding:a instanceof Z.WebGLRenderTarget&&(console.warn(\"THREE.WebGLPrograms.getTextureEncodingFromMap: don't use render targets as textures. Use their .texture property instead.\"),c=a.texture.encoding);else var c=Z.LinearEncoding;c===Z.LinearEncoding&&b&&(c=Z.GammaEncoding);return c}var d=[],e={MeshDepthMaterial:\"depth\",MeshNormalMaterial:\"normal\",MeshBasicMaterial:\"basic\",MeshLambertMaterial:\"lambert\",MeshPhongMaterial:\"phong\",\nMeshStandardMaterial:\"physical\",MeshPhysicalMaterial:\"physical\",LineBasicMaterial:\"basic\",LineDashedMaterial:\"dashed\",PointsMaterial:\"points\"},f=\"precision supportsVertexTextures map mapEncoding envMap envMapMode envMapEncoding lightMap aoMap emissiveMap emissiveMapEncoding bumpMap normalMap displacementMap specularMap roughnessMap metalnessMap alphaMap combine vertexColors fog useFog fogExp flatShading sizeAttenuation logarithmicDepthBuffer skinning maxBones useVertexTexture morphTargets morphNormals maxMorphTargets maxMorphNormals premultipliedAlpha numDirLights numPointLights numSpotLights numHemiLights shadowMapEnabled shadowMapType toneMapping physicallyCorrectLights alphaTest doubleSided flipSided numClippingPlanes depthPacking\".split(\" \");\nthis.getParameters=function(d,f,l,m,n){var g=e[d.type];if(b.floatVertexTextures&&n&&n.skeleton&&n.skeleton.useVertexTexture)var k=1024;else k=Math.floor((b.maxVertexUniforms-20)/4),void 0!==n&&n instanceof Z.SkinnedMesh&&(k=Math.min(n.skeleton.bones.length,k),k<n.skeleton.bones.length&&console.warn(\"WebGLRenderer: too many bones - \"+n.skeleton.bones.length+\", this GPU supports just \"+k+\" (try OpenGL instead of ANGLE)\"));var t=a.getPrecision();null!==d.precision&&(t=b.getMaxPrecision(d.precision),\nt!==d.precision&&console.warn(\"THREE.WebGLProgram.getParameters:\",d.precision,\"not supported, using\",t,\"instead.\"));var r=a.getCurrentRenderTarget();return{shaderID:g,precision:t,supportsVertexTextures:b.vertexTextures,outputEncoding:c(r?r.texture:null,a.gammaOutput),map:!!d.map,mapEncoding:c(d.map,a.gammaInput),envMap:!!d.envMap,envMapMode:d.envMap&&d.envMap.mapping,envMapEncoding:c(d.envMap,a.gammaInput),envMapCubeUV:!!d.envMap&&(d.envMap.mapping===Z.CubeUVReflectionMapping||d.envMap.mapping===\nZ.CubeUVRefractionMapping),lightMap:!!d.lightMap,aoMap:!!d.aoMap,emissiveMap:!!d.emissiveMap,emissiveMapEncoding:c(d.emissiveMap,a.gammaInput),bumpMap:!!d.bumpMap,normalMap:!!d.normalMap,displacementMap:!!d.displacementMap,roughnessMap:!!d.roughnessMap,metalnessMap:!!d.metalnessMap,specularMap:!!d.specularMap,alphaMap:!!d.alphaMap,combine:d.combine,vertexColors:d.vertexColors,fog:l,useFog:d.fog,fogExp:l instanceof Z.FogExp2,flatShading:d.shading===Z.FlatShading,sizeAttenuation:d.sizeAttenuation,logarithmicDepthBuffer:b.logarithmicDepthBuffer,\nskinning:d.skinning,maxBones:k,useVertexTexture:b.floatVertexTextures&&n&&n.skeleton&&n.skeleton.useVertexTexture,morphTargets:d.morphTargets,morphNormals:d.morphNormals,maxMorphTargets:a.maxMorphTargets,maxMorphNormals:a.maxMorphNormals,numDirLights:f.directional.length,numPointLights:f.point.length,numSpotLights:f.spot.length,numHemiLights:f.hemi.length,numClippingPlanes:m,shadowMapEnabled:a.shadowMap.enabled&&n.receiveShadow&&0<f.shadows.length,shadowMapType:a.shadowMap.type,toneMapping:a.toneMapping,\nphysicallyCorrectLights:a.physicallyCorrectLights,premultipliedAlpha:d.premultipliedAlpha,alphaTest:d.alphaTest,doubleSided:d.side===Z.DoubleSide,flipSided:d.side===Z.BackSide,depthPacking:void 0!==d.depthPacking?d.depthPacking:!1}};this.getProgramCode=function(a,b){var c=[];b.shaderID?c.push(b.shaderID):(c.push(a.fragmentShader),c.push(a.vertexShader));if(void 0!==a.defines)for(var d in a.defines)c.push(d),c.push(a.defines[d]);for(a=0;a<f.length;a++)c.push(b[f[a]]);return c.join()};this.acquireProgram=\nfunction(b,c,e){for(var f,g=0,k=d.length;g<k;g++){var l=d[g];if(l.code===e){f=l;++f.usedTimes;break}}void 0===f&&(f=new Z.WebGLProgram(a,e,b,c),d.push(f));return f};this.releaseProgram=function(a){0===--a.usedTimes&&(d[d.indexOf(a)]=d[d.length-1],d.pop(),a.destroy())};this.programs=d};Z.WebGLProperties=function(){var a={};this.get=function(b){b=b.uuid;var c=a[b];void 0===c&&(c={},a[b]=c);return c};this.delete=function(b){delete a[b.uuid]};this.clear=function(){a={}}};\nZ.WebGLShader=function(){function a(a){a=a.split(\"\\n\");for(var b=0;b<a.length;b++)a[b]=b+1+\": \"+a[b];return a.join(\"\\n\")}return function(b,c,d){var e=b.createShader(c);b.shaderSource(e,d);b.compileShader(e);!1===b.getShaderParameter(e,b.COMPILE_STATUS)&&console.error(\"THREE.WebGLShader: Shader couldn't compile.\");\"\"!==b.getShaderInfoLog(e)&&console.warn(\"THREE.WebGLShader: gl.getShaderInfoLog()\",c===b.VERTEX_SHADER?\"vertex\":\"fragment\",b.getShaderInfoLog(e),a(d));return e}}();\nZ.WebGLShadowMap=function(a,b,c){function d(b,c,d,e){var f=b.geometry,g=r,k=b.customDepthMaterial;d&&(g=v,k=b.customDistanceMaterial);k?f=k:(b=b instanceof Z.SkinnedMesh&&c.skinning,k=0,void 0!==f.morphTargets&&0<f.morphTargets.length&&c.morphTargets&&(k|=1),b&&(k|=2),f=g[k]);a.localClippingEnabled&&!0===c.clipShadows&&0!==c.clippingPlanes.length&&(k=f.uuid,g=c.uuid,b=w[k],void 0===b&&(b={},w[k]=b),k=b[g],void 0===k&&(k=f.clone(),b[g]=k),f=k);f.visible=c.visible;f.wireframe=c.wireframe;g=c.side;C.renderSingleSided&&\ng==Z.DoubleSide&&(g=Z.FrontSide);C.renderReverseSided&&(g===Z.FrontSide?g=Z.BackSide:g===Z.BackSide&&(g=Z.FrontSide));f.side=g;f.clipShadows=c.clipShadows;f.clippingPlanes=c.clippingPlanes;f.wireframeLinewidth=c.wireframeLinewidth;f.linewidth=c.linewidth;d&&void 0!==f.uniforms.lightPos&&f.uniforms.lightPos.value.copy(e);return f}function e(a,b,c){if(!1!==a.visible){a.layers.test(b.layers)&&(a instanceof Z.Mesh||a instanceof Z.Line||a instanceof Z.Points)&&a.castShadow&&(!1===a.frustumCulled||!0===\nk.intersectsObject(a))&&!0===a.material.visible&&(Nf(a.modelViewMatrix,c.matrixWorldInverse,a.matrixWorld),t.push(a));a=a.children;for(var d=0,f=a.length;d<f;d++)e(a[d],b,c)}}var f=a.context,g=a.state,k=new Z.Frustum,l=new Z.Matrix4,m=b.shadows,n=new Z.Vector2,q=new Z.Vector3,p=new Z.Vector3,t=[],r=Array(4),v=Array(4),w={},z=[new Z.Vector3(1,0,0),new Z.Vector3(-1,0,0),new Z.Vector3(0,0,1),new Z.Vector3(0,0,-1),new Z.Vector3(0,1,0),new Z.Vector3(0,-1,0)],y=[new Z.Vector3(0,1,0),new Z.Vector3(0,1,0),\nnew Z.Vector3(0,1,0),new Z.Vector3(0,1,0),new Z.Vector3(0,0,1),new Z.Vector3(0,0,-1)],B=[new Z.Vector4,new Z.Vector4,new Z.Vector4,new Z.Vector4,new Z.Vector4,new Z.Vector4];b=new Z.MeshDepthMaterial;b.depthPacking=Z.RGBADepthPacking;b.clipping=!0;for(var A=Z.ShaderLib.distanceRGBA,D=Z.UniformsUtils.clone(A.uniforms),E=0;4!==E;++E){var F=0!==(E&1),I=0!==(E&2),H=b.clone();H.morphTargets=F;H.skinning=I;r[E]=H;F=new Z.ShaderMaterial({defines:{USE_SHADOWMAP:\"\"},uniforms:D,vertexShader:A.vertexShader,\nfragmentShader:A.fragmentShader,morphTargets:F,skinning:I,clipping:!0});v[E]=F}var C=this;this.enabled=!1;this.autoUpdate=!0;this.needsUpdate=!1;this.type=Z.PCFShadowMap;this.renderSingleSided=this.renderReverseSided=!0;this.render=function(b,r){if(!1!==C.enabled&&(!1!==C.autoUpdate||!1!==C.needsUpdate)&&0!==m.length){g.clearColor(1,1,1,1);g.disable(f.BLEND);g.setDepthTest(!0);g.setScissorTest(!1);for(var v,w,A=0,E=m.length;A<E;A++){var D=m[A],K=D.shadow;if(void 0===K)console.warn(\"THREE.WebGLShadowMap:\",\nD,\"has no shadow.\");else{var N=K.camera;n.copy(K.mapSize);if(D instanceof Z.PointLight){v=6;w=!0;var F=n.x;var H=n.y;B[0].set(2*F,H,F,H);B[1].set(0,H,F,H);B[2].set(3*F,H,F,H);B[3].set(F,H,F,H);B[4].set(3*F,0,F,H);B[5].set(F,0,F,H);n.x*=4;n.y*=2}else v=1,w=!1;null===K.map&&(K.map=new Z.WebGLRenderTarget(n.x,n.y,{minFilter:Z.NearestFilter,magFilter:Z.NearestFilter,format:Z.RGBAFormat}),N.updateProjectionMatrix());K instanceof Z.SpotLightShadow&&K.update(D);F=K.map;K=K.matrix;Qf(p,D.matrixWorld);N.position.copy(p);\na.setRenderTarget(F);a.clear();for(var sa=0;sa<v;sa++){w?(q.copy(N.position),q.add(z[sa]),N.up.copy(y[sa]),N.lookAt(q),g.viewport(B[sa])):(Qf(q,D.target.matrixWorld),N.lookAt(q));N.updateMatrixWorld();N.matrixWorldInverse.getInverse(N.matrixWorld);K.set(.5,0,0,.5,0,.5,0,.5,0,0,.5,.5,0,0,0,1);K.multiply(N.projectionMatrix);K.multiply(N.matrixWorldInverse);Nf(l,N.projectionMatrix,N.matrixWorldInverse);bg(k,l);t.length=0;e(b,r,N);for(var I=0,J=t.length;I<J;I++){H=t[I];var M=c.update(H);var oa=H.material;\nif(oa instanceof Z.MultiMaterial){F=M.groups;var Cc=oa.materials;for(var Db=0,ec=F.length;Db<ec;Db++){oa=F[Db];var Va=Cc[oa.materialIndex];!0===Va.visible&&(Va=d(H,Va,w,p),a.renderBufferDirect(N,null,M,Va,H,oa))}}else Va=d(H,oa,w,p),a.renderBufferDirect(N,null,M,Va,H,null)}}}}a.setClearColor(a.getClearColor(),a.getClearAlpha());C.needsUpdate=!1}}};\nZ.WebGLState=function(a,b,c){function d(b,c,d){var e=new Uint8Array(3),f=a.createTexture();a.bindTexture(b,f);a.texParameteri(b,a.TEXTURE_MIN_FILTER,a.NEAREST);a.texParameteri(b,a.TEXTURE_MAG_FILTER,a.NEAREST);for(b=0;b<d;b++)a.texImage2D(c+b,0,a.RGB,1,1,0,a.RGB,a.UNSIGNED_BYTE,e);return f}var e=this;this.buffers={color:new Z.WebGLColorBuffer(a),depth:new Z.WebGLDepthBuffer(a,this),stencil:new Z.WebGLStencilBuffer(a,this)};var f=a.getParameter(a.MAX_VERTEX_ATTRIBS),g=new Uint8Array(f),k=new Uint8Array(f),\nl=new Uint8Array(f),m={},n=null,q=null,p=null,t=null,r=null,v=null,w=null,z=null,y=!1,B=null,A=null,D=null,E=null,F=null,I=null,H=a.getParameter(a.MAX_TEXTURE_IMAGE_UNITS),C=null,J={},M=new Z.Vector4,T=new Z.Vector4,U={};U[a.TEXTURE_2D]=d(a.TEXTURE_2D,a.TEXTURE_2D,1);U[a.TEXTURE_CUBE_MAP]=d(a.TEXTURE_CUBE_MAP,a.TEXTURE_CUBE_MAP_POSITIVE_X,6);this.init=function(){this.clearColor(0,0,0,1);this.clearDepth(1);this.clearStencil(0);this.enable(a.DEPTH_TEST);this.setDepthFunc(Z.LessEqualDepth);this.setFlipSided(!1);\nthis.setCullFace(Z.CullFaceBack);this.enable(a.CULL_FACE);this.enable(a.BLEND);this.setBlending(Z.NormalBlending)};this.initAttributes=function(){for(var a=0,b=g.length;a<b;a++)g[a]=0};this.enableAttribute=function(c){g[c]=1;0===k[c]&&(a.enableVertexAttribArray(c),k[c]=1);0!==l[c]&&(b.get(\"ANGLE_instanced_arrays\").vertexAttribDivisorANGLE(c,0),l[c]=0)};this.enableAttributeAndDivisor=function(b,c,d){g[b]=1;0===k[b]&&(a.enableVertexAttribArray(b),k[b]=1);l[b]!==c&&(d.vertexAttribDivisorANGLE(b,c),l[b]=\nc)};this.disableUnusedAttributes=function(){for(var b=0,c=k.length;b!==c;++b)k[b]!==g[b]&&(a.disableVertexAttribArray(b),k[b]=0)};this.enable=function(b){!0!==m[b]&&(a.enable(b),m[b]=!0)};this.disable=function(b){!1!==m[b]&&(a.disable(b),m[b]=!1)};this.getCompressedTextureFormats=function(){if(null===n&&(n=[],b.get(\"WEBGL_compressed_texture_pvrtc\")||b.get(\"WEBGL_compressed_texture_s3tc\")||b.get(\"WEBGL_compressed_texture_etc1\")))for(var c=a.getParameter(a.COMPRESSED_TEXTURE_FORMATS),d=0;d<c.length;d++)n.push(c[d]);\nreturn n};this.setBlending=function(b,d,e,f,g,k,l,m){if(b!==Z.NoBlending){this.enable(a.BLEND);if(b!==q||m!==y)b===Z.AdditiveBlending?m?(a.blendEquationSeparate(a.FUNC_ADD,a.FUNC_ADD),a.blendFuncSeparate(a.ONE,a.ONE,a.ONE,a.ONE)):(a.blendEquation(a.FUNC_ADD),a.blendFunc(a.SRC_ALPHA,a.ONE)):b===Z.SubtractiveBlending?m?(a.blendEquationSeparate(a.FUNC_ADD,a.FUNC_ADD),a.blendFuncSeparate(a.ZERO,a.ZERO,a.ONE_MINUS_SRC_COLOR,a.ONE_MINUS_SRC_ALPHA)):(a.blendEquation(a.FUNC_ADD),a.blendFunc(a.ZERO,a.ONE_MINUS_SRC_COLOR)):\nb===Z.MultiplyBlending?m?(a.blendEquationSeparate(a.FUNC_ADD,a.FUNC_ADD),a.blendFuncSeparate(a.ZERO,a.SRC_COLOR,a.ZERO,a.SRC_ALPHA)):(a.blendEquation(a.FUNC_ADD),a.blendFunc(a.ZERO,a.SRC_COLOR)):m?(a.blendEquationSeparate(a.FUNC_ADD,a.FUNC_ADD),a.blendFuncSeparate(a.ONE,a.ONE_MINUS_SRC_ALPHA,a.ONE,a.ONE_MINUS_SRC_ALPHA)):(a.blendEquationSeparate(a.FUNC_ADD,a.FUNC_ADD),a.blendFuncSeparate(a.SRC_ALPHA,a.ONE_MINUS_SRC_ALPHA,a.ONE,a.ONE_MINUS_SRC_ALPHA)),q=b,y=m;if(b===Z.CustomBlending){g=g||d;k=k||e;\nl=l||f;if(d!==p||g!==v)a.blendEquationSeparate(c(d),c(g)),p=d,v=g;if(e!==t||f!==r||k!==w||l!==z)a.blendFuncSeparate(c(e),c(f),c(k),c(l)),t=e,r=f,w=k,z=l}else z=w=v=r=t=p=null}else this.disable(a.BLEND),q=b};this.setColorWrite=function(a){this.buffers.color.setMask(a)};this.setDepthTest=function(a){this.buffers.depth.setTest(a)};this.setDepthWrite=function(a){this.buffers.depth.setMask(a)};this.setDepthFunc=function(a){this.buffers.depth.setFunc(a)};this.setStencilTest=function(a){this.buffers.stencil.setTest(a)};\nthis.setStencilWrite=function(a){this.buffers.stencil.setMask(a)};this.setStencilFunc=function(a,b,c){this.buffers.stencil.setFunc(a,b,c)};this.setStencilOp=function(a,b,c){this.buffers.stencil.setOp(a,b,c)};this.setFlipSided=function(b){B!==b&&(b?a.frontFace(a.CW):a.frontFace(a.CCW),B=b)};this.setCullFace=function(b){b!==Z.CullFaceNone?(this.enable(a.CULL_FACE),b!==A&&(b===Z.CullFaceBack?a.cullFace(a.BACK):b===Z.CullFaceFront?a.cullFace(a.FRONT):a.cullFace(a.FRONT_AND_BACK))):this.disable(a.CULL_FACE);\nA=b};this.setLineWidth=function(b){b!==D&&(a.lineWidth(b),D=b)};this.setPolygonOffset=function(b,c,d){if(b){if(this.enable(a.POLYGON_OFFSET_FILL),E!==c||F!==d)a.polygonOffset(c,d),E=c,F=d}else this.disable(a.POLYGON_OFFSET_FILL)};this.getScissorTest=function(){return I};this.setScissorTest=function(b){(I=b)?this.enable(a.SCISSOR_TEST):this.disable(a.SCISSOR_TEST)};this.activeTexture=function(b){void 0===b&&(b=a.TEXTURE0+H-1);C!==b&&(a.activeTexture(b),C=b)};this.bindTexture=function(b,c){null===C&&\ne.activeTexture();var d=J[C];void 0===d&&(d={type:void 0,texture:void 0},J[C]=d);if(d.type!==b||d.texture!==c)a.bindTexture(b,c||U[b]),d.type=b,d.texture=c};this.compressedTexImage2D=function(){try{a.compressedTexImage2D.apply(a,arguments)}catch(L){console.error(L)}};this.texImage2D=function(){try{a.texImage2D.apply(a,arguments)}catch(L){console.error(L)}};this.clearColor=function(a,b,c,d){this.buffers.color.setClear(a,b,c,d)};this.clearDepth=function(a){this.buffers.depth.setClear(a)};this.clearStencil=\nfunction(a){this.buffers.stencil.setClear(a)};this.scissor=function(b){!1===M.equals(b)&&(a.scissor(b.x,b.y,b.z,b.w),M.copy(b))};this.viewport=function(b){!1===T.equals(b)&&(a.viewport(b.x,b.y,b.z,b.w),T.copy(b))};this.reset=function(){for(var b=0;b<k.length;b++)1===k[b]&&(a.disableVertexAttribArray(b),k[b]=0);m={};C=n=null;J={};A=B=q=null;this.buffers.color.reset();this.buffers.depth.reset();this.buffers.stencil.reset()}};\nZ.WebGLColorBuffer=function(a){var b=!1,c=new Z.Vector4,d=null,e=new Z.Vector4;this.setMask=function(c){d===c||b||(a.colorMask(c,c,c,c),d=c)};this.setLocked=function(a){b=a};this.setClear=function(b,d,k,l){c.set(b,d,k,l);!1===e.equals(c)&&(a.clearColor(b,d,k,l),e.copy(c))};this.reset=function(){b=!1;d=null;e=new Z.Vector4}};\nZ.WebGLDepthBuffer=function(a,b){var c=!1,d=null,e=null,f=null;this.setTest=function(c){c?b.enable(a.DEPTH_TEST):b.disable(a.DEPTH_TEST)};this.setMask=function(b){d===b||c||(a.depthMask(b),d=b)};this.setFunc=function(b){if(e!==b){if(b)switch(b){case Z.NeverDepth:a.depthFunc(a.NEVER);break;case Z.AlwaysDepth:a.depthFunc(a.ALWAYS);break;case Z.LessDepth:a.depthFunc(a.LESS);break;case Z.LessEqualDepth:a.depthFunc(a.LEQUAL);break;case Z.EqualDepth:a.depthFunc(a.EQUAL);break;case Z.GreaterEqualDepth:a.depthFunc(a.GEQUAL);\nbreak;case Z.GreaterDepth:a.depthFunc(a.GREATER);break;case Z.NotEqualDepth:a.depthFunc(a.NOTEQUAL);break;default:a.depthFunc(a.LEQUAL)}else a.depthFunc(a.LEQUAL);e=b}};this.setLocked=function(a){c=a};this.setClear=function(b){f!==b&&(a.clearDepth(b),f=b)};this.reset=function(){c=!1;f=e=d=null}};\nZ.WebGLStencilBuffer=function(a,b){var c=!1,d=null,e=null,f=null,g=null,k=null,l=null,m=null,n=null;this.setTest=function(c){c?b.enable(a.STENCIL_TEST):b.disable(a.STENCIL_TEST)};this.setMask=function(b){d===b||c||(a.stencilMask(b),d=b)};this.setFunc=function(b,c,d){if(e!==b||f!==c||g!==d)a.stencilFunc(b,c,d),e=b,f=c,g=d};this.setOp=function(b,c,d){if(k!==b||l!==c||m!==d)a.stencilOp(b,c,d),k=b,l=c,m=d};this.setLocked=function(a){c=a};this.setClear=function(b){n!==b&&(a.clearStencil(b),n=b)};this.reset=\nfunction(){c=!1;n=m=l=k=g=f=e=d=null}};\nZ.WebGLUniforms=function(){function a(a,e,f){this.seq=[];this.map={};this.renderer=f;f=a.getProgramParameter(e,a.ACTIVE_UNIFORMS);for(var g=0;g!==f;++g){var k=a.getActiveUniform(e,g),l=k,k=a.getUniformLocation(e,k.name),m=this,n=l.name,p=n.length;for(R.lastIndex=0;;){var q=R.exec(n),r=R.lastIndex,t=q[1],v=q[3];\"]\"===q[2]&&(t|=0);if(void 0===v||\"[\"===v&&r+2===p){n=m;l=void 0===v?new d(t,l,k):new c(t,l,k);n.seq.push(l);n.map[l.id]=l;break}else v=m.map[t],void 0===v&&(v=new b(t),t=m,m=v,t.seq.push(m),\nt.map[m.id]=m),m=v}}}function b(a){this.id=a;this.seq=[];this.map={}}function c(a,b,c){this.id=a;this.addr=c;this.size=b.size;this.setValue=e(b.type)}function d(a,b,c){this.id=a;this.addr=c;this.setValue=v(b.type)}function e(a){switch(a){case 5126:return r;case 35664:return p;case 35665:return q;case 35666:return n;case 35674:return m;case 35675:return l;case 35676:return k;case 35678:return g;case 35680:return f;case 5124:case 35670:return t;case 35667:case 35671:return y;case 35668:case 35672:return z;\ncase 35669:case 35673:return w}}function f(a,b,c){var d=b.length,e=T(c,d);a.uniform1iv(this.addr,e);for(a=0;a!==d;++a){var f=b[a];f&&c.setTextureCube(f,e[a])}}function g(a,b,c){var d=b.length,e=T(c,d);a.uniform1iv(this.addr,e);for(a=0;a!==d;++a){var f=b[a];f&&c.setTexture2D(f,e[a])}}function k(a,b){a.uniformMatrix4fv(this.addr,!1,U(b,this.size,16))}function l(a,b){a.uniformMatrix3fv(this.addr,!1,U(b,this.size,9))}function m(a,b){a.uniformMatrix2fv(this.addr,!1,U(b,this.size,4))}function n(a,b){a.uniform4fv(this.addr,\nU(b,this.size,4))}function q(a,b){a.uniform3fv(this.addr,U(b,this.size,3))}function p(a,b){a.uniform2fv(this.addr,U(b,this.size,2))}function t(a,b){a.uniform1iv(this.addr,b)}function r(a,b){a.uniform1fv(this.addr,b)}function v(a){switch(a){case 5126:return M;case 35664:return C;case 35665:return H;case 35666:return I;case 35674:return F;case 35675:return E;case 35676:return D;case 35678:return A;case 35680:return B;case 5124:case 35670:return J;case 35667:case 35671:return y;case 35668:case 35672:return z;\ncase 35669:case 35673:return w}}function w(a,b){a.uniform4iv(this.addr,b)}function z(a,b){a.uniform3iv(this.addr,b)}function y(a,b){a.uniform2iv(this.addr,b)}function B(a,b,c){var d=c.allocTextureUnit();a.uniform1i(this.addr,d);b&&c.setTextureCube(b,d)}function A(a,b,c){var d=c.allocTextureUnit();a.uniform1i(this.addr,d);b&&c.setTexture2D(b,d)}function D(a,b){a.uniformMatrix4fv(this.addr,!1,b.elements||b)}function E(a,b){a.uniformMatrix3fv(this.addr,!1,b.elements||b)}function F(a,b){a.uniformMatrix2fv(this.addr,\n!1,b.elements||b)}function I(a,b){void 0===b.x?a.uniform4fv(this.addr,b):a.uniform4f(this.addr,b.x,b.y,b.z,b.w)}function H(a,b){void 0!==b.x?a.uniform3f(this.addr,b.x,b.y,b.z):void 0!==b.r?a.uniform3f(this.addr,b.r,b.g,b.b):a.uniform3fv(this.addr,b)}function C(a,b){void 0===b.x?a.uniform2fv(this.addr,b):a.uniform2f(this.addr,b.x,b.y)}function J(a,b){a.uniform1i(this.addr,b)}function M(a,b){a.uniform1f(this.addr,b)}function T(a,b){var c=S[b];void 0===c&&(c=new Int32Array(b),S[b]=c);for(var d=0;d!==\nb;++d)c[d]=a.allocTextureUnit();return c}function U(a,b,c){var d=a[0];if(0>=d||0<d)return a;var e=b*c,f=L[e];void 0===f&&(f=new Float32Array(e),L[e]=f);if(0!==b)for(d.toArray(f,0),d=1,e=0;d!==b;++d)e+=c,a[d].toArray(f,e);return f}var L=[],S=[];b.prototype.setValue=function(a,b){for(var c=this.seq,d=0,e=c.length;d!==e;++d){var f=c[d];f.setValue(a,b[f.id])}};var R=/([\\w\\d_]+)(\\])?(\\[|\\.)?/g;a.prototype.setValue=function(a,b,c){b=this.map[b];void 0!==b&&b.setValue(a,c,this.renderer)};a.prototype.set=\nfunction(a,b,c){var d=this.map[c];void 0!==d&&d.setValue(a,b[c],this.renderer)};a.prototype.setOptional=function(a,b,c){b=b[c];void 0!==b&&this.setValue(a,c,b)};a.upload=function(a,b,c,d){for(var e=0,f=b.length;e!==f;++e){var g=b[e],k=c[g.id];!1!==k.needsUpdate&&g.setValue(a,k.value,d)}};a.seqWithValue=function(a,b){for(var c=[],d=0,e=a.length;d!==e;++d){var f=a[d];f.id in b&&c.push(f)}return c};a.splitDynamic=function(a,b){for(var c=null,d=a.length,e=0,f=0;f!==d;++f){var g=a[f],k=b[g.id];k&&!0===\nk.dynamic?(null===c&&(c=[]),c.push(g)):(e<f&&(a[e]=g),++e)}e<d&&(a.length=e);return c};a.evalDynamic=function(a,b,c,d){for(var e=0,f=a.length;e!==f;++e){var g=b[a[e].id],k=g.onUpdateCallback;void 0!==k&&k.call(g,c,d)}};return a}();\nZ.LensFlarePlugin=function(a,b){var c,d,e,f,g,k,l,m,n,q,p=a.context,t=a.state,r,v,w,z,y,B;this.render=function(A,D,E){if(0!==b.length){A=new Z.Vector3;var F=E.w/E.z,I=.5*E.z,H=.5*E.w,C=16/E.w,J=new Z.Vector2(C*F,C),M=new Z.Vector3(1,1,0),T=new Z.Vector2(1,1),U=new Z.Box2;U.min.set(0,0);U.max.set(E.z-16,E.w-16);if(void 0===z){var C=new Float32Array([-1,-1,0,0,1,-1,1,0,1,1,1,1,-1,1,0,1]),L=new Uint16Array([0,1,2,0,2,3]);r=p.createBuffer();v=p.createBuffer();p.bindBuffer(p.ARRAY_BUFFER,r);p.bufferData(p.ARRAY_BUFFER,\nC,p.STATIC_DRAW);p.bindBuffer(p.ELEMENT_ARRAY_BUFFER,v);p.bufferData(p.ELEMENT_ARRAY_BUFFER,L,p.STATIC_DRAW);y=p.createTexture();B=p.createTexture();t.bindTexture(p.TEXTURE_2D,y);p.texImage2D(p.TEXTURE_2D,0,p.RGB,16,16,0,p.RGB,p.UNSIGNED_BYTE,null);p.texParameteri(p.TEXTURE_2D,p.TEXTURE_WRAP_S,p.CLAMP_TO_EDGE);p.texParameteri(p.TEXTURE_2D,p.TEXTURE_WRAP_T,p.CLAMP_TO_EDGE);p.texParameteri(p.TEXTURE_2D,p.TEXTURE_MAG_FILTER,p.NEAREST);p.texParameteri(p.TEXTURE_2D,p.TEXTURE_MIN_FILTER,p.NEAREST);t.bindTexture(p.TEXTURE_2D,\nB);p.texImage2D(p.TEXTURE_2D,0,p.RGBA,16,16,0,p.RGBA,p.UNSIGNED_BYTE,null);p.texParameteri(p.TEXTURE_2D,p.TEXTURE_WRAP_S,p.CLAMP_TO_EDGE);p.texParameteri(p.TEXTURE_2D,p.TEXTURE_WRAP_T,p.CLAMP_TO_EDGE);p.texParameteri(p.TEXTURE_2D,p.TEXTURE_MAG_FILTER,p.NEAREST);p.texParameteri(p.TEXTURE_2D,p.TEXTURE_MIN_FILTER,p.NEAREST);var C=w={vertexShader:\"uniform lowp int renderType;\\nuniform vec3 screenPosition;\\nuniform vec2 scale;\\nuniform float rotation;\\nuniform sampler2D occlusionMap;\\nattribute vec2 position;\\nattribute vec2 uv;\\nvarying vec2 vUV;\\nvarying float vVisibility;\\nvoid main() {\\nvUV \\x3d uv;\\nvec2 pos \\x3d position;\\nif ( renderType \\x3d\\x3d 2 ) {\\nvec4 visibility \\x3d texture2D( occlusionMap, vec2( 0.1, 0.1 ) );\\nvisibility +\\x3d texture2D( occlusionMap, vec2( 0.5, 0.1 ) );\\nvisibility +\\x3d texture2D( occlusionMap, vec2( 0.9, 0.1 ) );\\nvisibility +\\x3d texture2D( occlusionMap, vec2( 0.9, 0.5 ) );\\nvisibility +\\x3d texture2D( occlusionMap, vec2( 0.9, 0.9 ) );\\nvisibility +\\x3d texture2D( occlusionMap, vec2( 0.5, 0.9 ) );\\nvisibility +\\x3d texture2D( occlusionMap, vec2( 0.1, 0.9 ) );\\nvisibility +\\x3d texture2D( occlusionMap, vec2( 0.1, 0.5 ) );\\nvisibility +\\x3d texture2D( occlusionMap, vec2( 0.5, 0.5 ) );\\nvVisibility \\x3d        visibility.r / 9.0;\\nvVisibility *\\x3d 1.0 - visibility.g / 9.0;\\nvVisibility *\\x3d       visibility.b / 9.0;\\nvVisibility *\\x3d 1.0 - visibility.a / 9.0;\\npos.x \\x3d cos( rotation ) * position.x - sin( rotation ) * position.y;\\npos.y \\x3d sin( rotation ) * position.x + cos( rotation ) * position.y;\\n}\\ngl_Position \\x3d vec4( ( pos * scale + screenPosition.xy ).xy, screenPosition.z, 1.0 );\\n}\",\nfragmentShader:\"uniform lowp int renderType;\\nuniform sampler2D map;\\nuniform float opacity;\\nuniform vec3 color;\\nvarying vec2 vUV;\\nvarying float vVisibility;\\nvoid main() {\\nif ( renderType \\x3d\\x3d 0 ) {\\ngl_FragColor \\x3d vec4( 1.0, 0.0, 1.0, 0.0 );\\n} else if ( renderType \\x3d\\x3d 1 ) {\\ngl_FragColor \\x3d texture2D( map, vUV );\\n} else {\\nvec4 texture \\x3d texture2D( map, vUV );\\ntexture.a *\\x3d opacity * vVisibility;\\ngl_FragColor \\x3d texture;\\ngl_FragColor.rgb *\\x3d color;\\n}\\n}\"},L=p.createProgram(),\nS=p.createShader(p.FRAGMENT_SHADER),R=p.createShader(p.VERTEX_SHADER),K=\"precision \"+a.getPrecision()+\" float;\\n\";p.shaderSource(S,K+C.fragmentShader);p.shaderSource(R,K+C.vertexShader);p.compileShader(S);p.compileShader(R);p.attachShader(L,S);p.attachShader(L,R);p.linkProgram(L);z=L;n=p.getAttribLocation(z,\"position\");q=p.getAttribLocation(z,\"uv\");c=p.getUniformLocation(z,\"renderType\");d=p.getUniformLocation(z,\"map\");e=p.getUniformLocation(z,\"occlusionMap\");f=p.getUniformLocation(z,\"opacity\");g=\np.getUniformLocation(z,\"color\");k=p.getUniformLocation(z,\"scale\");l=p.getUniformLocation(z,\"rotation\");m=p.getUniformLocation(z,\"screenPosition\")}p.useProgram(z);t.initAttributes();t.enableAttribute(n);t.enableAttribute(q);t.disableUnusedAttributes();p.uniform1i(e,0);p.uniform1i(d,1);p.bindBuffer(p.ARRAY_BUFFER,r);p.vertexAttribPointer(n,2,p.FLOAT,!1,16,0);p.vertexAttribPointer(q,2,p.FLOAT,!1,16,8);p.bindBuffer(p.ELEMENT_ARRAY_BUFFER,v);t.disable(p.CULL_FACE);t.setDepthWrite(!1);L=0;for(S=b.length;L<\nS;L++)if(C=16/E.w,J.set(C*F,C),R=b[L],A.set(R.matrixWorld.elements[12],R.matrixWorld.elements[13],R.matrixWorld.elements[14]),A.applyMatrix4(D.matrixWorldInverse),Of(A,D.projectionMatrix),M.copy(A),T.x=E.x+M.x*I+I-8,T.y=E.y+M.y*H+H-8,!0===U.containsPoint(T)){t.activeTexture(p.TEXTURE0);t.bindTexture(p.TEXTURE_2D,null);t.activeTexture(p.TEXTURE1);t.bindTexture(p.TEXTURE_2D,y);p.copyTexImage2D(p.TEXTURE_2D,0,p.RGB,T.x,T.y,16,16,0);p.uniform1i(c,0);p.uniform2f(k,J.x,J.y);p.uniform3f(m,M.x,M.y,M.z);t.disable(p.BLEND);\nt.enable(p.DEPTH_TEST);p.drawElements(p.TRIANGLES,6,p.UNSIGNED_SHORT,0);t.activeTexture(p.TEXTURE0);t.bindTexture(p.TEXTURE_2D,B);p.copyTexImage2D(p.TEXTURE_2D,0,p.RGBA,T.x,T.y,16,16,0);p.uniform1i(c,1);t.disable(p.DEPTH_TEST);t.activeTexture(p.TEXTURE1);t.bindTexture(p.TEXTURE_2D,y);p.drawElements(p.TRIANGLES,6,p.UNSIGNED_SHORT,0);R.positionScreen.copy(M);R.customUpdateCallback?R.customUpdateCallback(R):R.updateLensFlares();p.uniform1i(c,2);t.enable(p.BLEND);for(var K=0,N=R.lensFlares.length;K<N;K++){var Q=\nR.lensFlares[K];.001<Q.opacity&&.001<Q.scale&&(M.x=Q.x,M.y=Q.y,M.z=Q.z,C=Q.size*Q.scale/E.w,J.x=C*F,J.y=C,p.uniform3f(m,M.x,M.y,M.z),p.uniform2f(k,J.x,J.y),p.uniform1f(l,Q.rotation),p.uniform1f(f,Q.opacity),p.uniform3f(g,Q.color.r,Q.color.g,Q.color.b),t.setBlending(Q.blending,Q.blendEquation,Q.blendSrc,Q.blendDst),a.setTexture2D(Q.texture,1),p.drawElements(p.TRIANGLES,6,p.UNSIGNED_SHORT,0))}}t.enable(p.CULL_FACE);t.enable(p.DEPTH_TEST);t.setDepthWrite(!0);a.resetGLState()}}};\nZ.SpritePlugin=function(a,b){var c,d,e,f,g,k,l,m,n,q,p,t,r,v,w,z,y;function B(a,b){return a.renderOrder!==b.renderOrder?a.renderOrder-b.renderOrder:a.z!==b.z?b.z-a.z:b.id-a.id}var A=a.context,D=a.state,E,F,I,H,C=new Z.Vector3,J=new Z.Quaternion,M=new Z.Vector3;this.render=function(T,U){if(0!==b.length){if(void 0===I){var L=new Float32Array([-.5,-.5,0,0,.5,-.5,1,0,.5,.5,1,1,-.5,.5,0,1]),S=new Uint16Array([0,1,2,0,2,3]);E=A.createBuffer();F=A.createBuffer();A.bindBuffer(A.ARRAY_BUFFER,E);A.bufferData(A.ARRAY_BUFFER,\nL,A.STATIC_DRAW);A.bindBuffer(A.ELEMENT_ARRAY_BUFFER,F);A.bufferData(A.ELEMENT_ARRAY_BUFFER,S,A.STATIC_DRAW);var L=A.createProgram(),S=A.createShader(A.VERTEX_SHADER),R=A.createShader(A.FRAGMENT_SHADER);A.shaderSource(S,[\"precision \"+a.getPrecision()+\" float;\",\"uniform mat4 modelViewMatrix;\\nuniform mat4 projectionMatrix;\\nuniform float rotation;\\nuniform vec2 scale;\\nuniform vec2 uvOffset;\\nuniform vec2 uvScale;\\nattribute vec2 position;\\nattribute vec2 uv;\\nvarying vec2 vUV;\\nvoid main() {\\nvUV \\x3d uvOffset + uv * uvScale;\\nvec2 alignedPosition \\x3d position * scale;\\nvec2 rotatedPosition;\\nrotatedPosition.x \\x3d cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;\\nrotatedPosition.y \\x3d sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;\\nvec4 finalPosition;\\nfinalPosition \\x3d modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );\\nfinalPosition.xy +\\x3d rotatedPosition;\\nfinalPosition \\x3d projectionMatrix * finalPosition;\\ngl_Position \\x3d finalPosition;\\n}\"].join(\"\\n\"));\nA.shaderSource(R,[\"precision \"+a.getPrecision()+\" float;\",\"uniform vec3 color;\\nuniform sampler2D map;\\nuniform float opacity;\\nuniform int fogType;\\nuniform vec3 fogColor;\\nuniform float fogDensity;\\nuniform float fogNear;\\nuniform float fogFar;\\nuniform float alphaTest;\\nvarying vec2 vUV;\\nvoid main() {\\nvec4 texture \\x3d texture2D( map, vUV );\\nif ( texture.a \\x3c alphaTest ) discard;\\ngl_FragColor \\x3d vec4( color * texture.xyz, texture.a * opacity );\\nif ( fogType \\x3e 0 ) {\\nfloat depth \\x3d gl_FragCoord.z / gl_FragCoord.w;\\nfloat fogFactor \\x3d 0.0;\\nif ( fogType \\x3d\\x3d 1 ) {\\nfogFactor \\x3d smoothstep( fogNear, fogFar, depth );\\n} else {\\nconst float LOG2 \\x3d 1.442695;\\nfogFactor \\x3d exp2( - fogDensity * fogDensity * depth * depth * LOG2 );\\nfogFactor \\x3d 1.0 - clamp( fogFactor, 0.0, 1.0 );\\n}\\ngl_FragColor \\x3d mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );\\n}\\n}\"].join(\"\\n\"));\nA.compileShader(S);A.compileShader(R);A.attachShader(L,S);A.attachShader(L,R);A.linkProgram(L);I=L;z=A.getAttribLocation(I,\"position\");y=A.getAttribLocation(I,\"uv\");c=A.getUniformLocation(I,\"uvOffset\");d=A.getUniformLocation(I,\"uvScale\");e=A.getUniformLocation(I,\"rotation\");f=A.getUniformLocation(I,\"scale\");g=A.getUniformLocation(I,\"color\");k=A.getUniformLocation(I,\"map\");l=A.getUniformLocation(I,\"opacity\");m=A.getUniformLocation(I,\"modelViewMatrix\");n=A.getUniformLocation(I,\"projectionMatrix\");q=\nA.getUniformLocation(I,\"fogType\");p=A.getUniformLocation(I,\"fogDensity\");t=A.getUniformLocation(I,\"fogNear\");r=A.getUniformLocation(I,\"fogFar\");v=A.getUniformLocation(I,\"fogColor\");w=A.getUniformLocation(I,\"alphaTest\");L=document.createElement(\"canvas\");L.width=8;L.height=8;S=L.getContext(\"2d\");S.fillStyle=\"white\";S.fillRect(0,0,8,8);H=new Z.Texture(L);H.needsUpdate=!0}A.useProgram(I);D.initAttributes();D.enableAttribute(z);D.enableAttribute(y);D.disableUnusedAttributes();D.disable(A.CULL_FACE);D.enable(A.BLEND);\nA.bindBuffer(A.ARRAY_BUFFER,E);A.vertexAttribPointer(z,2,A.FLOAT,!1,16,0);A.vertexAttribPointer(y,2,A.FLOAT,!1,16,8);A.bindBuffer(A.ELEMENT_ARRAY_BUFFER,F);A.uniformMatrix4fv(n,!1,U.projectionMatrix.elements);D.activeTexture(A.TEXTURE0);A.uniform1i(k,0);S=L=0;(R=T.fog)?(A.uniform3f(v,R.color.r,R.color.g,R.color.b),R instanceof Z.Fog?(A.uniform1f(t,R.near),A.uniform1f(r,R.far),A.uniform1i(q,1),S=L=1):R instanceof Z.FogExp2&&(A.uniform1f(p,R.density),A.uniform1i(q,2),S=L=2)):(A.uniform1i(q,0),S=L=0);\nfor(var R=0,K=b.length;R<K;R++){var N=b[R];Nf(N.modelViewMatrix,U.matrixWorldInverse,N.matrixWorld);N.z=-N.modelViewMatrix.elements[14]}b.sort(B);U=[];R=0;for(K=b.length;R<K;R++){N=b[R];var Q=N.material;A.uniform1f(w,Q.alphaTest);A.uniformMatrix4fv(m,!1,N.modelViewMatrix.elements);N.matrixWorld.decompose(C,J,M);U[0]=M.x;U[1]=M.y;N=0;T.fog&&Q.fog&&(N=S);L!==N&&(A.uniform1i(q,N),L=N);null!==Q.map?(A.uniform2f(c,Q.map.offset.x,Q.map.offset.y),A.uniform2f(d,Q.map.repeat.x,Q.map.repeat.y)):(A.uniform2f(c,\n0,0),A.uniform2f(d,1,1));A.uniform1f(l,Q.opacity);A.uniform3f(g,Q.color.r,Q.color.g,Q.color.b);A.uniform1f(e,Q.rotation);A.uniform2fv(f,U);D.setBlending(Q.blending,Q.blendEquation,Q.blendSrc,Q.blendDst);D.setDepthTest(Q.depthTest);D.setDepthWrite(Q.depthWrite);Q.map?a.setTexture2D(Q.map,0):a.setTexture2D(H,0);A.drawElements(A.TRIANGLES,6,A.UNSIGNED_SHORT,0)}D.enable(A.CULL_FACE);a.resetGLState()}}};\nObject.assign(Z,{Face4:function(a,b,c,d,e,f,g){console.warn(\"THREE.Face4 has been removed. A THREE.Face3 will be created instead.\");return new Z.Face3(a,b,c,e,f,g)},LineStrip:0,LinePieces:1,MeshFaceMaterial:Z.MultiMaterial,PointCloud:function(a,b){console.warn(\"THREE.PointCloud has been renamed to THREE.Points.\");return new Z.Points(a,b)},Particle:Z.Sprite,ParticleSystem:function(a,b){console.warn(\"THREE.ParticleSystem has been renamed to THREE.Points.\");return new Z.Points(a,b)},PointCloudMaterial:function(a){console.warn(\"THREE.PointCloudMaterial has been renamed to THREE.PointsMaterial.\");\nreturn new Z.PointsMaterial(a)},ParticleBasicMaterial:function(a){console.warn(\"THREE.ParticleBasicMaterial has been renamed to THREE.PointsMaterial.\");return new Z.PointsMaterial(a)},ParticleSystemMaterial:function(a){console.warn(\"THREE.ParticleSystemMaterial has been renamed to THREE.PointsMaterial.\");return new Z.PointsMaterial(a)},Vertex:function(a,b,c){console.warn(\"THREE.Vertex has been removed. Use THREE.Vector3 instead.\");return new Z.Vector3(a,b,c)}});\nObject.assign(Z.Box2.prototype,{empty:function(){console.warn(\"THREE.Box2: .empty() has been renamed to .isEmpty().\");return this.isEmpty()},isIntersectionBox:function(a){console.warn(\"THREE.Box2: .isIntersectionBox() has been renamed to .intersectsBox().\");return this.intersectsBox(a)}});\nObject.assign(Z.Box3.prototype,{empty:function(){console.warn(\"THREE.Box3: .empty() has been renamed to .isEmpty().\");return this.isEmpty()},isIntersectionBox:function(a){console.warn(\"THREE.Box3: .isIntersectionBox() has been renamed to .intersectsBox().\");return this.intersectsBox(a)},isIntersectionSphere:function(a){console.warn(\"THREE.Box3: .isIntersectionSphere() has been renamed to .intersectsSphere().\");return this.intersectsSphere(a)}});\nObject.assign(Z.Matrix3.prototype,{multiplyVector3:function(a){console.warn(\"THREE.Matrix3: .multiplyVector3() has been removed. Use vector.applyMatrix3( matrix ) instead.\");return Sf(a,this)},multiplyVector3Array:function(a){console.warn(\"THREE.Matrix3: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead.\");return this.applyToVector3Array(a)}});\nObject.assign(Z.Matrix4.prototype,{extractPosition:function(a){console.warn(\"THREE.Matrix4: .extractPosition() has been renamed to .copyPosition().\");var b=this.elements;a=a.elements;b[12]=a[12];b[13]=a[13];b[14]=a[14];return this},setRotationFromQuaternion:function(a){console.warn(\"THREE.Matrix4: .setRotationFromQuaternion() has been renamed to .makeRotationFromQuaternion().\");return Tf(this,a)},multiplyVector3:function(a){console.warn(\"THREE.Matrix4: .multiplyVector3() has been removed. Use vector.applyMatrix4( matrix ) or vector.applyProjection( matrix ) instead.\");\nreturn Of(a,this)},multiplyVector4:function(a){console.warn(\"THREE.Matrix4: .multiplyVector4() has been removed. Use vector.applyMatrix4( matrix ) instead.\");return a.applyMatrix4(this)},multiplyVector3Array:function(a){console.warn(\"THREE.Matrix4: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead.\");return this.applyToVector3Array(a)},rotateAxis:function(a){console.warn(\"THREE.Matrix4: .rotateAxis() has been removed. Use Vector3.transformDirection( matrix ) instead.\");\nRf(a,this)},crossVector:function(a){console.warn(\"THREE.Matrix4: .crossVector() has been removed. Use vector.applyMatrix4( matrix ) instead.\");return a.applyMatrix4(this)},translate:function(){console.error(\"THREE.Matrix4: .translate() has been removed.\")},rotateX:function(){console.error(\"THREE.Matrix4: .rotateX() has been removed.\")},rotateY:function(){console.error(\"THREE.Matrix4: .rotateY() has been removed.\")},rotateZ:function(){console.error(\"THREE.Matrix4: .rotateZ() has been removed.\")},rotateByAxis:function(){console.error(\"THREE.Matrix4: .rotateByAxis() has been removed.\")}});\nObject.assign(Z.Plane.prototype,{isIntersectionLine:function(a){console.warn(\"THREE.Plane: .isIntersectionLine() has been renamed to .intersectsLine().\");var b=this.distanceToPoint(a.start);a=this.distanceToPoint(a.end);return 0>b&&0<a||0>a&&0<b}});Object.assign(Z.Quaternion.prototype,{multiplyVector3:function(a){console.warn(\"THREE.Quaternion: .multiplyVector3() has been removed. Use is now vector.applyQuaternion( quaternion ) instead.\");return Mf(a,this)}});\nObject.assign(Z.Ray.prototype,{isIntersectionBox:function(a){console.warn(\"THREE.Ray: .isIntersectionBox() has been renamed to .intersectsBox().\");return this.intersectsBox(a)},isIntersectionPlane:function(a){console.warn(\"THREE.Ray: .isIntersectionPlane() has been renamed to .intersectsPlane().\");return this.intersectsPlane(a)},isIntersectionSphere:function(a){console.warn(\"THREE.Ray: .isIntersectionSphere() has been renamed to .intersectsSphere().\");return this.intersectsSphere(a)}});\nObject.assign(Z.Vector3.prototype,{setEulerFromRotationMatrix:function(){console.error(\"THREE.Vector3: .setEulerFromRotationMatrix() has been removed. Use Euler.setFromRotationMatrix() instead.\")},setEulerFromQuaternion:function(){console.error(\"THREE.Vector3: .setEulerFromQuaternion() has been removed. Use Euler.setFromQuaternion() instead.\")},getPositionFromMatrix:function(a){console.warn(\"THREE.Vector3: .getPositionFromMatrix() has been renamed to .setFromMatrixPosition().\");return Qf(this,a)},\ngetScaleFromMatrix:function(a){console.warn(\"THREE.Vector3: .getScaleFromMatrix() has been renamed to .setFromMatrixScale().\");var b=Pf(this,a,0).length(),c=Pf(this,a,1).length();a=Pf(this,a,2).length();this.x=b;this.y=c;this.z=a;return this},getColumnFromMatrix:function(a,b){console.warn(\"THREE.Vector3: .getColumnFromMatrix() has been renamed to .setFromMatrixColumn().\");return Pf(this,b,a)}});\nObject.assign(Z.Object3D.prototype,{getChildByName:function(a){console.warn(\"THREE.Object3D: .getChildByName() has been renamed to .getObjectByName().\");return this.getObjectByName(a)},renderDepth:function(){console.warn(\"THREE.Object3D: .renderDepth has been removed. Use .renderOrder, instead.\")},translate:function(a,b){console.warn(\"THREE.Object3D: .translate() has been removed. Use .translateOnAxis( axis, distance ) instead.\");return this.translateOnAxis(b,a)}});\nObject.defineProperties(Z.Object3D.prototype,{eulerOrder:{get:function(){console.warn(\"THREE.Object3D: .eulerOrder is now .rotation.order.\");return this.rotation.order},set:function(a){console.warn(\"THREE.Object3D: .eulerOrder is now .rotation.order.\");this.rotation.order=a}},useQuaternion:{get:function(){console.warn(\"THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.\")},set:function(){console.warn(\"THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.\")}}});\nObject.defineProperties(Z.LOD.prototype,{objects:{get:function(){console.warn(\"THREE.LOD: .objects has been renamed to .levels.\");return this.levels}}});Z.PerspectiveCamera.prototype.setLens=function(a,b){console.warn(\"THREE.PerspectiveCamera.setLens is deprecated. Use .setFocalLength and .filmGauge for a photographic setup.\");void 0!==b&&(this.filmGauge=b);this.setFocalLength(a)};\nObject.defineProperties(Z.Light.prototype,{onlyShadow:{set:function(){console.warn(\"THREE.Light: .onlyShadow has been removed.\")}},shadowCameraFov:{set:function(a){console.warn(\"THREE.Light: .shadowCameraFov is now .shadow.camera.fov.\");this.shadow.camera.fov=a}},shadowCameraLeft:{set:function(a){console.warn(\"THREE.Light: .shadowCameraLeft is now .shadow.camera.left.\");this.shadow.camera.left=a}},shadowCameraRight:{set:function(a){console.warn(\"THREE.Light: .shadowCameraRight is now .shadow.camera.right.\");\nthis.shadow.camera.right=a}},shadowCameraTop:{set:function(a){console.warn(\"THREE.Light: .shadowCameraTop is now .shadow.camera.top.\");this.shadow.camera.top=a}},shadowCameraBottom:{set:function(a){console.warn(\"THREE.Light: .shadowCameraBottom is now .shadow.camera.bottom.\");this.shadow.camera.bottom=a}},shadowCameraNear:{set:function(a){console.warn(\"THREE.Light: .shadowCameraNear is now .shadow.camera.near.\");this.shadow.camera.near=a}},shadowCameraFar:{set:function(a){console.warn(\"THREE.Light: .shadowCameraFar is now .shadow.camera.far.\");\nthis.shadow.camera.far=a}},shadowCameraVisible:{set:function(){console.warn(\"THREE.Light: .shadowCameraVisible has been removed. Use new THREE.CameraHelper( light.shadow.camera ) instead.\")}},shadowBias:{set:function(a){console.warn(\"THREE.Light: .shadowBias is now .shadow.bias.\");this.shadow.bias=a}},shadowDarkness:{set:function(){console.warn(\"THREE.Light: .shadowDarkness has been removed.\")}},shadowMapWidth:{set:function(a){console.warn(\"THREE.Light: .shadowMapWidth is now .shadow.mapSize.width.\");\nthis.shadow.mapSize.width=a}},shadowMapHeight:{set:function(a){console.warn(\"THREE.Light: .shadowMapHeight is now .shadow.mapSize.height.\");this.shadow.mapSize.height=a}}});Object.defineProperties(Z.BufferAttribute.prototype,{length:{get:function(){console.warn(\"THREE.BufferAttribute: .length has been deprecated. Please use .count.\");return this.array.length}}});\nObject.assign(Z.BufferGeometry.prototype,{addIndex:function(a){console.warn(\"THREE.BufferGeometry: .addIndex() has been renamed to .setIndex().\");this.setIndex(a)},addDrawCall:function(a,b,c){void 0!==c&&console.warn(\"THREE.BufferGeometry: .addDrawCall() no longer supports indexOffset.\");console.warn(\"THREE.BufferGeometry: .addDrawCall() is now .addGroup().\");this.addGroup(a,b)},clearDrawCalls:function(){console.warn(\"THREE.BufferGeometry: .clearDrawCalls() is now .clearGroups().\");this.clearGroups()},\ncomputeTangents:function(){console.warn(\"THREE.BufferGeometry: .computeTangents() has been removed.\")},computeOffsets:function(){console.warn(\"THREE.BufferGeometry: .computeOffsets() has been removed.\")}});Object.defineProperties(Z.BufferGeometry.prototype,{drawcalls:{get:function(){console.error(\"THREE.BufferGeometry: .drawcalls has been renamed to .groups.\");return this.groups}},offsets:{get:function(){console.warn(\"THREE.BufferGeometry: .offsets has been renamed to .groups.\");return this.groups}}});\nObject.defineProperties(Z.Material.prototype,{wrapAround:{get:function(){console.warn(\"THREE.\"+this.type+\": .wrapAround has been removed.\")},set:function(){console.warn(\"THREE.\"+this.type+\": .wrapAround has been removed.\")}},wrapRGB:{get:function(){console.warn(\"THREE.\"+this.type+\": .wrapRGB has been removed.\");return new Z.Color}}});\nObject.defineProperties(Z.MeshPhongMaterial.prototype,{metal:{get:function(){console.warn(\"THREE.MeshPhongMaterial: .metal has been removed. Use THREE.MeshStandardMaterial instead.\");return!1},set:function(){console.warn(\"THREE.MeshPhongMaterial: .metal has been removed. Use THREE.MeshStandardMaterial instead\")}}});\nObject.defineProperties(Z.ShaderMaterial.prototype,{derivatives:{get:function(){console.warn(\"THREE.ShaderMaterial: .derivatives has been moved to .extensions.derivatives.\");return this.extensions.derivatives},set:function(a){console.warn(\"THREE. ShaderMaterial: .derivatives has been moved to .extensions.derivatives.\");this.extensions.derivatives=a}}});\nZ.EventDispatcher.prototype=Object.assign(Object.create({constructor:Z.EventDispatcher,apply:function(a){console.warn(\"THREE.EventDispatcher: .apply is deprecated, just inherit or Object.assign the prototype to mix-in.\");Object.assign(a,this)}}),Z.EventDispatcher.prototype);\nObject.assign(Z.WebGLRenderer.prototype,{supportsFloatTextures:function(){console.warn(\"THREE.WebGLRenderer: .supportsFloatTextures() is now .extensions.get( 'OES_texture_float' ).\");return this.extensions.get(\"OES_texture_float\")},supportsHalfFloatTextures:function(){console.warn(\"THREE.WebGLRenderer: .supportsHalfFloatTextures() is now .extensions.get( 'OES_texture_half_float' ).\");return this.extensions.get(\"OES_texture_half_float\")},supportsStandardDerivatives:function(){console.warn(\"THREE.WebGLRenderer: .supportsStandardDerivatives() is now .extensions.get( 'OES_standard_derivatives' ).\");\nreturn this.extensions.get(\"OES_standard_derivatives\")},supportsCompressedTextureS3TC:function(){console.warn(\"THREE.WebGLRenderer: .supportsCompressedTextureS3TC() is now .extensions.get( 'WEBGL_compressed_texture_s3tc' ).\");return this.extensions.get(\"WEBGL_compressed_texture_s3tc\")},supportsCompressedTexturePVRTC:function(){console.warn(\"THREE.WebGLRenderer: .supportsCompressedTexturePVRTC() is now .extensions.get( 'WEBGL_compressed_texture_pvrtc' ).\");return this.extensions.get(\"WEBGL_compressed_texture_pvrtc\")},\nsupportsBlendMinMax:function(){console.warn(\"THREE.WebGLRenderer: .supportsBlendMinMax() is now .extensions.get( 'EXT_blend_minmax' ).\");return this.extensions.get(\"EXT_blend_minmax\")},supportsVertexTextures:function(){return this.capabilities.vertexTextures},supportsInstancedArrays:function(){console.warn(\"THREE.WebGLRenderer: .supportsInstancedArrays() is now .extensions.get( 'ANGLE_instanced_arrays' ).\");return this.extensions.get(\"ANGLE_instanced_arrays\")},enableScissorTest:function(a){console.warn(\"THREE.WebGLRenderer: .enableScissorTest() is now .setScissorTest().\");\nthis.setScissorTest(a)},initMaterial:function(){console.warn(\"THREE.WebGLRenderer: .initMaterial() has been removed.\")},addPrePlugin:function(){console.warn(\"THREE.WebGLRenderer: .addPrePlugin() has been removed.\")},addPostPlugin:function(){console.warn(\"THREE.WebGLRenderer: .addPostPlugin() has been removed.\")},updateShadowMap:function(){console.warn(\"THREE.WebGLRenderer: .updateShadowMap() has been removed.\")}});\nObject.defineProperties(Z.WebGLRenderer.prototype,{shadowMapEnabled:{get:function(){return this.shadowMap.enabled},set:function(a){console.warn(\"THREE.WebGLRenderer: .shadowMapEnabled is now .shadowMap.enabled.\");this.shadowMap.enabled=a}},shadowMapType:{get:function(){return this.shadowMap.type},set:function(a){console.warn(\"THREE.WebGLRenderer: .shadowMapType is now .shadowMap.type.\");this.shadowMap.type=a}},shadowMapCullFace:{get:function(){return this.shadowMap.cullFace},set:function(a){console.warn(\"THREE.WebGLRenderer: .shadowMapCullFace is now .shadowMap.cullFace.\");\nthis.shadowMap.cullFace=a}}});Object.defineProperties(Z.WebGLShadowMap.prototype,{cullFace:{get:function(){return this.renderReverseSided?Z.CullFaceFront:Z.CullFaceBack},set:function(a){a=a!==Z.CullFaceBack;console.warn(\"WebGLRenderer: .shadowMap.cullFace is deprecated. Set .shadowMap.renderReverseSided to \"+a+\".\");this.renderReverseSided=a}}});\nObject.defineProperties(Z.WebGLRenderTarget.prototype,{wrapS:{get:function(){console.warn(\"THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.\");return this.texture.wrapS},set:function(a){console.warn(\"THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.\");this.texture.wrapS=a}},wrapT:{get:function(){console.warn(\"THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.\");return this.texture.wrapT},set:function(a){console.warn(\"THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.\");this.texture.wrapT=\na}},magFilter:{get:function(){console.warn(\"THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.\");return this.texture.magFilter},set:function(a){console.warn(\"THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.\");this.texture.magFilter=a}},minFilter:{get:function(){console.warn(\"THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.\");return this.texture.minFilter},set:function(a){console.warn(\"THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.\");this.texture.minFilter=\na}},anisotropy:{get:function(){console.warn(\"THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.\");return this.texture.anisotropy},set:function(a){console.warn(\"THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.\");this.texture.anisotropy=a}},offset:{get:function(){console.warn(\"THREE.WebGLRenderTarget: .offset is now .texture.offset.\");return this.texture.offset},set:function(a){console.warn(\"THREE.WebGLRenderTarget: .offset is now .texture.offset.\");this.texture.offset=\na}},repeat:{get:function(){console.warn(\"THREE.WebGLRenderTarget: .repeat is now .texture.repeat.\");return this.texture.repeat},set:function(a){console.warn(\"THREE.WebGLRenderTarget: .repeat is now .texture.repeat.\");this.texture.repeat=a}},format:{get:function(){console.warn(\"THREE.WebGLRenderTarget: .format is now .texture.format.\");return this.texture.format},set:function(a){console.warn(\"THREE.WebGLRenderTarget: .format is now .texture.format.\");this.texture.format=a}},type:{get:function(){console.warn(\"THREE.WebGLRenderTarget: .type is now .texture.type.\");\nreturn this.texture.type},set:function(a){console.warn(\"THREE.WebGLRenderTarget: .type is now .texture.type.\");this.texture.type=a}},generateMipmaps:{get:function(){console.warn(\"THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.\");return this.texture.generateMipmaps},set:function(a){console.warn(\"THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.\");this.texture.generateMipmaps=a}}});\nObject.assign(Z.Audio.prototype,{load:function(a){console.warn(\"THREE.Audio: .load has been deprecated. Please use THREE.AudioLoader.\");var b=this;(new Z.AudioLoader).load(a,function(a){b.setBuffer(a)});return this}});Object.assign(Z.AudioAnalyser.prototype,{getData:function(){console.warn(\"THREE.AudioAnalyser: .getData() is now .getFrequencyData().\");return this.getFrequencyData()}});\nZ.GeometryUtils={merge:function(a,b,c){console.warn(\"THREE.GeometryUtils: .merge() has been moved to Geometry. Use geometry.merge( geometry2, matrix, materialIndexOffset ) instead.\");if(b instanceof Z.Mesh){b.matrixAutoUpdate&&b.updateMatrix();var d=b.matrix;b=b.geometry}a.merge(b,d,c)},center:function(a){console.warn(\"THREE.GeometryUtils: .center() has been moved to Geometry. Use geometry.center() instead.\");return a.center()}};\nZ.ImageUtils={crossOrigin:void 0,loadTexture:function(a,b,c,d){console.warn(\"THREE.ImageUtils.loadTexture has been deprecated. Use THREE.TextureLoader() instead.\");var e=new Z.TextureLoader;e.setCrossOrigin(this.crossOrigin);a=e.load(a,c,void 0,d);b&&(a.mapping=b);return a},loadTextureCube:function(a,b,c,d){console.warn(\"THREE.ImageUtils.loadTextureCube has been deprecated. Use THREE.CubeTextureLoader() instead.\");var e=new Z.CubeTextureLoader;e.setCrossOrigin(this.crossOrigin);a=e.load(a,c,void 0,\nd);b&&(a.mapping=b);return a},loadCompressedTexture:function(){console.error(\"THREE.ImageUtils.loadCompressedTexture has been removed. Use THREE.DDSLoader instead.\")},loadCompressedTextureCube:function(){console.error(\"THREE.ImageUtils.loadCompressedTextureCube has been removed. Use THREE.DDSLoader instead.\")}};\nZ.Projector=function(){console.error(\"THREE.Projector has been moved to /examples/js/renderers/Projector.js.\");this.projectVector=function(a,b){console.warn(\"THREE.Projector: .projectVector() is now vector.project().\");a.project(b)};this.unprojectVector=function(a,b){console.warn(\"THREE.Projector: .unprojectVector() is now vector.unproject().\");a.unproject(b)};this.pickingRay=function(){console.error(\"THREE.Projector: .pickingRay() is now raycaster.setFromCamera().\")}};\nZ.CanvasRenderer=function(){console.error(\"THREE.CanvasRenderer has been moved to /examples/js/renderers/CanvasRenderer.js\");this.domElement=document.createElement(\"canvas\");this.clear=function(){};this.render=function(){};this.setClearColor=function(){};this.setSize=function(){}};\nZ.CurveUtils={tangentQuadraticBezier:function(a,b,c,d){return 2*(1-a)*(c-b)+2*a*(d-c)},tangentCubicBezier:function(a,b,c,d,e){return-3*b*(1-a)*(1-a)+3*c*(1-a)*(1-a)-6*a*c*(1-a)+6*a*d*(1-a)-3*a*a*d+3*a*a*e},tangentSpline:function(a){return 6*a*a-6*a+(3*a*a-4*a+1)+(-6*a*a+6*a)+(3*a*a-2*a)},interpolate:function(a,b,c,d,e){a=.5*(c-a);d=.5*(d-b);var f=e*e;return(2*b-2*c+a+d)*e*f+(-3*b+3*c-2*a-d)*f+a*e+b}};\nZ.SceneUtils={createMultiMaterialObject:function(a,b){for(var c=new Z.Group,d=0,e=b.length;d<e;d++)c.add(new Z.Mesh(a,b[d]));return c},detach:function(a,b,c){a.applyMatrix(b.matrixWorld);b.remove(a);c.add(a)},attach:function(a,b,c){var d=new Z.Matrix4;d.getInverse(c.matrixWorld);a.applyMatrix(d);b.remove(a);c.add(a)}};\nZ.ShapeUtils={area:function(a){for(var b=a.length,c=0,d=b-1,e=0;e<b;d=e++)c+=a[d].x*a[e].y-a[e].x*a[d].y;return.5*c},triangulate:function(a,b){var c=a.length;if(3>c)return null;var d=[],e=[],f=[],g;if(0<Z.ShapeUtils.area(a))for(g=0;g<c;g++)e[g]=g;else for(g=0;g<c;g++)e[g]=c-1-g;var k=2*c;for(g=c-1;2<c;){if(0>=k--){console.warn(\"THREE.ShapeUtils: Unable to triangulate polygon! in triangulate()\");break}var l=g;c<=l&&(l=0);g=l+1;c<=g&&(g=0);var m=g+1;c<=m&&(m=0);a:{var n;var q=a[e[l]].x;var p=a[e[l]].y;\nvar t=a[e[g]].x;var r=a[e[g]].y;var v=a[e[m]].x;var w=a[e[m]].y;if(Number.EPSILON>(t-q)*(w-p)-(r-p)*(v-q))var z=!1;else{var y=v-t;var B=w-r;var A=q-v;var D=p-w;var E=t-q;z=r-p;for(n=0;n<c;n++){var F=a[e[n]].x;var I=a[e[n]].y;if(!(F===q&&I===p||F===t&&I===r||F===v&&I===w)){var H=F-q;var C=I-p;var J=F-t;var M=I-r;F-=v;I-=w;M=y*M-B*J;C=E*C-z*H;F=A*I-D*F;if(M>=-Number.EPSILON&&F>=-Number.EPSILON&&C>=-Number.EPSILON){z=!1;break a}}}z=!0}}if(z){d.push([a[e[l]],a[e[g]],a[e[m]]]);f.push([e[l],e[g],e[m]]);\nl=g;for(m=g+1;m<c;l++,m++)e[l]=e[m];c--;k=2*c}}return b?f:d},triangulateShape:function(a,b){function c(a,b,c){return a.x!==b.x?a.x<b.x?a.x<=c.x&&c.x<=b.x:b.x<=c.x&&c.x<=a.x:a.y<b.y?a.y<=c.y&&c.y<=b.y:b.y<=c.y&&c.y<=a.y}function d(a,b,d,e){var f=b.x-a.x,g=b.y-a.y,k=e.x-d.x,l=e.y-d.y,m=a.x-d.x,n=a.y-d.y,p=g*k-f*l,q=g*m-f*n;if(Math.abs(p)>Number.EPSILON){if(0<p){if(0>q||q>p)return[];k=l*m-k*n;if(0>k||k>p)return[]}else{if(0<q||q<p)return[];k=l*m-k*n;if(0<k||k<p)return[]}if(0===k)return 0!==q&&q!==p?[a]:\n[];if(k===p)return 0!==q&&q!==p?[b]:[];if(0===q)return[d];if(q===p)return[e];d=k/p;return[{x:a.x+d*f,y:a.y+d*g}]}if(0!==q||l*m!==k*n)return[];g=0===f&&0===g;k=0===k&&0===l;if(g&&k)return a.x!==d.x||a.y!==d.y?[]:[a];if(g)return c(d,e,a)?[a]:[];if(k)return c(a,b,d)?[d]:[];0!==f?(a.x<b.x?(f=a,k=a.x,g=b,a=b.x):(f=b,k=b.x,g=a,a=a.x),d.x<e.x?(b=d,p=d.x,l=e,d=e.x):(b=e,p=e.x,l=d,d=d.x)):(a.y<b.y?(f=a,k=a.y,g=b,a=b.y):(f=b,k=b.y,g=a,a=a.y),d.y<e.y?(b=d,p=d.y,l=e,d=e.y):(b=e,p=e.y,l=d,d=d.y));return k<=p?\na<p?[]:a===p?[]:a<=d?[b,g]:[b,l]:k>d?[]:k===d?[]:a<=d?[f,g]:[f,l]}function e(a,b,c,d){var e=b.x-a.x,f=b.y-a.y;b=c.x-a.x;c=c.y-a.y;var g=d.x-a.x;d=d.y-a.y;a=e*c-f*b;e=e*d-f*g;return Math.abs(a)>Number.EPSILON?(b=g*c-d*b,0<a?0<=e&&0<=b:0<=e||0<=b):0<e}var f,g={},k=a.concat();var l=0;for(f=b.length;l<f;l++)Array.prototype.push.apply(k,b[l]);l=0;for(f=k.length;l<f;l++){var m=k[l].x+\":\"+k[l].y;void 0!==g[m]&&console.warn(\"THREE.Shape: Duplicate point\",m);g[m]=l}l=function(a,b){function c(a,b){var c=k.length-\n1,d=a-1;0>d&&(d=c);var f=a+1;f>c&&(f=0);c=e(k[a],k[d],k[f],C[b]);if(!c)return!1;c=C.length-1;d=b-1;0>d&&(d=c);f=b+1;f>c&&(f=0);return(c=e(C[b],C[d],C[f],k[a]))?!0:!1}function f(a,b){var c;for(c=0;c<k.length;c++){var e=c+1;e%=k.length;e=d(a,b,k[c],k[e]);if(0<e.length)return!0}return!1}function g(a,c){var e,f;for(e=0;e<l.length;e++){var g=b[l[e]];for(f=0;f<g.length;f++){var k=f+1;k%=g.length;k=d(a,c,g[f],g[k]);if(0<k.length)return!0}}return!1}var k=a.concat(),l=[],m,n;a=[];var q,A=0;for(m=b.length;A<\nm;A++)l.push(A);var D=0;for(var E=2*l.length;0<l.length;){E--;if(0>E){console.log(\"Infinite Loop! Holes left:\"+l.length+\", Probably Hole outside Shape!\");break}for(n=D;n<k.length;n++){var F=k[n];m=-1;for(A=0;A<l.length;A++){var I=l[A];var H=F.x+\":\"+F.y+\":\"+I;if(void 0===a[H]){var C=b[I];for(q=0;q<C.length;q++)if(I=C[q],c(n,q)&&!f(F,I)&&!g(F,I)){m=q;l.splice(A,1);D=k.slice(0,n+1);I=k.slice(n);q=C.slice(m);var J=C.slice(0,m+1);k=D.concat(q).concat(J).concat(I);D=n;break}if(0<=m)break;a[H]=!0}}if(0<=\nm)break}}return k}(a,b);k=Z.ShapeUtils.triangulate(l,!1);l=0;for(f=k.length;l<f;l++)for(b=k[l],a=0;3>a;a++)m=b[a].x+\":\"+b[a].y,m=g[m],void 0!==m&&(b[a]=m);return k.concat()},isClockWise:function(a){return 0>Z.ShapeUtils.area(a)},b2:function(a,b,c,d){var e=1-a;return e*e*b+2*(1-a)*a*c+a*a*d},b3:function(a,b,c,d,e){var f=1-a,g=1-a;return f*f*f*b+3*g*g*a*c+3*(1-a)*a*a*d+a*a*a*e}};Z.Curve=function(){};\nZ.Curve.prototype={constructor:Z.Curve,getPoint:function(){console.warn(\"THREE.Curve: Warning, getPoint() not implemented!\");return null},getPointAt:function(a){a=Ag(this,a);return this.getPoint(a)},getPoints:function(a){a||(a=5);var b,c=[];for(b=0;b<=a;b++)c.push(this.getPoint(b/a));return c},getSpacedPoints:function(a){a||(a=5);var b,c=[];for(b=0;b<=a;b++)c.push(this.getPointAt(b/a));return c},getLength:function(){var a=Bg(this);return a[a.length-1]},updateArcLengths:function(){this.needsUpdate=\n!0;Bg(this)},getTangent:function(a){var b=a-1E-4;a+=1E-4;0>b&&(b=0);1<a&&(a=1);b=this.getPoint(b);return this.getPoint(a).clone().sub(b).normalize()}};function Ag(a,b){a=Bg(a);var c=a.length;var d=b*a[c-1];for(var e=0,f=c-1,g;e<=f;)if(b=Math.floor(e+(f-e)/2),g=a[b]-d,0>g)e=b+1;else if(0<g)f=b-1;else{f=b;break}b=f;if(a[b]===d)return b/(c-1);e=a[b];return(b+(d-e)/(a[b+1]-e))/(c-1)}\nfunction Bg(a){var b;b||(b=a.__arcLengthDivisions?a.__arcLengthDivisions:200);if(a.cacheArcLengths&&a.cacheArcLengths.length===b+1&&!a.needsUpdate)return a.cacheArcLengths;a.needsUpdate=!1;var c=[],d=a.getPoint(0),e,f=0;c.push(0);for(e=1;e<=b;e++){var g=a.getPoint(e/b);f+=g.distanceTo(d);c.push(f);d=g}return a.cacheArcLengths=c}Z.Curve.create=function(a,b){a.prototype=Object.create(Z.Curve.prototype);a.prototype.constructor=a;a.prototype.getPoint=b;return a};\nZ.CurvePath=function(){this.curves=[];this.autoClose=!1};\nZ.CurvePath.prototype=Object.assign(Object.create(Z.Curve.prototype),{constructor:Z.CurvePath,add:function(a){this.curves.push(a)},closePath:function(){var a=this.curves[0].getPoint(0),b=this.curves[this.curves.length-1].getPoint(1);a.equals(b)||this.curves.push(new Z.LineCurve(b,a))},getPoint:function(a){for(var b=a*this.getLength(),c=this.getCurveLengths(),d=0;d<c.length;){if(c[d]>=b)return a=this.curves[d],b=1-(c[d]-b)/a.getLength(),a.getPointAt(b);d++}return null},getLength:function(){var a=this.getCurveLengths();\nreturn a[a.length-1]},getCurveLengths:function(){if(this.cacheLengths&&this.cacheLengths.length===this.curves.length)return this.cacheLengths;for(var a=[],b=0,c=0,d=this.curves.length;c<d;c++)b+=this.curves[c].getLength(),a.push(b);return this.cacheLengths=a},createPointsGeometry:function(a){a=this.getPoints(a);return this.createGeometry(a)},createSpacedPointsGeometry:function(a){a=this.getSpacedPoints(a);return this.createGeometry(a)},createGeometry:function(a){for(var b=new Z.Geometry,c=0,d=a.length;c<\nd;c++){var e=a[c];b.vertices.push(new Z.Vector3(e.x,e.y,e.z||0))}return b}});Z.Font=function(a){this.data=a};\nObject.assign(Z.Font.prototype,{generateShapes:function(a,b,c){void 0===b&&(b=100);void 0===c&&(c=4);var d=this.data;a=String(a).split(\"\");var e=b/d.resolution,f=0;b=[];for(var g=0;g<a.length;g++){var k;var l=e;var m=f,n=d.glyphs[a[g]]||d.glyphs[\"?\"];if(n){var q=new Z.Path,p=[],t=Z.ShapeUtils.b2,r=Z.ShapeUtils.b3;if(n.o)for(var v=n._cachedOutline||(n._cachedOutline=n.o.split(\" \")),w=0,z=v.length;w<z;)switch(v[w++]){case \"m\":var y=v[w++]*l+m;var B=v[w++]*l;q.moveTo(y,B);break;case \"l\":y=v[w++]*l+m;\nB=v[w++]*l;q.lineTo(y,B);break;case \"q\":var A=v[w++]*l+m;var D=v[w++]*l;var E=v[w++]*l+m;var F=v[w++]*l;q.quadraticCurveTo(E,F,A,D);if(k=p[p.length-1]){var I=k.x;k=k.y;for(var H=1;H<=c;H++){var C=H/c;t(C,I,E,A);t(C,k,F,D)}}break;case \"b\":if(A=v[w++]*l+m,D=v[w++]*l,E=v[w++]*l+m,F=v[w++]*l,y=v[w++]*l+m,B=v[w++]*l,q.bezierCurveTo(E,F,y,B,A,D),k=p[p.length-1])for(I=k.x,k=k.y,H=1;H<=c;H++)C=H/c,r(C,I,E,y,A),r(C,k,F,B,D)}l={offset:n.ha*l,path:q}}else l=void 0;f+=l.offset;b.push(l.path)}c=[];d=0;for(a=b.length;d<\na;d++)Array.prototype.push.apply(c,b[d].toShapes());return c}});Z.Path=function(a){Z.CurvePath.call(this);this.actions=[];a&&this.fromPoints(a)};\nZ.Path.prototype=Object.assign(Object.create(Z.CurvePath.prototype),{constructor:Z.Path,fromPoints:function(a){this.moveTo(a[0].x,a[0].y);for(var b=1,c=a.length;b<c;b++)this.lineTo(a[b].x,a[b].y)},moveTo:function(a,b){this.actions.push({action:\"moveTo\",args:[a,b]})},lineTo:function(a,b){var c=this.actions[this.actions.length-1].args;this.curves.push(new Z.LineCurve(new Z.Vector2(c[c.length-2],c[c.length-1]),new Z.Vector2(a,b)));this.actions.push({action:\"lineTo\",args:[a,b]})},quadraticCurveTo:function(a,\nb,c,d){var e=this.actions[this.actions.length-1].args;this.curves.push(new Z.QuadraticBezierCurve(new Z.Vector2(e[e.length-2],e[e.length-1]),new Z.Vector2(a,b),new Z.Vector2(c,d)));this.actions.push({action:\"quadraticCurveTo\",args:[a,b,c,d]})},bezierCurveTo:function(a,b,c,d,e,f){var g=this.actions[this.actions.length-1].args;this.curves.push(new Z.CubicBezierCurve(new Z.Vector2(g[g.length-2],g[g.length-1]),new Z.Vector2(a,b),new Z.Vector2(c,d),new Z.Vector2(e,f)));this.actions.push({action:\"bezierCurveTo\",\nargs:[a,b,c,d,e,f]})},splineThru:function(a){var b=Array.prototype.slice.call(arguments),c=this.actions[this.actions.length-1].args,c=[new Z.Vector2(c[c.length-2],c[c.length-1])];Array.prototype.push.apply(c,a);this.curves.push(new Z.SplineCurve(c));this.actions.push({action:\"splineThru\",args:b})},arc:function(a,b,c,d,e,f){var g=this.actions[this.actions.length-1].args;this.absarc(a+g[g.length-2],b+g[g.length-1],c,d,e,f)},absarc:function(a,b,c,d,e,f){this.absellipse(a,b,c,c,d,e,f)},ellipse:function(a,\nb,c,d,e,f,g,k){var l=this.actions[this.actions.length-1].args;this.absellipse(a+l[l.length-2],b+l[l.length-1],c,d,e,f,g,k)},absellipse:function(a,b,c,d,e,f,g,k){var l=[a,b,c,d,e,f,g,k||0];a=new Z.EllipseCurve(a,b,c,d,e,f,g,k);this.curves.push(a);a=a.getPoint(1);l.push(a.x);l.push(a.y);this.actions.push({action:\"ellipse\",args:l})},getSpacedPoints:function(a){a||(a=40);for(var b=[],c=0;c<a;c++)b.push(this.getPoint(c/a));this.autoClose&&b.push(b[0]);return b},getPoints:function(a){a=a||12;for(var b=\nZ.ShapeUtils.b2,c=Z.ShapeUtils.b3,d=[],e,f,g,k,l,m,n,q,p=0,t=this.actions.length;p<t;p++){q=this.actions[p];var r=q.args;switch(q.action){case \"moveTo\":d.push(new Z.Vector2(r[0],r[1]));break;case \"lineTo\":d.push(new Z.Vector2(r[0],r[1]));break;case \"quadraticCurveTo\":e=r[2];f=r[3];l=r[0];m=r[1];if(0<d.length){q=d[d.length-1];var v=q.x;n=q.y}else q=this.actions[p-1].args,v=q[q.length-2],n=q[q.length-1];for(r=1;r<=a;r++){var w=r/a;q=b(w,v,l,e);w=b(w,n,m,f);d.push(new Z.Vector2(q,w))}break;case \"bezierCurveTo\":e=\nr[4];f=r[5];l=r[0];m=r[1];g=r[2];k=r[3];0<d.length?(q=d[d.length-1],v=q.x,n=q.y):(q=this.actions[p-1].args,v=q[q.length-2],n=q[q.length-1]);for(r=1;r<=a;r++)w=r/a,q=c(w,v,l,g,e),w=c(w,n,m,k,f),d.push(new Z.Vector2(q,w));break;case \"splineThru\":q=this.actions[p-1].args;w=[new Z.Vector2(q[q.length-2],q[q.length-1])];q=a*r[0].length;w=w.concat(r[0]);w=new Z.SplineCurve(w);for(r=1;r<=q;r++)d.push(w.getPointAt(r/q));break;case \"arc\":e=r[0];f=r[1];m=r[2];g=r[3];q=r[4];l=!!r[5];n=q-g;v=2*a;for(r=1;r<=v;r++)w=\nr/v,l||(w=1-w),w=g+w*n,q=e+m*Math.cos(w),w=f+m*Math.sin(w),d.push(new Z.Vector2(q,w));break;case \"ellipse\":e=r[0];f=r[1];m=r[2];k=r[3];g=r[4];q=r[5];l=!!r[6];var z=r[7];n=q-g;v=2*a;if(0!==z){var y=Math.cos(z);var B=Math.sin(z)}for(r=1;r<=v;r++){w=r/v;l||(w=1-w);w=g+w*n;q=e+m*Math.cos(w);w=f+k*Math.sin(w);if(0!==z){var A=q;q=(A-e)*y-(w-f)*B+e;w=(A-e)*B+(w-f)*y+f}d.push(new Z.Vector2(q,w))}}}a=d[d.length-1];Math.abs(a.x-d[0].x)<Number.EPSILON&&Math.abs(a.y-d[0].y)<Number.EPSILON&&d.splice(d.length-\n1,1);this.autoClose&&d.push(d[0]);return d},toShapes:function(a,b){function c(a){for(var b=[],c=0,d=a.length;c<d;c++){var e=a[c],f=new Z.Shape;f.actions=e.actions;f.curves=e.curves;b.push(f)}return b}function d(a,b){for(var c=b.length,d=!1,e=c-1,f=0;f<c;e=f++){var g=b[e],k=b[f],l=k.x-g.x,m=k.y-g.y;if(Math.abs(m)>Number.EPSILON){if(0>m&&(g=b[f],l=-l,k=b[e],m=-m),!(a.y<g.y||a.y>k.y))if(a.y===g.y){if(a.x===g.x)return!0}else{e=m*(a.x-g.x)-l*(a.y-g.y);if(0===e)return!0;0>e||(d=!d)}}else if(a.y===g.y&&\n(k.x<=a.x&&a.x<=g.x||g.x<=a.x&&a.x<=k.x))return!0}return d}var e=Z.ShapeUtils.isClockWise,f=function(a){for(var b=[],c=new Z.Path,d=0,e=a.length;d<e;d++){var f=a[d],g=f.args,f=f.action;\"moveTo\"===f&&0!==c.actions.length&&(b.push(c),c=new Z.Path);c[f].apply(c,g)}0!==c.actions.length&&b.push(c);return b}(this.actions);if(0===f.length)return[];if(!0===b)return c(f);b=[];if(1===f.length){var g=f[0];var k=new Z.Shape;k.actions=g.actions;k.curves=g.curves;b.push(k);return b}var l=!e(f[0].getPoints()),l=\na?!l:l;k=[];var m=[],n=[],q=0;m[q]=void 0;n[q]=[];for(var p=0,t=f.length;p<t;p++){g=f[p];var r=g.getPoints();var v=e(r);(v=a?!v:v)?(!l&&m[q]&&q++,m[q]={s:new Z.Shape,p:r},m[q].s.actions=g.actions,m[q].s.curves=g.curves,l&&q++,n[q]=[]):n[q].push({h:g,p:r[0]})}if(!m[0])return c(f);if(1<m.length){p=!1;a=[];e=0;for(f=m.length;e<f;e++)k[e]=[];e=0;for(f=m.length;e<f;e++)for(g=n[e],v=0;v<g.length;v++){l=g[v];q=!0;for(r=0;r<m.length;r++)d(l.p,m[r].p)&&(e!==r&&a.push({froms:e,tos:r,hole:v}),q?(q=!1,k[r].push(l)):\np=!0);q&&k[e].push(l)}0<a.length&&(p||(n=k))}p=0;for(e=m.length;p<e;p++)for(k=m[p].s,b.push(k),a=n[p],f=0,g=a.length;f<g;f++)k.holes.push(a[f].h);return b}});Z.Shape=function(){Z.Path.apply(this,arguments);this.holes=[]};\nZ.Shape.prototype=Object.assign(Object.create(Z.Path.prototype),{constructor:Z.Shape,extrude:function(a){return new Z.ExtrudeGeometry(this,a)},makeGeometry:function(a){return new Z.ShapeGeometry(this,a)},getPointsHoles:function(a){for(var b=[],c=0,d=this.holes.length;c<d;c++)b[c]=this.holes[c].getPoints(a);return b},extractAllPoints:function(a){return{shape:this.getPoints(a),holes:this.getPointsHoles(a)}},extractPoints:function(a){return this.extractAllPoints(a)}});\nZ.LineCurve=function(a,b){this.v1=a;this.v2=b};Z.LineCurve.prototype=Object.create(Z.Curve.prototype);Z.LineCurve.prototype.constructor=Z.LineCurve;Z.LineCurve.prototype.getPoint=function(a){var b=this.v2.clone().sub(this.v1);b.multiplyScalar(a).add(this.v1);return b};Z.LineCurve.prototype.getPointAt=function(a){return this.getPoint(a)};Z.LineCurve.prototype.getTangent=function(){return this.v2.clone().sub(this.v1).normalize()};Z.QuadraticBezierCurve=function(a,b,c){this.v0=a;this.v1=b;this.v2=c};\nZ.QuadraticBezierCurve.prototype=Object.create(Z.Curve.prototype);Z.QuadraticBezierCurve.prototype.constructor=Z.QuadraticBezierCurve;Z.QuadraticBezierCurve.prototype.getPoint=function(a){var b=Z.ShapeUtils.b2;return new Z.Vector2(b(a,this.v0.x,this.v1.x,this.v2.x),b(a,this.v0.y,this.v1.y,this.v2.y))};Z.QuadraticBezierCurve.prototype.getTangent=function(a){var b=Z.CurveUtils.tangentQuadraticBezier;return(new Z.Vector2(b(a,this.v0.x,this.v1.x,this.v2.x),b(a,this.v0.y,this.v1.y,this.v2.y))).normalize()};\nZ.CubicBezierCurve=function(a,b,c,d){this.v0=a;this.v1=b;this.v2=c;this.v3=d};Z.CubicBezierCurve.prototype=Object.create(Z.Curve.prototype);Z.CubicBezierCurve.prototype.constructor=Z.CubicBezierCurve;Z.CubicBezierCurve.prototype.getPoint=function(a){var b=Z.ShapeUtils.b3;return new Z.Vector2(b(a,this.v0.x,this.v1.x,this.v2.x,this.v3.x),b(a,this.v0.y,this.v1.y,this.v2.y,this.v3.y))};\nZ.CubicBezierCurve.prototype.getTangent=function(a){var b=Z.CurveUtils.tangentCubicBezier;return(new Z.Vector2(b(a,this.v0.x,this.v1.x,this.v2.x,this.v3.x),b(a,this.v0.y,this.v1.y,this.v2.y,this.v3.y))).normalize()};Z.SplineCurve=function(a){this.points=void 0==a?[]:a};Z.SplineCurve.prototype=Object.create(Z.Curve.prototype);Z.SplineCurve.prototype.constructor=Z.SplineCurve;\nZ.SplineCurve.prototype.getPoint=function(a){var b=this.points;a*=b.length-1;var c=Math.floor(a);a-=c;var d=b[0===c?c:c-1],e=b[c],f=b[c>b.length-2?b.length-1:c+1],b=b[c>b.length-3?b.length-1:c+2],c=Z.CurveUtils.interpolate;return new Z.Vector2(c(d.x,e.x,f.x,b.x,a),c(d.y,e.y,f.y,b.y,a))};Z.EllipseCurve=function(a,b,c,d,e,f,g,k){this.aX=a;this.aY=b;this.xRadius=c;this.yRadius=d;this.aStartAngle=e;this.aEndAngle=f;this.aClockwise=g;this.aRotation=k||0};Z.EllipseCurve.prototype=Object.create(Z.Curve.prototype);\nZ.EllipseCurve.prototype.constructor=Z.EllipseCurve;\nZ.EllipseCurve.prototype.getPoint=function(a){var b=this.aEndAngle-this.aStartAngle;0>b&&(b+=2*Math.PI);b>2*Math.PI&&(b-=2*Math.PI);b=!0===this.aClockwise?this.aEndAngle+(1-a)*(2*Math.PI-b):this.aStartAngle+a*b;a=this.aX+this.xRadius*Math.cos(b);var c=this.aY+this.yRadius*Math.sin(b);if(0!==this.aRotation){var b=Math.cos(this.aRotation),d=Math.sin(this.aRotation),e=a;a=(e-this.aX)*b-(c-this.aY)*d+this.aX;c=(e-this.aX)*d+(c-this.aY)*b+this.aY}return new Z.Vector2(a,c)};\nZ.ArcCurve=function(a,b,c,d,e,f){Z.EllipseCurve.call(this,a,b,c,c,d,e,f)};Z.ArcCurve.prototype=Object.create(Z.EllipseCurve.prototype);Z.ArcCurve.prototype.constructor=Z.ArcCurve;Z.LineCurve3=Z.Curve.create(function(a,b){this.v1=a;this.v2=b},function(a){var b=new Z.Vector3;b.subVectors(this.v2,this.v1);b.multiplyScalar(a);b.add(this.v1);return b});\nZ.QuadraticBezierCurve3=Z.Curve.create(function(a,b,c){this.v0=a;this.v1=b;this.v2=c},function(a){var b=Z.ShapeUtils.b2;return new Z.Vector3(b(a,this.v0.x,this.v1.x,this.v2.x),b(a,this.v0.y,this.v1.y,this.v2.y),b(a,this.v0.z,this.v1.z,this.v2.z))});\nZ.CubicBezierCurve3=Z.Curve.create(function(a,b,c,d){this.v0=a;this.v1=b;this.v2=c;this.v3=d},function(a){var b=Z.ShapeUtils.b3;return new Z.Vector3(b(a,this.v0.x,this.v1.x,this.v2.x,this.v3.x),b(a,this.v0.y,this.v1.y,this.v2.y,this.v3.y),b(a,this.v0.z,this.v1.z,this.v2.z,this.v3.z))});\nZ.SplineCurve3=Z.Curve.create(function(a){console.warn(\"THREE.SplineCurve3 will be deprecated. Please use THREE.CatmullRomCurve3\");this.points=void 0==a?[]:a},function(a){var b=this.points;a*=b.length-1;var c=Math.floor(a);a-=c;var d=b[0==c?c:c-1],e=b[c],f=b[c>b.length-2?b.length-1:c+1],b=b[c>b.length-3?b.length-1:c+2],c=Z.CurveUtils.interpolate;return new Z.Vector3(c(d.x,e.x,f.x,b.x,a),c(d.y,e.y,f.y,b.y,a),c(d.z,e.z,f.z,b.z,a))});\nZ.CatmullRomCurve3=function(){function a(){}var b=new Z.Vector3,c=new a,d=new a,e=new a;a.prototype.init=function(a,b,c,d){this.c0=a;this.c1=c;this.c2=-3*a+3*b-2*c-d;this.c3=2*a-2*b+c+d};a.prototype.initNonuniformCatmullRom=function(a,b,c,d,e,n,q){this.init(b,c,((b-a)/e-(c-a)/(e+n)+(c-b)/n)*n,((c-b)/n-(d-b)/(n+q)+(d-c)/q)*n)};a.prototype.initCatmullRom=function(a,b,c,d,e){this.init(b,c,e*(c-a),e*(d-b))};a.prototype.calc=function(a){var b=a*a;return this.c0+this.c1*a+this.c2*b+this.c3*b*a};return Z.Curve.create(function(a){this.points=\na||[];this.closed=!1},function(a){var f=this.points;var k=f.length;2>k&&console.log(\"duh, you need at least 2 points\");a*=k-(this.closed?0:1);var l=Math.floor(a);a-=l;this.closed?l+=0<l?0:(Math.floor(Math.abs(l)/f.length)+1)*f.length:0===a&&l===k-1&&(l=k-2,a=1);if(this.closed||0<l)var m=f[(l-1)%k];else b.subVectors(f[0],f[1]).add(f[0]),m=b;var n=f[l%k];var q=f[(l+1)%k];this.closed||l+2<k?f=f[(l+2)%k]:(b.subVectors(f[k-1],f[k-2]).add(f[k-1]),f=b);if(void 0===this.type||\"centripetal\"===this.type||\"chordal\"===\nthis.type){var p=\"chordal\"===this.type?.5:.25;k=Math.pow(m.distanceToSquared(n),p);l=Math.pow(n.distanceToSquared(q),p);p=Math.pow(q.distanceToSquared(f),p);1E-4>l&&(l=1);1E-4>k&&(k=l);1E-4>p&&(p=l);c.initNonuniformCatmullRom(m.x,n.x,q.x,f.x,k,l,p);d.initNonuniformCatmullRom(m.y,n.y,q.y,f.y,k,l,p);e.initNonuniformCatmullRom(m.z,n.z,q.z,f.z,k,l,p)}else\"catmullrom\"===this.type&&(k=void 0!==this.tension?this.tension:.5,c.initCatmullRom(m.x,n.x,q.x,f.x,k),d.initCatmullRom(m.y,n.y,q.y,f.y,k),e.initCatmullRom(m.z,\nn.z,q.z,f.z,k));return new Z.Vector3(c.calc(a),d.calc(a),e.calc(a))})}();Z.ClosedSplineCurve3=function(a){console.warn(\"THREE.ClosedSplineCurve3 has been deprecated. Please use THREE.CatmullRomCurve3.\");Z.CatmullRomCurve3.call(this,a);this.type=\"catmullrom\";this.closed=!0};Z.ClosedSplineCurve3.prototype=Object.create(Z.CatmullRomCurve3.prototype);\nZ.BoxGeometry=function(a,b,c,d,e,f){Z.Geometry.call(this);this.type=\"BoxGeometry\";this.parameters={width:a,height:b,depth:c,widthSegments:d,heightSegments:e,depthSegments:f};this.fromBufferGeometry(new Z.BoxBufferGeometry(a,b,c,d,e,f));this.mergeVertices()};Z.BoxGeometry.prototype=Object.create(Z.Geometry.prototype);Z.BoxGeometry.prototype.constructor=Z.BoxGeometry;Z.CubeGeometry=Z.BoxGeometry;\nZ.BoxBufferGeometry=function(a,b,c,d,e,f){function g(a,b,c,d,e,f,g,l,m,M,T){var A=f/m,B=g/M,F=f/2,E=g/2,C=l/2;g=m+1;for(var D=M+1,H=f=0,I=new Z.Vector3,J=0;J<D;J++)for(var fa=J*B-E,La=0;La<g;La++)I[a]=(La*A-F)*d,I[b]=fa*e,I[c]=C,q[r]=I.x,q[r+1]=I.y,q[r+2]=I.z,I[a]=0,I[b]=0,I[c]=0<l?1:-1,p[r]=I.x,p[r+1]=I.y,p[r+2]=I.z,t[v]=La/m,t[v+1]=1-J/M,r+=3,v+=2,f+=1;for(J=0;J<M;J++)for(La=0;La<m;La++)a=z+La+g*(J+1),b=z+(La+1)+g*(J+1),c=z+(La+1)+g*J,n[w]=z+La+g*J,n[w+1]=a,n[w+2]=c,n[w+3]=a,n[w+4]=b,n[w+5]=c,w+=\n6,H+=6;k.addGroup(y,H,T);y+=H;z+=f}Z.BufferGeometry.call(this);this.type=\"BoxBufferGeometry\";this.parameters={width:a,height:b,depth:c,widthSegments:d,heightSegments:e,depthSegments:f};var k=this;d=Math.floor(d)||1;e=Math.floor(e)||1;f=Math.floor(f)||1;var l=function(a,b,c){return a=0+(a+1)*(b+1)*2+(a+1)*(c+1)*2+(c+1)*(b+1)*2}(d,e,f),m=function(a,b,c){a=0+a*b*2+a*c*2+c*b*2;return 6*a}(d,e,f),n=new (65535<m?Uint32Array:Uint16Array)(m),q=new Float32Array(3*l),p=new Float32Array(3*l),t=new Float32Array(2*\nl),r=0,v=0,w=0,z=0,y=0;g(\"z\",\"y\",\"x\",-1,-1,c,b,a,f,e,0);g(\"z\",\"y\",\"x\",1,-1,c,b,-a,f,e,1);g(\"x\",\"z\",\"y\",1,1,a,c,b,d,f,2);g(\"x\",\"z\",\"y\",1,-1,a,c,-b,d,f,3);g(\"x\",\"y\",\"z\",1,-1,a,b,c,d,e,4);g(\"x\",\"y\",\"z\",-1,-1,a,b,-c,d,e,5);this.setIndex(new Z.BufferAttribute(n,1));this.addAttribute(\"position\",new Z.BufferAttribute(q,3));this.addAttribute(\"normal\",new Z.BufferAttribute(p,3));this.addAttribute(\"uv\",new Z.BufferAttribute(t,2))};Z.BoxBufferGeometry.prototype=Object.create(Z.BufferGeometry.prototype);\nZ.BoxBufferGeometry.prototype.constructor=Z.BoxBufferGeometry;Z.CircleGeometry=function(a,b,c,d){Z.Geometry.call(this);this.type=\"CircleGeometry\";this.parameters={radius:a,segments:b,thetaStart:c,thetaLength:d};this.fromBufferGeometry(new Z.CircleBufferGeometry(a,b,c,d))};Z.CircleGeometry.prototype=Object.create(Z.Geometry.prototype);Z.CircleGeometry.prototype.constructor=Z.CircleGeometry;\nZ.CircleBufferGeometry=function(a,b,c,d){Z.BufferGeometry.call(this);this.type=\"CircleBufferGeometry\";this.parameters={radius:a,segments:b,thetaStart:c,thetaLength:d};a=a||50;b=void 0!==b?Math.max(3,b):8;c=void 0!==c?c:0;d=void 0!==d?d:2*Math.PI;var e=b+2,f=new Float32Array(3*e),g=new Float32Array(3*e),e=new Float32Array(2*e);g[2]=1;e[0]=.5;e[1]=.5;for(var k=0,l=3,m=2;k<=b;k++,l+=3,m+=2){var n=c+k/b*d;f[l]=a*Math.cos(n);f[l+1]=a*Math.sin(n);g[l+2]=1;e[m]=(f[l]/a+1)/2;e[m+1]=(f[l+1]/a+1)/2}c=[];for(l=\n1;l<=b;l++)c.push(l,l+1,0);this.setIndex(new Z.BufferAttribute(new Uint16Array(c),1));this.addAttribute(\"position\",new Z.BufferAttribute(f,3));this.addAttribute(\"normal\",new Z.BufferAttribute(g,3));this.addAttribute(\"uv\",new Z.BufferAttribute(e,2));this.boundingSphere=new Z.Sphere(new Z.Vector3,a)};Z.CircleBufferGeometry.prototype=Object.create(Z.BufferGeometry.prototype);Z.CircleBufferGeometry.prototype.constructor=Z.CircleBufferGeometry;\nZ.CylinderBufferGeometry=function(a,b,c,d,e,f,g,k){function l(c){var e,f=new Z.Vector2,l=new Z.Vector3,n=0,p=!0===c?a:b,q=!0===c?1:-1;var B=z;for(e=1;e<=d;e++)r.setXYZ(z,0,A*q,0),v.setXYZ(z,0,q,0),f.x=.5,f.y=.5,w.setXY(z,f.x,f.y),z++;var E=z;for(e=0;e<=d;e++){var L=e/d*k+g,S=Math.cos(L),L=Math.sin(L);l.x=p*L;l.y=A*q;l.z=p*S;r.setXYZ(z,l.x,l.y,l.z);v.setXYZ(z,0,q,0);f.x=.5*S+.5;f.y=.5*L*q+.5;w.setXY(z,f.x,f.y);z++}for(e=0;e<d;e++)f=B+e,l=E+e,!0===c?(t.setX(y,l),y++,t.setX(y,l+1)):(t.setX(y,l+1),y++,\nt.setX(y,l)),y++,t.setX(y,f),y++,n+=3;m.addGroup(D,n,!0===c?1:2);D+=n}Z.BufferGeometry.call(this);this.type=\"CylinderBufferGeometry\";this.parameters={radiusTop:a,radiusBottom:b,height:c,radialSegments:d,heightSegments:e,openEnded:f,thetaStart:g,thetaLength:k};var m=this;a=void 0!==a?a:20;b=void 0!==b?b:20;c=void 0!==c?c:100;d=Math.floor(d)||8;e=Math.floor(e)||1;f=void 0!==f?f:!1;g=void 0!==g?g:0;k=void 0!==k?k:2*Math.PI;var n=0;!1===f&&(0<a&&n++,0<b&&n++);var q=function(){var a=(d+1)*(e+1);!1===f&&\n(a+=(d+1)*n+d*n);return a}(),p=function(){var a=d*e*6;!1===f&&(a+=d*n*3);return a}(),t=new Z.BufferAttribute(new (65535<p?Uint32Array:Uint16Array)(p),1),r=new Z.BufferAttribute(new Float32Array(3*q),3),v=new Z.BufferAttribute(new Float32Array(3*q),3),w=new Z.BufferAttribute(new Float32Array(2*q),2),z=0,y=0,B=[],A=c/2,D=0;(function(){var f,l,n=new Z.Vector3,p=new Z.Vector3,q=0,J=(b-a)/c;for(l=0;l<=e;l++){var M=[],T=l/e,U=T*(b-a)+a;for(f=0;f<=d;f++){var L=f/d;p.x=U*Math.sin(L*k+g);p.y=-T*c+A;p.z=U*\nMath.cos(L*k+g);r.setXYZ(z,p.x,p.y,p.z);n.copy(p);if(0===a&&0===l||0===b&&l===e)n.x=Math.sin(L*k+g),n.z=Math.cos(L*k+g);n.setY(Math.sqrt(n.x*n.x+n.z*n.z)*J).normalize();v.setXYZ(z,n.x,n.y,n.z);w.setXY(z,L,1-T);M.push(z);z++}B.push(M)}for(f=0;f<d;f++)for(l=0;l<e;l++)n=B[l+1][f],p=B[l+1][f+1],J=B[l][f+1],t.setX(y,B[l][f]),y++,t.setX(y,n),y++,t.setX(y,J),y++,t.setX(y,n),y++,t.setX(y,p),y++,t.setX(y,J),y++,q+=6;m.addGroup(D,q,0);D+=q})();!1===f&&(0<a&&l(!0),0<b&&l(!1));this.setIndex(t);this.addAttribute(\"position\",\nr);this.addAttribute(\"normal\",v);this.addAttribute(\"uv\",w)};Z.CylinderBufferGeometry.prototype=Object.create(Z.BufferGeometry.prototype);Z.CylinderBufferGeometry.prototype.constructor=Z.CylinderBufferGeometry;\nZ.CylinderGeometry=function(a,b,c,d,e,f,g,k){Z.Geometry.call(this);this.type=\"CylinderGeometry\";this.parameters={radiusTop:a,radiusBottom:b,height:c,radialSegments:d,heightSegments:e,openEnded:f,thetaStart:g,thetaLength:k};this.fromBufferGeometry(new Z.CylinderBufferGeometry(a,b,c,d,e,f,g,k));this.mergeVertices()};Z.CylinderGeometry.prototype=Object.create(Z.Geometry.prototype);Z.CylinderGeometry.prototype.constructor=Z.CylinderGeometry;\nZ.ConeBufferGeometry=function(a,b,c,d,e,f,g){Z.CylinderBufferGeometry.call(this,0,a,b,c,d,e,f,g);this.type=\"ConeBufferGeometry\";this.parameters={radius:a,height:b,radialSegments:c,heightSegments:d,thetaStart:f,thetaLength:g}};Z.ConeBufferGeometry.prototype=Object.create(Z.BufferGeometry.prototype);Z.ConeBufferGeometry.prototype.constructor=Z.ConeBufferGeometry;\nZ.ConeGeometry=function(a,b,c,d,e,f,g){Z.CylinderGeometry.call(this,0,a,b,c,d,e,f,g);this.type=\"ConeGeometry\";this.parameters={radius:a,height:b,radialSegments:c,heightSegments:d,openEnded:e,thetaStart:f,thetaLength:g}};Z.ConeGeometry.prototype=Object.create(Z.CylinderGeometry.prototype);Z.ConeGeometry.prototype.constructor=Z.ConeGeometry;\nZ.EdgesGeometry=function(a,b){function c(a,b){return a-b}Z.BufferGeometry.call(this);b=Math.cos(Z.Math.DEG2RAD*(void 0!==b?b:1));var d=[0,0],e={},f=[\"a\",\"b\",\"c\"];if(a instanceof Z.BufferGeometry){var g=new Z.Geometry;g.fromBufferGeometry(a)}else g=a.clone();g.mergeVertices();g.computeFaceNormals();a=g.vertices;g=g.faces;for(var k=0,l=g.length;k<l;k++)for(var m=g[k],n=0;3>n;n++){d[0]=m[f[n]];d[1]=m[f[(n+1)%3]];d.sort(c);var q=d.toString();void 0===e[q]?e[q]={vert1:d[0],vert2:d[1],face1:k,face2:void 0}:\ne[q].face2=k}d=[];for(q in e)if(f=e[q],void 0===f.face2||g[f.face1].normal.dot(g[f.face2].normal)<=b)k=a[f.vert1],d.push(k.x),d.push(k.y),d.push(k.z),k=a[f.vert2],d.push(k.x),d.push(k.y),d.push(k.z);this.addAttribute(\"position\",new Z.BufferAttribute(new Float32Array(d),3))};Z.EdgesGeometry.prototype=Object.create(Z.BufferGeometry.prototype);Z.EdgesGeometry.prototype.constructor=Z.EdgesGeometry;\nZ.ExtrudeGeometry=function(a,b){\"undefined\"!==typeof a&&(Z.Geometry.call(this),this.type=\"ExtrudeGeometry\",a=Array.isArray(a)?a:[a],this.addShapeList(a,b),this.computeFaceNormals())};Z.ExtrudeGeometry.prototype=Object.create(Z.Geometry.prototype);Z.ExtrudeGeometry.prototype.constructor=Z.ExtrudeGeometry;Z.ExtrudeGeometry.prototype.addShapeList=function(a,b){for(var c=a.length,d=0;d<c;d++)this.addShape(a[d],b)};\nZ.ExtrudeGeometry.prototype.addShape=function(a,b){function c(a,b,c){b||console.error(\"THREE.ExtrudeGeometry: vec does not exist\");return b.clone().multiplyScalar(c).add(a)}function d(a,b,c){var d=a.x-b.x;var e=a.y-b.y;var f=c.x-a.x;var g=c.y-a.y,k=d*d+e*e;if(Math.abs(d*g-e*f)>Number.EPSILON){var l=Math.sqrt(k),m=Math.sqrt(f*f+g*g),k=b.x-e/l;b=b.y+d/l;g=((c.x-g/m-k)*g-(c.y+f/m-b)*f)/(d*g-e*f);f=k+d*g-a.x;d=b+e*g-a.y;e=f*f+d*d;if(2>=e)return new Z.Vector2(f,d);e=Math.sqrt(e/2)}else a=!1,d>Number.EPSILON?\nf>Number.EPSILON&&(a=!0):d<-Number.EPSILON?f<-Number.EPSILON&&(a=!0):Math.sign(e)===Math.sign(g)&&(a=!0),a?(f=-e,e=Math.sqrt(k)):(f=d,d=e,e=Math.sqrt(k/2));return new Z.Vector2(f/e,d/e)}function e(a,b){for(K=a.length;0<=--K;){var c=K;var d=K-1;0>d&&(d=a.length-1);var e,f=t+2*n;for(e=0;e<f;e++){var g=L*e,k=L*(e+1),l=b+c+g,g=b+d+g,m=b+d+k,k=b+c+k,l=l+I,g=g+I,m=m+I,k=k+I;F.faces.push(new Z.Face3(l,g,k,null,null,1));F.faces.push(new Z.Face3(g,m,k,null,null,1));l=w.generateSideWallUV(F,l,g,m,k);F.faceVertexUvs[0].push([l[0],\nl[1],l[3]]);F.faceVertexUvs[0].push([l[1],l[2],l[3]])}}}function f(a,b,c){F.vertices.push(new Z.Vector3(a,b,c))}function g(a,b,c){a+=I;b+=I;c+=I;F.faces.push(new Z.Face3(a,b,c,null,null,0));F.faceVertexUvs[0].push(w.generateTopUV(F,a,b,c))}var k=void 0!==b.amount?b.amount:100,l=void 0!==b.bevelThickness?b.bevelThickness:6,m=void 0!==b.bevelSize?b.bevelSize:l-2,n=void 0!==b.bevelSegments?b.bevelSegments:3,q=void 0!==b.bevelEnabled?b.bevelEnabled:!0,p=void 0!==b.curveSegments?b.curveSegments:12,t=void 0!==\nb.steps?b.steps:1,r=b.extrudePath,v=!1,w=void 0!==b.UVGenerator?b.UVGenerator:Z.ExtrudeGeometry.WorldUVGenerator;if(r){var z=r.getSpacedPoints(t);v=!0;q=!1;var y=void 0!==b.frames?b.frames:new Z.TubeGeometry.FrenetFrames(r,t,!1);var B=new Z.Vector3;var A=new Z.Vector3;var D=new Z.Vector3}q||(m=l=n=0);var E,F=this,I=this.vertices.length;b=a.extractPoints(p);a=b.shape;var H=b.holes;if(b=!Z.ShapeUtils.isClockWise(a)){a=a.reverse();var C=0;for(E=H.length;C<E;C++){var J=H[C];Z.ShapeUtils.isClockWise(J)&&\n(H[C]=J.reverse())}b=!1}var M=Z.ShapeUtils.triangulateShape(a,H),T=a;C=0;for(E=H.length;C<E;C++)J=H[C],a=a.concat(J);var U,L=a.length,S,R=M.length;b=[];var K=0;var N=T.length;var Q=N-1;for(U=K+1;K<N;K++,Q++,U++)Q===N&&(Q=0),U===N&&(U=0),b[K]=d(T[K],T[Q],T[U]);var p=[],r=b.concat();C=0;for(E=H.length;C<E;C++){J=H[C];var la=[];K=0;N=J.length;Q=N-1;for(U=K+1;K<N;K++,Q++,U++)Q===N&&(Q=0),U===N&&(U=0),la[K]=d(J[K],J[Q],J[U]);p.push(la);r=r.concat(la)}for(Q=0;Q<n;Q++){N=Q/n;var sa=l*(1-N);U=m*Math.sin(N*\nMath.PI/2);K=0;for(N=T.length;K<N;K++){var fa=c(T[K],b[K],U);f(fa.x,fa.y,-sa)}C=0;for(E=H.length;C<E;C++)for(J=H[C],la=p[C],K=0,N=J.length;K<N;K++)fa=c(J[K],la[K],U),f(fa.x,fa.y,-sa)}U=m;for(K=0;K<L;K++)fa=q?c(a[K],r[K],U):a[K],v?(A.copy(y.normals[0]).multiplyScalar(fa.x),B.copy(y.binormals[0]).multiplyScalar(fa.y),D.copy(z[0]).add(A).add(B),f(D.x,D.y,D.z)):f(fa.x,fa.y,0);for(N=1;N<=t;N++)for(K=0;K<L;K++)fa=q?c(a[K],r[K],U):a[K],v?(A.copy(y.normals[N]).multiplyScalar(fa.x),B.copy(y.binormals[N]).multiplyScalar(fa.y),\nD.copy(z[N]).add(A).add(B),f(D.x,D.y,D.z)):f(fa.x,fa.y,k/t*N);for(Q=n-1;0<=Q;Q--){N=Q/n;sa=l*(1-N);U=m*Math.sin(N*Math.PI/2);K=0;for(N=T.length;K<N;K++)fa=c(T[K],b[K],U),f(fa.x,fa.y,k+sa);C=0;for(E=H.length;C<E;C++)for(J=H[C],la=p[C],K=0,N=J.length;K<N;K++)fa=c(J[K],la[K],U),v?f(fa.x,fa.y+z[t-1].y,z[t-1].x+sa):f(fa.x,fa.y,k+sa)}(function(){if(q){var a=0*L;for(K=0;K<R;K++)S=M[K],g(S[2]+a,S[1]+a,S[0]+a);a=L*(t+2*n);for(K=0;K<R;K++)S=M[K],g(S[0]+a,S[1]+a,S[2]+a)}else{for(K=0;K<R;K++)S=M[K],g(S[2],S[1],\nS[0]);for(K=0;K<R;K++)S=M[K],g(S[0]+L*t,S[1]+L*t,S[2]+L*t)}})();(function(){var a=0;e(T,a);a+=T.length;C=0;for(E=H.length;C<E;C++)J=H[C],e(J,a),a+=J.length})()};\nZ.ExtrudeGeometry.WorldUVGenerator={generateTopUV:function(a,b,c,d){a=a.vertices;b=a[b];c=a[c];d=a[d];return[new Z.Vector2(b.x,b.y),new Z.Vector2(c.x,c.y),new Z.Vector2(d.x,d.y)]},generateSideWallUV:function(a,b,c,d,e){a=a.vertices;b=a[b];c=a[c];d=a[d];e=a[e];return.01>Math.abs(b.y-c.y)?[new Z.Vector2(b.x,1-b.z),new Z.Vector2(c.x,1-c.z),new Z.Vector2(d.x,1-d.z),new Z.Vector2(e.x,1-e.z)]:[new Z.Vector2(b.y,1-b.z),new Z.Vector2(c.y,1-c.z),new Z.Vector2(d.y,1-d.z),new Z.Vector2(e.y,1-e.z)]}};\nZ.ShapeGeometry=function(a,b){Z.Geometry.call(this);this.type=\"ShapeGeometry\";!1===Array.isArray(a)&&(a=[a]);this.addShapeList(a,b);this.computeFaceNormals()};Z.ShapeGeometry.prototype=Object.create(Z.Geometry.prototype);Z.ShapeGeometry.prototype.constructor=Z.ShapeGeometry;Z.ShapeGeometry.prototype.addShapeList=function(a,b){for(var c=0,d=a.length;c<d;c++)this.addShape(a[c],b);return this};\nZ.ShapeGeometry.prototype.addShape=function(a,b){void 0===b&&(b={});var c=b.material,d=void 0===b.UVGenerator?Z.ExtrudeGeometry.WorldUVGenerator:b.UVGenerator,e,f=this.vertices.length;a=a.extractPoints(void 0!==b.curveSegments?b.curveSegments:12);var g=a.shape,k=a.holes;if(!Z.ShapeUtils.isClockWise(g))for(g=g.reverse(),a=0,e=k.length;a<e;a++){var l=k[a];Z.ShapeUtils.isClockWise(l)&&(k[a]=l.reverse())}b=Z.ShapeUtils.triangulateShape(g,k);a=0;for(e=k.length;a<e;a++)l=k[a],g=g.concat(l);k=g.length;e=\nb.length;for(a=0;a<k;a++)l=g[a],this.vertices.push(new Z.Vector3(l.x,l.y,0));for(a=0;a<e;a++)k=b[a],g=k[0]+f,l=k[1]+f,k=k[2]+f,this.faces.push(new Z.Face3(g,l,k,null,null,c)),this.faceVertexUvs[0].push(d.generateTopUV(this,g,l,k))};\nZ.LatheBufferGeometry=function(a,b,c,d){Z.BufferGeometry.call(this);this.type=\"LatheBufferGeometry\";this.parameters={points:a,segments:b,phiStart:c,phiLength:d};b=Math.floor(b)||12;c=c||0;d=d||2*Math.PI;d=Z.Math.clamp(d,0,2*Math.PI);for(var e=(b+1)*a.length,f=b*a.length*6,g=new Z.BufferAttribute(new (65535<f?Uint32Array:Uint16Array)(f),1),k=new Z.BufferAttribute(new Float32Array(3*e),3),l=new Z.BufferAttribute(new Float32Array(2*e),2),m=0,n=0,q=1/b,p=new Z.Vector3,t=new Z.Vector2,e=0;e<=b;e++)for(var f=\nc+e*q*d,r=Math.sin(f),v=Math.cos(f),f=0;f<=a.length-1;f++)p.x=a[f].x*r,p.y=a[f].y,p.z=a[f].x*v,k.setXYZ(m,p.x,p.y,p.z),t.x=e/b,t.y=f/(a.length-1),l.setXY(m,t.x,t.y),m++;for(e=0;e<b;e++)for(f=0;f<a.length-1;f++)c=f+e*a.length,m=c+a.length,q=c+a.length+1,p=c+1,g.setX(n,c),n++,g.setX(n,m),n++,g.setX(n,p),n++,g.setX(n,m),n++,g.setX(n,q),n++,g.setX(n,p),n++;this.setIndex(g);this.addAttribute(\"position\",k);this.addAttribute(\"uv\",l);this.computeVertexNormals();if(d===2*Math.PI)for(d=this.attributes.normal.array,\ng=new Z.Vector3,k=new Z.Vector3,l=new Z.Vector3,c=b*a.length*3,f=e=0;e<a.length;e++,f+=3)g.x=d[f+0],g.y=d[f+1],g.z=d[f+2],k.x=d[c+f+0],k.y=d[c+f+1],k.z=d[c+f+2],l.addVectors(g,k).normalize(),d[f+0]=d[c+f+0]=l.x,d[f+1]=d[c+f+1]=l.y,d[f+2]=d[c+f+2]=l.z};Z.LatheBufferGeometry.prototype=Object.create(Z.BufferGeometry.prototype);Z.LatheBufferGeometry.prototype.constructor=Z.LatheBufferGeometry;\nZ.LatheGeometry=function(a,b,c,d){Z.Geometry.call(this);this.type=\"LatheGeometry\";this.parameters={points:a,segments:b,phiStart:c,phiLength:d};this.fromBufferGeometry(new Z.LatheBufferGeometry(a,b,c,d));this.mergeVertices()};Z.LatheGeometry.prototype=Object.create(Z.Geometry.prototype);Z.LatheGeometry.prototype.constructor=Z.LatheGeometry;\nZ.PlaneGeometry=function(a,b,c,d){Z.Geometry.call(this);this.type=\"PlaneGeometry\";this.parameters={width:a,height:b,widthSegments:c,heightSegments:d};this.fromBufferGeometry(new Z.PlaneBufferGeometry(a,b,c,d))};Z.PlaneGeometry.prototype=Object.create(Z.Geometry.prototype);Z.PlaneGeometry.prototype.constructor=Z.PlaneGeometry;\nZ.PlaneBufferGeometry=function(a,b,c,d){Z.BufferGeometry.call(this);this.type=\"PlaneBufferGeometry\";this.parameters={width:a,height:b,widthSegments:c,heightSegments:d};var e=a/2,f=b/2;c=Math.floor(c)||1;d=Math.floor(d)||1;var g=c+1,k=d+1,l=a/c,m=b/d;b=new Float32Array(g*k*3);a=new Float32Array(g*k*3);for(var n=new Float32Array(g*k*2),q=0,p=0,t=0;t<k;t++)for(var r=t*m-f,v=0;v<g;v++)b[q]=v*l-e,b[q+1]=-r,a[q+2]=1,n[p]=v/c,n[p+1]=1-t/d,q+=3,p+=2;q=0;e=new (65535<b.length/3?Uint32Array:Uint16Array)(c*\nd*6);for(t=0;t<d;t++)for(v=0;v<c;v++)f=v+g*(t+1),k=v+1+g*(t+1),l=v+1+g*t,e[q]=v+g*t,e[q+1]=f,e[q+2]=l,e[q+3]=f,e[q+4]=k,e[q+5]=l,q+=6;this.setIndex(new Z.BufferAttribute(e,1));this.addAttribute(\"position\",new Z.BufferAttribute(b,3));this.addAttribute(\"normal\",new Z.BufferAttribute(a,3));this.addAttribute(\"uv\",new Z.BufferAttribute(n,2))};Z.PlaneBufferGeometry.prototype=Object.create(Z.BufferGeometry.prototype);Z.PlaneBufferGeometry.prototype.constructor=Z.PlaneBufferGeometry;\nZ.RingBufferGeometry=function(a,b,c,d,e,f){Z.BufferGeometry.call(this);this.type=\"RingBufferGeometry\";this.parameters={innerRadius:a,outerRadius:b,thetaSegments:c,phiSegments:d,thetaStart:e,thetaLength:f};a=a||20;b=b||50;e=void 0!==e?e:0;f=void 0!==f?f:2*Math.PI;c=void 0!==c?Math.max(3,c):8;d=void 0!==d?Math.max(1,d):1;var g=(c+1)*(d+1),k=c*d*6,k=new Z.BufferAttribute(new (65535<k?Uint32Array:Uint16Array)(k),1),l=new Z.BufferAttribute(new Float32Array(3*g),3),m=new Z.BufferAttribute(new Float32Array(3*\ng),3),g=new Z.BufferAttribute(new Float32Array(2*g),2),n=0,q=0,p=a,t=(b-a)/d,r=new Z.Vector3,v=new Z.Vector2,w;for(a=0;a<=d;a++){for(w=0;w<=c;w++){var z=e+w/c*f;r.x=p*Math.cos(z);r.y=p*Math.sin(z);l.setXYZ(n,r.x,r.y,r.z);m.setXYZ(n,0,0,1);v.x=(r.x/b+1)/2;v.y=(r.y/b+1)/2;g.setXY(n,v.x,v.y);n++}p+=t}for(a=0;a<d;a++)for(b=a*(c+1),w=0;w<c;w++)e=z=w+b,f=z+c+1,n=z+c+2,z+=1,k.setX(q,e),q++,k.setX(q,f),q++,k.setX(q,n),q++,k.setX(q,e),q++,k.setX(q,n),q++,k.setX(q,z),q++;this.setIndex(k);this.addAttribute(\"position\",\nl);this.addAttribute(\"normal\",m);this.addAttribute(\"uv\",g)};Z.RingBufferGeometry.prototype=Object.create(Z.BufferGeometry.prototype);Z.RingBufferGeometry.prototype.constructor=Z.RingBufferGeometry;Z.RingGeometry=function(a,b,c,d,e,f){Z.Geometry.call(this);this.type=\"RingGeometry\";this.parameters={innerRadius:a,outerRadius:b,thetaSegments:c,phiSegments:d,thetaStart:e,thetaLength:f};this.fromBufferGeometry(new Z.RingBufferGeometry(a,b,c,d,e,f))};Z.RingGeometry.prototype=Object.create(Z.Geometry.prototype);\nZ.RingGeometry.prototype.constructor=Z.RingGeometry;Z.SphereGeometry=function(a,b,c,d,e,f,g){Z.Geometry.call(this);this.type=\"SphereGeometry\";this.parameters={radius:a,widthSegments:b,heightSegments:c,phiStart:d,phiLength:e,thetaStart:f,thetaLength:g};this.fromBufferGeometry(new Z.SphereBufferGeometry(a,b,c,d,e,f,g))};Z.SphereGeometry.prototype=Object.create(Z.Geometry.prototype);Z.SphereGeometry.prototype.constructor=Z.SphereGeometry;\nZ.SphereBufferGeometry=function(a,b,c,d,e,f,g){Z.BufferGeometry.call(this);this.type=\"SphereBufferGeometry\";this.parameters={radius:a,widthSegments:b,heightSegments:c,phiStart:d,phiLength:e,thetaStart:f,thetaLength:g};a=a||50;b=Math.max(3,Math.floor(b)||8);c=Math.max(2,Math.floor(c)||6);d=void 0!==d?d:0;e=void 0!==e?e:2*Math.PI;f=void 0!==f?f:0;g=void 0!==g?g:Math.PI;for(var k=f+g,l=(b+1)*(c+1),m=new Z.BufferAttribute(new Float32Array(3*l),3),n=new Z.BufferAttribute(new Float32Array(3*l),3),l=new Z.BufferAttribute(new Float32Array(2*\nl),2),q=0,p=[],t=new Z.Vector3,r=0;r<=c;r++){for(var v=[],w=r/c,z=0;z<=b;z++){var y=z/b,B=-a*Math.cos(d+y*e)*Math.sin(f+w*g),A=a*Math.cos(f+w*g),D=a*Math.sin(d+y*e)*Math.sin(f+w*g);t.set(B,A,D).normalize();m.setXYZ(q,B,A,D);n.setXYZ(q,t.x,t.y,t.z);l.setXY(q,y,1-w);v.push(q);q++}p.push(v)}d=[];for(r=0;r<c;r++)for(z=0;z<b;z++)e=p[r][z+1],g=p[r][z],q=p[r+1][z],t=p[r+1][z+1],(0!==r||0<f)&&d.push(e,g,t),(r!==c-1||k<Math.PI)&&d.push(g,q,t);this.setIndex(new (65535<m.count?Z.Uint32Attribute:Z.Uint16Attribute)(d,\n1));this.addAttribute(\"position\",m);this.addAttribute(\"normal\",n);this.addAttribute(\"uv\",l);this.boundingSphere=new Z.Sphere(new Z.Vector3,a)};Z.SphereBufferGeometry.prototype=Object.create(Z.BufferGeometry.prototype);Z.SphereBufferGeometry.prototype.constructor=Z.SphereBufferGeometry;\nZ.TextGeometry=function(a,b){b=b||{};var c=b.font;if(!1===c instanceof Z.Font)return console.error(\"THREE.TextGeometry: font parameter is not an instance of THREE.Font.\"),new Z.Geometry;a=c.generateShapes(a,b.size,b.curveSegments);b.amount=void 0!==b.height?b.height:50;void 0===b.bevelThickness&&(b.bevelThickness=10);void 0===b.bevelSize&&(b.bevelSize=8);void 0===b.bevelEnabled&&(b.bevelEnabled=!1);Z.ExtrudeGeometry.call(this,a,b);this.type=\"TextGeometry\"};Z.TextGeometry.prototype=Object.create(Z.ExtrudeGeometry.prototype);\nZ.TextGeometry.prototype.constructor=Z.TextGeometry;\nZ.TorusBufferGeometry=function(a,b,c,d,e){Z.BufferGeometry.call(this);this.type=\"TorusBufferGeometry\";this.parameters={radius:a,tube:b,radialSegments:c,tubularSegments:d,arc:e};a=a||100;b=b||40;c=Math.floor(c)||8;d=Math.floor(d)||6;e=e||2*Math.PI;var f=(c+1)*(d+1),g=c*d*6,g=new (65535<g?Uint32Array:Uint16Array)(g),k=new Float32Array(3*f),l=new Float32Array(3*f),f=new Float32Array(2*f),m=0,n=0,q=0,p=new Z.Vector3,t=new Z.Vector3,r=new Z.Vector3,v,w;for(v=0;v<=c;v++)for(w=0;w<=d;w++){var z=w/d*e,y=\nv/c*Math.PI*2;t.x=(a+b*Math.cos(y))*Math.cos(z);t.y=(a+b*Math.cos(y))*Math.sin(z);t.z=b*Math.sin(y);k[m]=t.x;k[m+1]=t.y;k[m+2]=t.z;p.x=a*Math.cos(z);p.y=a*Math.sin(z);r.subVectors(t,p).normalize();l[m]=r.x;l[m+1]=r.y;l[m+2]=r.z;f[n]=w/d;f[n+1]=v/c;m+=3;n+=2}for(v=1;v<=c;v++)for(w=1;w<=d;w++)a=(d+1)*(v-1)+w-1,b=(d+1)*(v-1)+w,e=(d+1)*v+w,g[q]=(d+1)*v+w-1,g[q+1]=a,g[q+2]=e,g[q+3]=a,g[q+4]=b,g[q+5]=e,q+=6;this.setIndex(new Z.BufferAttribute(g,1));this.addAttribute(\"position\",new Z.BufferAttribute(k,3));\nthis.addAttribute(\"normal\",new Z.BufferAttribute(l,3));this.addAttribute(\"uv\",new Z.BufferAttribute(f,2))};Z.TorusBufferGeometry.prototype=Object.create(Z.BufferGeometry.prototype);Z.TorusBufferGeometry.prototype.constructor=Z.TorusBufferGeometry;Z.TorusGeometry=function(a,b,c,d,e){Z.Geometry.call(this);this.type=\"TorusGeometry\";this.parameters={radius:a,tube:b,radialSegments:c,tubularSegments:d,arc:e};this.fromBufferGeometry(new Z.TorusBufferGeometry(a,b,c,d,e))};Z.TorusGeometry.prototype=Object.create(Z.Geometry.prototype);\nZ.TorusGeometry.prototype.constructor=Z.TorusGeometry;\nZ.TorusKnotBufferGeometry=function(a,b,c,d,e,f){function g(a,b,c,d,e){var f=Math.sin(a);b=c/b*a;c=Math.cos(b);e.x=d*(2+c)*.5*Math.cos(a);e.y=d*(2+c)*f*.5;e.z=d*Math.sin(b)*.5}Z.BufferGeometry.call(this);this.type=\"TorusKnotBufferGeometry\";this.parameters={radius:a,tube:b,tubularSegments:c,radialSegments:d,p:e,q:f};a=a||100;b=b||40;c=Math.floor(c)||64;d=Math.floor(d)||8;e=e||2;f=f||3;var k=(d+1)*(c+1),l=d*c*6,l=new Z.BufferAttribute(new (65535<l?Uint32Array:Uint16Array)(l),1),m=new Z.BufferAttribute(new Float32Array(3*\nk),3),n=new Z.BufferAttribute(new Float32Array(3*k),3),k=new Z.BufferAttribute(new Float32Array(2*k),2),q,p=0,t=0,r=new Z.Vector3,v=new Z.Vector3,w=new Z.Vector2,z=new Z.Vector3,y=new Z.Vector3,B=new Z.Vector3,A=new Z.Vector3,D=new Z.Vector3;for(q=0;q<=c;++q){var E=q/c*e*Math.PI*2;g(E,e,f,a,z);g(E+.01,e,f,a,y);A.subVectors(y,z);D.addVectors(y,z);If(B,A,D);If(D,B,A);B.normalize();D.normalize();for(E=0;E<=d;++E){var F=E/d*Math.PI*2,I=-b*Math.cos(F),F=b*Math.sin(F);r.x=z.x+(I*D.x+F*B.x);r.y=z.y+(I*D.y+\nF*B.y);r.z=z.z+(I*D.z+F*B.z);m.setXYZ(p,r.x,r.y,r.z);v.subVectors(r,z).normalize();n.setXYZ(p,v.x,v.y,v.z);w.x=q/c;w.y=E/d;k.setXY(p,w.x,w.y);p++}}for(E=1;E<=c;E++)for(q=1;q<=d;q++)a=(d+1)*E+(q-1),b=(d+1)*E+q,e=(d+1)*(E-1)+q,l.setX(t,(d+1)*(E-1)+(q-1)),t++,l.setX(t,a),t++,l.setX(t,e),t++,l.setX(t,a),t++,l.setX(t,b),t++,l.setX(t,e),t++;this.setIndex(l);this.addAttribute(\"position\",m);this.addAttribute(\"normal\",n);this.addAttribute(\"uv\",k)};Z.TorusKnotBufferGeometry.prototype=Object.create(Z.BufferGeometry.prototype);\nZ.TorusKnotBufferGeometry.prototype.constructor=Z.TorusKnotBufferGeometry;Z.TorusKnotGeometry=function(a,b,c,d,e,f,g){Z.Geometry.call(this);this.type=\"TorusKnotGeometry\";this.parameters={radius:a,tube:b,tubularSegments:c,radialSegments:d,p:e,q:f};void 0!==g&&console.warn(\"THREE.TorusKnotGeometry: heightScale has been deprecated. Use .scale( x, y, z ) instead.\");this.fromBufferGeometry(new Z.TorusKnotBufferGeometry(a,b,c,d,e,f));this.mergeVertices()};Z.TorusKnotGeometry.prototype=Object.create(Z.Geometry.prototype);\nZ.TorusKnotGeometry.prototype.constructor=Z.TorusKnotGeometry;\nZ.TubeGeometry=function(a,b,c,d,e,f){Z.Geometry.call(this);this.type=\"TubeGeometry\";this.parameters={path:a,segments:b,radius:c,radialSegments:d,closed:e,taper:f};b=b||64;c=c||1;d=d||8;e=e||!1;f=f||Z.TubeGeometry.NoTaper;var g=[],k=b+1,l=new Z.Vector3;var m=new Z.TubeGeometry.FrenetFrames(a,b,e);var n=m.normals;var q=m.binormals;this.tangents=m.tangents;this.normals=n;this.binormals=q;for(m=0;m<k;m++){g[m]=[];var p=m/(k-1);var t=a.getPointAt(p);var r=n[m];var v=q[m];var w=c*f(p);for(p=0;p<d;p++){var z=\np/d*2*Math.PI;var y=-w*Math.cos(z);z=w*Math.sin(z);l.copy(t);l.x+=y*r.x+z*v.x;l.y+=y*r.y+z*v.y;l.z+=y*r.z+z*v.z;g[m][p]=this.vertices.push(new Z.Vector3(l.x,l.y,l.z))-1}}for(m=0;m<b;m++)for(p=0;p<d;p++)f=e?(m+1)%b:m+1,k=(p+1)%d,a=g[m][p],c=g[f][p],f=g[f][k],k=g[m][k],l=new Z.Vector2(m/b,p/d),n=new Z.Vector2((m+1)/b,p/d),q=new Z.Vector2((m+1)/b,(p+1)/d),r=new Z.Vector2(m/b,(p+1)/d),this.faces.push(new Z.Face3(a,c,k)),this.faceVertexUvs[0].push([l,n,r]),this.faces.push(new Z.Face3(c,f,k)),this.faceVertexUvs[0].push([n.clone(),\nq,r.clone()]);this.computeFaceNormals();this.computeVertexNormals()};Z.TubeGeometry.prototype=Object.create(Z.Geometry.prototype);Z.TubeGeometry.prototype.constructor=Z.TubeGeometry;Z.TubeGeometry.NoTaper=function(){return 1};Z.TubeGeometry.SinusoidalTaper=function(a){return Math.sin(Math.PI*a)};\nZ.TubeGeometry.FrenetFrames=function(a,b,c){var d=new Z.Vector3,e=[],f=[],g=[],k=new Z.Vector3,l=new Z.Matrix4;b+=1;var m;this.tangents=e;this.normals=f;this.binormals=g;for(m=0;m<b;m++){var n=m/(b-1);var q=m;var p=a;n=Ag(p,n);p=p.getTangent(n);e[q]=p;e[m].normalize()}f[0]=new Z.Vector3;g[0]=new Z.Vector3;a=Number.MAX_VALUE;m=Math.abs(e[0].x);q=Math.abs(e[0].y);p=Math.abs(e[0].z);m<=a&&(a=m,d.set(1,0,0));q<=a&&(a=q,d.set(0,1,0));p<=a&&d.set(0,0,1);If(k,e[0],d).normalize();If(f[0],e[0],k);If(g[0],\ne[0],f[0]);for(m=1;m<b;m++)f[m]=f[m-1].clone(),g[m]=g[m-1].clone(),If(k,e[m-1],e[m]),k.length()>Number.EPSILON&&(k.normalize(),d=Math.acos(Z.Math.clamp(e[m-1].dot(e[m]),-1,1)),f[m].applyMatrix4(Yf(l,k,d))),If(g[m],e[m],f[m]);if(c)for(d=Math.acos(Z.Math.clamp(f[0].dot(f[b-1]),-1,1)),d/=b-1,0<e[0].dot(If(k,f[0],f[b-1]))&&(d=-d),m=1;m<b;m++)f[m].applyMatrix4(Yf(l,e[m],d*m)),If(g[m],e[m],f[m])};\nZ.PolyhedronGeometry=function(a,b,c,d){function e(a){var b=a.normalize().clone();b.index=l.vertices.push(b)-1;b.uv=new Z.Vector2(Math.atan2(a.z,-a.x)/2/Math.PI+.5,1-(Math.atan2(-a.y,Math.sqrt(a.x*a.x+a.z*a.z))/Math.PI+.5));return b}function f(a,b,c,d){d=new Z.Face3(a.index,b.index,c.index,[a.clone(),b.clone(),c.clone()],void 0,d);l.faces.push(d);w.copy(a).add(b).add(c).divideScalar(3);d=Math.atan2(w.z,-w.x);l.faceVertexUvs[0].push([k(a.uv,a,d),k(b.uv,b,d),k(c.uv,c,d)])}function g(a,b){b=Math.pow(2,\nb);var c=e(l.vertices[a.a]),d=e(l.vertices[a.b]),g=e(l.vertices[a.c]),k=[];a=a.materialIndex;for(var m=0;m<=b;m++){k[m]=[];for(var n=e(c.clone().lerp(g,m/b)),p=e(d.clone().lerp(g,m/b)),q=b-m,r=0;r<=q;r++)k[m][r]=0===r&&m===b?n:e(n.clone().lerp(p,r/q))}for(m=0;m<b;m++)for(r=0;r<2*(b-m)-1;r++)c=Math.floor(r/2),0===r%2?f(k[m][c+1],k[m+1][c],k[m][c],a):f(k[m][c+1],k[m+1][c+1],k[m+1][c],a)}function k(a,b,c){0>c&&1===a.x&&(a=new Z.Vector2(a.x-1,a.y));0===b.x&&0===b.z&&(a=new Z.Vector2(c/2/Math.PI+.5,a.y));\nreturn a.clone()}Z.Geometry.call(this);this.type=\"PolyhedronGeometry\";this.parameters={vertices:a,indices:b,radius:c,detail:d};c=c||1;d=d||0;for(var l=this,m=0,n=a.length;m<n;m+=3)e(new Z.Vector3(a[m],a[m+1],a[m+2]));a=this.vertices;for(var q=[],p=m=0,n=b.length;m<n;m+=3,p++){var t=a[b[m]],r=a[b[m+1]],v=a[b[m+2]];q[p]=new Z.Face3(t.index,r.index,v.index,[t.clone(),r.clone(),v.clone()],void 0,p)}for(var w=new Z.Vector3,m=0,n=q.length;m<n;m++)g(q[m],d);m=0;for(n=this.faceVertexUvs[0].length;m<n;m++)b=\nthis.faceVertexUvs[0][m],d=b[0].x,a=b[1].x,q=b[2].x,p=Math.min(d,a,q),.9<Math.max(d,a,q)&&.1>p&&(.2>d&&(b[0].x+=1),.2>a&&(b[1].x+=1),.2>q&&(b[2].x+=1));m=0;for(n=this.vertices.length;m<n;m++)this.vertices[m].multiplyScalar(c);this.mergeVertices();this.computeFaceNormals();this.boundingSphere=new Z.Sphere(new Z.Vector3,c)};Z.PolyhedronGeometry.prototype=Object.create(Z.Geometry.prototype);Z.PolyhedronGeometry.prototype.constructor=Z.PolyhedronGeometry;\nZ.DodecahedronGeometry=function(a,b){var c=(1+Math.sqrt(5))/2,d=1/c;Z.PolyhedronGeometry.call(this,[-1,-1,-1,-1,-1,1,-1,1,-1,-1,1,1,1,-1,-1,1,-1,1,1,1,-1,1,1,1,0,-d,-c,0,-d,c,0,d,-c,0,d,c,-d,-c,0,-d,c,0,d,-c,0,d,c,0,-c,0,-d,c,0,-d,-c,0,d,c,0,d],[3,11,7,3,7,15,3,15,13,7,19,17,7,17,6,7,6,15,17,4,8,17,8,10,17,10,6,8,0,16,8,16,2,8,2,10,0,12,1,0,1,18,0,18,16,6,10,2,6,2,13,6,13,15,2,16,18,2,18,3,2,3,13,18,1,9,18,9,11,18,11,3,4,14,12,4,12,0,4,0,8,11,9,5,11,5,19,11,19,7,19,5,14,19,14,4,19,4,17,1,12,14,1,\n14,5,1,5,9],a,b);this.type=\"DodecahedronGeometry\";this.parameters={radius:a,detail:b}};Z.DodecahedronGeometry.prototype=Object.create(Z.PolyhedronGeometry.prototype);Z.DodecahedronGeometry.prototype.constructor=Z.DodecahedronGeometry;\nZ.IcosahedronGeometry=function(a,b){var c=(1+Math.sqrt(5))/2;Z.PolyhedronGeometry.call(this,[-1,c,0,1,c,0,-1,-c,0,1,-c,0,0,-1,c,0,1,c,0,-1,-c,0,1,-c,c,0,-1,c,0,1,-c,0,-1,-c,0,1],[0,11,5,0,5,1,0,1,7,0,7,10,0,10,11,1,5,9,5,11,4,11,10,2,10,7,6,7,1,8,3,9,4,3,4,2,3,2,6,3,6,8,3,8,9,4,9,5,2,4,11,6,2,10,8,6,7,9,8,1],a,b);this.type=\"IcosahedronGeometry\";this.parameters={radius:a,detail:b}};Z.IcosahedronGeometry.prototype=Object.create(Z.PolyhedronGeometry.prototype);\nZ.IcosahedronGeometry.prototype.constructor=Z.IcosahedronGeometry;Z.OctahedronGeometry=function(a,b){Z.PolyhedronGeometry.call(this,[1,0,0,-1,0,0,0,1,0,0,-1,0,0,0,1,0,0,-1],[0,2,4,0,4,3,0,3,5,0,5,2,1,2,5,1,5,3,1,3,4,1,4,2],a,b);this.type=\"OctahedronGeometry\";this.parameters={radius:a,detail:b}};Z.OctahedronGeometry.prototype=Object.create(Z.PolyhedronGeometry.prototype);Z.OctahedronGeometry.prototype.constructor=Z.OctahedronGeometry;\nZ.TetrahedronGeometry=function(a,b){Z.PolyhedronGeometry.call(this,[1,1,1,-1,-1,1,-1,1,-1,1,-1,-1],[2,1,0,0,3,2,1,3,0,2,3,1],a,b);this.type=\"TetrahedronGeometry\";this.parameters={radius:a,detail:b}};Z.TetrahedronGeometry.prototype=Object.create(Z.PolyhedronGeometry.prototype);Z.TetrahedronGeometry.prototype.constructor=Z.TetrahedronGeometry;\nZ.ParametricGeometry=function(a,b,c){Z.Geometry.call(this);this.type=\"ParametricGeometry\";this.parameters={func:a,slices:b,stacks:c};var d=this.vertices,e=this.faces,f=this.faceVertexUvs[0],g,k,l=b+1;for(g=0;g<=c;g++){var m=g/c;for(k=0;k<=b;k++){var n=k/b;n=a(n,m);d.push(n)}}for(g=0;g<c;g++)for(k=0;k<b;k++){a=g*l+k;d=g*l+k+1;m=(g+1)*l+k+1;n=(g+1)*l+k;var q=new Z.Vector2(k/b,g/c);var p=new Z.Vector2((k+1)/b,g/c);var t=new Z.Vector2((k+1)/b,(g+1)/c);var r=new Z.Vector2(k/b,(g+1)/c);e.push(new Z.Face3(a,\nd,n));f.push([q,p,r]);e.push(new Z.Face3(d,m,n));f.push([p.clone(),t,r.clone()])}this.computeFaceNormals();this.computeVertexNormals()};Z.ParametricGeometry.prototype=Object.create(Z.Geometry.prototype);Z.ParametricGeometry.prototype.constructor=Z.ParametricGeometry;\nZ.WireframeGeometry=function(a){function b(a,b){return a-b}var c;Z.BufferGeometry.call(this);var d=[0,0];var e={};var f=[\"a\",\"b\",\"c\"];if(a instanceof Z.Geometry){var g=a.vertices;var k=a.faces;var l=0;a=new Uint32Array(6*k.length);var m=0;for(c=k.length;m<c;m++)for(var n=k[m],q=0;3>q;q++){d[0]=n[f[q]];d[1]=n[f[(q+1)%3]];d.sort(b);var p=d.toString();void 0===e[p]&&(a[2*l]=d[0],a[2*l+1]=d[1],e[p]=!0,l++)}d=new Float32Array(6*l);m=0;for(c=l;m<c;m++)for(q=0;2>q;q++)e=g[a[2*m+q]],l=6*m+3*q,d[l+0]=e.x,\nd[l+1]=e.y,d[l+2]=e.z;this.addAttribute(\"position\",new Z.BufferAttribute(d,3))}else if(a instanceof Z.BufferGeometry){if(null!==a.index){c=a.index.array;g=a.attributes.position;f=a.groups;l=0;0===f.length&&a.addGroup(0,c.length);a=new Uint32Array(2*c.length);k=0;for(n=f.length;k<n;++k){m=f[k];q=m.start;p=m.count;for(var m=q,t=q+p;m<t;m+=3)for(q=0;3>q;q++)d[0]=c[m+q],d[1]=c[m+(q+1)%3],d.sort(b),p=d.toString(),void 0===e[p]&&(a[2*l]=d[0],a[2*l+1]=d[1],e[p]=!0,l++)}d=new Float32Array(6*l);m=0;for(c=\nl;m<c;m++)for(q=0;2>q;q++)l=6*m+3*q,e=a[2*m+q],d[l+0]=g.getX(e),d[l+1]=g.getY(e),d[l+2]=g.getZ(e)}else for(g=a.attributes.position.array,l=g.length/3,d=new Float32Array(6*l),m=0,c=l/3;m<c;m++)for(q=0;3>q;q++)l=18*m+6*q,a=9*m+3*q,d[l+0]=g[a],d[l+1]=g[a+1],d[l+2]=g[a+2],e=9*m+(q+1)%3*3,d[l+3]=g[e],d[l+4]=g[e+1],d[l+5]=g[e+2];this.addAttribute(\"position\",new Z.BufferAttribute(d,3))}};Z.WireframeGeometry.prototype=Object.create(Z.BufferGeometry.prototype);Z.WireframeGeometry.prototype.constructor=Z.WireframeGeometry;\nZ.AxisHelper=function(a){a=a||1;var b=new Float32Array([0,0,0,a,0,0,0,0,0,0,a,0,0,0,0,0,0,a]),c=new Float32Array([1,0,0,1,.6,0,0,1,0,.6,1,0,0,0,1,0,.6,1]);a=new Z.BufferGeometry;a.addAttribute(\"position\",new Z.BufferAttribute(b,3));a.addAttribute(\"color\",new Z.BufferAttribute(c,3));b=new Z.LineBasicMaterial({vertexColors:Z.VertexColors});Z.LineSegments.call(this,a,b)};Z.AxisHelper.prototype=Object.create(Z.LineSegments.prototype);Z.AxisHelper.prototype.constructor=Z.AxisHelper;\nZ.ArrowHelper=function(){var a=new Z.BufferGeometry;a.addAttribute(\"position\",new Z.Float32Attribute([0,0,0,0,1,0],3));var b=new Z.CylinderBufferGeometry(0,.5,1,5,1);b.translate(0,-.5,0);return function(c,d,e,f,g,k){Z.Object3D.call(this);void 0===f&&(f=16776960);void 0===e&&(e=1);void 0===g&&(g=.2*e);void 0===k&&(k=.2*g);this.position.copy(d);this.line=new Z.Line(a,new Z.LineBasicMaterial({color:f}));this.line.matrixAutoUpdate=!1;this.add(this.line);this.cone=new Z.Mesh(b,new Z.MeshBasicMaterial({color:f}));\nthis.cone.matrixAutoUpdate=!1;this.add(this.cone);this.setDirection(c);this.setLength(e,g,k)}}();Z.ArrowHelper.prototype=Object.create(Z.Object3D.prototype);Z.ArrowHelper.prototype.constructor=Z.ArrowHelper;Z.ArrowHelper.prototype.setDirection=function(){var a=new Z.Vector3,b;return function(c){.99999<c.y?this.quaternion.set(0,0,0,1):-.99999>c.y?this.quaternion.set(1,0,0,0):(a.set(c.z,0,-c.x).normalize(),b=Math.acos(c.y),Kf(this.quaternion,a,b))}}();\nZ.ArrowHelper.prototype.setLength=function(a,b,c){void 0===b&&(b=.2*a);void 0===c&&(c=.2*b);this.line.scale.set(1,Math.max(0,a-b),1);this.line.updateMatrix();this.cone.scale.set(c,b,c);this.cone.position.y=a;this.cone.updateMatrix()};Z.ArrowHelper.prototype.setColor=function(a){this.line.material.color.copy(a);this.cone.material.color.copy(a)};\nZ.BoxHelper=function(a){var b=new Uint16Array([0,1,1,2,2,3,3,0,4,5,5,6,6,7,7,4,0,4,1,5,2,6,3,7]),c=new Float32Array(24),d=new Z.BufferGeometry;d.setIndex(new Z.BufferAttribute(b,1));d.addAttribute(\"position\",new Z.BufferAttribute(c,3));Z.LineSegments.call(this,d,new Z.LineBasicMaterial({color:16776960}));void 0!==a&&this.update(a)};Z.BoxHelper.prototype=Object.create(Z.LineSegments.prototype);Z.BoxHelper.prototype.constructor=Z.BoxHelper;\nZ.BoxHelper.prototype.update=function(){var a=new Z.Box3;return function(b){b instanceof Z.Box3?a.copy(b):a.setFromObject(b);if(!a.isEmpty()){b=a.min;var c=a.max,d=this.geometry.attributes.position,e=d.array;e[0]=c.x;e[1]=c.y;e[2]=c.z;e[3]=b.x;e[4]=c.y;e[5]=c.z;e[6]=b.x;e[7]=b.y;e[8]=c.z;e[9]=c.x;e[10]=b.y;e[11]=c.z;e[12]=c.x;e[13]=c.y;e[14]=b.z;e[15]=b.x;e[16]=c.y;e[17]=b.z;e[18]=b.x;e[19]=b.y;e[20]=b.z;e[21]=c.x;e[22]=b.y;e[23]=b.z;d.needsUpdate=!0;this.geometry.computeBoundingSphere()}}}();\nZ.BoundingBoxHelper=function(a,b){b=void 0!==b?b:8947848;this.object=a;this.box=new Z.Box3;Z.Mesh.call(this,new Z.BoxGeometry(1,1,1),new Z.MeshBasicMaterial({color:b,wireframe:!0}))};Z.BoundingBoxHelper.prototype=Object.create(Z.Mesh.prototype);Z.BoundingBoxHelper.prototype.constructor=Z.BoundingBoxHelper;Z.BoundingBoxHelper.prototype.update=function(){this.box.setFromObject(this.object);this.box.size(this.scale);this.box.center(this.position)};\nZ.CameraHelper=function(a){function b(a,b,d){c(a,d);c(b,d)}function c(a,b){d.vertices.push(new Z.Vector3);d.colors.push(new Z.Color(b));void 0===f[a]&&(f[a]=[]);f[a].push(d.vertices.length-1)}var d=new Z.Geometry,e=new Z.LineBasicMaterial({color:16777215,vertexColors:Z.FaceColors}),f={};b(\"n1\",\"n2\",16755200);b(\"n2\",\"n4\",16755200);b(\"n4\",\"n3\",16755200);b(\"n3\",\"n1\",16755200);b(\"f1\",\"f2\",16755200);b(\"f2\",\"f4\",16755200);b(\"f4\",\"f3\",16755200);b(\"f3\",\"f1\",16755200);b(\"n1\",\"f1\",16755200);b(\"n2\",\"f2\",16755200);\nb(\"n3\",\"f3\",16755200);b(\"n4\",\"f4\",16755200);b(\"p\",\"n1\",16711680);b(\"p\",\"n2\",16711680);b(\"p\",\"n3\",16711680);b(\"p\",\"n4\",16711680);b(\"u1\",\"u2\",43775);b(\"u2\",\"u3\",43775);b(\"u3\",\"u1\",43775);b(\"c\",\"t\",16777215);b(\"p\",\"c\",3355443);b(\"cn1\",\"cn2\",3355443);b(\"cn3\",\"cn4\",3355443);b(\"cf1\",\"cf2\",3355443);b(\"cf3\",\"cf4\",3355443);Z.LineSegments.call(this,d,e);this.camera=a;this.camera.updateProjectionMatrix();this.matrix=a.matrixWorld;this.matrixAutoUpdate=!1;this.pointMap=f;this.update()};\nZ.CameraHelper.prototype=Object.create(Z.LineSegments.prototype);Z.CameraHelper.prototype.constructor=Z.CameraHelper;\nZ.CameraHelper.prototype.update=function(){function a(a,g,k,l){d.set(g,k,l).unproject(e);a=c[a];if(void 0!==a)for(g=0,k=a.length;g<k;g++)b.vertices[a[g]].copy(d)}var b,c,d=new Z.Vector3,e=new Z.Camera;return function(){b=this.geometry;c=this.pointMap;e.projectionMatrix.copy(this.camera.projectionMatrix);a(\"c\",0,0,-1);a(\"t\",0,0,1);a(\"n1\",-1,-1,-1);a(\"n2\",1,-1,-1);a(\"n3\",-1,1,-1);a(\"n4\",1,1,-1);a(\"f1\",-1,-1,1);a(\"f2\",1,-1,1);a(\"f3\",-1,1,1);a(\"f4\",1,1,1);a(\"u1\",.7,1.1,-1);a(\"u2\",-.7,1.1,-1);a(\"u3\",0,\n2,-1);a(\"cf1\",-1,0,1);a(\"cf2\",1,0,1);a(\"cf3\",0,-1,1);a(\"cf4\",0,1,1);a(\"cn1\",-1,0,-1);a(\"cn2\",1,0,-1);a(\"cn3\",0,-1,-1);a(\"cn4\",0,1,-1);b.verticesNeedUpdate=!0}}();\nZ.DirectionalLightHelper=function(a,b){Z.Object3D.call(this);this.light=a;this.light.updateMatrixWorld();this.matrix=a.matrixWorld;this.matrixAutoUpdate=!1;void 0===b&&(b=1);a=new Z.BufferGeometry;a.addAttribute(\"position\",new Z.Float32Attribute([-b,b,0,b,b,0,b,-b,0,-b,-b,0,-b,b,0],3));b=new Z.LineBasicMaterial({fog:!1});this.add(new Z.Line(a,b));a=new Z.BufferGeometry;a.addAttribute(\"position\",new Z.Float32Attribute([0,0,0,0,0,1],3));this.add(new Z.Line(a,b));this.update()};\nZ.DirectionalLightHelper.prototype=Object.create(Z.Object3D.prototype);Z.DirectionalLightHelper.prototype.constructor=Z.DirectionalLightHelper;Z.DirectionalLightHelper.prototype.dispose=function(){var a=this.children[0],b=this.children[1];a.geometry.dispose();a.material.dispose();b.geometry.dispose();b.material.dispose()};\nZ.DirectionalLightHelper.prototype.update=function(){var a=new Z.Vector3,b=new Z.Vector3,c=new Z.Vector3;return function(){Qf(a,this.light.matrixWorld);Qf(b,this.light.target.matrixWorld);c.subVectors(b,a);var d=this.children[0],e=this.children[1];d.lookAt(c);d.material.color.copy(this.light.color).multiplyScalar(this.light.intensity);e.lookAt(c);e.scale.z=c.length()}}();\nZ.EdgesHelper=function(a,b,c){b=void 0!==b?b:16777215;Z.LineSegments.call(this,new Z.EdgesGeometry(a.geometry,c),new Z.LineBasicMaterial({color:b}));this.matrix=a.matrixWorld;this.matrixAutoUpdate=!1};Z.EdgesHelper.prototype=Object.create(Z.LineSegments.prototype);Z.EdgesHelper.prototype.constructor=Z.EdgesHelper;\nZ.FaceNormalsHelper=function(a,b,c,d){this.object=a;this.size=void 0!==b?b:1;a=void 0!==c?c:16776960;d=void 0!==d?d:1;b=0;c=this.object.geometry;c instanceof Z.Geometry?b=c.faces.length:console.warn(\"THREE.FaceNormalsHelper: only THREE.Geometry is supported. Use THREE.VertexNormalsHelper, instead.\");c=new Z.BufferGeometry;b=new Z.Float32Attribute(6*b,3);c.addAttribute(\"position\",b);Z.LineSegments.call(this,c,new Z.LineBasicMaterial({color:a,linewidth:d}));this.matrixAutoUpdate=!1;this.update()};\nZ.FaceNormalsHelper.prototype=Object.create(Z.LineSegments.prototype);Z.FaceNormalsHelper.prototype.constructor=Z.FaceNormalsHelper;\nZ.FaceNormalsHelper.prototype.update=function(){var a=new Z.Vector3,b=new Z.Vector3,c=new Z.Matrix3;return function(){this.object.updateMatrixWorld(!0);Wf(c,this.object.matrixWorld);for(var d=this.object.matrixWorld,e=this.geometry.attributes.position,f=this.object.geometry,g=f.vertices,f=f.faces,k=0,l=0,m=f.length;l<m;l++){var n=f[l],q=n.normal;a.copy(g[n.a]).add(g[n.b]).add(g[n.c]).divideScalar(3).applyMatrix4(d);Sf(b.copy(q),c).normalize().multiplyScalar(this.size).add(a);e.setXYZ(k,a.x,a.y,a.z);\nk+=1;e.setXYZ(k,b.x,b.y,b.z);k+=1}e.needsUpdate=!0;return this}}();\nZ.GridHelper=function(a,b,c,d){c=new Z.Color(void 0!==c?c:4473924);d=new Z.Color(void 0!==d?d:8947848);for(var e=[],f=[],g=-a,k=0;g<=a;g+=b){e.push(-a,0,g,a,0,g);e.push(g,0,-a,g,0,a);var l=0===g?c:d;l.toArray(f,k);k+=3;l.toArray(f,k);k+=3;l.toArray(f,k);k+=3;l.toArray(f,k);k+=3}a=new Z.BufferGeometry;a.addAttribute(\"position\",new Z.Float32Attribute(e,3));a.addAttribute(\"color\",new Z.Float32Attribute(f,3));e=new Z.LineBasicMaterial({vertexColors:Z.VertexColors});Z.LineSegments.call(this,a,e)};\nZ.GridHelper.prototype=Object.create(Z.LineSegments.prototype);Z.GridHelper.prototype.constructor=Z.GridHelper;Z.GridHelper.prototype.setColors=function(){console.error(\"THREE.GridHelper: setColors() has been deprecated, pass them in the constructor instead.\")};\nZ.HemisphereLightHelper=function(a,b){Z.Object3D.call(this);this.light=a;this.light.updateMatrixWorld();this.matrix=a.matrixWorld;this.matrixAutoUpdate=!1;this.colors=[new Z.Color,new Z.Color];a=new Z.SphereGeometry(b,4,2);a.rotateX(-Math.PI/2);for(b=0;8>b;b++)a.faces[b].color=this.colors[4>b?0:1];b=new Z.MeshBasicMaterial({vertexColors:Z.FaceColors,wireframe:!0});this.lightSphere=new Z.Mesh(a,b);this.add(this.lightSphere);this.update()};Z.HemisphereLightHelper.prototype=Object.create(Z.Object3D.prototype);\nZ.HemisphereLightHelper.prototype.constructor=Z.HemisphereLightHelper;Z.HemisphereLightHelper.prototype.dispose=function(){this.lightSphere.geometry.dispose();this.lightSphere.material.dispose()};\nZ.HemisphereLightHelper.prototype.update=function(){var a=new Z.Vector3;return function(){this.colors[0].copy(this.light.color).multiplyScalar(this.light.intensity);this.colors[1].copy(this.light.groundColor).multiplyScalar(this.light.intensity);this.lightSphere.lookAt(Qf(a,this.light.matrixWorld).negate());this.lightSphere.geometry.colorsNeedUpdate=!0}}();\nZ.PointLightHelper=function(a,b){this.light=a;this.light.updateMatrixWorld();a=new Z.SphereBufferGeometry(b,4,2);b=new Z.MeshBasicMaterial({wireframe:!0,fog:!1});b.color.copy(this.light.color).multiplyScalar(this.light.intensity);Z.Mesh.call(this,a,b);this.matrix=this.light.matrixWorld;this.matrixAutoUpdate=!1};Z.PointLightHelper.prototype=Object.create(Z.Mesh.prototype);Z.PointLightHelper.prototype.constructor=Z.PointLightHelper;\nZ.PointLightHelper.prototype.dispose=function(){this.geometry.dispose();this.material.dispose()};Z.PointLightHelper.prototype.update=function(){this.material.color.copy(this.light.color).multiplyScalar(this.light.intensity)};\nZ.SkeletonHelper=function(a){this.bones=Cg(this,a);for(var b=new Z.Geometry,c=0;c<this.bones.length;c++)this.bones[c].parent instanceof Z.Bone&&(b.vertices.push(new Z.Vector3),b.vertices.push(new Z.Vector3),b.colors.push(new Z.Color(0,0,1)),b.colors.push(new Z.Color(0,1,0)));b.dynamic=!0;c=new Z.LineBasicMaterial({vertexColors:Z.VertexColors,depthTest:!1,depthWrite:!1,transparent:!0});Z.LineSegments.call(this,b,c);this.root=a;this.matrix=a.matrixWorld;this.matrixAutoUpdate=!1;this.update()};\nZ.SkeletonHelper.prototype=Object.create(Z.LineSegments.prototype);Z.SkeletonHelper.prototype.constructor=Z.SkeletonHelper;function Cg(a,b){var c=[];b instanceof Z.Bone&&c.push(b);for(var d=0;d<b.children.length;d++)c.push.apply(c,Cg(a,b.children[d]));return c}\nZ.SkeletonHelper.prototype.update=function(){for(var a=this.geometry,b=(new Z.Matrix4).getInverse(this.root.matrixWorld),c=new Z.Matrix4,d=0,e=0;e<this.bones.length;e++){var f=this.bones[e];f.parent instanceof Z.Bone&&(Nf(c,b,f.matrixWorld),Qf(a.vertices[d],c),Nf(c,b,f.parent.matrixWorld),Qf(a.vertices[d+1],c),d+=2)}a.verticesNeedUpdate=!0;a.computeBoundingSphere()};\nZ.SpotLightHelper=function(a){Z.Object3D.call(this);this.light=a;this.light.updateMatrixWorld();this.matrix=a.matrixWorld;this.matrixAutoUpdate=!1;a=new Z.BufferGeometry;for(var b=[0,0,0,0,0,1,0,0,0,1,0,1,0,0,0,-1,0,1,0,0,0,0,1,1,0,0,0,0,-1,1],c=0,d=1;32>c;c++,d++){var e=c/32*Math.PI*2,f=d/32*Math.PI*2;b.push(Math.cos(e),Math.sin(e),1,Math.cos(f),Math.sin(f),1)}a.addAttribute(\"position\",new Z.Float32Attribute(b,3));b=new Z.LineBasicMaterial({fog:!1});this.cone=new Z.LineSegments(a,b);this.add(this.cone);\nthis.update()};Z.SpotLightHelper.prototype=Object.create(Z.Object3D.prototype);Z.SpotLightHelper.prototype.constructor=Z.SpotLightHelper;Z.SpotLightHelper.prototype.dispose=function(){this.cone.geometry.dispose();this.cone.material.dispose()};\nZ.SpotLightHelper.prototype.update=function(){var a=new Z.Vector3,b=new Z.Vector3;return function(){var c=this.light.distance?this.light.distance:1E3,d=c*Math.tan(this.light.angle);this.cone.scale.set(d,d,c);Qf(a,this.light.matrixWorld);Qf(b,this.light.target.matrixWorld);this.cone.lookAt(b.sub(a));this.cone.material.color.copy(this.light.color).multiplyScalar(this.light.intensity)}}();\nZ.VertexNormalsHelper=function(a,b,c,d){this.object=a;this.size=void 0!==b?b:1;a=void 0!==c?c:16711680;d=void 0!==d?d:1;b=0;c=this.object.geometry;c instanceof Z.Geometry?b=3*c.faces.length:c instanceof Z.BufferGeometry&&(b=c.attributes.normal.count);c=new Z.BufferGeometry;b=new Z.Float32Attribute(6*b,3);c.addAttribute(\"position\",b);Z.LineSegments.call(this,c,new Z.LineBasicMaterial({color:a,linewidth:d}));this.matrixAutoUpdate=!1;this.update()};Z.VertexNormalsHelper.prototype=Object.create(Z.LineSegments.prototype);\nZ.VertexNormalsHelper.prototype.constructor=Z.VertexNormalsHelper;\nZ.VertexNormalsHelper.prototype.update=function(){var a=new Z.Vector3,b=new Z.Vector3,c=new Z.Matrix3;return function(){var d=[\"a\",\"b\",\"c\"];this.object.updateMatrixWorld(!0);Wf(c,this.object.matrixWorld);var e=this.object.matrixWorld,f=this.geometry.attributes.position;var g=this.object.geometry;if(g instanceof Z.Geometry)for(var k=g.vertices,l=g.faces,m=g=0,n=l.length;m<n;m++)for(var q=l[m],p=0,t=q.vertexNormals.length;p<t;p++){var r=q.vertexNormals[p];a.copy(k[q[d[p]]]).applyMatrix4(e);Sf(b.copy(r),\nc).normalize().multiplyScalar(this.size).add(a);f.setXYZ(g,a.x,a.y,a.z);g+=1;f.setXYZ(g,b.x,b.y,b.z);g+=1}else if(g instanceof Z.BufferGeometry)for(d=g.attributes.position,k=g.attributes.normal,p=g=0,t=d.count;p<t;p++)a.set(d.getX(p),d.getY(p),d.getZ(p)).applyMatrix4(e),b.set(k.getX(p),k.getY(p),k.getZ(p)),Sf(b,c).normalize().multiplyScalar(this.size).add(a),f.setXYZ(g,a.x,a.y,a.z),g+=1,f.setXYZ(g,b.x,b.y,b.z),g+=1;f.needsUpdate=!0;return this}}();\nZ.WireframeHelper=function(a,b){b=void 0!==b?b:16777215;Z.LineSegments.call(this,new Z.WireframeGeometry(a.geometry),new Z.LineBasicMaterial({color:b}));this.matrix=a.matrixWorld;this.matrixAutoUpdate=!1};Z.WireframeHelper.prototype=Object.create(Z.LineSegments.prototype);Z.WireframeHelper.prototype.constructor=Z.WireframeHelper;Z.ImmediateRenderObject=function(a){Z.Object3D.call(this);this.material=a;this.render=function(){}};Z.ImmediateRenderObject.prototype=Object.create(Z.Object3D.prototype);\nZ.ImmediateRenderObject.prototype.constructor=Z.ImmediateRenderObject;Z.MorphBlendMesh=function(a,b){Z.Mesh.call(this,a,b);this.animationsMap={};this.animationsList=[];a=this.geometry.morphTargets.length;Dg(this,\"__default\",0,a-1,a/1);if(a=this.animationsMap.__default)a.weight=1};Z.MorphBlendMesh.prototype=Object.create(Z.Mesh.prototype);h=Z.MorphBlendMesh.prototype;h.constructor=Z.MorphBlendMesh;\nfunction Dg(a,b,c,d,e){c={start:c,end:d,length:d-c+1,fps:e,duration:(d-c)/e,lastFrame:0,currentFrame:0,active:!1,time:0,direction:1,weight:1,directionBackwards:!1,mirroredLoop:!1};a.animationsMap[b]=c;a.animationsList.push(c)}\nh.autoCreateAnimations=function(a){for(var b,c,d=/([a-z]+)_?(\\d+)/i,e,f={},g=this.geometry,k=0,l=g.morphTargets.length;k<l;k++)(b=g.morphTargets[k].name.match(d))&&1<b.length&&(c=b[1],f[c]||(f[c]={start:Infinity,end:-Infinity}),b=f[c],k<b.start&&(b.start=k),k>b.end&&(b.end=k),e||(e=c));for(c in f)b=f[c],Dg(this,c,b.start,b.end,a);this.firstAnimation=e};h.setAnimationDirectionForward=function(a){if(a=this.animationsMap[a])a.direction=1,a.directionBackwards=!1};\nh.setAnimationDirectionBackward=function(a){if(a=this.animationsMap[a])a.direction=-1,a.directionBackwards=!0};h.setAnimationFPS=function(a,b){if(a=this.animationsMap[a])a.fps=b,a.duration=(a.end-a.start)/a.fps};h.setAnimationDuration=function(a,b){if(a=this.animationsMap[a])a.duration=b,a.fps=(a.end-a.start)/a.duration};h.setAnimationTime=function(a,b){if(a=this.animationsMap[a])a.time=b};h.getAnimationTime=function(a){var b=0;if(a=this.animationsMap[a])b=a.time;return b};\nh.getAnimationDuration=function(a){var b=-1;if(a=this.animationsMap[a])b=a.duration;return b};h.playAnimation=function(a){var b=this.animationsMap[a];b?(b.time=0,b.active=!0):console.warn(\"THREE.MorphBlendMesh: animation[\"+a+\"] undefined in .playAnimation()\")};h.stopAnimation=function(a){if(a=this.animationsMap[a])a.active=!1};\nh.update=function(a){for(var b=0,c=this.animationsList.length;b<c;b++){var d=this.animationsList[b];if(d.active){var e=d.duration/d.length;d.time+=d.direction*a;if(d.mirroredLoop){if(d.time>d.duration||0>d.time)d.direction*=-1,d.time>d.duration&&(d.time=d.duration,d.directionBackwards=!0),0>d.time&&(d.time=0,d.directionBackwards=!1)}else d.time%=d.duration,0>d.time&&(d.time+=d.duration);var f=d.start+Z.Math.clamp(Math.floor(d.time/e),0,d.length-1),g=d.weight;f!==d.currentFrame&&(this.morphTargetInfluences[d.lastFrame]=\n0,this.morphTargetInfluences[d.currentFrame]=1*g,this.morphTargetInfluences[f]=0,d.lastFrame=d.currentFrame,d.currentFrame=f);e=d.time%e/e;d.directionBackwards&&(e=1-e);d.currentFrame!==d.lastFrame?(this.morphTargetInfluences[d.currentFrame]=e*g,this.morphTargetInfluences[d.lastFrame]=(1-e)*g):this.morphTargetInfluences[d.currentFrame]=g}}};\n</script>\n<script>//~~WEBPATH~~/tf-imports/OrbitControls.js\nZ.OrbitControls=function(a,b){function c(){return Math.pow(.95,r.zoomSpeed)}function d(a){r.object instanceof Z.PerspectiveCamera?F/=a:r.object instanceof Z.OrthographicCamera?(r.object.zoom=Math.max(r.minZoom,Math.min(r.maxZoom,r.object.zoom*a)),r.object.updateProjectionMatrix(),H=!0):(console.warn(\"WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.\"),r.enableZoom=!1)}function e(a){r.object instanceof Z.PerspectiveCamera?F*=a:r.object instanceof Z.OrthographicCamera?\n(r.object.zoom=Math.max(r.minZoom,Math.min(r.maxZoom,r.object.zoom/a)),r.object.updateProjectionMatrix(),H=!0):(console.warn(\"WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.\"),r.enableZoom=!1)}function f(a){if(!1!==r.enabled){a.preventDefault();if(a.button===r.mouseButtons.ORBIT){if(!1===r.enableRotate)return;C.set(a.clientX,a.clientY);B=y.ROTATE}else if(a.button===r.mouseButtons.ZOOM){if(!1===r.enableZoom)return;S.set(a.clientX,a.clientY);B=y.DOLLY}else if(a.button===\nr.mouseButtons.PAN){if(!1===r.enablePan)return;T.set(a.clientX,a.clientY);B=y.PAN}B!==y.NONE&&(document.addEventListener(\"mousemove\",g,!1),document.addEventListener(\"mouseup\",k,!1),document.addEventListener(\"mouseout\",k,!1),r.dispatchEvent(w))}}function g(a){!1!==r.enabled&&(a.preventDefault(),B===y.ROTATE?!1!==r.enableRotate&&(J.set(a.clientX,a.clientY),M.subVectors(J,C),a=r.domElement===document?r.domElement.body:r.domElement,E.theta-=2*Math.PI*M.x/a.clientWidth*r.rotateSpeed,E.phi-=2*Math.PI*M.y/\na.clientHeight*r.rotateSpeed,C.copy(J),r.update()):B===y.DOLLY?!1!==r.enableZoom&&(R.set(a.clientX,a.clientY),K.subVectors(R,S),0<K.y?d(c()):0>K.y&&e(c()),S.copy(R),r.update()):B===y.PAN&&!1!==r.enablePan&&(U.set(a.clientX,a.clientY),L.subVectors(U,T),la(L.x,L.y),T.copy(U),r.update()))}function k(){!1!==r.enabled&&(document.removeEventListener(\"mousemove\",g,!1),document.removeEventListener(\"mouseup\",k,!1),document.removeEventListener(\"mouseout\",k,!1),r.dispatchEvent(z),B=y.NONE)}function l(a){if(!1!==\nr.enabled&&!1!==r.enableZoom&&(B===y.NONE||B===y.ROTATE)){a.preventDefault();a.stopPropagation();var b=0;void 0!==a.wheelDelta?b=a.wheelDelta:void 0!==a.detail&&(b=-a.detail);0<b?e(c()):0>b&&d(c());r.update();r.dispatchEvent(w);r.dispatchEvent(z)}}function m(a){if(!1!==r.enabled&&!1!==r.enableKeys&&!1!==r.enablePan)switch(a.keyCode){case r.keys.UP:la(0,r.keyPanSpeed);r.update();break;case r.keys.BOTTOM:la(0,-r.keyPanSpeed);r.update();break;case r.keys.LEFT:la(r.keyPanSpeed,0);r.update();break;case r.keys.RIGHT:la(-r.keyPanSpeed,\n0),r.update()}}function n(a){if(!1!==r.enabled){switch(a.touches.length){case 1:if(!1===r.enableRotate)return;C.set(a.touches[0].pageX,a.touches[0].pageY);B=y.TOUCH_ROTATE;break;case 2:if(!1===r.enableZoom)return;var b=a.touches[0].pageX-a.touches[1].pageX;a=a.touches[0].pageY-a.touches[1].pageY;S.set(0,Math.sqrt(b*b+a*a));B=y.TOUCH_DOLLY;break;case 3:if(!1===r.enablePan)return;T.set(a.touches[0].pageX,a.touches[0].pageY);B=y.TOUCH_PAN;break;default:B=y.NONE}B!==y.NONE&&r.dispatchEvent(w)}}function q(a){if(!1!==\nr.enabled)switch(a.preventDefault(),a.stopPropagation(),a.touches.length){case 1:if(!1===r.enableRotate)break;if(B!==y.TOUCH_ROTATE)break;J.set(a.touches[0].pageX,a.touches[0].pageY);M.subVectors(J,C);var b=r.domElement===document?r.domElement.body:r.domElement;E.theta-=2*Math.PI*M.x/b.clientWidth*r.rotateSpeed;E.phi-=2*Math.PI*M.y/b.clientHeight*r.rotateSpeed;C.copy(J);r.update();break;case 2:if(!1===r.enableZoom)break;if(B!==y.TOUCH_DOLLY)break;b=a.touches[0].pageX-a.touches[1].pageX;a=a.touches[0].pageY-\na.touches[1].pageY;R.set(0,Math.sqrt(b*b+a*a));K.subVectors(R,S);0<K.y?e(c()):0>K.y&&d(c());S.copy(R);r.update();break;case 3:if(!1===r.enablePan)break;if(B!==y.TOUCH_PAN)break;U.set(a.touches[0].pageX,a.touches[0].pageY);L.subVectors(U,T);la(L.x,L.y);T.copy(U);r.update();break;default:B=y.NONE}}function p(){!1!==r.enabled&&(r.dispatchEvent(z),B=y.NONE)}function t(a){a.preventDefault()}this.object=a;this.domElement=void 0!==b?b:document;this.enabled=!0;this.target=new Z.Vector3;this.minDistance=0;\nthis.maxDistance=Infinity;this.minZoom=0;this.maxZoom=Infinity;this.minPolarAngle=0;this.maxPolarAngle=Math.PI;this.minAzimuthAngle=-Infinity;this.maxAzimuthAngle=Infinity;this.enableDamping=!1;this.dampingFactor=.25;this.enableZoom=!0;this.zoomSpeed=1;this.enableRotate=!0;this.rotateSpeed=1;this.enablePan=!0;this.keyPanSpeed=7;this.autoRotate=!1;this.autoRotateSpeed=2;this.enableKeys=!0;this.keys={LEFT:37,UP:38,RIGHT:39,BOTTOM:40};this.mouseButtons={ORBIT:Z.MOUSE.LEFT,ZOOM:Z.MOUSE.MIDDLE,PAN:Z.MOUSE.RIGHT};\nthis.target0=this.target.clone();this.position0=this.object.position.clone();this.zoom0=this.object.zoom;this.getPolarAngle=function(){return D.phi};this.getAzimuthalAngle=function(){return D.theta};this.reset=function(){r.target.copy(r.target0);r.object.position.copy(r.position0);r.object.zoom=r.zoom0;r.object.updateProjectionMatrix();r.dispatchEvent(v);r.update();B=y.NONE};this.update=function(){var b=new Z.Vector3,c=(new Z.Quaternion).setFromUnitVectors(a.up,new Z.Vector3(0,1,0)),d=c.clone().inverse(),\ne=new Z.Vector3,f=new Z.Quaternion;return function(){var a=r.object.position;b.copy(a).sub(r.target);Mf(b,c);D.setFromVector3(b);r.autoRotate&&B===y.NONE&&(E.theta-=2*Math.PI/60/60*r.autoRotateSpeed);D.theta+=E.theta;D.phi+=E.phi;D.theta=Math.max(r.minAzimuthAngle,Math.min(r.maxAzimuthAngle,D.theta));D.phi=Math.max(r.minPolarAngle,Math.min(r.maxPolarAngle,D.phi));D.phi=Math.max(1E-6,Math.min(Math.PI-1E-6,D.phi));D.radius*=F;D.radius=Math.max(r.minDistance,Math.min(r.maxDistance,D.radius));r.target.add(I);\nvar g=D,k=Math.sin(g.phi)*g.radius;b.x=k*Math.sin(g.theta);b.y=Math.cos(g.phi)*g.radius;b.z=k*Math.cos(g.theta);Mf(b,d);a.copy(r.target).add(b);r.object.lookAt(r.target);!0===r.enableDamping?(E.theta*=1-r.dampingFactor,E.phi*=1-r.dampingFactor):E.set(0,0,0);F=1;I.set(0,0,0);return H||e.distanceToSquared(r.object.position)>A||8*(1-f.dot(r.object.quaternion))>A?(r.dispatchEvent(v),e.copy(r.object.position),f.copy(r.object.quaternion),H=!1,!0):!1}}();this.dispose=function(){r.domElement.removeEventListener(\"contextmenu\",\nt,!1);r.domElement.removeEventListener(\"mousedown\",f,!1);r.domElement.removeEventListener(\"mousewheel\",l,!1);r.domElement.removeEventListener(\"MozMousePixelScroll\",l,!1);r.domElement.removeEventListener(\"touchstart\",n,!1);r.domElement.removeEventListener(\"touchend\",p,!1);r.domElement.removeEventListener(\"touchmove\",q,!1);document.removeEventListener(\"mousemove\",g,!1);document.removeEventListener(\"mouseup\",k,!1);document.removeEventListener(\"mouseout\",k,!1);window.removeEventListener(\"keydown\",m,!1)};\nvar r=this,v={type:\"change\"},w={type:\"start\"},z={type:\"end\"},y={NONE:-1,ROTATE:0,DOLLY:1,PAN:2,TOUCH_ROTATE:3,TOUCH_DOLLY:4,TOUCH_PAN:5},B=y.NONE,A=1E-6,D=new Z.Spherical,E=new Z.Spherical,F=1,I=new Z.Vector3,H=!1,C=new Z.Vector2,J=new Z.Vector2,M=new Z.Vector2,T=new Z.Vector2,U=new Z.Vector2,L=new Z.Vector2,S=new Z.Vector2,R=new Z.Vector2,K=new Z.Vector2,N=function(){var a=new Z.Vector3;return function(b,c){Pf(a,c,0);a.multiplyScalar(-b);I.add(a)}}(),Q=function(){var a=new Z.Vector3;return function(b,\nc){Pf(a,c,1);a.multiplyScalar(b);I.add(a)}}(),la=function(){var a=new Z.Vector3;return function(b,c){var d=r.domElement===document?r.domElement.body:r.domElement;if(r.object instanceof Z.PerspectiveCamera){a.copy(r.object.position).sub(r.target);var e=a.length(),e=e*Math.tan(r.object.fov/2*Math.PI/180);N(2*b*e/d.clientHeight,r.object.matrix);Q(2*c*e/d.clientHeight,r.object.matrix)}else r.object instanceof Z.OrthographicCamera?(N(b*(r.object.right-r.object.left)/r.object.zoom/d.clientWidth,r.object.matrix),\nQ(c*(r.object.top-r.object.bottom)/r.object.zoom/d.clientHeight,r.object.matrix)):(console.warn(\"WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.\"),r.enablePan=!1)}}();r.domElement.addEventListener(\"contextmenu\",t,!1);r.domElement.addEventListener(\"mousedown\",f,!1);r.domElement.addEventListener(\"mousewheel\",l,!1);r.domElement.addEventListener(\"MozMousePixelScroll\",l,!1);r.domElement.addEventListener(\"touchstart\",n,!1);r.domElement.addEventListener(\"touchend\",p,!1);r.domElement.addEventListener(\"touchmove\",\nq,!1);window.addEventListener(\"keydown\",m,!1);this.update()};Z.OrbitControls.prototype=Object.create(Z.EventDispatcher.prototype);Z.OrbitControls.prototype.constructor=Z.OrbitControls;\nObject.defineProperties(Z.OrbitControls.prototype,{center:{get:function(){console.warn(\"THREE.OrbitControls: .center has been renamed to .target\");return this.target}},noZoom:{get:function(){console.warn(\"THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.\");return!this.enableZoom},set:function(a){console.warn(\"THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.\");this.enableZoom=!a}},noRotate:{get:function(){console.warn(\"THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.\");\nreturn!this.enableRotate},set:function(a){console.warn(\"THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.\");this.enableRotate=!a}},noPan:{get:function(){console.warn(\"THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.\");return!this.enablePan},set:function(a){console.warn(\"THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.\");this.enablePan=!a}},noKeys:{get:function(){console.warn(\"THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.\");\nreturn!this.enableKeys},set:function(a){console.warn(\"THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.\");this.enableKeys=!a}},staticMoving:{get:function(){console.warn(\"THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.\");return!this.enableDamping},set:function(a){console.warn(\"THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.\");this.enableDamping=!a}},dynamicDampingFactor:{get:function(){console.warn(\"THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.\");\nreturn this.dampingFactor},set:function(a){console.warn(\"THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.\");this.dampingFactor=a}}});\n</script>\n\n<script>//~~WEBPATH~~/facets-dive/lib/sprite-atlas.js\nvar Eg=this&&this.__extends||function(){var a=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(a,c){a.__proto__=c}||function(a,c){for(var b in c)c.hasOwnProperty(b)&&(a[b]=c[b])};return function(b,c){function d(){this.constructor=b}a(b,c);b.prototype=null===c?Object.create(c):(d.prototype=c.prototype,new d)}}(),Fg=function(a){function b(b,d,e){var c=Math.ceil(Math.sqrt(b)),g=Math.ceil(b/c),k=document.createElement(\"canvas\");k.width=d*c;k.height=e*g;var l=k.getContext(\"2d\");var m=a.call(this,\nk)||this;m.capacity=b;m.imageWidth=d;m.imageHeight=e;m.spriteColumns=c;m.spriteRows=g;m.canvas=k;m.context=l;m.minFilter=Z.LinearFilter;m.magFilter=Z.LinearFilter;m.drawTimeout=50;m.waitTimeout=1;m.drawQueue=[];m.isDrawQueued=!1;m.lastClearTimestamp=0;m.callbackQueue=[];m.pendingImageCount=0;m.fitter=new Ef({x:.125*d,y:.125*e,width:.75*d,height:.75*e});return m}Eg(b,a);b.prototype.clearQueues=function(){this.drawQueue=[];this.callbackQueue=[];this.pendingImageCount=0;return this.lastClearTimestamp=\nDate.now()};b.prototype.setSpriteImageData=function(a,b,e){this.drawQueue.push({spriteIndex:a,timestamp:Date.now(),imageData:b,callback:e});this.queueDraw()};b.prototype.setAtlasUrl=function(a,b,e){var c=this,d=this.clearQueues(),k=new Image;void 0!==b&&(k.crossOrigin=b);this.pendingImageCount++;k.onerror=function(){c.lastClearTimestamp>d||c.pendingImageCount--};k.onload=function(){if(!(c.lastClearTimestamp>d)&&(c.pendingImageCount--,c.updatePropertiesToMatchImageDimensions(k.width,k.height),c.context.drawImage(k,\n0,0,c.canvas.width,c.canvas.height),c.needsUpdate=!0,e&&c.callbackQueue.push({callback:e,args:[k]}),c.onDrawFinished))c.onDrawFinished()};k.src=a};b.prototype.updatePropertiesToMatchImageDimensions=function(a,b){if(a!==this.imageWidth*this.spriteColumns||b!==this.imageHeight*this.spriteRows){var c=a/this.imageWidth,d=b/this.imageHeight;if(c*d<this.capacity)throw Error(\"Atlas image too small to accommodate atlas capacity.\");if(c!==Math.round(c)||d!==Math.round(d))throw Error(\"Atlas image dimensions do not fit sprite image dimensions.\");\nthis.spriteColumns=c;this.spriteRows=d;this.canvas.width=a;this.canvas.height=b}};b.prototype.postRender=function(){if(!(this.drawQueue.length||0<this.pendingImageCount))for(;this.callbackQueue.length;){var a=this.callbackQueue.shift();a.callback.apply(null,a.args)}};b.prototype.queueDraw=function(){var a=this;this.isDrawQueued||(this.isDrawQueued=!0,setTimeout(function(){a.isDrawQueued&&a.workOnDrawJobs()},this.waitTimeout))};b.prototype.workOnDrawJobs=function(){function a(){var a=g.drawQueue.shift(),\nc=a.spriteIndex,d=a.timestamp,f=a.imageData,q=a.image,p=a.callback;if(q){var a=g.imageWidth,t=g.imageHeight,r=c%g.spriteColumns*a,v=t*Math.floor(c/g.spriteColumns);g.context.clearRect(r,v,a,t);g.context.drawImage(q,r,v,a,t);\"function\"===typeof p&&g.callbackQueue.push({callback:p,args:[c]})}else if(f&&\"text\"===f.type){var q=c%g.spriteColumns*g.imageWidth,a=g.imageHeight*Math.floor(c/g.spriteColumns),v=q+g.imageWidth/2,w=a+g.imageHeight/2,t=g.fitter.fit(f.data+\"\"),r=g.context;r.clearRect(q,a,g.imageWidth,\ng.imageHeight);r.save();r.translate(v,w);r.scale(g.imageWidth,g.imageHeight);r.beginPath();r.arc(0,0,.5,0,2*Math.PI);r.restore();r.fillStyle=\"#555555\";r.fill();r.fillStyle=\"white\";r.textBaseline=\"hanging\";r.font=(f.special?\"italic\":\"bold\")+\" \"+t.fontSize+\"px 'Roboto Mono', 'Consolas', 'Menlo', monospace\";v=t.lines;for(w=0;w<v.length;w++){var z=v[w];r.fillText(z.text,q+z.x,a+z.y,z.text.length*g.fitter.settings.glyphAspectRatio*t.fontSize)}\"function\"===typeof p&&g.callbackQueue.push({callback:p,args:[c]})}else if(f){var y=\nnew Image;g.pendingImageCount++;y.onload=function(){e<b.lastClearTimestamp||(b.pendingImageCount--,b.drawQueue.unshift({spriteIndex:c,timestamp:d,image:y,callback:p}),b.queueDraw())};y.onerror=function(){e<b.lastClearTimestamp||(b.pendingImageCount--,b.drawQueue.push({spriteIndex:c,timestamp:d,imageData:f,callback:p}),b.queueDraw())};y.src=\"svg\"===f.type?URL.createObjectURL(new Blob([f.data],{type:\"image/svg+xml;charset\\x3dutf-8\"})):\"data:\"+f.type+\";base64,\"+f.data}}var b=this;this.isDrawQueued=!1;\nfor(var e=Date.now(),f=e+(this.drawTimeout||Infinity),g=this;this.drawQueue.length&&Date.now()<f;)a();if(this.drawQueue.length||0<this.pendingImageCount)this.queueDraw();else if(this.needsUpdate=!0,this.onDrawFinished)this.onDrawFinished()};return b}(Z.Texture);\n</script>\n\n\n\n<script>//~~WEBPATH~~/facets-dive/lib/sprite-material.js\nvar Gg=this&&this.__extends||function(){var a=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(a,c){a.__proto__=c}||function(a,c){for(var b in c)c.hasOwnProperty(b)&&(a[b]=c[b])};return function(b,c){function d(){this.constructor=b}a(b,c);b.prototype=null===c?Object.create(c):(d.prototype=c.prototype,new d)}}(),Jg=function(a){function b(b,d){return a.call(this,{vertexShader:Hg,fragmentShader:Ig,uniforms:{time:{type:\"f\",value:0},defaultTexture:{type:\"t\",value:b},spriteAtlas:{type:\"t\",\nvalue:d},spriteColumns:{type:\"f\",value:d?d.spriteColumns:1},spriteRows:{type:\"f\",value:d?d.spriteRows:1}},transparent:!0})||this}Gg(b,a);Object.defineProperty(b.prototype,\"time\",{get:function(){return this.uniforms.time.value},set:function(a){this.uniforms.time.value=a},enumerable:!0,configurable:!0});Object.defineProperty(b.prototype,\"defaultTexture\",{get:function(){return this.uniforms.defaultTexture.value},set:function(a){this.uniforms.defaultTexture.value=a},enumerable:!0,configurable:!0});Object.defineProperty(b.prototype,\n\"spriteAtlas\",{get:function(){return this.uniforms.spriteAtlas.value},set:function(a){this.uniforms.spriteAtlas.value=a},enumerable:!0,configurable:!0});b.prototype.updateAtlasUniforms=function(){this.uniforms.spriteColumns.value=this.spriteAtlas.spriteColumns;this.uniforms.spriteRows.value=this.spriteAtlas.spriteRows};b.prototype.applyEasing=function(a){return.5>a?4*a*a*a:4*(a-1)*(a-1)*(a-1)+1};return b}(Z.RawShaderMaterial),Hg=\"\\n\\n  precision highp float;\\n  precision highp int;\\n\\n  #define SHADER_NAME SpriteMaterial\\n\\n  // Standard uniforms provided by THREE.js for projecting through the camera.\\n  uniform mat4 modelViewMatrix;\\n  uniform mat4 projectionMatrix;\\n\\n  uniform float time;\\n\\n  uniform float spriteColumns;\\n  uniform float spriteRows;\\n\\n  attribute vec3 position;\\n  attribute vec3 basePosition;\\n\\n  attribute vec4 color;\\n  attribute vec4 baseColor;\\n\\n  attribute float opacity;\\n  attribute float baseOpacity;\\n\\n  attribute float timestamp;\\n  attribute float baseTimestamp;\\n\\n  attribute float vertexIndex;\\n\\n  attribute float textureIndex;\\n  attribute float baseTextureIndex;\\n\\n  attribute float textureTimestamp;\\n  attribute float baseTextureTimestamp;\\n\\n  // Computed UV coordinates into the defaultTexture based on the vertexIndex.\\n  varying vec2 vDefaultUv;\\n\\n  // Computed UV coordinates into the sprite texture atlas.\\n  varying vec2 vSpriteUv;\\n\\n  // Interpolated color used by the fragment shader.\\n  varying vec4 vColor;\\n\\n  // Interpolated opacity used by the fragment shader.\\n  varying float vOpacity;\\n\\n  // Degree of mixing between base and current texture.\\n  varying float vTextureMix;\\n\\n  float applyEasing(float t) {\\n    return t \\x3c 0.5 ? 4.0 * t * t * t :\\n      4.0 * (t - 1.0) * (t - 1.0) * (t - 1.0) + 1.0;\\n  }\\n\\n  void main() {\\n\\n    // Compute default UVs. A \\x3d\\x3e (0,0), B \\x3d\\x3e (1,0), etc.\\n    vDefaultUv.x \\x3d mod(floor((vertexIndex + 1.0) / 2.0), 2.0);\\n    vDefaultUv.y \\x3d mod(floor(vertexIndex / 2.0), 2.0);\\n\\n    // Determine the row and column indices for this sprite.\\n    float spriteIndex \\x3d floor(vertexIndex / 4.0) + 0.5;\\n    float columnIndex \\x3d floor(mod(spriteIndex, spriteColumns));\\n    float rowIndex \\x3d spriteRows - 1.0 - floor(spriteIndex / spriteColumns);\\n\\n    // Compute sprite UVs from row and column indices.\\n    vSpriteUv.x \\x3d (columnIndex + vDefaultUv.x) / spriteColumns;\\n    vSpriteUv.y \\x3d (rowIndex + vDefaultUv.y) / spriteRows;\\n\\n    float blend \\x3d applyEasing(smoothstep(baseTimestamp, timestamp, time));\\n\\n    vTextureMix \\x3d mix(baseTextureIndex, textureIndex,\\n        smoothstep(baseTextureTimestamp, textureTimestamp, time));\\n\\n    vColor \\x3d mix(baseColor, color, blend);\\n\\n    vOpacity \\x3d mix(baseOpacity, opacity, blend);\\n\\n    gl_Position \\x3d projectionMatrix * modelViewMatrix *\\n        vec4(mix(basePosition, position, vec3(blend)), 1.0);\\n\\n  }\\n\\n\",\nIg=\"\\n\\n  precision highp float;\\n  precision highp int;\\n\\n  #define SHADER_NAME SpriteMaterial\\n\\n  // Lightness that should ideally exactly match the vColor.\\n  #define TARGET_LIGHTNESS 0.6\\n\\n  uniform float time;\\n\\n  uniform sampler2D defaultTexture;\\n  uniform sampler2D spriteAtlas;\\n\\n  varying vec2 vDefaultUv;\\n  varying vec2 vSpriteUv;\\n  varying vec4 vColor;\\n  varying float vOpacity;\\n  varying float vTextureMix;\\n\\n  // Compute relative luminance from RGB.\\n  float rgbToL(vec3 rgb) {\\n    return dot(rgb, vec3(0.3, 0.59, 0.11));\\n  }\\n\\n  // Apply luminance easing.\\n  float easeL(float l) {\\n    return 1.0 - (1.0 - l) * (1.0 - l) * (1.0 - l);\\n  }\\n\\n  void main() {\\n    if (vOpacity \\x3c\\x3d 0.05) {\\n      discard;\\n    }\\n\\n    // Interpolate between default texture and sprite texture.\\n    vec4 defaultColor \\x3d\\n      vTextureMix \\x3c 1.0 ? texture2D(defaultTexture, vDefaultUv) : vec4(0.0);\\n    vec4 spriteColor \\x3d\\n      vTextureMix \\x3e 0.0 ? texture2D(spriteAtlas, vSpriteUv) : vec4(0.0);\\n    vec4 mixedColor \\x3d mix(defaultColor, spriteColor, vTextureMix);\\n\\n    // Lightness of the mixed pixel.\\n    float mixedL \\x3d rgbToL(mixedColor.rgb);\\n\\n    // Using the mixed and target lightness, determine the color that's between\\n    // black, vColor and white.\\n    vec3 color \\x3d mixedL \\x3c TARGET_LIGHTNESS ?\\n        mix(vec3(0.0), vColor.rgb, easeL(mixedL / TARGET_LIGHTNESS)) :\\n        mix(vec3(1.0), vColor.rgb,\\n            easeL((1.0 - mixedL) / (1.0 - TARGET_LIGHTNESS)));\\n\\n    vec3 finalColor \\x3d mix(mixedColor.rgb, color, vColor.a);\\n\\n    // Apply opacity.\\n    gl_FragColor \\x3d vec4(finalColor, mixedColor.a * vOpacity);\\n  }\\n\";\n</script>\n\n\n<script>//~~WEBPATH~~/facets-dive/lib/sprite-mesh.js\nvar Kg=this&&this.__extends||function(){var a=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(a,c){a.__proto__=c}||function(a,c){for(var b in c)c.hasOwnProperty(b)&&(a[b]=c[b])};return function(b,c){function d(){this.constructor=b}a(b,c);b.prototype=null===c?Object.create(c):(d.prototype=c.prototype,new d)}}(),Lg=function(){function a(a,c){this._spriteMesh=a;this._spriteIndex=c}Object.defineProperty(a.prototype,\"spriteMesh\",{get:function(){return this._spriteMesh},enumerable:!0,configurable:!0});\nObject.defineProperty(a.prototype,\"spriteIndex\",{get:function(){return this._spriteIndex},enumerable:!0,configurable:!0});Object.defineProperty(a.prototype,\"x\",{get:function(){return this._spriteMesh.getX(this._spriteIndex)},set:function(a){this._spriteMesh.setX(this._spriteIndex,a)},enumerable:!0,configurable:!0});Object.defineProperty(a.prototype,\"y\",{get:function(){return this._spriteMesh.getY(this._spriteIndex)},set:function(a){this._spriteMesh.setY(this._spriteIndex,a)},enumerable:!0,configurable:!0});\nObject.defineProperty(a.prototype,\"z\",{get:function(){return this._spriteMesh.getZ(this._spriteIndex)},set:function(a){this._spriteMesh.setZ(this._spriteIndex,a)},enumerable:!0,configurable:!0});Object.defineProperty(a.prototype,\"r\",{get:function(){return this._spriteMesh.getR(this._spriteIndex)},set:function(a){this._spriteMesh.setR(this._spriteIndex,a)},enumerable:!0,configurable:!0});Object.defineProperty(a.prototype,\"g\",{get:function(){return this._spriteMesh.getG(this._spriteIndex)},set:function(a){this._spriteMesh.setG(this._spriteIndex,\na)},enumerable:!0,configurable:!0});Object.defineProperty(a.prototype,\"b\",{get:function(){return this._spriteMesh.getB(this._spriteIndex)},set:function(a){this._spriteMesh.setB(this._spriteIndex,a)},enumerable:!0,configurable:!0});Object.defineProperty(a.prototype,\"a\",{get:function(){return this._spriteMesh.getA(this._spriteIndex)},set:function(a){this._spriteMesh.setA(this._spriteIndex,a)},enumerable:!0,configurable:!0});Object.defineProperty(a.prototype,\"opacity\",{get:function(){return this._spriteMesh.getOpacity(this._spriteIndex)},\nset:function(a){this._spriteMesh.setOpacity(this._spriteIndex,a)},enumerable:!0,configurable:!0});Object.defineProperty(a.prototype,\"timestamp\",{get:function(){return this._spriteMesh.getTimestamp(this._spriteIndex)},set:function(a){this._spriteMesh.setTimestamp(this._spriteIndex,a)},enumerable:!0,configurable:!0});Object.defineProperty(a.prototype,\"baseX\",{get:function(){return this._spriteMesh.getBaseX(this._spriteIndex)},set:function(a){this._spriteMesh.setBaseX(this._spriteIndex,a)},enumerable:!0,\nconfigurable:!0});Object.defineProperty(a.prototype,\"baseY\",{get:function(){return this._spriteMesh.getBaseY(this._spriteIndex)},set:function(a){this._spriteMesh.setBaseY(this._spriteIndex,a)},enumerable:!0,configurable:!0});Object.defineProperty(a.prototype,\"baseZ\",{get:function(){return this._spriteMesh.getBaseZ(this._spriteIndex)},set:function(a){this._spriteMesh.setBaseZ(this._spriteIndex,a)},enumerable:!0,configurable:!0});Object.defineProperty(a.prototype,\"baseR\",{get:function(){return this._spriteMesh.getBaseR(this._spriteIndex)},\nset:function(a){this._spriteMesh.setBaseR(this._spriteIndex,a)},enumerable:!0,configurable:!0});Object.defineProperty(a.prototype,\"baseG\",{get:function(){return this._spriteMesh.getBaseG(this._spriteIndex)},set:function(a){this._spriteMesh.setBaseG(this._spriteIndex,a)},enumerable:!0,configurable:!0});Object.defineProperty(a.prototype,\"baseB\",{get:function(){return this._spriteMesh.getBaseB(this._spriteIndex)},set:function(a){this._spriteMesh.setBaseB(this._spriteIndex,a)},enumerable:!0,configurable:!0});\nObject.defineProperty(a.prototype,\"baseA\",{get:function(){return this._spriteMesh.getBaseA(this._spriteIndex)},set:function(a){this._spriteMesh.setBaseA(this._spriteIndex,a)},enumerable:!0,configurable:!0});Object.defineProperty(a.prototype,\"baseOpacity\",{get:function(){return this._spriteMesh.getBaseOpacity(this._spriteIndex)},set:function(a){this._spriteMesh.setBaseOpacity(this._spriteIndex,a)},enumerable:!0,configurable:!0});Object.defineProperty(a.prototype,\"baseTimestamp\",{get:function(){return this._spriteMesh.getBaseTimestamp(this._spriteIndex)},\nset:function(a){this._spriteMesh.setBaseTimestamp(this._spriteIndex,a)},enumerable:!0,configurable:!0});Object.defineProperty(a.prototype,\"textureIndex\",{get:function(){return this._spriteMesh.getTextureIndex(this._spriteIndex)},set:function(a){this._spriteMesh.setTextureIndex(this._spriteIndex,a)},enumerable:!0,configurable:!0});Object.defineProperty(a.prototype,\"baseTextureIndex\",{get:function(){return this._spriteMesh.getBaseTextureIndex(this._spriteIndex)},set:function(a){this._spriteMesh.setBaseTextureIndex(this._spriteIndex,\na)},enumerable:!0,configurable:!0});Object.defineProperty(a.prototype,\"textureTimestamp\",{get:function(){return this._spriteMesh.getTextureTimestamp(this._spriteIndex)},set:function(a){this._spriteMesh.setTextureTimestamp(this._spriteIndex,a)},enumerable:!0,configurable:!0});Object.defineProperty(a.prototype,\"baseTextureTimestamp\",{get:function(){return this._spriteMesh.getBaseTextureTimestamp(this._spriteIndex)},set:function(a){this._spriteMesh.setBaseTextureTimestamp(this._spriteIndex,a)},enumerable:!0,\nconfigurable:!0});a.prototype.rebase=function(a){this._spriteMesh.rebase(this._spriteIndex,a)};a.prototype.setSpriteImageData=function(a,c){this._spriteMesh.setSpriteImageData(this._spriteIndex,a,c)};a.prototype.switchTextures=function(a,c){this._spriteMesh.switchTextures(this._spriteIndex,a,c)};return a}(),Sg=function(a){function b(b,d,e){void 0===d&&(d=32);void 0===e&&(e=32);var c=a.call(this)||this;c.capacity=b;c.imageWidth=d;c.imageHeight=e;c.nextIndex=0;c.spriteWidth=c.imageWidth/c.imageHeight;\nc.spriteHeight=1;c.geometry=new Z.BufferGeometry;c.positionData=new Float32Array(12*b);c.positionAttribute=new Z.BufferAttribute(c.positionData,3);c.positionAttribute.setDynamic(!0);c.geometry.addAttribute(\"position\",c.positionAttribute);c.basePositionData=new Float32Array(12*b);c.basePositionAttribute=new Z.BufferAttribute(c.basePositionData,3);c.basePositionAttribute.setDynamic(!0);c.geometry.addAttribute(\"basePosition\",c.basePositionAttribute);c.colorData=new Uint8Array(16*b);c.colorAttribute=\nnew Z.BufferAttribute(c.colorData,4);c.colorAttribute.normalized=!0;c.colorAttribute.setDynamic(!0);c.geometry.addAttribute(\"color\",c.colorAttribute);c.baseColorData=new Uint8Array(16*b);c.baseColorAttribute=new Z.BufferAttribute(c.baseColorData,4);c.baseColorAttribute.normalized=!0;c.baseColorAttribute.setDynamic(!0);c.geometry.addAttribute(\"baseColor\",c.baseColorAttribute);c.opacityData=new Float32Array(4*b);c.opacityAttribute=new Z.BufferAttribute(c.opacityData,1);c.opacityAttribute.setDynamic(!0);\nc.geometry.addAttribute(\"opacity\",c.opacityAttribute);c.baseOpacityData=new Float32Array(4*b);c.baseOpacityAttribute=new Z.BufferAttribute(c.baseOpacityData,1);c.baseOpacityAttribute.setDynamic(!0);c.geometry.addAttribute(\"baseOpacity\",c.baseOpacityAttribute);c.timestampData=new Float32Array(4*b);c.timestampAttribute=new Z.BufferAttribute(c.timestampData,1);c.timestampAttribute.setDynamic(!0);c.geometry.addAttribute(\"timestamp\",c.timestampAttribute);c.baseTimestampData=new Float32Array(4*b);c.baseTimestampAttribute=\nnew Z.BufferAttribute(c.baseTimestampData,1);c.baseTimestampAttribute.setDynamic(!0);c.geometry.addAttribute(\"baseTimestamp\",c.baseTimestampAttribute);c.faceIndexData=new Uint32Array(6*b);for(var g=0;g<b;g++){var k=6*g,l=4*g;c.faceIndexData[k+0]=l+0;c.faceIndexData[k+1]=l+1;c.faceIndexData[k+2]=l+2;c.faceIndexData[k+3]=l+0;c.faceIndexData[k+4]=l+2;c.faceIndexData[k+5]=l+3}c.faceIndexAttribute=new Z.BufferAttribute(c.faceIndexData,1);c.geometry.setIndex(c.faceIndexAttribute);c.textureIndexData=new Float32Array(4*\nb);c.textureIndexAttribute=new Z.BufferAttribute(c.textureIndexData,1);c.textureIndexAttribute.setDynamic(!0);c.geometry.addAttribute(\"textureIndex\",c.textureIndexAttribute);c.baseTextureIndexData=new Float32Array(4*b);c.baseTextureIndexAttribute=new Z.BufferAttribute(c.baseTextureIndexData,1);c.baseTextureIndexAttribute.setDynamic(!0);c.geometry.addAttribute(\"baseTextureIndex\",c.baseTextureIndexAttribute);c.textureTimestampData=new Float32Array(4*b);c.textureTimestampAttribute=new Z.BufferAttribute(c.textureTimestampData,\n1);c.textureTimestampAttribute.setDynamic(!0);c.geometry.addAttribute(\"textureTimestamp\",c.textureTimestampAttribute);c.baseTextureTimestampData=new Float32Array(4*b);c.baseTextureTimestampAttribute=new Z.BufferAttribute(c.baseTextureTimestampData,1);c.baseTextureTimestampAttribute.setDynamic(!0);c.geometry.addAttribute(\"baseTextureTimestamp\",c.baseTextureTimestampAttribute);k=4*b;c.vertexIndexData=new Float32Array(k);for(g=0;g<k;g++)c.vertexIndexData[g]=g;c.vertexIndexAttribute=new Z.BufferAttribute(c.vertexIndexData,\n1);c.geometry.addAttribute(\"vertexIndex\",c.vertexIndexAttribute);c.defaultTextureCanvas=c.createDefaultTextureCanvas();c.defaultTexture=new Z.Texture(c.defaultTextureCanvas);c.defaultTexture.minFilter=Z.LinearFilter;c.defaultTexture.magFilter=Z.NearestFilter;c.defaultTexture.needsUpdate=!0;c.spriteAtlas=new Fg(b,d,e);c.material=new Jg(c.defaultTexture,c.spriteAtlas);c.onBeforeRender=function(){c.material.updateAtlasUniforms()};c.constructionTimestamp=Date.now();c.time=c.constructionTimestamp;c.frustumCulled=\n!1;return c}Kg(b,a);b.prototype.createSprite=function(){return new Lg(this,this.nextIndex++)};Object.defineProperty(b.prototype,\"time\",{get:function(){return this.material.time+this.constructionTimestamp},set:function(a){this.material.time=a-this.constructionTimestamp},enumerable:!0,configurable:!0});b.prototype.createDefaultTextureCanvas=function(){var a=this,b=this.defaultTextureCanvas=document.createElement(\"canvas\"),e=b.width=this.imageWidth,f=b.height=this.imageHeight,g=b.getContext(\"2d\"),k=\nnew Image;k.onload=function(){g.drawImage(k,0,0,e,f);a.defaultTexture.needsUpdate=!0};k.src=URL.createObjectURL(new Blob([Mg],{type:\"image/svg+xml;charset\\x3dutf-8\"}));return b};b.prototype.getX=function(a){return this.positionData[12*a+0]};b.prototype.setX=function(a,b){a*=12;this.positionData[a+0]=b;this.positionData[a+3]=b+this.spriteWidth;this.positionData[a+6]=b+this.spriteWidth;this.positionData[a+9]=b;this.positionAttribute.needsUpdate=!0};b.prototype.getY=function(a){return this.positionData[12*\na+1]};b.prototype.setY=function(a,b){a*=12;this.positionData[a+1]=b;this.positionData[a+4]=b;this.positionData[a+7]=b+this.spriteHeight;this.positionData[a+10]=b+this.spriteHeight;this.positionAttribute.needsUpdate=!0};b.prototype.getZ=function(a){return this.positionData[12*a+2]};b.prototype.setZ=function(a,b){a*=12;this.positionData[a+2]=b;this.positionData[a+5]=b;this.positionData[a+8]=b;this.positionData[a+11]=b;this.positionAttribute.needsUpdate=!0};b.prototype.getR=function(a){return this.colorData[16*\na+0]};b.prototype.setR=function(a,b){a*=16;this.colorData[a+0]=b;this.colorData[a+4]=b;this.colorData[a+8]=b;this.colorData[a+12]=b;this.colorAttribute.needsUpdate=!0};b.prototype.getG=function(a){return this.colorData[16*a+1]};b.prototype.setG=function(a,b){a*=16;this.colorData[a+1]=b;this.colorData[a+5]=b;this.colorData[a+9]=b;this.colorData[a+13]=b;this.colorAttribute.needsUpdate=!0};b.prototype.getB=function(a){return this.colorData[16*a+2]};b.prototype.setB=function(a,b){a*=16;this.colorData[a+\n2]=b;this.colorData[a+6]=b;this.colorData[a+10]=b;this.colorData[a+14]=b;this.colorAttribute.needsUpdate=!0};b.prototype.getA=function(a){return this.colorData[16*a+3]};b.prototype.setA=function(a,b){a*=16;this.colorData[a+3]=b;this.colorData[a+7]=b;this.colorData[a+11]=b;this.colorData[a+15]=b;this.colorAttribute.needsUpdate=!0};b.prototype.getBaseX=function(a){return this.basePositionData[12*a+0]};b.prototype.setBaseX=function(a,b){a*=12;this.basePositionData[a+0]=b;this.basePositionData[a+3]=b+\nthis.spriteWidth;this.basePositionData[a+6]=b+this.spriteWidth;this.basePositionData[a+9]=b;this.basePositionAttribute.needsUpdate=!0};b.prototype.getBaseY=function(a){return this.basePositionData[12*a+1]};b.prototype.setBaseY=function(a,b){a*=12;this.basePositionData[a+1]=b;this.basePositionData[a+4]=b;this.basePositionData[a+7]=b+this.spriteHeight;this.basePositionData[a+10]=b+this.spriteHeight;this.basePositionAttribute.needsUpdate=!0};b.prototype.getBaseZ=function(a){return this.basePositionData[12*\na+2]};b.prototype.setBaseZ=function(a,b){a*=12;this.basePositionData[a+2]=b;this.basePositionData[a+5]=b;this.basePositionData[a+8]=b;this.basePositionData[a+11]=b;this.basePositionAttribute.needsUpdate=!0};b.prototype.getBaseR=function(a){return this.baseColorData[16*a+0]};b.prototype.setBaseR=function(a,b){a*=16;this.baseColorData[a+0]=b;this.baseColorData[a+4]=b;this.baseColorData[a+8]=b;this.baseColorData[a+12]=b;this.baseColorAttribute.needsUpdate=!0};b.prototype.getBaseG=function(a){return this.baseColorData[16*\na+1]};b.prototype.setBaseG=function(a,b){a*=16;this.baseColorData[a+1]=b;this.baseColorData[a+5]=b;this.baseColorData[a+9]=b;this.baseColorData[a+13]=b;this.baseColorAttribute.needsUpdate=!0};b.prototype.getBaseB=function(a){return this.baseColorData[16*a+2]};b.prototype.setBaseB=function(a,b){a*=16;this.baseColorData[a+2]=b;this.baseColorData[a+6]=b;this.baseColorData[a+10]=b;this.baseColorData[a+14]=b;this.baseColorAttribute.needsUpdate=!0};b.prototype.getBaseA=function(a){return this.baseColorData[16*\na+3]};b.prototype.setBaseA=function(a,b){a*=16;this.baseColorData[a+3]=b;this.baseColorData[a+7]=b;this.baseColorData[a+11]=b;this.baseColorData[a+15]=b;this.baseColorAttribute.needsUpdate=!0};b.prototype.getOpacity=function(a){return this.opacityData[4*a+0]};b.prototype.setOpacity=function(a,b){a*=4;this.opacityData[a+0]=b;this.opacityData[a+1]=b;this.opacityData[a+2]=b;this.opacityData[a+3]=b;this.opacityAttribute.needsUpdate=!0};b.prototype.getBaseOpacity=function(a){return this.baseOpacityData[4*\na+0]};b.prototype.setBaseOpacity=function(a,b){a*=4;this.baseOpacityData[a+0]=b;this.baseOpacityData[a+1]=b;this.baseOpacityData[a+2]=b;this.baseOpacityData[a+3]=b;this.baseOpacityAttribute.needsUpdate=!0};b.prototype.getTimestamp=function(a){return this.timestampData[4*a+0]+this.constructionTimestamp};b.prototype.setTimestamp=function(a,b){a*=4;b-=this.constructionTimestamp;this.timestampData[a+0]=b;this.timestampData[a+1]=b;this.timestampData[a+2]=b;this.timestampData[a+3]=b;this.timestampAttribute.needsUpdate=\n!0};b.prototype.getBaseTimestamp=function(a){return this.baseTimestampData[4*a+0]+this.constructionTimestamp};b.prototype.setBaseTimestamp=function(a,b){a*=4;b-=this.constructionTimestamp;this.baseTimestampData[a+0]=b;this.baseTimestampData[a+1]=b;this.baseTimestampData[a+2]=b;this.baseTimestampData[a+3]=b;this.baseTimestampAttribute.needsUpdate=!0};b.prototype.getTextureIndex=function(a){return this.textureIndexData[4*a+0]};b.prototype.setTextureIndex=function(a,b){a*=4;this.textureIndexData[a+0]=\nb;this.textureIndexData[a+1]=b;this.textureIndexData[a+2]=b;this.textureIndexData[a+3]=b;this.textureIndexAttribute.needsUpdate=!0};b.prototype.getBaseTextureIndex=function(a){return this.baseTextureIndexData[4*a+0]};b.prototype.setBaseTextureIndex=function(a,b){a*=4;this.baseTextureIndexData[a+0]=b;this.baseTextureIndexData[a+1]=b;this.baseTextureIndexData[a+2]=b;this.baseTextureIndexData[a+3]=b;this.baseTextureIndexAttribute.needsUpdate=!0};b.prototype.getTextureTimestamp=function(a){return this.textureTimestampData[4*\na+0]+this.constructionTimestamp};b.prototype.setTextureTimestamp=function(a,b){a*=4;b-=this.constructionTimestamp;this.textureTimestampData[a+0]=b;this.textureTimestampData[a+1]=b;this.textureTimestampData[a+2]=b;this.textureTimestampData[a+3]=b;this.textureTimestampAttribute.needsUpdate=!0};b.prototype.getBaseTextureTimestamp=function(a){return this.baseTextureTimestampData[4*a+0]+this.constructionTimestamp};b.prototype.setBaseTextureTimestamp=function(a,b){a*=4;b-=this.constructionTimestamp;this.baseTextureTimestampData[a+\n0]=b;this.baseTextureTimestampData[a+1]=b;this.baseTextureTimestampData[a+2]=b;this.baseTextureTimestampData[a+3]=b;this.baseTextureTimestampAttribute.needsUpdate=!0};b.prototype.rebase=function(a,b){function c(a,b){return a*k+b*(1-k)}b=void 0===b?this.time:b;var d=this.getBaseTimestamp(a),g=this.getTimestamp(a),k=b>=g?1:b<=d?0:this.material.applyEasing((b-d)/(g-d));this.setBaseX(a,c(this.getX(a),this.getBaseX(a)));this.setBaseY(a,c(this.getY(a),this.getBaseY(a)));this.setBaseZ(a,c(this.getZ(a),this.getBaseZ(a)));\nthis.setBaseR(a,c(this.getR(a),this.getBaseR(a)));this.setBaseG(a,c(this.getG(a),this.getBaseG(a)));this.setBaseB(a,c(this.getB(a),this.getBaseB(a)));this.setBaseA(a,c(this.getA(a),this.getBaseA(a)));this.setBaseOpacity(a,c(this.getOpacity(a),this.getBaseOpacity(a)));this.setBaseTimestamp(a,b>=g?b:c(g,d))};b.prototype.setSpriteImageData=function(a,b,e){this.spriteAtlas.setSpriteImageData(a,b,e)};b.prototype.switchTextures=function(a,b,e){var c=this.getTextureIndex(a);this.setBaseTextureIndex(a,c);\nthis.setTextureIndex(a,0===c?1:0);this.setBaseTextureTimestamp(a,b);this.setTextureTimestamp(a,e)};b.prototype.findSprites=function(a,b){for(var c=[],d=0;d<this.capacity;d++){var g=12*d;a>=this.positionData[g+0]&&a<=this.positionData[g+6]&&b>=this.positionData[g+1]&&b<=this.positionData[g+7]&&c.push(d)}return c};return b}(Z.Mesh),Mg='\\n\\x3csvg version\\x3d\"1.1\"\\n     baseProfile\\x3d\"full\"\\n     width\\x3d\"128\" height\\x3d\"128\"\\n     xmlns\\x3d\"http://www.w3.org/2000/svg\"\\n     xmlns:xlink\\x3d\"http://www.w3.org/1999/xlink\"\\x3e\\n  \\x3cdefs\\x3e\\n    \\x3clinearGradient id\\x3d\"linearGradient3774\"\\x3e\\n      \\x3cstop\\n         style\\x3d\"stop-color:#808080;stop-opacity:1;\"\\n         offset\\x3d\"0\" /\\x3e\\n      \\x3cstop\\n         style\\x3d\"stop-color:#555555;stop-opacity:1;\"\\n         offset\\x3d\"1\" /\\x3e\\n    \\x3c/linearGradient\\x3e\\n    \\x3cradialGradient\\n       xlink:href\\x3d\"#linearGradient3774\"\\n       id\\x3d\"radialGradient3780\"\\n       cx\\x3d\"80\"\\n       cy\\x3d\"40\"\\n       fx\\x3d\"80\"\\n       fy\\x3d\"40\"\\n       r\\x3d\"80\"\\n       gradientUnits\\x3d\"userSpaceOnUse\"\\n       spreadMethod\\x3d\"pad\" /\\x3e\\n  \\x3c/defs\\x3e\\n  \\x3ccircle cx\\x3d\"50%\" cy\\x3d\"50%\" r\\x3d\"50%\" fill\\x3d\"url(#radialGradient3780)\" /\\x3e\\n\\x3c/svg\\x3e\\n';\n</script>\n\n<script>//~~WEBPATH~~/facets-dive/lib/wordtree.js\nvar Tg=/\\b[-'\\w]+\\b/g;function Ug(a){return typeof a+\"\\u001f\"+a}\nfunction Vg(a){function b(a,b){for(var c=0;c<a.length;c++)b[a[c]]=!0}if(2>a.valueCount)return null;for(var c={},d=a;d;)b(d.commonWords,c),d=d.parent;for(d=0;d<a.children.length;d++)b(a.children[d].commonWords,c);var d={},e;for(e in a.valueHash){var f=a.valueHash[e],g=f.count,f=f.words,k;for(k in f)k in c||(d[k]=(d[k]||0)+g,d[k]===a.totalCount&&(a.commonWords.push(k),c[k]=!0,delete d[k]))}a=null;c=0;for(k in d)d[k]>c&&(a=k,c=d[k]);return a}\nfunction Wg(a){function b(a){a.order=++p;for(var c=0;c<a.children.length;c++)b(a.children[c])}function c(a){return a.valueCount+a.nonValueCount}var d={parent:null,commonWords:[],level:1,order:0,totalCount:0,valueHash:{},valueCount:0,nonValueCount:0,children:[]},e={root:d,nodeHash:{},highestLevel:1,levelHash:{1:d}},f;for(f in a)if(a.hasOwnProperty(f)){var g=a[f];var k=g.value;var l=g.count;var m=g.words;\"string\"===typeof k?(d.valueHash[f]={value:k,count:l,words:m},d.valueCount+=l):d.nonValueCount+=\nl;d.totalCount+=l;e.nodeHash[f]=d}a=d.level;if(d.nonValueCount){a++;var n={parent:d,commonWords:[],level:a,order:0,totalCount:d.nonValueCount,valueHash:{},valueCount:0,nonValueCount:d.nonValueCount,children:[]};d.nonValueCount=0;d.children.push(n);e.highestLevel=a;e.levelHash[a]=n;for(f in e.nodeHash)f in d.valueHash||(e.nodeHash[f]=n)}for(d=[d];100>a&&d.length;){l=0;k=c(d[l]);for(g=1;g<d.length;g++){var q=c(d[g]);q>k&&(l=g,k=q)}q=d[l];if(g=Vg(q))for(f in a++,n={parent:q,commonWords:[g],level:a,order:0,\ntotalCount:0,valueHash:{},valueCount:0,nonValueCount:0,children:[]},q.children.push(n),d.push(n),q.valueHash)q.valueHash.hasOwnProperty(f)&&(m=q.valueHash[f],k=m.value,l=m.count,(m=m.words)&&g in m&&(n.valueHash[f]={value:k,count:l,words:m},n.valueCount+=l,n.totalCount+=l,delete q.valueHash[f],q.valueCount-=l,e.nodeHash[f]=n,e.highestLevel=a,e.levelHash[a]=n));else d.splice(l,1)}var p=0;b(e.root);return e};\n</script>\n\n<script>//~~WEBPATH~~/facets-dive/lib/stats.js\nvar Xg=function(){function a(){this.uniqueCount=this.totalCount=0;this.valueHash={};this.otherCount=this.stringCount=this.integerCount=this.numberCount=0;this.stringLengthsCount=this.stringMeanLength=this.stringMaxLength=this.stringMinLength=this.numberMax=this.numberMin=null;this.stringLengthsHash={};this.totalWordCount=this.multiwordCount=0;this.wordCounts={};this.uniqueWordCount=0;this.wordTree=null}a.prototype.isNumeric=function(){return 0<this.numberCount&&null!==this.numberMin&&null!==this.numberMax&&\nthis.numberMax>this.numberMin};a.prototype.isInteger=function(){return 0<this.numberCount&&this.integerCount===this.numberCount};a.prototype.addValue=function(a){this.totalCount++;var b=Ug(a);b in this.valueHash||(this.valueHash[b]={value:a,count:0},this.uniqueCount++);this.valueHash[b].count++;switch(typeof a){case \"number\":this.incorporateNumberValue(a);break;case \"string\":this.incorporateStringValue(b,a);break;default:this.otherCount++}};a.prototype.incorporateNumberValue=function(a){this.numberCount++;\n\"number\"===typeof a&&a>>0===a&&this.integerCount++;isNaN(a)||(this.numberMin=null===this.numberMin?a:Math.min(this.numberMin,a),this.numberMax=null===this.numberMax?a:Math.max(this.numberMax,a))};a.prototype.incorporateStringValue=function(a,c){this.stringCount++;var b=c.length;b in this.stringLengthsHash||(this.stringLengthsCount=(this.stringLengthsCount||0)+1);this.stringLengthsHash[b]=(this.stringLengthsHash[b]||0)+1;this.stringMinLength=null===this.stringMinLength?b:Math.min(this.stringMinLength,\nb);this.stringMaxLength=null===this.stringMaxLength?b:Math.max(this.stringMaxLength,b);this.stringMeanLength=(this.stringMeanLength||0)*(this.stringCount-1)/this.stringCount+b/this.stringCount;if(!this.valueHash[a].words){c=c.toLowerCase().toLowerCase().match(Tg)||[];1<c.length&&(this.multiwordCount++,this.totalWordCount+=c.length);for(var b=this.valueHash[a].words={},e=0;e<c.length;e++){var f=c[e];b[f]=(b[f]||0)+1;f in this.wordCounts||(this.wordCounts[f]=0,this.uniqueWordCount++)}}a=this.valueHash[a].words;\nfor(f in a)this.wordCounts[f]=(this.wordCounts[f]||0)+1};return a}();function Yg(a){if(!a||!a.length)return{};for(var b={},c=0;c<a.length;c++){var d=a[c];if(null!=d)for(var e=Object.keys(d),f=0;f<e.length;f++){var g=e[f],k=d[g];g in b||(b[g]=new Xg);b[g].addValue(k)}}for(var l in b)a=b[l],a.multiwordCount&&(a.wordTree=Wg(a.valueHash));return b};\n</script>\n\n<script>//~~WEBPATH~~/facets-dive/lib/string-format.js\nfunction Zg(a){return 65>a.length?a:a.substr(0,30)+\"...\"+a.substr(-30)};\n</script>\n\n\n\n\n<dom-module id=\"facets-dive-vis\">\n  <template>\n    <style>\n      :host {\n        box-sizing: border-box;\n        display: block;\n        height: 100%;\n        width: 100%;\n      }\n      ::content .labels {\n        @apply(--paper-font-common-base);\n        @apply(--paper-font-headline);\n      }\n    </style>\n    \n  </template>\n</dom-module>\n\n<script>//~~WEBPATH~~/facets-dive/components/facets-dive-vis/facets-dive-vis.js\nvar $g=this&&this.__extends||function(){var a=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(a,c){a.__proto__=c}||function(a,c){for(var b in c)c.hasOwnProperty(b)&&(a[b]=c[b])};return function(b,c){function d(){this.constructor=b}a(b,c);b.prototype=null===c?Object.create(c):(d.prototype=c.prototype,new d)}}(),ah={bottom:6,left:6,right:6,top:6},bh={\"\\ufffcOTHER\\ufffc\":\"other\",\"\\ufffcNO_WORDS\\ufffc\":\"non-words\",\"\\ufffcALL_WORDS\\ufffc\":\"other\"};\nfunction ch(a){return null!==a&&a in bh?{label:bh[a],special:!0}:\"number\"!==typeof a&&\"string\"!==typeof a?{label:\"\"+a,special:!0}:{label:Zg(\"\"+a),special:!1}}\nvar dh=\"#4285F4 #DB4437 #F4B400 #0F9D58 #AB47BC #00ACC1 #FF7043 #9E9D24 #5C6BC0 #F06292 #00796B #C2185B\".split(\" \"),eh=\"#4285F4 #0F9D58 #00ACC1 #9E9D24 #5C6BC0 #00796B #607D8B\".split(\" \"),fh=\"#DB4437 #F4B400 #AB47BC #F06292 #AB47BC #795548 #FF7043 #C2185B\".split(\" \"),gh=\"#4285F4 #C53929 #F7CB4D #0B8043 #5E35B1 #80DEEA #FF7043 #C0CA33\".split(\" \"),hh={\"alignment-baseline\":\"middle\",fill:\"#444444\",\"font-size\":18,\"font-style\":\"normal\",\"text-anchor\":\"middle\",x:0,y:0},ih=function(a){function b(){return null!==\na&&a.apply(this,arguments)||this}$g(b,a);return b}(jf),jh=function(){function a(a){this.elem=a;this.endTimestamp=0;this.renderQueued=!1;this.labels=[];this.autoColorBy=!1;this.horizontalFacetInfo=this.verticalFacetInfo=null}a.prototype.ready=function(){this.layout=new yf;this.cellBackgroundSVG=d3.select(this.elem).append(\"svg\").style(\"left\",0).style(\"position\",\"absolute\").style(\"top\",0);this.cellBackgroundSVGRoot=this.cellBackgroundSVG.append(\"g\").attr(\"class\",\"root\");this.cellBackgroundLayer=this.cellBackgroundSVGRoot.append(\"g\").attr(\"class\",\n\"labels\");this.scene=new Z.Scene;this.camera=new Z.OrthographicCamera(0,100,0,100,.1,1E3);try{this.renderer=new Z.WebGLRenderer({alpha:!0}),this.renderer.setPixelRatio(),d3.select(this.renderer.domElement).style(\"left\",0).style(\"pointer-events\",\"none\").style(\"position\",\"absolute\").style(\"top\",0),this.elem.appendChild(this.renderer.domElement)}catch(b){}this.zoom=d3.zoom().scaleExtent([.01,1E3]).on(\"zoom\",this.zoomed.bind(this));d3.select(this.elem).call(this.zoom);this.labelsAndAxesSVG=d3.select(this.elem).append(\"svg\").style(\"left\",\n0).style(\"position\",\"absolute\").style(\"top\",0);this.labelsAndAxesSVGRoot=this.labelsAndAxesSVG.append(\"g\").attr(\"class\",\"root\");this.labelsLayer=this.labelsAndAxesSVGRoot.append(\"g\").attr(\"class\",\"labels\");this.axesLayer=this.labelsAndAxesSVGRoot.append(\"g\").attr(\"class\",\"axes\");this.labelsAndAxesSVG.on(\"click\",this.clicked.bind(this));this.renderer||(this.labelsAndAxesSVG.style(\"display\",\"none\"),this.cellBackgroundSVG.style(\"display\",\"none\"),d3.select(this.elem).append(\"p\").attr(\"class\",\"error\").style(\"color\",\n\"darkred\").html('\\n            \\x3cstrong\\x3eERROR\\x3c/strong\\x3e: Facets Dive requires WebGL, and it is not\\n            enabled in your browser. See\\n            \\x3ca rel\\x3d\"noreferrer\" href\\x3d\"http://webglreport.com/\"\\x3e\\n            WebGL Report\\x3c/a\\x3e for details.\\n          '))};a.prototype.zoomed=function(){var a=d3.event.transform,c=a.x,d=a.y,a=a.k,e=this.scale/a;this.camera.top*=e;this.camera.left*=e;this.camera.right*=e;this.camera.bottom*=e;this.camera.position.set(-c/a,d/a,this.camera.position.z);\nthis.camera.updateProjectionMatrix();this.scale=a;this.transformSVG();this.updateObjectVisibility();this.queueRenderScene()};a.prototype.clicked=function(){for(var a=this.elem.getBoundingClientRect(),c=d3.event,a=this.spriteMesh.findSprites(this.camera.position.x+(c.clientX-a.left)/this.scale,this.camera.position.y-(c.clientY-a.top)/this.scale),c=Array(a.length),d=0;d<a.length;d++)c[d]=this.elem.data[a[d]];this.elem.set(\"selectedData\",c)};a.prototype.fitToViewport=function(){var a=this,c=this.elem.getBoundingClientRect();\nif(c.width&&c.height){this.layout.viewport.width=c.width;this.layout.viewport.height=c.height;this.layout.padding.bottom=this.elem.scenePadding;this.layout.padding.left=this.elem.scenePadding;this.layout.padding.right=this.elem.scenePadding;this.layout.padding.top=this.elem.scenePadding;this.layout.grid={bottom:0,left:0,right:this.grid.width,top:this.grid.height};if(this.labels.length){var d=0,e=0,f=0,g=0;this.labelsLayer.selectAll(\".label\").each(function(a){var b=d3.select(this).select(\".current\").node().getBoundingClientRect(),\nc=a.elementMargin||{bottom:0,left:0,right:0,top:0},k=b.height+c.top+c.bottom,b=b.width+c.left+c.right;switch(a.side){case kf.Bottom:d=Math.max(d,k);break;case kf.Top:g=Math.max(g,k);break;case kf.Left:e=Math.max(e,b);break;case kf.Right:f=Math.max(f,b);break;default:throw Error(\"Unrecognized Side.\");}});this.layout.padding.bottom+=d;this.layout.padding.left+=e;this.layout.padding.right+=f;this.layout.padding.top+=g}this.layout.reducePaddingToFitWidth(c.width);this.layout.reducePaddingToFitHeight(c.height);\nthis.scale=this.layout.computeScale();var k=this.layout.computeCamera(),c=k.position,k=k.frustum;this.camera.left=k.left;this.camera.right=k.right;this.camera.top=k.top;this.camera.bottom=k.bottom;this.camera.position.set(c.x,c.y,100);this.camera.updateProjectionMatrix();d3.select(this.elem).call(this.zoom.transform,d3.zoomIdentity.scale(this.scale).translate(-this.camera.position.x,this.camera.position.y));this.transformSVG();this.updateObjectVisibility();this.queueRenderScene()}else setTimeout(function(){return a.fitToViewport()},\n100)};a.prototype.zoomIn=function(){this.zoom.scaleBy(d3.select(this.elem),1.1)};a.prototype.zoomOut=function(){this.zoom.scaleBy(d3.select(this.elem),1/1.1)};a.prototype.transformSVG=function(){var a=this,c=-this.camera.position.x*this.scale,d=this.camera.position.y*this.scale;this.cellBackgroundSVGRoot.attr(\"transform\",\"translate(\"+c+\",\"+d+\") scale(\"+this.scale+\",\"+-this.scale+\")\");this.labelsAndAxesSVGRoot.attr(\"transform\",\"translate(\"+c+\",\"+d+\") scale(\"+this.scale+\",\"+-this.scale+\")\");this.labelsAndAxesSVGRoot.selectAll(\".unscale\").attr(\"transform\",\n\"scale(\"+1/this.scale+\")\");this.axesLayer.selectAll(\".axis\").select(\"path\").attr(\"d\",function(b){return b.path(a.scale)}).attr(\"stroke-width\",function(b){return b.strokeWidth(a.scale)})};a.prototype.isVisible=function(a,c){return a.shouldBeVisible(c,this.scale,this.camera.position,this.camera)};a.prototype.updateObjectVisibility=function(){var a=this,c=this,d=this.labelsLayer.selectAll(\".label\"),e=d.filter(function(a){return(void 0===a.visible||!a.visible)&&c.isVisible(a,this)}).each(function(a){return a.visible=\n!0}),f=d.filter(function(a){return(void 0===a.visible||a.visible)&&!c.isVisible(a,this)}).each(function(a){return a.visible=!1});e.selectAll(\".opacity\").transition().duration(this.elem.tweenDuration).attr(\"opacity\",1);f.selectAll(\".opacity\").transition().duration(this.elem.tweenDuration).attr(\"opacity\",0);d.filter(function(a){return!!a.scaleDown}).selectAll(\".scale\").attr(\"transform\",function(b){return\"scale(\"+(a.scale<b.minScale?a.scale/b.minScale:1)+\")\"});d=this.axesLayer.selectAll(\".axis\").each(function(a){a.visible=\nc.isVisible(a,this)});d.filter(function(a){return!!a.visible}).select(\"path\").transition().duration(this.elem.tweenDuration).attr(\"stroke-opacity\",1);d.filter(function(a){return!a.visible}).select(\"path\").transition().duration(this.elem.tweenDuration).attr(\"stroke-opacity\",0)};a.prototype.addVerticalFacetLabels=function(a){var b=this;this.elem.verticalFacet in this.stats&&this.grid.getColumn(this.grid.horizontalKeys[this.grid.horizontalKeys.length-1]).forEach(function(c){var d=b.verticalFacetInfo.labelingFunction(c.verticalKey),\nf=new ih;f.text=d.label;f.x=c.x+c.width;f.y=c.contentY+c.innerHeight/2;f.side=kf.Right;f.cell=c;f.attributes={\"alignment-baseline\":\"middle\",fill:\"#666666\",\"font-size\":hh[\"font-size\"],\"text-anchor\":\"start\",\"font-style\":d.special?\"italic\":\"normal\"};f.offsetPosition={x:8};f.minScale=hh[\"font-size\"]/(c.height+b.grid.cellMargin);f.scaleDown=!0;a.push(f)})};a.prototype.addHorizontalFacetLabels=function(a){var b=this;this.elem.horizontalFacet in this.stats&&this.grid.getRow(this.grid.verticalKeys[this.grid.verticalKeys.length-\n1]).forEach(function(c){var d=b.horizontalFacetInfo.labelingFunction(c.horizontalKey),f=new ih;f.text=d.label;f.x=c.contentX+c.innerWidth/2;f.y=c.y+c.height;f.side=kf.Top;f.cell=c;f.rotate=-45;f.attributes={\"alignment-baseline\":\"ideographic\",fill:\"#dd6622\",\"font-size\":hh[\"font-size\"],\"text-anchor\":\"start\",\"font-style\":d.special?\"italic\":\"normal\"};f.offsetPosition={x:8,y:-8};f.minScale=hh[\"font-size\"]/(c.width+b.grid.cellMargin/2);f.scaleDown=!0;a.push(f)})};a.prototype.addVerticalPositioningLabels=\nfunction(a){var b=this;if(\"scatter\"===this.elem.positionMode&&this.elem.verticalPosition in this.stats){var d=this.stats[this.elem.verticalPosition],e=this.formatNumber(d.numberMin),f=this.formatNumber(d.numberMax),g=(e.length+3)/(e.length+f.length+6);this.grid.eachCell(function(c){if(c.items.length){for(var d=c.siblings.left;!(!d||d.items.length||d.siblings.above&&d.siblings.above.items.length);)d=d.siblings.left;var d=d?d.contentX+d.innerWidth:-Infinity,k=c.x+8,n=c.contentY,q=c.contentY+c.innerHeight,\np=new ih;p.id=c.compoundKey+\"-left-start\";p.text=e;p.x=c.x+8;p.y=c.y+(b.elem.horizontalPosition?8:0);p.side=kf.Left;p.cell=c;p.rotate=-90;p.attributes={\"alignment-baseline\":\"ideographic\",fill:\"#2255aa\",\"font-size\":16,\"text-anchor\":\"start\"};p.offsetPosition={x:ah.bottom,y:-ah.right};p.boundingBox={bottom:n,left:d,right:k,top:n+c.innerHeight*(Math.max(g,.1)-.05)};p.elementMargin=ah;a.push(p);p=new ih;p.id=c.compoundKey+\"-left-end\";p.text=f;p.x=c.x+8;p.y=c.y+c.height;p.side=kf.Left;p.cell=c;p.rotate=\n-90;p.attributes={\"alignment-baseline\":\"ideographic\",fill:\"#2255aa\",\"font-size\":16,\"text-anchor\":\"end\"};p.offsetPosition={x:-ah.top,y:-ah.right};p.boundingBox={bottom:n+c.innerHeight*(Math.min(g,.9)+.05),left:d,right:k,top:q};p.elementMargin=ah;a.push(p)}})}};a.prototype.addHorizontalPositioningLabels=function(a){var b=this;if(\"scatter\"===this.elem.positionMode&&this.elem.horizontalPosition in this.stats){var d=this.stats[this.elem.horizontalPosition],e=this.formatNumber(d.numberMin),f=this.formatNumber(d.numberMax),\ng=(e.length+3)/(e.length+f.length+6);this.grid.eachCell(function(c){if(c.items.length){for(var d=c.siblings.below;!(!d||d.items.length||d.siblings.right&&d.siblings.right.items.length);)d=d.siblings.below;var d=d?d.contentY+d.innerHeight:-Infinity,k=c.contentY,n=c.contentX,q=n+c.innerWidth,p=new ih;p.id=c.compoundKey+\"-bottom-start\";p.text=e;p.x=c.x+(b.elem.verticalPosition?8:0);p.y=c.y+8;p.side=kf.Bottom;p.cell=c;p.attributes={\"alignment-baseline\":\"hanging\",fill:\"#118844\",\"font-size\":16,\"text-anchor\":\"start\"};\np.offsetPosition={x:ah.left,y:ah.top};p.boundingBox={bottom:d,left:n,right:n+c.innerWidth*(Math.max(g,.1)-.05),top:k};p.elementMargin=ah;a.push(p);p=new ih;p.id=c.compoundKey+\"-bottom-end\";p.text=f;p.x=c.x+c.width;p.y=c.y+8;p.side=kf.Bottom;p.cell=c;p.attributes={\"alignment-baseline\":\"hanging\",fill:\"#118844\",\"font-size\":16,\"text-anchor\":\"end\"};p.offsetPosition={x:-ah.right,y:ah.top};p.boundingBox={bottom:d,left:n+c.innerWidth*(Math.min(g,.9)+.05),right:q,top:k};p.elementMargin=ah;a.push(p)}})}};a.prototype.determineLabels=\nfunction(){var a=[];this.addVerticalFacetLabels(a);this.addHorizontalFacetLabels(a);this.addVerticalPositioningLabels(a);this.addHorizontalPositioningLabels(a);return a};a.prototype.updateCellBackgrounds=function(){var a=this.grid.getCells().filter(function(a){return a.items.length}),a=this.cellBackgroundLayer.selectAll(\".cell\").data(a,function(a){return a.compoundKey});a.enter().append(\"rect\").attr(\"class\",\"cell\").attr(\"x\",function(a){return a.contentX||0}).attr(\"y\",function(a){return a.contentY||\n0}).attr(\"width\",function(a){return a.innerWidth||0}).attr(\"height\",function(a){return a.innerHeight||0}).attr(\"fill\",\"#f8f8f9\").attr(\"fill-opacity\",0).merge(a).transition().duration(this.elem.tweenDuration).attr(\"x\",function(a){return a.contentX||0}).attr(\"y\",function(a){return a.contentY||0}).attr(\"width\",function(a){return a.innerWidth||0}).attr(\"height\",function(a){return a.innerHeight||0}).attr(\"fill-opacity\",1);a.exit().transition().duration(this.elem.tweenDuration).remove().attr(\"fill-opacity\",\n0)};a.prototype.updateAxes=function(){var a=this,c=[];\"stacked\"!==this.elem.positionMode&&this.grid.eachCell(function(b){if(b.items.length){if(a.elem.verticalPosition){var d=new xf(kf.Left,b);c.push(d)}a.elem.horizontalPosition&&(d=new xf(kf.Bottom,b),c.push(d))}});var d=this.axesLayer.selectAll(\".axis\").data(c,function(a){return a.key()}),e=d.enter().append(\"g\").attr(\"class\",\"axis\").attr(\"opacity\",0);e.append(\"path\").attr(\"d\",function(b){return b.path(a.scale)}).attr(\"stroke\",function(a){return a.side===\nkf.Left?\"#2255aa\":\"#118844\"}).attr(\"stroke-width\",function(b){return b.strokeWidth(a.scale)}).attr(\"stroke-opacity\",0).attr(\"fill\",\"none\");e.merge(d).transition().duration(this.elem.tweenDuration).attr(\"opacity\",1);e.merge(d).select(\"path\").transition().duration(this.elem.tweenDuration).attr(\"d\",function(b){return b.path(a.scale)});d.exit().transition().duration(this.elem.tweenDuration).remove().attr(\"opacity\",0)};a.prototype.updateLabels=function(){if(this.scale){this.labels=this.determineLabels();\nvar a=this.labelsLayer.selectAll(\".label\").data(this.labels,function(a){return a.id||a.side+\"-\"+a.text});a.each(function(a){var b=d3.select(this),c=b.select(\".current\");a.text!==c.text()&&(c.attr(\"fill-opacity\",0),b.select(\".old\").attr(\"fill-opacity\",1).text(c.text()))}).select(\".current\").text(function(a){return a.text});var c=function(a){return function(b){return void 0===b.attributes||void 0===b.attributes[a]?hh[a]:b.attributes[a]}},d=a.enter().append(\"g\").attr(\"class\",\"label\").attr(\"transform\",\nfunction(a){return\"translate(\"+a.x+\",\"+a.y+\")\"}),e=d.append(\"g\").attr(\"class\",\"flip\").attr(\"transform\",\"scale(1,-1)\").append(\"g\").attr(\"class\",\"rotate\").attr(\"transform\",function(a){return\"rotate(\"+(\"rotate\"in a?a.rotate:0)+\")\"}).append(\"g\").attr(\"class\",\"unscale\").attr(\"transform\",\"scale(\"+1/this.scale+\")\").append(\"g\").attr(\"class\",\"position\").append(\"g\").attr(\"class\",\"opacity scale\"),f=e.append(\"text\").attr(\"class\",\"old\").attr(\"fill-opacity\",0),e=e.append(\"text\").attr(\"class\",\"current\").attr(\"fill-opacity\",\n0).text(function(a){return a.text}),g;for(g in hh)hh.hasOwnProperty(g)&&(f.attr(g,c(g)),e.attr(g,c(g)));f=d.merge(a).transition().duration(this.elem.tweenDuration).attr(\"transform\",function(a){return\"translate(\"+a.x+\",\"+a.y+\")\"});f.select(\".rotate\").attr(\"transform\",function(a){return\"rotate(\"+(\"rotate\"in a?a.rotate:0)+\")\"});f.filter(function(a){return!!a.offsetPosition}).select(\".position\").attr(\"transform\",function(a){return\"translate(\"+(a.offsetPosition.x||0)+\",\"+(a.offsetPosition.y||0)+\")\"});\nd=f.select(\".old\").attr(\"fill-opacity\",0);f=f.select(\".current\").attr(\"fill-opacity\",1);for(g in hh)hh.hasOwnProperty(g)&&(d.attr(g,c(g)),f.attr(g,c(g)));a.exit().transition().duration(this.elem.tweenDuration).remove().select(\".current\").attr(\"fill-opacity\",0)}};a.prototype.dataChange=function(){var a=this,c=this.elem.data;if(c&&c.length)if(this.scene){var d=!!this.spriteMesh;this.resizeHandler();d&&(this.scene.remove(this.spriteMesh),this.spriteMesh.spriteAtlas.clearQueues(),delete this.spriteMesh);\nvar e=this.elem.spriteImageWidth,f=this.elem.spriteImageHeight,g=e/f,k=c.length;this.spriteMesh=new Sg(k,e,f);this.scene.add(this.spriteMesh);this.spriteMesh.spriteAtlas.onDrawFinished=function(){return a.queueRenderScene()};this.items=[];for(var e=Math.ceil(Math.sqrt(k)),f=Math.ceil(k/e),l=0;l<k;l++){var m=this.spriteMesh.createSprite();m.x=e/2;m.y=f/2;m.opacity=0;m.timestamp=Date.now();m.rebase(m.timestamp);this.items.push({sprite:m,data:c[l]})}this.grid=new uf(this.items);this.grid.cellMargin=\n1;this.grid.itemAspectRatio=g;this.grid.itemPositionSetter=function(b,c,d){var e=Date.now();b.sprite.rebase(e);b.sprite.x=c;b.sprite.y=d;b.sprite.opacity=1;b.sprite.timestamp=e+a.elem.tweenDuration;a.renderUntil(b.sprite.timestamp)};this.stats=Yg(c);this.updateGridFaceting();this.updateGridItemPositions();d?this.updateColors():this.elem.colorBy||this.pickColorByField();d?this.updateImageFieldName():this.elem.imageFieldName||this.pickTextDrawingField()}else requestAnimationFrame(this.dataChange.bind(this))};\na.prototype.filteredDataIndicesChange=function(){var a=this.elem.filteredDataIndices;if(this.scene&&this.items){var c=[];if(a)for(var d=0;d<a.length;d++){var e=a[d];e<this.items.length&&(c[e]=!0)}for(var e=[],f=[],g=Date.now(),k=g+this.elem.tweenDuration,d=0;d<this.items.length;d++){var l=this.items[d];!a||c[d]?(e.push(l.data),f.push(l),l.sprite.opacity||(l.sprite.rebase(g),l.sprite.timestamp=k,l.sprite.opacity=1)):0<l.sprite.opacity&&(l.sprite.rebase(g),l.sprite.timestamp=k,l.sprite.opacity=0)}this.renderUntil(k);\nthis.stats=Yg(e);this.grid.items=f;this.updateGridFaceting();this.updateGridItemPositions()}else requestAnimationFrame(this.filteredDataIndicesChange.bind(this))};a.prototype.pickColorByField=function(){var a=null,c=Infinity,d;for(d in this.stats)if(this.stats.hasOwnProperty(d)){var e=this.stats[d],f=Math.abs(e.uniqueCount-dh.length);1<e.uniqueCount&&f<c&&(a=d,c=f)}isFinite(c)&&a in this.stats&&(this.autoColorBy=!0,this.elem.set(\"colorBy\",a))};a.prototype.pickTextDrawingField=function(){var a=\"\",\nc=-Infinity,d;for(d in this.stats)if(this.stats.hasOwnProperty(d)){var e=this.stats[d],e=e.stringCount+e.stringLengthsCount-e.totalCount;e>c&&(a=d,c=e)}isFinite(c)&&a in this.stats&&this.elem.set(\"imageFieldName\",a)};a.prototype.atlasUrlChange=function(){var a=this,c=this.elem.atlasUrl;c?this.spriteMesh?this.spriteMesh.spriteAtlas.setAtlasUrl(c,this.elem.crossOrigin,function(){for(var b=a.elem.data,c=Date.now(),f=c+a.elem.fadeDuration,g=0;b&&g<b.length;g++)a.spriteMesh.switchTextures(g,c,f);a.renderUntil(f);\na.elem.set(\"imageFieldName\",\"\");a.autoColorBy&&(a.autoColorBy=!1,a.elem.set(\"colorBy\",\"\"))}):requestAnimationFrame(this.atlasUrlChange.bind(this)):this.pickTextDrawingField()};a.prototype.spriteUrlChange=function(){var a=this,c=this.elem.spriteUrl;if(c)if(this.spriteMesh){var d=new Image;void 0!==this.elem.crossOrigin&&(d.crossOrigin=this.elem.crossOrigin);d.onload=function(){var b=a.spriteMesh.defaultTextureCanvas,c=b.getContext(\"2d\");c.clearRect(0,0,b.width,b.height);c.drawImage(d,0,0,b.width,b.height);\na.spriteMesh.defaultTexture.needsUpdate=!0;a.queueRenderScene()};d.src=c}else requestAnimationFrame(this.spriteUrlChange.bind(this))};a.prototype.updateGridStacking=function(){\"stacked\"===this.elem.positionMode&&(this.grid.computeItemPosition=qf(this.elem.verticalFacet?\"middle\":\"bottom\",this.elem.horizontalFacet?\"middle\":\"right\"))};a.prototype.updateGridFaceting=function(){if(this.grid){this.updateGridStacking();var a=this.verticalFacetInfo=this.generateFacetingInfo(this.elem.verticalFacet,this.elem.verticalBuckets,\nthis.elem.verticalBagOfWords,!0);this.grid.verticalFacet=a.facetingFunction;this.grid.verticalKeyCompare=a.keyCompareFunction;a=this.horizontalFacetInfo=this.generateFacetingInfo(this.elem.horizontalFacet,this.elem.horizontalBuckets,this.elem.horizontalBagOfWords,!1);this.grid.horizontalFacet=a.facetingFunction;this.grid.horizontalKeyCompare=a.keyCompareFunction;this.grid.arrange();this.updateCellBackgrounds();this.updateAxes();this.updateLabels();this.fitToViewport()}};a.prototype.updateGridItemPositions=\nfunction(){if(this.grid){this.updateGridStacking();var a=this.grid.cellPadding,c=vf.Tight,d=vf.Uniform,e=!1;if(\"stacked\"===this.elem.positionMode)e=this.grid.verticalGridAlignment!==c||this.grid.horizontalGridAlignment!==c,this.grid.verticalGridAlignment=c,this.grid.horizontalGridAlignment=c,this.grid.cellPadding.top=0,this.grid.cellPadding.left=0,this.grid.cellPadding.right=0,this.grid.cellPadding.bottom=0,this.grid.minCellAspectRatio=0,this.grid.maxCellAspectRatio=Infinity;else{this.elem.verticalPosition?\n(e=this.grid.verticalGridAlignment!==d,this.grid.verticalGridAlignment=d):(e=this.grid.verticalGridAlignment!==c,this.grid.verticalGridAlignment=c);this.elem.horizontalPosition?(e=e||this.grid.horizontalGridAlignment!==d,this.grid.horizontalGridAlignment=d):(e=e||this.grid.horizontalGridAlignment!==c,this.grid.horizontalGridAlignment=c);var f=this.generatePositionFunction(this.elem.horizontalPosition)||of,g=this.generatePositionFunction(this.elem.verticalPosition)||pf;this.grid.computeItemPosition=\nfunction(a,b,c,d){return{x:f(a,b,c,d),y:g(a,b,c,d)}};c=this.elem.verticalPosition?8:0;d=this.elem.horizontalPosition?8:0;e=e||0!==a.top||c!==a.left||0!==a.right||d!==a.bottom;this.grid.cellPadding.top=0;this.grid.cellPadding.right=0;this.grid.cellPadding.left=c;this.grid.cellPadding.bottom=d;this.grid.minCellAspectRatio=1;this.grid.maxCellAspectRatio=2}e?(this.grid.arrange(),this.updateCellBackgrounds()):this.grid.positionItems();this.updateAxes();this.updateLabels();this.fitToViewport()}};a.prototype.getPaletteSource=\nfunction(){switch(this.elem.paletteChoice){case \"warm\":return fh;case \"cool\":return eh;case \"assist\":return gh;default:return dh}};a.prototype.updateScalarPalette=function(){var a=this.elem.colorBy,c=this.stats[a],d=this.grid.items,e=d3.rgb(\"#A52714\"),f=d3.scaleLinear();f.domain([c.numberMin,c.numberMax]).range([\"white\",\"#1C3AA9\"]);for(var g=[],k=0;k<d.length;k++){var l=d[k],l=a in l.data?l.data[a]:NaN,l=\"number\"!==typeof l||isNaN(l)?e:d3.rgb(f(l));g.push(l)}d=this.generateFacetingInfo(a,5,!1,!1).labelingFunction;\ne=d3.scaleLinear();e.domain([0,4]).range([\"white\",\"#1C3AA9\"]);f=[];for(k=4;0<=k;k--)l=d(k),f.push({key:k,color:e(k),content:l});(c.otherCount||c.stringCount||c.totalCount<this.grid.items.length)&&f.push({key:NaN,color:\"#A52714\",content:{label:\"missing\",special:!0}});this.elem.set(\"palette\",f);this.grid.cellItemComparator=function(b,c){if(!(a in b.data||a in c.data))return 0;if(!(a in b.data))return-1;if(!(a in c.data))return 1;b=b.data[a];c=c.data[a];if(b===c)return 0;var d=\"number\"!==typeof b||isNaN(b),\ne=\"number\"!==typeof c||isNaN(c);return d&&e?0:d?-1:e?1:b-c};return g};a.prototype.updateCategoricalPalette=function(a){var b=this.elem.colorBy,d=this.stats[b],e=this.grid.items,f=Object.keys(d.valueHash);f.sort(function(a,b){return d.valueHash[b].count-d.valueHash[a].count});for(var g=Math.min(a.length,f.length),k=f.slice(0,g).reduce(function(a,b,c){a[b]=c;return a},{}),l=d3.rgb(\"#F0F0F0\"),m=a.map(function(a){return d3.rgb(a)}),n=!1,q=[],p=0;p<e.length;p++){var t=Ug(e[p].data[b]),n=n||!(t in k);q.push(m[k[t]]||\nl)}a=a.slice(0,g).map(function(a,b){b=d.valueHash[f[b]].value;return{key:b,color:a,content:{label:b+\"\",special:\"number\"!==typeof b&&\"string\"!==typeof b||b in bh}}});n&&a.push({key:null,color:\"#F0F0F0\",content:{label:\"other\",special:!0}});this.elem.set(\"palette\",a);this.grid.cellItemComparator=function(a,c){if(!(b in a.data||b in c.data))return 0;if(!(b in a.data))return 1;if(!(b in c.data))return-1;a=a.data[b];c=c.data[b];if(a===c)return 0;a=Ug(a);c=Ug(c);return a in k||c in k?a in k?c in k?k[a]-\nk[c]:-1:1:0};return q};a.prototype.updateColors=function(){if(this.grid){var a=this.elem.colorBy;if(a in this.stats){for(var a=this.stats[a],c=this.getPaletteSource(),a=a.uniqueCount>c.length&&a.isNumeric()?this.updateScalarPalette():this.updateCategoricalPalette(c),c=this.grid.items,d=Date.now(),e=d+this.elem.tweenDuration,f=0;f<c.length;f++){var g=c[f],k=a[f];g.sprite.rebase(d);g.sprite.r=k.r;g.sprite.g=k.g;g.sprite.b=k.b;g.sprite.a=180;g.sprite.timestamp=e}this.renderUntil(e);this.updateGridItemPositionsAfterColorChange()}else this.clearColors()}};\na.prototype.updateGridItemPositionsAfterColorChange=function(){\"stacked\"!==this.elem.positionMode&&this.elem.verticalPosition&&this.elem.horizontalPosition||this.updateGridItemPositions()};a.prototype.clearColors=function(){for(var a=this.grid.items,c=Date.now(),d=c+this.elem.tweenDuration,e=0;e<a.length;e++){var f=a[e];f.sprite.rebase(c);f.sprite.r=0;f.sprite.g=0;f.sprite.b=0;f.sprite.a=0;f.sprite.timestamp=d}this.renderUntil(d);this.elem.set(\"palette\",[]);this.grid.cellItemComparator&&(this.grid.cellItemComparator=\nnull,this.updateGridItemPositionsAfterColorChange())};a.prototype.updateImageFieldName=function(){var a=this;if(this.grid){var c=this.grid.items;this.spriteMesh.spriteAtlas.clearQueues();for(var d=Date.now(),e=d+this.elem.fadeDuration,f=0;f<c.length;f++){var g=c[f];0<g.sprite.textureIndex&&g.sprite.switchTextures(d,e)}this.renderUntil(e);var k=this.elem.imageFieldName;if(k in this.stats)for(d=function(b){b=c[b];var d=b.sprite;d.setSpriteImageData({type:\"text\",data:ch(b.data[k]).label},function(){var b=\nDate.now();d.baseTextureTimestamp=b;d.baseTextureIndex=0;d.textureTimestamp=b+a.elem.tweenDuration;d.textureIndex=1;a.renderUntil(d.textureTimestamp)})},f=0;f<c.length;f++)d(f);else this.atlasUrlChange()}};a.prototype.generatePositionFunction=function(a){var b=this.stats[a];if(!b||!b.isNumeric())return null;var d=b.numberMax-b.numberMin;return function(c){return(c.data[a]-b.numberMin)/d}};a.prototype.generateFacetingInfo=function(a,c,d,e){if(!(a in this.stats))return{facetingFunction:function(){return null},\nkeyCompareFunction:function(){return 0},labelingFunction:ch};var b=this.stats[a];if(b.wordTree&&1<b.wordTree.highestLevel&&d)return this.generateBagOfWordsFacetingInfo(a,c,e);if(b.uniqueCount<=c)return{facetingFunction:function(b){return a in b.data?b.data[a]:null},keyCompareFunction:b.isNumeric()?nf:e?mf:lf,labelingFunction:ch};if(b.isNumeric()&&b.numberMax!==b.numberMin)return this.generateNumericFacetingInfo(a,c);d=Object.keys(b.valueHash);d.sort(function(a,c){return b.valueHash[c].count-b.valueHash[a].count});\nvar g=d.slice(0,c).reduce(function(a,b){a[b]=!0;return a},{});return{facetingFunction:function(b){if(!(a in b.data))return null;b=b.data[a];return Ug(b)in g?b:\"\\ufffcOTHER\\ufffc\"},keyCompareFunction:e?mf:lf,labelingFunction:ch}};a.prototype.generateBagOfWordsFacetingInfo=function(a,c,d){var b=this.stats[a].wordTree,f=b.levelHash;return{facetingFunction:function(d){if(!(a in d.data))return null;for(d=b.nodeHash[Ug(d.data[a])];d.parent&&d.level>c;)d=d.parent;return d.level},keyCompareFunction:function(a,\nb){a=f[a];b=f[b];if(void 0===a&&void 0===b)return 0;if(void 0===a)return-1;if(void 0===b)return 1;if(a.nonValueCount&&b.nonValueCount)return 0;if(a.nonValueCount)return-1;if(b.nonValueCount)return 1;b=b.order-a.order;return d?b:-b},labelingFunction:function(a){a=f[+a];if(!a.parent&&!a.commonWords.length)return{label:\"other\",special:!0};if(a.nonValueCount)return{label:\"non-words\",special:!0};for(var b=\" \\u2022 \"+a.commonWords.join(\" \"),d=0;d<a.children.length;d++)if(a.children[d].level>c){b+=\" \\u2026\";\nbreak}for(;a.parent;)a=a.parent,a.commonWords.length&&(b=\" \\u2022 \"+a.commonWords.join(\" \")+\" \"+b);return{label:b}}}};a.prototype.generateNumericFacetingInfo=function(a,c){var b=this,e=this.stats[a],f=e.numberMax-e.numberMin;return{facetingFunction:function(b){if(!(a in b.data))return null;b=b.data[a];return\"number\"!==typeof b?b:isNaN(b)?b:Math.min(Math.floor(c*(b-e.numberMin)/f),c-1)},keyCompareFunction:nf,labelingFunction:function(a){if(\"number\"!==typeof a||isNaN(+a))return ch(a);var d=e.numberMax-\ne.numberMin,f=a/c*d+e.numberMin;a=(1+a)/c*d+e.numberMin;return e.isInteger()?{label:b.formatRange(Math.ceil(f),Math.floor(a))}:{label:b.formatRange(f,a)}}}};a.prototype.formatNumber=function(a){if(null===a)return\"null\";a=parseFloat(a.toPrecision(3));return 1E3<=Math.abs(a)?d3.format(\"s\")(a):\"\"+a};a.prototype.formatRange=function(a,c){return this.formatNumber(a)+\" \\u2014 \"+this.formatNumber(c)};a.prototype.getKeys=function(){var a;if((a=this.elem.data)&&a.length){for(var c={},d=0;d<a.length;d++)if(a[d])for(var e=\nObject.keys(a[d]),f=0;f<e.length;f++)c[e[f]]=!0;a=Object.keys(c)}else a=[];return a.sort()};a.prototype.renderUntil=function(a){this.endTimestamp=Math.max(this.endTimestamp,a);this.queueRenderScene()};a.prototype.resizeHandler=function(){var a=this,c=this.elem.getBoundingClientRect();c.width&&c.height?(this.labelsAndAxesSVG.attr(\"width\",c.width).attr(\"height\",c.height),this.cellBackgroundSVG.attr(\"width\",c.width).attr(\"height\",c.height),this.renderer&&this.renderer.setSize(c.width,c.height),this.camera.right=\nc.width/this.scale,this.camera.bottom=-c.height/this.scale,this.camera.updateProjectionMatrix(),this.queueRenderScene()):requestAnimationFrame(function(){return a.resizeHandler()})};a.prototype.queueRenderScene=function(){var a=this;this.renderQueued||(this.renderQueued=!0,requestAnimationFrame(function(){a.renderQueued&&a.renderScene()}))};a.prototype.renderScene=function(){this.renderQueued=!1;var a=Date.now();this.endTimestamp>a&&this.queueRenderScene();if(this.spriteMesh&&(this.spriteMesh.time=\na,81>+Z.REVISION&&this.spriteMesh.onBeforeRender))this.spriteMesh.onBeforeRender();this.renderer&&this.renderer.render(this.scene,this.camera);this.spriteMesh&&this.spriteMesh.spriteAtlas&&this.spriteMesh.spriteAtlas.postRender()};return a}();\nPolymer({is:\"facets-dive-vis\",behaviors:[Polymer.IronResizableBehavior],properties:{data:{type:Array,value:null,observer:\"_dataChange\"},filteredDataIndices:{type:Array,value:null,observer:\"_filteredDataIndicesChange\"},atlasUrl:{type:String,value:null,observer:\"_atlasUrlChange\"},spriteUrl:{type:String,value:null,observer:\"_spriteUrlChange\"},crossOrigin:{type:String,value:null},keys:{type:Array,value:[],notify:!0,readOnly:!0},stats:{type:Object,value:{},notify:!0,readOnly:!0},scenePadding:{type:Number,\nvalue:8},tweenDuration:{type:Number,value:600},fadeDuration:{type:Number,value:200},spriteImageWidth:{type:Number,value:64},spriteImageHeight:{type:Number,value:64},gridFacetingVerticalLabelColor:{type:String,value:\"#666666\"},gridFacetingHorizontalLabelColor:{type:String,value:\"#dd6622\"},itemPositioningVerticalLabelColor:{type:String,value:\"#2255aa\"},itemPositioningHorizontalLabelColor:{type:String,value:\"#118844\"},verticalFacet:{type:String,value:\"\",observer:\"_updateGridFaceting\"},verticalBuckets:{type:Number,\nvalue:10,observer:\"_updateGridFaceting\"},verticalBagOfWords:{type:Boolean,value:!1,observer:\"_updateGridFaceting\"},horizontalFacet:{type:String,value:\"\",observer:\"_updateGridFaceting\"},horizontalBuckets:{type:Number,value:10,observer:\"_updateGridFaceting\"},horizontalBagOfWords:{type:Boolean,value:!1,observer:\"_updateGridFaceting\"},positionMode:{type:String,value:\"\",observer:\"_updateGridItemPositions\"},verticalPosition:{type:String,value:\"\",observer:\"_updateGridItemPositions\"},horizontalPosition:{type:String,\nvalue:\"\",observer:\"_updateGridItemPositions\"},colorBy:{type:String,value:\"\",observer:\"_updateColors\",notify:!0},imageFieldName:{type:String,value:\"\",observer:\"_updateImageFieldName\",notify:!0},palette:{type:Array,value:[],notify:!0},paletteChoice:{type:String,value:\"standard\",observer:\"_updateColors\"},selectedData:{type:Array,value:[],notify:!0}},listeners:{\"iron-resize\":\"_onIronResize\"},created:function(){this._backing=new jh(this)},ready:function(){this._backing.ready()},_dataChange:function(){this._backing.dataChange();\nthis._setKeys(this._backing.getKeys());this._setStats(this._backing.stats)},_filteredDataIndicesChange:function(){this._backing.filteredDataIndicesChange();this._setKeys(this._backing.getKeys());this._setStats(this._backing.stats)},_atlasUrlChange:function(){this._backing.atlasUrlChange()},_spriteUrlChange:function(){this._backing.spriteUrlChange()},_updateGridFaceting:function(){this._backing.updateGridFaceting()},_updateGridItemPositions:function(){this._backing.updateGridItemPositions()},_updateColors:function(){this._backing.updateColors()},\n_updateImageFieldName:function(){this._backing.updateImageFieldName()},_onIronResize:function(){this._backing.resizeHandler()},fitToViewport:function(){this._backing.fitToViewport()},zoomIn:function(){this._backing.zoomIn()},zoomOut:function(){this._backing.zoomOut()}});\n</script>\n\n\n<dom-module id=\"facets-dive-controls\">\n  <template>\n    <style>\n      :host {\n        @apply(--paper-font-common-base);\n\n        box-sizing: border-box;\n        display: flex;\n        flex-flow: column;\n        height: 100%;\n        overflow: visible;\n        width: 100%;\n      }\n\n      .layout-row {\n        display: flex;\n      }\n\n      /**\n       * Menus.\n       */\n      .menu {\n        box-sizing: border-box;\n        flex: 1;\n        overflow-y: scroll;\n      }\n      .menu-trigger {\n        border-bottom: 1px solid #ccc;\n        cursor: pointer;\n      }\n      paper-menu {\n        font-size: 14px;\n        margin: 6px;\n        padding: 0;\n        --paper-menu-focused-item: {\n          color: rgba(0,0,0,0);\n        };\n      }\n      paper-submenu .menu-trigger {\n        --paper-item: {\n          color: #44706e;\n        };\n        --paper-item-selected: {\n          color: #183232;\n        };\n      }\n      paper-submenu .menu-trigger-text {\n        font-weight: normal;\n      }\n      paper-menu .menu-content {\n        margin: 0 8px;\n        padding: 0 0 24px 0;\n      }\n      paper-submenu iron-icon {\n        margin: 16px 8px 0 0;\n      }\n      .expand-button {\n        color: #9b9b9b;\n        --paper-icon-button-ink-color: #9b9b9b;\n      }\n      paper-menu paper-checkbox {\n        display: block;\n        font-weight: normal;\n        font-size: 12.5px;\n        text-align: center;\n      }\n\n      paper-item {\n        padding: 0 14px;\n        --paper-item-min-height: 36px;\n      }\n      paper-dropdown-menu paper-item {\n        border-bottom: 1px solid #ccc;\n      }\n\n      #verticalFacet {\n        --paper-input-container-input: {\n          color: var(--grid-faceting-vertical-label-color);\n        };\n      }\n      #horizontalFacet {\n        --paper-input-container-input: {\n          color: var(--grid-faceting-horizontal-label-color);\n        };\n      }\n      #verticalPosition {\n        --paper-input-container-input: {\n          color: var(--item-positioning-vertical-label-color);\n        };\n      }\n      #horizontalPosition {\n        --paper-input-container-input: {\n          color: var(--item-positioning-horizontal-label-color);\n        };\n      }\n\n      /**\n       * Legend.\n       */\n      .legend {\n        background: #fefefe;\n        border-top: 6px solid #a09f9f;\n        box-sizing: border-box;\n        margin: 8px 0 0 0;\n        max-height: 50%;\n        overflow-y: scroll;\n        padding: 16px 8px 8px 8px;\n      }\n      .legend .layout-row {\n        margin: 0;\n      }\n      .legend .layout-row span {\n        margin: 2px 0 0 8px;\n      }\n\n      /**\n       * Legend table shim. Polymer's dom-repeat feature has a known issue in\n       * which it doesn't work with <tr> elements inside of a <table>. So\n       * instead, we use CSS with classed divs to achieve table behavior.\n       */\n      .legend-table {\n        display: table;\n        margin-left: 2px;\n      }\n      .legend-row {\n        display: table-row;\n      }\n      .legend-cell {\n        display: table-cell;\n      }\n\n      /**\n       * Color legend.\n       */\n      .legend .color {\n        font-size: 14px;\n      }\n      .legend .color iron-icon {\n        --iron-icon-width: 16px;\n        --iron-icon-height: 16px;\n        margin: 0 2px;\n      }\n      .legend .color iron-icon[fill=\"#ffffff\"] {\n        background: #dddddd;\n      }\n      .legend .color span {\n        margin: 0;\n      }\n      .legend .special {\n        font-style: italic;\n      }\n\n      .legend h2 {\n        @apply(--paper-font-subhead);\n        color: #4f423e;\n        font-weight: bold;\n        line-height: 1;\n        margin: 0;\n      }\n      .legend .color-by-field {\n        color: #968e8c;\n        display: block;\n        font-size: 12.5px;\n        font-weight: normal;\n        margin: 2px 0 4px 20px;\n      }\n\n      .vertical-facet {\n        color: var(--grid-faceting-vertical-label-color);\n      }\n      .vertical-facet iron-icon {\n        fill: var(--grid-faceting-vertical-label-color);\n        transform: rotate(-90deg) scale(0.9, 1.1);\n      }\n      .horizontal-facet {\n        color: var(--grid-faceting-horizontal-label-color);\n      }\n      .horizontal-facet iron-icon {\n        fill: var(--grid-faceting-horizontal-label-color);\n      }\n      .vertical-position {\n        color: var(--item-positioning-vertical-label-color);\n      }\n      .vertical-position iron-icon {\n        fill: var(--item-positioning-vertical-label-color);\n        transform: rotate(-90deg);\n      }\n      .horizontal-position {\n        color: var(--item-positioning-horizontal-label-color);\n      }\n      .horizontal-position iron-icon {\n        fill: var(--item-positioning-horizontal-label-color);\n      }\n    </style>\n\n    <div class=\"menu\">\n\n      <paper-menu multi=\"true\">\n\n        <paper-submenu>\n\n          <paper-item class=\"menu-trigger\">\n            <span class=\"menu-trigger-text\">Faceting</span>\n            <span style=\"flex:1\"></span>\n            <paper-icon-button icon=\"image:view-comfy\" class=\"expand-button\">\n            </paper-icon-button>\n          </paper-item>\n\n          <paper-menu class=\"menu-content\" opened=\"{{_anyFacet(verticalFacet, horizontalFacet)}}\">\n\n            <div class=\"layout-row vertical-facet\">\n              <iron-icon icon=\"av:equalizer\"></iron-icon>\n              <paper-dropdown-menu id=\"verticalFacet\" label=\"Row-Based Faceting\" class=\"facet-selector\">\n                <paper-listbox class=\"dropdown-content\" selected=\"{{verticalFacet}}\" attr-for-selected=\"value\">\n                  <paper-item value=\"\">&lt;NONE&gt;</paper-item>\n                  <template is=\"dom-repeat\" items=\"[[keys]]\">\n                    <paper-item value=\"[[item]]\">[[_breakUpAndTruncate(item)]]</paper-item>\n                  </template>\n                </paper-listbox>\n              </paper-dropdown-menu>\n            </div>\n\n            <template is=\"dom-if\" if=\"[[verticalFacet]]\">\n              <paper-slider pin snaps editable min=\"1\" max=\"[[_maxBuckets(verticalFacet,verticalBagOfWords)]]\" step=\"1\" value=\"{{verticalBuckets}}\" immediate-value=\"{{verticalBuckets}}\"></paper-slider>\n            </template>\n\n            <template is=\"dom-if\" if=\"[[_hasWordTree(verticalFacet)]]\">\n              <paper-checkbox checked=\"{{verticalBagOfWords}}\">\n                Bag of words\n              </paper-checkbox>\n            </template>\n\n            <div class=\"layout-row horizontal-facet\">\n              <iron-icon icon=\"av:equalizer\"></iron-icon>\n              <paper-dropdown-menu id=\"horizontalFacet\" label=\"Column-Based Faceting\" class=\"facet-selector\">\n                <paper-listbox class=\"dropdown-content\" selected=\"{{horizontalFacet}}\" attr-for-selected=\"value\">\n                  <paper-item value=\"\">&lt;NONE&gt;</paper-item>\n                  <template is=\"dom-repeat\" items=\"[[keys]]\">\n                    <paper-item value=\"[[item]]\">[[_breakUpAndTruncate(item)]]</paper-item>\n                  </template>\n                </paper-listbox>\n              </paper-dropdown-menu>\n            </div>\n\n            <template is=\"dom-if\" if=\"[[horizontalFacet]]\">\n              <paper-slider pin snaps editable min=\"1\" max=\"[[_maxBuckets(horizontalFacet,horizontalBagOfWords)]]\" step=\"1\" value=\"{{horizontalBuckets}}\" immediate-value=\"{{horizontalBuckets}}\"></paper-slider>\n            </template>\n\n            <template is=\"dom-if\" if=\"[[_hasWordTree(horizontalFacet)]]\">\n              <paper-checkbox checked=\"{{horizontalBagOfWords}}\">\n                Bag of words\n              </paper-checkbox>\n            </template>\n\n          </paper-menu>\n\n        </paper-submenu>\n\n      </paper-menu>\n\n      <paper-menu multi=\"true\">\n\n        <paper-submenu>\n\n          <paper-item class=\"menu-trigger\">\n            <span class=\"menu-trigger-text\">Positioning</span>\n            <span style=\"flex:1\"></span>\n            <paper-icon-button icon=\"image:grain\" class=\"expand-button\">\n            </paper-icon-button>\n          </paper-item>\n\n          <paper-menu class=\"menu-content\" opened=\"{{_anyPosition(verticalPosition,horizontalPosition,positionMode)}}\">\n\n            <paper-radio-group selected=\"{{positionMode}}\">\n              <paper-radio-button name=\"stacked\">Stacked</paper-radio-button>\n              <paper-radio-button name=\"scatter\">Scatter</paper-radio-button>\n            </paper-radio-group>\n\n            <template is=\"dom-if\" if=\"[[_isModeScatter(positionMode)]]\">\n\n              <div class=\"layout-row vertical-position\">\n                <iron-icon icon=\"icons:trending-flat\"></iron-icon>\n                <paper-dropdown-menu id=\"verticalPosition\" label=\"Vertical Position\" class=\"position-selector\">\n                  <paper-listbox class=\"dropdown-content\" selected=\"{{verticalPosition}}\" attr-for-selected=\"value\">\n                    <paper-item value=\"\">&lt;DEFAULT&gt;</paper-item>\n                    <template is=\"dom-repeat\" items=\"[[keys]]\" filter=\"_isKeyNumeric\">\n                      <paper-item value=\"[[item]]\">[[item]]</paper-item>\n                    </template>\n                  </paper-listbox>\n                </paper-dropdown-menu>\n              </div>\n\n              <div class=\"layout-row horizontal-position\">\n                <iron-icon icon=\"icons:trending-flat\"></iron-icon>\n                <paper-dropdown-menu id=\"horizontalPosition\" label=\"Horizontal Position\" class=\"position-selector\">\n                  <paper-listbox class=\"dropdown-content\" selected=\"{{horizontalPosition}}\" attr-for-selected=\"value\">\n                    <paper-item value=\"\">&lt;DEFAULT&gt;</paper-item>\n                    <template is=\"dom-repeat\" items=\"[[keys]]\" filter=\"_isKeyNumeric\">\n                      <paper-item value=\"[[item]]\">[[item]]</paper-item>\n                    </template>\n                  </paper-listbox>\n                </paper-dropdown-menu>\n              </div>\n\n            </template>\n\n          </paper-menu>\n\n        </paper-submenu>\n\n      </paper-menu>\n\n      <paper-menu multi=\"true\">\n\n        <paper-submenu>\n\n          <paper-item class=\"menu-trigger\">\n            <span class=\"menu-trigger-text\">Color</span>\n            <span style=\"flex:1\"></span>\n            <paper-icon-button icon=\"image:palette\" class=\"expand-button\">\n            </paper-icon-button>\n          </paper-item>\n\n          <paper-menu class=\"menu-content\" opened=\"{{_anyColor(colorBy)}}\">\n\n            <paper-dropdown-menu id=\"colorBy\" label=\"Color By\">\n              <paper-listbox class=\"dropdown-content\" selected=\"{{colorBy}}\" attr-for-selected=\"value\">\n                <paper-item value=\"\">&lt;NONE&gt;</paper-item>\n                <template is=\"dom-repeat\" items=\"[[keys]]\">\n                  <paper-item value=\"[[item]]\">[[item]]</paper-item>\n                </template>\n              </paper-listbox>\n            </paper-dropdown-menu>\n\n            <template is=\"dom-if\" if=\"{{_isKeyCategorical(colorBy)}}\">\n              <paper-dropdown-menu id=\"paletteChoice\" label=\"Palette\">\n                <paper-listbox class=\"dropdown-content\" selected=\"{{paletteChoice}}\" attr-for-selected=\"value\">\n                  <paper-item value=\"standard\">standard</paper-item>\n                  <paper-item value=\"warm\">warm</paper-item>\n                  <paper-item value=\"cool\">cool</paper-item>\n                  <paper-item value=\"assist\">assist</paper-item>\n                </paper-listbox>\n              </paper-dropdown-menu>\n            </template>\n\n          </paper-menu>\n\n        </paper-submenu>\n\n      </paper-menu>\n\n      <paper-menu multi=\"true\">\n\n        <paper-submenu>\n\n          <paper-item class=\"menu-trigger\">\n            <span class=\"menu-trigger-text\">Display</span>\n            <span style=\"flex:1\"></span>\n            <paper-icon-button icon=\"image:image\" class=\"expand-button\">\n            </paper-icon-button>\n          </paper-item>\n\n          <paper-menu class=\"menu-content\" opened=\"\">\n\n            <paper-dropdown-menu id=\"imageFieldName\" label=\"Show for each Datapoint\">\n              <paper-listbox class=\"dropdown-content\" selected=\"{{imageFieldName}}\" attr-for-selected=\"value\">\n                <paper-item value=\"\">\n                  [[_getImageFieldNameDefaultLabel(atlasUrl)]]\n                </paper-item>\n                <template is=\"dom-repeat\" items=\"[[keys]]\">\n                  <paper-item value=\"[[item]]\">[[item]]</paper-item>\n                </template>\n              </paper-listbox>\n            </paper-dropdown-menu>\n\n          </paper-menu>\n\n        </paper-submenu>\n\n      </paper-menu>\n\n    </div>\n\n    <template is=\"dom-if\" if=\"{{_anySettings(verticalFacet,horizontalFacet,verticalPosition,horizontalPosition,colorBy,palette)}}\">\n\n      <div class=\"legend\">\n\n        <template is=\"dom-if\" if=\"{{_anyFacetOrPosition(verticalFacet, horizontalFacet, verticalPosition, horizontalPosition)}}\">\n\n          <h2>Legend</h2>\n\n          <template is=\"dom-if\" if=\"[[verticalFacet]]\">\n            <div class=\"layout-row vertical-facet\">\n              <iron-icon icon=\"av:equalizer\"></iron-icon>\n              <span>[[_breakUpAndTruncate(verticalFacet)]]</span>\n            </div>\n          </template>\n          <template is=\"dom-if\" if=\"[[horizontalFacet]]\">\n            <div class=\"layout-row horizontal-facet\">\n              <iron-icon icon=\"av:equalizer\"></iron-icon>\n              <span>[[_breakUpAndTruncate(horizontalFacet)]]</span>\n            </div>\n          </template>\n          <template is=\"dom-if\" if=\"[[_isModeScatter(positionMode)]]\">\n            <template is=\"dom-if\" if=\"[[verticalPosition]]\">\n              <div class=\"layout-row vertical-position\">\n                <iron-icon icon=\"icons:trending-flat\"></iron-icon>\n                <span>[[_breakUpAndTruncate(verticalPosition)]]</span>\n              </div>\n            </template>\n            <template is=\"dom-if\" if=\"[[horizontalPosition]]\">\n              <div class=\"layout-row horizontal-position\">\n                <iron-icon icon=\"icons:trending-flat\"></iron-icon>\n                <span>[[_breakUpAndTruncate(horizontalPosition)]]</span>\n              </div>\n            </template>\n          </template>\n\n        </template>\n\n        <template is=\"dom-if\" if=\"{{_anyColor(colorBy, palette)}}\">\n\n          <h2>Colors</h2>\n          <span class=\"color-by-field\">\n            by [[_breakUpAndTruncate(colorBy)]]\n            <paper-tooltip position=\"top\">[[colorBy]]</paper-tooltip>\n          </span>\n\n          <div class=\"legend-table\">\n          <template is=\"dom-repeat\" items=\"[[palette]]\">\n            <div class=\"legend-row color\">\n              <div class=\"legend-cell\">\n              <iron-icon icon=\"av:fiber-manual-record\" fill$=\"[[item.color]]\" style$=\"fill:[[item.color]]\"></iron-icon>\n              </div>\n              <div class=\"legend-cell\">\n                <span class$=\"[[_specialClass(item.content.special)]]\">\n                  [[_breakUpAndTruncate(item.content.label)]]\n                </span>\n                <paper-tooltip position=\"top\">[[item.content.label]]</paper-tooltip>\n              </div>\n            </div>\n          </template>\n          </div>\n\n        </template>\n\n      </div>\n\n    </template>\n\n  </template>\n</dom-module>\n\n<script>//~~WEBPATH~~/facets-dive/components/facets-dive-controls/facets-dive-controls.js\nPolymer({is:\"facets-dive-controls\",properties:{atlasUrl:{type:String,value:\"\"},keys:{type:Array,value:[]},stats:{type:Object,value:{}},verticalFacet:{type:String,value:\"\",notify:!0},verticalBuckets:{type:Number,value:10,notify:!0},verticalBagOfWords:{type:Boolean,value:!1,notify:!0},horizontalFacet:{type:String,value:\"\",notify:!0},horizontalBuckets:{type:Number,value:10,notify:!0},horizontalBagOfWords:{type:Boolean,value:!1,notify:!0},positionMode:{type:String,value:\"stacked\",notify:!0},verticalPosition:{type:String,\nvalue:\"\",notify:!0},horizontalPosition:{type:String,value:\"\",notify:!0},colorBy:{type:String,value:\"\",notify:!0},imageFieldName:{type:String,value:\"\",notify:!0},palette:{type:Array,value:[]},paletteChoice:{type:String,value:\"standard\",notify:!0},gridFacetingVerticalLabelColor:{type:String,value:\"#666666\",observer:\"_updateCSSVars\"},gridFacetingHorizontalLabelColor:{type:String,value:\"#dd6622\",observer:\"_updateCSSVars\"},itemPositioningVerticalLabelColor:{type:String,value:\"#2255aa\",observer:\"_updateCSSVars\"},\nitemPositioningHorizontalLabelColor:{type:String,value:\"#118844\",observer:\"_updateCSSVars\"}},_getImageFieldNameDefaultLabel:function(a){return a?\"\\x3cIMAGE\\x3e\":\"\\x3cDEFAULT\\x3e\"},_isModeScatter:function(a){return\"scatter\"===a},_isKeyNumeric:function(a){return this.stats&&a in this.stats&&this.stats[a].isNumeric()},_isKeyCategorical:function(a){return this.stats&&a in this.stats&&!this.stats[a].isNumeric()},_updateCSSVars:function(){this.customStyle[\"--grid-faceting-vertical-label-color\"]=this.gridFacetingVerticalLabelColor;\nthis.customStyle[\"--grid-faceting-horizontal-label-color\"]=this.gridFacetingHorizontalLabelColor;this.customStyle[\"--item-positioning-vertical-label-color\"]=this.itemPositioningVerticalLabelColor;this.customStyle[\"--item-positioning-horizontal-label-color\"]=this.itemPositioningHorizontalLabelColor;this.updateStyles()},_breakUp:function(a){return(\"\"+a).replace(/([\\W_])/g,\"$1\\u200b\")},_breakUpAndTruncate:function(a){return Zg(\"\"+a).replace(/([\\W_])/g,\"$1\\u200b\")},_specialClass:function(a){return a?\n\"special\":\"\"},_maxBuckets:function(a,b){var c=this.stats[a];return c?b&&this._hasWordTree(a)?Math.min(100,c.wordTree.highestLevel):Math.min(100,c.uniqueCount+1):100},_hasWordTree:function(a){a=this.stats[a];return!!a&&!!a.wordTree&&1<a.wordTree.highestLevel},_anyFacet:function(){for(var a=0;a<arguments.length;a++);return!(!this.verticalFacet&&!this.horizontalFacet)},_anyPosition:function(){for(var a=0;a<arguments.length;a++);return!(!this.verticalPosition&&!this.horizontalPosition&&\"stacked\"===this.positionMode)},\n_anyFacetOrPosition:function(){for(var a=0;a<arguments.length;a++);return this._anyFacet()||this._anyPosition()},_anyColor:function(){return!!(this.colorBy&&this.palette&&this.palette.length)},_anySettings:function(){return this._anyFacet()||this._anyPosition()||this._anyColor()}});\n</script>\n\n\n\n\n\n\n\n\n<dom-module id=\"iron-image\">\n  <template>\n    <style>\n      :host {\n        display: inline-block;\n        overflow: hidden;\n        position: relative;\n      }\n\n      #baseURIAnchor {\n        display: none;\n      }\n\n      #sizedImgDiv {\n        position: absolute;\n        top: 0px;\n        right: 0px;\n        bottom: 0px;\n        left: 0px;\n\n        display: none;\n      }\n\n      #img {\n        display: block;\n        width: var(--iron-image-width, auto);\n        height: var(--iron-image-height, auto);\n      }\n\n      :host([sizing]) #sizedImgDiv {\n        display: block;\n      }\n\n      :host([sizing]) #img {\n        display: none;\n      }\n\n      #placeholder {\n        position: absolute;\n        top: 0px;\n        right: 0px;\n        bottom: 0px;\n        left: 0px;\n\n        background-color: inherit;\n        opacity: 1;\n\n        @apply --iron-image-placeholder;\n      }\n\n      #placeholder.faded-out {\n        transition: opacity 0.5s linear;\n        opacity: 0;\n      }\n    </style>\n\n    <a id=\"baseURIAnchor\" href=\"#\"></a>\n    <div id=\"sizedImgDiv\" role=\"img\" hidden$=\"[[_computeImgDivHidden(sizing)]]\" aria-hidden$=\"[[_computeImgDivARIAHidden(alt)]]\" aria-label$=\"[[_computeImgDivARIALabel(alt, src)]]\"></div>\n    <img id=\"img\" alt$=\"[[alt]]\" hidden$=\"[[_computeImgHidden(sizing)]]\" on-load=\"_imgOnLoad\" on-error=\"_imgOnError\">\n    <div id=\"placeholder\" hidden$=\"[[_computePlaceholderHidden(preload, fade, loading, loaded)]]\" class$=\"[[_computePlaceholderClassName(preload, fade, loading, loaded)]]\"></div>\n  </template>\n\n  <script>//~~WEBPATH~~/iron-image/iron-image.html.js\nPolymer({is:\"iron-image\",properties:{src:{type:String,value:\"\"},alt:{type:String,value:null},preventLoad:{type:Boolean,value:!1},sizing:{type:String,value:null,reflectToAttribute:!0},position:{type:String,value:\"center\"},preload:{type:Boolean,value:!1},placeholder:{type:String,value:null,observer:\"_placeholderChanged\"},fade:{type:Boolean,value:!1},loaded:{notify:!0,readOnly:!0,type:Boolean,value:!1},loading:{notify:!0,readOnly:!0,type:Boolean,value:!1},error:{notify:!0,readOnly:!0,type:Boolean,value:!1},\nwidth:{observer:\"_widthChanged\",type:Number,value:null},height:{observer:\"_heightChanged\",type:Number,value:null}},observers:[\"_transformChanged(sizing, position)\",\"_loadStateObserver(src, preventLoad)\"],created:function(){this._resolvedSrc=\"\"},_imgOnLoad:function(){this.$.img.src===this._resolveSrc(this.src)&&(this._setLoading(!1),this._setLoaded(!0),this._setError(!1))},_imgOnError:function(){this.$.img.src===this._resolveSrc(this.src)&&(this.$.img.removeAttribute(\"src\"),this.$.sizedImgDiv.style.backgroundImage=\n\"\",this._setLoading(!1),this._setLoaded(!1),this._setError(!0))},_computePlaceholderHidden:function(){return!this.preload||!this.fade&&!this.loading&&this.loaded},_computePlaceholderClassName:function(){return this.preload&&this.fade&&!this.loading&&this.loaded?\"faded-out\":\"\"},_computeImgDivHidden:function(){return!this.sizing},_computeImgDivARIAHidden:function(){return\"\"===this.alt?\"true\":void 0},_computeImgDivARIALabel:function(){return null!==this.alt?this.alt:\"\"===this.src?\"\":this._resolveSrc(this.src).replace(/[?|#].*/g,\n\"\").split(\"/\").pop()},_computeImgHidden:function(){return!!this.sizing},_widthChanged:function(){this.style.width=isNaN(this.width)?this.width:this.width+\"px\"},_heightChanged:function(){this.style.height=isNaN(this.height)?this.height:this.height+\"px\"},_loadStateObserver:function(a,b){var c=this._resolveSrc(a);c!==this._resolvedSrc&&(this._resolvedSrc=c,this.$.img.removeAttribute(\"src\"),this.$.sizedImgDiv.style.backgroundImage=\"\",\"\"===a||b?this._setLoading(!1):(this.$.img.src=this._resolvedSrc,this.$.sizedImgDiv.style.backgroundImage=\n'url(\"'+this._resolvedSrc+'\")',this._setLoading(!0)),this._setLoaded(!1),this._setError(!1))},_placeholderChanged:function(){this.$.placeholder.style.backgroundImage=this.placeholder?'url(\"'+this.placeholder+'\")':\"\"},_transformChanged:function(){var a=this.$.sizedImgDiv.style,b=this.$.placeholder.style;a.backgroundSize=b.backgroundSize=this.sizing;a.backgroundPosition=b.backgroundPosition=this.sizing?this.position:\"\";a.backgroundRepeat=b.backgroundRepeat=this.sizing?\"no-repeat\":\"\"},_resolveSrc:function(a){a=\nPolymer.ResolveUrl.resolveUrl(a,this.$.baseURIAnchor.href);\"/\"===a[0]&&(a=(location.origin||location.protocol+\"//\"+location.host)+a);return a}});\n</script>\n</dom-module>\n\n\n\n\n\n\n<dom-module id=\"paper-material-styles\">\n  <template>\n    <style>\n      :host, html {\n        --paper-material: {\n          display: block;\n          position: relative;\n        };\n        --paper-material-elevation-1: {\n          @apply --shadow-elevation-2dp;\n        };\n        --paper-material-elevation-2: {\n          @apply --shadow-elevation-4dp;\n        };\n        --paper-material-elevation-3: {\n          @apply --shadow-elevation-6dp;\n        };\n        --paper-material-elevation-4: {\n          @apply --shadow-elevation-8dp;\n        };\n        --paper-material-elevation-5: {\n          @apply --shadow-elevation-16dp;\n        };\n      }\n      :host(.paper-material), .paper-material {\n        @apply --paper-material;\n      }\n      :host(.paper-material[elevation=\"1\"]), .paper-material[elevation=\"1\"] {\n        @apply --paper-material-elevation-1;\n      }\n      :host(.paper-material[elevation=\"2\"]), .paper-material[elevation=\"2\"] {\n        @apply --paper-material-elevation-2;\n      }\n      :host(.paper-material[elevation=\"3\"]), .paper-material[elevation=\"3\"] {\n        @apply --paper-material-elevation-3;\n      }\n      :host(.paper-material[elevation=\"4\"]), .paper-material[elevation=\"4\"] {\n        @apply --paper-material-elevation-4;\n      }\n      :host(.paper-material[elevation=\"5\"]), .paper-material[elevation=\"5\"] {\n        @apply --paper-material-elevation-5;\n      }\n    </style>\n  </template>\n</dom-module>\n\n\n\n\n\n<dom-module id=\"paper-card\">\n  <template>\n    <style include=\"paper-material-styles\">\n      :host {\n        display: inline-block;\n        position: relative;\n        box-sizing: border-box;\n        background-color: var(--paper-card-background-color, var(--primary-background-color));\n        border-radius: 2px;\n\n        @apply --paper-font-common-base;\n        @apply --paper-card;\n      }\n\n      /* IE 10 support for HTML5 hidden attr */\n      [hidden] {\n        display: none !important;\n      }\n\n      .header {\n        position: relative;\n        border-top-left-radius: inherit;\n        border-top-right-radius: inherit;\n        overflow: hidden;\n\n        @apply --paper-card-header;\n      }\n\n      .header iron-image {\n        display: block;\n        width: 100%;\n        --iron-image-width: 100%;\n        pointer-events: none;\n\n        @apply --paper-card-header-image;\n      }\n\n      .header .title-text {\n        padding: 16px;\n        font-size: 24px;\n        font-weight: 400;\n        color: var(--paper-card-header-color, #000);\n\n        @apply --paper-card-header-text;\n      }\n\n      .header .title-text.over-image {\n        position: absolute;\n        bottom: 0px;\n\n        @apply --paper-card-header-image-text;\n      }\n\n      :host ::slotted(.card-content) {\n        padding: 16px;\n        position:relative;\n\n        @apply --paper-card-content;\n      }\n\n      :host ::slotted(.card-actions) {\n        border-top: 1px solid #e8e8e8;\n        padding: 5px 16px;\n        position:relative;\n\n        @apply --paper-card-actions;\n      }\n\n      :host([elevation=\"1\"]) {\n        @apply --paper-material-elevation-1;\n      }\n\n      :host([elevation=\"2\"]) {\n        @apply --paper-material-elevation-2;\n      }\n\n      :host([elevation=\"3\"]) {\n        @apply --paper-material-elevation-3;\n      }\n\n      :host([elevation=\"4\"]) {\n        @apply --paper-material-elevation-4;\n      }\n\n      :host([elevation=\"5\"]) {\n        @apply --paper-material-elevation-5;\n      }\n    </style>\n\n    <div class=\"header\">\n      <iron-image hidden$=\"[[!image]]\" aria-hidden$=\"[[_isHidden(image)]]\" src=\"[[image]]\" alt=\"[[alt]]\" placeholder=\"[[placeholderImage]]\" preload=\"[[preloadImage]]\" fade=\"[[fadeImage]]\"></iron-image>\n      <div hidden$=\"[[!heading]]\" class$=\"title-text [[_computeHeadingClass(image)]]\">[[heading]]</div>\n    </div>\n\n    <slot></slot>\n  </template>\n\n  <script>//~~WEBPATH~~/paper-card/paper-card.html.js\nPolymer({is:\"paper-card\",properties:{heading:{type:String,value:\"\",observer:\"_headingChanged\"},image:{type:String,value:\"\"},alt:{type:String},preloadImage:{type:Boolean,value:!1},fadeImage:{type:Boolean,value:!1},placeholderImage:{type:String,value:null},elevation:{type:Number,value:1,reflectToAttribute:!0},animatedShadow:{type:Boolean,value:!1},animated:{type:Boolean,reflectToAttribute:!0,readOnly:!0,computed:\"_computeAnimated(animatedShadow)\"}},_isHidden:function(a){return a?\"false\":\"true\"},_headingChanged:function(a){var b=\nthis.getAttribute(\"heading\"),c=this.getAttribute(\"aria-label\");\"string\"===typeof c&&c!==b||this.setAttribute(\"aria-label\",a)},_computeHeadingClass:function(a){return a?\" over-image\":\"\"},_computeAnimated:function(a){return a}});\n</script>\n</dom-module>\n\n\n<script>//~~WEBPATH~~/iron-flex-layout/classes/iron-shadow-flex-layout.html.js\nconsole.warn(\"This file is deprecated. Please use `iron-flex-layout/iron-flex-layout-classes.html`, and one of the specific dom-modules instead\");\n</script>\n\n<style>\n\n  /*******************************\n            Flex Layout\n  *******************************/\n\n  html /deep/ .layout.horizontal,\n  html /deep/ .layout.horizontal-reverse,\n  html /deep/ .layout.vertical,\n  html /deep/ .layout.vertical-reverse {\n    display: -ms-flexbox;\n    display: -webkit-flex;\n    display: flex;\n  }\n\n  html /deep/ .layout.inline {\n    display: -ms-inline-flexbox;\n    display: -webkit-inline-flex;\n    display: inline-flex;\n  }\n\n  html /deep/ .layout.horizontal {\n    -ms-flex-direction: row;\n    -webkit-flex-direction: row;\n    flex-direction: row;\n  }\n\n  html /deep/ .layout.horizontal-reverse {\n    -ms-flex-direction: row-reverse;\n    -webkit-flex-direction: row-reverse;\n    flex-direction: row-reverse;\n  }\n\n  html /deep/ .layout.vertical {\n    -ms-flex-direction: column;\n    -webkit-flex-direction: column;\n    flex-direction: column;\n  }\n\n  html /deep/ .layout.vertical-reverse {\n    -ms-flex-direction: column-reverse;\n    -webkit-flex-direction: column-reverse;\n    flex-direction: column-reverse;\n  }\n\n  html /deep/ .layout.wrap {\n    -ms-flex-wrap: wrap;\n    -webkit-flex-wrap: wrap;\n    flex-wrap: wrap;\n  }\n\n  html /deep/ .layout.wrap-reverse {\n    -ms-flex-wrap: wrap-reverse;\n    -webkit-flex-wrap: wrap-reverse;\n    flex-wrap: wrap-reverse;\n  }\n\n  html /deep/ .flex-auto {\n    -ms-flex: 1 1 auto;\n    -webkit-flex: 1 1 auto;\n    flex: 1 1 auto;\n  }\n\n  html /deep/ .flex-none {\n    -ms-flex: none;\n    -webkit-flex: none;\n    flex: none;\n  }\n\n  html /deep/ .flex,\n  html /deep/ .flex-1 {\n    -ms-flex: 1;\n    -webkit-flex: 1;\n    flex: 1;\n  }\n\n  html /deep/ .flex-2 {\n    -ms-flex: 2;\n    -webkit-flex: 2;\n    flex: 2;\n  }\n\n  html /deep/ .flex-3 {\n    -ms-flex: 3;\n    -webkit-flex: 3;\n    flex: 3;\n  }\n\n  html /deep/ .flex-4 {\n    -ms-flex: 4;\n    -webkit-flex: 4;\n    flex: 4;\n  }\n\n  html /deep/ .flex-5 {\n    -ms-flex: 5;\n    -webkit-flex: 5;\n    flex: 5;\n  }\n\n  html /deep/ .flex-6 {\n    -ms-flex: 6;\n    -webkit-flex: 6;\n    flex: 6;\n  }\n\n  html /deep/ .flex-7 {\n    -ms-flex: 7;\n    -webkit-flex: 7;\n    flex: 7;\n  }\n\n  html /deep/ .flex-8 {\n    -ms-flex: 8;\n    -webkit-flex: 8;\n    flex: 8;\n  }\n\n  html /deep/ .flex-9 {\n    -ms-flex: 9;\n    -webkit-flex: 9;\n    flex: 9;\n  }\n\n  html /deep/ .flex-10 {\n    -ms-flex: 10;\n    -webkit-flex: 10;\n    flex: 10;\n  }\n\n  html /deep/ .flex-11 {\n    -ms-flex: 11;\n    -webkit-flex: 11;\n    flex: 11;\n  }\n\n  html /deep/ .flex-12 {\n    -ms-flex: 12;\n    -webkit-flex: 12;\n    flex: 12;\n  }\n\n  /* alignment in cross axis */\n\n  html /deep/ .layout.start {\n    -ms-flex-align: start;\n    -webkit-align-items: flex-start;\n    align-items: flex-start;\n  }\n\n  html /deep/ .layout.center,\n  html /deep/ .layout.center-center {\n    -ms-flex-align: center;\n    -webkit-align-items: center;\n    align-items: center;\n  }\n\n  html /deep/ .layout.end {\n    -ms-flex-align: end;\n    -webkit-align-items: flex-end;\n    align-items: flex-end;\n  }\n\n  /* alignment in main axis */\n\n  html /deep/ .layout.start-justified {\n    -ms-flex-pack: start;\n    -webkit-justify-content: flex-start;\n    justify-content: flex-start;\n  }\n\n  html /deep/ .layout.center-justified,\n  html /deep/ .layout.center-center {\n    -ms-flex-pack: center;\n    -webkit-justify-content: center;\n    justify-content: center;\n  }\n\n  html /deep/ .layout.end-justified {\n    -ms-flex-pack: end;\n    -webkit-justify-content: flex-end;\n    justify-content: flex-end;\n  }\n\n  html /deep/ .layout.around-justified {\n    -ms-flex-pack: around;\n    -webkit-justify-content: space-around;\n    justify-content: space-around;\n  }\n\n  html /deep/ .layout.justified {\n    -ms-flex-pack: justify;\n    -webkit-justify-content: space-between;\n    justify-content: space-between;\n  }\n\n  /* self alignment */\n\n  html /deep/ .self-start {\n    -ms-align-self: flex-start;\n    -webkit-align-self: flex-start;\n    align-self: flex-start;\n  }\n\n  html /deep/ .self-center {\n    -ms-align-self: center;\n    -webkit-align-self: center;\n    align-self: center;\n  }\n\n  html /deep/ .self-end {\n    -ms-align-self: flex-end;\n    -webkit-align-self: flex-end;\n    align-self: flex-end;\n  }\n\n  html /deep/ .self-stretch {\n    -ms-align-self: stretch;\n    -webkit-align-self: stretch;\n    align-self: stretch;\n  }\n\n  /*******************************\n            Other Layout\n  *******************************/\n\n  html /deep/ .block {\n    display: block;\n  }\n\n  /* IE 10 support for HTML5 hidden attr */\n  html /deep/ [hidden] {\n    display: none !important;\n  }\n\n  html /deep/ .invisible {\n    visibility: hidden !important;\n  }\n\n  html /deep/ .relative {\n    position: relative;\n  }\n\n  html /deep/ .fit {\n    position: absolute;\n    top: 0;\n    right: 0;\n    bottom: 0;\n    left: 0;\n  }\n\n  body.fullbleed {\n    margin: 0;\n    height: 100vh;\n  }\n\n  html /deep/ .scroll {\n    -webkit-overflow-scrolling: touch;\n    overflow: auto;\n  }\n\n  .fixed-bottom,\n  .fixed-left,\n  .fixed-right,\n  .fixed-top {\n    position: fixed;\n  }\n\n  html /deep/ .fixed-top {\n    top: 0;\n    left: 0;\n    right: 0;\n  }\n\n  html /deep/ .fixed-right {\n    top: 0;\n    right: 0;\n    bottom: 0;\n  }\n\n  html /deep/ .fixed-bottom {\n    right: 0;\n    bottom: 0;\n    left: 0;\n  }\n\n  html /deep/ .fixed-left {\n    top: 0;\n    bottom: 0;\n    left: 0;\n  }\n\n</style>\n\n\n<script>//~~WEBPATH~~/iron-flex-layout/classes/iron-flex-layout.html.js\nconsole.warn(\"This file is deprecated. Please use `iron-flex-layout/iron-flex-layout-classes.html`, and one of the specific dom-modules instead\");\n</script>\n\n<style>\n\n  /*******************************\n            Flex Layout\n  *******************************/\n\n  .layout.horizontal,\n  .layout.horizontal-reverse,\n  .layout.vertical,\n  .layout.vertical-reverse {\n    display: -ms-flexbox;\n    display: -webkit-flex;\n    display: flex;\n  }\n\n  .layout.inline {\n    display: -ms-inline-flexbox;\n    display: -webkit-inline-flex;\n    display: inline-flex;\n  }\n\n  .layout.horizontal {\n    -ms-flex-direction: row;\n    -webkit-flex-direction: row;\n    flex-direction: row;\n  }\n\n  .layout.horizontal-reverse {\n    -ms-flex-direction: row-reverse;\n    -webkit-flex-direction: row-reverse;\n    flex-direction: row-reverse;\n  }\n\n  .layout.vertical {\n    -ms-flex-direction: column;\n    -webkit-flex-direction: column;\n    flex-direction: column;\n  }\n\n  .layout.vertical-reverse {\n    -ms-flex-direction: column-reverse;\n    -webkit-flex-direction: column-reverse;\n    flex-direction: column-reverse;\n  }\n\n  .layout.wrap {\n    -ms-flex-wrap: wrap;\n    -webkit-flex-wrap: wrap;\n    flex-wrap: wrap;\n  }\n\n  .layout.wrap-reverse {\n    -ms-flex-wrap: wrap-reverse;\n    -webkit-flex-wrap: wrap-reverse;\n    flex-wrap: wrap-reverse;\n  }\n\n  .flex-auto {\n    -ms-flex: 1 1 auto;\n    -webkit-flex: 1 1 auto;\n    flex: 1 1 auto;\n  }\n\n  .flex-none {\n    -ms-flex: none;\n    -webkit-flex: none;\n    flex: none;\n  }\n\n  .flex,\n  .flex-1 {\n    -ms-flex: 1;\n    -webkit-flex: 1;\n    flex: 1;\n  }\n\n  .flex-2 {\n    -ms-flex: 2;\n    -webkit-flex: 2;\n    flex: 2;\n  }\n\n  .flex-3 {\n    -ms-flex: 3;\n    -webkit-flex: 3;\n    flex: 3;\n  }\n\n  .flex-4 {\n    -ms-flex: 4;\n    -webkit-flex: 4;\n    flex: 4;\n  }\n\n  .flex-5 {\n    -ms-flex: 5;\n    -webkit-flex: 5;\n    flex: 5;\n  }\n\n  .flex-6 {\n    -ms-flex: 6;\n    -webkit-flex: 6;\n    flex: 6;\n  }\n\n  .flex-7 {\n    -ms-flex: 7;\n    -webkit-flex: 7;\n    flex: 7;\n  }\n\n  .flex-8 {\n    -ms-flex: 8;\n    -webkit-flex: 8;\n    flex: 8;\n  }\n\n  .flex-9 {\n    -ms-flex: 9;\n    -webkit-flex: 9;\n    flex: 9;\n  }\n\n  .flex-10 {\n    -ms-flex: 10;\n    -webkit-flex: 10;\n    flex: 10;\n  }\n\n  .flex-11 {\n    -ms-flex: 11;\n    -webkit-flex: 11;\n    flex: 11;\n  }\n\n  .flex-12 {\n    -ms-flex: 12;\n    -webkit-flex: 12;\n    flex: 12;\n  }\n\n  /* alignment in cross axis */\n\n  .layout.start {\n    -ms-flex-align: start;\n    -webkit-align-items: flex-start;\n    align-items: flex-start;\n  }\n\n  .layout.center,\n  .layout.center-center {\n    -ms-flex-align: center;\n    -webkit-align-items: center;\n    align-items: center;\n  }\n\n  .layout.end {\n    -ms-flex-align: end;\n    -webkit-align-items: flex-end;\n    align-items: flex-end;\n  }\n\n  /* alignment in main axis */\n\n  .layout.start-justified {\n    -ms-flex-pack: start;\n    -webkit-justify-content: flex-start;\n    justify-content: flex-start;\n  }\n\n  .layout.center-justified,\n  .layout.center-center {\n    -ms-flex-pack: center;\n    -webkit-justify-content: center;\n    justify-content: center;\n  }\n\n  .layout.end-justified {\n    -ms-flex-pack: end;\n    -webkit-justify-content: flex-end;\n    justify-content: flex-end;\n  }\n\n  .layout.around-justified {\n    -ms-flex-pack: around;\n    -webkit-justify-content: space-around;\n    justify-content: space-around;\n  }\n\n  .layout.justified {\n    -ms-flex-pack: justify;\n    -webkit-justify-content: space-between;\n    justify-content: space-between;\n  }\n\n  /* self alignment */\n\n  .self-start {\n    -ms-align-self: flex-start;\n    -webkit-align-self: flex-start;\n    align-self: flex-start;\n  }\n\n  .self-center {\n    -ms-align-self: center;\n    -webkit-align-self: center;\n    align-self: center;\n  }\n\n  .self-end {\n    -ms-align-self: flex-end;\n    -webkit-align-self: flex-end;\n    align-self: flex-end;\n  }\n\n  .self-stretch {\n    -ms-align-self: stretch;\n    -webkit-align-self: stretch;\n    align-self: stretch;\n  }\n\n  /*******************************\n            Other Layout\n  *******************************/\n\n  .block {\n    display: block;\n  }\n\n  /* IE 10 support for HTML5 hidden attr */\n  [hidden] {\n    display: none !important;\n  }\n\n  .invisible {\n    visibility: hidden !important;\n  }\n\n  .relative {\n    position: relative;\n  }\n\n  .fit {\n    position: absolute;\n    top: 0;\n    right: 0;\n    bottom: 0;\n    left: 0;\n  }\n\n  body.fullbleed {\n    margin: 0;\n    height: 100vh;\n  }\n\n  .scroll {\n    -webkit-overflow-scrolling: touch;\n    overflow: auto;\n  }\n\n  /* fixed position */\n\n  .fixed-bottom,\n  .fixed-left,\n  .fixed-right,\n  .fixed-top {\n    position: fixed;\n  }\n\n  .fixed-top {\n    top: 0;\n    left: 0;\n    right: 0;\n  }\n\n  .fixed-right {\n    top: 0;\n    right: 0;\n    bottom: 0;\n  }\n\n  .fixed-bottom {\n    right: 0;\n    bottom: 0;\n    left: 0;\n  }\n\n  .fixed-left {\n    top: 0;\n    bottom: 0;\n    left: 0;\n  }\n\n</style>\n\n\n\n\n\n\n\n\n\n<script>//~~WEBPATH~~/facets-dive/lib/info-renderers.js\nfunction kh(a,b){var c=document.createElement(\"dl\"),d;for(d in a)if(a.hasOwnProperty(d)){var e=document.createElement(\"dt\");e.textContent=d;c.appendChild(e);e=document.createElement(\"dd\");e.textContent=a[d];c.appendChild(e)}b.appendChild(c)};\n</script>\n\n\n<dom-module id=\"facets-dive-info-card\">\n  <template>\n    <style>\n      :host {\n        @apply(--paper-font-common-base);\n        box-sizing: border-box;\n        max-height: 100%;\n        max-width: 100%;\n        overflow: auto;\n        padding: 8px;\n      }\n      ::content dt {\n        color: #9e7c65;\n        font-size: 14px;\n      }\n      ::content dd {\n        @apply(--paper-font-common-code);\n        color: #513726;\n        margin: 0 0 16px 0;\n      }\n    </style>\n    \n  </template>\n</dom-module>\n\n<script>//~~WEBPATH~~/facets-dive/components/facets-dive-info-card/facets-dive-info-card.js\nPolymer({is:\"facets-dive-info-card\",properties:{infoRenderer:{type:Object},selectedData:{type:Array,value:[],observer:\"_updateSelected\"}},_updateSelected:function(a){var b=Polymer.dom(this.root);b.innerHTML=\"\";if(a)for(var c=this.infoRenderer||kh,d=0;d<a.length;d++){var e=a[d],f=document.createElement(\"div\");f.style.width=\"100%\";b.appendChild(f);c(e,f)}}});\n</script>\n\n\n\n\n<dom-module id=\"facets-dive\">\n  <template>\n\n    <style>\n      /**\n       * paper-input-container uses an element containing only &nbsp; for\n       * spacing purposes. Aggressive vulcanizers sometimes remove this content.\n       * This CSS rule forces the containing element to have the correct height\n       * in either case.\n       */\n      ::content paper-input-container > .floated-label-placeholder {\n        min-height: 20px;\n      }\n\n      :host {\n        background: #ffffff;\n        box-sizing: border-box;\n        display: flex;\n        flex: 1;\n        height: 100%;\n        overflow: hidden;\n        position: relative;\n        width: 100%;\n      }\n      .fill {\n        bottom: 0;\n        left: 0;\n        position: absolute;\n        right: 0;\n        top: 0;\n      }\n      #vis {\n        bottom: 0;\n        left: 240px;\n        position: absolute;\n        right: 240px;\n        top: 0;\n        width: auto;\n      }\n      #controls {\n        background: #e1eae9;\n        border-right: 1px solid #cccccc;\n        bottom: 0;\n        box-sizing: border-box;\n        left: 0;\n        position: absolute;\n        top: 0;\n        width: 240px;\n      }\n      #infoCard {\n        background: #fff8f4;\n        bottom: 0;\n        border-left: 1px solid #c6c6c6;\n        box-sizing: border-box;\n        position: absolute;\n        right: 0;\n        top: 0;\n        width: 240px;\n      }\n\n      /**\n       * Zoom Controls.\n       */\n      .zoom-controls {\n        bottom: 14px;\n        box-sizing: border-box;\n        left: 250px;\n        position: absolute;\n      }\n      .zoom-controls paper-button {\n        background-color: #e7e7e7;\n        clear: left;\n        color: #2b2b2b;\n        display: block;\n        float: left;\n        margin: 4px 8px;\n        min-width: 0;\n        padding: 8px;\n      }\n    </style>\n\n    <div class=\"fill\">\n      <facets-dive-vis id=\"vis\" class=\"fill\" data=\"[[data]]\" filtered-data-indices=\"[[filteredDataIndices]]\" atlas-url=\"[[atlasUrl]]\" sprite-url=\"[[spriteUrl]]\" cross-origin=\"[[crossOrigin]]\" keys=\"{{_keys}}\" stats=\"{{_stats}}\" sprite-image-width=\"[[spriteImageWidth]]\" sprite-image-height=\"[[spriteImageHeight]]\" vertical-facet=\"[[verticalFacet]]\" vertical-buckets=\"[[verticalBuckets]]\" vertical-bag-of-words=\"[[verticalBagOfWords]]\" horizontal-facet=\"[[horizontalFacet]]\" horizontal-buckets=\"[[horizontalBuckets]]\" horizontal-bag-of-words=\"[[horizontalBagOfWords]]\" position-mode=\"[[positionMode]]\" vertical-position=\"[[verticalPosition]]\" horizontal-position=\"[[horizontalPosition]]\" color-by=\"{{colorBy}}\" image-field-name=\"{{imageFieldName}}\" palette=\"{{_palette}}\" palette-choice=\"[[paletteChoice]]\" grid-faceting-vertical-label-color=\"{{gridFacetingVerticalLabelColor}}\" grid-faceting-horizontal-label-color=\"{{gridFacetingHorizontalLabelColor}}\" item-positioning-vertical-label-color=\"{{itemPositioningVerticalLabelColor}}\" item-positioning-horizontal-label-color=\"{{itemPositioningHorizontalLabelColor}}\" selected-data=\"{{selectedData}}\"></facets-dive-vis>\n\n      <facets-dive-controls id=\"controls\" atlas-url=\"[[atlasUrl]]\" keys=\"[[_keys]]\" stats=\"[[_stats]]\" vertical-facet=\"{{verticalFacet}}\" vertical-buckets=\"{{verticalBuckets}}\" vertical-bag-of-words=\"{{verticalBagOfWords}}\" horizontal-facet=\"{{horizontalFacet}}\" horizontal-buckets=\"{{horizontalBuckets}}\" horizontal-bag-of-words=\"{{horizontalBagOfWords}}\" position-mode=\"{{positionMode}}\" vertical-position=\"{{verticalPosition}}\" horizontal-position=\"{{horizontalPosition}}\" color-by=\"{{colorBy}}\" image-field-name=\"{{imageFieldName}}\" palette=\"[[_palette]]\" palette-choice=\"{{paletteChoice}}\" grid-faceting-vertical-label-color=\"[[gridFacetingVerticalLabelColor]]\" grid-faceting-horizontal-label-color=\"[[gridFacetingHorizontalLabelColor]]\" item-positioning-vertical-label-color=\"[[itemPositioningVerticalLabelColor]]\" item-positioning-horizontal-label-color=\"[[itemPositioningHorizontalLabelColor]]\"></facets-dive-controls>\n\n      <div class=\"zoom-controls\">\n        <paper-button raised id=\"zoomInButton\">\n          <iron-icon icon=\"icons:add\"></iron-icon>\n        </paper-button>\n        <paper-button raised id=\"zoomOutButton\">\n          <iron-icon icon=\"icons:remove\"></iron-icon>\n        </paper-button>\n        <paper-button raised id=\"fitButton\">\n          <iron-icon icon=\"icons:aspect-ratio\"></iron-icon>\n        </paper-button>\n      </div>\n\n      <facets-dive-info-card id=\"infoCard\" selected-data=\"[[selectedData]]\" info-renderer=\"[[infoRenderer]]\"></facets-dive-info-card>\n    </div>\n\n  </template>\n</dom-module>\n\n<script>//~~WEBPATH~~/facets-dive/components/facets-dive/facets-dive.js\nPolymer({is:\"facets-dive\",properties:{data:{type:Array,value:null,notify:!0},filteredDataIndices:{type:Array,value:null},_keys:{type:Array,value:[]},_stats:{type:Object,value:{}},atlasUrl:{type:String,value:null,notify:!0},spriteUrl:{type:String,value:null,notify:!0},crossOrigin:{type:String,value:null,notify:!0},spriteImageWidth:{type:Number,value:64},spriteImageHeight:{type:Number,value:64},gridFacetingVerticalLabelColor:{type:String,value:\"#666666\"},gridFacetingHorizontalLabelColor:{type:String,\nvalue:\"#dd6622\"},itemPositioningVerticalLabelColor:{type:String,value:\"#2255aa\"},itemPositioningHorizontalLabelColor:{type:String,value:\"#118844\"},verticalFacet:{type:String,value:\"\",notify:!0},verticalBuckets:{type:Number,value:10,notify:!0},verticalBagOfWords:{type:Boolean,value:!1,notify:!0},horizontalFacet:{type:String,value:\"\",notify:!0},horizontalBuckets:{type:Number,value:10,notify:!0},horizontalBagOfWords:{type:Boolean,value:!1,notify:!0},positionMode:{type:String,value:\"stacked\",notify:!0},\nverticalPosition:{type:String,value:\"\",notify:!0},horizontalPosition:{type:String,value:\"\",notify:!0},colorBy:{type:String,value:\"\",notify:!0},imageFieldName:{type:String,value:\"\",notify:!0},_palette:{type:Array,value:[]},paletteChoice:{type:String,value:\"standard\",notify:!0},selectedData:{type:Array,value:[],notify:!0},height:{type:Number,value:null,observer:\"_updateHeight\"},infoRenderer:{type:Object}},ready:function(){var a=this.$;a.fitButton.onclick=function(){return a.vis.fitToViewport()};a.zoomInButton.onclick=\nfunction(){return a.vis.zoomIn()};a.zoomOutButton.onclick=function(){return a.vis.zoomOut()};this._updateHeight()},_updateHeight:function(){null!==this.height&&(this.style.height=\"number\"===typeof this.height?this.height+\"px\":this.height)}});</script>\n"
  },
  {
    "path": "google/datalab/notebook/static/extern/lantern-browser.html",
    "content": "<html><head><!--\n@license\nCopyright (c) 2016 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n--><!--\n@license\nCopyright (c) 2014 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n--><!--\n@license\nCopyright (c) 2015 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n--><meta charset=\"UTF-8\">\n    </head>\n  <body><div hidden by-vulcanize=\"\">\n\n<dom-module id=\"iron-pages\" assetpath=\"/iron-pages/\">\n\n  <template>\n    <style>\n      :host {\n        display: block;\n      }\n\n      :host > ::content > :not(.iron-selected) {\n        display: none !important;\n      }\n    </style>\n\n    <content></content>\n  </template>\n\n  </dom-module>\n\n\n<dom-module id=\"iron-a11y-announcer\" assetpath=\"/iron-a11y-announcer/\">\n  <template>\n    <style>\n      :host {\n        display: inline-block;\n        position: fixed;\n        clip: rect(0px,0px,0px,0px);\n      }\n    </style>\n    <div aria-live$=\"[[mode]]\">[[_text]]</div>\n  </template>\n\n  </dom-module>\n\n\n<link rel=\"stylesheet\" href=\"https://fonts.googleapis.com/css?family=Roboto:400,300,300italic,400italic,500,500italic,700,700italic\">\n<link rel=\"stylesheet\" href=\"https://fonts.googleapis.com/css?family=Roboto+Mono:400,700\">\n<style is=\"custom-style\">\n\n  :root {\n\n    /* Shared Styles */\n    --paper-font-common-base: {\n      font-family: 'Roboto', 'Noto', sans-serif;\n      -webkit-font-smoothing: antialiased;\n    };\n\n    --paper-font-common-code: {\n      font-family: 'Roboto Mono', 'Consolas', 'Menlo', monospace;\n      -webkit-font-smoothing: antialiased;\n    };\n\n    --paper-font-common-expensive-kerning: {\n      text-rendering: optimizeLegibility;\n    };\n\n    --paper-font-common-nowrap: {\n      white-space: nowrap;\n      overflow: hidden;\n      text-overflow: ellipsis;\n    };\n\n    /* Material Font Styles */\n\n    --paper-font-display4: {\n      @apply(--paper-font-common-base);\n      @apply(--paper-font-common-nowrap);\n\n      font-size: 112px;\n      font-weight: 300;\n      letter-spacing: -.044em;\n      line-height: 120px;\n    };\n\n    --paper-font-display3: {\n      @apply(--paper-font-common-base);\n      @apply(--paper-font-common-nowrap);\n\n      font-size: 56px;\n      font-weight: 400;\n      letter-spacing: -.026em;\n      line-height: 60px;\n    };\n\n    --paper-font-display2: {\n      @apply(--paper-font-common-base);\n\n      font-size: 45px;\n      font-weight: 400;\n      letter-spacing: -.018em;\n      line-height: 48px;\n    };\n\n    --paper-font-display1: {\n      @apply(--paper-font-common-base);\n\n      font-size: 34px;\n      font-weight: 400;\n      letter-spacing: -.01em;\n      line-height: 40px;\n    };\n\n    --paper-font-headline: {\n      @apply(--paper-font-common-base);\n\n      font-size: 24px;\n      font-weight: 400;\n      letter-spacing: -.012em;\n      line-height: 32px;\n    };\n\n    --paper-font-title: {\n      @apply(--paper-font-common-base);\n      @apply(--paper-font-common-nowrap);\n\n      font-size: 20px;\n      font-weight: 500;\n      line-height: 28px;\n    };\n\n    --paper-font-subhead: {\n      @apply(--paper-font-common-base);\n\n      font-size: 16px;\n      font-weight: 400;\n      line-height: 24px;\n    };\n\n    --paper-font-body2: {\n      @apply(--paper-font-common-base);\n\n      font-size: 14px;\n      font-weight: 500;\n      line-height: 24px;\n    };\n\n    --paper-font-body1: {\n      @apply(--paper-font-common-base);\n\n      font-size: 14px;\n      font-weight: 400;\n      line-height: 20px;\n    };\n\n    --paper-font-caption: {\n      @apply(--paper-font-common-base);\n      @apply(--paper-font-common-nowrap);\n\n      font-size: 12px;\n      font-weight: 400;\n      letter-spacing: 0.011em;\n      line-height: 20px;\n    };\n\n    --paper-font-menu: {\n      @apply(--paper-font-common-base);\n      @apply(--paper-font-common-nowrap);\n\n      font-size: 13px;\n      font-weight: 500;\n      line-height: 24px;\n    };\n\n    --paper-font-button: {\n      @apply(--paper-font-common-base);\n      @apply(--paper-font-common-nowrap);\n\n      font-size: 14px;\n      font-weight: 500;\n      letter-spacing: 0.018em;\n      line-height: 24px;\n      text-transform: uppercase;\n    };\n\n    --paper-font-code2: {\n      @apply(--paper-font-common-code);\n\n      font-size: 14px;\n      font-weight: 700;\n      line-height: 20px;\n    };\n\n    --paper-font-code1: {\n      @apply(--paper-font-common-code);\n\n      font-size: 14px;\n      font-weight: 500;\n      line-height: 20px;\n    };\n\n  }\n\n</style><dom-module id=\"paper-input-char-counter\" assetpath=\"/paper-input/\">\n  <template>\n    <style>\n      :host {\n        display: inline-block;\n        float: right;\n\n        @apply(--paper-font-caption);\n        @apply(--paper-input-char-counter);\n      }\n\n      :host([hidden]) {\n        display: none !important;\n      }\n\n      :host-context([dir=\"rtl\"]) {\n        float: left;\n      }\n    </style>\n\n    <span>[[_charCounterStr]]</span>\n  </template>\n</dom-module>\n\n<style>\n  /* IE 10 support for HTML5 hidden attr */\n  [hidden] {\n    display: none !important;\n  }\n</style><style is=\"custom-style\">\n  :root {\n\n    --layout: {\n      display: -ms-flexbox;\n      display: -webkit-flex;\n      display: flex;\n    };\n\n    --layout-inline: {\n      display: -ms-inline-flexbox;\n      display: -webkit-inline-flex;\n      display: inline-flex;\n    };\n\n    --layout-horizontal: {\n      @apply(--layout);\n\n      -ms-flex-direction: row;\n      -webkit-flex-direction: row;\n      flex-direction: row;\n    };\n\n    --layout-horizontal-reverse: {\n      @apply(--layout);\n\n      -ms-flex-direction: row-reverse;\n      -webkit-flex-direction: row-reverse;\n      flex-direction: row-reverse;\n    };\n\n    --layout-vertical: {\n      @apply(--layout);\n\n      -ms-flex-direction: column;\n      -webkit-flex-direction: column;\n      flex-direction: column;\n    };\n\n    --layout-vertical-reverse: {\n      @apply(--layout);\n\n      -ms-flex-direction: column-reverse;\n      -webkit-flex-direction: column-reverse;\n      flex-direction: column-reverse;\n    };\n\n    --layout-wrap: {\n      -ms-flex-wrap: wrap;\n      -webkit-flex-wrap: wrap;\n      flex-wrap: wrap;\n    };\n\n    --layout-wrap-reverse: {\n      -ms-flex-wrap: wrap-reverse;\n      -webkit-flex-wrap: wrap-reverse;\n      flex-wrap: wrap-reverse;\n    };\n\n    --layout-flex-auto: {\n      -ms-flex: 1 1 auto;\n      -webkit-flex: 1 1 auto;\n      flex: 1 1 auto;\n    };\n\n    --layout-flex-none: {\n      -ms-flex: none;\n      -webkit-flex: none;\n      flex: none;\n    };\n\n    --layout-flex: {\n      -ms-flex: 1 1 0.000000001px;\n      -webkit-flex: 1;\n      flex: 1;\n      -webkit-flex-basis: 0.000000001px;\n      flex-basis: 0.000000001px;\n    };\n\n    --layout-flex-2: {\n      -ms-flex: 2;\n      -webkit-flex: 2;\n      flex: 2;\n    };\n\n    --layout-flex-3: {\n      -ms-flex: 3;\n      -webkit-flex: 3;\n      flex: 3;\n    };\n\n    --layout-flex-4: {\n      -ms-flex: 4;\n      -webkit-flex: 4;\n      flex: 4;\n    };\n\n    --layout-flex-5: {\n      -ms-flex: 5;\n      -webkit-flex: 5;\n      flex: 5;\n    };\n\n    --layout-flex-6: {\n      -ms-flex: 6;\n      -webkit-flex: 6;\n      flex: 6;\n    };\n\n    --layout-flex-7: {\n      -ms-flex: 7;\n      -webkit-flex: 7;\n      flex: 7;\n    };\n\n    --layout-flex-8: {\n      -ms-flex: 8;\n      -webkit-flex: 8;\n      flex: 8;\n    };\n\n    --layout-flex-9: {\n      -ms-flex: 9;\n      -webkit-flex: 9;\n      flex: 9;\n    };\n\n    --layout-flex-10: {\n      -ms-flex: 10;\n      -webkit-flex: 10;\n      flex: 10;\n    };\n\n    --layout-flex-11: {\n      -ms-flex: 11;\n      -webkit-flex: 11;\n      flex: 11;\n    };\n\n    --layout-flex-12: {\n      -ms-flex: 12;\n      -webkit-flex: 12;\n      flex: 12;\n    };\n\n    /* alignment in cross axis */\n\n    --layout-start: {\n      -ms-flex-align: start;\n      -webkit-align-items: flex-start;\n      align-items: flex-start;\n    };\n\n    --layout-center: {\n      -ms-flex-align: center;\n      -webkit-align-items: center;\n      align-items: center;\n    };\n\n    --layout-end: {\n      -ms-flex-align: end;\n      -webkit-align-items: flex-end;\n      align-items: flex-end;\n    };\n\n    /* alignment in main axis */\n\n    --layout-start-justified: {\n      -ms-flex-pack: start;\n      -webkit-justify-content: flex-start;\n      justify-content: flex-start;\n    };\n\n    --layout-center-justified: {\n      -ms-flex-pack: center;\n      -webkit-justify-content: center;\n      justify-content: center;\n    };\n\n    --layout-end-justified: {\n      -ms-flex-pack: end;\n      -webkit-justify-content: flex-end;\n      justify-content: flex-end;\n    };\n\n    --layout-around-justified: {\n      -ms-flex-pack: distribute;\n      -webkit-justify-content: space-around;\n      justify-content: space-around;\n    };\n\n    --layout-justified: {\n      -ms-flex-pack: justify;\n      -webkit-justify-content: space-between;\n      justify-content: space-between;\n    };\n\n    --layout-center-center: {\n      @apply(--layout-center);\n      @apply(--layout-center-justified);\n    };\n\n    /* self alignment */\n\n    --layout-self-start: {\n      -ms-align-self: flex-start;\n      -webkit-align-self: flex-start;\n      align-self: flex-start;\n    };\n\n    --layout-self-center: {\n      -ms-align-self: center;\n      -webkit-align-self: center;\n      align-self: center;\n    };\n\n    --layout-self-end: {\n      -ms-align-self: flex-end;\n      -webkit-align-self: flex-end;\n      align-self: flex-end;\n    };\n\n    --layout-self-stretch: {\n      -ms-align-self: stretch;\n      -webkit-align-self: stretch;\n      align-self: stretch;\n    };\n\n    /*******************************\n              Other Layout\n    *******************************/\n\n    --layout-block: {\n      display: block;\n    };\n\n    --layout-invisible: {\n      visibility: hidden !important;\n    };\n\n    --layout-relative: {\n      position: relative;\n    };\n\n    --layout-fit: {\n      position: absolute;\n      top: 0;\n      right: 0;\n      bottom: 0;\n      left: 0;\n    };\n\n    --layout-scroll: {\n      -webkit-overflow-scrolling: touch;\n      overflow: auto;\n    };\n\n    --layout-fullbleed: {\n      margin: 0;\n      height: 100vh;\n    };\n\n    /* fixed position */\n\n    --layout-fixed-top: {\n      position: fixed;\n      top: 0;\n      left: 0;\n      right: 0;\n    };\n\n    --layout-fixed-right: {\n      position: fixed;\n      top: 0;\n      right: 0;\n      bottom: 0;\n    };\n\n    --layout-fixed-bottom: {\n      position: fixed;\n      right: 0;\n      bottom: 0;\n      left: 0;\n    };\n\n    --layout-fixed-left: {\n      position: fixed;\n      top: 0;\n      bottom: 0;\n      left: 0;\n    };\n\n  }\n\n</style>\n\n<style is=\"custom-style\">\n\n  :root {\n\n    /* Material Design color palette for Google products */\n\n    --google-red-100: #f4c7c3;\n    --google-red-300: #e67c73;\n    --google-red-500: #db4437;\n    --google-red-700: #c53929;\n\n    --google-blue-100: #c6dafc;\n    --google-blue-300: #7baaf7;\n    --google-blue-500: #4285f4;\n    --google-blue-700: #3367d6;\n\n    --google-green-100: #b7e1cd;\n    --google-green-300: #57bb8a;\n    --google-green-500: #0f9d58;\n    --google-green-700: #0b8043;\n\n    --google-yellow-100: #fce8b2;\n    --google-yellow-300: #f7cb4d;\n    --google-yellow-500: #f4b400;\n    --google-yellow-700: #f09300;\n\n    --google-grey-100: #f5f5f5;\n    --google-grey-300: #e0e0e0;\n    --google-grey-500: #9e9e9e;\n    --google-grey-700: #616161;\n    \n    /* Material Design color palette from online spec document */\n\n    --paper-red-50: #ffebee;\n    --paper-red-100: #ffcdd2;\n    --paper-red-200: #ef9a9a;\n    --paper-red-300: #e57373;\n    --paper-red-400: #ef5350;\n    --paper-red-500: #f44336;\n    --paper-red-600: #e53935;\n    --paper-red-700: #d32f2f;\n    --paper-red-800: #c62828;\n    --paper-red-900: #b71c1c;\n    --paper-red-a100: #ff8a80;\n    --paper-red-a200: #ff5252;\n    --paper-red-a400: #ff1744;\n    --paper-red-a700: #d50000;\n \n    --paper-pink-50: #fce4ec;\n    --paper-pink-100: #f8bbd0;\n    --paper-pink-200: #f48fb1;\n    --paper-pink-300: #f06292;\n    --paper-pink-400: #ec407a;\n    --paper-pink-500: #e91e63;\n    --paper-pink-600: #d81b60;\n    --paper-pink-700: #c2185b;\n    --paper-pink-800: #ad1457;\n    --paper-pink-900: #880e4f;\n    --paper-pink-a100: #ff80ab;\n    --paper-pink-a200: #ff4081;\n    --paper-pink-a400: #f50057;\n    --paper-pink-a700: #c51162;\n \n    --paper-purple-50: #f3e5f5;\n    --paper-purple-100: #e1bee7;\n    --paper-purple-200: #ce93d8;\n    --paper-purple-300: #ba68c8;\n    --paper-purple-400: #ab47bc;\n    --paper-purple-500: #9c27b0;\n    --paper-purple-600: #8e24aa;\n    --paper-purple-700: #7b1fa2;\n    --paper-purple-800: #6a1b9a;\n    --paper-purple-900: #4a148c;\n    --paper-purple-a100: #ea80fc;\n    --paper-purple-a200: #e040fb;\n    --paper-purple-a400: #d500f9;\n    --paper-purple-a700: #aa00ff;\n \n    --paper-deep-purple-50: #ede7f6;\n    --paper-deep-purple-100: #d1c4e9;\n    --paper-deep-purple-200: #b39ddb;\n    --paper-deep-purple-300: #9575cd;\n    --paper-deep-purple-400: #7e57c2;\n    --paper-deep-purple-500: #673ab7;\n    --paper-deep-purple-600: #5e35b1;\n    --paper-deep-purple-700: #512da8;\n    --paper-deep-purple-800: #4527a0;\n    --paper-deep-purple-900: #311b92;\n    --paper-deep-purple-a100: #b388ff;\n    --paper-deep-purple-a200: #7c4dff;\n    --paper-deep-purple-a400: #651fff;\n    --paper-deep-purple-a700: #6200ea;\n \n    --paper-indigo-50: #e8eaf6;\n    --paper-indigo-100: #c5cae9;\n    --paper-indigo-200: #9fa8da;\n    --paper-indigo-300: #7986cb;\n    --paper-indigo-400: #5c6bc0;\n    --paper-indigo-500: #3f51b5;\n    --paper-indigo-600: #3949ab;\n    --paper-indigo-700: #303f9f;\n    --paper-indigo-800: #283593;\n    --paper-indigo-900: #1a237e;\n    --paper-indigo-a100: #8c9eff;\n    --paper-indigo-a200: #536dfe;\n    --paper-indigo-a400: #3d5afe;\n    --paper-indigo-a700: #304ffe;\n \n    --paper-blue-50: #e3f2fd;\n    --paper-blue-100: #bbdefb;\n    --paper-blue-200: #90caf9;\n    --paper-blue-300: #64b5f6;\n    --paper-blue-400: #42a5f5;\n    --paper-blue-500: #2196f3;\n    --paper-blue-600: #1e88e5;\n    --paper-blue-700: #1976d2;\n    --paper-blue-800: #1565c0;\n    --paper-blue-900: #0d47a1;\n    --paper-blue-a100: #82b1ff;\n    --paper-blue-a200: #448aff;\n    --paper-blue-a400: #2979ff;\n    --paper-blue-a700: #2962ff;\n \n    --paper-light-blue-50: #e1f5fe;\n    --paper-light-blue-100: #b3e5fc;\n    --paper-light-blue-200: #81d4fa;\n    --paper-light-blue-300: #4fc3f7;\n    --paper-light-blue-400: #29b6f6;\n    --paper-light-blue-500: #03a9f4;\n    --paper-light-blue-600: #039be5;\n    --paper-light-blue-700: #0288d1;\n    --paper-light-blue-800: #0277bd;\n    --paper-light-blue-900: #01579b;\n    --paper-light-blue-a100: #80d8ff;\n    --paper-light-blue-a200: #40c4ff;\n    --paper-light-blue-a400: #00b0ff;\n    --paper-light-blue-a700: #0091ea;\n \n    --paper-cyan-50: #e0f7fa;\n    --paper-cyan-100: #b2ebf2;\n    --paper-cyan-200: #80deea;\n    --paper-cyan-300: #4dd0e1;\n    --paper-cyan-400: #26c6da;\n    --paper-cyan-500: #00bcd4;\n    --paper-cyan-600: #00acc1;\n    --paper-cyan-700: #0097a7;\n    --paper-cyan-800: #00838f;\n    --paper-cyan-900: #006064;\n    --paper-cyan-a100: #84ffff;\n    --paper-cyan-a200: #18ffff;\n    --paper-cyan-a400: #00e5ff;\n    --paper-cyan-a700: #00b8d4;\n \n    --paper-teal-50: #e0f2f1;\n    --paper-teal-100: #b2dfdb;\n    --paper-teal-200: #80cbc4;\n    --paper-teal-300: #4db6ac;\n    --paper-teal-400: #26a69a;\n    --paper-teal-500: #009688;\n    --paper-teal-600: #00897b;\n    --paper-teal-700: #00796b;\n    --paper-teal-800: #00695c;\n    --paper-teal-900: #004d40;\n    --paper-teal-a100: #a7ffeb;\n    --paper-teal-a200: #64ffda;\n    --paper-teal-a400: #1de9b6;\n    --paper-teal-a700: #00bfa5;\n \n    --paper-green-50: #e8f5e9;\n    --paper-green-100: #c8e6c9;\n    --paper-green-200: #a5d6a7;\n    --paper-green-300: #81c784;\n    --paper-green-400: #66bb6a;\n    --paper-green-500: #4caf50;\n    --paper-green-600: #43a047;\n    --paper-green-700: #388e3c;\n    --paper-green-800: #2e7d32;\n    --paper-green-900: #1b5e20;\n    --paper-green-a100: #b9f6ca;\n    --paper-green-a200: #69f0ae;\n    --paper-green-a400: #00e676;\n    --paper-green-a700: #00c853;\n \n    --paper-light-green-50: #f1f8e9;\n    --paper-light-green-100: #dcedc8;\n    --paper-light-green-200: #c5e1a5;\n    --paper-light-green-300: #aed581;\n    --paper-light-green-400: #9ccc65;\n    --paper-light-green-500: #8bc34a;\n    --paper-light-green-600: #7cb342;\n    --paper-light-green-700: #689f38;\n    --paper-light-green-800: #558b2f;\n    --paper-light-green-900: #33691e;\n    --paper-light-green-a100: #ccff90;\n    --paper-light-green-a200: #b2ff59;\n    --paper-light-green-a400: #76ff03;\n    --paper-light-green-a700: #64dd17;\n \n    --paper-lime-50: #f9fbe7;\n    --paper-lime-100: #f0f4c3;\n    --paper-lime-200: #e6ee9c;\n    --paper-lime-300: #dce775;\n    --paper-lime-400: #d4e157;\n    --paper-lime-500: #cddc39;\n    --paper-lime-600: #c0ca33;\n    --paper-lime-700: #afb42b;\n    --paper-lime-800: #9e9d24;\n    --paper-lime-900: #827717;\n    --paper-lime-a100: #f4ff81;\n    --paper-lime-a200: #eeff41;\n    --paper-lime-a400: #c6ff00;\n    --paper-lime-a700: #aeea00;\n \n    --paper-yellow-50: #fffde7;\n    --paper-yellow-100: #fff9c4;\n    --paper-yellow-200: #fff59d;\n    --paper-yellow-300: #fff176;\n    --paper-yellow-400: #ffee58;\n    --paper-yellow-500: #ffeb3b;\n    --paper-yellow-600: #fdd835;\n    --paper-yellow-700: #fbc02d;\n    --paper-yellow-800: #f9a825;\n    --paper-yellow-900: #f57f17;\n    --paper-yellow-a100: #ffff8d;\n    --paper-yellow-a200: #ffff00;\n    --paper-yellow-a400: #ffea00;\n    --paper-yellow-a700: #ffd600;\n \n    --paper-amber-50: #fff8e1;\n    --paper-amber-100: #ffecb3;\n    --paper-amber-200: #ffe082;\n    --paper-amber-300: #ffd54f;\n    --paper-amber-400: #ffca28;\n    --paper-amber-500: #ffc107;\n    --paper-amber-600: #ffb300;\n    --paper-amber-700: #ffa000;\n    --paper-amber-800: #ff8f00;\n    --paper-amber-900: #ff6f00;\n    --paper-amber-a100: #ffe57f;\n    --paper-amber-a200: #ffd740;\n    --paper-amber-a400: #ffc400;\n    --paper-amber-a700: #ffab00;\n \n    --paper-orange-50: #fff3e0;\n    --paper-orange-100: #ffe0b2;\n    --paper-orange-200: #ffcc80;\n    --paper-orange-300: #ffb74d;\n    --paper-orange-400: #ffa726;\n    --paper-orange-500: #ff9800;\n    --paper-orange-600: #fb8c00;\n    --paper-orange-700: #f57c00;\n    --paper-orange-800: #ef6c00;\n    --paper-orange-900: #e65100;\n    --paper-orange-a100: #ffd180;\n    --paper-orange-a200: #ffab40;\n    --paper-orange-a400: #ff9100;\n    --paper-orange-a700: #ff6500;\n \n    --paper-deep-orange-50: #fbe9e7;\n    --paper-deep-orange-100: #ffccbc;\n    --paper-deep-orange-200: #ffab91;\n    --paper-deep-orange-300: #ff8a65;\n    --paper-deep-orange-400: #ff7043;\n    --paper-deep-orange-500: #ff5722;\n    --paper-deep-orange-600: #f4511e;\n    --paper-deep-orange-700: #e64a19;\n    --paper-deep-orange-800: #d84315;\n    --paper-deep-orange-900: #bf360c;\n    --paper-deep-orange-a100: #ff9e80;\n    --paper-deep-orange-a200: #ff6e40;\n    --paper-deep-orange-a400: #ff3d00;\n    --paper-deep-orange-a700: #dd2c00;\n \n    --paper-brown-50: #efebe9;\n    --paper-brown-100: #d7ccc8;\n    --paper-brown-200: #bcaaa4;\n    --paper-brown-300: #a1887f;\n    --paper-brown-400: #8d6e63;\n    --paper-brown-500: #795548;\n    --paper-brown-600: #6d4c41;\n    --paper-brown-700: #5d4037;\n    --paper-brown-800: #4e342e;\n    --paper-brown-900: #3e2723;\n \n    --paper-grey-50: #fafafa;\n    --paper-grey-100: #f5f5f5;\n    --paper-grey-200: #eeeeee;\n    --paper-grey-300: #e0e0e0;\n    --paper-grey-400: #bdbdbd;\n    --paper-grey-500: #9e9e9e;\n    --paper-grey-600: #757575;\n    --paper-grey-700: #616161;\n    --paper-grey-800: #424242;\n    --paper-grey-900: #212121;\n \n    --paper-blue-grey-50: #eceff1;\n    --paper-blue-grey-100: #cfd8dc;\n    --paper-blue-grey-200: #b0bec5;\n    --paper-blue-grey-300: #90a4ae;\n    --paper-blue-grey-400: #78909c;\n    --paper-blue-grey-500: #607d8b;\n    --paper-blue-grey-600: #546e7a;\n    --paper-blue-grey-700: #455a64;\n    --paper-blue-grey-800: #37474f;\n    --paper-blue-grey-900: #263238;\n\n    /* opacity for dark text on a light background */\n    --dark-divider-opacity: 0.12;\n    --dark-disabled-opacity: 0.38; /* or hint text or icon */\n    --dark-secondary-opacity: 0.54;\n    --dark-primary-opacity: 0.87;\n\n    /* opacity for light text on a dark background */\n    --light-divider-opacity: 0.12;\n    --light-disabled-opacity: 0.3; /* or hint text or icon */\n    --light-secondary-opacity: 0.7;\n    --light-primary-opacity: 1.0;\n\n  }\n\n</style><style is=\"custom-style\">\n\n  :root {\n    /*\n     * You can use these generic variables in your elements for easy theming.\n     * For example, if all your elements use `--primary-text-color` as its main\n     * color, then switching from a light to a dark theme is just a matter of\n     * changing the value of `--primary-text-color` in your application.\n     */\n    --primary-text-color: var(--light-theme-text-color);\n    --primary-background-color: var(--light-theme-background-color);\n    --secondary-text-color: var(--light-theme-secondary-color);\n    --disabled-text-color: var(--light-theme-disabled-color);\n    --divider-color: var(--light-theme-divider-color);\n    --error-color: var(--paper-deep-orange-a700);\n\n    /*\n     * Primary and accent colors. Also see color.html for more colors.\n     */\n    --primary-color: var(--paper-indigo-500);\n    --light-primary-color: var(--paper-indigo-100);\n    --dark-primary-color: var(--paper-indigo-700);\n\n    --accent-color: var(--paper-pink-a200);\n    --light-accent-color: var(--paper-pink-a100);\n    --dark-accent-color: var(--paper-pink-a400);\n\n\n    /*\n     * Material Design Light background theme\n     */\n    --light-theme-background-color: #ffffff;\n    --light-theme-base-color: #000000;\n    --light-theme-text-color: var(--paper-grey-900);\n    --light-theme-secondary-color: #737373;  /* for secondary text and icons */\n    --light-theme-disabled-color: #9b9b9b;  /* disabled/hint text */\n    --light-theme-divider-color: #dbdbdb;\n\n    /*\n     * Material Design Dark background theme\n     */\n    --dark-theme-background-color: var(--paper-grey-900);\n    --dark-theme-base-color: #ffffff;\n    --dark-theme-text-color: #ffffff;\n    --dark-theme-secondary-color: #bcbcbc;  /* for secondary text and icons */\n    --dark-theme-disabled-color: #646464;  /* disabled/hint text */\n    --dark-theme-divider-color: #3c3c3c;\n\n    /*\n     * Deprecated values because of their confusing names.\n     */\n    --text-primary-color: var(--dark-theme-text-color);\n    --default-primary-color: var(--primary-color);\n\n  }\n\n</style><dom-module id=\"paper-input-container\" assetpath=\"/paper-input/\">\n  <template>\n    <style>\n      :host {\n        display: block;\n        padding: 8px 0;\n\n        @apply(--paper-input-container);\n      }\n\n      :host([inline]) {\n        display: inline-block;\n      }\n\n      :host([disabled]) {\n        pointer-events: none;\n        opacity: 0.33;\n\n        @apply(--paper-input-container-disabled);\n      }\n\n      :host([hidden]) {\n        display: none !important;\n      }\n\n      .floated-label-placeholder {\n        @apply(--paper-font-caption);\n      }\n\n      .underline {\n        position: relative;\n      }\n\n      .focused-line {\n        @apply(--layout-fit);\n\n        background: var(--paper-input-container-focus-color, --primary-color);\n        height: 2px;\n\n        -webkit-transform-origin: center center;\n        transform-origin: center center;\n        -webkit-transform: scale3d(0,1,1);\n        transform: scale3d(0,1,1);\n\n        @apply(--paper-input-container-underline-focus);\n      }\n\n      .underline.is-highlighted .focused-line {\n        -webkit-transform: none;\n        transform: none;\n        -webkit-transition: -webkit-transform 0.25s;\n        transition: transform 0.25s;\n\n        @apply(--paper-transition-easing);\n      }\n\n      .underline.is-invalid .focused-line {\n        background: var(--paper-input-container-invalid-color, --error-color);\n        -webkit-transform: none;\n        transform: none;\n        -webkit-transition: -webkit-transform 0.25s;\n        transition: transform 0.25s;\n\n        @apply(--paper-transition-easing);\n      }\n\n      .unfocused-line {\n        @apply(--layout-fit);\n\n        background: var(--paper-input-container-color, --secondary-text-color);\n        height: 1px;\n\n        @apply(--paper-input-container-underline);\n      }\n\n      :host([disabled]) .unfocused-line {\n        border-bottom: 1px dashed;\n        border-color: var(--paper-input-container-color, --secondary-text-color);\n        background: transparent;\n\n        @apply(--paper-input-container-underline-disabled);\n      }\n\n      .label-and-input-container {\n        @apply(--layout-flex-auto);\n        @apply(--layout-relative);\n\n        width: 100%;\n        max-width: 100%;\n      }\n\n      .input-content {\n        @apply(--layout-horizontal);\n        @apply(--layout-center);\n\n        position: relative;\n      }\n\n      .input-content ::content label,\n      .input-content ::content .paper-input-label {\n        position: absolute;\n        top: 0;\n        right: 0;\n        left: 0;\n        width: 100%;\n        font: inherit;\n        color: var(--paper-input-container-color, --secondary-text-color);\n        -webkit-transition: -webkit-transform 0.25s, width 0.25s;\n        transition: transform 0.25s, width 0.25s;\n        -webkit-transform-origin: left top;\n        transform-origin: left top;\n\n        @apply(--paper-font-common-nowrap);\n        @apply(--paper-font-subhead);\n        @apply(--paper-input-container-label);\n        @apply(--paper-transition-easing);\n      }\n\n      .input-content.label-is-floating ::content label,\n      .input-content.label-is-floating ::content .paper-input-label {\n        -webkit-transform: translateY(-75%) scale(0.75);\n        transform: translateY(-75%) scale(0.75);\n\n        /* Since we scale to 75/100 of the size, we actually have 100/75 of the\n        original space now available */\n        width: 133%;\n\n        @apply(--paper-input-container-label-floating);\n      }\n\n      :host-context([dir=\"rtl\"]) .input-content.label-is-floating ::content label,\n      :host-context([dir=\"rtl\"]) .input-content.label-is-floating ::content .paper-input-label {\n        /* TODO(noms): Figure out why leaving the width at 133% before the animation\n         * actually makes\n         * it wider on the right side, not left side, as you would expect in RTL */\n        width: 100%;\n        -webkit-transform-origin: right top;\n        transform-origin: right top;\n      }\n\n      .input-content.label-is-highlighted ::content label,\n      .input-content.label-is-highlighted ::content .paper-input-label {\n        color: var(--paper-input-container-focus-color, --primary-color);\n\n        @apply(--paper-input-container-label-focus);\n      }\n\n      .input-content.is-invalid ::content label,\n      .input-content.is-invalid ::content .paper-input-label {\n        color: var(--paper-input-container-invalid-color, --error-color);\n      }\n\n      .input-content.label-is-hidden ::content label,\n      .input-content.label-is-hidden ::content .paper-input-label {\n        visibility: hidden;\n      }\n\n      .input-content ::content input,\n      .input-content ::content textarea,\n      .input-content ::content iron-autogrow-textarea,\n      .input-content ::content .paper-input-input {\n        position: relative; /* to make a stacking context */\n        outline: none;\n        box-shadow: none;\n        padding: 0;\n        width: 100%;\n        max-width: 100%;\n        background: transparent;\n        border: none;\n        color: var(--paper-input-container-input-color, --primary-text-color);\n        -webkit-appearance: none;\n        text-align: inherit;\n\n        @apply(--paper-font-subhead);\n        @apply(--paper-input-container-input);\n      }\n\n      ::content [prefix] {\n        @apply(--paper-font-subhead);\n\n        @apply(--paper-input-prefix);\n        @apply(--layout-flex-none);\n      }\n\n      ::content [suffix] {\n        @apply(--paper-font-subhead);\n\n        @apply(--paper-input-suffix);\n        @apply(--layout-flex-none);\n      }\n\n      /* Firefox sets a min-width on the input, which can cause layout issues */\n      .input-content ::content input {\n        min-width: 0;\n      }\n\n      .input-content ::content textarea {\n        resize: none;\n      }\n\n      .add-on-content {\n        position: relative;\n      }\n\n      .add-on-content.is-invalid ::content * {\n        color: var(--paper-input-container-invalid-color, --error-color);\n      }\n\n      .add-on-content.is-highlighted ::content * {\n        color: var(--paper-input-container-focus-color, --primary-color);\n      }\n    </style>\n\n    <template is=\"dom-if\" if=\"[[!noLabelFloat]]\">\n      <div class=\"floated-label-placeholder\" aria-hidden=\"true\">&nbsp;</div>\n    </template>\n\n    <div class$=\"[[X_(noLabelFloat,alwaysFloatLabel,focused,invalid,_inputHasContent)]]\">\n      <content select=\"[prefix]\" id=\"prefix\"></content>\n\n      <div class=\"label-and-input-container\" id=\"labelAndInputContainer\">\n        <content select=\":not([add-on]):not([prefix]):not([suffix])\"></content>\n      </div>\n\n      <content select=\"[suffix]\"></content>\n    </div>\n\n    <div class$=\"[[b0(focused,invalid)]]\">\n      <div class=\"unfocused-line\"></div>\n      <div class=\"focused-line\"></div>\n    </div>\n\n    <div class$=\"[[P_(focused,invalid)]]\">\n      <content id=\"addOnContent\" select=\"[add-on]\"></content>\n    </div>\n  </template>\n</dom-module>\n\n<dom-module id=\"paper-input-error\" assetpath=\"/paper-input/\">\n  <template>\n    <style>\n      :host {\n        display: inline-block;\n        visibility: hidden;\n\n        color: var(--paper-input-container-invalid-color, --error-color);\n\n        @apply(--paper-font-caption);\n        @apply(--paper-input-error);\n        position: absolute;\n        left:0;\n        right:0;\n      }\n\n      :host([invalid]) {\n        visibility: visible;\n      };\n    </style>\n\n    <content></content>\n  </template>\n</dom-module>\n\n<dom-module id=\"paper-input\" assetpath=\"/paper-input/\">\n  <template>\n    <style>\n      :host {\n        display: block;\n      }\n\n      :host([focused]) {\n        outline: none;\n      }\n\n      :host([hidden]) {\n        display: none !important;\n      }\n\n      input::-webkit-input-placeholder {\n        color: var(--paper-input-container-color, --secondary-text-color);\n      }\n\n      input:-moz-placeholder {\n        color: var(--paper-input-container-color, --secondary-text-color);\n      }\n\n      input::-moz-placeholder {\n        color: var(--paper-input-container-color, --secondary-text-color);\n      }\n\n      input:-ms-input-placeholder {\n        color: var(--paper-input-container-color, --secondary-text-color);\n      }\n\n      label {\n        pointer-events: none;\n      }\n    </style>\n\n    <paper-input-container no-label-float=\"[[noLabelFloat]]\" always-float-label=\"[[Q_(alwaysFloatLabel,placeholder)]]\" auto-validate$=\"[[autoValidate]]\" disabled$=\"[[disabled]]\" invalid=\"[[invalid]]\">\n\n      <content select=\"[prefix]\"></content>\n\n      <label hidden$=\"[[!label]]\" aria-hidden=\"true\" for=\"input\">[[label]]</label>\n\n      <input is=\"iron-input\" id=\"input\" aria-labelledby$=\"[[_ariaLabelledBy]]\" aria-describedby$=\"[[_ariaDescribedBy]]\" disabled$=\"[[disabled]]\" title$=\"[[title]]\" bind-value=\"{{value}}\" invalid=\"{{invalid}}\" prevent-invalid-input=\"[[preventInvalidInput]]\" allowed-pattern=\"[[allowedPattern]]\" validator=\"[[validator]]\" type$=\"[[type]]\" pattern$=\"[[pattern]]\" required$=\"[[required]]\" autocomplete$=\"[[autocomplete]]\" autofocus$=\"[[autofocus]]\" inputmode$=\"[[inputmode]]\" minlength$=\"[[minlength]]\" maxlength$=\"[[maxlength]]\" min$=\"[[min]]\" max$=\"[[max]]\" step$=\"[[step]]\" name$=\"[[name]]\" placeholder$=\"[[placeholder]]\" readonly$=\"[[readonly]]\" list$=\"[[list]]\" size$=\"[[size]]\" autocapitalize$=\"[[autocapitalize]]\" autocorrect$=\"[[autocorrect]]\" on-change=\"J0\" tabindex$=\"[[tabindex]]\" autosave$=\"[[autosave]]\" results$=\"[[results]]\" accept$=\"[[accept]]\" multiple$=\"[[multiple]]\">\n\n      <content select=\"[suffix]\"></content>\n\n      <template is=\"dom-if\" if=\"[[errorMessage]]\">\n        <paper-input-error aria-live=\"assertive\">[[errorMessage]]</paper-input-error>\n      </template>\n\n      <template is=\"dom-if\" if=\"[[charCounter]]\">\n        <paper-input-char-counter></paper-input-char-counter>\n      </template>\n\n    </paper-input-container>\n  </template>\n</dom-module>\n\n<dom-module id=\"iron-icon\" assetpath=\"/iron-icon/\">\n  <template>\n    <style>\n      :host {\n        @apply(--layout-inline);\n        @apply(--layout-center-center);\n        position: relative;\n\n        vertical-align: middle;\n\n        fill: var(--iron-icon-fill-color, currentcolor);\n        stroke: var(--iron-icon-stroke-color, none);\n\n        width: var(--iron-icon-width, 24px);\n        height: var(--iron-icon-height, 24px);\n        @apply(--iron-icon);\n      }\n    </style>\n  </template>\n\n  </dom-module>\n\n\n\n\n<dom-module id=\"iron-overlay-backdrop\" assetpath=\"/iron-overlay-behavior/\">\n\n  <template>\n    <style>\n      :host {\n        position: fixed;\n        top: 0;\n        left: 0;\n        width: 100%;\n        height: 100%;\n        background-color: var(--iron-overlay-backdrop-background-color, #000);\n        opacity: 0;\n        transition: opacity 0.2s;\n        pointer-events: none;\n        @apply(--iron-overlay-backdrop);\n      }\n\n      :host(.opened) {\n        opacity: var(--iron-overlay-backdrop-opacity, 0.6);\n        pointer-events: auto;\n        @apply(--iron-overlay-backdrop-opened);\n      }\n    </style>\n\n    <content></content>\n  </template>\n\n</dom-module>\n\n<dom-module id=\"iron-dropdown\" assetpath=\"/iron-dropdown/\">\n  <template>\n    <style>\n      :host {\n        position: fixed;\n      }\n\n      #contentWrapper ::content > * {\n        overflow: auto;\n      }\n\n      #contentWrapper.animating ::content > * {\n        overflow: hidden;\n      }\n    </style>\n\n    <div id=\"contentWrapper\">\n      <content id=\"content\" select=\".dropdown-content\"></content>\n    </div>\n  </template>\n\n  </dom-module>\n\n\n<style is=\"custom-style\">\n\n  :root {\n\n    --shadow-transition: {\n      transition: box-shadow 0.28s cubic-bezier(0.4, 0, 0.2, 1);\n    };\n\n    --shadow-none: {\n      box-shadow: none;\n    };\n\n    /* from http://codepen.io/shyndman/pen/c5394ddf2e8b2a5c9185904b57421cdb */\n\n    --shadow-elevation-2dp: {\n      box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14),\n                  0 1px 5px 0 rgba(0, 0, 0, 0.12),\n                  0 3px 1px -2px rgba(0, 0, 0, 0.2);\n    };\n\n    --shadow-elevation-3dp: {\n      box-shadow: 0 3px 4px 0 rgba(0, 0, 0, 0.14),\n                  0 1px 8px 0 rgba(0, 0, 0, 0.12),\n                  0 3px 3px -2px rgba(0, 0, 0, 0.4);\n    };\n\n    --shadow-elevation-4dp: {\n      box-shadow: 0 4px 5px 0 rgba(0, 0, 0, 0.14),\n                  0 1px 10px 0 rgba(0, 0, 0, 0.12),\n                  0 2px 4px -1px rgba(0, 0, 0, 0.4);\n    };\n\n    --shadow-elevation-6dp: {\n      box-shadow: 0 6px 10px 0 rgba(0, 0, 0, 0.14),\n                  0 1px 18px 0 rgba(0, 0, 0, 0.12),\n                  0 3px 5px -1px rgba(0, 0, 0, 0.4);\n    };\n\n    --shadow-elevation-8dp: {\n      box-shadow: 0 8px 10px 1px rgba(0, 0, 0, 0.14),\n                  0 3px 14px 2px rgba(0, 0, 0, 0.12),\n                  0 5px 5px -3px rgba(0, 0, 0, 0.4);\n    };\n\n    --shadow-elevation-12dp: {\n      box-shadow: 0 12px 16px 1px rgba(0, 0, 0, 0.14),\n                  0 4px 22px 3px rgba(0, 0, 0, 0.12),\n                  0 6px 7px -4px rgba(0, 0, 0, 0.4);\n    };\n\n    --shadow-elevation-16dp: {\n      box-shadow: 0 16px 24px 2px rgba(0, 0, 0, 0.14),\n                  0  6px 30px 5px rgba(0, 0, 0, 0.12),\n                  0  8px 10px -5px rgba(0, 0, 0, 0.4);\n    };\n\n  }\n\n</style><dom-module id=\"paper-menu-button\" assetpath=\"/paper-menu-button/\">\n  <template>\n    <style>\n      :host {\n        display: inline-block;\n        position: relative;\n        padding: 8px;\n        outline: none;\n\n        @apply(--paper-menu-button);\n      }\n\n      :host([disabled]) {\n        cursor: auto;\n        color: var(--disabled-text-color);\n\n        @apply(--paper-menu-button-disabled);\n      }\n\n      iron-dropdown {\n        @apply(--paper-menu-button-dropdown);\n      }\n\n      .dropdown-content {\n        @apply(--shadow-elevation-2dp);\n\n        position: relative;\n        border-radius: 2px;\n        background-color: var(--paper-menu-button-dropdown-background, --primary-background-color);\n\n        @apply(--paper-menu-button-content);\n      }\n\n      :host([vertical-align=\"top\"]) .dropdown-content {\n        margin-bottom: 20px;\n        margin-top: -10px;\n        top: 10px;\n      }\n\n      :host([vertical-align=\"bottom\"]) .dropdown-content {\n        bottom: 10px;\n        margin-bottom: -10px;\n        margin-top: 20px;\n      }\n    </style>\n\n    <div id=\"trigger\" on-tap=\"toggle\">\n      <content select=\".dropdown-trigger\"></content>\n    </div>\n\n    <iron-dropdown id=\"dropdown\" opened=\"{{opened}}\" horizontal-align=\"[[horizontalAlign]]\" vertical-align=\"[[verticalAlign]]\" dynamic-align=\"[[dynamicAlign]]\" horizontal-offset=\"[[horizontalOffset]]\" vertical-offset=\"[[verticalOffset]]\" no-overlap=\"[[noOverlap]]\" open-animation-config=\"[[openAnimationConfig]]\" close-animation-config=\"[[closeAnimationConfig]]\" no-animations=\"[[noAnimations]]\" focus-target=\"[[_dropdownContent]]\" allow-outside-scroll=\"[[allowOutsideScroll]]\" restore-focus-on-close=\"[[restoreFocusOnClose]]\" on-iron-overlay-canceled=\"B_\">\n      <div class=\"dropdown-content\">\n        <content id=\"content\" select=\".dropdown-content\"></content>\n      </div>\n    </iron-dropdown>\n  </template>\n\n  </dom-module>\n\n\n<dom-module id=\"paper-ripple\" assetpath=\"/paper-ripple/\">\n\n  \n\n  <template>\n    <style>\n      :host {\n        display: block;\n        position: absolute;\n        border-radius: inherit;\n        overflow: hidden;\n        top: 0;\n        left: 0;\n        right: 0;\n        bottom: 0;\n\n        /* See PolymerElements/paper-behaviors/issues/34. On non-Chrome browsers,\n         * creating a node (with a position:absolute) in the middle of an event\n         * handler \"interrupts\" that event handler (which happens when the\n         * ripple is created on demand) */\n        pointer-events: none;\n      }\n\n      :host([animating]) {\n        /* This resolves a rendering issue in Chrome (as of 40) where the\n           ripple is not properly clipped by its parent (which may have\n           rounded corners). See: http://jsbin.com/temexa/4\n\n           Note: We only apply this style conditionally. Otherwise, the browser\n           will create a new compositing layer for every ripple element on the\n           page, and that would be bad. */\n        -webkit-transform: translate(0, 0);\n        transform: translate3d(0, 0, 0);\n      }\n\n      #background,\n      #waves,\n      .wave-container,\n      .wave {\n        pointer-events: none;\n        position: absolute;\n        top: 0;\n        left: 0;\n        width: 100%;\n        height: 100%;\n      }\n\n      #background,\n      .wave {\n        opacity: 0;\n      }\n\n      #waves,\n      .wave {\n        overflow: hidden;\n      }\n\n      .wave-container,\n      .wave {\n        border-radius: 50%;\n      }\n\n      :host(.circle) #background,\n      :host(.circle) #waves {\n        border-radius: 50%;\n      }\n\n      :host(.circle) .wave-container {\n        overflow: hidden;\n      }\n    </style>\n\n    <div id=\"background\"></div>\n    <div id=\"waves\"></div>\n  </template>\n</dom-module>\n<iron-iconset-svg name=\"paper-dropdown-menu\" size=\"24\">\n<svg><defs>\n<g id=\"arrow-drop-down\"><path d=\"M7 10l5 5 5-5z\"></path></g>\n</defs></svg>\n</iron-iconset-svg>\n<dom-module id=\"paper-dropdown-menu-shared-styles\" assetpath=\"/paper-dropdown-menu/\">\n  <template>\n    <style>\n      :host {\n        display: inline-block;\n        position: relative;\n        text-align: left;\n\n        /* NOTE(cdata): Both values are needed, since some phones require the\n         * value to be `transparent`.\n         */\n        -webkit-tap-highlight-color: rgba(0,0,0,0);\n        -webkit-tap-highlight-color: transparent;\n\n        --paper-input-container-input: {\n          overflow: hidden;\n          white-space: nowrap;\n          text-overflow: ellipsis;\n          max-width: 100%;\n          box-sizing: border-box;\n          cursor: pointer;\n        };\n\n        @apply(--paper-dropdown-menu);\n      }\n\n      :host([disabled]) {\n        @apply(--paper-dropdown-menu-disabled);\n      }\n\n      :host([noink]) paper-ripple {\n        display: none;\n      }\n\n      :host([no-label-float]) paper-ripple {\n        top: 8px;\n      }\n\n      paper-ripple {\n        top: 12px;\n        left: 0px;\n        bottom: 8px;\n        right: 0px;\n\n        @apply(--paper-dropdown-menu-ripple);\n      }\n\n      paper-menu-button {\n        display: block;\n        padding: 0;\n\n        @apply(--paper-dropdown-menu-button);\n      }\n\n      paper-input {\n        @apply(--paper-dropdown-menu-input);\n      }\n\n      iron-icon {\n        color: var(--disabled-text-color);\n\n        @apply(--paper-dropdown-menu-icon);\n      }\n    </style>\n  </template>\n</dom-module>\n<dom-module id=\"paper-dropdown-menu\" assetpath=\"/paper-dropdown-menu/\">\n  <template>\n    <style include=\"paper-dropdown-menu-shared-styles\"></style>\n\n    \n    <span role=\"button\"></span>\n    <paper-menu-button id=\"menuButton\" vertical-align=\"[[verticalAlign]]\" horizontal-align=\"[[horizontalAlign]]\" dynamic-align=\"[[dynamicAlign]]\" vertical-offset=\"[[qF(noLabelFloat)]]\" disabled=\"[[disabled]]\" no-animations=\"[[noAnimations]]\" on-iron-select=\"Zv\" on-iron-deselect=\"xG\" opened=\"{{opened}}\" close-on-activate=\"\" allow-outside-scroll=\"[[allowOutsideScroll]]\" restore-focus-on-close=\"[[restoreFocusOnClose]]\">\n      <div class=\"dropdown-trigger\">\n        <paper-ripple></paper-ripple>\n        \n        <paper-input type=\"text\" invalid=\"[[invalid]]\" readonly disabled=\"[[disabled]]\" value=\"[[selectedItemLabel]]\" placeholder=\"[[placeholder]]\" error-message=\"[[errorMessage]]\" always-float-label=\"[[alwaysFloatLabel]]\" no-label-float=\"[[noLabelFloat]]\" label=\"[[label]]\">\n          <iron-icon icon=\"paper-dropdown-menu:arrow-drop-down\" suffix=\"\"></iron-icon>\n        </paper-input>\n      </div>\n      <content id=\"content\" select=\".dropdown-content\"></content>\n    </paper-menu-button>\n  </template>\n\n  </dom-module>\n\n\n\n\n<dom-module id=\"paper-item-shared-styles\" assetpath=\"/paper-item/\">\n  <template>\n    <style>\n      :host {\n        display: block;\n        position: relative;\n        min-height: var(--paper-item-min-height, 48px);\n        padding: 0px 16px;\n      }\n\n      :host([hidden]) {\n        display: none !important;\n      }\n\n      :host(.iron-selected) {\n        font-weight: var(--paper-item-selected-weight, bold);\n\n        @apply(--paper-item-selected);\n      }\n\n      :host([disabled]) {\n        color: var(--paper-item-disabled-color, --disabled-text-color);\n\n        @apply(--paper-item-disabled);\n      }\n\n      :host(:focus) {\n        position: relative;\n        outline: 0;\n\n        @apply(--paper-item-focused);\n      }\n\n      :host(:focus):before {\n        @apply(--layout-fit);\n\n        background: currentColor;\n        content: '';\n        opacity: var(--dark-divider-opacity);\n        pointer-events: none;\n\n        @apply(--paper-item-focused-before);\n      }\n    </style>\n  </template>\n</dom-module>\n<dom-module id=\"paper-item\" assetpath=\"/paper-item/\">\n  <template>\n    <style include=\"paper-item-shared-styles\"></style>\n    <style>\n      :host {\n        @apply(--layout-horizontal);\n        @apply(--layout-center);\n        @apply(--paper-font-subhead);\n\n        @apply(--paper-item);\n      }\n    </style>\n\n    <content></content>\n  </template>\n\n  </dom-module>\n\n\n<dom-module id=\"paper-listbox\" assetpath=\"/paper-listbox/\">\n  <template>\n    <style>\n      :host {\n        display: block;\n        padding: 8px 0;\n\n        background: var(--paper-listbox-background-color, --primary-background-color);\n        color: var(--paper-listbox-color, --primary-text-color);\n\n        @apply(--paper-listbox);\n      }\n    </style>\n\n    <content></content>\n  </template>\n\n  </dom-module>\n\n\n<dom-module id=\"paper-progress\" assetpath=\"/paper-progress/\">\n  <template>\n    <style>\n      :host {\n        display: block;\n        width: 200px;\n        position: relative;\n        overflow: hidden;\n      }\n\n      #progressContainer {\n        position: relative;\n      }\n\n      #progressContainer,\n      /* the stripe for the indeterminate animation*/\n      .indeterminate::after {\n        height: var(--paper-progress-height, 4px);\n      }\n\n      #primaryProgress,\n      #secondaryProgress,\n      .indeterminate::after {\n        @apply(--layout-fit);\n      }\n\n      #progressContainer,\n      .indeterminate::after {\n        background: var(--paper-progress-container-color, --google-grey-300);\n      }\n\n      :host(.transiting) #primaryProgress,\n      :host(.transiting) #secondaryProgress {\n        -webkit-transition-property: -webkit-transform;\n        transition-property: transform;\n\n        /* Duration */\n        -webkit-transition-duration: var(--paper-progress-transition-duration, 0.08s);\n        transition-duration: var(--paper-progress-transition-duration, 0.08s);\n\n        /* Timing function */\n        -webkit-transition-timing-function: var(--paper-progress-transition-timing-function, ease);\n        transition-timing-function: var(--paper-progress-transition-timing-function, ease);\n\n        /* Delay */\n        -webkit-transition-delay: var(--paper-progress-transition-delay, 0s);\n        transition-delay: var(--paper-progress-transition-delay, 0s);\n      }\n\n      #primaryProgress,\n      #secondaryProgress {\n        @apply(--layout-fit);\n        -webkit-transform-origin: left center;\n        transform-origin: left center;\n        -webkit-transform: scaleX(0);\n        transform: scaleX(0);\n        will-change: transform;\n      }\n\n      #primaryProgress {\n        background: var(--paper-progress-active-color, --google-green-500);\n      }\n\n      #secondaryProgress {\n        background: var(--paper-progress-secondary-color, --google-green-100);\n      }\n\n      :host([disabled]) #primaryProgress {\n        background: var(--paper-progress-disabled-active-color, --google-grey-500);\n      }\n\n      :host([disabled]) #secondaryProgress {\n        background: var(--paper-progress-disabled-secondary-color, --google-grey-300);\n      }\n\n      :host(:not([disabled])) #primaryProgress.indeterminate {\n        -webkit-transform-origin: right center;\n        transform-origin: right center;\n        -webkit-animation: indeterminate-bar 2s linear infinite;\n        animation: indeterminate-bar 2s linear infinite;\n      }\n\n      :host(:not([disabled])) #primaryProgress.indeterminate::after {\n        content: \"\";\n        -webkit-transform-origin: center center;\n        transform-origin: center center;\n\n        -webkit-animation: indeterminate-splitter 2s linear infinite;\n        animation: indeterminate-splitter 2s linear infinite;\n      }\n\n      @-webkit-keyframes indeterminate-bar {\n        0% {\n          -webkit-transform: scaleX(1) translateX(-100%);\n        }\n        50% {\n          -webkit-transform: scaleX(1) translateX(0%);\n        }\n        75% {\n          -webkit-transform: scaleX(1) translateX(0%);\n          -webkit-animation-timing-function: cubic-bezier(.28,.62,.37,.91);\n        }\n        100% {\n          -webkit-transform: scaleX(0) translateX(0%);\n        }\n      }\n\n      @-webkit-keyframes indeterminate-splitter {\n        0% {\n          -webkit-transform: scaleX(.75) translateX(-125%);\n        }\n        30% {\n          -webkit-transform: scaleX(.75) translateX(-125%);\n          -webkit-animation-timing-function: cubic-bezier(.42,0,.6,.8);\n        }\n        90% {\n          -webkit-transform: scaleX(.75) translateX(125%);\n        }\n        100% {\n          -webkit-transform: scaleX(.75) translateX(125%);\n        }\n      }\n\n      @keyframes indeterminate-bar {\n        0% {\n          transform: scaleX(1) translateX(-100%);\n        }\n        50% {\n          transform: scaleX(1) translateX(0%);\n        }\n        75% {\n          transform: scaleX(1) translateX(0%);\n          animation-timing-function: cubic-bezier(.28,.62,.37,.91);\n        }\n        100% {\n          transform: scaleX(0) translateX(0%);\n        }\n      }\n\n      @keyframes indeterminate-splitter {\n        0% {\n          transform: scaleX(.75) translateX(-125%);\n        }\n        30% {\n          transform: scaleX(.75) translateX(-125%);\n          animation-timing-function: cubic-bezier(.42,0,.6,.8);\n        }\n        90% {\n          transform: scaleX(.75) translateX(125%);\n        }\n        100% {\n          transform: scaleX(.75) translateX(125%);\n        }\n      }\n    </style>\n\n    <div id=\"progressContainer\">\n      <div id=\"secondaryProgress\" hidden$=\"[[s0(secondaryRatio)]]\"></div>\n      <div id=\"primaryProgress\"></div>\n    </div>\n  </template>\n</dom-module>\n\n<dom-module id=\"paper-slider\" assetpath=\"/paper-slider/\">\n  <template strip-whitespace=\"\">\n    <style>\n      :host {\n        @apply(--layout);\n        @apply(--layout-justified);\n        @apply(--layout-center);\n        width: 200px;\n        cursor: default;\n        -webkit-user-select: none;\n        -moz-user-select: none;\n        -ms-user-select: none;\n        user-select: none;\n        -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n        --paper-progress-active-color: var(--paper-slider-active-color, --google-blue-700);\n        --paper-progress-secondary-color: var(--paper-slider-secondary-color, --google-blue-300);\n        --paper-progress-disabled-active-color: var(--paper-slider-disabled-active-color, --paper-grey-400);\n        --paper-progress-disabled-secondary-color: var(--paper-slider-disabled-secondary-color, --paper-grey-400);\n      }\n\n      /* focus shows the ripple */\n      :host(:focus) {\n        outline: none;\n      }\n\n      #sliderContainer {\n        position: relative;\n        width: 100%;\n        height: calc(30px + var(--paper-slider-height, 2px));\n        margin-left: calc(15px + var(--paper-slider-height, 2px)/2);\n        margin-right: calc(15px + var(--paper-slider-height, 2px)/2);\n      }\n\n      #sliderContainer:focus {\n        outline: 0;\n      }\n\n      #sliderContainer.editable {\n        margin-top: 12px;\n        margin-bottom: 12px;\n      }\n\n      .bar-container {\n        position: absolute;\n        top: 0;\n        bottom: 0;\n        left: 0;\n        right: 0;\n        overflow: hidden;\n      }\n\n      .ring > .bar-container {\n        left: calc(5px + var(--paper-slider-height, 2px)/2);\n        transition: left 0.18s ease;\n      }\n\n      .ring.expand.dragging > .bar-container {\n        transition: none;\n      }\n\n      .ring.expand:not(.pin) > .bar-container {\n        left: calc(8px + var(--paper-slider-height, 2px)/2);\n      }\n\n      #sliderBar {\n        padding: 15px 0;\n        width: 100%;\n        background-color: var(--paper-slider-bar-color, transparent);\n        --paper-progress-container-color: var(--paper-grey-400);\n        --paper-progress-height: var(--paper-slider-height, 2px);\n      }\n\n      .slider-markers {\n        position: absolute;\n        top: calc(14px + var(--paper-slider-height,2px)/2);\n        height: var(--paper-slider-height, 2px);\n        left: 0;\n        right: -1px;\n        box-sizing: border-box;\n        pointer-events: none;\n        @apply(--layout-horizontal);\n      }\n\n      .slider-marker {\n        @apply(--layout-flex);\n      }\n      .slider-markers::after,\n      .slider-marker::after {\n        content: \"\";\n        display: block;\n        margin-left: -1px;\n        width: 2px;\n        height: 2px;\n        border-radius: 50%;\n        background-color: black;\n      }\n\n      #sliderKnob {\n        position: absolute;\n        left: 0;\n        top: 0;\n        margin-left: calc(-15px - var(--paper-slider-height, 2px)/2);\n        width: calc(30px + var(--paper-slider-height, 2px));\n        height: calc(30px + var(--paper-slider-height, 2px));\n      }\n\n      .transiting > #sliderKnob {\n        transition: left 0.08s ease;\n      }\n\n      #sliderKnob:focus {\n        outline: none;\n      }\n\n      #sliderKnob.dragging {\n        transition: none;\n      }\n\n      .snaps > #sliderKnob.dragging {\n        transition: -webkit-transform 0.08s ease;\n        transition: transform 0.08s ease;\n      }\n\n      #sliderKnobInner {\n        margin: 10px;\n        width: calc(100% - 20px);\n        height: calc(100% - 20px);\n        background-color: var(--paper-slider-knob-color, --google-blue-700);\n        border: 2px solid var(--paper-slider-knob-color, --google-blue-700);\n        border-radius: 50%;\n\n        -moz-box-sizing: border-box;\n        box-sizing: border-box;\n\n        transition-property: -webkit-transform, background-color, border;\n        transition-property: transform, background-color, border;\n        transition-duration: 0.18s;\n        transition-timing-function: ease;\n      }\n\n      .expand:not(.pin) > #sliderKnob > #sliderKnobInner {\n        -webkit-transform: scale(1.5);\n        transform: scale(1.5);\n      }\n\n      .ring > #sliderKnob > #sliderKnobInner {\n        background-color: var(--paper-slider-knob-start-color, transparent);\n        border: 2px solid var(--paper-slider-knob-start-border-color, --paper-grey-400);\n      }\n\n      #sliderKnobInner::before {\n        background-color: var(--paper-slider-pin-color, --google-blue-700);\n      }\n\n      .pin > #sliderKnob > #sliderKnobInner::before {\n        content: \"\";\n        position: absolute;\n        top: 0;\n        left: 50%;\n        margin-left: -13px;\n        width: 26px;\n        height: 26px;\n        border-radius: 50% 50% 50% 0;\n\n        -webkit-transform: rotate(-45deg) scale(0) translate(0);\n        transform: rotate(-45deg) scale(0) translate(0);\n      }\n\n      #sliderKnobInner::before,\n      #sliderKnobInner::after {\n        transition: -webkit-transform .18s ease, background-color .18s ease;\n        transition: transform .18s ease, background-color .18s ease;\n      }\n\n      .pin.ring > #sliderKnob > #sliderKnobInner::before {\n        background-color: var(--paper-slider-pin-start-color, --paper-grey-400);\n      }\n\n      .pin.expand > #sliderKnob > #sliderKnobInner::before {\n        -webkit-transform: rotate(-45deg) scale(1) translate(17px, -17px);\n        transform: rotate(-45deg) scale(1) translate(17px, -17px);\n      }\n\n      .pin > #sliderKnob > #sliderKnobInner::after {\n        content: attr(value);\n        position: absolute;\n        top: 0;\n        left: 50%;\n        margin-left: -16px;\n        width: 32px;\n        height: 26px;\n        text-align: center;\n        color: var(--paper-slider-font-color, #fff);\n        font-size: 10px;\n\n        -webkit-transform: scale(0) translate(0);\n        transform: scale(0) translate(0);\n      }\n\n      .pin.expand > #sliderKnob > #sliderKnobInner::after {\n        -webkit-transform: scale(1) translate(0, -17px);\n        transform: scale(1) translate(0, -17px);\n      }\n\n      /* paper-input */\n      .slider-input {\n        width: 50px;\n        overflow: hidden;\n        --paper-input-container-input: {\n          text-align: center;\n        };\n        @apply(--paper-slider-input);\n      }\n\n      /* disabled state */\n      #sliderContainer.disabled {\n        pointer-events: none;\n      }\n\n      .disabled > #sliderKnob > #sliderKnobInner {\n        background-color: var(--paper-slider-disabled-knob-color, --paper-grey-400);\n        border: 2px solid var(--paper-slider-disabled-knob-color, --paper-grey-400);\n        -webkit-transform: scale3d(0.75, 0.75, 1);\n        transform: scale3d(0.75, 0.75, 1);\n      }\n\n      .disabled.ring > #sliderKnob > #sliderKnobInner {\n        background-color: var(--paper-slider-knob-start-color, transparent);\n        border: 2px solid var(--paper-slider-knob-start-border-color, --paper-grey-400);\n      }\n\n      paper-ripple {\n        color: var(--paper-slider-knob-color, --google-blue-700);\n      }\n    </style>\n\n    <div id=\"sliderContainer\" class$=\"[[n0(disabled,pin,snaps,immediateValue,min,expand,dragging,transiting,editable)]]\">\n\n      <div class=\"bar-container\">\n        <paper-progress disabled$=\"[[disabled]]\" id=\"sliderBar\" aria-hidden=\"true\" min=\"[[min]]\" max=\"[[max]]\" step=\"[[step]]\" value=\"[[immediateValue]]\" secondary-progress=\"[[secondaryProgress]]\" on-down=\"K_\" on-up=\"LG\" on-track=\"Z0\">\n        </paper-progress>\n      </div>\n\n      <template is=\"dom-if\" if=\"[[snaps]]\">\n        <div class=\"slider-markers\">\n          <template is=\"dom-repeat\" items=\"[[markers]]\">\n            <div class=\"slider-marker\"></div>\n          </template>\n        </div>\n      </template>\n\n      <div id=\"sliderKnob\" on-down=\"C0\" on-up=\"LG\" on-track=\"Z0\" on-transitionend=\"B0\">\n          <div id=\"sliderKnobInner\" value$=\"[[immediateValue]]\"></div>\n      </div>\n    </div>\n\n    <template is=\"dom-if\" if=\"[[editable]]\">\n      <paper-input id=\"input\" type=\"number\" step=\"[[step]]\" min=\"[[min]]\" max=\"[[max]]\" class=\"slider-input\" disabled$=\"[[disabled]]\" value=\"[[immediateValue]]\" on-change=\"M_\" on-keydown=\"z0\" no-label-float=\"\">\n      </paper-input>\n    </template>\n  </template>\n\n  </dom-module>\n<iron-iconset-svg name=\"icons\" size=\"24\">\n<svg><defs>\n<g id=\"3d-rotation\"><path d=\"M7.52 21.48C4.25 19.94 1.91 16.76 1.55 13H.05C.56 19.16 5.71 24 12 24l.66-.03-3.81-3.81-1.33 1.32zm.89-6.52c-.19 0-.37-.03-.52-.08-.16-.06-.29-.13-.4-.24-.11-.1-.2-.22-.26-.37-.06-.14-.09-.3-.09-.47h-1.3c0 .36.07.68.21.95.14.27.33.5.56.69.24.18.51.32.82.41.3.1.62.15.96.15.37 0 .72-.05 1.03-.15.32-.1.6-.25.83-.44s.42-.43.55-.72c.13-.29.2-.61.2-.97 0-.19-.02-.38-.07-.56-.05-.18-.12-.35-.23-.51-.1-.16-.24-.3-.4-.43-.17-.13-.37-.23-.61-.31.2-.09.37-.2.52-.33.15-.13.27-.27.37-.42.1-.15.17-.3.22-.46.05-.16.07-.32.07-.48 0-.36-.06-.68-.18-.96-.12-.28-.29-.51-.51-.69-.2-.19-.47-.33-.77-.43C9.1 8.05 8.76 8 8.39 8c-.36 0-.69.05-1 .16-.3.11-.57.26-.79.45-.21.19-.38.41-.51.67-.12.26-.18.54-.18.85h1.3c0-.17.03-.32.09-.45s.14-.25.25-.34c.11-.09.23-.17.38-.22.15-.05.3-.08.48-.08.4 0 .7.1.89.31.19.2.29.49.29.86 0 .18-.03.34-.08.49-.05.15-.14.27-.25.37-.11.1-.25.18-.41.24-.16.06-.36.09-.58.09H7.5v1.03h.77c.22 0 .42.02.6.07s.33.13.45.23c.12.11.22.24.29.4.07.16.1.35.1.57 0 .41-.12.72-.35.93-.23.23-.55.33-.95.33zm8.55-5.92c-.32-.33-.7-.59-1.14-.77-.43-.18-.92-.27-1.46-.27H12v8h2.3c.55 0 1.06-.09 1.51-.27.45-.18.84-.43 1.16-.76.32-.33.57-.73.74-1.19.17-.47.26-.99.26-1.57v-.4c0-.58-.09-1.1-.26-1.57-.18-.47-.43-.87-.75-1.2zm-.39 3.16c0 .42-.05.79-.14 1.13-.1.33-.24.62-.43.85-.19.23-.43.41-.71.53-.29.12-.62.18-.99.18h-.91V9.12h.97c.72 0 1.27.23 1.64.69.38.46.57 1.12.57 1.99v.4zM12 0l-.66.03 3.81 3.81 1.33-1.33c3.27 1.55 5.61 4.72 5.96 8.48h1.5C23.44 4.84 18.29 0 12 0z\"></path></g>\n<g id=\"accessibility\"><path d=\"M12 2c1.1 0 2 .9 2 2s-.9 2-2 2-2-.9-2-2 .9-2 2-2zm9 7h-6v13h-2v-6h-2v6H9V9H3V7h18v2z\"></path></g>\n<g id=\"accessible\"><circle cx=\"12\" cy=\"4\" r=\"2\"></circle><path d=\"M19 13v-2c-1.54.02-3.09-.75-4.07-1.83l-1.29-1.43c-.17-.19-.38-.34-.61-.45-.01 0-.01-.01-.02-.01H13c-.35-.2-.75-.3-1.19-.26C10.76 7.11 10 8.04 10 9.09V15c0 1.1.9 2 2 2h5v5h2v-5.5c0-1.1-.9-2-2-2h-3v-3.45c1.29 1.07 3.25 1.94 5 1.95zm-6.17 5c-.41 1.16-1.52 2-2.83 2-1.66 0-3-1.34-3-3 0-1.31.84-2.41 2-2.83V12.1c-2.28.46-4 2.48-4 4.9 0 2.76 2.24 5 5 5 2.42 0 4.44-1.72 4.9-4h-2.07z\"></path></g>\n<g id=\"account-balance\"><path d=\"M4 10v7h3v-7H4zm6 0v7h3v-7h-3zM2 22h19v-3H2v3zm14-12v7h3v-7h-3zm-4.5-9L2 6v2h19V6l-9.5-5z\"></path></g>\n<g id=\"account-balance-wallet\"><path d=\"M21 18v1c0 1.1-.9 2-2 2H5c-1.11 0-2-.9-2-2V5c0-1.1.89-2 2-2h14c1.1 0 2 .9 2 2v1h-9c-1.11 0-2 .9-2 2v8c0 1.1.89 2 2 2h9zm-9-2h10V8H12v8zm4-2.5c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5z\"></path></g>\n<g id=\"account-box\"><path d=\"M3 5v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2H5c-1.11 0-2 .9-2 2zm12 4c0 1.66-1.34 3-3 3s-3-1.34-3-3 1.34-3 3-3 3 1.34 3 3zm-9 8c0-2 4-3.1 6-3.1s6 1.1 6 3.1v1H6v-1z\"></path></g>\n<g id=\"account-circle\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 3c1.66 0 3 1.34 3 3s-1.34 3-3 3-3-1.34-3-3 1.34-3 3-3zm0 14.2c-2.5 0-4.71-1.28-6-3.22.03-1.99 4-3.08 6-3.08 1.99 0 5.97 1.09 6 3.08-1.29 1.94-3.5 3.22-6 3.22z\"></path></g>\n<g id=\"add\"><path d=\"M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z\"></path></g>\n<g id=\"add-alert\"><path d=\"M10.01 21.01c0 1.1.89 1.99 1.99 1.99s1.99-.89 1.99-1.99h-3.98zm8.87-4.19V11c0-3.25-2.25-5.97-5.29-6.69v-.72C13.59 2.71 12.88 2 12 2s-1.59.71-1.59 1.59v.72C7.37 5.03 5.12 7.75 5.12 11v5.82L3 18.94V20h18v-1.06l-2.12-2.12zM16 13.01h-3v3h-2v-3H8V11h3V8h2v3h3v2.01z\"></path></g>\n<g id=\"add-box\"><path d=\"M19 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-2 10h-4v4h-2v-4H7v-2h4V7h2v4h4v2z\"></path></g>\n<g id=\"add-circle\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm5 11h-4v4h-2v-4H7v-2h4V7h2v4h4v2z\"></path></g>\n<g id=\"add-circle-outline\"><path d=\"M13 7h-2v4H7v2h4v4h2v-4h4v-2h-4V7zm-1-5C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z\"></path></g>\n<g id=\"add-shopping-cart\"><path d=\"M11 9h2V6h3V4h-3V1h-2v3H8v2h3v3zm-4 9c-1.1 0-1.99.9-1.99 2S5.9 22 7 22s2-.9 2-2-.9-2-2-2zm10 0c-1.1 0-1.99.9-1.99 2s.89 2 1.99 2 2-.9 2-2-.9-2-2-2zm-9.83-3.25l.03-.12.9-1.63h7.45c.75 0 1.41-.41 1.75-1.03l3.86-7.01L19.42 4h-.01l-1.1 2-2.76 5H8.53l-.13-.27L6.16 6l-.95-2-.94-2H1v2h2l3.6 7.59-1.35 2.45c-.16.28-.25.61-.25.96 0 1.1.9 2 2 2h12v-2H7.42c-.13 0-.25-.11-.25-.25z\"></path></g>\n<g id=\"alarm\"><path d=\"M22 5.72l-4.6-3.86-1.29 1.53 4.6 3.86L22 5.72zM7.88 3.39L6.6 1.86 2 5.71l1.29 1.53 4.59-3.85zM12.5 8H11v6l4.75 2.85.75-1.23-4-2.37V8zM12 4c-4.97 0-9 4.03-9 9s4.02 9 9 9c4.97 0 9-4.03 9-9s-4.03-9-9-9zm0 16c-3.87 0-7-3.13-7-7s3.13-7 7-7 7 3.13 7 7-3.13 7-7 7z\"></path></g>\n<g id=\"alarm-add\"><path d=\"M7.88 3.39L6.6 1.86 2 5.71l1.29 1.53 4.59-3.85zM22 5.72l-4.6-3.86-1.29 1.53 4.6 3.86L22 5.72zM12 4c-4.97 0-9 4.03-9 9s4.02 9 9 9c4.97 0 9-4.03 9-9s-4.03-9-9-9zm0 16c-3.87 0-7-3.13-7-7s3.13-7 7-7 7 3.13 7 7-3.13 7-7 7zm1-11h-2v3H8v2h3v3h2v-3h3v-2h-3V9z\"></path></g>\n<g id=\"alarm-off\"><path d=\"M12 6c3.87 0 7 3.13 7 7 0 .84-.16 1.65-.43 2.4l1.52 1.52c.58-1.19.91-2.51.91-3.92 0-4.97-4.03-9-9-9-1.41 0-2.73.33-3.92.91L9.6 6.43C10.35 6.16 11.16 6 12 6zm10-.28l-4.6-3.86-1.29 1.53 4.6 3.86L22 5.72zM2.92 2.29L1.65 3.57 2.98 4.9l-1.11.93 1.42 1.42 1.11-.94.8.8C3.83 8.69 3 10.75 3 13c0 4.97 4.02 9 9 9 2.25 0 4.31-.83 5.89-2.2l2.2 2.2 1.27-1.27L3.89 3.27l-.97-.98zm13.55 16.1C15.26 19.39 13.7 20 12 20c-3.87 0-7-3.13-7-7 0-1.7.61-3.26 1.61-4.47l9.86 9.86zM8.02 3.28L6.6 1.86l-.86.71 1.42 1.42.86-.71z\"></path></g>\n<g id=\"alarm-on\"><path d=\"M22 5.72l-4.6-3.86-1.29 1.53 4.6 3.86L22 5.72zM7.88 3.39L6.6 1.86 2 5.71l1.29 1.53 4.59-3.85zM12 4c-4.97 0-9 4.03-9 9s4.02 9 9 9c4.97 0 9-4.03 9-9s-4.03-9-9-9zm0 16c-3.87 0-7-3.13-7-7s3.13-7 7-7 7 3.13 7 7-3.13 7-7 7zm-1.46-5.47L8.41 12.4l-1.06 1.06 3.18 3.18 6-6-1.06-1.06-4.93 4.95z\"></path></g>\n<g id=\"all-out\"><path d=\"M16.21 4.16l4 4v-4zm4 12l-4 4h4zm-12 4l-4-4v4zm-4-12l4-4h-4zm12.95-.95c-2.73-2.73-7.17-2.73-9.9 0s-2.73 7.17 0 9.9 7.17 2.73 9.9 0 2.73-7.16 0-9.9zm-1.1 8.8c-2.13 2.13-5.57 2.13-7.7 0s-2.13-5.57 0-7.7 5.57-2.13 7.7 0 2.13 5.57 0 7.7z\"></path></g>\n<g id=\"android\"><path d=\"M6 18c0 .55.45 1 1 1h1v3.5c0 .83.67 1.5 1.5 1.5s1.5-.67 1.5-1.5V19h2v3.5c0 .83.67 1.5 1.5 1.5s1.5-.67 1.5-1.5V19h1c.55 0 1-.45 1-1V8H6v10zM3.5 8C2.67 8 2 8.67 2 9.5v7c0 .83.67 1.5 1.5 1.5S5 17.33 5 16.5v-7C5 8.67 4.33 8 3.5 8zm17 0c-.83 0-1.5.67-1.5 1.5v7c0 .83.67 1.5 1.5 1.5s1.5-.67 1.5-1.5v-7c0-.83-.67-1.5-1.5-1.5zm-4.97-5.84l1.3-1.3c.2-.2.2-.51 0-.71-.2-.2-.51-.2-.71 0l-1.48 1.48C13.85 1.23 12.95 1 12 1c-.96 0-1.86.23-2.66.63L7.85.15c-.2-.2-.51-.2-.71 0-.2.2-.2.51 0 .71l1.31 1.31C6.97 3.26 6 5.01 6 7h12c0-1.99-.97-3.75-2.47-4.84zM10 5H9V4h1v1zm5 0h-1V4h1v1z\"></path></g>\n<g id=\"announcement\"><path d=\"M20 2H4c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-7 9h-2V5h2v6zm0 4h-2v-2h2v2z\"></path></g>\n<g id=\"apps\"><path d=\"M4 8h4V4H4v4zm6 12h4v-4h-4v4zm-6 0h4v-4H4v4zm0-6h4v-4H4v4zm6 0h4v-4h-4v4zm6-10v4h4V4h-4zm-6 4h4V4h-4v4zm6 6h4v-4h-4v4zm0 6h4v-4h-4v4z\"></path></g>\n<g id=\"archive\"><path d=\"M20.54 5.23l-1.39-1.68C18.88 3.21 18.47 3 18 3H6c-.47 0-.88.21-1.16.55L3.46 5.23C3.17 5.57 3 6.02 3 6.5V19c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V6.5c0-.48-.17-.93-.46-1.27zM12 17.5L6.5 12H10v-2h4v2h3.5L12 17.5zM5.12 5l.81-1h12l.94 1H5.12z\"></path></g>\n<g id=\"arrow-back\"><path d=\"M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2z\"></path></g>\n<g id=\"arrow-downward\"><path d=\"M20 12l-1.41-1.41L13 16.17V4h-2v12.17l-5.58-5.59L4 12l8 8 8-8z\"></path></g>\n<g id=\"arrow-drop-down\"><path d=\"M7 10l5 5 5-5z\"></path></g>\n<g id=\"arrow-drop-down-circle\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 12l-4-4h8l-4 4z\"></path></g>\n<g id=\"arrow-drop-up\"><path d=\"M7 14l5-5 5 5z\"></path></g>\n<g id=\"arrow-forward\"><path d=\"M12 4l-1.41 1.41L16.17 11H4v2h12.17l-5.58 5.59L12 20l8-8z\"></path></g>\n<g id=\"arrow-upward\"><path d=\"M4 12l1.41 1.41L11 7.83V20h2V7.83l5.58 5.59L20 12l-8-8-8 8z\"></path></g>\n<g id=\"aspect-ratio\"><path d=\"M19 12h-2v3h-3v2h5v-5zM7 9h3V7H5v5h2V9zm14-6H3c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16.01H3V4.99h18v14.02z\"></path></g>\n<g id=\"assessment\"><path d=\"M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM9 17H7v-7h2v7zm4 0h-2V7h2v10zm4 0h-2v-4h2v4z\"></path></g>\n<g id=\"assignment\"><path d=\"M19 3h-4.18C14.4 1.84 13.3 1 12 1c-1.3 0-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-7 0c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm2 14H7v-2h7v2zm3-4H7v-2h10v2zm0-4H7V7h10v2z\"></path></g>\n<g id=\"assignment-ind\"><path d=\"M19 3h-4.18C14.4 1.84 13.3 1 12 1c-1.3 0-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-7 0c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm0 4c1.66 0 3 1.34 3 3s-1.34 3-3 3-3-1.34-3-3 1.34-3 3-3zm6 12H6v-1.4c0-2 4-3.1 6-3.1s6 1.1 6 3.1V19z\"></path></g>\n<g id=\"assignment-late\"><path d=\"M19 3h-4.18C14.4 1.84 13.3 1 12 1c-1.3 0-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-6 15h-2v-2h2v2zm0-4h-2V8h2v6zm-1-9c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1z\"></path></g>\n<g id=\"assignment-return\"><path d=\"M19 3h-4.18C14.4 1.84 13.3 1 12 1c-1.3 0-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-7 0c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm4 12h-4v3l-5-5 5-5v3h4v4z\"></path></g>\n<g id=\"assignment-returned\"><path d=\"M19 3h-4.18C14.4 1.84 13.3 1 12 1c-1.3 0-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-7 0c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm0 15l-5-5h3V9h4v4h3l-5 5z\"></path></g>\n<g id=\"assignment-turned-in\"><path d=\"M19 3h-4.18C14.4 1.84 13.3 1 12 1c-1.3 0-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-7 0c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm-2 14l-4-4 1.41-1.41L10 14.17l6.59-6.59L18 9l-8 8z\"></path></g>\n<g id=\"attachment\"><path d=\"M2 12.5C2 9.46 4.46 7 7.5 7H18c2.21 0 4 1.79 4 4s-1.79 4-4 4H9.5C8.12 15 7 13.88 7 12.5S8.12 10 9.5 10H17v2H9.41c-.55 0-.55 1 0 1H18c1.1 0 2-.9 2-2s-.9-2-2-2H7.5C5.57 9 4 10.57 4 12.5S5.57 16 7.5 16H17v2H7.5C4.46 18 2 15.54 2 12.5z\"></path></g>\n<g id=\"autorenew\"><path d=\"M12 6v3l4-4-4-4v3c-4.42 0-8 3.58-8 8 0 1.57.46 3.03 1.24 4.26L6.7 14.8c-.45-.83-.7-1.79-.7-2.8 0-3.31 2.69-6 6-6zm6.76 1.74L17.3 9.2c.44.84.7 1.79.7 2.8 0 3.31-2.69 6-6 6v-3l-4 4 4 4v-3c4.42 0 8-3.58 8-8 0-1.57-.46-3.03-1.24-4.26z\"></path></g>\n<g id=\"backspace\"><path d=\"M22 3H7c-.69 0-1.23.35-1.59.88L0 12l5.41 8.11c.36.53.9.89 1.59.89h15c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-3 12.59L17.59 17 14 13.41 10.41 17 9 15.59 12.59 12 9 8.41 10.41 7 14 10.59 17.59 7 19 8.41 15.41 12 19 15.59z\"></path></g>\n<g id=\"backup\"><path d=\"M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM14 13v4h-4v-4H7l5-5 5 5h-3z\"></path></g>\n<g id=\"block\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zM4 12c0-4.42 3.58-8 8-8 1.85 0 3.55.63 4.9 1.69L5.69 16.9C4.63 15.55 4 13.85 4 12zm8 8c-1.85 0-3.55-.63-4.9-1.69L18.31 7.1C19.37 8.45 20 10.15 20 12c0 4.42-3.58 8-8 8z\"></path></g>\n<g id=\"book\"><path d=\"M18 2H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zM6 4h5v8l-2.5-1.5L6 12V4z\"></path></g>\n<g id=\"bookmark\"><path d=\"M17 3H7c-1.1 0-1.99.9-1.99 2L5 21l7-3 7 3V5c0-1.1-.9-2-2-2z\"></path></g>\n<g id=\"bookmark-border\"><path d=\"M17 3H7c-1.1 0-1.99.9-1.99 2L5 21l7-3 7 3V5c0-1.1-.9-2-2-2zm0 15l-5-2.18L7 18V5h10v13z\"></path></g>\n<g id=\"bug-report\"><path d=\"M20 8h-2.81c-.45-.78-1.07-1.45-1.82-1.96L17 4.41 15.59 3l-2.17 2.17C12.96 5.06 12.49 5 12 5c-.49 0-.96.06-1.41.17L8.41 3 7 4.41l1.62 1.63C7.88 6.55 7.26 7.22 6.81 8H4v2h2.09c-.05.33-.09.66-.09 1v1H4v2h2v1c0 .34.04.67.09 1H4v2h2.81c1.04 1.79 2.97 3 5.19 3s4.15-1.21 5.19-3H20v-2h-2.09c.05-.33.09-.66.09-1v-1h2v-2h-2v-1c0-.34-.04-.67-.09-1H20V8zm-6 8h-4v-2h4v2zm0-4h-4v-2h4v2z\"></path></g>\n<g id=\"build\"><path d=\"M22.7 19l-9.1-9.1c.9-2.3.4-5-1.5-6.9-2-2-5-2.4-7.4-1.3L9 6 6 9 1.6 4.7C.4 7.1.9 10.1 2.9 12.1c1.9 1.9 4.6 2.4 6.9 1.5l9.1 9.1c.4.4 1 .4 1.4 0l2.3-2.3c.5-.4.5-1.1.1-1.4z\"></path></g>\n<g id=\"cached\"><path d=\"M19 8l-4 4h3c0 3.31-2.69 6-6 6-1.01 0-1.97-.25-2.8-.7l-1.46 1.46C8.97 19.54 10.43 20 12 20c4.42 0 8-3.58 8-8h3l-4-4zM6 12c0-3.31 2.69-6 6-6 1.01 0 1.97.25 2.8.7l1.46-1.46C15.03 4.46 13.57 4 12 4c-4.42 0-8 3.58-8 8H1l4 4 4-4H6z\"></path></g>\n<g id=\"camera-enhance\"><path d=\"M9 3L7.17 5H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2h-3.17L15 3H9zm3 15c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-1l1.25-2.75L16 13l-2.75-1.25L12 9l-1.25 2.75L8 13l2.75 1.25z\"></path></g>\n<g id=\"cancel\"><path d=\"M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm5 13.59L15.59 17 12 13.41 8.41 17 7 15.59 10.59 12 7 8.41 8.41 7 12 10.59 15.59 7 17 8.41 13.41 12 17 15.59z\"></path></g>\n<g id=\"card-giftcard\"><path d=\"M20 6h-2.18c.11-.31.18-.65.18-1 0-1.66-1.34-3-3-3-1.05 0-1.96.54-2.5 1.35l-.5.67-.5-.68C10.96 2.54 10.05 2 9 2 7.34 2 6 3.34 6 5c0 .35.07.69.18 1H4c-1.11 0-1.99.89-1.99 2L2 19c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V8c0-1.11-.89-2-2-2zm-5-2c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zM9 4c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm11 15H4v-2h16v2zm0-5H4V8h5.08L7 10.83 8.62 12 11 8.76l1-1.36 1 1.36L15.38 12 17 10.83 14.92 8H20v6z\"></path></g>\n<g id=\"card-membership\"><path d=\"M20 2H4c-1.11 0-2 .89-2 2v11c0 1.11.89 2 2 2h4v5l4-2 4 2v-5h4c1.11 0 2-.89 2-2V4c0-1.11-.89-2-2-2zm0 13H4v-2h16v2zm0-5H4V4h16v6z\"></path></g>\n<g id=\"card-travel\"><path d=\"M20 6h-3V4c0-1.11-.89-2-2-2H9c-1.11 0-2 .89-2 2v2H4c-1.11 0-2 .89-2 2v11c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V8c0-1.11-.89-2-2-2zM9 4h6v2H9V4zm11 15H4v-2h16v2zm0-5H4V8h3v2h2V8h6v2h2V8h3v6z\"></path></g>\n<g id=\"change-history\"><path d=\"M12 7.77L18.39 18H5.61L12 7.77M12 4L2 20h20L12 4z\"></path></g>\n<g id=\"check\"><path d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\"></path></g>\n<g id=\"check-box\"><path d=\"M19 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.11 0 2-.9 2-2V5c0-1.1-.89-2-2-2zm-9 14l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z\"></path></g>\n<g id=\"check-box-outline-blank\"><path d=\"M19 5v14H5V5h14m0-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z\"></path></g>\n<g id=\"check-circle\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z\"></path></g>\n<g id=\"chevron-left\"><path d=\"M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z\"></path></g>\n<g id=\"chevron-right\"><path d=\"M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z\"></path></g>\n<g id=\"chrome-reader-mode\"><path d=\"M13 12h7v1.5h-7zm0-2.5h7V11h-7zm0 5h7V16h-7zM21 4H3c-1.1 0-2 .9-2 2v13c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 15h-9V6h9v13z\"></path></g>\n<g id=\"class\"><path d=\"M18 2H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zM6 4h5v8l-2.5-1.5L6 12V4z\"></path></g>\n<g id=\"clear\"><path d=\"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"></path></g>\n<g id=\"close\"><path d=\"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"></path></g>\n<g id=\"cloud\"><path d=\"M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96z\"></path></g>\n<g id=\"cloud-circle\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm4.5 14H8c-1.66 0-3-1.34-3-3s1.34-3 3-3l.14.01C8.58 8.28 10.13 7 12 7c2.21 0 4 1.79 4 4h.5c1.38 0 2.5 1.12 2.5 2.5S17.88 16 16.5 16z\"></path></g>\n<g id=\"cloud-done\"><path d=\"M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM10 17l-3.5-3.5 1.41-1.41L10 14.17 15.18 9l1.41 1.41L10 17z\"></path></g>\n<g id=\"cloud-download\"><path d=\"M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM17 13l-5 5-5-5h3V9h4v4h3z\"></path></g>\n<g id=\"cloud-off\"><path d=\"M19.35 10.04C18.67 6.59 15.64 4 12 4c-1.48 0-2.85.43-4.01 1.17l1.46 1.46C10.21 6.23 11.08 6 12 6c3.04 0 5.5 2.46 5.5 5.5v.5H19c1.66 0 3 1.34 3 3 0 1.13-.64 2.11-1.56 2.62l1.45 1.45C23.16 18.16 24 16.68 24 15c0-2.64-2.05-4.78-4.65-4.96zM3 5.27l2.75 2.74C2.56 8.15 0 10.77 0 14c0 3.31 2.69 6 6 6h11.73l2 2L21 20.73 4.27 4 3 5.27zM7.73 10l8 8H6c-2.21 0-4-1.79-4-4s1.79-4 4-4h1.73z\"></path></g>\n<g id=\"cloud-queue\"><path d=\"M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM19 18H6c-2.21 0-4-1.79-4-4s1.79-4 4-4h.71C7.37 7.69 9.48 6 12 6c3.04 0 5.5 2.46 5.5 5.5v.5H19c1.66 0 3 1.34 3 3s-1.34 3-3 3z\"></path></g>\n<g id=\"cloud-upload\"><path d=\"M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM14 13v4h-4v-4H7l5-5 5 5h-3z\"></path></g>\n<g id=\"code\"><path d=\"M9.4 16.6L4.8 12l4.6-4.6L8 6l-6 6 6 6 1.4-1.4zm5.2 0l4.6-4.6-4.6-4.6L16 6l6 6-6 6-1.4-1.4z\"></path></g>\n<g id=\"compare-arrows\"><path d=\"M9.01 14H2v2h7.01v3L13 15l-3.99-4v3zm5.98-1v-3H22V8h-7.01V5L11 9l3.99 4z\"></path></g>\n<g id=\"content-copy\"><path d=\"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z\"></path></g>\n<g id=\"content-cut\"><path d=\"M9.64 7.64c.23-.5.36-1.05.36-1.64 0-2.21-1.79-4-4-4S2 3.79 2 6s1.79 4 4 4c.59 0 1.14-.13 1.64-.36L10 12l-2.36 2.36C7.14 14.13 6.59 14 6 14c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4c0-.59-.13-1.14-.36-1.64L12 14l7 7h3v-1L9.64 7.64zM6 8c-1.1 0-2-.89-2-2s.9-2 2-2 2 .89 2 2-.9 2-2 2zm0 12c-1.1 0-2-.89-2-2s.9-2 2-2 2 .89 2 2-.9 2-2 2zm6-7.5c-.28 0-.5-.22-.5-.5s.22-.5.5-.5.5.22.5.5-.22.5-.5.5zM19 3l-6 6 2 2 7-7V3z\"></path></g>\n<g id=\"content-paste\"><path d=\"M19 2h-4.18C14.4.84 13.3 0 12 0c-1.3 0-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-7 0c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm7 18H5V4h2v3h10V4h2v16z\"></path></g>\n<g id=\"copyright\"><path d=\"M10.08 10.86c.05-.33.16-.62.3-.87s.34-.46.59-.62c.24-.15.54-.22.91-.23.23.01.44.05.63.13.2.09.38.21.52.36s.25.33.34.53.13.42.14.64h1.79c-.02-.47-.11-.9-.28-1.29s-.4-.73-.7-1.01-.66-.5-1.08-.66-.88-.23-1.39-.23c-.65 0-1.22.11-1.7.34s-.88.53-1.2.92-.56.84-.71 1.36S8 11.29 8 11.87v.27c0 .58.08 1.12.23 1.64s.39.97.71 1.35.72.69 1.2.91 1.05.34 1.7.34c.47 0 .91-.08 1.32-.23s.77-.36 1.08-.63.56-.58.74-.94.29-.74.3-1.15h-1.79c-.01.21-.06.4-.15.58s-.21.33-.36.46-.32.23-.52.3c-.19.07-.39.09-.6.1-.36-.01-.66-.08-.89-.23-.25-.16-.45-.37-.59-.62s-.25-.55-.3-.88-.08-.67-.08-1v-.27c0-.35.03-.68.08-1.01zM12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z\"></path></g>\n<g id=\"create\"><path d=\"M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z\"></path></g>\n<g id=\"create-new-folder\"><path d=\"M20 6h-8l-2-2H4c-1.11 0-1.99.89-1.99 2L2 18c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V8c0-1.11-.89-2-2-2zm-1 8h-3v3h-2v-3h-3v-2h3V9h2v3h3v2z\"></path></g>\n<g id=\"credit-card\"><path d=\"M20 4H4c-1.11 0-1.99.89-1.99 2L2 18c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V6c0-1.11-.89-2-2-2zm0 14H4v-6h16v6zm0-10H4V6h16v2z\"></path></g>\n<g id=\"dashboard\"><path d=\"M3 13h8V3H3v10zm0 8h8v-6H3v6zm10 0h8V11h-8v10zm0-18v6h8V3h-8z\"></path></g>\n<g id=\"date-range\"><path d=\"M9 11H7v2h2v-2zm4 0h-2v2h2v-2zm4 0h-2v2h2v-2zm2-7h-1V2h-2v2H8V2H6v2H5c-1.11 0-1.99.9-1.99 2L3 20c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 16H5V9h14v11z\"></path></g>\n<g id=\"delete\"><path d=\"M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z\"></path></g>\n<g id=\"description\"><path d=\"M14 2H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6zm2 16H8v-2h8v2zm0-4H8v-2h8v2zm-3-5V3.5L18.5 9H13z\"></path></g>\n<g id=\"dns\"><path d=\"M20 13H4c-.55 0-1 .45-1 1v6c0 .55.45 1 1 1h16c.55 0 1-.45 1-1v-6c0-.55-.45-1-1-1zM7 19c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zM20 3H4c-.55 0-1 .45-1 1v6c0 .55.45 1 1 1h16c.55 0 1-.45 1-1V4c0-.55-.45-1-1-1zM7 9c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2z\"></path></g>\n<g id=\"done\"><path d=\"M9 16.2L4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4L9 16.2z\"></path></g>\n<g id=\"done-all\"><path d=\"M18 7l-1.41-1.41-6.34 6.34 1.41 1.41L18 7zm4.24-1.41L11.66 16.17 7.48 12l-1.41 1.41L11.66 19l12-12-1.42-1.41zM.41 13.41L6 19l1.41-1.41L1.83 12 .41 13.41z\"></path></g>\n<g id=\"donut-large\"><path d=\"M11 5.08V2c-5 .5-9 4.81-9 10s4 9.5 9 10v-3.08c-3-.48-6-3.4-6-6.92s3-6.44 6-6.92zM18.97 11H22c-.47-5-4-8.53-9-9v3.08C16 5.51 18.54 8 18.97 11zM13 18.92V22c5-.47 8.53-4 9-9h-3.03c-.43 3-2.97 5.49-5.97 5.92z\"></path></g>\n<g id=\"donut-small\"><path d=\"M11 9.16V2c-5 .5-9 4.79-9 10s4 9.5 9 10v-7.16c-1-.41-2-1.52-2-2.84s1-2.43 2-2.84zM14.86 11H22c-.48-4.75-4-8.53-9-9v7.16c1 .3 1.52.98 1.86 1.84zM13 14.84V22c5-.47 8.52-4.25 9-9h-7.14c-.34.86-.86 1.54-1.86 1.84z\"></path></g>\n<g id=\"drafts\"><path d=\"M21.99 8c0-.72-.37-1.35-.94-1.7L12 1 2.95 6.3C2.38 6.65 2 7.28 2 8v10c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2l-.01-10zM12 13L3.74 7.84 12 3l8.26 4.84L12 13z\"></path></g>\n<g id=\"eject\"><path d=\"M5 17h14v2H5zm7-12L5.33 15h13.34z\"></path></g>\n<g id=\"error\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z\"></path></g>\n<g id=\"error-outline\"><path d=\"M11 15h2v2h-2zm0-8h2v6h-2zm.99-5C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z\"></path></g>\n<g id=\"event\"><path d=\"M17 12h-5v5h5v-5zM16 1v2H8V1H6v2H5c-1.11 0-1.99.9-1.99 2L3 19c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2h-1V1h-2zm3 18H5V8h14v11z\"></path></g>\n<g id=\"event-seat\"><path d=\"M4 18v3h3v-3h10v3h3v-6H4zm15-8h3v3h-3zM2 10h3v3H2zm15 3H7V5c0-1.1.9-2 2-2h6c1.1 0 2 .9 2 2v8z\"></path></g>\n<g id=\"exit-to-app\"><path d=\"M10.09 15.59L11.5 17l5-5-5-5-1.41 1.41L12.67 11H3v2h9.67l-2.58 2.59zM19 3H5c-1.11 0-2 .9-2 2v4h2V5h14v14H5v-4H3v4c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z\"></path></g>\n<g id=\"expand-less\"><path d=\"M12 8l-6 6 1.41 1.41L12 10.83l4.59 4.58L18 14z\"></path></g>\n<g id=\"expand-more\"><path d=\"M16.59 8.59L12 13.17 7.41 8.59 6 10l6 6 6-6z\"></path></g>\n<g id=\"explore\"><path d=\"M12 10.9c-.61 0-1.1.49-1.1 1.1s.49 1.1 1.1 1.1c.61 0 1.1-.49 1.1-1.1s-.49-1.1-1.1-1.1zM12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm2.19 12.19L6 18l3.81-8.19L18 6l-3.81 8.19z\"></path></g>\n<g id=\"extension\"><path d=\"M20.5 11H19V7c0-1.1-.9-2-2-2h-4V3.5C13 2.12 11.88 1 10.5 1S8 2.12 8 3.5V5H4c-1.1 0-1.99.9-1.99 2v3.8H3.5c1.49 0 2.7 1.21 2.7 2.7s-1.21 2.7-2.7 2.7H2V20c0 1.1.9 2 2 2h3.8v-1.5c0-1.49 1.21-2.7 2.7-2.7 1.49 0 2.7 1.21 2.7 2.7V22H17c1.1 0 2-.9 2-2v-4h1.5c1.38 0 2.5-1.12 2.5-2.5S21.88 11 20.5 11z\"></path></g>\n<g id=\"face\"><path d=\"M9 11.75c-.69 0-1.25.56-1.25 1.25s.56 1.25 1.25 1.25 1.25-.56 1.25-1.25-.56-1.25-1.25-1.25zm6 0c-.69 0-1.25.56-1.25 1.25s.56 1.25 1.25 1.25 1.25-.56 1.25-1.25-.56-1.25-1.25-1.25zM12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8 0-.29.02-.58.05-.86 2.36-1.05 4.23-2.98 5.21-5.37C11.07 8.33 14.05 10 17.42 10c.78 0 1.53-.09 2.25-.26.21.71.33 1.47.33 2.26 0 4.41-3.59 8-8 8z\"></path></g>\n<g id=\"favorite\"><path d=\"M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z\"></path></g>\n<g id=\"favorite-border\"><path d=\"M16.5 3c-1.74 0-3.41.81-4.5 2.09C10.91 3.81 9.24 3 7.5 3 4.42 3 2 5.42 2 8.5c0 3.78 3.4 6.86 8.55 11.54L12 21.35l1.45-1.32C18.6 15.36 22 12.28 22 8.5 22 5.42 19.58 3 16.5 3zm-4.4 15.55l-.1.1-.1-.1C7.14 14.24 4 11.39 4 8.5 4 6.5 5.5 5 7.5 5c1.54 0 3.04.99 3.57 2.36h1.87C13.46 5.99 14.96 5 16.5 5c2 0 3.5 1.5 3.5 3.5 0 2.89-3.14 5.74-7.9 10.05z\"></path></g>\n<g id=\"feedback\"><path d=\"M20 2H4c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-7 12h-2v-2h2v2zm0-4h-2V6h2v4z\"></path></g>\n<g id=\"file-download\"><path d=\"M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z\"></path></g>\n<g id=\"file-upload\"><path d=\"M9 16h6v-6h4l-7-7-7 7h4zm-4 2h14v2H5z\"></path></g>\n<g id=\"filter-list\"><path d=\"M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z\"></path></g>\n<g id=\"find-in-page\"><path d=\"M20 19.59V8l-6-6H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c.45 0 .85-.15 1.19-.4l-4.43-4.43c-.8.52-1.74.83-2.76.83-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5c0 1.02-.31 1.96-.83 2.75L20 19.59zM9 13c0 1.66 1.34 3 3 3s3-1.34 3-3-1.34-3-3-3-3 1.34-3 3z\"></path></g>\n<g id=\"find-replace\"><path d=\"M11 6c1.38 0 2.63.56 3.54 1.46L12 10h6V4l-2.05 2.05C14.68 4.78 12.93 4 11 4c-3.53 0-6.43 2.61-6.92 6H6.1c.46-2.28 2.48-4 4.9-4zm5.64 9.14c.66-.9 1.12-1.97 1.28-3.14H15.9c-.46 2.28-2.48 4-4.9 4-1.38 0-2.63-.56-3.54-1.46L10 12H4v6l2.05-2.05C7.32 17.22 9.07 18 11 18c1.55 0 2.98-.51 4.14-1.36L20 21.49 21.49 20l-4.85-4.86z\"></path></g>\n<g id=\"fingerprint\"><path d=\"M17.81 4.47c-.08 0-.16-.02-.23-.06C15.66 3.42 14 3 12.01 3c-1.98 0-3.86.47-5.57 1.41-.24.13-.54.04-.68-.2-.13-.24-.04-.55.2-.68C7.82 2.52 9.86 2 12.01 2c2.13 0 3.99.47 6.03 1.52.25.13.34.43.21.67-.09.18-.26.28-.44.28zM3.5 9.72c-.1 0-.2-.03-.29-.09-.23-.16-.28-.47-.12-.7.99-1.4 2.25-2.5 3.75-3.27C9.98 4.04 14 4.03 17.15 5.65c1.5.77 2.76 1.86 3.75 3.25.16.22.11.54-.12.7-.23.16-.54.11-.7-.12-.9-1.26-2.04-2.25-3.39-2.94-2.87-1.47-6.54-1.47-9.4.01-1.36.7-2.5 1.7-3.4 2.96-.08.14-.23.21-.39.21zm6.25 12.07c-.13 0-.26-.05-.35-.15-.87-.87-1.34-1.43-2.01-2.64-.69-1.23-1.05-2.73-1.05-4.34 0-2.97 2.54-5.39 5.66-5.39s5.66 2.42 5.66 5.39c0 .28-.22.5-.5.5s-.5-.22-.5-.5c0-2.42-2.09-4.39-4.66-4.39-2.57 0-4.66 1.97-4.66 4.39 0 1.44.32 2.77.93 3.85.64 1.15 1.08 1.64 1.85 2.42.19.2.19.51 0 .71-.11.1-.24.15-.37.15zm7.17-1.85c-1.19 0-2.24-.3-3.1-.89-1.49-1.01-2.38-2.65-2.38-4.39 0-.28.22-.5.5-.5s.5.22.5.5c0 1.41.72 2.74 1.94 3.56.71.48 1.54.71 2.54.71.24 0 .64-.03 1.04-.1.27-.05.53.13.58.41.05.27-.13.53-.41.58-.57.11-1.07.12-1.21.12zM14.91 22c-.04 0-.09-.01-.13-.02-1.59-.44-2.63-1.03-3.72-2.1-1.4-1.39-2.17-3.24-2.17-5.22 0-1.62 1.38-2.94 3.08-2.94 1.7 0 3.08 1.32 3.08 2.94 0 1.07.93 1.94 2.08 1.94s2.08-.87 2.08-1.94c0-3.77-3.25-6.83-7.25-6.83-2.84 0-5.44 1.58-6.61 4.03-.39.81-.59 1.76-.59 2.8 0 .78.07 2.01.67 3.61.1.26-.03.55-.29.64-.26.1-.55-.04-.64-.29-.49-1.31-.73-2.61-.73-3.96 0-1.2.23-2.29.68-3.24 1.33-2.79 4.28-4.6 7.51-4.6 4.55 0 8.25 3.51 8.25 7.83 0 1.62-1.38 2.94-3.08 2.94s-3.08-1.32-3.08-2.94c0-1.07-.93-1.94-2.08-1.94s-2.08.87-2.08 1.94c0 1.71.66 3.31 1.87 4.51.95.94 1.86 1.46 3.27 1.85.27.07.42.35.35.61-.05.23-.26.38-.47.38z\"></path></g>\n<g id=\"flag\"><path d=\"M14.4 6L14 4H5v17h2v-7h5.6l.4 2h7V6z\"></path></g>\n<g id=\"flight-land\"><path d=\"M2.5 19h19v2h-19zm7.18-5.73l4.35 1.16 5.31 1.42c.8.21 1.62-.26 1.84-1.06.21-.8-.26-1.62-1.06-1.84l-5.31-1.42-2.76-9.02L10.12 2v8.28L5.15 8.95l-.93-2.32-1.45-.39v5.17l1.6.43 5.31 1.43z\"></path></g>\n<g id=\"flight-takeoff\"><path d=\"M2.5 19h19v2h-19zm19.57-9.36c-.21-.8-1.04-1.28-1.84-1.06L14.92 10l-6.9-6.43-1.93.51 4.14 7.17-4.97 1.33-1.97-1.54-1.45.39 1.82 3.16.77 1.33 1.6-.43 5.31-1.42 4.35-1.16L21 11.49c.81-.23 1.28-1.05 1.07-1.85z\"></path></g>\n<g id=\"flip-to-back\"><path d=\"M9 7H7v2h2V7zm0 4H7v2h2v-2zm0-8c-1.11 0-2 .9-2 2h2V3zm4 12h-2v2h2v-2zm6-12v2h2c0-1.1-.9-2-2-2zm-6 0h-2v2h2V3zM9 17v-2H7c0 1.1.89 2 2 2zm10-4h2v-2h-2v2zm0-4h2V7h-2v2zm0 8c1.1 0 2-.9 2-2h-2v2zM5 7H3v12c0 1.1.89 2 2 2h12v-2H5V7zm10-2h2V3h-2v2zm0 12h2v-2h-2v2z\"></path></g>\n<g id=\"flip-to-front\"><path d=\"M3 13h2v-2H3v2zm0 4h2v-2H3v2zm2 4v-2H3c0 1.1.89 2 2 2zM3 9h2V7H3v2zm12 12h2v-2h-2v2zm4-18H9c-1.11 0-2 .9-2 2v10c0 1.1.89 2 2 2h10c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 12H9V5h10v10zm-8 6h2v-2h-2v2zm-4 0h2v-2H7v2z\"></path></g>\n<g id=\"folder\"><path d=\"M10 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2h-8l-2-2z\"></path></g>\n<g id=\"folder-open\"><path d=\"M20 6h-8l-2-2H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2zm0 12H4V8h16v10z\"></path></g>\n<g id=\"folder-shared\"><path d=\"M20 6h-8l-2-2H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2zm-5 3c1.1 0 2 .9 2 2s-.9 2-2 2-2-.9-2-2 .9-2 2-2zm4 8h-8v-1c0-1.33 2.67-2 4-2s4 .67 4 2v1z\"></path></g>\n<g id=\"font-download\"><path d=\"M9.93 13.5h4.14L12 7.98zM20 2H4c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-4.05 16.5l-1.14-3H9.17l-1.12 3H5.96l5.11-13h1.86l5.11 13h-2.09z\"></path></g>\n<g id=\"forward\"><path d=\"M12 8V4l8 8-8 8v-4H4V8z\"></path></g>\n<g id=\"fullscreen\"><path d=\"M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z\"></path></g>\n<g id=\"fullscreen-exit\"><path d=\"M5 16h3v3h2v-5H5v2zm3-8H5v2h5V5H8v3zm6 11h2v-3h3v-2h-5v5zm2-11V5h-2v5h5V8h-3z\"></path></g>\n<g id=\"gavel\"><path d=\"M1 21h12v2H1zM5.245 8.07l2.83-2.827 14.14 14.142-2.828 2.828zM12.317 1l5.657 5.656-2.83 2.83-5.654-5.66zM3.825 9.485l5.657 5.657-2.828 2.828-5.657-5.657z\"></path></g>\n<g id=\"gesture\"><path d=\"M4.59 6.89c.7-.71 1.4-1.35 1.71-1.22.5.2 0 1.03-.3 1.52-.25.42-2.86 3.89-2.86 6.31 0 1.28.48 2.34 1.34 2.98.75.56 1.74.73 2.64.46 1.07-.31 1.95-1.4 3.06-2.77 1.21-1.49 2.83-3.44 4.08-3.44 1.63 0 1.65 1.01 1.76 1.79-3.78.64-5.38 3.67-5.38 5.37 0 1.7 1.44 3.09 3.21 3.09 1.63 0 4.29-1.33 4.69-6.1H21v-2.5h-2.47c-.15-1.65-1.09-4.2-4.03-4.2-2.25 0-4.18 1.91-4.94 2.84-.58.73-2.06 2.48-2.29 2.72-.25.3-.68.84-1.11.84-.45 0-.72-.83-.36-1.92.35-1.09 1.4-2.86 1.85-3.52.78-1.14 1.3-1.92 1.3-3.28C8.95 3.69 7.31 3 6.44 3 5.12 3 3.97 4 3.72 4.25c-.36.36-.66.66-.88.93l1.75 1.71zm9.29 11.66c-.31 0-.74-.26-.74-.72 0-.6.73-2.2 2.87-2.76-.3 2.69-1.43 3.48-2.13 3.48z\"></path></g>\n<g id=\"get-app\"><path d=\"M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z\"></path></g>\n<g id=\"gif\"><path d=\"M11.5 9H13v6h-1.5zM9 9H6c-.6 0-1 .5-1 1v4c0 .5.4 1 1 1h3c.6 0 1-.5 1-1v-2H8.5v1.5h-2v-3H10V10c0-.5-.4-1-1-1zm10 1.5V9h-4.5v6H16v-2h2v-1.5h-2v-1z\"></path></g>\n<g id=\"grade\"><path d=\"M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z\"></path></g>\n<g id=\"group-work\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zM8 17.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5zM9.5 8c0-1.38 1.12-2.5 2.5-2.5s2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5S9.5 9.38 9.5 8zm6.5 9.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z\"></path></g>\n<g id=\"help\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 17h-2v-2h2v2zm2.07-7.75l-.9.92C13.45 12.9 13 13.5 13 15h-2v-.5c0-1.1.45-2.1 1.17-2.83l1.24-1.26c.37-.36.59-.86.59-1.41 0-1.1-.9-2-2-2s-2 .9-2 2H8c0-2.21 1.79-4 4-4s4 1.79 4 4c0 .88-.36 1.68-.93 2.25z\"></path></g>\n<g id=\"help-outline\"><path d=\"M11 18h2v-2h-2v2zm1-16C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm0-14c-2.21 0-4 1.79-4 4h2c0-1.1.9-2 2-2s2 .9 2 2c0 2-3 1.75-3 5h2c0-2.25 3-2.5 3-5 0-2.21-1.79-4-4-4z\"></path></g>\n<g id=\"highlight-off\"><path d=\"M14.59 8L12 10.59 9.41 8 8 9.41 10.59 12 8 14.59 9.41 16 12 13.41 14.59 16 16 14.59 13.41 12 16 9.41 14.59 8zM12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z\"></path></g>\n<g id=\"history\"><path d=\"M13 3c-4.97 0-9 4.03-9 9H1l3.89 3.89.07.14L9 12H6c0-3.87 3.13-7 7-7s7 3.13 7 7-3.13 7-7 7c-1.93 0-3.68-.79-4.94-2.06l-1.42 1.42C8.27 19.99 10.51 21 13 21c4.97 0 9-4.03 9-9s-4.03-9-9-9zm-1 5v5l4.28 2.54.72-1.21-3.5-2.08V8H12z\"></path></g>\n<g id=\"home\"><path d=\"M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z\"></path></g>\n<g id=\"hourglass-empty\"><path d=\"M6 2v6h.01L6 8.01 10 12l-4 4 .01.01H6V22h12v-5.99h-.01L18 16l-4-4 4-3.99-.01-.01H18V2H6zm10 14.5V20H8v-3.5l4-4 4 4zm-4-5l-4-4V4h8v3.5l-4 4z\"></path></g>\n<g id=\"hourglass-full\"><path d=\"M6 2v6h.01L6 8.01 10 12l-4 4 .01.01H6V22h12v-5.99h-.01L18 16l-4-4 4-3.99-.01-.01H18V2H6z\"></path></g>\n<g id=\"http\"><path d=\"M4.5 11h-2V9H1v6h1.5v-2.5h2V15H6V9H4.5v2zm2.5-.5h1.5V15H10v-4.5h1.5V9H7v1.5zm5.5 0H14V15h1.5v-4.5H17V9h-4.5v1.5zm9-1.5H18v6h1.5v-2h2c.8 0 1.5-.7 1.5-1.5v-1c0-.8-.7-1.5-1.5-1.5zm0 2.5h-2v-1h2v1z\"></path></g>\n<g id=\"https\"><path d=\"M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zm-6 9c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zm3.1-9H8.9V6c0-1.71 1.39-3.1 3.1-3.1 1.71 0 3.1 1.39 3.1 3.1v2z\"></path></g>\n<g id=\"important-devices\"><path d=\"M23 11.01L18 11c-.55 0-1 .45-1 1v9c0 .55.45 1 1 1h5c.55 0 1-.45 1-1v-9c0-.55-.45-.99-1-.99zM23 20h-5v-7h5v7zM20 2H2C.89 2 0 2.89 0 4v12c0 1.1.89 2 2 2h7v2H7v2h8v-2h-2v-2h2v-2H2V4h18v5h2V4c0-1.11-.9-2-2-2zm-8.03 7L11 6l-.97 3H7l2.47 1.76-.94 2.91 2.47-1.8 2.47 1.8-.94-2.91L15 9h-3.03z\"></path></g>\n<g id=\"inbox\"><path d=\"M19 3H4.99c-1.11 0-1.98.89-1.98 2L3 19c0 1.1.88 2 1.99 2H19c1.1 0 2-.9 2-2V5c0-1.11-.9-2-2-2zm0 12h-4c0 1.66-1.35 3-3 3s-3-1.34-3-3H4.99V5H19v10z\"></path></g>\n<g id=\"indeterminate-check-box\"><path d=\"M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-2 10H7v-2h10v2z\"></path></g>\n<g id=\"info\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z\"></path></g>\n<g id=\"info-outline\"><path d=\"M11 17h2v-6h-2v6zm1-15C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zM11 9h2V7h-2v2z\"></path></g>\n<g id=\"input\"><path d=\"M21 3.01H3c-1.1 0-2 .9-2 2V9h2V4.99h18v14.03H3V15H1v4.01c0 1.1.9 1.98 2 1.98h18c1.1 0 2-.88 2-1.98v-14c0-1.11-.9-2-2-2zM11 16l4-4-4-4v3H1v2h10v3z\"></path></g>\n<g id=\"invert-colors\"><path d=\"M17.66 7.93L12 2.27 6.34 7.93c-3.12 3.12-3.12 8.19 0 11.31C7.9 20.8 9.95 21.58 12 21.58c2.05 0 4.1-.78 5.66-2.34 3.12-3.12 3.12-8.19 0-11.31zM12 19.59c-1.6 0-3.11-.62-4.24-1.76C6.62 16.69 6 15.19 6 13.59s.62-3.11 1.76-4.24L12 5.1v14.49z\"></path></g>\n<g id=\"label\"><path d=\"M17.63 5.84C17.27 5.33 16.67 5 16 5L5 5.01C3.9 5.01 3 5.9 3 7v10c0 1.1.9 1.99 2 1.99L16 19c.67 0 1.27-.33 1.63-.84L22 12l-4.37-6.16z\"></path></g>\n<g id=\"label-outline\"><path d=\"M17.63 5.84C17.27 5.33 16.67 5 16 5L5 5.01C3.9 5.01 3 5.9 3 7v10c0 1.1.9 1.99 2 1.99L16 19c.67 0 1.27-.33 1.63-.84L22 12l-4.37-6.16zM16 17H5V7h11l3.55 5L16 17z\"></path></g>\n<g id=\"language\"><path d=\"M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zm6.93 6h-2.95c-.32-1.25-.78-2.45-1.38-3.56 1.84.63 3.37 1.91 4.33 3.56zM12 4.04c.83 1.2 1.48 2.53 1.91 3.96h-3.82c.43-1.43 1.08-2.76 1.91-3.96zM4.26 14C4.1 13.36 4 12.69 4 12s.1-1.36.26-2h3.38c-.08.66-.14 1.32-.14 2 0 .68.06 1.34.14 2H4.26zm.82 2h2.95c.32 1.25.78 2.45 1.38 3.56-1.84-.63-3.37-1.9-4.33-3.56zm2.95-8H5.08c.96-1.66 2.49-2.93 4.33-3.56C8.81 5.55 8.35 6.75 8.03 8zM12 19.96c-.83-1.2-1.48-2.53-1.91-3.96h3.82c-.43 1.43-1.08 2.76-1.91 3.96zM14.34 14H9.66c-.09-.66-.16-1.32-.16-2 0-.68.07-1.35.16-2h4.68c.09.65.16 1.32.16 2 0 .68-.07 1.34-.16 2zm.25 5.56c.6-1.11 1.06-2.31 1.38-3.56h2.95c-.96 1.65-2.49 2.93-4.33 3.56zM16.36 14c.08-.66.14-1.32.14-2 0-.68-.06-1.34-.14-2h3.38c.16.64.26 1.31.26 2s-.1 1.36-.26 2h-3.38z\"></path></g>\n<g id=\"launch\"><path d=\"M19 19H5V5h7V3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2v-7h-2v7zM14 3v2h3.59l-9.83 9.83 1.41 1.41L19 6.41V10h2V3h-7z\"></path></g>\n<g id=\"lightbulb-outline\"><path d=\"M9 21c0 .55.45 1 1 1h4c.55 0 1-.45 1-1v-1H9v1zm3-19C8.14 2 5 5.14 5 9c0 2.38 1.19 4.47 3 5.74V17c0 .55.45 1 1 1h6c.55 0 1-.45 1-1v-2.26c1.81-1.27 3-3.36 3-5.74 0-3.86-3.14-7-7-7zm2.85 11.1l-.85.6V16h-4v-2.3l-.85-.6C7.8 12.16 7 10.63 7 9c0-2.76 2.24-5 5-5s5 2.24 5 5c0 1.63-.8 3.16-2.15 4.1z\"></path></g>\n<g id=\"line-style\"><path d=\"M3 16h5v-2H3v2zm6.5 0h5v-2h-5v2zm6.5 0h5v-2h-5v2zM3 20h2v-2H3v2zm4 0h2v-2H7v2zm4 0h2v-2h-2v2zm4 0h2v-2h-2v2zm4 0h2v-2h-2v2zM3 12h8v-2H3v2zm10 0h8v-2h-8v2zM3 4v4h18V4H3z\"></path></g>\n<g id=\"line-weight\"><path d=\"M3 17h18v-2H3v2zm0 3h18v-1H3v1zm0-7h18v-3H3v3zm0-9v4h18V4H3z\"></path></g>\n<g id=\"link\"><path d=\"M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z\"></path></g>\n<g id=\"list\"><path d=\"M3 13h2v-2H3v2zm0 4h2v-2H3v2zm0-8h2V7H3v2zm4 4h14v-2H7v2zm0 4h14v-2H7v2zM7 7v2h14V7H7z\"></path></g>\n<g id=\"lock\"><path d=\"M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zm-6 9c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zm3.1-9H8.9V6c0-1.71 1.39-3.1 3.1-3.1 1.71 0 3.1 1.39 3.1 3.1v2z\"></path></g>\n<g id=\"lock-open\"><path d=\"M12 17c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm6-9h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6h1.9c0-1.71 1.39-3.1 3.1-3.1 1.71 0 3.1 1.39 3.1 3.1v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zm0 12H6V10h12v10z\"></path></g>\n<g id=\"lock-outline\"><path d=\"M12 17c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm6-9h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zM8.9 6c0-1.71 1.39-3.1 3.1-3.1s3.1 1.39 3.1 3.1v2H8.9V6zM18 20H6V10h12v10z\"></path></g>\n<g id=\"loyalty\"><path d=\"M21.41 11.58l-9-9C12.05 2.22 11.55 2 11 2H4c-1.1 0-2 .9-2 2v7c0 .55.22 1.05.59 1.42l9 9c.36.36.86.58 1.41.58.55 0 1.05-.22 1.41-.59l7-7c.37-.36.59-.86.59-1.41 0-.55-.23-1.06-.59-1.42zM5.5 7C4.67 7 4 6.33 4 5.5S4.67 4 5.5 4 7 4.67 7 5.5 6.33 7 5.5 7zm11.77 8.27L13 19.54l-4.27-4.27C8.28 14.81 8 14.19 8 13.5c0-1.38 1.12-2.5 2.5-2.5.69 0 1.32.28 1.77.74l.73.72.73-.73c.45-.45 1.08-.73 1.77-.73 1.38 0 2.5 1.12 2.5 2.5 0 .69-.28 1.32-.73 1.77z\"></path></g>\n<g id=\"mail\"><path d=\"M20 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 4l-8 5-8-5V6l8 5 8-5v2z\"></path></g>\n<g id=\"markunread\"><path d=\"M20 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 4l-8 5-8-5V6l8 5 8-5v2z\"></path></g>\n<g id=\"markunread-mailbox\"><path d=\"M20 6H10v6H8V4h6V0H6v6H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2z\"></path></g>\n<g id=\"menu\"><path d=\"M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z\"></path></g>\n<g id=\"more-horiz\"><path d=\"M6 10c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm12 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm-6 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z\"></path></g>\n<g id=\"more-vert\"><path d=\"M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z\"></path></g>\n<g id=\"motorcycle\"><path d=\"M19.44 9.03L15.41 5H11v2h3.59l2 2H5c-2.8 0-5 2.2-5 5s2.2 5 5 5c2.46 0 4.45-1.69 4.9-4h1.65l2.77-2.77c-.21.54-.32 1.14-.32 1.77 0 2.8 2.2 5 5 5s5-2.2 5-5c0-2.65-1.97-4.77-4.56-4.97zM7.82 15C7.4 16.15 6.28 17 5 17c-1.63 0-3-1.37-3-3s1.37-3 3-3c1.28 0 2.4.85 2.82 2H5v2h2.82zM19 17c-1.66 0-3-1.34-3-3s1.34-3 3-3 3 1.34 3 3-1.34 3-3 3z\"></path></g>\n<g id=\"move-to-inbox\"><path d=\"M19 3H4.99c-1.11 0-1.98.9-1.98 2L3 19c0 1.1.88 2 1.99 2H19c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 12h-4c0 1.66-1.35 3-3 3s-3-1.34-3-3H4.99V5H19v10zm-3-5h-2V7h-4v3H8l4 4 4-4z\"></path></g>\n<g id=\"next-week\"><path d=\"M20 7h-4V5c0-.55-.22-1.05-.59-1.41C15.05 3.22 14.55 3 14 3h-4c-1.1 0-2 .9-2 2v2H4c-1.1 0-2 .9-2 2v11c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V9c0-1.1-.9-2-2-2zM10 5h4v2h-4V5zm1 13.5l-1-1 3-3-3-3 1-1 4 4-4 4z\"></path></g>\n<g id=\"note-add\"><path d=\"M14 2H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6zm2 14h-3v3h-2v-3H8v-2h3v-3h2v3h3v2zm-3-7V3.5L18.5 9H13z\"></path></g>\n<g id=\"offline-pin\"><path d=\"M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10 10-4.5 10-10S17.5 2 12 2zm5 16H7v-2h10v2zm-6.7-4L7 10.7l1.4-1.4 1.9 1.9 5.3-5.3L17 7.3 10.3 14z\"></path></g>\n<g id=\"opacity\"><path d=\"M17.66 8L12 2.35 6.34 8C4.78 9.56 4 11.64 4 13.64s.78 4.11 2.34 5.67 3.61 2.35 5.66 2.35 4.1-.79 5.66-2.35S20 15.64 20 13.64 19.22 9.56 17.66 8zM6 14c.01-2 .62-3.27 1.76-4.4L12 5.27l4.24 4.38C17.38 10.77 17.99 12 18 14H6z\"></path></g>\n<g id=\"open-in-browser\"><path d=\"M19 4H5c-1.11 0-2 .9-2 2v12c0 1.1.89 2 2 2h4v-2H5V8h14v10h-4v2h4c1.1 0 2-.9 2-2V6c0-1.1-.89-2-2-2zm-7 6l-4 4h3v6h2v-6h3l-4-4z\"></path></g>\n<g id=\"open-in-new\"><path d=\"M19 19H5V5h7V3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2v-7h-2v7zM14 3v2h3.59l-9.83 9.83 1.41 1.41L19 6.41V10h2V3h-7z\"></path></g>\n<g id=\"open-with\"><path d=\"M10 9h4V6h3l-5-5-5 5h3v3zm-1 1H6V7l-5 5 5 5v-3h3v-4zm14 2l-5-5v3h-3v4h3v3l5-5zm-9 3h-4v3H7l5 5 5-5h-3v-3z\"></path></g>\n<g id=\"pageview\"><path d=\"M11.5 9C10.12 9 9 10.12 9 11.5s1.12 2.5 2.5 2.5 2.5-1.12 2.5-2.5S12.88 9 11.5 9zM20 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm-3.21 14.21l-2.91-2.91c-.69.44-1.51.7-2.39.7C9.01 16 7 13.99 7 11.5S9.01 7 11.5 7 16 9.01 16 11.5c0 .88-.26 1.69-.7 2.39l2.91 2.9-1.42 1.42z\"></path></g>\n<g id=\"pan-tool\"><path d=\"M23 5.5V20c0 2.2-1.8 4-4 4h-7.3c-1.08 0-2.1-.43-2.85-1.19L1 14.83s1.26-1.23 1.3-1.25c.22-.19.49-.29.79-.29.22 0 .42.06.6.16.04.01 4.31 2.46 4.31 2.46V4c0-.83.67-1.5 1.5-1.5S11 3.17 11 4v7h1V1.5c0-.83.67-1.5 1.5-1.5S15 .67 15 1.5V11h1V2.5c0-.83.67-1.5 1.5-1.5s1.5.67 1.5 1.5V11h1V5.5c0-.83.67-1.5 1.5-1.5s1.5.67 1.5 1.5z\"></path></g>\n<g id=\"payment\"><path d=\"M20 4H4c-1.11 0-1.99.89-1.99 2L2 18c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V6c0-1.11-.89-2-2-2zm0 14H4v-6h16v6zm0-10H4V6h16v2z\"></path></g>\n<g id=\"perm-camera-mic\"><path d=\"M20 5h-3.17L15 3H9L7.17 5H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h7v-2.09c-2.83-.48-5-2.94-5-5.91h2c0 2.21 1.79 4 4 4s4-1.79 4-4h2c0 2.97-2.17 5.43-5 5.91V21h7c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm-6 8c0 1.1-.9 2-2 2s-2-.9-2-2V9c0-1.1.9-2 2-2s2 .9 2 2v4z\"></path></g>\n<g id=\"perm-contact-calendar\"><path d=\"M19 3h-1V1h-2v2H8V1H6v2H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-7 3c1.66 0 3 1.34 3 3s-1.34 3-3 3-3-1.34-3-3 1.34-3 3-3zm6 12H6v-1c0-2 4-3.1 6-3.1s6 1.1 6 3.1v1z\"></path></g>\n<g id=\"perm-data-setting\"><path d=\"M18.99 11.5c.34 0 .67.03 1 .07L20 0 0 20h11.56c-.04-.33-.07-.66-.07-1 0-4.14 3.36-7.5 7.5-7.5zm3.71 7.99c.02-.16.04-.32.04-.49 0-.17-.01-.33-.04-.49l1.06-.83c.09-.08.12-.21.06-.32l-1-1.73c-.06-.11-.19-.15-.31-.11l-1.24.5c-.26-.2-.54-.37-.85-.49l-.19-1.32c-.01-.12-.12-.21-.24-.21h-2c-.12 0-.23.09-.25.21l-.19 1.32c-.3.13-.59.29-.85.49l-1.24-.5c-.11-.04-.24 0-.31.11l-1 1.73c-.06.11-.04.24.06.32l1.06.83c-.02.16-.03.32-.03.49 0 .17.01.33.03.49l-1.06.83c-.09.08-.12.21-.06.32l1 1.73c.06.11.19.15.31.11l1.24-.5c.26.2.54.37.85.49l.19 1.32c.02.12.12.21.25.21h2c.12 0 .23-.09.25-.21l.19-1.32c.3-.13.59-.29.84-.49l1.25.5c.11.04.24 0 .31-.11l1-1.73c.06-.11.03-.24-.06-.32l-1.07-.83zm-3.71 1.01c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5z\"></path></g>\n<g id=\"perm-device-information\"><path d=\"M13 7h-2v2h2V7zm0 4h-2v6h2v-6zm4-9.99L7 1c-1.1 0-2 .9-2 2v18c0 1.1.9 2 2 2h10c1.1 0 2-.9 2-2V3c0-1.1-.9-1.99-2-1.99zM17 19H7V5h10v14z\"></path></g>\n<g id=\"perm-identity\"><path d=\"M12 5.9c1.16 0 2.1.94 2.1 2.1s-.94 2.1-2.1 2.1S9.9 9.16 9.9 8s.94-2.1 2.1-2.1m0 9c2.97 0 6.1 1.46 6.1 2.1v1.1H5.9V17c0-.64 3.13-2.1 6.1-2.1M12 4C9.79 4 8 5.79 8 8s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4zm0 9c-2.67 0-8 1.34-8 4v3h16v-3c0-2.66-5.33-4-8-4z\"></path></g>\n<g id=\"perm-media\"><path d=\"M2 6H0v5h.01L0 20c0 1.1.9 2 2 2h18v-2H2V6zm20-2h-8l-2-2H6c-1.1 0-1.99.9-1.99 2L4 16c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zM7 15l4.5-6 3.5 4.51 2.5-3.01L21 15H7z\"></path></g>\n<g id=\"perm-phone-msg\"><path d=\"M20 15.5c-1.25 0-2.45-.2-3.57-.57-.35-.11-.74-.03-1.02.24l-2.2 2.2c-2.83-1.44-5.15-3.75-6.59-6.58l2.2-2.21c.28-.27.36-.66.25-1.01C8.7 6.45 8.5 5.25 8.5 4c0-.55-.45-1-1-1H4c-.55 0-1 .45-1 1 0 9.39 7.61 17 17 17 .55 0 1-.45 1-1v-3.5c0-.55-.45-1-1-1zM12 3v10l3-3h6V3h-9z\"></path></g>\n<g id=\"perm-scan-wifi\"><path d=\"M12 3C6.95 3 3.15 4.85 0 7.23L12 22 24 7.25C20.85 4.87 17.05 3 12 3zm1 13h-2v-6h2v6zm-2-8V6h2v2h-2z\"></path></g>\n<g id=\"pets\"><circle cx=\"4.5\" cy=\"9.5\" r=\"2.5\"></circle><circle cx=\"9\" cy=\"5.5\" r=\"2.5\"></circle><circle cx=\"15\" cy=\"5.5\" r=\"2.5\"></circle><circle cx=\"19.5\" cy=\"9.5\" r=\"2.5\"></circle><path d=\"M17.34 14.86c-.87-1.02-1.6-1.89-2.48-2.91-.46-.54-1.05-1.08-1.75-1.32-.11-.04-.22-.07-.33-.09-.25-.04-.52-.04-.78-.04s-.53 0-.79.05c-.11.02-.22.05-.33.09-.7.24-1.28.78-1.75 1.32-.87 1.02-1.6 1.89-2.48 2.91-1.31 1.31-2.92 2.76-2.62 4.79.29 1.02 1.02 2.03 2.33 2.32.73.15 3.06-.44 5.54-.44h.18c2.48 0 4.81.58 5.54.44 1.31-.29 2.04-1.31 2.33-2.32.31-2.04-1.3-3.49-2.61-4.8z\"></path></g>\n<g id=\"picture-in-picture\"><path d=\"M19 7h-8v6h8V7zm2-4H3c-1.1 0-2 .9-2 2v14c0 1.1.9 1.98 2 1.98h18c1.1 0 2-.88 2-1.98V5c0-1.1-.9-2-2-2zm0 16.01H3V4.98h18v14.03z\"></path></g>\n<g id=\"picture-in-picture-alt\"><path d=\"M19 11h-8v6h8v-6zm4 8V4.98C23 3.88 22.1 3 21 3H3c-1.1 0-2 .88-2 1.98V19c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2zm-2 .02H3V4.97h18v14.05z\"></path></g>\n<g id=\"play-for-work\"><path d=\"M11 5v5.59H7.5l4.5 4.5 4.5-4.5H13V5h-2zm-5 9c0 3.31 2.69 6 6 6s6-2.69 6-6h-2c0 2.21-1.79 4-4 4s-4-1.79-4-4H6z\"></path></g>\n<g id=\"polymer\"><path d=\"M19 4h-4L7.11 16.63 4.5 12 9 4H5L.5 12 5 20h4l7.89-12.63L19.5 12 15 20h4l4.5-8z\"></path></g>\n<g id=\"power-settings-new\"><path d=\"M13 3h-2v10h2V3zm4.83 2.17l-1.42 1.42C17.99 7.86 19 9.81 19 12c0 3.87-3.13 7-7 7s-7-3.13-7-7c0-2.19 1.01-4.14 2.58-5.42L6.17 5.17C4.23 6.82 3 9.26 3 12c0 4.97 4.03 9 9 9s9-4.03 9-9c0-2.74-1.23-5.18-3.17-6.83z\"></path></g>\n<g id=\"pregnant-woman\"><path d=\"M9 4c0-1.11.89-2 2-2s2 .89 2 2-.89 2-2 2-2-.89-2-2zm7 9c-.01-1.34-.83-2.51-2-3 0-1.66-1.34-3-3-3s-3 1.34-3 3v7h2v5h3v-5h3v-4z\"></path></g>\n<g id=\"print\"><path d=\"M19 8H5c-1.66 0-3 1.34-3 3v6h4v4h12v-4h4v-6c0-1.66-1.34-3-3-3zm-3 11H8v-5h8v5zm3-7c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm-1-9H6v4h12V3z\"></path></g>\n<g id=\"query-builder\"><path d=\"M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zm.5-13H11v6l5.25 3.15.75-1.23-4.5-2.67z\"></path></g>\n<g id=\"question-answer\"><path d=\"M21 6h-2v9H6v2c0 .55.45 1 1 1h11l4 4V7c0-.55-.45-1-1-1zm-4 6V3c0-.55-.45-1-1-1H3c-.55 0-1 .45-1 1v14l4-4h10c.55 0 1-.45 1-1z\"></path></g>\n<g id=\"radio-button-checked\"><path d=\"M12 7c-2.76 0-5 2.24-5 5s2.24 5 5 5 5-2.24 5-5-2.24-5-5-5zm0-5C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z\"></path></g>\n<g id=\"radio-button-unchecked\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z\"></path></g>\n<g id=\"receipt\"><path d=\"M18 17H6v-2h12v2zm0-4H6v-2h12v2zm0-4H6V7h12v2zM3 22l1.5-1.5L6 22l1.5-1.5L9 22l1.5-1.5L12 22l1.5-1.5L15 22l1.5-1.5L18 22l1.5-1.5L21 22V2l-1.5 1.5L18 2l-1.5 1.5L15 2l-1.5 1.5L12 2l-1.5 1.5L9 2 7.5 3.5 6 2 4.5 3.5 3 2v20z\"></path></g>\n<g id=\"record-voice-over\"><circle cx=\"9\" cy=\"9\" r=\"4\"></circle><path d=\"M9 15c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4zm7.76-9.64l-1.68 1.69c.84 1.18.84 2.71 0 3.89l1.68 1.69c2.02-2.02 2.02-5.07 0-7.27zM20.07 2l-1.63 1.63c2.77 3.02 2.77 7.56 0 10.74L20.07 16c3.9-3.89 3.91-9.95 0-14z\"></path></g>\n<g id=\"redeem\"><path d=\"M20 6h-2.18c.11-.31.18-.65.18-1 0-1.66-1.34-3-3-3-1.05 0-1.96.54-2.5 1.35l-.5.67-.5-.68C10.96 2.54 10.05 2 9 2 7.34 2 6 3.34 6 5c0 .35.07.69.18 1H4c-1.11 0-1.99.89-1.99 2L2 19c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V8c0-1.11-.89-2-2-2zm-5-2c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zM9 4c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm11 15H4v-2h16v2zm0-5H4V8h5.08L7 10.83 8.62 12 11 8.76l1-1.36 1 1.36L15.38 12 17 10.83 14.92 8H20v6z\"></path></g>\n<g id=\"redo\"><path d=\"M18.4 10.6C16.55 8.99 14.15 8 11.5 8c-4.65 0-8.58 3.03-9.96 7.22L3.9 16c1.05-3.19 4.05-5.5 7.6-5.5 1.95 0 3.73.72 5.12 1.88L13 16h9V7l-3.6 3.6z\"></path></g>\n<g id=\"refresh\"><path d=\"M17.65 6.35C16.2 4.9 14.21 4 12 4c-4.42 0-7.99 3.58-7.99 8s3.57 8 7.99 8c3.73 0 6.84-2.55 7.73-6h-2.08c-.82 2.33-3.04 4-5.65 4-3.31 0-6-2.69-6-6s2.69-6 6-6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z\"></path></g>\n<g id=\"remove\"><path d=\"M19 13H5v-2h14v2z\"></path></g>\n<g id=\"remove-circle\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm5 11H7v-2h10v2z\"></path></g>\n<g id=\"remove-circle-outline\"><path d=\"M7 11v2h10v-2H7zm5-9C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z\"></path></g>\n<g id=\"reorder\"><path d=\"M3 15h18v-2H3v2zm0 4h18v-2H3v2zm0-8h18V9H3v2zm0-6v2h18V5H3z\"></path></g>\n<g id=\"reply\"><path d=\"M10 9V5l-7 7 7 7v-4.1c5 0 8.5 1.6 11 5.1-1-5-4-10-11-11z\"></path></g>\n<g id=\"reply-all\"><path d=\"M7 8V5l-7 7 7 7v-3l-4-4 4-4zm6 1V5l-7 7 7 7v-4.1c5 0 8.5 1.6 11 5.1-1-5-4-10-11-11z\"></path></g>\n<g id=\"report\"><path d=\"M15.73 3H8.27L3 8.27v7.46L8.27 21h7.46L21 15.73V8.27L15.73 3zM12 17.3c-.72 0-1.3-.58-1.3-1.3 0-.72.58-1.3 1.3-1.3.72 0 1.3.58 1.3 1.3 0 .72-.58 1.3-1.3 1.3zm1-4.3h-2V7h2v6z\"></path></g>\n<g id=\"report-problem\"><path d=\"M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z\"></path></g>\n<g id=\"restore\"><path d=\"M13 3c-4.97 0-9 4.03-9 9H1l3.89 3.89.07.14L9 12H6c0-3.87 3.13-7 7-7s7 3.13 7 7-3.13 7-7 7c-1.93 0-3.68-.79-4.94-2.06l-1.42 1.42C8.27 19.99 10.51 21 13 21c4.97 0 9-4.03 9-9s-4.03-9-9-9zm-1 5v5l4.28 2.54.72-1.21-3.5-2.08V8H12z\"></path></g>\n<g id=\"room\"><path d=\"M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z\"></path></g>\n<g id=\"rounded-corner\"><path d=\"M19 19h2v2h-2v-2zm0-2h2v-2h-2v2zM3 13h2v-2H3v2zm0 4h2v-2H3v2zm0-8h2V7H3v2zm0-4h2V3H3v2zm4 0h2V3H7v2zm8 16h2v-2h-2v2zm-4 0h2v-2h-2v2zm4 0h2v-2h-2v2zm-8 0h2v-2H7v2zm-4 0h2v-2H3v2zM21 8c0-2.76-2.24-5-5-5h-5v2h5c1.65 0 3 1.35 3 3v5h2V8z\"></path></g>\n<g id=\"rowing\"><path d=\"M8.5 14.5L4 19l1.5 1.5L9 17h2l-2.5-2.5zM15 1c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm6 20.01L18 24l-2.99-3.01V19.5l-7.1-7.09c-.31.05-.61.07-.91.07v-2.16c1.66.03 3.61-.87 4.67-2.04l1.4-1.55c.19-.21.43-.38.69-.5.29-.14.62-.23.96-.23h.03C15.99 6.01 17 7.02 17 8.26v5.75c0 .84-.35 1.61-.92 2.16l-3.58-3.58v-2.27c-.63.52-1.43 1.02-2.29 1.39L16.5 18H18l3 3.01z\"></path></g>\n<g id=\"save\"><path d=\"M17 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V7l-4-4zm-5 16c-1.66 0-3-1.34-3-3s1.34-3 3-3 3 1.34 3 3-1.34 3-3 3zm3-10H5V5h10v4z\"></path></g>\n<g id=\"schedule\"><path d=\"M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zm.5-13H11v6l5.25 3.15.75-1.23-4.5-2.67z\"></path></g>\n<g id=\"search\"><path d=\"M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z\"></path></g>\n<g id=\"select-all\"><path d=\"M3 5h2V3c-1.1 0-2 .9-2 2zm0 8h2v-2H3v2zm4 8h2v-2H7v2zM3 9h2V7H3v2zm10-6h-2v2h2V3zm6 0v2h2c0-1.1-.9-2-2-2zM5 21v-2H3c0 1.1.9 2 2 2zm-2-4h2v-2H3v2zM9 3H7v2h2V3zm2 18h2v-2h-2v2zm8-8h2v-2h-2v2zm0 8c1.1 0 2-.9 2-2h-2v2zm0-12h2V7h-2v2zm0 8h2v-2h-2v2zm-4 4h2v-2h-2v2zm0-16h2V3h-2v2zM7 17h10V7H7v10zm2-8h6v6H9V9z\"></path></g>\n<g id=\"send\"><path d=\"M2.01 21L23 12 2.01 3 2 10l15 2-15 2z\"></path></g>\n<g id=\"settings\"><path d=\"M19.43 12.98c.04-.32.07-.64.07-.98s-.03-.66-.07-.98l2.11-1.65c.19-.15.24-.42.12-.64l-2-3.46c-.12-.22-.39-.3-.61-.22l-2.49 1c-.52-.4-1.08-.73-1.69-.98l-.38-2.65C14.46 2.18 14.25 2 14 2h-4c-.25 0-.46.18-.49.42l-.38 2.65c-.61.25-1.17.59-1.69.98l-2.49-1c-.23-.09-.49 0-.61.22l-2 3.46c-.13.22-.07.49.12.64l2.11 1.65c-.04.32-.07.65-.07.98s.03.66.07.98l-2.11 1.65c-.19.15-.24.42-.12.64l2 3.46c.12.22.39.3.61.22l2.49-1c.52.4 1.08.73 1.69.98l.38 2.65c.03.24.24.42.49.42h4c.25 0 .46-.18.49-.42l.38-2.65c.61-.25 1.17-.59 1.69-.98l2.49 1c.23.09.49 0 .61-.22l2-3.46c.12-.22.07-.49-.12-.64l-2.11-1.65zM12 15.5c-1.93 0-3.5-1.57-3.5-3.5s1.57-3.5 3.5-3.5 3.5 1.57 3.5 3.5-1.57 3.5-3.5 3.5z\"></path></g>\n<g id=\"settings-applications\"><path d=\"M12 10c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm7-7H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.11 0 2-.9 2-2V5c0-1.1-.89-2-2-2zm-1.75 9c0 .23-.02.46-.05.68l1.48 1.16c.13.11.17.3.08.45l-1.4 2.42c-.09.15-.27.21-.43.15l-1.74-.7c-.36.28-.76.51-1.18.69l-.26 1.85c-.03.17-.18.3-.35.3h-2.8c-.17 0-.32-.13-.35-.29l-.26-1.85c-.43-.18-.82-.41-1.18-.69l-1.74.7c-.16.06-.34 0-.43-.15l-1.4-2.42c-.09-.15-.05-.34.08-.45l1.48-1.16c-.03-.23-.05-.46-.05-.69 0-.23.02-.46.05-.68l-1.48-1.16c-.13-.11-.17-.3-.08-.45l1.4-2.42c.09-.15.27-.21.43-.15l1.74.7c.36-.28.76-.51 1.18-.69l.26-1.85c.03-.17.18-.3.35-.3h2.8c.17 0 .32.13.35.29l.26 1.85c.43.18.82.41 1.18.69l1.74-.7c.16-.06.34 0 .43.15l1.4 2.42c.09.15.05.34-.08.45l-1.48 1.16c.03.23.05.46.05.69z\"></path></g>\n<g id=\"settings-backup-restore\"><path d=\"M14 12c0-1.1-.9-2-2-2s-2 .9-2 2 .9 2 2 2 2-.9 2-2zm-2-9c-4.97 0-9 4.03-9 9H0l4 4 4-4H5c0-3.87 3.13-7 7-7s7 3.13 7 7-3.13 7-7 7c-1.51 0-2.91-.49-4.06-1.3l-1.42 1.44C8.04 20.3 9.94 21 12 21c4.97 0 9-4.03 9-9s-4.03-9-9-9z\"></path></g>\n<g id=\"settings-bluetooth\"><path d=\"M11 24h2v-2h-2v2zm-4 0h2v-2H7v2zm8 0h2v-2h-2v2zm2.71-18.29L12 0h-1v7.59L6.41 3 5 4.41 10.59 10 5 15.59 6.41 17 11 12.41V20h1l5.71-5.71-4.3-4.29 4.3-4.29zM13 3.83l1.88 1.88L13 7.59V3.83zm1.88 10.46L13 16.17v-3.76l1.88 1.88z\"></path></g>\n<g id=\"settings-brightness\"><path d=\"M21 3H3c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16.01H3V4.99h18v14.02zM8 16h2.5l1.5 1.5 1.5-1.5H16v-2.5l1.5-1.5-1.5-1.5V8h-2.5L12 6.5 10.5 8H8v2.5L6.5 12 8 13.5V16zm4-7c1.66 0 3 1.34 3 3s-1.34 3-3 3V9z\"></path></g>\n<g id=\"settings-cell\"><path d=\"M7 24h2v-2H7v2zm4 0h2v-2h-2v2zm4 0h2v-2h-2v2zM16 .01L8 0C6.9 0 6 .9 6 2v16c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V2c0-1.1-.9-1.99-2-1.99zM16 16H8V4h8v12z\"></path></g>\n<g id=\"settings-ethernet\"><path d=\"M7.77 6.76L6.23 5.48.82 12l5.41 6.52 1.54-1.28L3.42 12l4.35-5.24zM7 13h2v-2H7v2zm10-2h-2v2h2v-2zm-6 2h2v-2h-2v2zm6.77-7.52l-1.54 1.28L20.58 12l-4.35 5.24 1.54 1.28L23.18 12l-5.41-6.52z\"></path></g>\n<g id=\"settings-input-antenna\"><path d=\"M12 5c-3.87 0-7 3.13-7 7h2c0-2.76 2.24-5 5-5s5 2.24 5 5h2c0-3.87-3.13-7-7-7zm1 9.29c.88-.39 1.5-1.26 1.5-2.29 0-1.38-1.12-2.5-2.5-2.5S9.5 10.62 9.5 12c0 1.02.62 1.9 1.5 2.29v3.3L7.59 21 9 22.41l3-3 3 3L16.41 21 13 17.59v-3.3zM12 1C5.93 1 1 5.93 1 12h2c0-4.97 4.03-9 9-9s9 4.03 9 9h2c0-6.07-4.93-11-11-11z\"></path></g>\n<g id=\"settings-input-component\"><path d=\"M5 2c0-.55-.45-1-1-1s-1 .45-1 1v4H1v6h6V6H5V2zm4 14c0 1.3.84 2.4 2 2.82V23h2v-4.18c1.16-.41 2-1.51 2-2.82v-2H9v2zm-8 0c0 1.3.84 2.4 2 2.82V23h2v-4.18C6.16 18.4 7 17.3 7 16v-2H1v2zM21 6V2c0-.55-.45-1-1-1s-1 .45-1 1v4h-2v6h6V6h-2zm-8-4c0-.55-.45-1-1-1s-1 .45-1 1v4H9v6h6V6h-2V2zm4 14c0 1.3.84 2.4 2 2.82V23h2v-4.18c1.16-.41 2-1.51 2-2.82v-2h-6v2z\"></path></g>\n<g id=\"settings-input-composite\"><path d=\"M5 2c0-.55-.45-1-1-1s-1 .45-1 1v4H1v6h6V6H5V2zm4 14c0 1.3.84 2.4 2 2.82V23h2v-4.18c1.16-.41 2-1.51 2-2.82v-2H9v2zm-8 0c0 1.3.84 2.4 2 2.82V23h2v-4.18C6.16 18.4 7 17.3 7 16v-2H1v2zM21 6V2c0-.55-.45-1-1-1s-1 .45-1 1v4h-2v6h6V6h-2zm-8-4c0-.55-.45-1-1-1s-1 .45-1 1v4H9v6h6V6h-2V2zm4 14c0 1.3.84 2.4 2 2.82V23h2v-4.18c1.16-.41 2-1.51 2-2.82v-2h-6v2z\"></path></g>\n<g id=\"settings-input-hdmi\"><path d=\"M18 7V4c0-1.1-.9-2-2-2H8c-1.1 0-2 .9-2 2v3H5v6l3 6v3h8v-3l3-6V7h-1zM8 4h8v3h-2V5h-1v2h-2V5h-1v2H8V4z\"></path></g>\n<g id=\"settings-input-svideo\"><path d=\"M8 11.5c0-.83-.67-1.5-1.5-1.5S5 10.67 5 11.5 5.67 13 6.5 13 8 12.33 8 11.5zm7-5c0-.83-.67-1.5-1.5-1.5h-3C9.67 5 9 5.67 9 6.5S9.67 8 10.5 8h3c.83 0 1.5-.67 1.5-1.5zM8.5 15c-.83 0-1.5.67-1.5 1.5S7.67 18 8.5 18s1.5-.67 1.5-1.5S9.33 15 8.5 15zM12 1C5.93 1 1 5.93 1 12s4.93 11 11 11 11-4.93 11-11S18.07 1 12 1zm0 20c-4.96 0-9-4.04-9-9s4.04-9 9-9 9 4.04 9 9-4.04 9-9 9zm5.5-11c-.83 0-1.5.67-1.5 1.5s.67 1.5 1.5 1.5 1.5-.67 1.5-1.5-.67-1.5-1.5-1.5zm-2 5c-.83 0-1.5.67-1.5 1.5s.67 1.5 1.5 1.5 1.5-.67 1.5-1.5-.67-1.5-1.5-1.5z\"></path></g>\n<g id=\"settings-overscan\"><path d=\"M12.01 5.5L10 8h4l-1.99-2.5zM18 10v4l2.5-1.99L18 10zM6 10l-2.5 2.01L6 14v-4zm8 6h-4l2.01 2.5L14 16zm7-13H3c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16.01H3V4.99h18v14.02z\"></path></g>\n<g id=\"settings-phone\"><path d=\"M13 9h-2v2h2V9zm4 0h-2v2h2V9zm3 6.5c-1.25 0-2.45-.2-3.57-.57-.35-.11-.74-.03-1.02.24l-2.2 2.2c-2.83-1.44-5.15-3.75-6.59-6.58l2.2-2.21c.28-.27.36-.66.25-1.01C8.7 6.45 8.5 5.25 8.5 4c0-.55-.45-1-1-1H4c-.55 0-1 .45-1 1 0 9.39 7.61 17 17 17 .55 0 1-.45 1-1v-3.5c0-.55-.45-1-1-1zM19 9v2h2V9h-2z\"></path></g>\n<g id=\"settings-power\"><path d=\"M7 24h2v-2H7v2zm4 0h2v-2h-2v2zm2-22h-2v10h2V2zm3.56 2.44l-1.45 1.45C16.84 6.94 18 8.83 18 11c0 3.31-2.69 6-6 6s-6-2.69-6-6c0-2.17 1.16-4.06 2.88-5.12L7.44 4.44C5.36 5.88 4 8.28 4 11c0 4.42 3.58 8 8 8s8-3.58 8-8c0-2.72-1.36-5.12-3.44-6.56zM15 24h2v-2h-2v2z\"></path></g>\n<g id=\"settings-remote\"><path d=\"M15 9H9c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h6c.55 0 1-.45 1-1V10c0-.55-.45-1-1-1zm-3 6c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zM7.05 6.05l1.41 1.41C9.37 6.56 10.62 6 12 6s2.63.56 3.54 1.46l1.41-1.41C15.68 4.78 13.93 4 12 4s-3.68.78-4.95 2.05zM12 0C8.96 0 6.21 1.23 4.22 3.22l1.41 1.41C7.26 3.01 9.51 2 12 2s4.74 1.01 6.36 2.64l1.41-1.41C17.79 1.23 15.04 0 12 0z\"></path></g>\n<g id=\"settings-voice\"><path d=\"M7 24h2v-2H7v2zm5-11c1.66 0 2.99-1.34 2.99-3L15 4c0-1.66-1.34-3-3-3S9 2.34 9 4v6c0 1.66 1.34 3 3 3zm-1 11h2v-2h-2v2zm4 0h2v-2h-2v2zm4-14h-1.7c0 3-2.54 5.1-5.3 5.1S6.7 13 6.7 10H5c0 3.41 2.72 6.23 6 6.72V20h2v-3.28c3.28-.49 6-3.31 6-6.72z\"></path></g>\n<g id=\"shop\"><path d=\"M16 6V4c0-1.11-.89-2-2-2h-4c-1.11 0-2 .89-2 2v2H2v13c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V6h-6zm-6-2h4v2h-4V4zM9 18V9l7.5 4L9 18z\"></path></g>\n<g id=\"shop-two\"><path d=\"M3 9H1v11c0 1.11.89 2 2 2h14c1.11 0 2-.89 2-2H3V9zm15-4V3c0-1.11-.89-2-2-2h-4c-1.11 0-2 .89-2 2v2H5v11c0 1.11.89 2 2 2h14c1.11 0 2-.89 2-2V5h-5zm-6-2h4v2h-4V3zm0 12V8l5.5 3-5.5 4z\"></path></g>\n<g id=\"shopping-basket\"><path d=\"M17.21 9l-4.38-6.56c-.19-.28-.51-.42-.83-.42-.32 0-.64.14-.83.43L6.79 9H2c-.55 0-1 .45-1 1 0 .09.01.18.04.27l2.54 9.27c.23.84 1 1.46 1.92 1.46h13c.92 0 1.69-.62 1.93-1.46l2.54-9.27L23 10c0-.55-.45-1-1-1h-4.79zM9 9l3-4.4L15 9H9zm3 8c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2z\"></path></g>\n<g id=\"shopping-cart\"><path d=\"M7 18c-1.1 0-1.99.9-1.99 2S5.9 22 7 22s2-.9 2-2-.9-2-2-2zM1 2v2h2l3.6 7.59-1.35 2.45c-.16.28-.25.61-.25.96 0 1.1.9 2 2 2h12v-2H7.42c-.14 0-.25-.11-.25-.25l.03-.12.9-1.63h7.45c.75 0 1.41-.41 1.75-1.03l3.58-6.49c.08-.14.12-.31.12-.48 0-.55-.45-1-1-1H5.21l-.94-2H1zm16 16c-1.1 0-1.99.9-1.99 2s.89 2 1.99 2 2-.9 2-2-.9-2-2-2z\"></path></g>\n<g id=\"sort\"><path d=\"M3 18h6v-2H3v2zM3 6v2h18V6H3zm0 7h12v-2H3v2z\"></path></g>\n<g id=\"speaker-notes\"><path d=\"M20 2H4c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zM8 14H6v-2h2v2zm0-3H6V9h2v2zm0-3H6V6h2v2zm7 6h-5v-2h5v2zm3-3h-8V9h8v2zm0-3h-8V6h8v2z\"></path></g>\n<g id=\"spellcheck\"><path d=\"M12.45 16h2.09L9.43 3H7.57L2.46 16h2.09l1.12-3h5.64l1.14 3zm-6.02-5L8.5 5.48 10.57 11H6.43zm15.16.59l-8.09 8.09L9.83 16l-1.41 1.41 5.09 5.09L23 13l-1.41-1.41z\"></path></g>\n<g id=\"star\"><path d=\"M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z\"></path></g>\n<g id=\"star-border\"><path d=\"M22 9.24l-7.19-.62L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21 12 17.27 18.18 21l-1.63-7.03L22 9.24zM12 15.4l-3.76 2.27 1-4.28-3.32-2.88 4.38-.38L12 6.1l1.71 4.04 4.38.38-3.32 2.88 1 4.28L12 15.4z\"></path></g>\n<g id=\"star-half\"><path d=\"M22 9.24l-7.19-.62L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21 12 17.27 18.18 21l-1.63-7.03L22 9.24zM12 15.4V6.1l1.71 4.04 4.38.38-3.32 2.88 1 4.28L12 15.4z\"></path></g>\n<g id=\"stars\"><path d=\"M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zm4.24 16L12 15.45 7.77 18l1.12-4.81-3.73-3.23 4.92-.42L12 5l1.92 4.53 4.92.42-3.73 3.23L16.23 18z\"></path></g>\n<g id=\"store\"><path d=\"M20 4H4v2h16V4zm1 10v-2l-1-5H4l-1 5v2h1v6h10v-6h4v6h2v-6h1zm-9 4H6v-4h6v4z\"></path></g>\n<g id=\"subdirectory-arrow-left\"><path d=\"M11 9l1.42 1.42L8.83 14H18V4h2v12H8.83l3.59 3.58L11 21l-6-6 6-6z\"></path></g>\n<g id=\"subdirectory-arrow-right\"><path d=\"M19 15l-6 6-1.42-1.42L15.17 16H4V4h2v10h9.17l-3.59-3.58L13 9l6 6z\"></path></g>\n<g id=\"subject\"><path d=\"M14 17H4v2h10v-2zm6-8H4v2h16V9zM4 15h16v-2H4v2zM4 5v2h16V5H4z\"></path></g>\n<g id=\"supervisor-account\"><path d=\"M16.5 12c1.38 0 2.49-1.12 2.49-2.5S17.88 7 16.5 7C15.12 7 14 8.12 14 9.5s1.12 2.5 2.5 2.5zM9 11c1.66 0 2.99-1.34 2.99-3S10.66 5 9 5C7.34 5 6 6.34 6 8s1.34 3 3 3zm7.5 3c-1.83 0-5.5.92-5.5 2.75V19h11v-2.25c0-1.83-3.67-2.75-5.5-2.75zM9 13c-2.33 0-7 1.17-7 3.5V19h7v-2.25c0-.85.33-2.34 2.37-3.47C10.5 13.1 9.66 13 9 13z\"></path></g>\n<g id=\"swap-horiz\"><path d=\"M6.99 11L3 15l3.99 4v-3H14v-2H6.99v-3zM21 9l-3.99-4v3H10v2h7.01v3L21 9z\"></path></g>\n<g id=\"swap-vert\"><path d=\"M16 17.01V10h-2v7.01h-3L15 21l4-3.99h-3zM9 3L5 6.99h3V14h2V6.99h3L9 3z\"></path></g>\n<g id=\"swap-vertical-circle\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zM6.5 9L10 5.5 13.5 9H11v4H9V9H6.5zm11 6L14 18.5 10.5 15H13v-4h2v4h2.5z\"></path></g>\n<g id=\"system-update-alt\"><path d=\"M12 16.5l4-4h-3v-9h-2v9H8l4 4zm9-13h-6v1.99h6v14.03H3V5.49h6V3.5H3c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2v-14c0-1.1-.9-2-2-2z\"></path></g>\n<g id=\"tab\"><path d=\"M21 3H3c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H3V5h10v4h8v10z\"></path></g>\n<g id=\"tab-unselected\"><path d=\"M1 9h2V7H1v2zm0 4h2v-2H1v2zm0-8h2V3c-1.1 0-2 .9-2 2zm8 16h2v-2H9v2zm-8-4h2v-2H1v2zm2 4v-2H1c0 1.1.9 2 2 2zM21 3h-8v6h10V5c0-1.1-.9-2-2-2zm0 14h2v-2h-2v2zM9 5h2V3H9v2zM5 21h2v-2H5v2zM5 5h2V3H5v2zm16 16c1.1 0 2-.9 2-2h-2v2zm0-8h2v-2h-2v2zm-8 8h2v-2h-2v2zm4 0h2v-2h-2v2z\"></path></g>\n<g id=\"text-format\"><path d=\"M5 17v2h14v-2H5zm4.5-4.2h5l.9 2.2h2.1L12.75 4h-1.5L6.5 15h2.1l.9-2.2zM12 5.98L13.87 11h-3.74L12 5.98z\"></path></g>\n<g id=\"theaters\"><path d=\"M18 3v2h-2V3H8v2H6V3H4v18h2v-2h2v2h8v-2h2v2h2V3h-2zM8 17H6v-2h2v2zm0-4H6v-2h2v2zm0-4H6V7h2v2zm10 8h-2v-2h2v2zm0-4h-2v-2h2v2zm0-4h-2V7h2v2z\"></path></g>\n<g id=\"thumb-down\"><path d=\"M15 3H6c-.83 0-1.54.5-1.84 1.22l-3.02 7.05c-.09.23-.14.47-.14.73v1.91l.01.01L1 14c0 1.1.9 2 2 2h6.31l-.95 4.57-.03.32c0 .41.17.79.44 1.06L9.83 23l6.59-6.59c.36-.36.58-.86.58-1.41V5c0-1.1-.9-2-2-2zm4 0v12h4V3h-4z\"></path></g>\n<g id=\"thumb-up\"><path d=\"M1 21h4V9H1v12zm22-11c0-1.1-.9-2-2-2h-6.31l.95-4.57.03-.32c0-.41-.17-.79-.44-1.06L14.17 1 7.59 7.59C7.22 7.95 7 8.45 7 9v10c0 1.1.9 2 2 2h9c.83 0 1.54-.5 1.84-1.22l3.02-7.05c.09-.23.14-.47.14-.73v-1.91l-.01-.01L23 10z\"></path></g>\n<g id=\"thumbs-up-down\"><path d=\"M12 6c0-.55-.45-1-1-1H5.82l.66-3.18.02-.23c0-.31-.13-.59-.33-.8L5.38 0 .44 4.94C.17 5.21 0 5.59 0 6v6.5c0 .83.67 1.5 1.5 1.5h6.75c.62 0 1.15-.38 1.38-.91l2.26-5.29c.07-.17.11-.36.11-.55V6zm10.5 4h-6.75c-.62 0-1.15.38-1.38.91l-2.26 5.29c-.07.17-.11.36-.11.55V18c0 .55.45 1 1 1h5.18l-.66 3.18-.02.24c0 .31.13.59.33.8l.79.78 4.94-4.94c.27-.27.44-.65.44-1.06v-6.5c0-.83-.67-1.5-1.5-1.5z\"></path></g>\n<g id=\"timeline\"><path d=\"M23 8c0 1.1-.9 2-2 2-.18 0-.35-.02-.51-.07l-3.56 3.55c.05.16.07.34.07.52 0 1.1-.9 2-2 2s-2-.9-2-2c0-.18.02-.36.07-.52l-2.55-2.55c-.16.05-.34.07-.52.07s-.36-.02-.52-.07l-4.55 4.56c.05.16.07.33.07.51 0 1.1-.9 2-2 2s-2-.9-2-2 .9-2 2-2c.18 0 .35.02.51.07l4.56-4.55C8.02 9.36 8 9.18 8 9c0-1.1.9-2 2-2s2 .9 2 2c0 .18-.02.36-.07.52l2.55 2.55c.16-.05.34-.07.52-.07s.36.02.52.07l3.55-3.56C19.02 8.35 19 8.18 19 8c0-1.1.9-2 2-2s2 .9 2 2z\"></path></g>\n<g id=\"toc\"><path d=\"M3 9h14V7H3v2zm0 4h14v-2H3v2zm0 4h14v-2H3v2zm16 0h2v-2h-2v2zm0-10v2h2V7h-2zm0 6h2v-2h-2v2z\"></path></g>\n<g id=\"today\"><path d=\"M19 3h-1V1h-2v2H8V1H6v2H5c-1.11 0-1.99.9-1.99 2L3 19c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V8h14v11zM7 10h5v5H7z\"></path></g>\n<g id=\"toll\"><path d=\"M15 4c-4.42 0-8 3.58-8 8s3.58 8 8 8 8-3.58 8-8-3.58-8-8-8zm0 14c-3.31 0-6-2.69-6-6s2.69-6 6-6 6 2.69 6 6-2.69 6-6 6zM3 12c0-2.61 1.67-4.83 4-5.65V4.26C3.55 5.15 1 8.27 1 12s2.55 6.85 6 7.74v-2.09c-2.33-.82-4-3.04-4-5.65z\"></path></g>\n<g id=\"touch-app\"><path d=\"M9 11.24V7.5C9 6.12 10.12 5 11.5 5S14 6.12 14 7.5v3.74c1.21-.81 2-2.18 2-3.74C16 5.01 13.99 3 11.5 3S7 5.01 7 7.5c0 1.56.79 2.93 2 3.74zm9.84 4.63l-4.54-2.26c-.17-.07-.35-.11-.54-.11H13v-6c0-.83-.67-1.5-1.5-1.5S10 6.67 10 7.5v10.74l-3.43-.72c-.08-.01-.15-.03-.24-.03-.31 0-.59.13-.79.33l-.79.8 4.94 4.94c.27.27.65.44 1.06.44h6.79c.75 0 1.33-.55 1.44-1.28l.75-5.27c.01-.07.02-.14.02-.2 0-.62-.38-1.16-.91-1.38z\"></path></g>\n<g id=\"track-changes\"><path d=\"M19.07 4.93l-1.41 1.41C19.1 7.79 20 9.79 20 12c0 4.42-3.58 8-8 8s-8-3.58-8-8c0-4.08 3.05-7.44 7-7.93v2.02C8.16 6.57 6 9.03 6 12c0 3.31 2.69 6 6 6s6-2.69 6-6c0-1.66-.67-3.16-1.76-4.24l-1.41 1.41C15.55 9.9 16 10.9 16 12c0 2.21-1.79 4-4 4s-4-1.79-4-4c0-1.86 1.28-3.41 3-3.86v2.14c-.6.35-1 .98-1 1.72 0 1.1.9 2 2 2s2-.9 2-2c0-.74-.4-1.38-1-1.72V2h-1C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10c0-2.76-1.12-5.26-2.93-7.07z\"></path></g>\n<g id=\"translate\"><path d=\"M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z\"></path></g>\n<g id=\"trending-down\"><path d=\"M16 18l2.29-2.29-4.88-4.88-4 4L2 7.41 3.41 6l6 6 4-4 6.3 6.29L22 12v6z\"></path></g>\n<g id=\"trending-flat\"><path d=\"M22 12l-4-4v3H3v2h15v3z\"></path></g>\n<g id=\"trending-up\"><path d=\"M16 6l2.29 2.29-4.88 4.88-4-4L2 16.59 3.41 18l6-6 4 4 6.3-6.29L22 12V6z\"></path></g>\n<g id=\"turned-in\"><path d=\"M17 3H7c-1.1 0-1.99.9-1.99 2L5 21l7-3 7 3V5c0-1.1-.9-2-2-2z\"></path></g>\n<g id=\"turned-in-not\"><path d=\"M17 3H7c-1.1 0-1.99.9-1.99 2L5 21l7-3 7 3V5c0-1.1-.9-2-2-2zm0 15l-5-2.18L7 18V5h10v13z\"></path></g>\n<g id=\"unarchive\"><path d=\"M20.55 5.22l-1.39-1.68C18.88 3.21 18.47 3 18 3H6c-.47 0-.88.21-1.15.55L3.46 5.22C3.17 5.57 3 6.01 3 6.5V19c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V6.5c0-.49-.17-.93-.45-1.28zM12 9.5l5.5 5.5H14v2h-4v-2H6.5L12 9.5zM5.12 5l.82-1h12l.93 1H5.12z\"></path></g>\n<g id=\"undo\"><path d=\"M12.5 8c-2.65 0-5.05.99-6.9 2.6L2 7v9h9l-3.62-3.62c1.39-1.16 3.16-1.88 5.12-1.88 3.54 0 6.55 2.31 7.6 5.5l2.37-.78C21.08 11.03 17.15 8 12.5 8z\"></path></g>\n<g id=\"unfold-less\"><path d=\"M7.41 18.59L8.83 20 12 16.83 15.17 20l1.41-1.41L12 14l-4.59 4.59zm9.18-13.18L15.17 4 12 7.17 8.83 4 7.41 5.41 12 10l4.59-4.59z\"></path></g>\n<g id=\"unfold-more\"><path d=\"M12 5.83L15.17 9l1.41-1.41L12 3 7.41 7.59 8.83 9 12 5.83zm0 12.34L8.83 15l-1.41 1.41L12 21l4.59-4.59L15.17 15 12 18.17z\"></path></g>\n<g id=\"update\"><path d=\"M21 10.12h-6.78l2.74-2.82c-2.73-2.7-7.15-2.8-9.88-.1-2.73 2.71-2.73 7.08 0 9.79 2.73 2.71 7.15 2.71 9.88 0C18.32 15.65 19 14.08 19 12.1h2c0 1.98-.88 4.55-2.64 6.29-3.51 3.48-9.21 3.48-12.72 0-3.5-3.47-3.53-9.11-.02-12.58 3.51-3.47 9.14-3.47 12.65 0L21 3v7.12zM12.5 8v4.25l3.5 2.08-.72 1.21L11 13V8h1.5z\"></path></g>\n<g id=\"verified-user\"><path d=\"M12 1L3 5v6c0 5.55 3.84 10.74 9 12 5.16-1.26 9-6.45 9-12V5l-9-4zm-2 16l-4-4 1.41-1.41L10 14.17l6.59-6.59L18 9l-8 8z\"></path></g>\n<g id=\"view-agenda\"><path d=\"M20 13H3c-.55 0-1 .45-1 1v6c0 .55.45 1 1 1h17c.55 0 1-.45 1-1v-6c0-.55-.45-1-1-1zm0-10H3c-.55 0-1 .45-1 1v6c0 .55.45 1 1 1h17c.55 0 1-.45 1-1V4c0-.55-.45-1-1-1z\"></path></g>\n<g id=\"view-array\"><path d=\"M4 18h3V5H4v13zM18 5v13h3V5h-3zM8 18h9V5H8v13z\"></path></g>\n<g id=\"view-carousel\"><path d=\"M7 19h10V4H7v15zm-5-2h4V6H2v11zM18 6v11h4V6h-4z\"></path></g>\n<g id=\"view-column\"><path d=\"M10 18h5V5h-5v13zm-6 0h5V5H4v13zM16 5v13h5V5h-5z\"></path></g>\n<g id=\"view-day\"><path d=\"M2 21h19v-3H2v3zM20 8H3c-.55 0-1 .45-1 1v6c0 .55.45 1 1 1h17c.55 0 1-.45 1-1V9c0-.55-.45-1-1-1zM2 3v3h19V3H2z\"></path></g>\n<g id=\"view-headline\"><path d=\"M4 15h16v-2H4v2zm0 4h16v-2H4v2zm0-8h16V9H4v2zm0-6v2h16V5H4z\"></path></g>\n<g id=\"view-list\"><path d=\"M4 14h4v-4H4v4zm0 5h4v-4H4v4zM4 9h4V5H4v4zm5 5h12v-4H9v4zm0 5h12v-4H9v4zM9 5v4h12V5H9z\"></path></g>\n<g id=\"view-module\"><path d=\"M4 11h5V5H4v6zm0 7h5v-6H4v6zm6 0h5v-6h-5v6zm6 0h5v-6h-5v6zm-6-7h5V5h-5v6zm6-6v6h5V5h-5z\"></path></g>\n<g id=\"view-quilt\"><path d=\"M10 18h5v-6h-5v6zm-6 0h5V5H4v13zm12 0h5v-6h-5v6zM10 5v6h11V5H10z\"></path></g>\n<g id=\"view-stream\"><path d=\"M4 18h17v-6H4v6zM4 5v6h17V5H4z\"></path></g>\n<g id=\"view-week\"><path d=\"M6 5H3c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h3c.55 0 1-.45 1-1V6c0-.55-.45-1-1-1zm14 0h-3c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h3c.55 0 1-.45 1-1V6c0-.55-.45-1-1-1zm-7 0h-3c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h3c.55 0 1-.45 1-1V6c0-.55-.45-1-1-1z\"></path></g>\n<g id=\"visibility\"><path d=\"M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z\"></path></g>\n<g id=\"visibility-off\"><path d=\"M12 7c2.76 0 5 2.24 5 5 0 .65-.13 1.26-.36 1.83l2.92 2.92c1.51-1.26 2.7-2.89 3.43-4.75-1.73-4.39-6-7.5-11-7.5-1.4 0-2.74.25-3.98.7l2.16 2.16C10.74 7.13 11.35 7 12 7zM2 4.27l2.28 2.28.46.46C3.08 8.3 1.78 10.02 1 12c1.73 4.39 6 7.5 11 7.5 1.55 0 3.03-.3 4.38-.84l.42.42L19.73 22 21 20.73 3.27 3 2 4.27zM7.53 9.8l1.55 1.55c-.05.21-.08.43-.08.65 0 1.66 1.34 3 3 3 .22 0 .44-.03.65-.08l1.55 1.55c-.67.33-1.41.53-2.2.53-2.76 0-5-2.24-5-5 0-.79.2-1.53.53-2.2zm4.31-.78l3.15 3.15.02-.16c0-1.66-1.34-3-3-3l-.17.01z\"></path></g>\n<g id=\"warning\"><path d=\"M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z\"></path></g>\n<g id=\"watch-later\"><path d=\"M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10 10-4.5 10-10S17.5 2 12 2zm4.2 14.2L11 13V7h1.5v5.2l4.5 2.7-.8 1.3z\"></path></g>\n<g id=\"weekend\"><path d=\"M21 10c-1.1 0-2 .9-2 2v3H5v-3c0-1.1-.9-2-2-2s-2 .9-2 2v5c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2v-5c0-1.1-.9-2-2-2zm-3-5H6c-1.1 0-2 .9-2 2v2.15c1.16.41 2 1.51 2 2.82V14h12v-2.03c0-1.3.84-2.4 2-2.82V7c0-1.1-.9-2-2-2z\"></path></g>\n<g id=\"work\"><path d=\"M20 6h-4V4c0-1.11-.89-2-2-2h-4c-1.11 0-2 .89-2 2v2H4c-1.11 0-1.99.89-1.99 2L2 19c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V8c0-1.11-.89-2-2-2zm-6 0h-4V4h4v2z\"></path></g>\n<g id=\"youtube-searched-for\"><path d=\"M17.01 14h-.8l-.27-.27c.98-1.14 1.57-2.61 1.57-4.23 0-3.59-2.91-6.5-6.5-6.5s-6.5 3-6.5 6.5H2l3.84 4 4.16-4H6.51C6.51 7 8.53 5 11.01 5s4.5 2.01 4.5 4.5c0 2.48-2.02 4.5-4.5 4.5-.65 0-1.26-.14-1.82-.38L7.71 15.1c.97.57 2.09.9 3.3.9 1.61 0 3.08-.59 4.22-1.57l.27.27v.79l5.01 4.99L22 19l-4.99-5z\"></path></g>\n<g id=\"zoom-in\"><path d=\"M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14zm2.5-4h-2v2H9v-2H7V9h2V7h1v2h2v1z\"></path></g>\n<g id=\"zoom-out\"><path d=\"M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14zM7 9h5v1H7z\"></path></g>\n</defs></svg>\n</iron-iconset-svg>\n\n\n\n\n<dom-module id=\"paper-material-shared-styles\" assetpath=\"/paper-material/\">\n  <template>\n    <style>\n      :host {\n        display: block;\n        position: relative;\n      }\n\n      :host([elevation=\"1\"]) {\n        @apply(--shadow-elevation-2dp);\n      }\n\n      :host([elevation=\"2\"]) {\n        @apply(--shadow-elevation-4dp);\n      }\n\n      :host([elevation=\"3\"]) {\n        @apply(--shadow-elevation-6dp);\n      }\n\n      :host([elevation=\"4\"]) {\n        @apply(--shadow-elevation-8dp);\n      }\n\n      :host([elevation=\"5\"]) {\n        @apply(--shadow-elevation-16dp);\n      }\n    </style>\n  </template>\n</dom-module>\n<dom-module id=\"paper-material\" assetpath=\"/paper-material/\">\n  <template>\n    <style include=\"paper-material-shared-styles\"></style>\n    <style>\n      :host([animated]) {\n        @apply(--shadow-transition);\n      }\n    </style>\n\n    <content></content>\n  </template>\n</dom-module>\n<dom-module id=\"paper-button\" assetpath=\"/paper-button/\">\n  <template strip-whitespace=\"\">\n\n    <style include=\"paper-material\">\n      :host {\n        display: inline-block;\n        position: relative;\n        box-sizing: border-box;\n        min-width: 5.14em;\n        margin: 0 0.29em;\n        background: transparent;\n        text-align: center;\n        font: inherit;\n        text-transform: uppercase;\n        outline-width: 0;\n        border-radius: 3px;\n        -moz-user-select: none;\n        -ms-user-select: none;\n        -webkit-user-select: none;\n        user-select: none;\n        cursor: pointer;\n        z-index: 0;\n        padding: 0.7em 0.57em;\n\n        @apply(--paper-button);\n      }\n\n      :host([raised].keyboard-focus) {\n        font-weight: bold;\n        @apply(--paper-button-raised-keyboard-focus);\n      }\n\n      :host(:not([raised]).keyboard-focus) {\n        font-weight: bold;\n        @apply(--paper-button-flat-keyboard-focus);\n      }\n\n      :host([disabled]) {\n        background: #eaeaea;\n        color: #a8a8a8;\n        cursor: auto;\n        pointer-events: none;\n\n        @apply(--paper-button-disabled);\n      }\n\n      paper-ripple {\n        color: var(--paper-button-ink-color);\n      }\n\n      :host > ::content * {\n        text-transform: inherit;\n      }\n    </style>\n    <content></content>\n  </template>\n</dom-module>\n\n<dom-module id=\"iron-image\" assetpath=\"/iron-image/\">\n  <template>\n    <style>\n      :host {\n        display: inline-block;\n        overflow: hidden;\n        position: relative;\n      }\n\n      #sizedImgDiv {\n        @apply(--layout-fit);\n\n        display: none;\n      }\n\n      #img {\n        display: block;\n        width: var(--iron-image-width, auto);\n        height: var(--iron-image-height, auto);\n      }\n\n      :host([sizing]) #sizedImgDiv {\n        display: block;\n      }\n\n      :host([sizing]) #img {\n        display: none;\n      }\n\n      #placeholder {\n        @apply(--layout-fit);\n\n        background-color: inherit;\n        opacity: 1;\n\n        @apply(--iron-image-placeholder);\n      }\n\n      #placeholder.faded-out {\n        transition: opacity 0.5s linear;\n        opacity: 0;\n      }\n    </style>\n\n    <div id=\"sizedImgDiv\" role=\"img\" hidden$=\"[[V_(sizing)]]\" aria-hidden$=\"[[T_(alt)]]\" aria-label$=\"[[U_(alt,src)]]\"></div>\n    <img id=\"img\" alt$=\"[[alt]]\" hidden$=\"[[W_(sizing)]]\">\n    <div id=\"placeholder\" hidden$=\"[[a0(preload,fade,loading,loaded)]]\" class$=\"[[$_(preload,fade,loading,loaded)]]\"></div>\n  </template>\n\n  </dom-module>\n<dom-module id=\"paper-card\" assetpath=\"/paper-card/\">\n  <template>\n    <style include=\"paper-material\">\n      :host {\n        display: inline-block;\n        position: relative;\n        box-sizing: border-box;\n        background-color: var(--paper-card-background-color, --primary-background-color);\n        border-radius: 2px;\n\n        @apply(--paper-font-common-base);\n        @apply(--paper-card);\n      }\n\n      /* IE 10 support for HTML5 hidden attr */\n      [hidden] {\n        display: none !important;\n      }\n\n      .header {\n        position: relative;\n        border-top-left-radius: inherit;\n        border-top-right-radius: inherit;\n        overflow: hidden;\n\n        @apply(--paper-card-header);\n      }\n\n      .header iron-image {\n        display: block;\n        width: 100%;\n        --iron-image-width: 100%;\n        pointer-events: none;\n\n        @apply(--paper-card-header-image);\n      }\n\n      .header .title-text {\n        padding: 16px;\n        font-size: 24px;\n        font-weight: 400;\n        color: var(--paper-card-header-color, #000);\n\n        @apply(--paper-card-header-text);\n      }\n\n      .header .title-text.over-image {\n        position: absolute;\n        bottom: 0px;\n\n        @apply(--paper-card-header-image-text);\n      }\n\n      :host ::content .card-content {\n        padding: 16px;\n        position:relative;\n\n        @apply(--paper-card-content);\n      }\n\n      :host ::content .card-actions {\n        border-top: 1px solid #e8e8e8;\n        padding: 5px 16px;\n        position:relative;\n\n        @apply(--paper-card-actions);\n      }\n    </style>\n\n    <div class=\"header\">\n      <iron-image hidden$=\"[[!image]]\" aria-hidden$=\"[[A0(image)]]\" src=\"[[image]]\" alt=\"[[alt]]\" placeholder=\"[[placeholderImage]]\" preload=\"[[preloadImage]]\" fade=\"[[fadeImage]]\"></iron-image>\n      <div hidden$=\"[[!heading]]\" class$=\"title-text [[S_(image)]]\">[[heading]]</div>\n    </div>\n\n    <content></content>\n  </template>\n\n  </dom-module>\n\n\n<dom-module id=\"paper-dialog-shared-styles\" assetpath=\"/paper-dialog-behavior/\">\n  <template>\n    <style>\n      :host {\n        display: block;\n        margin: 24px 40px;\n\n        background: var(--paper-dialog-background-color, --primary-background-color);\n        color: var(--paper-dialog-color, --primary-text-color);\n\n        @apply(--paper-font-body1);\n        @apply(--shadow-elevation-16dp);\n        @apply(--paper-dialog);\n      }\n\n      :host > ::content > * {\n        margin-top: 20px;\n        padding: 0 24px;\n      }\n\n      :host > ::content > .no-padding {\n        padding: 0;\n      }\n\n      :host > ::content > *:first-child {\n        margin-top: 24px;\n      }\n\n      :host > ::content > *:last-child {\n        margin-bottom: 24px;\n      }\n\n      :host > ::content h2 {\n        position: relative;\n        margin: 0;\n        @apply(--paper-font-title);\n\n        @apply(--paper-dialog-title);\n      }\n\n      :host > ::content .buttons {\n        position: relative;\n        padding: 8px 8px 8px 24px;\n        margin: 0;\n\n        color: var(--paper-dialog-button-color, --primary-color);\n\n        @apply(--layout-horizontal);\n        @apply(--layout-end-justified);\n      }\n    </style>\n  </template>\n</dom-module>\n<dom-module id=\"paper-dialog\" assetpath=\"/paper-dialog/\">\n  <template>\n    <style include=\"paper-dialog-shared-styles\"></style>\n    <content></content>\n  </template>\n</dom-module>\n\n<dom-module id=\"paper-icon-button\" assetpath=\"/paper-icon-button/\">\n  <template strip-whitespace=\"\">\n    <style>\n      :host {\n        display: inline-block;\n        position: relative;\n        padding: 8px;\n        outline: none;\n        -webkit-user-select: none;\n        -moz-user-select: none;\n        -ms-user-select: none;\n        user-select: none;\n        cursor: pointer;\n        z-index: 0;\n        line-height: 1;\n\n        width: 40px;\n        height: 40px;\n\n        /* NOTE: Both values are needed, since some phones require the value to be `transparent`. */\n        -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n        -webkit-tap-highlight-color: transparent;\n\n        /* Because of polymer/2558, this style has lower specificity than * */\n        box-sizing: border-box !important;\n\n        @apply(--paper-icon-button);\n      }\n\n      :host #ink {\n        color: var(--paper-icon-button-ink-color, --primary-text-color);\n        opacity: 0.6;\n      }\n\n      :host([disabled]) {\n        color: var(--paper-icon-button-disabled-text, --disabled-text-color);\n        pointer-events: none;\n        cursor: auto;\n\n        @apply(--paper-icon-button-disabled);\n      }\n\n      :host(:hover) {\n        @apply(--paper-icon-button-hover);\n      }\n\n      iron-icon {\n        --iron-icon-width: 100%;\n        --iron-icon-height: 100%;\n      }\n    </style>\n\n    <iron-icon id=\"icon\" src=\"[[src]]\" icon=\"[[icon]]\" alt$=\"[[alt]]\"></iron-icon>\n  </template>\n\n  </dom-module>\n\n\n<dom-module id=\"paper-toggle-button\" assetpath=\"/paper-toggle-button/\">\n  <template strip-whitespace=\"\">\n\n    <style>\n      :host {\n        display: inline-block;\n        @apply(--layout-horizontal);\n        @apply(--layout-center);\n        @apply(--paper-font-common-base);\n      }\n\n      :host([disabled]) {\n        pointer-events: none;\n      }\n\n      :host(:focus) {\n        outline:none;\n      }\n\n      .toggle-bar {\n        position: absolute;\n        height: 100%;\n        width: 100%;\n        border-radius: 8px;\n        pointer-events: none;\n        opacity: 0.4;\n        transition: background-color linear .08s;\n        background-color: var(--paper-toggle-button-unchecked-bar-color, #000000);\n\n        @apply(--paper-toggle-button-unchecked-bar);\n      }\n\n      .toggle-button {\n        position: absolute;\n        top: -3px;\n        left: 0;\n        height: 20px;\n        width: 20px;\n        border-radius: 50%;\n        box-shadow: 0 1px 5px 0 rgba(0, 0, 0, 0.6);\n        transition: -webkit-transform linear .08s, background-color linear .08s;\n        transition: transform linear .08s, background-color linear .08s;\n        will-change: transform;\n        background-color: var(--paper-toggle-button-unchecked-button-color, --paper-grey-50);\n\n        @apply(--paper-toggle-button-unchecked-button);\n      }\n\n      .toggle-button.dragging {\n        -webkit-transition: none;\n        transition: none;\n      }\n\n      :host([checked]:not([disabled])) .toggle-bar {\n        opacity: 0.5;\n        background-color: var(--paper-toggle-button-checked-bar-color, --primary-color);\n\n        @apply(--paper-toggle-button-checked-bar);\n      }\n\n      :host([disabled]) .toggle-bar {\n        background-color: #000;\n        opacity: 0.12;\n      }\n\n      :host([checked]) .toggle-button {\n        -webkit-transform: translate(16px, 0);\n        transform: translate(16px, 0);\n      }\n\n      :host([checked]:not([disabled])) .toggle-button {\n        background-color: var(--paper-toggle-button-checked-button-color, --primary-color);\n\n        @apply(--paper-toggle-button-checked-button);\n      }\n\n      :host([disabled]) .toggle-button {\n        background-color: #bdbdbd;\n        opacity: 1;\n      }\n\n      .toggle-ink {\n        position: absolute;\n        top: -14px;\n        left: -14px;\n        right: auto;\n        bottom: auto;\n        width: 48px;\n        height: 48px;\n        opacity: 0.5;\n        pointer-events: none;\n        color: var(--paper-toggle-button-unchecked-ink-color, --primary-text-color);\n      }\n\n      :host([checked]) .toggle-ink {\n        color: var(--paper-toggle-button-checked-ink-color, --primary-color);\n      }\n\n      .toggle-container {\n        display: inline-block;\n        position: relative;\n        width: 36px;\n        height: 14px;\n        /* The toggle button has an absolute position of -3px; The extra 1px\n        /* accounts for the toggle button shadow box. */\n        margin: 4px 1px;\n      }\n\n      .toggle-label {\n        position: relative;\n        display: inline-block;\n        vertical-align: middle;\n        padding-left: var(--paper-toggle-button-label-spacing, 8px);\n        pointer-events: none;\n        color: var(--paper-toggle-button-label-color, --primary-text-color);\n      }\n\n      /* invalid state */\n      :host([invalid]) .toggle-bar {\n        background-color: var(--paper-toggle-button-invalid-bar-color, --error-color);\n      }\n\n      :host([invalid]) .toggle-button {\n        background-color: var(--paper-toggle-button-invalid-button-color, --error-color);\n      }\n\n      :host([invalid]) .toggle-ink {\n        color: var(--paper-toggle-button-invalid-ink-color, --error-color);\n      }\n    </style>\n\n    <div class=\"toggle-container\">\n      <div id=\"toggleBar\" class=\"toggle-bar\"></div>\n      <div id=\"toggleButton\" class=\"toggle-button\"></div>\n    </div>\n\n    <div class=\"toggle-label\"><content></content></div>\n\n  </template>\n\n  </dom-module>\n<dom-module id=\"gviz-loader\" assetpath=\"/gviz-loader/\">\n  <template>\n  </template>\n  </dom-module>\n<dom-module id=\"metrics-histogram\" assetpath=\"/metrics-histogram/\">\n  \n  <template><style>\n:host {\n  display: block;\n}\n\n.section {\n  margin: 5px 0;\n}\n\n.ui {\n  margin: auto;\n  width: 680px; /* Three ui-elements (210px each) + options toggle (50px) */\n}\n\n.ui-input {\n  width: 200px;\n}\n\n.ui-element {\n  display: inline-block;\n  margin-right: 2px;\n}\n\n.placeholder {\n  height: 32px;\n  display: flex;\n}\n\n#overview ::content path.blue {\n  fill: #3366cc;\n}\n\n#overview ::content path.red {\n  fill: #dc3912;\n}\n\n#overview ::content rect.overview {\n  fill: #ccc;\n  stroke: #000;\n  opacity: .1;\n}\n\n#overview ::content rect#focus {\n  fill: gray;\n  stroke: #000;\n  opacity: .2;\n}\n\n#details ::content rect.highlighted {\n  fill: #ffde5a;\n}\n\n#details ::content g.highlighted text {\n  fill: #212121;\n  font-weight: bold;\n}\n\n#empty {\n  margin: 20px auto 0;\n  width: calc(100% - 240px);\n  text-align: center;\n}\n\n</style>\n    <gviz-loader id=\"loader\" packages=\"[[chartPackages_]]\"></gviz-loader>\n    <div class=\"ui section\">\n      <span id=\"metric-select\" class=\"ui-element ui-input\">\n        <paper-dropdown-menu label=\"Select Metric\">\n          <paper-listbox class=\"dropdown-content\" selected=\"{{metric}}\" attr-for-selected=\"value\">\n            <template is=\"dom-repeat\" items=\"[[selectableMetrics_]]\">\n              <paper-item value=\"[[item]]\">[[item]]</paper-item>\n            </template>\n          </paper-listbox>\n        </paper-dropdown-menu>\n        <div class=\"placeholder\"></div>\n      </span>\n      <span id=\"type-select\" class=\"ui-element ui-input\">\n        <paper-dropdown-menu label=\"Histogram Type\">\n          <paper-listbox class=\"dropdown-content\" selected=\"{{type}}\" attr-for-selected=\"value\">\n            <paper-item value=\"unweighted\">Slice Counts</paper-item>\n            <paper-item value=\"weighted\">Example Counts</paper-item>\n            <paper-item value=\"both\">Both</paper-item>\n          </paper-listbox>\n        </paper-dropdown-menu>\n        <div class=\"placeholder\"></div>\n      </span>\n      <span id=\"num-buckets\" class=\"ui-element ui-input\">\n        <paper-input label=\"Number of Buckets\" always-float-label=\"\" value=\"{{numBuckets}}\" auto-validate=\"\" pattern=\"[1-9]|[1-4][0-9]|50\" error-message=\"must be between [1, 50]\"></paper-input>\n        <paper-slider class=\"slider\" min=\"1\" max=\"50\" value=\"{{numBuckets}}\" immediate-value=\"{{numBuckets}}\"></paper-slider>\n      </span>\n      <span class=\"ui-element\">\n        <paper-icon-button id=\"options-toggle\" icon=\"settings\" data-dialog=\"options\" on-tap=\"l$\">More Options</paper-icon-button>\n        <div class=\"placeholder\"></div>\n        <paper-dialog id=\"options\">\n          <h2>Options</h2>\n          <div>\n            <paper-toggle-button id=\"logarithm-scale\" type=\"checkbox\" checked=\"{{logarithmScale}}\">Logarithm Scale</paper-toggle-button>\n          </div>\n        </paper-dialog>\n      </span>\n    </div>\n    <svg id=\"overview\" class=\"section\">\n      <g class=\"unweighted\"></g>\n      <g class=\"weighted\"></g>\n    </svg>\n    <div id=\"details\"></div>\n    <paper-card id=\"empty\">\n      <div class=\"card-content\">\n        <paper-icon-button icon=\"block\"></paper-icon-button>\n        <div>Empty Histogram</div>\n      </div>\n    </paper-card>\n  </template>\n  </dom-module>\n<dom-module id=\"gviz-table\" assetpath=\"/gviz-table/\">\n  <template>\n    <gviz-loader id=\"loader\"></gviz-loader>\n    <div id=\"table\"></div>\n  </template>\n  </dom-module>\n<dom-module id=\"bounded-value\" assetpath=\"/bounded-value/\">\n  \n  <template><style>\n:host {\n  display: block;\n}\n\n</style>\n    [[value_]]±[[range_]]\n  </template>\n  </dom-module>\n<dom-module id=\"precision-at-k\" assetpath=\"/precision-at-k/\">\n  \n  <template><style>\n:host div.tr:nth-child(even) {\n  background: #e4e4e4;\n}\n\n/**\n * NOTE(paulyang): There is a bad interaction between dom-repeat element, table\n * tag and vulcanization. Use div and equivalent display: table* on class table,\n * tr and td as a work-around.\n *\n * See b/22376520 for more details.\n */\n:host div.table {\n  text-align: center;\n  display: table;\n}\n\n:host div.td {\n  min-width: 15px;\n  padding: 0 5px;\n  display: table-cell;\n}\n\n:host div.tr {\n  display: table-row;\n}\n\n/**\n * Hides the weighted count when comparinging precision at k inside\n * lantern-model-diff.\n */\n:host-context(lantern-model-diff) div.td:nth-child(3) {\n  display: none;\n}\n\n</style>\n    <div class=\"table\">\n        <template is=\"dom-repeat\" items=\"{{formattedData_}}\">\n          <div class=\"tr\">\n            <div class=\"td\">[[item.k]]</div>\n            <div class=\"td\">[[item.value]]</div>\n            <div class=\"td\">[[item.total]]</div>\n          </div>\n        </template>\n      \n    </div>\n  </template>\n  </dom-module>\n<dom-module id=\"metrics-table\" assetpath=\"/metrics-table/\">\n  \n  <template><style>\n:host {\n  display: block;\n  box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14),\n              0 1px 5px 0 rgba(0, 0, 0, 0.12),\n              0 3px 1px -2px rgba(0, 0, 0, 0.2)\n}\n\ngoogle-chart {\n  width: 100%;\n  height: 100%;\n}\n\ngoogle-chart ::content * {\n  font-family: 'Roboto','Noto','Helvetica Neue',Helvetica,Arial,sans-serif;\n  font-weight: 400;\n  font-size: 12px;\n  text-align: left;\n}\n\ngoogle-chart ::content .google-visualization-table-th {\n  font-weight: 500;\n  text-overflow: ellipsis;\n  color: rgba(0,0,0,0.54);\n  border-right: none;\n  padding: 0 24px 0 24px;\n  background-color: white;\n  text-align: left;\n  box-shadow: 0 1px 0 rgba(0, 0, 0, 0.09),\n              0 2px 0 rgba(0, 0, 0, 0.03),\n              0 3px 0 rgba(0, 0, 0, 0.01),\n              0 4px 0 rgba(0, 0, 0, 0.005);\n  -webkit-user-select: none;\n}\n\ngoogle-chart ::content .google-visualization-table-td {\n  font-size: 13px;\n  color: rgba(0,0,0,0.87);\n  border-bottom: 1px solid #e3e3e3;\n  border-right: none;\n  padding: 0 24px 0 24px;\n}\n\ngoogle-chart ::content thead > tr {\n  height: 56px;\n}\n\ngoogle-chart ::content tbody > tr {\n  line-height: 2.2;\n}\n\ngoogle-chart ::content .sort-descending > span.google-visualization-table-sortind::after {\n  content: \"➔\";\n  font-size: 13px;\n  display: inline-block;\n  transform: rotate(90deg);\n  color: rgba(0, 0, 0, 0.87);\n}\n\ngoogle-chart ::content .sort-ascending > span.google-visualization-table-sortind::after {\n  content: \"➔\";\n  font-size: 13px;\n  display: inline-block;\n  transform: rotate(-90deg);\n  color: rgba(0, 0, 0, 0.87);\n}\n\ngoogle-chart ::content .google-visualization-table-div-page {\n  background-color: white;\n  position: relative;\n  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.14);\n  border: none;\n}\n\ngoogle-chart ::content tr.google-visualization-table-tr-sel,\ngoogle-chart ::content tr.google-visualization-table-tr-sel.google-visualization-table-tr-over {\n  background-color: #eee;\n}\n\ngoogle-chart ::content tr.google-visualization-table-tr-over {\n  background-color: #e9e9e9;\n}\n\ngoogle-chart ::content .google-visualization-table-tr-odd {\n  background-color: white;\n}\n\ngoogle-chart ::content a.google-visualization-table-page-number:hover {\n  font-weight: bold;\n}\n\ngoogle-chart ::content a.google-visualization-table-page-number {\n  padding: 4px;\n  background-color: white;\n  border: 1px solid rgba(0,0,0,.2);\n  text-align: center;\n  font-size: 11px;\n  color: rgba(0,0,0,.87);\n}\n\ngoogle-chart ::content a.google-visualization-table-page-number.current {\n  font-size: 12px;\n}\n\n/*\n * For the following rules, we have two versions for the experiment browser and\n * the other environments. In the experiment browser, the chart styles are\n * prefixed with \"charts\" while in other places the prefixes are \"goog\".\n */\ngoogle-chart ::content .goog-custom-button-hover .goog-custom-button-inner-box,\ngoogle-chart ::content .goog-custom-button-hover .goog-custom-button-outer-box,\ngoogle-chart ::content .charts-custom-button-hover .charts-custom-button-inner-box,\ngoogle-chart ::content .charts-custom-button-hover .charts-custom-button-outer-box {\n  border-color: rgba(0,0,0,.3) !important; /* Overwrite google-chart important */\n}\n\ngoogle-chart ::content .goog-inline-block.goog-custom-button-outer-box,\ngoogle-chart ::content .charts-inline-block.charts-custom-button-outer-box {\n  background-color: white;\n  border-color: rgba(0,0,0,.2);\n}\n\ngoogle-chart ::content .goog-inline-block.goog-custom-button-inner-box,\ngoogle-chart ::content .charts-inline-block.charts-custom-button-inner-box {\n  padding: 4px;\n  color: rgba(0,0,0,.4);\n}\n\n\n</style>\n    <gviz-table type=\"table\" options=\"[[options]]\" data=\"[[plotData_]]\" selection=\"{{selection}}\" chart-ready=\"{{tableReady_}}\">\n    </gviz-table>\n  </template>\n  </dom-module>\n<dom-module id=\"slice-overview\" assetpath=\"/slice-overview/\">\n  <template>\n    <style>\n      #controls {\n        margin: 0 auto 20px;\n        width: 724px;\n      }\n      #controls paper-dropdown-menu {\n        width: 320px;\n        padding: 0 12px;\n      }\n    </style>\n    <div id=\"controls\">\n      <paper-dropdown-menu label=\"Show\">\n        <paper-listbox class=\"dropdown-content\" selected=\"{{metricToShow}}\" attr-for-selected=\"value\">\n          <template is=\"dom-repeat\" items=\"[[metrics_]]\">\n            <paper-item value=\"[[item.name]]\" disabled=\"[[item.disabled]]\">\n              [[item.name]]\n            </paper-item>\n          </template>\n        </paper-listbox>\n      </paper-dropdown-menu>\n      <paper-dropdown-menu label=\"Sort by\">\n        <paper-listbox class=\"dropdown-content\" selected=\"{{metricToSort_}}\" attr-for-selected=\"value\">\n          <template is=\"dom-repeat\" items=\"[[metricsForSorting_]]\">\n            <paper-item value=\"[[item.name]]\" disabled=\"[[item.disabled]]\">\n              [[item.name]]\n            </paper-item>\n          </template>\n        </paper-listbox>\n      </paper-dropdown-menu>\n    </div>\n    <gviz-loader id=\"loader\" packages=\"[[chartPackages_]]\"></gviz-loader>\n    <div id=\"chart\"></div>\n  </template>\n  </dom-module>\n<dom-module id=\"lantern-browser\" assetpath=\"/lantern-browser/\">\n  \n  <template><style>\n#table {\n  display: block;\n  width: calc(100% - 240px);\n  margin: 20px 120px 60px 120px;\n}\n\n.ui {\n  margin: 20px auto 0;\n  /* Two ui-inputs, each 260px (have 10px soft margin) */\n  width: calc(260px * 2);\n}\n\n.ui-input {\n  width: 250px;\n}\n\n.ui-element {\n  display: inline-block;\n  margin-right: 2px;\n}\n\n.placeholder {\n  height: 32px;\n  display: flex;\n}\n\n::content .links {\n  text-transform: none;\n  font-weight: normal;\n  text-decoration: underline;\n  font-size: 13px;\n  color: #337ab7;\n}\n\n</style>\n    <div class=\"section ui\">\n      <span id=\"chart-type\" class=\"ui-element ui-input\">\n        <paper-dropdown-menu label=\"Visualization\">\n          <paper-listbox class=\"dropdown-content\" selected=\"{{chartType}}\">\n            <paper-item>Slices Overview</paper-item>\n            <paper-item>Metrics Histogram</paper-item>\n          </paper-listbox>\n        </paper-dropdown-menu>\n        <div class=\"placeholder\"></div>\n      </span>\n      <span id=\"weighted-examples-threshold\" class=\"ui-element ui-input\">\n        <paper-input-container always-float-label=\"\">\n          <label>Examples (Weighted) Threshold\n            <paper-icon-button suffix=\"\" icon=\"help\" title=\"ignore slices with number of (weighted) examples less than this threshold\"></paper-icon-button>\n          </label>\n          <input value=\"0\" type=\"number\">\n        </paper-input-container>\n        <paper-slider class=\"slider\" min=\"0\" max=\"[[weightedExamplesInfo_.max]]\" step=\"[[weightedExamplesInfo_.step]]\"></paper-slider>\n      </span>\n    </div>\n    <iron-pages selected=\"[[chartType]]\">\n      <slice-overview slices=\"[[filteredData_]]\" metric-to-show=\"[[weightedExamplesColumn]]\">\n      </slice-overview>\n      <div>\n        <metrics-histogram id=\"histogram\" data=\"[[filteredData_]]\" details-data=\"{{focusedData_}}\" weighted-examples-column=\"[[weightedExamplesColumn]]\" selected-features=\"[[selectedFeatures]]\" class=\"vis\"></metrics-histogram>\n      </div>\n    </iron-pages>\n    <metrics-table id=\"table\" data=\"[[metricsTableData_]]\" metrics=\"[[metrics]]\" metric-formats=\"[[metricFormats_]]\" selected=\"[[selectedColumn]]\">\n    </metrics-table>\n  </template>\n  </dom-module>\n</div>\n    <lantern-browser></lantern-browser>\n  \n\n\n<script>\n(function(){function resolve(){document.body.removeAttribute(\"unresolved\")}if(window.WebComponents)addEventListener(\"WebComponentsReady\",resolve);else if(document.readyState===\"interactive\"||document.readyState===\"complete\")resolve();else addEventListener(\"DOMContentLoaded\",resolve)})();\nwindow.Polymer={Settings:function(){var settings=window.Polymer||{};if(!settings.noUrlSettings){var parts=location.search.slice(1).split(\"&\");for(var i=0,o;i<parts.length&&(o=parts[i]);i++){o=o.split(\"=\");o[0]&&(settings[o[0]]=o[1]||true)}}settings.wantShadow=settings.dom===\"shadow\";settings.hasShadow=Boolean(Element.prototype.createShadowRoot);settings.nativeShadow=settings.hasShadow&&!window.ShadowDOMPolyfill;settings.useShadow=settings.wantShadow&&settings.hasShadow;settings.hasNativeImports=Boolean(\"import\"in\ndocument.createElement(\"link\"));settings.useNativeImports=settings.hasNativeImports;settings.useNativeCustomElements=!window.CustomElements||window.CustomElements.useNative;settings.useNativeShadow=settings.useShadow&&settings.nativeShadow;settings.usePolyfillProto=!settings.useNativeCustomElements&&!Object.__proto__;settings.hasNativeCSSProperties=!navigator.userAgent.match(\"AppleWebKit/601\")&&window.CSS&&CSS.supports&&CSS.supports(\"box-shadow\",\"0 0 0 var(--foo)\");settings.useNativeCSSProperties=\nsettings.hasNativeCSSProperties&&settings.lazyRegister&&settings.useNativeCSSProperties;settings.isIE=navigator.userAgent.match(\"Trident\");return settings}()};\n(function(){var userPolymer=window.Polymer;window.Polymer=function(prototype){if(typeof prototype===\"function\")prototype=prototype.prototype;if(!prototype)prototype={};prototype=desugar(prototype);var customCtor=prototype===prototype.constructor.prototype?prototype.constructor:null;var options={prototype:prototype};if(prototype[\"extends\"])options[\"extends\"]=prototype[\"extends\"];Polymer.telemetry._registrate(prototype);var ctor=document.registerElement(prototype.is,options);return customCtor||ctor};\nvar desugar=function(prototype){var base=Polymer.Base;if(prototype[\"extends\"])base=Polymer.Base._getExtendedPrototype(prototype[\"extends\"]);prototype=Polymer.Base.chainObject(prototype,base);prototype.registerCallback();return prototype};if(userPolymer)for(var i in userPolymer)Polymer[i]=userPolymer[i];Polymer.Class=function(prototype){if(!prototype.factoryImpl)prototype.factoryImpl=function(){};return desugar(prototype).constructor}})();\nPolymer.telemetry={registrations:[],_regLog:function(prototype){console.log(\"[\"+prototype.is+\"]: registered\")},_registrate:function(prototype){this.registrations.push(prototype);Polymer.log&&this._regLog(prototype)},dumpRegistrations:function(){this.registrations.forEach(this._regLog)}};Object.defineProperty(window,\"currentImport\",{enumerable:true,configurable:true,get:function(){return(document._currentScript||document.currentScript||{}).ownerDocument}});\nPolymer.RenderStatus={_ready:false,_callbacks:[],whenReady:function(cb){if(this._ready)cb();else this._callbacks.push(cb)},_makeReady:function(){this._ready=true;for(var i=0;i<this._callbacks.length;i++)this._callbacks[i]();this._callbacks=[]},_catchFirstRender:function(){requestAnimationFrame(function(){Polymer.RenderStatus._makeReady()})},_afterNextRenderQueue:[],_waitingNextRender:false,afterNextRender:function(element,fn,args){this._watchNextRender();this._afterNextRenderQueue.push([element,fn,\nargs])},hasRendered:function(){return this._ready},_watchNextRender:function(){if(!this._waitingNextRender){this._waitingNextRender=true;var fn=function(){Polymer.RenderStatus._flushNextRender()};if(!this._ready)this.whenReady(fn);else requestAnimationFrame(fn)}},_flushNextRender:function(){var self=this;setTimeout(function(){self._flushRenderCallbacks(self._afterNextRenderQueue);self._afterNextRenderQueue=[];self._waitingNextRender=false})},_flushRenderCallbacks:function(callbacks){for(var i=0,h;i<\ncallbacks.length;i++){h=callbacks[i];h[1].apply(h[0],h[2]||Polymer.nar)}}};if(window.HTMLImports)HTMLImports.whenReady(function(){Polymer.RenderStatus._catchFirstRender()});else Polymer.RenderStatus._catchFirstRender();Polymer.ImportStatus=Polymer.RenderStatus;Polymer.ImportStatus.whenLoaded=Polymer.ImportStatus.whenReady;\n(function(){var settings=Polymer.Settings;Polymer.Base={__isPolymerInstance__:true,_addFeature:function(feature){this.mixin(this,feature)},registerCallback:function(){if(settings.lazyRegister===\"max\"){if(this.beforeRegister)this.beforeRegister()}else{this._desugarBehaviors();for(var i=0,b;i<this.behaviors.length;i++){b=this.behaviors[i];if(b.beforeRegister)b.beforeRegister.call(this)}if(this.beforeRegister)this.beforeRegister()}this._registerFeatures();if(!settings.lazyRegister)this.ensureRegisterFinished()},\ncreatedCallback:function(){if(settings.disableUpgradeEnabled)if(this.hasAttribute(\"disable-upgrade\")){this._propertySetter=disableUpgradePropertySetter;this.__data__={};return}else this.__hasInitialized=true;this.__initialize()},__initialize:function(){if(!this.__hasRegisterFinished)this._ensureRegisterFinished(this.__proto__);Polymer.telemetry.instanceCount++;this.root=this;for(var i=0,b;i<this.behaviors.length;i++){b=this.behaviors[i];if(b.created)b.created.call(this)}if(this.created)this.created();\nthis._initFeatures()},ensureRegisterFinished:function(){this._ensureRegisterFinished(this)},_ensureRegisterFinished:function(proto){if(proto.__hasRegisterFinished!==proto.is||!proto.is){if(settings.lazyRegister===\"max\"){proto._desugarBehaviors();for(var i=0,b;i<proto.behaviors.length;i++){b=proto.behaviors[i];if(b.beforeRegister)b.beforeRegister.call(proto)}}proto.__hasRegisterFinished=proto.is;if(proto._finishRegisterFeatures)proto._finishRegisterFeatures();for(var j=0,pb;j<proto.behaviors.length;j++){pb=\nproto.behaviors[j];if(pb.registered)pb.registered.call(proto)}if(proto.registered)proto.registered();if(settings.usePolyfillProto&&proto!==this)proto.extend(this,proto)}},attachedCallback:function(){var self=this;Polymer.RenderStatus.whenReady(function(){self.isAttached=true;for(var i=0,b;i<self.behaviors.length;i++){b=self.behaviors[i];if(b.attached)b.attached.call(self)}if(self.attached)self.attached()})},detachedCallback:function(){var self=this;Polymer.RenderStatus.whenReady(function(){self.isAttached=\nfalse;for(var i=0,b;i<self.behaviors.length;i++){b=self.behaviors[i];if(b.detached)b.detached.call(self)}if(self.detached)self.detached()})},attributeChangedCallback:function(name,oldValue,newValue){this._attributeChangedImpl(name);for(var i=0,b;i<this.behaviors.length;i++){b=this.behaviors[i];if(b.attributeChanged)b.attributeChanged.call(this,name,oldValue,newValue)}if(this.attributeChanged)this.attributeChanged(name,oldValue,newValue)},_attributeChangedImpl:function(name){this._setAttributeToProperty(this,\nname)},extend:function(target,source){if(target&&source){var n$=Object.getOwnPropertyNames(source);for(var i=0,n;i<n$.length&&(n=n$[i]);i++)this.copyOwnProperty(n,source,target)}return target||source},mixin:function(target,source){for(var i in source)target[i]=source[i];return target},copyOwnProperty:function(name,source,target){var pd=Object.getOwnPropertyDescriptor(source,name);if(pd)Object.defineProperty(target,name,pd)},_logger:function(level,args){if(args.length===1&&Array.isArray(args[0]))args=\nargs[0];switch(level){case \"log\":case \"warn\":case \"error\":console[level].apply(console,args);break}},_log:function(){var args=Array.prototype.slice.call(arguments,0);this._logger(\"log\",args)},_warn:function(){var args=Array.prototype.slice.call(arguments,0);this._logger(\"warn\",args)},_error:function(){var args=Array.prototype.slice.call(arguments,0);this._logger(\"error\",args)},_logf:function(){return this._logPrefix.concat(this.is).concat(Array.prototype.slice.call(arguments,0))}};Polymer.Base._logPrefix=\nfunction(){var color=window.chrome&&!/edge/i.test(navigator.userAgent)||/firefox/i.test(navigator.userAgent);return color?[\"%c[%s::%s]:\",\"font-weight: bold; background-color:#EEEE00;\"]:[\"[%s::%s]:\"]}();Polymer.Base.chainObject=function(object,inherited){if(object&&inherited&&object!==inherited){if(!Object.__proto__)object=Polymer.Base.extend(Object.create(inherited),object);object.__proto__=inherited}return object};Polymer.Base=Polymer.Base.chainObject(Polymer.Base,HTMLElement.prototype);Polymer.BaseDescriptors=\n{};var disableUpgradePropertySetter;if(settings.disableUpgradeEnabled){disableUpgradePropertySetter=function(property,value){this.__data__[property]=value};var origAttributeChangedCallback=Polymer.Base.attributeChangedCallback;Polymer.Base.attributeChangedCallback=function(name,oldValue,newValue){if(!this.__hasInitialized&&name===\"disable-upgrade\"){this.__hasInitialized=true;this._propertySetter=Polymer.Bind._modelApi._propertySetter;this.__initialize()}origAttributeChangedCallback.call(this,name,\noldValue,newValue)}}if(window.CustomElements)Polymer[\"instanceof\"]=CustomElements[\"instanceof\"];else Polymer[\"instanceof\"]=function(obj,ctor){return obj instanceof ctor};Polymer.isInstance=function(obj){return Boolean(obj&&obj.__isPolymerInstance__)};Polymer.telemetry.instanceCount=0})();\n(function(){var modules={};var lcModules={};var findModule=function(id){return modules[id]||lcModules[id.toLowerCase()]};var DomModule=function(){return document.createElement(\"dom-module\")};DomModule.prototype=Object.create(HTMLElement.prototype);Polymer.Base.mixin(DomModule.prototype,{createdCallback:function(){this.register()},register:function(id){id=id||this.id||this.getAttribute(\"name\")||this.getAttribute(\"is\");if(id){this.id=id;modules[id]=this;lcModules[id.toLowerCase()]=this}},\"import\":function(id,\nselector){if(id){var m=findModule(id);if(!m){forceDomModulesUpgrade();m=findModule(id)}if(m&&selector)m=m.querySelector(selector);return m}}});Object.defineProperty(DomModule.prototype,\"constructor\",{value:DomModule,configurable:true,writable:true});var cePolyfill=window.CustomElements&&!CustomElements.useNative;document.registerElement(\"dom-module\",DomModule);function forceDomModulesUpgrade(){if(cePolyfill){var script=document._currentScript||document.currentScript;var doc=script&&script.ownerDocument||\ndocument;var modules=doc.querySelectorAll(\"dom-module\");for(var i=modules.length-1,m;i>=0&&(m=modules[i]);i--)if(m.__upgraded__)return;else CustomElements.upgrade(m)}}})();Polymer.Base._addFeature({_prepIs:function(){if(!this.is){var module=(document._currentScript||document.currentScript).parentNode;if(module.localName===\"dom-module\"){var id=module.id||module.getAttribute(\"name\")||module.getAttribute(\"is\");this.is=id}}if(this.is)this.is=this.is.toLowerCase()}});\nPolymer.Base._addFeature({behaviors:[],_desugarBehaviors:function(){if(this.behaviors.length)this.behaviors=this._desugarSomeBehaviors(this.behaviors)},_desugarSomeBehaviors:function(behaviors){var behaviorSet=[];behaviors=this._flattenBehaviorsList(behaviors);for(var i=behaviors.length-1;i>=0;i--){var b=behaviors[i];if(behaviorSet.indexOf(b)===-1){this._mixinBehavior(b);behaviorSet.unshift(b)}}return behaviorSet},_flattenBehaviorsList:function(behaviors){var flat=[];for(var i=0;i<behaviors.length;i++){var b=\nbehaviors[i];if(b instanceof Array)flat=flat.concat(this._flattenBehaviorsList(b));else if(b)flat.push(b);else this._warn(this._logf(\"_flattenBehaviorsList\",\"behavior is null, check for missing or 404 import\"))}return flat},_mixinBehavior:function(b){var n$=Object.getOwnPropertyNames(b);var useAssignment=b._noAccessors;for(var i=0,n;i<n$.length&&(n=n$[i]);i++)if(!Polymer.Base._behaviorProperties[n]&&!this.hasOwnProperty(n))if(useAssignment)this[n]=b[n];else this.copyOwnProperty(n,b,this)},_prepBehaviors:function(){this._prepFlattenedBehaviors(this.behaviors)},\n_prepFlattenedBehaviors:function(behaviors){for(var i=0,l=behaviors.length;i<l;i++)this._prepBehavior(behaviors[i]);this._prepBehavior(this)},_marshalBehaviors:function(){for(var i=0;i<this.behaviors.length;i++)this._marshalBehavior(this.behaviors[i]);this._marshalBehavior(this)}});Polymer.Base._behaviorProperties={hostAttributes:true,beforeRegister:true,registered:true,properties:true,observers:true,listeners:true,created:true,attached:true,detached:true,attributeChanged:true,ready:true,_noAccessors:true};\nPolymer.Base._addFeature({_getExtendedPrototype:function(tag){return this._getExtendedNativePrototype(tag)},_nativePrototypes:{},_getExtendedNativePrototype:function(tag){var p=this._nativePrototypes[tag];if(!p){p=Object.create(this.getNativePrototype(tag));var p$=Object.getOwnPropertyNames(Polymer.Base);for(var i=0,n;i<p$.length&&(n=p$[i]);i++)if(!Polymer.BaseDescriptors[n])p[n]=Polymer.Base[n];Object.defineProperties(p,Polymer.BaseDescriptors);this._nativePrototypes[tag]=p}return p},getNativePrototype:function(tag){return Object.getPrototypeOf(document.createElement(tag))}});\nPolymer.Base._addFeature({_prepConstructor:function(){this._factoryArgs=this[\"extends\"]?[this[\"extends\"],this.is]:[this.is];var ctor=function(){return this._factory(arguments)};if(this.hasOwnProperty(\"extends\"))ctor[\"extends\"]=this[\"extends\"];Object.defineProperty(this,\"constructor\",{value:ctor,writable:true,configurable:true});ctor.prototype=this},_factory:function(args){var elt=document.createElement.apply(document,this._factoryArgs);if(this.factoryImpl)this.factoryImpl.apply(elt,args);return elt}});\nPolymer.nob=Object.create(null);\nPolymer.Base._addFeature({getPropertyInfo:function(property){var info=this._getPropertyInfo(property,this.properties);if(!info)for(var i=0;i<this.behaviors.length;i++){info=this._getPropertyInfo(property,this.behaviors[i].properties);if(info)return info}return info||Polymer.nob},_getPropertyInfo:function(property,properties){var p=properties&&properties[property];if(typeof p===\"function\")p=properties[property]={type:p};if(p)p.defined=true;return p},_prepPropertyInfo:function(){this._propertyInfo={};\nfor(var i=0;i<this.behaviors.length;i++)this._addPropertyInfo(this._propertyInfo,this.behaviors[i].properties);this._addPropertyInfo(this._propertyInfo,this.properties);this._addPropertyInfo(this._propertyInfo,this._propertyEffects)},_addPropertyInfo:function(target,source){if(source){var t,s;for(var i in source){t=target[i];s=source[i];if(i[0]===\"_\"&&!s.readOnly)continue;if(!target[i])target[i]={type:typeof s===\"function\"?s:s.type,readOnly:s.readOnly,attribute:Polymer.CaseMap.camelToDashCase(i)};\nelse{if(!t.type)t.type=s.type;if(!t.readOnly)t.readOnly=s.readOnly}}}}});(function(){var propertiesDesc={configurable:true,writable:true,enumerable:true,value:{}};Polymer.BaseDescriptors.properties=propertiesDesc;Object.defineProperty(Polymer.Base,\"properties\",propertiesDesc)})();\nPolymer.CaseMap={_caseMap:{},_rx:{dashToCamel:/-[a-z]/g,camelToDash:/([A-Z])/g},dashToCamelCase:function(dash){return this._caseMap[dash]||(this._caseMap[dash]=dash.indexOf(\"-\")<0?dash:dash.replace(this._rx.dashToCamel,function(m){return m[1].toUpperCase()}))},camelToDashCase:function(camel){return this._caseMap[camel]||(this._caseMap[camel]=camel.replace(this._rx.camelToDash,\"-$1\").toLowerCase())}};\nPolymer.Base._addFeature({_addHostAttributes:function(attributes){if(!this._aggregatedAttributes)this._aggregatedAttributes={};if(attributes)this.mixin(this._aggregatedAttributes,attributes)},_marshalHostAttributes:function(){if(this._aggregatedAttributes)this._applyAttributes(this,this._aggregatedAttributes)},_applyAttributes:function(node,attr$){for(var n in attr$)if(!this.hasAttribute(n)&&n!==\"class\"){var v=attr$[n];this.serializeValueToAttribute(v,n,this)}},_marshalAttributes:function(){this._takeAttributesToModel(this)},\n_takeAttributesToModel:function(model){if(this.hasAttributes())for(var i in this._propertyInfo){var info=this._propertyInfo[i];if(this.hasAttribute(info.attribute))this._setAttributeToProperty(model,info.attribute,i,info)}},_setAttributeToProperty:function(model,attribute,property,info){if(!this._serializing){property=property||Polymer.CaseMap.dashToCamelCase(attribute);info=info||this._propertyInfo&&this._propertyInfo[property];if(info&&!info.readOnly){var v=this.getAttribute(attribute);model[property]=\nthis.deserialize(v,info.type)}}},_serializing:false,reflectPropertyToAttribute:function(property,attribute,value){this._serializing=true;value=value===undefined?this[property]:value;this.serializeValueToAttribute(value,attribute||Polymer.CaseMap.camelToDashCase(property));this._serializing=false},serializeValueToAttribute:function(value,attribute,node){var str=this.serialize(value);node=node||this;if(str===undefined)node.removeAttribute(attribute);else node.setAttribute(attribute,str)},deserialize:function(value,\ntype){switch(type){case Number:value=Number(value);break;case Boolean:value=value!=null;break;case Object:try{value=JSON.parse(value)}catch(x){}break;case Array:try{value=JSON.parse(value)}catch(x$0){value=null;console.warn(\"Polymer::Attributes: couldn`t decode Array as JSON\")}break;case Date:value=new Date(value);break;case String:default:break}return value},serialize:function(value){switch(typeof value){case \"boolean\":return value?\"\":undefined;case \"object\":if(value instanceof Date)return value.toString();\nelse if(value)try{return JSON.stringify(value)}catch(x){return\"\"}default:return value!=null?value:undefined}}});Polymer.version=\"1.8.0\";Polymer.Base._addFeature({_registerFeatures:function(){this._prepIs();this._prepBehaviors();this._prepConstructor();this._prepPropertyInfo()},_prepBehavior:function(b){this._addHostAttributes(b.hostAttributes)},_marshalBehavior:function(b){},_initFeatures:function(){this._marshalHostAttributes();this._marshalBehaviors()}});Polymer.Base._addFeature({_prepTemplate:function(){if(this._template===undefined)this._template=Polymer.DomModule[\"import\"](this.is,\"template\");if(this._template&&this._template.hasAttribute(\"is\"))this._warn(this._logf(\"_prepTemplate\",\"top-level Polymer template \"+\"must not be a type-extension, found\",this._template,\"Move inside simple <template>.\"));if(this._template&&!this._template.content&&window.HTMLTemplateElement&&HTMLTemplateElement.decorate)HTMLTemplateElement.decorate(this._template)},_stampTemplate:function(){if(this._template)this.root=\nthis.instanceTemplate(this._template)},instanceTemplate:function(template){var dom=document.importNode(template._content||template.content,true);return dom}});\n(function(){var baseAttachedCallback=Polymer.Base.attachedCallback;Polymer.Base._addFeature({_hostStack:[],ready:function(){},_registerHost:function(host){this.dataHost=host=host||Polymer.Base._hostStack[Polymer.Base._hostStack.length-1];if(host&&host._clients)host._clients.push(this);this._clients=null;this._clientsReadied=false},_beginHosting:function(){Polymer.Base._hostStack.push(this);if(!this._clients)this._clients=[]},_endHosting:function(){Polymer.Base._hostStack.pop()},_tryReady:function(){this._readied=\nfalse;if(this._canReady())this._ready()},_canReady:function(){return!this.dataHost||this.dataHost._clientsReadied},_ready:function(){this._beforeClientsReady();if(this._template){this._setupRoot();this._readyClients()}this._clientsReadied=true;this._clients=null;this._afterClientsReady();this._readySelf()},_readyClients:function(){this._beginDistribute();var c$=this._clients;if(c$)for(var i=0,l=c$.length,c;i<l&&(c=c$[i]);i++)c._ready();this._finishDistribute()},_readySelf:function(){for(var i=0,b;i<\nthis.behaviors.length;i++){b=this.behaviors[i];if(b.ready)b.ready.call(this)}if(this.ready)this.ready();this._readied=true;if(this._attachedPending){this._attachedPending=false;this.attachedCallback()}},_beforeClientsReady:function(){},_afterClientsReady:function(){},_beforeAttached:function(){},attachedCallback:function(){if(this._readied){this._beforeAttached();baseAttachedCallback.call(this)}else this._attachedPending=true}})})();\nPolymer.ArraySplice=function(){function newSplice(index,removed,addedCount){return{index:index,removed:removed,addedCount:addedCount}}var EDIT_LEAVE=0;var EDIT_UPDATE=1;var EDIT_ADD=2;var EDIT_DELETE=3;function ArraySplice(){}ArraySplice.prototype={calcEditDistances:function(current,currentStart,currentEnd,old,oldStart,oldEnd){var rowCount=oldEnd-oldStart+1;var columnCount=currentEnd-currentStart+1;var distances=new Array(rowCount);for(var i=0;i<rowCount;i++){distances[i]=new Array(columnCount);distances[i][0]=\ni}for(var j=0;j<columnCount;j++)distances[0][j]=j;for(i=1;i<rowCount;i++)for(j=1;j<columnCount;j++)if(this.equals(current[currentStart+j-1],old[oldStart+i-1]))distances[i][j]=distances[i-1][j-1];else{var north=distances[i-1][j]+1;var west=distances[i][j-1]+1;distances[i][j]=north<west?north:west}return distances},spliceOperationsFromEditDistances:function(distances){var i=distances.length-1;var j=distances[0].length-1;var current=distances[i][j];var edits=[];while(i>0||j>0){if(i==0){edits.push(EDIT_ADD);\nj--;continue}if(j==0){edits.push(EDIT_DELETE);i--;continue}var northWest=distances[i-1][j-1];var west=distances[i-1][j];var north=distances[i][j-1];var min;if(west<north)min=west<northWest?west:northWest;else min=north<northWest?north:northWest;if(min==northWest){if(northWest==current)edits.push(EDIT_LEAVE);else{edits.push(EDIT_UPDATE);current=northWest}i--;j--}else if(min==west){edits.push(EDIT_DELETE);i--;current=west}else{edits.push(EDIT_ADD);j--;current=north}}edits.reverse();return edits},calcSplices:function(current,\ncurrentStart,currentEnd,old,oldStart,oldEnd){var prefixCount=0;var suffixCount=0;var minLength=Math.min(currentEnd-currentStart,oldEnd-oldStart);if(currentStart==0&&oldStart==0)prefixCount=this.sharedPrefix(current,old,minLength);if(currentEnd==current.length&&oldEnd==old.length)suffixCount=this.sharedSuffix(current,old,minLength-prefixCount);currentStart+=prefixCount;oldStart+=prefixCount;currentEnd-=suffixCount;oldEnd-=suffixCount;if(currentEnd-currentStart==0&&oldEnd-oldStart==0)return[];if(currentStart==\ncurrentEnd){var splice=newSplice(currentStart,[],0);while(oldStart<oldEnd)splice.removed.push(old[oldStart++]);return[splice]}else if(oldStart==oldEnd)return[newSplice(currentStart,[],currentEnd-currentStart)];var ops=this.spliceOperationsFromEditDistances(this.calcEditDistances(current,currentStart,currentEnd,old,oldStart,oldEnd));splice=undefined;var splices=[];var index=currentStart;var oldIndex=oldStart;for(var i=0;i<ops.length;i++)switch(ops[i]){case EDIT_LEAVE:if(splice){splices.push(splice);\nsplice=undefined}index++;oldIndex++;break;case EDIT_UPDATE:if(!splice)splice=newSplice(index,[],0);splice.addedCount++;index++;splice.removed.push(old[oldIndex]);oldIndex++;break;case EDIT_ADD:if(!splice)splice=newSplice(index,[],0);splice.addedCount++;index++;break;case EDIT_DELETE:if(!splice)splice=newSplice(index,[],0);splice.removed.push(old[oldIndex]);oldIndex++;break}if(splice)splices.push(splice);return splices},sharedPrefix:function(current,old,searchLength){for(var i=0;i<searchLength;i++)if(!this.equals(current[i],\nold[i]))return i;return searchLength},sharedSuffix:function(current,old,searchLength){var index1=current.length;var index2=old.length;var count=0;while(count<searchLength&&this.equals(current[--index1],old[--index2]))count++;return count},calculateSplices:function(current,previous){return this.calcSplices(current,0,current.length,previous,0,previous.length)},equals:function(currentValue,previousValue){return currentValue===previousValue}};return new ArraySplice}();\nPolymer.domInnerHTML=function(){var escapeAttrRegExp=/[&\\u00A0\"]/g;var escapeDataRegExp=/[&\\u00A0<>]/g;function escapeReplace(c){switch(c){case \"&\":return\"&amp;\";case \"<\":return\"&lt;\";case \">\":return\"&gt;\";case '\"':return\"&quot;\";case \"\\u00a0\":return\"&nbsp;\"}}function escapeAttr(s){return s.replace(escapeAttrRegExp,escapeReplace)}function escapeData(s){return s.replace(escapeDataRegExp,escapeReplace)}function makeSet(arr){var set={};for(var i=0;i<arr.length;i++)set[arr[i]]=true;return set}var voidElements=\nmakeSet([\"area\",\"base\",\"br\",\"col\",\"command\",\"embed\",\"hr\",\"img\",\"input\",\"keygen\",\"link\",\"meta\",\"param\",\"source\",\"track\",\"wbr\"]);var plaintextParents=makeSet([\"style\",\"script\",\"xmp\",\"iframe\",\"noembed\",\"noframes\",\"plaintext\",\"noscript\"]);function getOuterHTML(node,parentNode,composed){switch(node.nodeType){case Node.ELEMENT_NODE:var tagName=node.localName;var s=\"<\"+tagName;var attrs=node.attributes;for(var i=0,attr;attr=attrs[i];i++)s+=\" \"+attr.name+'=\"'+escapeAttr(attr.value)+'\"';s+=\">\";if(voidElements[tagName])return s;\nreturn s+getInnerHTML(node,composed)+\"</\"+tagName+\">\";case Node.TEXT_NODE:var data=node.data;if(parentNode&&plaintextParents[parentNode.localName])return data;return escapeData(data);case Node.COMMENT_NODE:return\"\\x3c!--\"+node.data+\"--\\x3e\";default:console.error(node);throw new Error(\"not implemented\");}}function getInnerHTML(node,composed){if(node instanceof HTMLTemplateElement)node=node.content;var s=\"\";var c$=Polymer.dom(node).childNodes;for(var i=0,l=c$.length,child;i<l&&(child=c$[i]);i++)s+=\ngetOuterHTML(child,node,composed);return s}return{getInnerHTML:getInnerHTML}}();\n(function(){var nativeInsertBefore=Element.prototype.insertBefore;var nativeAppendChild=Element.prototype.appendChild;var nativeRemoveChild=Element.prototype.removeChild;Polymer.TreeApi={arrayCopyChildNodes:function(parent){var copy=[],i=0;for(var n=parent.firstChild;n;n=n.nextSibling)copy[i++]=n;return copy},arrayCopyChildren:function(parent){var copy=[],i=0;for(var n=parent.firstElementChild;n;n=n.nextElementSibling)copy[i++]=n;return copy},arrayCopy:function(a$){var l=a$.length;var copy=new Array(l);\nfor(var i=0;i<l;i++)copy[i]=a$[i];return copy}};Polymer.TreeApi.Logical={hasParentNode:function(node){return Boolean(node.__dom&&node.__dom.parentNode)},hasChildNodes:function(node){return Boolean(node.__dom&&node.__dom.childNodes!==undefined)},getChildNodes:function(node){return this.hasChildNodes(node)?this._getChildNodes(node):node.childNodes},_getChildNodes:function(node){if(!node.__dom.childNodes){node.__dom.childNodes=[];for(var n=node.__dom.firstChild;n;n=n.__dom.nextSibling)node.__dom.childNodes.push(n)}return node.__dom.childNodes},\ngetParentNode:function(node){return node.__dom&&node.__dom.parentNode!==undefined?node.__dom.parentNode:node.parentNode},getFirstChild:function(node){return node.__dom&&node.__dom.firstChild!==undefined?node.__dom.firstChild:node.firstChild},getLastChild:function(node){return node.__dom&&node.__dom.lastChild!==undefined?node.__dom.lastChild:node.lastChild},getNextSibling:function(node){return node.__dom&&node.__dom.nextSibling!==undefined?node.__dom.nextSibling:node.nextSibling},getPreviousSibling:function(node){return node.__dom&&\nnode.__dom.previousSibling!==undefined?node.__dom.previousSibling:node.previousSibling},getFirstElementChild:function(node){return node.__dom&&node.__dom.firstChild!==undefined?this._getFirstElementChild(node):node.firstElementChild},_getFirstElementChild:function(node){var n=node.__dom.firstChild;while(n&&n.nodeType!==Node.ELEMENT_NODE)n=n.__dom.nextSibling;return n},getLastElementChild:function(node){return node.__dom&&node.__dom.lastChild!==undefined?this._getLastElementChild(node):node.lastElementChild},\n_getLastElementChild:function(node){var n=node.__dom.lastChild;while(n&&n.nodeType!==Node.ELEMENT_NODE)n=n.__dom.previousSibling;return n},getNextElementSibling:function(node){return node.__dom&&node.__dom.nextSibling!==undefined?this._getNextElementSibling(node):node.nextElementSibling},_getNextElementSibling:function(node){var n=node.__dom.nextSibling;while(n&&n.nodeType!==Node.ELEMENT_NODE)n=n.__dom.nextSibling;return n},getPreviousElementSibling:function(node){return node.__dom&&node.__dom.previousSibling!==\nundefined?this._getPreviousElementSibling(node):node.previousElementSibling},_getPreviousElementSibling:function(node){var n=node.__dom.previousSibling;while(n&&n.nodeType!==Node.ELEMENT_NODE)n=n.__dom.previousSibling;return n},saveChildNodes:function(node){if(!this.hasChildNodes(node)){node.__dom=node.__dom||{};node.__dom.firstChild=node.firstChild;node.__dom.lastChild=node.lastChild;node.__dom.childNodes=[];for(var n=node.firstChild;n;n=n.nextSibling){n.__dom=n.__dom||{};n.__dom.parentNode=node;\nnode.__dom.childNodes.push(n);n.__dom.nextSibling=n.nextSibling;n.__dom.previousSibling=n.previousSibling}}},recordInsertBefore:function(node,container,ref_node){container.__dom.childNodes=null;if(node.nodeType===Node.DOCUMENT_FRAGMENT_NODE)for(var n=node.firstChild;n;n=n.nextSibling)this._linkNode(n,container,ref_node);else this._linkNode(node,container,ref_node)},_linkNode:function(node,container,ref_node){node.__dom=node.__dom||{};container.__dom=container.__dom||{};if(ref_node)ref_node.__dom=\nref_node.__dom||{};node.__dom.previousSibling=ref_node?ref_node.__dom.previousSibling:container.__dom.lastChild;if(node.__dom.previousSibling)node.__dom.previousSibling.__dom.nextSibling=node;node.__dom.nextSibling=ref_node||null;if(node.__dom.nextSibling)node.__dom.nextSibling.__dom.previousSibling=node;node.__dom.parentNode=container;if(ref_node){if(ref_node===container.__dom.firstChild)container.__dom.firstChild=node}else{container.__dom.lastChild=node;if(!container.__dom.firstChild)container.__dom.firstChild=\nnode}container.__dom.childNodes=null},recordRemoveChild:function(node,container){node.__dom=node.__dom||{};container.__dom=container.__dom||{};if(node===container.__dom.firstChild)container.__dom.firstChild=node.__dom.nextSibling;if(node===container.__dom.lastChild)container.__dom.lastChild=node.__dom.previousSibling;var p=node.__dom.previousSibling;var n=node.__dom.nextSibling;if(p)p.__dom.nextSibling=n;if(n)n.__dom.previousSibling=p;node.__dom.parentNode=node.__dom.previousSibling=node.__dom.nextSibling=\nundefined;container.__dom.childNodes=null}};Polymer.TreeApi.Composed={getChildNodes:function(node){return Polymer.TreeApi.arrayCopyChildNodes(node)},getParentNode:function(node){return node.parentNode},clearChildNodes:function(node){node.textContent=\"\"},insertBefore:function(parentNode,newChild,refChild){return nativeInsertBefore.call(parentNode,newChild,refChild||null)},appendChild:function(parentNode,newChild){return nativeAppendChild.call(parentNode,newChild)},removeChild:function(parentNode,node){return nativeRemoveChild.call(parentNode,\nnode)}}})();\nPolymer.DomApi=function(){var Settings=Polymer.Settings;var TreeApi=Polymer.TreeApi;var DomApi=function(node){this.node=needsToWrap?DomApi.wrap(node):node};var needsToWrap=Settings.hasShadow&&!Settings.nativeShadow;DomApi.wrap=window.wrap?window.wrap:function(node){return node};DomApi.prototype={flush:function(){Polymer.dom.flush()},deepContains:function(node){if(this.node.contains(node))return true;var n=node;var doc=node.ownerDocument;while(n&&n!==doc&&n!==this.node)n=Polymer.dom(n).parentNode||n.host;\nreturn n===this.node},queryDistributedElements:function(selector){var c$=this.getEffectiveChildNodes();var list=[];for(var i=0,l=c$.length,c;i<l&&(c=c$[i]);i++)if(c.nodeType===Node.ELEMENT_NODE&&DomApi.matchesSelector.call(c,selector))list.push(c);return list},getEffectiveChildNodes:function(){var list=[];var c$=this.childNodes;for(var i=0,l=c$.length,c;i<l&&(c=c$[i]);i++)if(c.localName===CONTENT){var d$=dom(c).getDistributedNodes();for(var j=0;j<d$.length;j++)list.push(d$[j])}else list.push(c);return list},\nobserveNodes:function(callback){if(callback){if(!this.observer)this.observer=this.node.localName===CONTENT?new DomApi.DistributedNodesObserver(this):new DomApi.EffectiveNodesObserver(this);return this.observer.addListener(callback)}},unobserveNodes:function(handle){if(this.observer)this.observer.removeListener(handle)},notifyObserver:function(){if(this.observer)this.observer.notify()},_query:function(matcher,node,halter){node=node||this.node;var list=[];this._queryElements(TreeApi.Logical.getChildNodes(node),\nmatcher,halter,list);return list},_queryElements:function(elements,matcher,halter,list){for(var i=0,l=elements.length,c;i<l&&(c=elements[i]);i++)if(c.nodeType===Node.ELEMENT_NODE)if(this._queryElement(c,matcher,halter,list))return true},_queryElement:function(node,matcher,halter,list){var result=matcher(node);if(result)list.push(node);if(halter&&halter(result))return result;this._queryElements(TreeApi.Logical.getChildNodes(node),matcher,halter,list)}};var CONTENT=DomApi.CONTENT=\"content\";var dom=\nDomApi.factory=function(node){node=node||document;if(!node.__domApi)node.__domApi=new DomApi.ctor(node);return node.__domApi};DomApi.hasApi=function(node){return Boolean(node.__domApi)};DomApi.ctor=DomApi;Polymer.dom=function(obj,patch){if(obj instanceof Event)return Polymer.EventApi.factory(obj);else return DomApi.factory(obj,patch)};var p=Element.prototype;DomApi.matchesSelector=p.matches||p.matchesSelector||p.mozMatchesSelector||p.msMatchesSelector||p.oMatchesSelector||p.webkitMatchesSelector;\nreturn DomApi}();\n(function(){var Settings=Polymer.Settings;var DomApi=Polymer.DomApi;var dom=DomApi.factory;var TreeApi=Polymer.TreeApi;var getInnerHTML=Polymer.domInnerHTML.getInnerHTML;var CONTENT=DomApi.CONTENT;if(Settings.useShadow)return;var nativeCloneNode=Element.prototype.cloneNode;var nativeImportNode=Document.prototype.importNode;Polymer.Base.mixin(DomApi.prototype,{_lazyDistribute:function(host){if(host.shadyRoot&&host.shadyRoot._distributionClean){host.shadyRoot._distributionClean=false;Polymer.dom.addDebouncer(host.debounce(\"_distribute\",\nhost._distributeContent))}},appendChild:function(node){return this.insertBefore(node)},insertBefore:function(node,ref_node){if(ref_node&&TreeApi.Logical.getParentNode(ref_node)!==this.node)throw Error(\"The ref_node to be inserted before is not a child \"+\"of this node\");if(node.nodeType!==Node.DOCUMENT_FRAGMENT_NODE){var parent=TreeApi.Logical.getParentNode(node);if(parent){if(DomApi.hasApi(parent))dom(parent).notifyObserver();this._removeNode(node)}else this._removeOwnerShadyRoot(node)}if(!this._addNode(node,\nref_node)){if(ref_node)ref_node=ref_node.localName===CONTENT?this._firstComposedNode(ref_node):ref_node;var container=this.node._isShadyRoot?this.node.host:this.node;if(ref_node)TreeApi.Composed.insertBefore(container,node,ref_node);else TreeApi.Composed.appendChild(container,node)}this.notifyObserver();return node},_addNode:function(node,ref_node){var root=this.getOwnerRoot();if(root){var ipAdded=this._maybeAddInsertionPoint(node,this.node);if(!root._invalidInsertionPoints)root._invalidInsertionPoints=\nipAdded;this._addNodeToHost(root.host,node)}if(TreeApi.Logical.hasChildNodes(this.node))TreeApi.Logical.recordInsertBefore(node,this.node,ref_node);var handled=this._maybeDistribute(node)||this.node.shadyRoot;if(handled)if(node.nodeType===Node.DOCUMENT_FRAGMENT_NODE)while(node.firstChild)TreeApi.Composed.removeChild(node,node.firstChild);else{var parent=TreeApi.Composed.getParentNode(node);if(parent)TreeApi.Composed.removeChild(parent,node)}return handled},removeChild:function(node){if(TreeApi.Logical.getParentNode(node)!==\nthis.node)throw Error(\"The node to be removed is not a child of this node: \"+node);if(!this._removeNode(node)){var container=this.node._isShadyRoot?this.node.host:this.node;var parent=TreeApi.Composed.getParentNode(node);if(container===parent)TreeApi.Composed.removeChild(container,node)}this.notifyObserver();return node},_removeNode:function(node){var logicalParent=TreeApi.Logical.hasParentNode(node)&&TreeApi.Logical.getParentNode(node);var distributed;var root=this._ownerShadyRootForNode(node);if(logicalParent){distributed=\ndom(node)._maybeDistributeParent();TreeApi.Logical.recordRemoveChild(node,logicalParent);if(root&&this._removeDistributedChildren(root,node)){root._invalidInsertionPoints=true;this._lazyDistribute(root.host)}}this._removeOwnerShadyRoot(node);if(root)this._removeNodeFromHost(root.host,node);return distributed},replaceChild:function(node,ref_node){this.insertBefore(node,ref_node);this.removeChild(ref_node);return node},_hasCachedOwnerRoot:function(node){return Boolean(node._ownerShadyRoot!==undefined)},\ngetOwnerRoot:function(){return this._ownerShadyRootForNode(this.node)},_ownerShadyRootForNode:function(node){if(!node)return;var root=node._ownerShadyRoot;if(root===undefined){if(node._isShadyRoot)root=node;else{var parent=TreeApi.Logical.getParentNode(node);if(parent)root=parent._isShadyRoot?parent:this._ownerShadyRootForNode(parent);else root=null}if(root||document.documentElement.contains(node))node._ownerShadyRoot=root}return root},_maybeDistribute:function(node){var fragContent=node.nodeType===\nNode.DOCUMENT_FRAGMENT_NODE&&!node.__noContent&&dom(node).querySelector(CONTENT);var wrappedContent=fragContent&&TreeApi.Logical.getParentNode(fragContent).nodeType!==Node.DOCUMENT_FRAGMENT_NODE;var hasContent=fragContent||node.localName===CONTENT;if(hasContent){var root=this.getOwnerRoot();if(root)this._lazyDistribute(root.host)}var needsDist=this._nodeNeedsDistribution(this.node);if(needsDist)this._lazyDistribute(this.node);return needsDist||hasContent&&!wrappedContent},_maybeAddInsertionPoint:function(node,\nparent){var added;if(node.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&!node.__noContent){var c$=dom(node).querySelectorAll(CONTENT);for(var i=0,n,np,na;i<c$.length&&(n=c$[i]);i++){np=TreeApi.Logical.getParentNode(n);if(np===node)np=parent;na=this._maybeAddInsertionPoint(n,np);added=added||na}}else if(node.localName===CONTENT){TreeApi.Logical.saveChildNodes(parent);TreeApi.Logical.saveChildNodes(node);added=true}return added},_updateInsertionPoints:function(host){var i$=host.shadyRoot._insertionPoints=\ndom(host.shadyRoot).querySelectorAll(CONTENT);for(var i=0,c;i<i$.length;i++){c=i$[i];TreeApi.Logical.saveChildNodes(c);TreeApi.Logical.saveChildNodes(TreeApi.Logical.getParentNode(c))}},_nodeNeedsDistribution:function(node){return node&&node.shadyRoot&&DomApi.hasInsertionPoint(node.shadyRoot)},_addNodeToHost:function(host,node){if(host._elementAdd)host._elementAdd(node)},_removeNodeFromHost:function(host,node){if(host._elementRemove)host._elementRemove(node)},_removeDistributedChildren:function(root,\ncontainer){var hostNeedsDist;var ip$=root._insertionPoints;for(var i=0;i<ip$.length;i++){var content=ip$[i];if(this._contains(container,content)){var dc$=dom(content).getDistributedNodes();for(var j=0;j<dc$.length;j++){hostNeedsDist=true;var node=dc$[j];var parent=TreeApi.Composed.getParentNode(node);if(parent)TreeApi.Composed.removeChild(parent,node)}}}return hostNeedsDist},_contains:function(container,node){while(node){if(node==container)return true;node=TreeApi.Logical.getParentNode(node)}},_removeOwnerShadyRoot:function(node){if(this._hasCachedOwnerRoot(node)){var c$=\nTreeApi.Logical.getChildNodes(node);for(var i=0,l=c$.length,n;i<l&&(n=c$[i]);i++)this._removeOwnerShadyRoot(n)}node._ownerShadyRoot=undefined},_firstComposedNode:function(content){var n$=dom(content).getDistributedNodes();for(var i=0,l=n$.length,n,p$;i<l&&(n=n$[i]);i++){p$=dom(n).getDestinationInsertionPoints();if(p$[p$.length-1]===content)return n}},querySelector:function(selector){var result=this._query(function(n){return DomApi.matchesSelector.call(n,selector)},this.node,function(n){return Boolean(n)})[0];\nreturn result||null},querySelectorAll:function(selector){return this._query(function(n){return DomApi.matchesSelector.call(n,selector)},this.node)},getDestinationInsertionPoints:function(){return this.node._destinationInsertionPoints||[]},getDistributedNodes:function(){return this.node._distributedNodes||[]},_clear:function(){while(this.childNodes.length)this.removeChild(this.childNodes[0])},setAttribute:function(name,value){this.node.setAttribute(name,value);this._maybeDistributeParent()},removeAttribute:function(name){this.node.removeAttribute(name);\nthis._maybeDistributeParent()},_maybeDistributeParent:function(){if(this._nodeNeedsDistribution(this.parentNode)){this._lazyDistribute(this.parentNode);return true}},cloneNode:function(deep){var n=nativeCloneNode.call(this.node,false);if(deep){var c$=this.childNodes;var d=dom(n);for(var i=0,nc;i<c$.length;i++){nc=dom(c$[i]).cloneNode(true);d.appendChild(nc)}}return n},importNode:function(externalNode,deep){var doc=this.node instanceof Document?this.node:this.node.ownerDocument;var n=nativeImportNode.call(doc,\nexternalNode,false);if(deep){var c$=TreeApi.Logical.getChildNodes(externalNode);var d=dom(n);for(var i=0,nc;i<c$.length;i++){nc=dom(doc).importNode(c$[i],true);d.appendChild(nc)}}return n},_getComposedInnerHTML:function(){return getInnerHTML(this.node,true)}});Object.defineProperties(DomApi.prototype,{activeElement:{get:function(){var active=document.activeElement;if(!active)return null;var isShadyRoot=!!this.node._isShadyRoot;if(this.node!==document){if(!isShadyRoot)return null;if(this.node.host===\nactive||!this.node.host.contains(active))return null}var activeRoot=dom(active).getOwnerRoot();while(activeRoot&&activeRoot!==this.node){active=activeRoot.host;activeRoot=dom(active).getOwnerRoot()}if(this.node===document)return activeRoot?null:active;else return activeRoot===this.node?active:null},configurable:true},childNodes:{get:function(){var c$=TreeApi.Logical.getChildNodes(this.node);return Array.isArray(c$)?c$:TreeApi.arrayCopyChildNodes(this.node)},configurable:true},children:{get:function(){if(TreeApi.Logical.hasChildNodes(this.node))return Array.prototype.filter.call(this.childNodes,\nfunction(n){return n.nodeType===Node.ELEMENT_NODE});else return TreeApi.arrayCopyChildren(this.node)},configurable:true},parentNode:{get:function(){return TreeApi.Logical.getParentNode(this.node)},configurable:true},firstChild:{get:function(){return TreeApi.Logical.getFirstChild(this.node)},configurable:true},lastChild:{get:function(){return TreeApi.Logical.getLastChild(this.node)},configurable:true},nextSibling:{get:function(){return TreeApi.Logical.getNextSibling(this.node)},configurable:true},\npreviousSibling:{get:function(){return TreeApi.Logical.getPreviousSibling(this.node)},configurable:true},firstElementChild:{get:function(){return TreeApi.Logical.getFirstElementChild(this.node)},configurable:true},lastElementChild:{get:function(){return TreeApi.Logical.getLastElementChild(this.node)},configurable:true},nextElementSibling:{get:function(){return TreeApi.Logical.getNextElementSibling(this.node)},configurable:true},previousElementSibling:{get:function(){return TreeApi.Logical.getPreviousElementSibling(this.node)},\nconfigurable:true},textContent:{get:function(){var nt=this.node.nodeType;if(nt===Node.TEXT_NODE||nt===Node.COMMENT_NODE)return this.node.textContent;else{var tc=[];for(var i=0,cn=this.childNodes,c;c=cn[i];i++)if(c.nodeType!==Node.COMMENT_NODE)tc.push(c.textContent);return tc.join(\"\")}},set:function(text){var nt=this.node.nodeType;if(nt===Node.TEXT_NODE||nt===Node.COMMENT_NODE)this.node.textContent=text;else{this._clear();if(text)this.appendChild(document.createTextNode(text))}},configurable:true},\ninnerHTML:{get:function(){var nt=this.node.nodeType;if(nt===Node.TEXT_NODE||nt===Node.COMMENT_NODE)return null;else return getInnerHTML(this.node)},set:function(text){var nt=this.node.nodeType;if(nt!==Node.TEXT_NODE||nt!==Node.COMMENT_NODE){this._clear();var d=document.createElement(\"div\");d.innerHTML=text;var c$=TreeApi.arrayCopyChildNodes(d);for(var i=0;i<c$.length;i++)this.appendChild(c$[i])}},configurable:true}});DomApi.hasInsertionPoint=function(root){return Boolean(root&&root._insertionPoints.length)}})();\n(function(){var Settings=Polymer.Settings;var TreeApi=Polymer.TreeApi;var DomApi=Polymer.DomApi;if(!Settings.useShadow)return;Polymer.Base.mixin(DomApi.prototype,{querySelectorAll:function(selector){return TreeApi.arrayCopy(this.node.querySelectorAll(selector))},getOwnerRoot:function(){var n=this.node;while(n){if(n.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&n.host)return n;n=n.parentNode}},importNode:function(externalNode,deep){var doc=this.node instanceof Document?this.node:this.node.ownerDocument;\nreturn doc.importNode(externalNode,deep)},getDestinationInsertionPoints:function(){var n$=this.node.getDestinationInsertionPoints&&this.node.getDestinationInsertionPoints();return n$?TreeApi.arrayCopy(n$):[]},getDistributedNodes:function(){var n$=this.node.getDistributedNodes&&this.node.getDistributedNodes();return n$?TreeApi.arrayCopy(n$):[]}});Object.defineProperties(DomApi.prototype,{activeElement:{get:function(){var node=DomApi.wrap(this.node);var activeElement=node.activeElement;return node.contains(activeElement)?\nactiveElement:null},configurable:true},childNodes:{get:function(){return TreeApi.arrayCopyChildNodes(this.node)},configurable:true},children:{get:function(){return TreeApi.arrayCopyChildren(this.node)},configurable:true},textContent:{get:function(){return this.node.textContent},set:function(value){return this.node.textContent=value},configurable:true},innerHTML:{get:function(){return this.node.innerHTML},set:function(value){return this.node.innerHTML=value},configurable:true}});var forwardMethods=\nfunction(m$){for(var i=0;i<m$.length;i++)forwardMethod(m$[i])};var forwardMethod=function(method){DomApi.prototype[method]=function(){return this.node[method].apply(this.node,arguments)}};forwardMethods([\"cloneNode\",\"appendChild\",\"insertBefore\",\"removeChild\",\"replaceChild\",\"setAttribute\",\"removeAttribute\",\"querySelector\"]);var forwardProperties=function(f$){for(var i=0;i<f$.length;i++)forwardProperty(f$[i])};var forwardProperty=function(name){Object.defineProperty(DomApi.prototype,name,{get:function(){return this.node[name]},\nconfigurable:true})};forwardProperties([\"parentNode\",\"firstChild\",\"lastChild\",\"nextSibling\",\"previousSibling\",\"firstElementChild\",\"lastElementChild\",\"nextElementSibling\",\"previousElementSibling\"])})();\nPolymer.Base.mixin(Polymer.dom,{_flushGuard:0,_FLUSH_MAX:100,_needsTakeRecords:!Polymer.Settings.useNativeCustomElements,_debouncers:[],_staticFlushList:[],_finishDebouncer:null,flush:function(){this._flushGuard=0;this._prepareFlush();while(this._debouncers.length&&this._flushGuard<this._FLUSH_MAX){while(this._debouncers.length)this._debouncers.shift().complete();if(this._finishDebouncer)this._finishDebouncer.complete();this._prepareFlush();this._flushGuard++}if(this._flushGuard>=this._FLUSH_MAX)console.warn(\"Polymer.dom.flush aborted. Flush may not be complete.\")},\n_prepareFlush:function(){if(this._needsTakeRecords)CustomElements.takeRecords();for(var i=0;i<this._staticFlushList.length;i++)this._staticFlushList[i]()},addStaticFlush:function(fn){this._staticFlushList.push(fn)},removeStaticFlush:function(fn){var i=this._staticFlushList.indexOf(fn);if(i>=0)this._staticFlushList.splice(i,1)},addDebouncer:function(debouncer){this._debouncers.push(debouncer);this._finishDebouncer=Polymer.Debounce(this._finishDebouncer,this._finishFlush)},_finishFlush:function(){Polymer.dom._debouncers=\n[]}});\nPolymer.EventApi=function(){var DomApi=Polymer.DomApi.ctor;var Settings=Polymer.Settings;DomApi.Event=function(event){this.event=event};if(Settings.useShadow)DomApi.Event.prototype={get rootTarget(){return this.event.path[0]},get localTarget(){return this.event.target},get path(){var path=this.event.path;if(!Array.isArray(path))path=Array.prototype.slice.call(path);return path}};else DomApi.Event.prototype={get rootTarget(){return this.event.target},get localTarget(){var current=this.event.currentTarget;var currentRoot=\ncurrent&&Polymer.dom(current).getOwnerRoot();var p$=this.path;for(var i=0;i<p$.length;i++)if(Polymer.dom(p$[i]).getOwnerRoot()===currentRoot)return p$[i]},get path(){if(!this.event._path){var path=[];var current=this.rootTarget;while(current){path.push(current);var insertionPoints=Polymer.dom(current).getDestinationInsertionPoints();if(insertionPoints.length){for(var i=0;i<insertionPoints.length-1;i++)path.push(insertionPoints[i]);current=insertionPoints[insertionPoints.length-1]}else current=Polymer.dom(current).parentNode||\ncurrent.host}path.push(window);this.event._path=path}return this.event._path}};var factory=function(event){if(!event.__eventApi)event.__eventApi=new DomApi.Event(event);return event.__eventApi};return{factory:factory}}();\n(function(){var DomApi=Polymer.DomApi.ctor;var useShadow=Polymer.Settings.useShadow;Object.defineProperty(DomApi.prototype,\"classList\",{get:function(){if(!this._classList)this._classList=new DomApi.ClassList(this);return this._classList},configurable:true});DomApi.ClassList=function(host){this.domApi=host;this.node=host.node};DomApi.ClassList.prototype={add:function(){this.node.classList.add.apply(this.node.classList,arguments);this._distributeParent()},remove:function(){this.node.classList.remove.apply(this.node.classList,\narguments);this._distributeParent()},toggle:function(){this.node.classList.toggle.apply(this.node.classList,arguments);this._distributeParent()},_distributeParent:function(){if(!useShadow)this.domApi._maybeDistributeParent()},contains:function(){return this.node.classList.contains.apply(this.node.classList,arguments)}}})();\n(function(){var DomApi=Polymer.DomApi.ctor;var Settings=Polymer.Settings;DomApi.EffectiveNodesObserver=function(domApi){this.domApi=domApi;this.node=this.domApi.node;this._listeners=[]};DomApi.EffectiveNodesObserver.prototype={addListener:function(callback){if(!this._isSetup){this._setup();this._isSetup=true}var listener={fn:callback,_nodes:[]};this._listeners.push(listener);this._scheduleNotify();return listener},removeListener:function(handle){var i=this._listeners.indexOf(handle);if(i>=0){this._listeners.splice(i,\n1);handle._nodes=[]}if(!this._hasListeners()){this._cleanup();this._isSetup=false}},_setup:function(){this._observeContentElements(this.domApi.childNodes)},_cleanup:function(){this._unobserveContentElements(this.domApi.childNodes)},_hasListeners:function(){return Boolean(this._listeners.length)},_scheduleNotify:function(){if(this._debouncer)this._debouncer.stop();this._debouncer=Polymer.Debounce(this._debouncer,this._notify);this._debouncer.context=this;Polymer.dom.addDebouncer(this._debouncer)},\nnotify:function(){if(this._hasListeners())this._scheduleNotify()},_notify:function(){this._beforeCallListeners();this._callListeners()},_beforeCallListeners:function(){this._updateContentElements()},_updateContentElements:function(){this._observeContentElements(this.domApi.childNodes)},_observeContentElements:function(elements){for(var i=0,n;i<elements.length&&(n=elements[i]);i++)if(this._isContent(n)){n.__observeNodesMap=n.__observeNodesMap||new WeakMap;if(!n.__observeNodesMap.has(this))n.__observeNodesMap.set(this,\nthis._observeContent(n))}},_observeContent:function(content){var self=this;var h=Polymer.dom(content).observeNodes(function(){self._scheduleNotify()});h._avoidChangeCalculation=true;return h},_unobserveContentElements:function(elements){for(var i=0,n,h;i<elements.length&&(n=elements[i]);i++)if(this._isContent(n)){h=n.__observeNodesMap.get(this);if(h){Polymer.dom(n).unobserveNodes(h);n.__observeNodesMap[\"delete\"](this)}}},_isContent:function(node){return node.localName===\"content\"},_callListeners:function(){var o$=\nthis._listeners;var nodes=this._getEffectiveNodes();for(var i=0,o;i<o$.length&&(o=o$[i]);i++){var info=this._generateListenerInfo(o,nodes);if(info||o._alwaysNotify)this._callListener(o,info)}},_getEffectiveNodes:function(){return this.domApi.getEffectiveChildNodes()},_generateListenerInfo:function(listener,newNodes){if(listener._avoidChangeCalculation)return true;var oldNodes=listener._nodes;var info={target:this.node,addedNodes:[],removedNodes:[]};var splices=Polymer.ArraySplice.calculateSplices(newNodes,\noldNodes);for(var i=0,s;i<splices.length&&(s=splices[i]);i++)for(var j=0,n;j<s.removed.length&&(n=s.removed[j]);j++)info.removedNodes.push(n);for(i=0,s;i<splices.length&&(s=splices[i]);i++)for(j=s.index;j<s.index+s.addedCount;j++)info.addedNodes.push(newNodes[j]);listener._nodes=newNodes;if(info.addedNodes.length||info.removedNodes.length)return info},_callListener:function(listener,info){return listener.fn.call(this.node,info)},enableShadowAttributeTracking:function(){}};if(Settings.useShadow){var baseSetup=\nDomApi.EffectiveNodesObserver.prototype._setup;var baseCleanup=DomApi.EffectiveNodesObserver.prototype._cleanup;Polymer.Base.mixin(DomApi.EffectiveNodesObserver.prototype,{_setup:function(){if(!this._observer){var self=this;this._mutationHandler=function(mxns){if(mxns&&mxns.length)self._scheduleNotify()};this._observer=new MutationObserver(this._mutationHandler);this._boundFlush=function(){self._flush()};Polymer.dom.addStaticFlush(this._boundFlush);this._observer.observe(this.node,{childList:true})}baseSetup.call(this)},\n_cleanup:function(){this._observer.disconnect();this._observer=null;this._mutationHandler=null;Polymer.dom.removeStaticFlush(this._boundFlush);baseCleanup.call(this)},_flush:function(){if(this._observer)this._mutationHandler(this._observer.takeRecords())},enableShadowAttributeTracking:function(){if(this._observer){this._makeContentListenersAlwaysNotify();this._observer.disconnect();this._observer.observe(this.node,{childList:true,attributes:true,subtree:true});var root=this.domApi.getOwnerRoot();\nvar host=root&&root.host;if(host&&Polymer.dom(host).observer)Polymer.dom(host).observer.enableShadowAttributeTracking()}},_makeContentListenersAlwaysNotify:function(){for(var i=0,h;i<this._listeners.length;i++){h=this._listeners[i];h._alwaysNotify=h._isContentListener}}})}})();\n(function(){var DomApi=Polymer.DomApi.ctor;var Settings=Polymer.Settings;DomApi.DistributedNodesObserver=function(domApi){DomApi.EffectiveNodesObserver.call(this,domApi)};DomApi.DistributedNodesObserver.prototype=Object.create(DomApi.EffectiveNodesObserver.prototype);Polymer.Base.mixin(DomApi.DistributedNodesObserver.prototype,{_setup:function(){},_cleanup:function(){},_beforeCallListeners:function(){},_getEffectiveNodes:function(){return this.domApi.getDistributedNodes()}});if(Settings.useShadow)Polymer.Base.mixin(DomApi.DistributedNodesObserver.prototype,\n{_setup:function(){if(!this._observer){var root=this.domApi.getOwnerRoot();var host=root&&root.host;if(host){var self=this;this._observer=Polymer.dom(host).observeNodes(function(){self._scheduleNotify()});this._observer._isContentListener=true;if(this._hasAttrSelect())Polymer.dom(host).observer.enableShadowAttributeTracking()}}},_hasAttrSelect:function(){var select=this.node.getAttribute(\"select\");return select&&select.match(/[[.]+/)},_cleanup:function(){var root=this.domApi.getOwnerRoot();var host=\nroot&&root.host;if(host)Polymer.dom(host).unobserveNodes(this._observer);this._observer=null}})})();\n(function(){var DomApi=Polymer.DomApi;var TreeApi=Polymer.TreeApi;Polymer.Base._addFeature({_prepShady:function(){this._useContent=this._useContent||Boolean(this._template)},_setupShady:function(){this.shadyRoot=null;if(!this.__domApi)this.__domApi=null;if(!this.__dom)this.__dom=null;if(!this._ownerShadyRoot)this._ownerShadyRoot=undefined},_poolContent:function(){if(this._useContent)TreeApi.Logical.saveChildNodes(this)},_setupRoot:function(){if(this._useContent){this._createLocalRoot();if(!this.dataHost)upgradeLogicalChildren(TreeApi.Logical.getChildNodes(this))}},\n_createLocalRoot:function(){this.shadyRoot=this.root;this.shadyRoot._distributionClean=false;this.shadyRoot._hasDistributed=false;this.shadyRoot._isShadyRoot=true;this.shadyRoot._dirtyRoots=[];var i$=this.shadyRoot._insertionPoints=!this._notes||this._notes._hasContent?this.shadyRoot.querySelectorAll(\"content\"):[];TreeApi.Logical.saveChildNodes(this.shadyRoot);for(var i=0,c;i<i$.length;i++){c=i$[i];TreeApi.Logical.saveChildNodes(c);TreeApi.Logical.saveChildNodes(c.parentNode)}this.shadyRoot.host=\nthis},distributeContent:function(updateInsertionPoints){if(this.shadyRoot){this.shadyRoot._invalidInsertionPoints=this.shadyRoot._invalidInsertionPoints||updateInsertionPoints;var host=getTopDistributingHost(this);Polymer.dom(this)._lazyDistribute(host)}},_distributeContent:function(){if(this._useContent&&!this.shadyRoot._distributionClean){if(this.shadyRoot._invalidInsertionPoints){Polymer.dom(this)._updateInsertionPoints(this);this.shadyRoot._invalidInsertionPoints=false}this._beginDistribute();\nthis._distributeDirtyRoots();this._finishDistribute()}},_beginDistribute:function(){if(this._useContent&&DomApi.hasInsertionPoint(this.shadyRoot)){this._resetDistribution();this._distributePool(this.shadyRoot,this._collectPool())}},_distributeDirtyRoots:function(){var c$=this.shadyRoot._dirtyRoots;for(var i=0,l=c$.length,c;i<l&&(c=c$[i]);i++)c._distributeContent();this.shadyRoot._dirtyRoots=[]},_finishDistribute:function(){if(this._useContent){this.shadyRoot._distributionClean=true;if(DomApi.hasInsertionPoint(this.shadyRoot)){this._composeTree();\nnotifyContentObservers(this.shadyRoot)}else if(!this.shadyRoot._hasDistributed){TreeApi.Composed.clearChildNodes(this);this.appendChild(this.shadyRoot)}else{var children=this._composeNode(this);this._updateChildNodes(this,children)}if(!this.shadyRoot._hasDistributed)notifyInitialDistribution(this);this.shadyRoot._hasDistributed=true}},elementMatches:function(selector,node){node=node||this;return DomApi.matchesSelector.call(node,selector)},_resetDistribution:function(){var children=TreeApi.Logical.getChildNodes(this);\nfor(var i=0;i<children.length;i++){var child=children[i];if(child._destinationInsertionPoints)child._destinationInsertionPoints=undefined;if(isInsertionPoint(child))clearDistributedDestinationInsertionPoints(child)}var root=this.shadyRoot;var p$=root._insertionPoints;for(var j=0;j<p$.length;j++)p$[j]._distributedNodes=[]},_collectPool:function(){var pool=[];var children=TreeApi.Logical.getChildNodes(this);for(var i=0;i<children.length;i++){var child=children[i];if(isInsertionPoint(child))pool.push.apply(pool,\nchild._distributedNodes);else pool.push(child)}return pool},_distributePool:function(node,pool){var p$=node._insertionPoints;for(var i=0,l=p$.length,p;i<l&&(p=p$[i]);i++){this._distributeInsertionPoint(p,pool);maybeRedistributeParent(p,this)}},_distributeInsertionPoint:function(content,pool){var anyDistributed=false;for(var i=0,l=pool.length,node;i<l;i++){node=pool[i];if(!node)continue;if(this._matchesContentSelect(node,content)){distributeNodeInto(node,content);pool[i]=undefined;anyDistributed=true}}if(!anyDistributed){var children=\nTreeApi.Logical.getChildNodes(content);for(var j=0;j<children.length;j++)distributeNodeInto(children[j],content)}},_composeTree:function(){this._updateChildNodes(this,this._composeNode(this));var p$=this.shadyRoot._insertionPoints;for(var i=0,l=p$.length,p,parent;i<l&&(p=p$[i]);i++){parent=TreeApi.Logical.getParentNode(p);if(!parent._useContent&&parent!==this&&parent!==this.shadyRoot)this._updateChildNodes(parent,this._composeNode(parent))}},_composeNode:function(node){var children=[];var c$=TreeApi.Logical.getChildNodes(node.shadyRoot||\nnode);for(var i=0;i<c$.length;i++){var child=c$[i];if(isInsertionPoint(child)){var distributedNodes=child._distributedNodes;for(var j=0;j<distributedNodes.length;j++){var distributedNode=distributedNodes[j];if(isFinalDestination(child,distributedNode))children.push(distributedNode)}}else children.push(child)}return children},_updateChildNodes:function(container,children){var composed=TreeApi.Composed.getChildNodes(container);var splices=Polymer.ArraySplice.calculateSplices(children,composed);for(var i=\n0,d=0,s;i<splices.length&&(s=splices[i]);i++){for(var j=0,n;j<s.removed.length&&(n=s.removed[j]);j++){if(TreeApi.Composed.getParentNode(n)===container)TreeApi.Composed.removeChild(container,n);composed.splice(s.index+d,1)}d-=s.addedCount}for(var i=0,s,next;i<splices.length&&(s=splices[i]);i++){next=composed[s.index];for(j=s.index,n;j<s.index+s.addedCount;j++){n=children[j];TreeApi.Composed.insertBefore(container,n,next);composed.splice(j,0,n)}}},_matchesContentSelect:function(node,contentElement){var select=\ncontentElement.getAttribute(\"select\");if(!select)return true;select=select.trim();if(!select)return true;if(!(node instanceof Element))return false;var validSelectors=/^(:not\\()?[*.#[a-zA-Z_|]/;if(!validSelectors.test(select))return false;return this.elementMatches(select,node)},_elementAdd:function(){},_elementRemove:function(){}});var domHostDesc={get:function(){var root=Polymer.dom(this).getOwnerRoot();return root&&root.host},configurable:true};Object.defineProperty(Polymer.Base,\"domHost\",domHostDesc);\nPolymer.BaseDescriptors.domHost=domHostDesc;function distributeNodeInto(child,insertionPoint){insertionPoint._distributedNodes.push(child);var points=child._destinationInsertionPoints;if(!points)child._destinationInsertionPoints=[insertionPoint];else points.push(insertionPoint)}function clearDistributedDestinationInsertionPoints(content){var e$=content._distributedNodes;if(e$)for(var i=0;i<e$.length;i++){var d=e$[i]._destinationInsertionPoints;if(d)d.splice(d.indexOf(content)+1,d.length)}}function maybeRedistributeParent(content,\nhost){var parent=TreeApi.Logical.getParentNode(content);if(parent&&parent.shadyRoot&&DomApi.hasInsertionPoint(parent.shadyRoot)&&parent.shadyRoot._distributionClean){parent.shadyRoot._distributionClean=false;host.shadyRoot._dirtyRoots.push(parent)}}function isFinalDestination(insertionPoint,node){var points=node._destinationInsertionPoints;return points&&points[points.length-1]===insertionPoint}function isInsertionPoint(node){return node.localName==\"content\"}function getTopDistributingHost(host){while(host&&\nhostNeedsRedistribution(host))host=host.domHost;return host}function hostNeedsRedistribution(host){var c$=TreeApi.Logical.getChildNodes(host);for(var i=0,c;i<c$.length;i++){c=c$[i];if(c.localName&&c.localName===\"content\")return host.domHost}}function notifyContentObservers(root){for(var i=0,c;i<root._insertionPoints.length;i++){c=root._insertionPoints[i];if(DomApi.hasApi(c))Polymer.dom(c).notifyObserver()}}function notifyInitialDistribution(host){if(DomApi.hasApi(host))Polymer.dom(host).notifyObserver()}\nvar needsUpgrade=window.CustomElements&&!CustomElements.useNative;function upgradeLogicalChildren(children){if(needsUpgrade&&children)for(var i=0;i<children.length;i++)CustomElements.upgrade(children[i])}})();\nif(Polymer.Settings.useShadow)Polymer.Base._addFeature({_poolContent:function(){},_beginDistribute:function(){},distributeContent:function(){},_distributeContent:function(){},_finishDistribute:function(){},_createLocalRoot:function(){this.createShadowRoot();this.shadowRoot.appendChild(this.root);this.root=this.shadowRoot}});\nPolymer.Async={_currVal:0,_lastVal:0,_callbacks:[],_twiddleContent:0,_twiddle:document.createTextNode(\"\"),run:function(callback,waitTime){if(waitTime>0)return~setTimeout(callback,waitTime);else{this._twiddle.textContent=this._twiddleContent++;this._callbacks.push(callback);return this._currVal++}},cancel:function(handle){if(handle<0)clearTimeout(~handle);else{var idx=handle-this._lastVal;if(idx>=0){if(!this._callbacks[idx])throw\"invalid async handle: \"+handle;this._callbacks[idx]=null}}},_atEndOfMicrotask:function(){var len=\nthis._callbacks.length;for(var i=0;i<len;i++){var cb=this._callbacks[i];if(cb)try{cb()}catch(e){i++;this._callbacks.splice(0,i);this._lastVal+=i;this._twiddle.textContent=this._twiddleContent++;throw e;}}this._callbacks.splice(0,len);this._lastVal+=len}};(new window.MutationObserver(function(){Polymer.Async._atEndOfMicrotask()})).observe(Polymer.Async._twiddle,{characterData:true});\nPolymer.Debounce=function(){var Async=Polymer.Async;var Debouncer=function(context){this.context=context;var self=this;this.boundComplete=function(){self.complete()}};Debouncer.prototype={go:function(callback,wait){var h;this.finish=function(){Async.cancel(h)};h=Async.run(this.boundComplete,wait);this.callback=callback},stop:function(){if(this.finish){this.finish();this.finish=null;this.callback=null}},complete:function(){if(this.finish){var callback=this.callback;this.stop();callback.call(this.context)}}};\nfunction debounce(debouncer,callback,wait){if(debouncer)debouncer.stop();else debouncer=new Debouncer(this);debouncer.go(callback,wait);return debouncer}return debounce}();\nPolymer.Base._addFeature({_setupDebouncers:function(){this._debouncers={}},debounce:function(jobName,callback,wait){return this._debouncers[jobName]=Polymer.Debounce.call(this,this._debouncers[jobName],callback,wait)},isDebouncerActive:function(jobName){var debouncer=this._debouncers[jobName];return!!(debouncer&&debouncer.finish)},flushDebouncer:function(jobName){var debouncer=this._debouncers[jobName];if(debouncer)debouncer.complete()},cancelDebouncer:function(jobName){var debouncer=this._debouncers[jobName];\nif(debouncer)debouncer.stop()}});Polymer.DomModule=document.createElement(\"dom-module\");\nPolymer.Base._addFeature({_registerFeatures:function(){this._prepIs();this._prepBehaviors();this._prepConstructor();this._prepTemplate();this._prepShady();this._prepPropertyInfo()},_prepBehavior:function(b){this._addHostAttributes(b.hostAttributes)},_initFeatures:function(){this._registerHost();if(this._template){this._poolContent();this._beginHosting();this._stampTemplate();this._endHosting()}this._marshalHostAttributes();this._setupDebouncers();this._marshalBehaviors();this._tryReady()},_marshalBehavior:function(b){}});(function(){Polymer.nar=[];var disableUpgradeEnabled=Polymer.Settings.disableUpgradeEnabled;Polymer.Annotations={parseAnnotations:function(template,stripWhiteSpace){var list=[];var content=template._content||template.content;this._parseNodeAnnotations(content,list,stripWhiteSpace||template.hasAttribute(\"strip-whitespace\"));return list},_parseNodeAnnotations:function(node,list,stripWhiteSpace){return node.nodeType===Node.TEXT_NODE?this._parseTextNodeAnnotation(node,list):this._parseElementAnnotations(node,\nlist,stripWhiteSpace)},_bindingRegex:function(){var IDENT=\"(?:\"+\"[a-zA-Z_$][\\\\w.:$\\\\-*]*\"+\")\";var NUMBER=\"(?:\"+\"[-+]?[0-9]*\\\\.?[0-9]+(?:[eE][-+]?[0-9]+)?\"+\")\";var SQUOTE_STRING=\"(?:\"+\"'(?:[^'\\\\\\\\]|\\\\\\\\.)*'\"+\")\";var DQUOTE_STRING=\"(?:\"+'\"(?:[^\"\\\\\\\\]|\\\\\\\\.)*\"'+\")\";var STRING=\"(?:\"+SQUOTE_STRING+\"|\"+DQUOTE_STRING+\")\";var ARGUMENT=\"(?:\"+IDENT+\"|\"+NUMBER+\"|\"+STRING+\"\\\\s*\"+\")\";var ARGUMENTS=\"(?:\"+ARGUMENT+\"(?:,\\\\s*\"+ARGUMENT+\")*\"+\")\";var ARGUMENT_LIST=\"(?:\"+\"\\\\(\\\\s*\"+\"(?:\"+ARGUMENTS+\"?\"+\")\"+\"\\\\)\\\\s*\"+\")\";\nvar BINDING=\"(\"+IDENT+\"\\\\s*\"+ARGUMENT_LIST+\"?\"+\")\";var OPEN_BRACKET=\"(\\\\[\\\\[|{{)\"+\"\\\\s*\";var CLOSE_BRACKET=\"(?:]]|}})\";var NEGATE=\"(?:(!)\\\\s*)?\";var EXPRESSION=OPEN_BRACKET+NEGATE+BINDING+CLOSE_BRACKET;return new RegExp(EXPRESSION,\"g\")}(),_parseBindings:function(text){var re=this._bindingRegex;var parts=[];var lastIndex=0;var m;while((m=re.exec(text))!==null){if(m.index>lastIndex)parts.push({literal:text.slice(lastIndex,m.index)});var mode=m[1][0];var negate=Boolean(m[2]);var value=m[3].trim();var customEvent,\nnotifyEvent,colon;if(mode==\"{\"&&(colon=value.indexOf(\"::\"))>0){notifyEvent=value.substring(colon+2);value=value.substring(0,colon);customEvent=true}parts.push({compoundIndex:parts.length,value:value,mode:mode,negate:negate,event:notifyEvent,customEvent:customEvent});lastIndex=re.lastIndex}if(lastIndex&&lastIndex<text.length){var literal=text.substring(lastIndex);if(literal)parts.push({literal:literal})}if(parts.length)return parts},_literalFromParts:function(parts){var s=\"\";for(var i=0;i<parts.length;i++){var literal=\nparts[i].literal;s+=literal||\"\"}return s},_parseTextNodeAnnotation:function(node,list){var parts=this._parseBindings(node.textContent);if(parts){node.textContent=this._literalFromParts(parts)||\" \";var annote={bindings:[{kind:\"text\",name:\"textContent\",parts:parts,isCompound:parts.length!==1}]};list.push(annote);return annote}},_parseElementAnnotations:function(element,list,stripWhiteSpace){var annote={bindings:[],events:[]};if(element.localName===\"content\")list._hasContent=true;this._parseChildNodesAnnotations(element,\nannote,list,stripWhiteSpace);if(element.attributes){this._parseNodeAttributeAnnotations(element,annote,list);if(this.prepElement)this.prepElement(element)}if(annote.bindings.length||annote.events.length||annote.id)list.push(annote);return annote},_parseChildNodesAnnotations:function(root,annote,list,stripWhiteSpace){if(root.firstChild){var node=root.firstChild;var i=0;while(node){var next=node.nextSibling;if(node.localName===\"template\"&&!node.hasAttribute(\"preserve-content\"))this._parseTemplate(node,\ni,list,annote,stripWhiteSpace);if(node.localName==\"slot\")node=this._replaceSlotWithContent(node);if(node.nodeType===Node.TEXT_NODE){var n=next;while(n&&n.nodeType===Node.TEXT_NODE){node.textContent+=n.textContent;next=n.nextSibling;root.removeChild(n);n=next}if(stripWhiteSpace&&!node.textContent.trim()){root.removeChild(node);i--}}if(node.parentNode){var childAnnotation=this._parseNodeAnnotations(node,list,stripWhiteSpace);if(childAnnotation){childAnnotation.parent=annote;childAnnotation.index=i}}node=\nnext;i++}}},_replaceSlotWithContent:function(slot){var content=slot.ownerDocument.createElement(\"content\");while(slot.firstChild)content.appendChild(slot.firstChild);var attrs=slot.attributes;for(var i=0;i<attrs.length;i++){var attr=attrs[i];content.setAttribute(attr.name,attr.value)}var name=slot.getAttribute(\"name\");if(name)content.setAttribute(\"select\",\"[slot='\"+name+\"']\");slot.parentNode.replaceChild(content,slot);return content},_parseTemplate:function(node,index,list,parent,stripWhiteSpace){var content=\ndocument.createDocumentFragment();content._notes=this.parseAnnotations(node,stripWhiteSpace);content.appendChild(node.content);list.push({bindings:Polymer.nar,events:Polymer.nar,templateContent:content,parent:parent,index:index})},_parseNodeAttributeAnnotations:function(node,annotation){var attrs=Array.prototype.slice.call(node.attributes);for(var i=attrs.length-1,a;a=attrs[i];i--){var n=a.name;var v=a.value;var b;if(n.slice(0,3)===\"on-\"){node.removeAttribute(n);annotation.events.push({name:n.slice(3),\nvalue:v})}else if(b=this._parseNodeAttributeAnnotation(node,n,v))annotation.bindings.push(b);else if(n===\"id\")annotation.id=v}},_parseNodeAttributeAnnotation:function(node,name,value){var parts=this._parseBindings(value);if(parts){var origName=name;var kind=\"property\";if(name[name.length-1]==\"$\"){name=name.slice(0,-1);kind=\"attribute\"}var literal=this._literalFromParts(parts);if(literal&&kind==\"attribute\")node.setAttribute(name,literal);if(node.localName===\"input\"&&origName===\"value\")node.setAttribute(origName,\n\"\");if(disableUpgradeEnabled&&origName===\"disable-upgrade$\")node.setAttribute(name,\"\");node.removeAttribute(origName);var propertyName=Polymer.CaseMap.dashToCamelCase(name);if(kind===\"property\")name=propertyName;return{kind:kind,name:name,propertyName:propertyName,parts:parts,literal:literal,isCompound:parts.length!==1}}},findAnnotatedNode:function(root,annote){var parent=annote.parent&&Polymer.Annotations.findAnnotatedNode(root,annote.parent);if(parent)for(var n=parent.firstChild,i=0;n;n=n.nextSibling){if(annote.index===\ni++)return n}else return root}}})();\n(function(){function resolveCss(cssText,ownerDocument){return cssText.replace(CSS_URL_RX,function(m,pre,url,post){return pre+\"'\"+resolve(url.replace(/[\"']/g,\"\"),ownerDocument)+\"'\"+post})}function resolveAttrs(element,ownerDocument){for(var name in URL_ATTRS){var a$=URL_ATTRS[name];for(var i=0,l=a$.length,a,at,v;i<l&&(a=a$[i]);i++)if(name===\"*\"||element.localName===name){at=element.attributes[a];v=at&&at.value;if(v&&v.search(BINDING_RX)<0)at.value=a===\"style\"?resolveCss(v,ownerDocument):resolve(v,\nownerDocument)}}}function resolve(url,ownerDocument){if(url&&ABS_URL.test(url))return url;var resolver=getUrlResolver(ownerDocument);resolver.href=url;return resolver.href||url}var tempDoc;var tempDocBase;function resolveUrl(url,baseUri){if(!tempDoc){tempDoc=document.implementation.createHTMLDocument(\"temp\");tempDocBase=tempDoc.createElement(\"base\");tempDoc.head.appendChild(tempDocBase)}tempDocBase.href=baseUri;return resolve(url,tempDoc)}function getUrlResolver(ownerDocument){return ownerDocument.body.__urlResolver||\n(ownerDocument.body.__urlResolver=ownerDocument.createElement(\"a\"))}var CSS_URL_RX=/(url\\()([^)]*)(\\))/g;var URL_ATTRS={\"*\":[\"href\",\"src\",\"style\",\"url\"],form:[\"action\"]};var ABS_URL=/(^\\/)|(^#)|(^[\\w-\\d]*:)/;var BINDING_RX=/\\{\\{|\\[\\[/;Polymer.ResolveUrl={resolveCss:resolveCss,resolveAttrs:resolveAttrs,resolveUrl:resolveUrl}})();\nPolymer.Path={root:function(path){var dotIndex=path.indexOf(\".\");if(dotIndex===-1)return path;return path.slice(0,dotIndex)},isDeep:function(path){return path.indexOf(\".\")!==-1},isAncestor:function(base,path){return base.indexOf(path+\".\")===0},isDescendant:function(base,path){return path.indexOf(base+\".\")===0},translate:function(base,newBase,path){return newBase+path.slice(base.length)},matches:function(base,wildcard,path){return base===path||this.isAncestor(base,path)||Boolean(wildcard)&&this.isDescendant(base,\npath)}};\nPolymer.Base._addFeature({_prepAnnotations:function(){if(!this._template)this._notes=[];else{var self=this;Polymer.Annotations.prepElement=function(element){self._prepElement(element)};if(this._template._content&&this._template._content._notes)this._notes=this._template._content._notes;else{this._notes=Polymer.Annotations.parseAnnotations(this._template);this._processAnnotations(this._notes)}Polymer.Annotations.prepElement=null}},_processAnnotations:function(notes){for(var i=0;i<notes.length;i++){var note=notes[i];\nfor(var j=0;j<note.bindings.length;j++){var b=note.bindings[j];for(var k=0;k<b.parts.length;k++){var p=b.parts[k];if(!p.literal){var signature=this._parseMethod(p.value);if(signature)p.signature=signature;else p.model=Polymer.Path.root(p.value)}}}if(note.templateContent){this._processAnnotations(note.templateContent._notes);var pp=note.templateContent._parentProps=this._discoverTemplateParentProps(note.templateContent._notes);var bindings=[];for(var prop in pp){var name=\"_parent_\"+prop;bindings.push({index:note.index,\nkind:\"property\",name:name,propertyName:name,parts:[{mode:\"{\",model:prop,value:prop}]})}note.bindings=note.bindings.concat(bindings)}}},_discoverTemplateParentProps:function(notes){var pp={};for(var i=0,n;i<notes.length&&(n=notes[i]);i++){for(var j=0,b$=n.bindings,b;j<b$.length&&(b=b$[j]);j++)for(var k=0,p$=b.parts,p;k<p$.length&&(p=p$[k]);k++)if(p.signature){var args=p.signature.args;for(var kk=0;kk<args.length;kk++){var model=args[kk].model;if(model)pp[model]=true}if(p.signature.dynamicFn)pp[p.signature.method]=\ntrue}else if(p.model)pp[p.model]=true;if(n.templateContent){var tpp=n.templateContent._parentProps;Polymer.Base.mixin(pp,tpp)}}return pp},_prepElement:function(element){Polymer.ResolveUrl.resolveAttrs(element,this._template.ownerDocument)},_findAnnotatedNode:Polymer.Annotations.findAnnotatedNode,_marshalAnnotationReferences:function(){if(this._template){this._marshalIdNodes();this._marshalAnnotatedNodes();this._marshalAnnotatedListeners()}},_configureAnnotationReferences:function(){var notes=this._notes;\nvar nodes=this._nodes;for(var i=0;i<notes.length;i++){var note=notes[i];var node=nodes[i];this._configureTemplateContent(note,node);this._configureCompoundBindings(note,node)}},_configureTemplateContent:function(note,node){if(note.templateContent)node._content=note.templateContent},_configureCompoundBindings:function(note,node){var bindings=note.bindings;for(var i=0;i<bindings.length;i++){var binding=bindings[i];if(binding.isCompound){var storage=node.__compoundStorage__||(node.__compoundStorage__=\n{});var parts=binding.parts;var literals=new Array(parts.length);for(var j=0;j<parts.length;j++)literals[j]=parts[j].literal;var name=binding.name;storage[name]=literals;if(binding.literal&&binding.kind==\"property\")if(node._configValue)node._configValue(name,binding.literal);else node[name]=binding.literal}}},_marshalIdNodes:function(){this.$={};for(var i=0,l=this._notes.length,a;i<l&&(a=this._notes[i]);i++)if(a.id)this.$[a.id]=this._findAnnotatedNode(this.root,a)},_marshalAnnotatedNodes:function(){if(this._notes&&\nthis._notes.length){var r=new Array(this._notes.length);for(var i=0;i<this._notes.length;i++)r[i]=this._findAnnotatedNode(this.root,this._notes[i]);this._nodes=r}},_marshalAnnotatedListeners:function(){for(var i=0,l=this._notes.length,a;i<l&&(a=this._notes[i]);i++)if(a.events&&a.events.length){var node=this._findAnnotatedNode(this.root,a);for(var j=0,e$=a.events,e;j<e$.length&&(e=e$[j]);j++)this.listen(node,e.name,e.value)}}});\nPolymer.Base._addFeature({listeners:{},_listenListeners:function(listeners){var node,name,eventName;for(eventName in listeners){if(eventName.indexOf(\".\")<0){node=this;name=eventName}else{name=eventName.split(\".\");node=this.$[name[0]];name=name[1]}this.listen(node,name,listeners[eventName])}},listen:function(node,eventName,methodName){var handler=this._recallEventHandler(this,eventName,node,methodName);if(!handler)handler=this._createEventHandler(node,eventName,methodName);if(handler._listening)return;\nthis._listen(node,eventName,handler);handler._listening=true},_boundListenerKey:function(eventName,methodName){return eventName+\":\"+methodName},_recordEventHandler:function(host,eventName,target,methodName,handler){var hbl=host.__boundListeners;if(!hbl)hbl=host.__boundListeners=new WeakMap;var bl=hbl.get(target);if(!bl){bl={};if(!Polymer.Settings.isIE||target!=window)hbl.set(target,bl)}var key=this._boundListenerKey(eventName,methodName);bl[key]=handler},_recallEventHandler:function(host,eventName,\ntarget,methodName){var hbl=host.__boundListeners;if(!hbl)return;var bl=hbl.get(target);if(!bl)return;var key=this._boundListenerKey(eventName,methodName);return bl[key]},_createEventHandler:function(node,eventName,methodName){var host=this;var handler=function(e){if(host[methodName])host[methodName](e,e.detail);else host._warn(host._logf(\"_createEventHandler\",\"listener method `\"+methodName+\"` not defined\"))};handler._listening=false;this._recordEventHandler(host,eventName,node,methodName,handler);\nreturn handler},unlisten:function(node,eventName,methodName){var handler=this._recallEventHandler(this,eventName,node,methodName);if(handler){this._unlisten(node,eventName,handler);handler._listening=false}},_listen:function(node,eventName,handler){node.addEventListener(eventName,handler)},_unlisten:function(node,eventName,handler){node.removeEventListener(eventName,handler)}});\n(function(){var wrap=Polymer.DomApi.wrap;var HAS_NATIVE_TA=typeof document.head.style.touchAction===\"string\";var GESTURE_KEY=\"__polymerGestures\";var HANDLED_OBJ=\"__polymerGesturesHandled\";var TOUCH_ACTION=\"__polymerGesturesTouchAction\";var TAP_DISTANCE=25;var TRACK_DISTANCE=5;var TRACK_LENGTH=2;var MOUSE_TIMEOUT=2500;var MOUSE_EVENTS=[\"mousedown\",\"mousemove\",\"mouseup\",\"click\"];var MOUSE_WHICH_TO_BUTTONS=[0,1,4,2];var MOUSE_HAS_BUTTONS=function(){try{return(new MouseEvent(\"test\",{buttons:1})).buttons===\n1}catch(e){return false}}();var SUPPORTS_PASSIVE=false;(function(){try{var opts=Object.defineProperty({},\"passive\",{get:function(){SUPPORTS_PASSIVE=true}});window.addEventListener(\"test\",null,opts);window.removeEventListener(\"test\",null,opts)}catch(e){}})();var IS_TOUCH_ONLY=navigator.userAgent.match(/iP(?:[oa]d|hone)|Android/);var mouseCanceller=function(mouseEvent){var sc=mouseEvent.sourceCapabilities;if(sc&&!sc.firesTouchEvents)return;mouseEvent[HANDLED_OBJ]={skip:true};if(mouseEvent.type===\"click\"){var path=\nPolymer.dom(mouseEvent).path;for(var i=0;i<path.length;i++)if(path[i]===POINTERSTATE.mouse.target)return;mouseEvent.preventDefault();mouseEvent.stopPropagation()}};function setupTeardownMouseCanceller(setup){var events=IS_TOUCH_ONLY?[\"click\"]:MOUSE_EVENTS;for(var i=0,en;i<events.length;i++){en=events[i];if(setup)document.addEventListener(en,mouseCanceller,true);else document.removeEventListener(en,mouseCanceller,true)}}function ignoreMouse(ev){if(!POINTERSTATE.mouse.mouseIgnoreJob)setupTeardownMouseCanceller(true);\nvar unset=function(){setupTeardownMouseCanceller();POINTERSTATE.mouse.target=null;POINTERSTATE.mouse.mouseIgnoreJob=null};POINTERSTATE.mouse.target=Polymer.dom(ev).rootTarget;POINTERSTATE.mouse.mouseIgnoreJob=Polymer.Debounce(POINTERSTATE.mouse.mouseIgnoreJob,unset,MOUSE_TIMEOUT)}function hasLeftMouseButton(ev){var type=ev.type;if(MOUSE_EVENTS.indexOf(type)===-1)return false;if(type===\"mousemove\"){var buttons=ev.buttons===undefined?1:ev.buttons;if(ev instanceof window.MouseEvent&&!MOUSE_HAS_BUTTONS)buttons=\nMOUSE_WHICH_TO_BUTTONS[ev.which]||0;return Boolean(buttons&1)}else{var button=ev.button===undefined?0:ev.button;return button===0}}function isSyntheticClick(ev){if(ev.type===\"click\"){if(ev.detail===0)return true;var t=Gestures.findOriginalTarget(ev);var bcr=t.getBoundingClientRect();var x=ev.pageX,y=ev.pageY;return!(x>=bcr.left&&x<=bcr.right&&(y>=bcr.top&&y<=bcr.bottom))}return false}var POINTERSTATE={mouse:{target:null,mouseIgnoreJob:null},touch:{x:0,y:0,id:-1,scrollDecided:false}};function firstTouchAction(ev){var path=\nPolymer.dom(ev).path;var ta=\"auto\";for(var i=0,n;i<path.length;i++){n=path[i];if(n[TOUCH_ACTION]){ta=n[TOUCH_ACTION];break}}return ta}function trackDocument(stateObj,movefn,upfn){stateObj.movefn=movefn;stateObj.upfn=upfn;document.addEventListener(\"mousemove\",movefn);document.addEventListener(\"mouseup\",upfn)}function untrackDocument(stateObj){document.removeEventListener(\"mousemove\",stateObj.movefn);document.removeEventListener(\"mouseup\",stateObj.upfn);stateObj.movefn=null;stateObj.upfn=null}document.addEventListener(\"touchend\",\nignoreMouse,SUPPORTS_PASSIVE?{passive:true}:false);var Gestures={gestures:{},recognizers:[],deepTargetFind:function(x,y){var node=document.elementFromPoint(x,y);var next=node;while(next&&next.shadowRoot){next=next.shadowRoot.elementFromPoint(x,y);if(next)node=next}return node},findOriginalTarget:function(ev){if(ev.path)return ev.path[0];return ev.target},handleNative:function(ev){var handled;var type=ev.type;var node=wrap(ev.currentTarget);var gobj=node[GESTURE_KEY];if(!gobj)return;var gs=gobj[type];\nif(!gs)return;if(!ev[HANDLED_OBJ]){ev[HANDLED_OBJ]={};if(type.slice(0,5)===\"touch\"){var t=ev.changedTouches[0];if(type===\"touchstart\")if(ev.touches.length===1)POINTERSTATE.touch.id=t.identifier;if(POINTERSTATE.touch.id!==t.identifier)return;if(!HAS_NATIVE_TA)if(type===\"touchstart\"||type===\"touchmove\")Gestures.handleTouchAction(ev)}}handled=ev[HANDLED_OBJ];if(handled.skip)return;var recognizers=Gestures.recognizers;for(var i=0,r;i<recognizers.length;i++){r=recognizers[i];if(gs[r.name]&&!handled[r.name])if(r.flow&&\nr.flow.start.indexOf(ev.type)>-1&&r.reset)r.reset()}for(i=0,r;i<recognizers.length;i++){r=recognizers[i];if(gs[r.name]&&!handled[r.name]){handled[r.name]=true;r[type](ev)}}},handleTouchAction:function(ev){var t=ev.changedTouches[0];var type=ev.type;if(type===\"touchstart\"){POINTERSTATE.touch.x=t.clientX;POINTERSTATE.touch.y=t.clientY;POINTERSTATE.touch.scrollDecided=false}else if(type===\"touchmove\"){if(POINTERSTATE.touch.scrollDecided)return;POINTERSTATE.touch.scrollDecided=true;var ta=firstTouchAction(ev);\nvar prevent=false;var dx=Math.abs(POINTERSTATE.touch.x-t.clientX);var dy=Math.abs(POINTERSTATE.touch.y-t.clientY);if(!ev.cancelable);else if(ta===\"none\")prevent=true;else if(ta===\"pan-x\")prevent=dy>dx;else if(ta===\"pan-y\")prevent=dx>dy;if(prevent)ev.preventDefault();else Gestures.prevent(\"track\")}},add:function(node,evType,handler){node=wrap(node);var recognizer=this.gestures[evType];var deps=recognizer.deps;var name=recognizer.name;var gobj=node[GESTURE_KEY];if(!gobj)node[GESTURE_KEY]=gobj={};for(var i=\n0,dep,gd;i<deps.length;i++){dep=deps[i];if(IS_TOUCH_ONLY&&MOUSE_EVENTS.indexOf(dep)>-1&&dep!==\"click\")continue;gd=gobj[dep];if(!gd)gobj[dep]=gd={_count:0};if(gd._count===0)node.addEventListener(dep,this.handleNative);gd[name]=(gd[name]||0)+1;gd._count=(gd._count||0)+1}node.addEventListener(evType,handler);if(recognizer.touchAction)this.setTouchAction(node,recognizer.touchAction)},remove:function(node,evType,handler){node=wrap(node);var recognizer=this.gestures[evType];var deps=recognizer.deps;var name=\nrecognizer.name;var gobj=node[GESTURE_KEY];if(gobj)for(var i=0,dep,gd;i<deps.length;i++){dep=deps[i];gd=gobj[dep];if(gd&&gd[name]){gd[name]=(gd[name]||1)-1;gd._count=(gd._count||1)-1;if(gd._count===0)node.removeEventListener(dep,this.handleNative)}}node.removeEventListener(evType,handler)},register:function(recog){this.recognizers.push(recog);for(var i=0;i<recog.emits.length;i++)this.gestures[recog.emits[i]]=recog},findRecognizerByEvent:function(evName){for(var i=0,r;i<this.recognizers.length;i++){r=\nthis.recognizers[i];for(var j=0,n;j<r.emits.length;j++){n=r.emits[j];if(n===evName)return r}}return null},setTouchAction:function(node,value){if(HAS_NATIVE_TA)node.style.touchAction=value;node[TOUCH_ACTION]=value},fire:function(target,type,detail){var ev=Polymer.Base.fire(type,detail,{node:target,bubbles:true,cancelable:true});if(ev.defaultPrevented){var preventer=detail.preventer||detail.sourceEvent;if(preventer&&preventer.preventDefault)preventer.preventDefault()}},prevent:function(evName){var recognizer=\nthis.findRecognizerByEvent(evName);if(recognizer.info)recognizer.info.prevent=true},resetMouseCanceller:function(){if(POINTERSTATE.mouse.mouseIgnoreJob)POINTERSTATE.mouse.mouseIgnoreJob.complete()}};Gestures.register({name:\"downup\",deps:[\"mousedown\",\"touchstart\",\"touchend\"],flow:{start:[\"mousedown\",\"touchstart\"],end:[\"mouseup\",\"touchend\"]},emits:[\"down\",\"up\"],info:{movefn:null,upfn:null},reset:function(){untrackDocument(this.info)},mousedown:function(e){if(!hasLeftMouseButton(e))return;var t=Gestures.findOriginalTarget(e);\nvar self=this;var movefn=function movefn(e){if(!hasLeftMouseButton(e)){self.fire(\"up\",t,e);untrackDocument(self.info)}};var upfn=function upfn(e){if(hasLeftMouseButton(e))self.fire(\"up\",t,e);untrackDocument(self.info)};trackDocument(this.info,movefn,upfn);this.fire(\"down\",t,e)},touchstart:function(e){this.fire(\"down\",Gestures.findOriginalTarget(e),e.changedTouches[0],e)},touchend:function(e){this.fire(\"up\",Gestures.findOriginalTarget(e),e.changedTouches[0],e)},fire:function(type,target,event,preventer){Gestures.fire(target,\ntype,{x:event.clientX,y:event.clientY,sourceEvent:event,preventer:preventer,prevent:function(e){return Gestures.prevent(e)}})}});Gestures.register({name:\"track\",touchAction:\"none\",deps:[\"mousedown\",\"touchstart\",\"touchmove\",\"touchend\"],flow:{start:[\"mousedown\",\"touchstart\"],end:[\"mouseup\",\"touchend\"]},emits:[\"track\"],info:{x:0,y:0,state:\"start\",started:false,moves:[],addMove:function(move){if(this.moves.length>TRACK_LENGTH)this.moves.shift();this.moves.push(move)},movefn:null,upfn:null,prevent:false},\nreset:function(){this.info.state=\"start\";this.info.started=false;this.info.moves=[];this.info.x=0;this.info.y=0;this.info.prevent=false;untrackDocument(this.info)},hasMovedEnough:function(x,y){if(this.info.prevent)return false;if(this.info.started)return true;var dx=Math.abs(this.info.x-x);var dy=Math.abs(this.info.y-y);return dx>=TRACK_DISTANCE||dy>=TRACK_DISTANCE},mousedown:function(e){if(!hasLeftMouseButton(e))return;var t=Gestures.findOriginalTarget(e);var self=this;var movefn=function movefn(e){var x=\ne.clientX,y=e.clientY;if(self.hasMovedEnough(x,y)){self.info.state=self.info.started?e.type===\"mouseup\"?\"end\":\"track\":\"start\";if(self.info.state===\"start\")Gestures.prevent(\"tap\");self.info.addMove({x:x,y:y});if(!hasLeftMouseButton(e)){self.info.state=\"end\";untrackDocument(self.info)}self.fire(t,e);self.info.started=true}};var upfn=function upfn(e){if(self.info.started)movefn(e);untrackDocument(self.info)};trackDocument(this.info,movefn,upfn);this.info.x=e.clientX;this.info.y=e.clientY},touchstart:function(e){var ct=\ne.changedTouches[0];this.info.x=ct.clientX;this.info.y=ct.clientY},touchmove:function(e){var t=Gestures.findOriginalTarget(e);var ct=e.changedTouches[0];var x=ct.clientX,y=ct.clientY;if(this.hasMovedEnough(x,y)){if(this.info.state===\"start\")Gestures.prevent(\"tap\");this.info.addMove({x:x,y:y});this.fire(t,ct);this.info.state=\"track\";this.info.started=true}},touchend:function(e){var t=Gestures.findOriginalTarget(e);var ct=e.changedTouches[0];if(this.info.started){this.info.state=\"end\";this.info.addMove({x:ct.clientX,\ny:ct.clientY});this.fire(t,ct,e)}},fire:function(target,touch,preventer){var secondlast=this.info.moves[this.info.moves.length-2];var lastmove=this.info.moves[this.info.moves.length-1];var dx=lastmove.x-this.info.x;var dy=lastmove.y-this.info.y;var ddx,ddy=0;if(secondlast){ddx=lastmove.x-secondlast.x;ddy=lastmove.y-secondlast.y}return Gestures.fire(target,\"track\",{state:this.info.state,x:touch.clientX,y:touch.clientY,dx:dx,dy:dy,ddx:ddx,ddy:ddy,sourceEvent:touch,preventer:preventer,hover:function(){return Gestures.deepTargetFind(touch.clientX,\ntouch.clientY)}})}});Gestures.register({name:\"tap\",deps:[\"mousedown\",\"click\",\"touchstart\",\"touchend\"],flow:{start:[\"mousedown\",\"touchstart\"],end:[\"click\",\"touchend\"]},emits:[\"tap\"],info:{x:NaN,y:NaN,prevent:false},reset:function(){this.info.x=NaN;this.info.y=NaN;this.info.prevent=false},save:function(e){this.info.x=e.clientX;this.info.y=e.clientY},mousedown:function(e){if(hasLeftMouseButton(e))this.save(e)},click:function(e){if(hasLeftMouseButton(e))this.forward(e)},touchstart:function(e){this.save(e.changedTouches[0],\ne)},touchend:function(e){this.forward(e.changedTouches[0],e)},forward:function(e,preventer){var dx=Math.abs(e.clientX-this.info.x);var dy=Math.abs(e.clientY-this.info.y);var t=Gestures.findOriginalTarget(e);if(isNaN(dx)||isNaN(dy)||dx<=TAP_DISTANCE&&dy<=TAP_DISTANCE||isSyntheticClick(e))if(!this.info.prevent)Gestures.fire(t,\"tap\",{x:e.clientX,y:e.clientY,sourceEvent:e,preventer:preventer})}});var DIRECTION_MAP={x:\"pan-x\",y:\"pan-y\",none:\"none\",all:\"auto\"};Polymer.Base._addFeature({_setupGestures:function(){this.__polymerGestures=\nnull},_listen:function(node,eventName,handler){if(Gestures.gestures[eventName])Gestures.add(node,eventName,handler);else node.addEventListener(eventName,handler)},_unlisten:function(node,eventName,handler){if(Gestures.gestures[eventName])Gestures.remove(node,eventName,handler);else node.removeEventListener(eventName,handler)},setScrollDirection:function(direction,node){node=node||this;Gestures.setTouchAction(node,DIRECTION_MAP[direction]||\"auto\")}});Polymer.Gestures=Gestures})();\n(function(){Polymer.Base._addFeature({$$:function(slctr){return Polymer.dom(this.root).querySelector(slctr)},toggleClass:function(name,bool,node){node=node||this;if(arguments.length==1)bool=!node.classList.contains(name);if(bool)Polymer.dom(node).classList.add(name);else Polymer.dom(node).classList.remove(name)},toggleAttribute:function(name,bool,node){node=node||this;if(arguments.length==1)bool=!node.hasAttribute(name);if(bool)Polymer.dom(node).setAttribute(name,\"\");else Polymer.dom(node).removeAttribute(name)},\nclassFollows:function(name,toElement,fromElement){if(fromElement)Polymer.dom(fromElement).classList.remove(name);if(toElement)Polymer.dom(toElement).classList.add(name)},attributeFollows:function(name,toElement,fromElement){if(fromElement)Polymer.dom(fromElement).removeAttribute(name);if(toElement)Polymer.dom(toElement).setAttribute(name,\"\")},getEffectiveChildNodes:function(){return Polymer.dom(this).getEffectiveChildNodes()},getEffectiveChildren:function(){var list=Polymer.dom(this).getEffectiveChildNodes();\nreturn list.filter(function(n){return n.nodeType===Node.ELEMENT_NODE})},getEffectiveTextContent:function(){var cn=this.getEffectiveChildNodes();var tc=[];for(var i=0,c;c=cn[i];i++)if(c.nodeType!==Node.COMMENT_NODE)tc.push(Polymer.dom(c).textContent);return tc.join(\"\")},queryEffectiveChildren:function(slctr){var e$=Polymer.dom(this).queryDistributedElements(slctr);return e$&&e$[0]},queryAllEffectiveChildren:function(slctr){return Polymer.dom(this).queryDistributedElements(slctr)},getContentChildNodes:function(slctr){var content=\nPolymer.dom(this.root).querySelector(slctr||\"content\");return content?Polymer.dom(content).getDistributedNodes():[]},getContentChildren:function(slctr){return this.getContentChildNodes(slctr).filter(function(n){return n.nodeType===Node.ELEMENT_NODE})},fire:function(type,detail,options){options=options||Polymer.nob;var node=options.node||this;detail=detail===null||detail===undefined?{}:detail;var bubbles=options.bubbles===undefined?true:options.bubbles;var cancelable=Boolean(options.cancelable);var useCache=\noptions._useCache;var event=this._getEvent(type,bubbles,cancelable,useCache);event.detail=detail;if(useCache)this.__eventCache[type]=null;node.dispatchEvent(event);if(useCache)this.__eventCache[type]=event;return event},__eventCache:{},_getEvent:function(type,bubbles,cancelable,useCache){var event=useCache&&this.__eventCache[type];if(!event||(event.bubbles!=bubbles||event.cancelable!=cancelable))event=new Event(type,{bubbles:Boolean(bubbles),cancelable:cancelable});return event},async:function(callback,\nwaitTime){var self=this;return Polymer.Async.run(function(){callback.call(self)},waitTime)},cancelAsync:function(handle){Polymer.Async.cancel(handle)},arrayDelete:function(path,item){var index;if(Array.isArray(path)){index=path.indexOf(item);if(index>=0)return path.splice(index,1)}else{var arr=this._get(path);index=arr.indexOf(item);if(index>=0)return this.splice(path,index,1)}},transform:function(transform,node){node=node||this;node.style.webkitTransform=transform;node.style.transform=transform},\ntranslate3d:function(x,y,z,node){node=node||this;this.transform(\"translate3d(\"+x+\",\"+y+\",\"+z+\")\",node)},importHref:function(href,onload,onerror,optAsync){var link=document.createElement(\"link\");link.rel=\"import\";link.href=href;var list=Polymer.Base.importHref.imported=Polymer.Base.importHref.imported||{};var cached=list[link.href];var imprt=cached||link;var self=this;var loadListener=function(e){e.target.__firedLoad=true;e.target.removeEventListener(\"load\",loadListener);e.target.removeEventListener(\"error\",\nerrorListener);return onload.call(self,e)};var errorListener=function(e){e.target.__firedError=true;e.target.removeEventListener(\"load\",loadListener);e.target.removeEventListener(\"error\",errorListener);return onerror.call(self,e)};if(onload)imprt.addEventListener(\"load\",loadListener);if(onerror)imprt.addEventListener(\"error\",errorListener);if(cached){if(cached.__firedLoad)cached.dispatchEvent(new Event(\"load\"));if(cached.__firedError)cached.dispatchEvent(new Event(\"error\"))}else{list[link.href]=link;\noptAsync=Boolean(optAsync);if(optAsync)link.setAttribute(\"async\",\"\");document.head.appendChild(link)}return imprt},create:function(tag,props){var elt=document.createElement(tag);if(props)for(var n in props)elt[n]=props[n];return elt},isLightDescendant:function(node){return this!==node&&this.contains(node)&&Polymer.dom(this).getOwnerRoot()===Polymer.dom(node).getOwnerRoot()},isLocalDescendant:function(node){return this.root===Polymer.dom(node).getOwnerRoot()}});if(!Polymer.Settings.useNativeCustomElements){var importHref=\nPolymer.Base.importHref;Polymer.Base.importHref=function(href,onload,onerror,optAsync){CustomElements.ready=false;var loadFn=function(e){CustomElements.upgradeDocumentTree(document);CustomElements.ready=true;if(onload)return onload.call(this,e)};return importHref.call(this,href,loadFn,onerror,optAsync)}}})();\nPolymer.Bind={prepareModel:function(model){Polymer.Base.mixin(model,this._modelApi)},_modelApi:{_notifyChange:function(source,event,value){value=value===undefined?this[source]:value;event=event||Polymer.CaseMap.camelToDashCase(source)+\"-changed\";this.fire(event,{value:value},{bubbles:false,cancelable:false,_useCache:Polymer.Settings.eventDataCache||!Polymer.Settings.isIE})},_propertySetter:function(property,value,effects,fromAbove){var old=this.__data__[property];if(old!==value&&(old===old||value===\nvalue)){this.__data__[property]=value;if(typeof value==\"object\")this._clearPath(property);if(this._propertyChanged)this._propertyChanged(property,value,old);if(effects)this._effectEffects(property,value,effects,old,fromAbove)}return old},__setProperty:function(property,value,quiet,node){node=node||this;var effects=node._propertyEffects&&node._propertyEffects[property];if(effects)node._propertySetter(property,value,effects,quiet);else if(node[property]!==value)node[property]=value},_effectEffects:function(property,\nvalue,effects,old,fromAbove){for(var i=0,l=effects.length,fx;i<l&&(fx=effects[i]);i++)fx.fn.call(this,property,this[property],fx.effect,old,fromAbove)},_clearPath:function(path){for(var prop in this.__data__)if(Polymer.Path.isDescendant(path,prop))this.__data__[prop]=undefined}},ensurePropertyEffects:function(model,property){if(!model._propertyEffects)model._propertyEffects={};var fx=model._propertyEffects[property];if(!fx)fx=model._propertyEffects[property]=[];return fx},addPropertyEffect:function(model,\nproperty,kind,effect){var fx=this.ensurePropertyEffects(model,property);var propEffect={kind:kind,effect:effect,fn:Polymer.Bind[\"_\"+kind+\"Effect\"]};fx.push(propEffect);return propEffect},createBindings:function(model){var fx$=model._propertyEffects;if(fx$)for(var n in fx$){var fx=fx$[n];fx.sort(this._sortPropertyEffects);this._createAccessors(model,n,fx)}},_sortPropertyEffects:function(){var EFFECT_ORDER={\"compute\":0,\"annotation\":1,\"annotatedComputation\":2,\"reflect\":3,\"notify\":4,\"observer\":5,\"complexObserver\":6,\n\"function\":7};return function(a,b){return EFFECT_ORDER[a.kind]-EFFECT_ORDER[b.kind]}}(),_createAccessors:function(model,property,effects){var defun={get:function(){return this.__data__[property]}};var setter=function(value){this._propertySetter(property,value,effects)};var info=model.getPropertyInfo&&model.getPropertyInfo(property);if(info&&info.readOnly){if(!info.computed)model[\"_set\"+this.upper(property)]=setter}else defun.set=setter;Object.defineProperty(model,property,defun)},upper:function(name){return name[0].toUpperCase()+\nname.substring(1)},_addAnnotatedListener:function(model,index,property,path,event,negated){if(!model._bindListeners)model._bindListeners=[];var fn=this._notedListenerFactory(property,path,Polymer.Path.isDeep(path),negated);var eventName=event||Polymer.CaseMap.camelToDashCase(property)+\"-changed\";model._bindListeners.push({index:index,property:property,path:path,changedFn:fn,event:eventName})},_isEventBogus:function(e,target){return e.path&&e.path[0]!==target},_notedListenerFactory:function(property,\npath,isStructured,negated){return function(target,value,targetPath){if(targetPath){var newPath=Polymer.Path.translate(property,path,targetPath);this._notifyPath(newPath,value)}else{value=target[property];if(negated)value=!value;if(!isStructured)this[path]=value;else if(this.__data__[path]!=value)this.set(path,value)}}},prepareInstance:function(inst){inst.__data__=Object.create(null)},setupBindListeners:function(inst){var b$=inst._bindListeners;for(var i=0,l=b$.length,info;i<l&&(info=b$[i]);i++){var node=\ninst._nodes[info.index];this._addNotifyListener(node,inst,info.event,info.changedFn)}},_addNotifyListener:function(element,context,event,changedFn){element.addEventListener(event,function(e){return context._notifyListener(changedFn,e)})}};\nPolymer.Base.mixin(Polymer.Bind,{_shouldAddListener:function(effect){return effect.name&&effect.kind!=\"attribute\"&&effect.kind!=\"text\"&&!effect.isCompound&&effect.parts[0].mode===\"{\"},_annotationEffect:function(source,value,effect){if(source!=effect.value){value=this._get(effect.value);this.__data__[effect.value]=value}this._applyEffectValue(effect,value)},_reflectEffect:function(source,value,effect){this.reflectPropertyToAttribute(source,effect.attribute,value)},_notifyEffect:function(source,value,\neffect,old,fromAbove){if(!fromAbove)this._notifyChange(source,effect.event,value)},_functionEffect:function(source,value,fn,old,fromAbove){fn.call(this,source,value,old,fromAbove)},_observerEffect:function(source,value,effect,old){var fn=this[effect.method];if(fn)fn.call(this,value,old);else this._warn(this._logf(\"_observerEffect\",\"observer method `\"+effect.method+\"` not defined\"))},_complexObserverEffect:function(source,value,effect){var fn=this[effect.method];if(fn){var args=Polymer.Bind._marshalArgs(this.__data__,\neffect,source,value);if(args)fn.apply(this,args)}else if(effect.dynamicFn);else this._warn(this._logf(\"_complexObserverEffect\",\"observer method `\"+effect.method+\"` not defined\"))},_computeEffect:function(source,value,effect){var fn=this[effect.method];if(fn){var args=Polymer.Bind._marshalArgs(this.__data__,effect,source,value);if(args){var computedvalue=fn.apply(this,args);this.__setProperty(effect.name,computedvalue)}}else if(effect.dynamicFn);else this._warn(this._logf(\"_computeEffect\",\"compute method `\"+\neffect.method+\"` not defined\"))},_annotatedComputationEffect:function(source,value,effect){var computedHost=this._rootDataHost||this;var fn=computedHost[effect.method];if(fn){var args=Polymer.Bind._marshalArgs(this.__data__,effect,source,value);if(args){var computedvalue=fn.apply(computedHost,args);this._applyEffectValue(effect,computedvalue)}}else if(effect.dynamicFn);else computedHost._warn(computedHost._logf(\"_annotatedComputationEffect\",\"compute method `\"+effect.method+\"` not defined\"))},_marshalArgs:function(model,\neffect,path,value){var values=[];var args=effect.args;var bailoutEarly=args.length>1||effect.dynamicFn;for(var i=0,l=args.length;i<l;i++){var arg=args[i];var name=arg.name;var v;if(arg.literal)v=arg.value;else if(path===name)v=value;else{v=model[name];if(v===undefined&&arg.structured)v=Polymer.Base._get(name,model)}if(bailoutEarly&&v===undefined)return;if(arg.wildcard){var matches=Polymer.Path.isAncestor(path,name);values[i]={path:matches?path:name,value:matches?value:v,base:v}}else values[i]=v}return values}});\nPolymer.Base._addFeature({_addPropertyEffect:function(property,kind,effect){var prop=Polymer.Bind.addPropertyEffect(this,property,kind,effect);prop.pathFn=this[\"_\"+prop.kind+\"PathEffect\"]},_prepEffects:function(){Polymer.Bind.prepareModel(this);this._addAnnotationEffects(this._notes)},_prepBindings:function(){Polymer.Bind.createBindings(this)},_addPropertyEffects:function(properties){if(properties)for(var p in properties){var prop=properties[p];if(prop.observer)this._addObserverEffect(p,prop.observer);\nif(prop.computed){prop.readOnly=true;this._addComputedEffect(p,prop.computed)}if(prop.notify)this._addPropertyEffect(p,\"notify\",{event:Polymer.CaseMap.camelToDashCase(p)+\"-changed\"});if(prop.reflectToAttribute){var attr=Polymer.CaseMap.camelToDashCase(p);if(attr[0]===\"-\")this._warn(this._logf(\"_addPropertyEffects\",\"Property \"+p+\" cannot be reflected to attribute \"+attr+' because \"-\" is not a valid starting attribute name. Use a lowercase first letter for the property instead.'));else this._addPropertyEffect(p,\n\"reflect\",{attribute:attr})}if(prop.readOnly)Polymer.Bind.ensurePropertyEffects(this,p)}},_addComputedEffect:function(name,expression){var sig=this._parseMethod(expression);var dynamicFn=sig.dynamicFn;for(var i=0,arg;i<sig.args.length&&(arg=sig.args[i]);i++)this._addPropertyEffect(arg.model,\"compute\",{method:sig.method,args:sig.args,trigger:arg,name:name,dynamicFn:dynamicFn});if(dynamicFn)this._addPropertyEffect(sig.method,\"compute\",{method:sig.method,args:sig.args,trigger:null,name:name,dynamicFn:dynamicFn})},\n_addObserverEffect:function(property,observer){this._addPropertyEffect(property,\"observer\",{method:observer,property:property})},_addComplexObserverEffects:function(observers){if(observers)for(var i=0,o;i<observers.length&&(o=observers[i]);i++)this._addComplexObserverEffect(o)},_addComplexObserverEffect:function(observer){var sig=this._parseMethod(observer);if(!sig)throw new Error(\"Malformed observer expression '\"+observer+\"'\");var dynamicFn=sig.dynamicFn;for(var i=0,arg;i<sig.args.length&&(arg=sig.args[i]);i++)this._addPropertyEffect(arg.model,\n\"complexObserver\",{method:sig.method,args:sig.args,trigger:arg,dynamicFn:dynamicFn});if(dynamicFn)this._addPropertyEffect(sig.method,\"complexObserver\",{method:sig.method,args:sig.args,trigger:null,dynamicFn:dynamicFn})},_addAnnotationEffects:function(notes){for(var i=0,note;i<notes.length&&(note=notes[i]);i++){var b$=note.bindings;for(var j=0,binding;j<b$.length&&(binding=b$[j]);j++)this._addAnnotationEffect(binding,i)}},_addAnnotationEffect:function(note,index){if(Polymer.Bind._shouldAddListener(note))Polymer.Bind._addAnnotatedListener(this,\nindex,note.name,note.parts[0].value,note.parts[0].event,note.parts[0].negate);for(var i=0;i<note.parts.length;i++){var part=note.parts[i];if(part.signature)this._addAnnotatedComputationEffect(note,part,index);else if(!part.literal)if(note.kind===\"attribute\"&&note.name[0]===\"-\")this._warn(this._logf(\"_addAnnotationEffect\",\"Cannot set attribute \"+note.name+' because \"-\" is not a valid attribute starting character'));else this._addPropertyEffect(part.model,\"annotation\",{kind:note.kind,index:index,name:note.name,\npropertyName:note.propertyName,value:part.value,isCompound:note.isCompound,compoundIndex:part.compoundIndex,event:part.event,customEvent:part.customEvent,negate:part.negate})}},_addAnnotatedComputationEffect:function(note,part,index){var sig=part.signature;if(sig[\"static\"])this.__addAnnotatedComputationEffect(\"__static__\",index,note,part,null);else{for(var i=0,arg;i<sig.args.length&&(arg=sig.args[i]);i++)if(!arg.literal)this.__addAnnotatedComputationEffect(arg.model,index,note,part,arg);if(sig.dynamicFn)this.__addAnnotatedComputationEffect(sig.method,\nindex,note,part,null)}},__addAnnotatedComputationEffect:function(property,index,note,part,trigger){this._addPropertyEffect(property,\"annotatedComputation\",{index:index,isCompound:note.isCompound,compoundIndex:part.compoundIndex,kind:note.kind,name:note.name,negate:part.negate,method:part.signature.method,args:part.signature.args,trigger:trigger,dynamicFn:part.signature.dynamicFn})},_parseMethod:function(expression){var m=expression.match(/([^\\s]+?)\\(([\\s\\S]*)\\)/);if(m){var sig={method:m[1],\"static\":true};\nif(this.getPropertyInfo(sig.method)!==Polymer.nob){sig[\"static\"]=false;sig.dynamicFn=true}if(m[2].trim()){var args=m[2].replace(/\\\\,/g,\"&comma;\").split(\",\");return this._parseArgs(args,sig)}else{sig.args=Polymer.nar;return sig}}},_parseArgs:function(argList,sig){sig.args=argList.map(function(rawArg){var arg=this._parseArg(rawArg);if(!arg.literal)sig[\"static\"]=false;return arg},this);return sig},_parseArg:function(rawArg){var arg=rawArg.trim().replace(/&comma;/g,\",\").replace(/\\\\(.)/g,\"$1\");var a={name:arg};\nvar fc=arg[0];if(fc===\"-\")fc=arg[1];if(fc>=\"0\"&&fc<=\"9\")fc=\"#\";switch(fc){case \"'\":case '\"':a.value=arg.slice(1,-1);a.literal=true;break;case \"#\":a.value=Number(arg);a.literal=true;break}if(!a.literal){a.model=Polymer.Path.root(arg);a.structured=Polymer.Path.isDeep(arg);if(a.structured){a.wildcard=arg.slice(-2)==\".*\";if(a.wildcard)a.name=arg.slice(0,-2)}}return a},_marshalInstanceEffects:function(){Polymer.Bind.prepareInstance(this);if(this._bindListeners)Polymer.Bind.setupBindListeners(this)},_applyEffectValue:function(info,\nvalue){var node=this._nodes[info.index];var property=info.name;value=this._computeFinalAnnotationValue(node,property,value,info);if(info.kind==\"attribute\")this.serializeValueToAttribute(value,property,node);else{var pinfo=node._propertyInfo&&node._propertyInfo[property];if(pinfo&&pinfo.readOnly)return;this.__setProperty(property,value,Polymer.Settings.suppressBindingNotifications,node)}},_computeFinalAnnotationValue:function(node,property,value,info){if(info.negate)value=!value;if(info.isCompound){var storage=\nnode.__compoundStorage__[property];storage[info.compoundIndex]=value;value=storage.join(\"\")}if(info.kind!==\"attribute\"){if(property===\"className\")value=this._scopeElementClass(node,value);if(property===\"textContent\"||node.localName==\"input\"&&property==\"value\")value=value==undefined?\"\":value}return value},_executeStaticEffects:function(){if(this._propertyEffects&&this._propertyEffects.__static__)this._effectEffects(\"__static__\",null,this._propertyEffects.__static__)}});\n(function(){var usePolyfillProto=Polymer.Settings.usePolyfillProto;Polymer.Base._addFeature({_setupConfigure:function(initialConfig){this._config={};this._handlers=[];this._aboveConfig=null;if(initialConfig)for(var i in initialConfig)if(initialConfig[i]!==undefined)this._config[i]=initialConfig[i]},_marshalAttributes:function(){this._takeAttributesToModel(this._config)},_attributeChangedImpl:function(name){var model=this._clientsReadied?this:this._config;this._setAttributeToProperty(model,name)},\n_configValue:function(name,value){var info=this._propertyInfo[name];if(!info||!info.readOnly)this._config[name]=value},_beforeClientsReady:function(){this._configure()},_configure:function(){this._configureAnnotationReferences();this._configureInstanceProperties();this._aboveConfig=this.mixin({},this._config);var config={};for(var i=0;i<this.behaviors.length;i++)this._configureProperties(this.behaviors[i].properties,config);this._configureProperties(this.properties,config);this.mixin(config,this._aboveConfig);\nthis._config=config;if(this._clients&&this._clients.length)this._distributeConfig(this._config)},_configureInstanceProperties:function(){for(var i in this._propertyEffects)if(!usePolyfillProto&&this.hasOwnProperty(i)){this._configValue(i,this[i]);delete this[i]}},_configureProperties:function(properties,config){for(var i in properties){var c=properties[i];if(c.value!==undefined){var value=c.value;if(typeof value==\"function\")value=value.call(this,this._config);config[i]=value}}},_distributeConfig:function(config){var fx$=\nthis._propertyEffects;if(fx$)for(var p in config){var fx=fx$[p];if(fx)for(var i=0,l=fx.length,x;i<l&&(x=fx[i]);i++)if(x.kind===\"annotation\"){var node=this._nodes[x.effect.index];var name=x.effect.propertyName;var isAttr=x.effect.kind==\"attribute\";var hasEffect=node._propertyEffects&&node._propertyEffects[name];if(node._configValue&&(hasEffect||!isAttr)){var value=p===x.effect.value?config[p]:this._get(x.effect.value,config);value=this._computeFinalAnnotationValue(node,name,value,x.effect);if(isAttr)value=\nnode.deserialize(this.serialize(value),node._propertyInfo[name].type);node._configValue(name,value)}}}},_afterClientsReady:function(){this._executeStaticEffects();this._applyConfig(this._config,this._aboveConfig);this._flushHandlers()},_applyConfig:function(config,aboveConfig){for(var n in config)if(this[n]===undefined)this.__setProperty(n,config[n],n in aboveConfig)},_notifyListener:function(fn,e){if(!Polymer.Bind._isEventBogus(e,e.target)){var value,path;if(e.detail){value=e.detail.value;path=e.detail.path}if(!this._clientsReadied)this._queueHandler([fn,\ne.target,value,path]);else return fn.call(this,e.target,value,path)}},_queueHandler:function(args){this._handlers.push(args)},_flushHandlers:function(){var h$=this._handlers;for(var i=0,l=h$.length,h;i<l&&(h=h$[i]);i++)h[0].call(this,h[1],h[2],h[3]);this._handlers=[]}})})();\n(function(){var Path=Polymer.Path;Polymer.Base._addFeature({notifyPath:function(path,value,fromAbove){var info={};var v=this._get(path,this,info);if(arguments.length===1)value=v;if(info.path)this._notifyPath(info.path,value,fromAbove)},_notifyPath:function(path,value,fromAbove){var old=this._propertySetter(path,value);if(old!==value&&(old===old||value===value)){this._pathEffector(path,value);if(!fromAbove)this._notifyPathUp(path,value);return true}},_getPathParts:function(path){if(Array.isArray(path)){var parts=\n[];for(var i=0;i<path.length;i++){var args=path[i].toString().split(\".\");for(var j=0;j<args.length;j++)parts.push(args[j])}return parts}else return path.toString().split(\".\")},set:function(path,value,root){var prop=root||this;var parts=this._getPathParts(path);var array;var last=parts[parts.length-1];if(parts.length>1){for(var i=0;i<parts.length-1;i++){var part=parts[i];if(array&&part[0]==\"#\")prop=Polymer.Collection.get(array).getItem(part);else{prop=prop[part];if(array&&parseInt(part,10)==part)parts[i]=\nPolymer.Collection.get(array).getKey(prop)}if(!prop)return;array=Array.isArray(prop)?prop:null}if(array){var coll=Polymer.Collection.get(array);var old,key;if(last[0]==\"#\"){key=last;old=coll.getItem(key);last=array.indexOf(old);coll.setItem(key,value)}else if(parseInt(last,10)==last){old=prop[last];key=coll.getKey(old);parts[i]=key;coll.setItem(key,value)}}prop[last]=value;if(!root)this._notifyPath(parts.join(\".\"),value)}else prop[path]=value},get:function(path,root){return this._get(path,root)},\n_get:function(path,root,info){var prop=root||this;var parts=this._getPathParts(path);var array;for(var i=0;i<parts.length;i++){if(!prop)return;var part=parts[i];if(array&&part[0]==\"#\")prop=Polymer.Collection.get(array).getItem(part);else{prop=prop[part];if(info&&array&&parseInt(part,10)==part)parts[i]=Polymer.Collection.get(array).getKey(prop)}array=Array.isArray(prop)?prop:null}if(info)info.path=parts.join(\".\");return prop},_pathEffector:function(path,value){var model=Path.root(path);var fx$=this._propertyEffects&&\nthis._propertyEffects[model];if(fx$)for(var i=0,fx;i<fx$.length&&(fx=fx$[i]);i++){var fxFn=fx.pathFn;if(fxFn)fxFn.call(this,path,value,fx.effect)}if(this._boundPaths)this._notifyBoundPaths(path,value)},_annotationPathEffect:function(path,value,effect){if(Path.matches(effect.value,false,path))Polymer.Bind._annotationEffect.call(this,path,value,effect);else if(!effect.negate&&Path.isDescendant(effect.value,path)){var node=this._nodes[effect.index];if(node&&node._notifyPath){var newPath=Path.translate(effect.value,\neffect.name,path);node._notifyPath(newPath,value,true)}}},_complexObserverPathEffect:function(path,value,effect){if(Path.matches(effect.trigger.name,effect.trigger.wildcard,path))Polymer.Bind._complexObserverEffect.call(this,path,value,effect)},_computePathEffect:function(path,value,effect){if(Path.matches(effect.trigger.name,effect.trigger.wildcard,path))Polymer.Bind._computeEffect.call(this,path,value,effect)},_annotatedComputationPathEffect:function(path,value,effect){if(Path.matches(effect.trigger.name,\neffect.trigger.wildcard,path))Polymer.Bind._annotatedComputationEffect.call(this,path,value,effect)},linkPaths:function(to,from){this._boundPaths=this._boundPaths||{};if(from)this._boundPaths[to]=from;else this.unlinkPaths(to)},unlinkPaths:function(path){if(this._boundPaths)delete this._boundPaths[path]},_notifyBoundPaths:function(path,value){for(var a in this._boundPaths){var b=this._boundPaths[a];if(Path.isDescendant(a,path))this._notifyPath(Path.translate(a,b,path),value);else if(Path.isDescendant(b,\npath))this._notifyPath(Path.translate(b,a,path),value)}},_notifyPathUp:function(path,value){var rootName=Path.root(path);var dashCaseName=Polymer.CaseMap.camelToDashCase(rootName);var eventName=dashCaseName+this._EVENT_CHANGED;this.fire(eventName,{path:path,value:value},{bubbles:false,_useCache:Polymer.Settings.eventDataCache||!Polymer.Settings.isIE})},_EVENT_CHANGED:\"-changed\",notifySplices:function(path,splices){var info={};var array=this._get(path,this,info);this._notifySplices(array,info.path,\nsplices)},_notifySplices:function(array,path,splices){var change={keySplices:Polymer.Collection.applySplices(array,splices),indexSplices:splices};var splicesPath=path+\".splices\";this._notifyPath(splicesPath,change);this._notifyPath(path+\".length\",array.length);this.__data__[splicesPath]={keySplices:null,indexSplices:null}},_notifySplice:function(array,path,index,added,removed){this._notifySplices(array,path,[{index:index,addedCount:added,removed:removed,object:array,type:\"splice\"}])},push:function(path){var info=\n{};var array=this._get(path,this,info);var args=Array.prototype.slice.call(arguments,1);var len=array.length;var ret=array.push.apply(array,args);if(args.length)this._notifySplice(array,info.path,len,args.length,[]);return ret},pop:function(path){var info={};var array=this._get(path,this,info);var hadLength=Boolean(array.length);var args=Array.prototype.slice.call(arguments,1);var ret=array.pop.apply(array,args);if(hadLength)this._notifySplice(array,info.path,array.length,0,[ret]);return ret},splice:function(path,\nstart){var info={};var array=this._get(path,this,info);if(start<0)start=array.length-Math.floor(-start);else start=Math.floor(start);if(!start)start=0;var args=Array.prototype.slice.call(arguments,1);var ret=array.splice.apply(array,args);var addedCount=Math.max(args.length-2,0);if(addedCount||ret.length)this._notifySplice(array,info.path,start,addedCount,ret);return ret},shift:function(path){var info={};var array=this._get(path,this,info);var hadLength=Boolean(array.length);var args=Array.prototype.slice.call(arguments,\n1);var ret=array.shift.apply(array,args);if(hadLength)this._notifySplice(array,info.path,0,0,[ret]);return ret},unshift:function(path){var info={};var array=this._get(path,this,info);var args=Array.prototype.slice.call(arguments,1);var ret=array.unshift.apply(array,args);if(args.length)this._notifySplice(array,info.path,0,args.length,[]);return ret},prepareModelNotifyPath:function(model){this.mixin(model,{fire:Polymer.Base.fire,_getEvent:Polymer.Base._getEvent,__eventCache:Polymer.Base.__eventCache,\nnotifyPath:Polymer.Base.notifyPath,_get:Polymer.Base._get,_EVENT_CHANGED:Polymer.Base._EVENT_CHANGED,_notifyPath:Polymer.Base._notifyPath,_notifyPathUp:Polymer.Base._notifyPathUp,_pathEffector:Polymer.Base._pathEffector,_annotationPathEffect:Polymer.Base._annotationPathEffect,_complexObserverPathEffect:Polymer.Base._complexObserverPathEffect,_annotatedComputationPathEffect:Polymer.Base._annotatedComputationPathEffect,_computePathEffect:Polymer.Base._computePathEffect,_notifyBoundPaths:Polymer.Base._notifyBoundPaths,\n_getPathParts:Polymer.Base._getPathParts})}})})();Polymer.Base._addFeature({resolveUrl:function(url){var module=Polymer.DomModule[\"import\"](this.is);var root=\"\";if(module){var assetPath=module.getAttribute(\"assetpath\")||\"\";root=Polymer.ResolveUrl.resolveUrl(assetPath,module.ownerDocument.baseURI)}return Polymer.ResolveUrl.resolveUrl(url,root)}});\nPolymer.CssParse=function(){return{parse:function(text){text=this._clean(text);return this._parseCss(this._lex(text),text)},_clean:function(cssText){return cssText.replace(this._rx.comments,\"\").replace(this._rx.port,\"\")},_lex:function(text){var root={start:0,end:text.length};var n=root;for(var i=0,l=text.length;i<l;i++)switch(text[i]){case this.OPEN_BRACE:if(!n.rules)n.rules=[];var p=n;var previous=p.rules[p.rules.length-1];n={start:i+1,parent:p,previous:previous};p.rules.push(n);break;case this.CLOSE_BRACE:n.end=\ni+1;n=n.parent||root;break}return root},_parseCss:function(node,text){var t=text.substring(node.start,node.end-1);node.parsedCssText=node.cssText=t.trim();if(node.parent){var ss=node.previous?node.previous.end:node.parent.start;t=text.substring(ss,node.start-1);t=this._expandUnicodeEscapes(t);t=t.replace(this._rx.multipleSpaces,\" \");t=t.substring(t.lastIndexOf(\";\")+1);var s=node.parsedSelector=node.selector=t.trim();node.atRule=s.indexOf(this.AT_START)===0;if(node.atRule)if(s.indexOf(this.MEDIA_START)===\n0)node.type=this.types.MEDIA_RULE;else{if(s.match(this._rx.keyframesRule)){node.type=this.types.KEYFRAMES_RULE;node.keyframesName=node.selector.split(this._rx.multipleSpaces).pop()}}else if(s.indexOf(this.VAR_START)===0)node.type=this.types.MIXIN_RULE;else node.type=this.types.STYLE_RULE}var r$=node.rules;if(r$)for(var i=0,l=r$.length,r;i<l&&(r=r$[i]);i++)this._parseCss(r,text);return node},_expandUnicodeEscapes:function(s){return s.replace(/\\\\([0-9a-f]{1,6})\\s/gi,function(){var code=arguments[1],\nrepeat=6-code.length;while(repeat--)code=\"0\"+code;return\"\\\\\"+code})},stringify:function(node,preserveProperties,text){text=text||\"\";var cssText=\"\";if(node.cssText||node.rules){var r$=node.rules;if(r$&&!this._hasMixinRules(r$))for(var i=0,l=r$.length,r;i<l&&(r=r$[i]);i++)cssText=this.stringify(r,preserveProperties,cssText);else{cssText=preserveProperties?node.cssText:this.removeCustomProps(node.cssText);cssText=cssText.trim();if(cssText)cssText=\"  \"+cssText+\"\\n\"}}if(cssText){if(node.selector)text+=\nnode.selector+\" \"+this.OPEN_BRACE+\"\\n\";text+=cssText;if(node.selector)text+=this.CLOSE_BRACE+\"\\n\\n\"}return text},_hasMixinRules:function(rules){return rules[0].selector.indexOf(this.VAR_START)===0},removeCustomProps:function(cssText){cssText=this.removeCustomPropAssignment(cssText);return this.removeCustomPropApply(cssText)},removeCustomPropAssignment:function(cssText){return cssText.replace(this._rx.customProp,\"\").replace(this._rx.mixinProp,\"\")},removeCustomPropApply:function(cssText){return cssText.replace(this._rx.mixinApply,\n\"\").replace(this._rx.varApply,\"\")},types:{STYLE_RULE:1,KEYFRAMES_RULE:7,MEDIA_RULE:4,MIXIN_RULE:1E3},OPEN_BRACE:\"{\",CLOSE_BRACE:\"}\",_rx:{comments:/\\/\\*[^*]*\\*+([^\\/*][^*]*\\*+)*\\//gim,port:/@import[^;]*;/gim,customProp:/(?:^[^;\\-\\s}]+)?--[^;{}]*?:[^{};]*?(?:[;\\n]|$)/gim,mixinProp:/(?:^[^;\\-\\s}]+)?--[^;{}]*?:[^{};]*?{[^}]*?}(?:[;\\n]|$)?/gim,mixinApply:/@apply\\s*\\(?[^);]*\\)?\\s*(?:[;\\n]|$)?/gim,varApply:/[^;:]*?:[^;]*?var\\([^;]*\\)(?:[;\\n]|$)?/gim,keyframesRule:/^@[^\\s]*keyframes/,multipleSpaces:/\\s+/g},\nVAR_START:\"--\",MEDIA_START:\"@media\",AT_START:\"@\"}}();\nPolymer.StyleUtil=function(){var settings=Polymer.Settings;return{NATIVE_VARIABLES:Polymer.Settings.useNativeCSSProperties,MODULE_STYLES_SELECTOR:\"style, link[rel=import][type~=css], template\",INCLUDE_ATTR:\"include\",toCssText:function(rules,callback){if(typeof rules===\"string\")rules=this.parser.parse(rules);if(callback)this.forEachRule(rules,callback);return this.parser.stringify(rules,this.NATIVE_VARIABLES)},forRulesInStyles:function(styles,styleRuleCallback,keyframesRuleCallback){if(styles)for(var i=\n0,l=styles.length,s;i<l&&(s=styles[i]);i++)this.forEachRuleInStyle(s,styleRuleCallback,keyframesRuleCallback)},forActiveRulesInStyles:function(styles,styleRuleCallback,keyframesRuleCallback){if(styles)for(var i=0,l=styles.length,s;i<l&&(s=styles[i]);i++)this.forEachRuleInStyle(s,styleRuleCallback,keyframesRuleCallback,true)},rulesForStyle:function(style){if(!style.__cssRules&&style.textContent)style.__cssRules=this.parser.parse(style.textContent);return style.__cssRules},isKeyframesSelector:function(rule){return rule.parent&&\nrule.parent.type===this.ruleTypes.KEYFRAMES_RULE},forEachRuleInStyle:function(style,styleRuleCallback,keyframesRuleCallback,onlyActiveRules){var rules=this.rulesForStyle(style);var styleCallback,keyframeCallback;if(styleRuleCallback)styleCallback=function(rule){styleRuleCallback(rule,style)};if(keyframesRuleCallback)keyframeCallback=function(rule){keyframesRuleCallback(rule,style)};this.forEachRule(rules,styleCallback,keyframeCallback,onlyActiveRules)},forEachRule:function(node,styleRuleCallback,\nkeyframesRuleCallback,onlyActiveRules){if(!node)return;var skipRules=false;if(onlyActiveRules)if(node.type===this.ruleTypes.MEDIA_RULE){var matchMedia=node.selector.match(this.rx.MEDIA_MATCH);if(matchMedia)if(!window.matchMedia(matchMedia[1]).matches)skipRules=true}if(node.type===this.ruleTypes.STYLE_RULE)styleRuleCallback(node);else if(keyframesRuleCallback&&node.type===this.ruleTypes.KEYFRAMES_RULE)keyframesRuleCallback(node);else if(node.type===this.ruleTypes.MIXIN_RULE)skipRules=true;var r$=node.rules;\nif(r$&&!skipRules)for(var i=0,l=r$.length,r;i<l&&(r=r$[i]);i++)this.forEachRule(r,styleRuleCallback,keyframesRuleCallback,onlyActiveRules)},applyCss:function(cssText,moniker,target,contextNode){var style=this.createScopeStyle(cssText,moniker);return this.applyStyle(style,target,contextNode)},applyStyle:function(style,target,contextNode){target=target||document.head;var after=contextNode&&contextNode.nextSibling||target.firstChild;this.__lastHeadApplyNode=style;return target.insertBefore(style,after)},\ncreateScopeStyle:function(cssText,moniker){var style=document.createElement(\"style\");if(moniker)style.setAttribute(\"scope\",moniker);style.textContent=cssText;return style},__lastHeadApplyNode:null,applyStylePlaceHolder:function(moniker){var placeHolder=document.createComment(\" Shady DOM styles for \"+moniker+\" \");var after=this.__lastHeadApplyNode?this.__lastHeadApplyNode.nextSibling:null;var scope=document.head;scope.insertBefore(placeHolder,after||scope.firstChild);this.__lastHeadApplyNode=placeHolder;\nreturn placeHolder},cssFromModules:function(moduleIds,warnIfNotFound){var modules=moduleIds.trim().split(\" \");var cssText=\"\";for(var i=0;i<modules.length;i++)cssText+=this.cssFromModule(modules[i],warnIfNotFound);return cssText},cssFromModule:function(moduleId,warnIfNotFound){var m=Polymer.DomModule[\"import\"](moduleId);if(m&&!m._cssText)m._cssText=this.cssFromElement(m);if(!m&&warnIfNotFound)console.warn(\"Could not find style data in module named\",moduleId);return m&&m._cssText||\"\"},cssFromElement:function(element){var cssText=\n\"\";var content=element.content||element;var e$=Polymer.TreeApi.arrayCopy(content.querySelectorAll(this.MODULE_STYLES_SELECTOR));for(var i=0,e;i<e$.length;i++){e=e$[i];if(e.localName===\"template\"){if(!e.hasAttribute(\"preserve-content\"))cssText+=this.cssFromElement(e)}else if(e.localName===\"style\"){var include=e.getAttribute(this.INCLUDE_ATTR);if(include)cssText+=this.cssFromModules(include,true);e=e.__appliedElement||e;e.parentNode.removeChild(e);cssText+=this.resolveCss(e.textContent,element.ownerDocument)}else if(e[\"import\"]&&\ne[\"import\"].body)cssText+=this.resolveCss(e[\"import\"].body.textContent,e[\"import\"])}return cssText},isTargetedBuild:function(buildType){return settings.useNativeShadow?buildType===\"shadow\":buildType===\"shady\"},cssBuildTypeForModule:function(module){var dm=Polymer.DomModule[\"import\"](module);if(dm)return this.getCssBuildType(dm)},getCssBuildType:function(element){return element.getAttribute(\"css-build\")},_findMatchingParen:function(text,start){var level=0;for(var i=start,l=text.length;i<l;i++)switch(text[i]){case \"(\":level++;\nbreak;case \")\":if(--level===0)return i;break}return-1},processVariableAndFallback:function(str,callback){var start=str.indexOf(\"var(\");if(start===-1)return callback(str,\"\",\"\",\"\");var end=this._findMatchingParen(str,start+3);var inner=str.substring(start+4,end);var prefix=str.substring(0,start);var suffix=this.processVariableAndFallback(str.substring(end+1),callback);var comma=inner.indexOf(\",\");if(comma===-1)return callback(prefix,inner.trim(),\"\",suffix);var value=inner.substring(0,comma).trim();\nvar fallback=inner.substring(comma+1).trim();return callback(prefix,value,fallback,suffix)},rx:{VAR_ASSIGN:/(?:^|[;\\s{]\\s*)(--[\\w-]*?)\\s*:\\s*(?:([^;{]*)|{([^}]*)})(?:(?=[;\\s}])|$)/gi,MIXIN_MATCH:/(?:^|\\W+)@apply\\s*\\(?([^);\\n]*)\\)?/gi,VAR_CONSUMED:/(--[\\w-]+)\\s*([:,;)]|$)/gi,ANIMATION_MATCH:/(animation\\s*:)|(animation-name\\s*:)/,MEDIA_MATCH:/@media[^(]*(\\([^)]*\\))/,IS_VAR:/^--/,BRACKETED:/\\{[^}]*\\}/g,HOST_PREFIX:\"(?:^|[^.#[:])\",HOST_SUFFIX:\"($|[.:[\\\\s>+~])\"},resolveCss:Polymer.ResolveUrl.resolveCss,\nparser:Polymer.CssParse,ruleTypes:Polymer.CssParse.types}}();\nPolymer.StyleTransformer=function(){var styleUtil=Polymer.StyleUtil;var settings=Polymer.Settings;var api={dom:function(node,scope,useAttr,shouldRemoveScope){this._transformDom(node,scope||\"\",useAttr,shouldRemoveScope)},_transformDom:function(node,selector,useAttr,shouldRemoveScope){if(node.setAttribute)this.element(node,selector,useAttr,shouldRemoveScope);var c$=Polymer.dom(node).childNodes;for(var i=0;i<c$.length;i++)this._transformDom(c$[i],selector,useAttr,shouldRemoveScope)},element:function(element,\nscope,useAttr,shouldRemoveScope){if(useAttr)if(shouldRemoveScope)element.removeAttribute(SCOPE_NAME);else element.setAttribute(SCOPE_NAME,scope);else if(scope)if(element.classList)if(shouldRemoveScope){element.classList.remove(SCOPE_NAME);element.classList.remove(scope)}else{element.classList.add(SCOPE_NAME);element.classList.add(scope)}else if(element.getAttribute){var c=element.getAttribute(CLASS);if(shouldRemoveScope){if(c)element.setAttribute(CLASS,c.replace(SCOPE_NAME,\"\").replace(scope,\"\"))}else element.setAttribute(CLASS,\n(c?c+\" \":\"\")+SCOPE_NAME+\" \"+scope)}},elementStyles:function(element,callback){var styles=element._styles;var cssText=\"\";var cssBuildType=element.__cssBuild;var passthrough=settings.useNativeShadow||cssBuildType===\"shady\";var cb;if(passthrough){var self=this;cb=function(rule){rule.selector=self._slottedToContent(rule.selector);rule.selector=rule.selector.replace(ROOT,\":host > *\");if(callback)callback(rule)}}for(var i=0,l=styles.length,s;i<l&&(s=styles[i]);i++){var rules=styleUtil.rulesForStyle(s);\ncssText+=passthrough?styleUtil.toCssText(rules,cb):this.css(rules,element.is,element[\"extends\"],callback,element._scopeCssViaAttr)+\"\\n\\n\"}return cssText.trim()},css:function(rules,scope,ext,callback,useAttr){var hostScope=this._calcHostScope(scope,ext);scope=this._calcElementScope(scope,useAttr);var self=this;return styleUtil.toCssText(rules,function(rule){if(!rule.isScoped){self.rule(rule,scope,hostScope);rule.isScoped=true}if(callback)callback(rule,scope,hostScope)})},_calcElementScope:function(scope,\nuseAttr){if(scope)return useAttr?CSS_ATTR_PREFIX+scope+CSS_ATTR_SUFFIX:CSS_CLASS_PREFIX+scope;else return\"\"},_calcHostScope:function(scope,ext){return ext?\"[is=\"+scope+\"]\":scope},rule:function(rule,scope,hostScope){this._transformRule(rule,this._transformComplexSelector,scope,hostScope)},_transformRule:function(rule,transformer,scope,hostScope){rule.selector=rule.transformedSelector=this._transformRuleCss(rule,transformer,scope,hostScope)},_transformRuleCss:function(rule,transformer,scope,hostScope){var p$=\nrule.selector.split(COMPLEX_SELECTOR_SEP);if(!styleUtil.isKeyframesSelector(rule))for(var i=0,l=p$.length,p;i<l&&(p=p$[i]);i++)p$[i]=transformer.call(this,p,scope,hostScope);return p$.join(COMPLEX_SELECTOR_SEP)},_transformComplexSelector:function(selector,scope,hostScope){var stop=false;var hostContext=false;var self=this;selector=selector.trim();selector=this._slottedToContent(selector);selector=selector.replace(ROOT,\":host > *\");selector=selector.replace(CONTENT_START,HOST+\" $1\");selector=selector.replace(SIMPLE_SELECTOR_SEP,\nfunction(m,c,s){if(!stop){var info=self._transformCompoundSelector(s,c,scope,hostScope);stop=stop||info.stop;hostContext=hostContext||info.hostContext;c=info.combinator;s=info.value}else s=s.replace(SCOPE_JUMP,\" \");return c+s});if(hostContext)selector=selector.replace(HOST_CONTEXT_PAREN,function(m,pre,paren,post){return pre+paren+\" \"+hostScope+post+COMPLEX_SELECTOR_SEP+\" \"+pre+hostScope+paren+post});return selector},_transformCompoundSelector:function(selector,combinator,scope,hostScope){var jumpIndex=\nselector.search(SCOPE_JUMP);var hostContext=false;if(selector.indexOf(HOST_CONTEXT)>=0)hostContext=true;else if(selector.indexOf(HOST)>=0)selector=this._transformHostSelector(selector,hostScope);else if(jumpIndex!==0)selector=scope?this._transformSimpleSelector(selector,scope):selector;if(selector.indexOf(CONTENT)>=0)combinator=\"\";var stop;if(jumpIndex>=0){selector=selector.replace(SCOPE_JUMP,\" \");stop=true}return{value:selector,combinator:combinator,stop:stop,hostContext:hostContext}},_transformSimpleSelector:function(selector,\nscope){var p$=selector.split(PSEUDO_PREFIX);p$[0]+=scope;return p$.join(PSEUDO_PREFIX)},_transformHostSelector:function(selector,hostScope){var m=selector.match(HOST_PAREN);var paren=m&&m[2].trim()||\"\";if(paren)if(!paren[0].match(SIMPLE_SELECTOR_PREFIX)){var typeSelector=paren.split(SIMPLE_SELECTOR_PREFIX)[0];if(typeSelector===hostScope)return paren;else return SELECTOR_NO_MATCH}else return selector.replace(HOST_PAREN,function(m,host,paren){return hostScope+paren});else return selector.replace(HOST,\nhostScope)},documentRule:function(rule){rule.selector=rule.parsedSelector;this.normalizeRootSelector(rule);if(!settings.useNativeShadow)this._transformRule(rule,this._transformDocumentSelector)},normalizeRootSelector:function(rule){rule.selector=rule.selector.replace(ROOT,\"html\")},_transformDocumentSelector:function(selector){return selector.match(SCOPE_JUMP)?this._transformComplexSelector(selector,SCOPE_DOC_SELECTOR):this._transformSimpleSelector(selector.trim(),SCOPE_DOC_SELECTOR)},_slottedToContent:function(cssText){return cssText.replace(SLOTTED_PAREN,\nCONTENT+\"> $1\")},SCOPE_NAME:\"style-scope\"};var SCOPE_NAME=api.SCOPE_NAME;var SCOPE_DOC_SELECTOR=\":not([\"+SCOPE_NAME+\"])\"+\":not(.\"+SCOPE_NAME+\")\";var COMPLEX_SELECTOR_SEP=\",\";var SIMPLE_SELECTOR_SEP=/(^|[\\s>+~]+)((?:\\[.+?\\]|[^\\s>+~=\\[])+)/g;var SIMPLE_SELECTOR_PREFIX=/[[.:#*]/;var HOST=\":host\";var ROOT=\":root\";var HOST_PAREN=/(:host)(?:\\(((?:\\([^)(]*\\)|[^)(]*)+?)\\))/;var HOST_CONTEXT=\":host-context\";var HOST_CONTEXT_PAREN=/(.*)(?::host-context)(?:\\(((?:\\([^)(]*\\)|[^)(]*)+?)\\))(.*)/;var CONTENT=\"::content\";\nvar SCOPE_JUMP=/::content|::shadow|\\/deep\\//;var CSS_CLASS_PREFIX=\".\";var CSS_ATTR_PREFIX=\"[\"+SCOPE_NAME+\"~=\";var CSS_ATTR_SUFFIX=\"]\";var PSEUDO_PREFIX=\":\";var CLASS=\"class\";var CONTENT_START=new RegExp(\"^(\"+CONTENT+\")\");var SELECTOR_NO_MATCH=\"should_not_match\";var SLOTTED_PAREN=/(?:::slotted)(?:\\(((?:\\([^)(]*\\)|[^)(]*)+?)\\))/g;return api}();\nPolymer.StyleExtends=function(){var styleUtil=Polymer.StyleUtil;return{hasExtends:function(cssText){return Boolean(cssText.match(this.rx.EXTEND))},transform:function(style){var rules=styleUtil.rulesForStyle(style);var self=this;styleUtil.forEachRule(rules,function(rule){self._mapRuleOntoParent(rule);if(rule.parent){var m;while(m=self.rx.EXTEND.exec(rule.cssText)){var extend=m[1];var extendor=self._findExtendor(extend,rule);if(extendor)self._extendRule(rule,extendor)}}rule.cssText=rule.cssText.replace(self.rx.EXTEND,\n\"\")});return styleUtil.toCssText(rules,function(rule){if(rule.selector.match(self.rx.STRIP))rule.cssText=\"\"},true)},_mapRuleOntoParent:function(rule){if(rule.parent){var map=rule.parent.map||(rule.parent.map={});var parts=rule.selector.split(\",\");for(var i=0,p;i<parts.length;i++){p=parts[i];map[p.trim()]=rule}return map}},_findExtendor:function(extend,rule){return rule.parent&&rule.parent.map&&rule.parent.map[extend]||this._findExtendor(extend,rule.parent)},_extendRule:function(target,source){if(target.parent!==\nsource.parent)this._cloneAndAddRuleToParent(source,target.parent);target[\"extends\"]=target[\"extends\"]||[];target[\"extends\"].push(source);source.selector=source.selector.replace(this.rx.STRIP,\"\");source.selector=(source.selector&&source.selector+\",\\n\")+target.selector;if(source[\"extends\"])source[\"extends\"].forEach(function(e){this._extendRule(target,e)},this)},_cloneAndAddRuleToParent:function(rule,parent){rule=Object.create(rule);rule.parent=parent;if(rule[\"extends\"])rule[\"extends\"]=rule[\"extends\"].slice();\nparent.rules.push(rule)},rx:{EXTEND:/@extends\\(([^)]*)\\)\\s*?;/gim,STRIP:/%[^,]*$/}}}();\nPolymer.ApplyShim=function(){var styleUtil=Polymer.StyleUtil;var MIXIN_MATCH=styleUtil.rx.MIXIN_MATCH;var VAR_ASSIGN=styleUtil.rx.VAR_ASSIGN;var BAD_VAR=/var\\(\\s*(--[^,]*),\\s*(--[^)]*)\\)/g;var APPLY_NAME_CLEAN=/;\\s*/m;var INITIAL_INHERIT=/^\\s*(initial)|(inherit)\\s*$/;var MIXIN_VAR_SEP=\"_-_\";var mixinMap={};function mapSet(name,props){name=name.trim();mixinMap[name]={properties:props,dependants:{}}}function mapGet(name){name=name.trim();return mixinMap[name]}function replaceInitialOrInherit(property,\nvalue){var match=INITIAL_INHERIT.exec(value);if(match)if(match[1])value=ApplyShim._getInitialValueForProperty(property);else value=\"apply-shim-inherit\";return value}function cssTextToMap(text){var props=text.split(\";\");var property,value;var out={};for(var i=0,p,sp;i<props.length;i++){p=props[i];if(p){sp=p.split(\":\");if(sp.length>1){property=sp[0].trim();value=replaceInitialOrInherit(property,sp.slice(1).join(\":\"));out[property]=value}}}return out}function invalidateMixinEntry(mixinEntry){var currentProto=\nApplyShim.__currentElementProto;var currentElementName=currentProto&&currentProto.is;for(var elementName in mixinEntry.dependants)if(elementName!==currentElementName)mixinEntry.dependants[elementName].__applyShimInvalid=true}function produceCssProperties(matchText,propertyName,valueProperty,valueMixin){if(valueProperty)styleUtil.processVariableAndFallback(valueProperty,function(prefix,value){if(value&&mapGet(value))valueMixin=\"@apply \"+value+\";\"});if(!valueMixin)return matchText;var mixinAsProperties=\nconsumeCssProperties(valueMixin);var prefix=matchText.slice(0,matchText.indexOf(\"--\"));var mixinValues=cssTextToMap(mixinAsProperties);var combinedProps=mixinValues;var mixinEntry=mapGet(propertyName);var oldProps=mixinEntry&&mixinEntry.properties;if(oldProps){combinedProps=Object.create(oldProps);combinedProps=Polymer.Base.mixin(combinedProps,mixinValues)}else mapSet(propertyName,combinedProps);var out=[];var p,v;var needToInvalidate=false;for(p in combinedProps){v=mixinValues[p];if(v===undefined)v=\n\"initial\";if(oldProps&&!(p in oldProps))needToInvalidate=true;out.push(propertyName+MIXIN_VAR_SEP+p+\": \"+v)}if(needToInvalidate)invalidateMixinEntry(mixinEntry);if(mixinEntry)mixinEntry.properties=combinedProps;if(valueProperty)prefix=matchText+\";\"+prefix;return prefix+out.join(\"; \")+\";\"}function fixVars(matchText,varA,varB){return\"var(\"+varA+\",\"+\"var(\"+varB+\"))\"}function atApplyToCssProperties(mixinName,fallbacks){mixinName=mixinName.replace(APPLY_NAME_CLEAN,\"\");var vars=[];var mixinEntry=mapGet(mixinName);\nif(!mixinEntry){mapSet(mixinName,{});mixinEntry=mapGet(mixinName)}if(mixinEntry){var currentProto=ApplyShim.__currentElementProto;if(currentProto)mixinEntry.dependants[currentProto.is]=currentProto;var p,parts,f;for(p in mixinEntry.properties){f=fallbacks&&fallbacks[p];parts=[p,\": var(\",mixinName,MIXIN_VAR_SEP,p];if(f)parts.push(\",\",f);parts.push(\")\");vars.push(parts.join(\"\"))}}return vars.join(\"; \")}function consumeCssProperties(text){var m;while(m=MIXIN_MATCH.exec(text)){var matchText=m[0];var mixinName=\nm[1];var idx=m.index;var applyPos=idx+matchText.indexOf(\"@apply\");var afterApplyPos=idx+matchText.length;var textBeforeApply=text.slice(0,applyPos);var textAfterApply=text.slice(afterApplyPos);var defaults=cssTextToMap(textBeforeApply);var replacement=atApplyToCssProperties(mixinName,defaults);text=[textBeforeApply,replacement,textAfterApply].join(\"\");MIXIN_MATCH.lastIndex=idx+replacement.length}return text}var ApplyShim={_measureElement:null,_map:mixinMap,_separator:MIXIN_VAR_SEP,transform:function(styles,\nelementProto){this.__currentElementProto=elementProto;styleUtil.forRulesInStyles(styles,this._boundFindDefinitions);styleUtil.forRulesInStyles(styles,this._boundFindApplications);if(elementProto)elementProto.__applyShimInvalid=false;this.__currentElementProto=null},_findDefinitions:function(rule){var cssText=rule.parsedCssText;cssText=cssText.replace(BAD_VAR,fixVars);cssText=cssText.replace(VAR_ASSIGN,produceCssProperties);rule.cssText=cssText;if(rule.selector===\":root\")rule.selector=\":host > *\"},\n_findApplications:function(rule){rule.cssText=consumeCssProperties(rule.cssText)},transformRule:function(rule){this._findDefinitions(rule);this._findApplications(rule)},_getInitialValueForProperty:function(property){if(!this._measureElement){this._measureElement=document.createElement(\"meta\");this._measureElement.style.all=\"initial\";document.head.appendChild(this._measureElement)}return window.getComputedStyle(this._measureElement).getPropertyValue(property)}};ApplyShim._boundTransformRule=ApplyShim.transformRule.bind(ApplyShim);\nApplyShim._boundFindDefinitions=ApplyShim._findDefinitions.bind(ApplyShim);ApplyShim._boundFindApplications=ApplyShim._findApplications.bind(ApplyShim);return ApplyShim}();\n(function(){var prepElement=Polymer.Base._prepElement;var nativeShadow=Polymer.Settings.useNativeShadow;var styleUtil=Polymer.StyleUtil;var styleTransformer=Polymer.StyleTransformer;var styleExtends=Polymer.StyleExtends;var applyShim=Polymer.ApplyShim;var settings=Polymer.Settings;Polymer.Base._addFeature({_prepElement:function(element){if(this._encapsulateStyle&&this.__cssBuild!==\"shady\")styleTransformer.element(element,this.is,this._scopeCssViaAttr);prepElement.call(this,element)},_prepStyles:function(){if(this._encapsulateStyle===\nundefined)this._encapsulateStyle=!nativeShadow;if(!nativeShadow)this._scopeStyle=styleUtil.applyStylePlaceHolder(this.is);this.__cssBuild=styleUtil.cssBuildTypeForModule(this.is)},_prepShimStyles:function(){if(this._template){var hasTargetedCssBuild=styleUtil.isTargetedBuild(this.__cssBuild);if(settings.useNativeCSSProperties&&this.__cssBuild===\"shadow\"&&hasTargetedCssBuild)return;this._styles=this._styles||this._collectStyles();if(settings.useNativeCSSProperties&&!this.__cssBuild)applyShim.transform(this._styles,\nthis);var cssText=settings.useNativeCSSProperties&&hasTargetedCssBuild?this._styles.length&&this._styles[0].textContent.trim():styleTransformer.elementStyles(this);this._prepStyleProperties();if(!this._needsStyleProperties()&&cssText)styleUtil.applyCss(cssText,this.is,nativeShadow?this._template.content:null,this._scopeStyle)}else this._styles=[]},_collectStyles:function(){var styles=[];var cssText=\"\",m$=this.styleModules;if(m$)for(var i=0,l=m$.length,m;i<l&&(m=m$[i]);i++)cssText+=styleUtil.cssFromModule(m);\ncssText+=styleUtil.cssFromModule(this.is);var p=this._template&&this._template.parentNode;if(this._template&&(!p||p.id.toLowerCase()!==this.is))cssText+=styleUtil.cssFromElement(this._template);if(cssText){var style=document.createElement(\"style\");style.textContent=cssText;if(styleExtends.hasExtends(style.textContent))cssText=styleExtends.transform(style);styles.push(style)}return styles},_elementAdd:function(node){if(this._encapsulateStyle)if(node.__styleScoped)node.__styleScoped=false;else styleTransformer.dom(node,\nthis.is,this._scopeCssViaAttr)},_elementRemove:function(node){if(this._encapsulateStyle)styleTransformer.dom(node,this.is,this._scopeCssViaAttr,true)},scopeSubtree:function(container,shouldObserve){if(nativeShadow)return;var self=this;var scopify=function(node){if(node.nodeType===Node.ELEMENT_NODE){var className=node.getAttribute(\"class\");node.setAttribute(\"class\",self._scopeElementClass(node,className));var n$=node.querySelectorAll(\"*\");for(var i=0,n;i<n$.length&&(n=n$[i]);i++){className=n.getAttribute(\"class\");\nn.setAttribute(\"class\",self._scopeElementClass(n,className))}}};scopify(container);if(shouldObserve){var mo=new MutationObserver(function(mxns){for(var i=0,m;i<mxns.length&&(m=mxns[i]);i++)if(m.addedNodes)for(var j=0;j<m.addedNodes.length;j++)scopify(m.addedNodes[j])});mo.observe(container,{childList:true,subtree:true});return mo}}})})();\nPolymer.StyleProperties=function(){var matchesSelector=Polymer.DomApi.matchesSelector;var styleUtil=Polymer.StyleUtil;var styleTransformer=Polymer.StyleTransformer;var IS_IE=navigator.userAgent.match(\"Trident\");var settings=Polymer.Settings;return{decorateStyles:function(styles,scope){var self=this,props={},keyframes=[],ruleIndex=0;var scopeSelector=styleTransformer._calcHostScope(scope.is,scope[\"extends\"]);styleUtil.forRulesInStyles(styles,function(rule,style){self.decorateRule(rule);rule.index=\nruleIndex++;self.whenHostOrRootRule(scope,rule,style,function(info){if(rule.parent.type===styleUtil.ruleTypes.MEDIA_RULE)scope.__notStyleScopeCacheable=true;if(info.isHost){var hostContextOrFunction=info.selector.split(\" \").some(function(s){return s.indexOf(scopeSelector)===0&&s.length!==scopeSelector.length});scope.__notStyleScopeCacheable=scope.__notStyleScopeCacheable||hostContextOrFunction}});self.collectPropertiesInCssText(rule.propertyInfo.cssText,props)},function onKeyframesRule(rule){keyframes.push(rule)});\nstyles._keyframes=keyframes;var names=[];for(var i in props)names.push(i);return names},decorateRule:function(rule){if(rule.propertyInfo)return rule.propertyInfo;var info={},properties={};var hasProperties=this.collectProperties(rule,properties);if(hasProperties){info.properties=properties;rule.rules=null}info.cssText=this.collectCssText(rule);rule.propertyInfo=info;return info},collectProperties:function(rule,properties){var info=rule.propertyInfo;if(info){if(info.properties){Polymer.Base.mixin(properties,\ninfo.properties);return true}}else{var m,rx=this.rx.VAR_ASSIGN;var cssText=rule.parsedCssText;var value;var any;while(m=rx.exec(cssText)){value=(m[2]||m[3]).trim();if(value!==\"inherit\")properties[m[1].trim()]=value;any=true}return any}},collectCssText:function(rule){return this.collectConsumingCssText(rule.parsedCssText)},collectConsumingCssText:function(cssText){return cssText.replace(this.rx.BRACKETED,\"\").replace(this.rx.VAR_ASSIGN,\"\")},collectPropertiesInCssText:function(cssText,props){var m;while(m=\nthis.rx.VAR_CONSUMED.exec(cssText)){var name=m[1];if(m[2]!==\":\")props[name]=true}},reify:function(props){var names=Object.getOwnPropertyNames(props);for(var i=0,n;i<names.length;i++){n=names[i];props[n]=this.valueForProperty(props[n],props)}},valueForProperty:function(property,props){if(property)if(property.indexOf(\";\")>=0)property=this.valueForProperties(property,props);else{var self=this;var fn=function(prefix,value,fallback,suffix){var propertyValue=self.valueForProperty(props[value],props);if(!propertyValue||\npropertyValue===\"initial\")propertyValue=self.valueForProperty(props[fallback]||fallback,props)||fallback;else if(propertyValue===\"apply-shim-inherit\")propertyValue=\"inherit\";return prefix+(propertyValue||\"\")+suffix};property=styleUtil.processVariableAndFallback(property,fn)}return property&&property.trim()||\"\"},valueForProperties:function(property,props){var parts=property.split(\";\");for(var i=0,p,m;i<parts.length;i++)if(p=parts[i]){this.rx.MIXIN_MATCH.lastIndex=0;m=this.rx.MIXIN_MATCH.exec(p);if(m)p=\nthis.valueForProperty(props[m[1]],props);else{var colon=p.indexOf(\":\");if(colon!==-1){var pp=p.substring(colon);pp=pp.trim();pp=this.valueForProperty(pp,props)||pp;p=p.substring(0,colon)+pp}}parts[i]=p&&p.lastIndexOf(\";\")===p.length-1?p.slice(0,-1):p||\"\"}return parts.join(\";\")},applyProperties:function(rule,props){var output=\"\";if(!rule.propertyInfo)this.decorateRule(rule);if(rule.propertyInfo.cssText)output=this.valueForProperties(rule.propertyInfo.cssText,props);rule.cssText=output},applyKeyframeTransforms:function(rule,\nkeyframeTransforms){var input=rule.cssText;var output=rule.cssText;if(rule.hasAnimations==null)rule.hasAnimations=this.rx.ANIMATION_MATCH.test(input);if(rule.hasAnimations){var transform;if(rule.keyframeNamesToTransform==null){rule.keyframeNamesToTransform=[];for(var keyframe in keyframeTransforms){transform=keyframeTransforms[keyframe];output=transform(input);if(input!==output){input=output;rule.keyframeNamesToTransform.push(keyframe)}}}else{for(var i=0;i<rule.keyframeNamesToTransform.length;++i){transform=\nkeyframeTransforms[rule.keyframeNamesToTransform[i]];input=transform(input)}output=input}}rule.cssText=output},propertyDataFromStyles:function(styles,element){var props={},self=this;var o=[];styleUtil.forActiveRulesInStyles(styles,function(rule){if(!rule.propertyInfo)self.decorateRule(rule);var selectorToMatch=rule.transformedSelector||rule.parsedSelector;if(element&&rule.propertyInfo.properties&&selectorToMatch)if(matchesSelector.call(element,selectorToMatch)){self.collectProperties(rule,props);\naddToBitMask(rule.index,o)}});return{properties:props,key:o}},_rootSelector:/:root|:host\\s*>\\s*\\*/,_checkRoot:function(hostScope,selector){return Boolean(selector.match(this._rootSelector))||hostScope===\"html\"&&selector.indexOf(\"html\")>-1},whenHostOrRootRule:function(scope,rule,style,callback){if(!rule.propertyInfo)self.decorateRule(rule);if(!rule.propertyInfo.properties)return;var hostScope=scope.is?styleTransformer._calcHostScope(scope.is,scope[\"extends\"]):\"html\";var parsedSelector=rule.parsedSelector;\nvar isRoot=this._checkRoot(hostScope,parsedSelector);var isHost=!isRoot&&parsedSelector.indexOf(\":host\")===0;var cssBuild=scope.__cssBuild||style.__cssBuild;if(cssBuild===\"shady\"){isRoot=parsedSelector===hostScope+\" > *.\"+hostScope||parsedSelector.indexOf(\"html\")>-1;isHost=!isRoot&&parsedSelector.indexOf(hostScope)===0}if(!isRoot&&!isHost)return;var selectorToMatch=hostScope;if(isHost){if(settings.useNativeShadow&&!rule.transformedSelector)rule.transformedSelector=styleTransformer._transformRuleCss(rule,\nstyleTransformer._transformComplexSelector,scope.is,hostScope);selectorToMatch=rule.transformedSelector||rule.parsedSelector}if(isRoot&&hostScope===\"html\")selectorToMatch=rule.transformedSelector||rule.parsedSelector;callback({selector:selectorToMatch,isHost:isHost,isRoot:isRoot})},hostAndRootPropertiesForScope:function(scope){var hostProps={},rootProps={},self=this;styleUtil.forActiveRulesInStyles(scope._styles,function(rule,style){self.whenHostOrRootRule(scope,rule,style,function(info){var element=\nscope._element||scope;if(matchesSelector.call(element,info.selector))if(info.isHost)self.collectProperties(rule,hostProps);else self.collectProperties(rule,rootProps)})});return{rootProps:rootProps,hostProps:hostProps}},transformStyles:function(element,properties,scopeSelector){var self=this;var hostSelector=styleTransformer._calcHostScope(element.is,element[\"extends\"]);var rxHostSelector=element[\"extends\"]?\"\\\\\"+hostSelector.slice(0,-1)+\"\\\\]\":hostSelector;var hostRx=new RegExp(this.rx.HOST_PREFIX+\nrxHostSelector+this.rx.HOST_SUFFIX);var keyframeTransforms=this._elementKeyframeTransforms(element,scopeSelector);return styleTransformer.elementStyles(element,function(rule){self.applyProperties(rule,properties);if(!settings.useNativeShadow&&!Polymer.StyleUtil.isKeyframesSelector(rule)&&rule.cssText){self.applyKeyframeTransforms(rule,keyframeTransforms);self._scopeSelector(rule,hostRx,hostSelector,element._scopeCssViaAttr,scopeSelector)}})},_elementKeyframeTransforms:function(element,scopeSelector){var keyframesRules=\nelement._styles._keyframes;var keyframeTransforms={};if(!settings.useNativeShadow&&keyframesRules)for(var i=0,keyframesRule=keyframesRules[i];i<keyframesRules.length;keyframesRule=keyframesRules[++i]){this._scopeKeyframes(keyframesRule,scopeSelector);keyframeTransforms[keyframesRule.keyframesName]=this._keyframesRuleTransformer(keyframesRule)}return keyframeTransforms},_keyframesRuleTransformer:function(keyframesRule){return function(cssText){return cssText.replace(keyframesRule.keyframesNameRx,keyframesRule.transformedKeyframesName)}},\n_scopeKeyframes:function(rule,scopeId){rule.keyframesNameRx=new RegExp(rule.keyframesName,\"g\");rule.transformedKeyframesName=rule.keyframesName+\"-\"+scopeId;rule.transformedSelector=rule.transformedSelector||rule.selector;rule.selector=rule.transformedSelector.replace(rule.keyframesName,rule.transformedKeyframesName)},_scopeSelector:function(rule,hostRx,hostSelector,viaAttr,scopeId){rule.transformedSelector=rule.transformedSelector||rule.selector;var selector=rule.transformedSelector;var scope=viaAttr?\n\"[\"+styleTransformer.SCOPE_NAME+\"~=\"+scopeId+\"]\":\".\"+scopeId;var parts=selector.split(\",\");for(var i=0,l=parts.length,p;i<l&&(p=parts[i]);i++)parts[i]=p.match(hostRx)?p.replace(hostSelector,scope):scope+\" \"+p;rule.selector=parts.join(\",\")},applyElementScopeSelector:function(element,selector,old,viaAttr){var c=viaAttr?element.getAttribute(styleTransformer.SCOPE_NAME):element.getAttribute(\"class\")||\"\";var v=old?c.replace(old,selector):(c?c+\" \":\"\")+this.XSCOPE_NAME+\" \"+selector;if(c!==v)if(viaAttr)element.setAttribute(styleTransformer.SCOPE_NAME,\nv);else element.setAttribute(\"class\",v)},applyElementStyle:function(element,properties,selector,style){var cssText=style?style.textContent||\"\":this.transformStyles(element,properties,selector);var s=element._customStyle;if(s&&!settings.useNativeShadow&&s!==style){s._useCount--;if(s._useCount<=0&&s.parentNode)s.parentNode.removeChild(s)}if(settings.useNativeShadow)if(element._customStyle){element._customStyle.textContent=cssText;style=element._customStyle}else{if(cssText)style=styleUtil.applyCss(cssText,\nselector,element.root,element._scopeStyle)}else if(!style){if(cssText)style=styleUtil.applyCss(cssText,selector,null,element._scopeStyle)}else if(!style.parentNode){if(IS_IE&&cssText.indexOf(\"@media\")>-1)style.textContent=cssText;styleUtil.applyStyle(style,null,element._scopeStyle)}if(style){style._useCount=style._useCount||0;if(element._customStyle!=style)style._useCount++;element._customStyle=style}return style},mixinCustomStyle:function(props,customStyle){var v;for(var i in customStyle){v=customStyle[i];\nif(v||v===0)props[i]=v}},updateNativeStyleProperties:function(element,properties){var oldPropertyNames=element.__customStyleProperties;if(oldPropertyNames)for(var i=0;i<oldPropertyNames.length;i++)element.style.removeProperty(oldPropertyNames[i]);var propertyNames=[];for(var p in properties)if(properties[p]!==null){element.style.setProperty(p,properties[p]);propertyNames.push(p)}element.__customStyleProperties=propertyNames},rx:styleUtil.rx,XSCOPE_NAME:\"x-scope\"};function addToBitMask(n,bits){var o=\nparseInt(n/32);var v=1<<n%32;bits[o]=(bits[o]||0)|v}}();\n(function(){Polymer.StyleCache=function(){this.cache={}};Polymer.StyleCache.prototype={MAX:100,store:function(is,data,keyValues,keyStyles){data.keyValues=keyValues;data.styles=keyStyles;var s$=this.cache[is]=this.cache[is]||[];s$.push(data);if(s$.length>this.MAX)s$.shift()},retrieve:function(is,keyValues,keyStyles){var cache=this.cache[is];if(cache)for(var i=cache.length-1,data;i>=0;i--){data=cache[i];if(keyStyles===data.styles&&this._objectsEqual(keyValues,data.keyValues))return data}},clear:function(){this.cache=\n{}},_objectsEqual:function(target,source){var t,s;for(var i in target){t=target[i],s=source[i];if(!(typeof t===\"object\"&&t?this._objectsStrictlyEqual(t,s):t===s))return false}if(Array.isArray(target))return target.length===source.length;return true},_objectsStrictlyEqual:function(target,source){return this._objectsEqual(target,source)&&this._objectsEqual(source,target)}}})();\nPolymer.StyleDefaults=function(){var styleProperties=Polymer.StyleProperties;var StyleCache=Polymer.StyleCache;var nativeVariables=Polymer.Settings.useNativeCSSProperties;var api={_styles:[],_properties:null,customStyle:{},_styleCache:new StyleCache,_element:Polymer.DomApi.wrap(document.documentElement),addStyle:function(style){this._styles.push(style);this._properties=null},get _styleProperties(){if(!this._properties){styleProperties.decorateStyles(this._styles,this);this._styles._scopeStyleProperties=\nnull;this._properties=styleProperties.hostAndRootPropertiesForScope(this).rootProps;styleProperties.mixinCustomStyle(this._properties,this.customStyle);styleProperties.reify(this._properties)}return this._properties},hasStyleProperties:function(){return Boolean(this._properties)},_needsStyleProperties:function(){},_computeStyleProperties:function(){return this._styleProperties},updateStyles:function(properties){this._properties=null;if(properties)Polymer.Base.mixin(this.customStyle,properties);this._styleCache.clear();\nfor(var i=0,s;i<this._styles.length;i++){s=this._styles[i];s=s.__importElement||s;s._apply()}if(nativeVariables)styleProperties.updateNativeStyleProperties(document.documentElement,this.customStyle)}};return api}();\n(function(){var serializeValueToAttribute=Polymer.Base.serializeValueToAttribute;var propertyUtils=Polymer.StyleProperties;var styleTransformer=Polymer.StyleTransformer;var styleDefaults=Polymer.StyleDefaults;var nativeShadow=Polymer.Settings.useNativeShadow;var nativeVariables=Polymer.Settings.useNativeCSSProperties;Polymer.Base._addFeature({_prepStyleProperties:function(){if(!nativeVariables)this._ownStylePropertyNames=this._styles&&this._styles.length?propertyUtils.decorateStyles(this._styles,\nthis):null},customStyle:null,getComputedStyleValue:function(property){if(!nativeVariables&&!this._styleProperties)this._computeStyleProperties();return!nativeVariables&&this._styleProperties&&this._styleProperties[property]||getComputedStyle(this).getPropertyValue(property)},_setupStyleProperties:function(){this.customStyle={};this._styleCache=null;this._styleProperties=null;this._scopeSelector=null;this._ownStyleProperties=null;this._customStyle=null},_needsStyleProperties:function(){return Boolean(!nativeVariables&&\nthis._ownStylePropertyNames&&this._ownStylePropertyNames.length)},_validateApplyShim:function(){if(this.__applyShimInvalid){Polymer.ApplyShim.transform(this._styles,this.__proto__);var cssText=styleTransformer.elementStyles(this);if(nativeShadow){var templateStyle=this._template.content.querySelector(\"style\");if(templateStyle)templateStyle.textContent=cssText}else{var shadyStyle=this._scopeStyle&&this._scopeStyle.nextSibling;if(shadyStyle)shadyStyle.textContent=cssText}}},_beforeAttached:function(){if((!this._scopeSelector||\nthis.__stylePropertiesInvalid)&&this._needsStyleProperties()){this.__stylePropertiesInvalid=false;this._updateStyleProperties()}},_findStyleHost:function(){var e=this,root;while(root=Polymer.dom(e).getOwnerRoot()){if(Polymer.isInstance(root.host))return root.host;e=root.host}return styleDefaults},_updateStyleProperties:function(){var info,scope=this._findStyleHost();if(!scope._styleProperties)scope._computeStyleProperties();if(!scope._styleCache)scope._styleCache=new Polymer.StyleCache;var scopeData=\npropertyUtils.propertyDataFromStyles(scope._styles,this);var scopeCacheable=!this.__notStyleScopeCacheable;if(scopeCacheable){scopeData.key.customStyle=this.customStyle;info=scope._styleCache.retrieve(this.is,scopeData.key,this._styles)}var scopeCached=Boolean(info);if(scopeCached)this._styleProperties=info._styleProperties;else this._computeStyleProperties(scopeData.properties);this._computeOwnStyleProperties();if(!scopeCached)info=styleCache.retrieve(this.is,this._ownStyleProperties,this._styles);\nvar globalCached=Boolean(info)&&!scopeCached;var style=this._applyStyleProperties(info);if(!scopeCached){style=style&&nativeShadow?style.cloneNode(true):style;info={style:style,_scopeSelector:this._scopeSelector,_styleProperties:this._styleProperties};if(scopeCacheable){scopeData.key.customStyle={};this.mixin(scopeData.key.customStyle,this.customStyle);scope._styleCache.store(this.is,info,scopeData.key,this._styles)}if(!globalCached)styleCache.store(this.is,Object.create(info),this._ownStyleProperties,\nthis._styles)}},_computeStyleProperties:function(scopeProps){var scope=this._findStyleHost();if(!scope._styleProperties)scope._computeStyleProperties();var props=Object.create(scope._styleProperties);var hostAndRootProps=propertyUtils.hostAndRootPropertiesForScope(this);this.mixin(props,hostAndRootProps.hostProps);scopeProps=scopeProps||propertyUtils.propertyDataFromStyles(scope._styles,this).properties;this.mixin(props,scopeProps);this.mixin(props,hostAndRootProps.rootProps);propertyUtils.mixinCustomStyle(props,\nthis.customStyle);propertyUtils.reify(props);this._styleProperties=props},_computeOwnStyleProperties:function(){var props={};for(var i=0,n;i<this._ownStylePropertyNames.length;i++){n=this._ownStylePropertyNames[i];props[n]=this._styleProperties[n]}this._ownStyleProperties=props},_scopeCount:0,_applyStyleProperties:function(info){var oldScopeSelector=this._scopeSelector;this._scopeSelector=info?info._scopeSelector:this.is+\"-\"+this.__proto__._scopeCount++;var style=propertyUtils.applyElementStyle(this,\nthis._styleProperties,this._scopeSelector,info&&info.style);if(!nativeShadow)propertyUtils.applyElementScopeSelector(this,this._scopeSelector,oldScopeSelector,this._scopeCssViaAttr);return style},serializeValueToAttribute:function(value,attribute,node){node=node||this;if(attribute===\"class\"&&!nativeShadow){var host=node===this?this.domHost||this.dataHost:this;if(host)value=host._scopeElementClass(node,value)}node=this.shadyRoot&&this.shadyRoot._hasDistributed?Polymer.dom(node):node;serializeValueToAttribute.call(this,\nvalue,attribute,node)},_scopeElementClass:function(element,selector){if(!nativeShadow&&!this._scopeCssViaAttr)selector=(selector?selector+\" \":\"\")+SCOPE_NAME+\" \"+this.is+(element._scopeSelector?\" \"+XSCOPE_NAME+\" \"+element._scopeSelector:\"\");return selector},updateStyles:function(properties){if(properties)this.mixin(this.customStyle,properties);if(nativeVariables)propertyUtils.updateNativeStyleProperties(this,this.customStyle);else{if(this.isAttached)if(this._needsStyleProperties())this._updateStyleProperties();\nelse this._styleProperties=null;else this.__stylePropertiesInvalid=true;if(this._styleCache)this._styleCache.clear();this._updateRootStyles()}},_updateRootStyles:function(root){root=root||this.root;var c$=Polymer.dom(root)._query(function(e){return e.shadyRoot||e.shadowRoot});for(var i=0,l=c$.length,c;i<l&&(c=c$[i]);i++)if(c.updateStyles)c.updateStyles()}});Polymer.updateStyles=function(properties){styleDefaults.updateStyles(properties);Polymer.Base._updateRootStyles(document)};var styleCache=new Polymer.StyleCache;\nPolymer.customStyleCache=styleCache;var SCOPE_NAME=styleTransformer.SCOPE_NAME;var XSCOPE_NAME=propertyUtils.XSCOPE_NAME})();\nPolymer.Base._addFeature({_registerFeatures:function(){this._prepIs();if(this.factoryImpl)this._prepConstructor();this._prepStyles()},_finishRegisterFeatures:function(){this._prepTemplate();this._prepShimStyles();this._prepAnnotations();this._prepEffects();this._prepBehaviors();this._prepPropertyInfo();this._prepBindings();this._prepShady()},_prepBehavior:function(b){this._addPropertyEffects(b.properties);this._addComplexObserverEffects(b.observers);this._addHostAttributes(b.hostAttributes)},_initFeatures:function(){this._setupGestures();\nthis._setupConfigure(this.__data__);this._setupStyleProperties();this._setupDebouncers();this._setupShady();this._registerHost();if(this._template){this._validateApplyShim();this._poolContent();this._beginHosting();this._stampTemplate();this._endHosting();this._marshalAnnotationReferences()}this._marshalInstanceEffects();this._marshalBehaviors();this._marshalHostAttributes();this._marshalAttributes();this._tryReady()},_marshalBehavior:function(b){if(b.listeners)this._listenListeners(b.listeners)}});\n(function(){var propertyUtils=Polymer.StyleProperties;var styleUtil=Polymer.StyleUtil;var cssParse=Polymer.CssParse;var styleDefaults=Polymer.StyleDefaults;var styleTransformer=Polymer.StyleTransformer;var applyShim=Polymer.ApplyShim;var debounce=Polymer.Debounce;var settings=Polymer.Settings;var updateDebouncer;Polymer({is:\"custom-style\",\"extends\":\"style\",_template:null,properties:{include:String},ready:function(){this.__appliedElement=this.__appliedElement||this;this.__cssBuild=styleUtil.getCssBuildType(this);\nif(this.__appliedElement!==this)this.__appliedElement.__cssBuild=this.__cssBuild;this._tryApply()},attached:function(){this._tryApply()},_tryApply:function(){if(!this._appliesToDocument)if(this.parentNode&&this.parentNode.localName!==\"dom-module\"){this._appliesToDocument=true;var e=this.__appliedElement;if(!settings.useNativeCSSProperties){this.__needsUpdateStyles=styleDefaults.hasStyleProperties();styleDefaults.addStyle(e)}if(e.textContent||this.include)this._apply(true);else{var self=this;var observer=\nnew MutationObserver(function(){observer.disconnect();self._apply(true)});observer.observe(e,{childList:true})}}},_updateStyles:function(){Polymer.updateStyles()},_apply:function(initialApply){var e=this.__appliedElement;if(this.include)e.textContent=styleUtil.cssFromModules(this.include,true)+e.textContent;if(!e.textContent)return;var buildType=this.__cssBuild;var targetedBuild=styleUtil.isTargetedBuild(buildType);if(settings.useNativeCSSProperties&&targetedBuild)return;var styleRules=styleUtil.rulesForStyle(e);\nif(!targetedBuild){styleUtil.forEachRule(styleRules,function(rule){styleTransformer.documentRule(rule)});if(settings.useNativeCSSProperties&&!buildType)applyShim.transform([e])}if(settings.useNativeCSSProperties)e.textContent=styleUtil.toCssText(styleRules);else{var self=this;var fn=function fn(){self._flushCustomProperties()};if(initialApply)Polymer.RenderStatus.whenReady(fn);else fn()}},_flushCustomProperties:function(){if(this.__needsUpdateStyles){this.__needsUpdateStyles=false;updateDebouncer=\ndebounce(updateDebouncer,this._updateStyles)}else this._applyCustomProperties()},_applyCustomProperties:function(){var element=this.__appliedElement;this._computeStyleProperties();var props=this._styleProperties;var rules=styleUtil.rulesForStyle(element);if(!rules)return;element.textContent=styleUtil.toCssText(rules,function(rule){var css=rule.cssText=rule.parsedCssText;if(rule.propertyInfo&&rule.propertyInfo.cssText){css=cssParse.removeCustomPropAssignment(css);rule.cssText=propertyUtils.valueForProperties(css,\nprops)}})}})})();\nPolymer.Templatizer={properties:{__hideTemplateChildren__:{observer:\"_showHideChildren\"}},_instanceProps:Polymer.nob,_parentPropPrefix:\"_parent_\",templatize:function(template){this._templatized=template;if(!template._content)template._content=template.content;if(template._content._ctor){this.ctor=template._content._ctor;this._prepParentProperties(this.ctor.prototype,template);return}var archetype=Object.create(Polymer.Base);this._customPrepAnnotations(archetype,template);this._prepParentProperties(archetype,template);\narchetype._prepEffects();this._customPrepEffects(archetype);archetype._prepBehaviors();archetype._prepPropertyInfo();archetype._prepBindings();archetype._notifyPathUp=this._notifyPathUpImpl;archetype._scopeElementClass=this._scopeElementClassImpl;archetype.listen=this._listenImpl;archetype._showHideChildren=this._showHideChildrenImpl;archetype.__setPropertyOrig=this.__setProperty;archetype.__setProperty=this.__setPropertyImpl;var _constructor=this._constructorImpl;var ctor=function TemplateInstance(model,\nhost){_constructor.call(this,model,host)};ctor.prototype=archetype;archetype.constructor=ctor;template._content._ctor=ctor;this.ctor=ctor},_getRootDataHost:function(){return this.dataHost&&this.dataHost._rootDataHost||this.dataHost},_showHideChildrenImpl:function(hide){var c=this._children;for(var i=0;i<c.length;i++){var n=c[i];if(Boolean(hide)!=Boolean(n.__hideTemplateChildren__))if(n.nodeType===Node.TEXT_NODE)if(hide){n.__polymerTextContent__=n.textContent;n.textContent=\"\"}else n.textContent=n.__polymerTextContent__;\nelse if(n.style)if(hide){n.__polymerDisplay__=n.style.display;n.style.display=\"none\"}else n.style.display=n.__polymerDisplay__;n.__hideTemplateChildren__=hide}},__setPropertyImpl:function(property,value,fromAbove,node){if(node&&node.__hideTemplateChildren__&&property==\"textContent\")property=\"__polymerTextContent__\";this.__setPropertyOrig(property,value,fromAbove,node)},_debounceTemplate:function(fn){Polymer.dom.addDebouncer(this.debounce(\"_debounceTemplate\",fn))},_flushTemplates:function(){Polymer.dom.flush()},\n_customPrepEffects:function(archetype){var parentProps=archetype._parentProps;for(var prop in parentProps)archetype._addPropertyEffect(prop,\"function\",this._createHostPropEffector(prop));for(prop in this._instanceProps)archetype._addPropertyEffect(prop,\"function\",this._createInstancePropEffector(prop))},_customPrepAnnotations:function(archetype,template){archetype._template=template;var c=template._content;if(!c._notes){var rootDataHost=archetype._rootDataHost;if(rootDataHost)Polymer.Annotations.prepElement=\nfunction(){rootDataHost._prepElement()};c._notes=Polymer.Annotations.parseAnnotations(template);Polymer.Annotations.prepElement=null;this._processAnnotations(c._notes)}archetype._notes=c._notes;archetype._parentProps=c._parentProps},_prepParentProperties:function(archetype,template){var parentProps=this._parentProps=archetype._parentProps;if(this._forwardParentProp&&parentProps){var proto=archetype._parentPropProto;var prop;if(!proto){for(prop in this._instanceProps)delete parentProps[prop];proto=\narchetype._parentPropProto=Object.create(null);if(template!=this){Polymer.Bind.prepareModel(proto);Polymer.Base.prepareModelNotifyPath(proto)}for(prop in parentProps){var parentProp=this._parentPropPrefix+prop;var effects=[{kind:\"function\",effect:this._createForwardPropEffector(prop),fn:Polymer.Bind._functionEffect},{kind:\"notify\",fn:Polymer.Bind._notifyEffect,effect:{event:Polymer.CaseMap.camelToDashCase(parentProp)+\"-changed\"}}];proto._propertyEffects=proto._propertyEffects||{};proto._propertyEffects[parentProp]=\neffects;Polymer.Bind._createAccessors(proto,parentProp,effects)}}var self=this;if(template!=this){Polymer.Bind.prepareInstance(template);template._forwardParentProp=function(source,value){self._forwardParentProp(source,value)}}this._extendTemplate(template,proto);template._pathEffector=function(path,value,fromAbove){return self._pathEffectorImpl(path,value,fromAbove)}}},_createForwardPropEffector:function(prop){return function(source,value){this._forwardParentProp(prop,value)}},_createHostPropEffector:function(prop){var prefix=\nthis._parentPropPrefix;return function(source,value){this.dataHost._templatized[prefix+prop]=value}},_createInstancePropEffector:function(prop){return function(source,value,old,fromAbove){if(!fromAbove)this.dataHost._forwardInstanceProp(this,prop,value)}},_extendTemplate:function(template,proto){var n$=Object.getOwnPropertyNames(proto);if(proto._propertySetter)template._propertySetter=proto._propertySetter;for(var i=0,n;i<n$.length&&(n=n$[i]);i++){var val=template[n];if(val&&n==\"_propertyEffects\"){var pe=\nPolymer.Base.mixin({},val);template._propertyEffects=Polymer.Base.mixin(pe,proto._propertyEffects)}else{var pd=Object.getOwnPropertyDescriptor(proto,n);Object.defineProperty(template,n,pd);if(val!==undefined)template._propertySetter(n,val)}}},_showHideChildren:function(hidden){},_forwardInstancePath:function(inst,path,value){},_forwardInstanceProp:function(inst,prop,value){},_notifyPathUpImpl:function(path,value){var dataHost=this.dataHost;var root=Polymer.Path.root(path);dataHost._forwardInstancePath.call(dataHost,\nthis,path,value);if(root in dataHost._parentProps)dataHost._templatized._notifyPath(dataHost._parentPropPrefix+path,value)},_pathEffectorImpl:function(path,value,fromAbove){if(this._forwardParentPath)if(path.indexOf(this._parentPropPrefix)===0){var subPath=path.substring(this._parentPropPrefix.length);var model=Polymer.Path.root(subPath);if(model in this._parentProps)this._forwardParentPath(subPath,value)}Polymer.Base._pathEffector.call(this._templatized,path,value,fromAbove)},_constructorImpl:function(model,\nhost){this._rootDataHost=host._getRootDataHost();this._setupConfigure(model);this._registerHost(host);this._beginHosting();this.root=this.instanceTemplate(this._template);this.root.__noContent=!this._notes._hasContent;this.root.__styleScoped=true;this._endHosting();this._marshalAnnotatedNodes();this._marshalInstanceEffects();this._marshalAnnotatedListeners();var children=[];for(var n=this.root.firstChild;n;n=n.nextSibling){children.push(n);n._templateInstance=this}this._children=children;if(host.__hideTemplateChildren__)this._showHideChildren(true);\nthis._tryReady()},_listenImpl:function(node,eventName,methodName){var model=this;var host=this._rootDataHost;var handler=host._createEventHandler(node,eventName,methodName);var decorated=function(e){e.model=model;handler(e)};host._listen(node,eventName,decorated)},_scopeElementClassImpl:function(node,value){var host=this._rootDataHost;if(host)return host._scopeElementClass(node,value);return value},stamp:function(model){model=model||{};if(this._parentProps){var templatized=this._templatized;for(var prop in this._parentProps)if(model[prop]===\nundefined)model[prop]=templatized[this._parentPropPrefix+prop]}return new this.ctor(model,this)},modelForElement:function(el){var model;while(el)if(model=el._templateInstance)if(model.dataHost!=this)el=model.dataHost;else return model;else el=el.parentNode}};Polymer({is:\"dom-template\",\"extends\":\"template\",_template:null,behaviors:[Polymer.Templatizer],ready:function(){this.templatize(this)}});Polymer._collections=new WeakMap;\nPolymer.Collection=function(userArray){Polymer._collections.set(userArray,this);this.userArray=userArray;this.store=userArray.slice();this.initMap()};\nPolymer.Collection.prototype={constructor:Polymer.Collection,initMap:function(){var omap=this.omap=new WeakMap;var pmap=this.pmap={};var s=this.store;for(var i=0;i<s.length;i++){var item=s[i];if(item&&typeof item==\"object\")omap.set(item,i);else pmap[item]=i}},add:function(item){var key=this.store.push(item)-1;if(item&&typeof item==\"object\")this.omap.set(item,key);else this.pmap[item]=key;return\"#\"+key},removeKey:function(key){if(key=this._parseKey(key)){this._removeFromMap(this.store[key]);delete this.store[key]}},\n_removeFromMap:function(item){if(item&&typeof item==\"object\")this.omap[\"delete\"](item);else delete this.pmap[item]},remove:function(item){var key=this.getKey(item);this.removeKey(key);return key},getKey:function(item){var key;if(item&&typeof item==\"object\")key=this.omap.get(item);else key=this.pmap[item];if(key!=undefined)return\"#\"+key},getKeys:function(){return Object.keys(this.store).map(function(key){return\"#\"+key})},_parseKey:function(key){if(key&&key[0]==\"#\")return key.slice(1)},setItem:function(key,\nitem){if(key=this._parseKey(key)){var old=this.store[key];if(old)this._removeFromMap(old);if(item&&typeof item==\"object\")this.omap.set(item,key);else this.pmap[item]=key;this.store[key]=item}},getItem:function(key){if(key=this._parseKey(key))return this.store[key]},getItems:function(){var items=[],store=this.store;for(var key in store)items.push(store[key]);return items},_applySplices:function(splices){var keyMap={},key;for(var i=0,s;i<splices.length&&(s=splices[i]);i++){s.addedKeys=[];for(var j=\n0;j<s.removed.length;j++){key=this.getKey(s.removed[j]);keyMap[key]=keyMap[key]?null:-1}for(j=0;j<s.addedCount;j++){var item=this.userArray[s.index+j];key=this.getKey(item);key=key===undefined?this.add(item):key;keyMap[key]=keyMap[key]?null:1;s.addedKeys.push(key)}}var removed=[];var added=[];for(key in keyMap){if(keyMap[key]<0){this.removeKey(key);removed.push(key)}if(keyMap[key]>0)added.push(key)}return[{removed:removed,added:added}]}};\nPolymer.Collection.get=function(userArray){return Polymer._collections.get(userArray)||new Polymer.Collection(userArray)};Polymer.Collection.applySplices=function(userArray,splices){var coll=Polymer._collections.get(userArray);return coll?coll._applySplices(splices):null};\nPolymer({is:\"dom-repeat\",\"extends\":\"template\",_template:null,properties:{items:{type:Array},as:{type:String,value:\"item\"},indexAs:{type:String,value:\"index\"},sort:{type:Function,observer:\"_sortChanged\"},filter:{type:Function,observer:\"_filterChanged\"},observe:{type:String,observer:\"_observeChanged\"},delay:Number,renderedItemCount:{type:Number,notify:!Polymer.Settings.suppressTemplateNotifications,readOnly:true},initialCount:{type:Number,observer:\"_initializeChunking\"},targetFramerate:{type:Number,\nvalue:20},notifyDomChange:{type:Boolean},_targetFrameTime:{type:Number,computed:\"_computeFrameTime(targetFramerate)\"}},behaviors:[Polymer.Templatizer],observers:[\"_itemsChanged(items.*)\"],created:function(){this._instances=[];this._pool=[];this._limit=Infinity;var self=this;this._boundRenderChunk=function(){self._renderChunk()}},detached:function(){this.__isDetached=true;for(var i=0;i<this._instances.length;i++)this._detachInstance(i)},attached:function(){if(this.__isDetached){this.__isDetached=false;\nvar parent=Polymer.dom(Polymer.dom(this).parentNode);for(var i=0;i<this._instances.length;i++)this._attachInstance(i,parent)}},ready:function(){this._instanceProps={__key__:true};this._instanceProps[this.as]=true;this._instanceProps[this.indexAs]=true;if(!this.ctor)this.templatize(this)},_sortChanged:function(sort){var dataHost=this._getRootDataHost();this._sortFn=sort&&(typeof sort==\"function\"?sort:function(){return dataHost[sort].apply(dataHost,arguments)});this._needFullRefresh=true;if(this.items)this._debounceTemplate(this._render)},\n_filterChanged:function(filter){var dataHost=this._getRootDataHost();this._filterFn=filter&&(typeof filter==\"function\"?filter:function(){return dataHost[filter].apply(dataHost,arguments)});this._needFullRefresh=true;if(this.items)this._debounceTemplate(this._render)},_computeFrameTime:function(rate){return Math.ceil(1E3/rate)},_initializeChunking:function(){if(this.initialCount){this._limit=this.initialCount;this._chunkCount=this.initialCount;this._lastChunkTime=performance.now()}},_tryRenderChunk:function(){if(this.items&&\nthis._limit<this.items.length)this.debounce(\"renderChunk\",this._requestRenderChunk)},_requestRenderChunk:function(){requestAnimationFrame(this._boundRenderChunk)},_renderChunk:function(){var currChunkTime=performance.now();var ratio=this._targetFrameTime/(currChunkTime-this._lastChunkTime);this._chunkCount=Math.round(this._chunkCount*ratio)||1;this._limit+=this._chunkCount;this._lastChunkTime=currChunkTime;this._debounceTemplate(this._render)},_observeChanged:function(){this._observePaths=this.observe&&\nthis.observe.replace(\".*\",\".\").split(\" \")},_itemsChanged:function(change){if(change.path==\"items\"){if(Array.isArray(this.items))this.collection=Polymer.Collection.get(this.items);else if(!this.items)this.collection=null;else this._error(this._logf(\"dom-repeat\",\"expected array for `items`,\"+\" found\",this.items));this._keySplices=[];this._indexSplices=[];this._needFullRefresh=true;this._initializeChunking();this._debounceTemplate(this._render)}else if(change.path==\"items.splices\"){this._keySplices=\nthis._keySplices.concat(change.value.keySplices);this._indexSplices=this._indexSplices.concat(change.value.indexSplices);this._debounceTemplate(this._render)}else{var subpath=change.path.slice(6);this._forwardItemPath(subpath,change.value);this._checkObservedPaths(subpath)}},_checkObservedPaths:function(path){if(this._observePaths){path=path.substring(path.indexOf(\".\")+1);var paths=this._observePaths;for(var i=0;i<paths.length;i++)if(path.indexOf(paths[i])===0){this._needFullRefresh=true;if(this.delay)this.debounce(\"render\",\nthis._render,this.delay);else this._debounceTemplate(this._render);return}}},render:function(){this._needFullRefresh=true;this._debounceTemplate(this._render);this._flushTemplates()},_render:function(){if(this._needFullRefresh){this._applyFullRefresh();this._needFullRefresh=false}else if(this._keySplices.length)if(this._sortFn)this._applySplicesUserSort(this._keySplices);else if(this._filterFn)this._applyFullRefresh();else this._applySplicesArrayOrder(this._indexSplices);else;this._keySplices=[];\nthis._indexSplices=[];var keyToIdx=this._keyToInstIdx={};for(var i=this._instances.length-1;i>=0;i--){var inst=this._instances[i];if(inst.isPlaceholder&&i<this._limit)inst=this._insertInstance(i,inst.__key__);else if(!inst.isPlaceholder&&i>=this._limit)inst=this._downgradeInstance(i,inst.__key__);keyToIdx[inst.__key__]=i;if(!inst.isPlaceholder)inst.__setProperty(this.indexAs,i,true)}this._pool.length=0;this._setRenderedItemCount(this._instances.length);if(!Polymer.Settings.suppressTemplateNotifications||\nthis.notifyDomChange)this.fire(\"dom-change\");this._tryRenderChunk()},_applyFullRefresh:function(){var c=this.collection;var keys;if(this._sortFn)keys=c?c.getKeys():[];else{keys=[];var items=this.items;if(items)for(var i=0;i<items.length;i++)keys.push(c.getKey(items[i]))}var self=this;if(this._filterFn)keys=keys.filter(function(a){return self._filterFn(c.getItem(a))});if(this._sortFn)keys.sort(function(a,b){return self._sortFn(c.getItem(a),c.getItem(b))});for(i=0;i<keys.length;i++){var key=keys[i];\nvar inst=this._instances[i];if(inst){inst.__key__=key;if(!inst.isPlaceholder&&i<this._limit)inst.__setProperty(this.as,c.getItem(key),true)}else if(i<this._limit)this._insertInstance(i,key);else this._insertPlaceholder(i,key)}for(var j=this._instances.length-1;j>=i;j--)this._detachAndRemoveInstance(j)},_numericSort:function(a,b){return a-b},_applySplicesUserSort:function(splices){var c=this.collection;var keyMap={};var key;for(var i=0,s;i<splices.length&&(s=splices[i]);i++){for(var j=0;j<s.removed.length;j++){key=\ns.removed[j];keyMap[key]=keyMap[key]?null:-1}for(j=0;j<s.added.length;j++){key=s.added[j];keyMap[key]=keyMap[key]?null:1}}var removedIdxs=[];var addedKeys=[];for(key in keyMap){if(keyMap[key]===-1)removedIdxs.push(this._keyToInstIdx[key]);if(keyMap[key]===1)addedKeys.push(key)}if(removedIdxs.length){removedIdxs.sort(this._numericSort);for(i=removedIdxs.length-1;i>=0;i--){var idx=removedIdxs[i];if(idx!==undefined)this._detachAndRemoveInstance(idx)}}var self=this;if(addedKeys.length){if(this._filterFn)addedKeys=\naddedKeys.filter(function(a){return self._filterFn(c.getItem(a))});addedKeys.sort(function(a,b){return self._sortFn(c.getItem(a),c.getItem(b))});var start=0;for(i=0;i<addedKeys.length;i++)start=this._insertRowUserSort(start,addedKeys[i])}},_insertRowUserSort:function(start,key){var c=this.collection;var item=c.getItem(key);var end=this._instances.length-1;var idx=-1;while(start<=end){var mid=start+end>>1;var midKey=this._instances[mid].__key__;var cmp=this._sortFn(c.getItem(midKey),item);if(cmp<0)start=\nmid+1;else if(cmp>0)end=mid-1;else{idx=mid;break}}if(idx<0)idx=end+1;this._insertPlaceholder(idx,key);return idx},_applySplicesArrayOrder:function(splices){for(var i=0,s;i<splices.length&&(s=splices[i]);i++){for(var j=0;j<s.removed.length;j++)this._detachAndRemoveInstance(s.index);for(j=0;j<s.addedKeys.length;j++)this._insertPlaceholder(s.index+j,s.addedKeys[j])}},_detachInstance:function(idx){var inst=this._instances[idx];if(!inst.isPlaceholder){for(var i=0;i<inst._children.length;i++){var el=inst._children[i];\nPolymer.dom(inst.root).appendChild(el)}return inst}},_attachInstance:function(idx,parent){var inst=this._instances[idx];if(!inst.isPlaceholder)parent.insertBefore(inst.root,this)},_detachAndRemoveInstance:function(idx){var inst=this._detachInstance(idx);if(inst)this._pool.push(inst);this._instances.splice(idx,1)},_insertPlaceholder:function(idx,key){this._instances.splice(idx,0,{isPlaceholder:true,__key__:key})},_stampInstance:function(idx,key){var model={__key__:key};model[this.as]=this.collection.getItem(key);\nmodel[this.indexAs]=idx;return this.stamp(model)},_insertInstance:function(idx,key){var inst=this._pool.pop();if(inst){inst.__setProperty(this.as,this.collection.getItem(key),true);inst.__setProperty(\"__key__\",key,true)}else inst=this._stampInstance(idx,key);var beforeRow=this._instances[idx+1];var beforeNode=beforeRow&&!beforeRow.isPlaceholder?beforeRow._children[0]:this;var parentNode=Polymer.dom(this).parentNode;Polymer.dom(parentNode).insertBefore(inst.root,beforeNode);this._instances[idx]=inst;\nreturn inst},_downgradeInstance:function(idx,key){var inst=this._detachInstance(idx);if(inst)this._pool.push(inst);inst={isPlaceholder:true,__key__:key};this._instances[idx]=inst;return inst},_showHideChildren:function(hidden){for(var i=0;i<this._instances.length;i++)if(!this._instances[i].isPlaceholder)this._instances[i]._showHideChildren(hidden)},_forwardInstanceProp:function(inst,prop,value){if(prop==this.as){var idx;if(this._sortFn||this._filterFn)idx=this.items.indexOf(this.collection.getItem(inst.__key__));\nelse idx=inst[this.indexAs];this.set(\"items.\"+idx,value)}},_forwardInstancePath:function(inst,path,value){if(path.indexOf(this.as+\".\")===0)this._notifyPath(\"items.\"+inst.__key__+\".\"+path.slice(this.as.length+1),value)},_forwardParentProp:function(prop,value){var i$=this._instances;for(var i=0,inst;i<i$.length&&(inst=i$[i]);i++)if(!inst.isPlaceholder)inst.__setProperty(prop,value,true)},_forwardParentPath:function(path,value){var i$=this._instances;for(var i=0,inst;i<i$.length&&(inst=i$[i]);i++)if(!inst.isPlaceholder)inst._notifyPath(path,\nvalue,true)},_forwardItemPath:function(path,value){if(this._keyToInstIdx){var dot=path.indexOf(\".\");var key=path.substring(0,dot<0?path.length:dot);var idx=this._keyToInstIdx[key];var inst=this._instances[idx];if(inst&&!inst.isPlaceholder)if(dot>=0){path=this.as+\".\"+path.substring(dot+1);inst._notifyPath(path,value,true)}else inst.__setProperty(this.as,value,true)}},itemForElement:function(el){var instance=this.modelForElement(el);return instance&&instance[this.as]},keyForElement:function(el){var instance=\nthis.modelForElement(el);return instance&&instance.__key__},indexForElement:function(el){var instance=this.modelForElement(el);return instance&&instance[this.indexAs]}});\nPolymer({is:\"array-selector\",_template:null,properties:{items:{type:Array,observer:\"clearSelection\"},multi:{type:Boolean,value:false,observer:\"clearSelection\"},selected:{type:Object,notify:true},selectedItem:{type:Object,notify:true},toggle:{type:Boolean,value:false}},clearSelection:function(){if(Array.isArray(this.selected))for(var i=0;i<this.selected.length;i++)this.unlinkPaths(\"selected.\"+i);else{this.unlinkPaths(\"selected\");this.unlinkPaths(\"selectedItem\")}if(this.multi){if(!this.selected||this.selected.length){this.selected=\n[];this._selectedColl=Polymer.Collection.get(this.selected)}}else{this.selected=null;this._selectedColl=null}this.selectedItem=null},isSelected:function(item){if(this.multi)return this._selectedColl.getKey(item)!==undefined;else return this.selected==item},deselect:function(item){if(this.multi){if(this.isSelected(item)){var skey=this._selectedColl.getKey(item);this.arrayDelete(\"selected\",item);this.unlinkPaths(\"selected.\"+skey)}}else{this.selected=null;this.selectedItem=null;this.unlinkPaths(\"selected\");\nthis.unlinkPaths(\"selectedItem\")}},select:function(item){var icol=Polymer.Collection.get(this.items);var key=icol.getKey(item);if(this.multi)if(this.isSelected(item)){if(this.toggle)this.deselect(item)}else{this.push(\"selected\",item);var skey=this._selectedColl.getKey(item);this.linkPaths(\"selected.\"+skey,\"items.\"+key)}else if(this.toggle&&item==this.selected)this.deselect();else{this.selected=item;this.selectedItem=item;this.linkPaths(\"selected\",\"items.\"+key);this.linkPaths(\"selectedItem\",\"items.\"+\nkey)}}});\nPolymer({is:\"dom-if\",\"extends\":\"template\",_template:null,properties:{\"if\":{type:Boolean,value:false,observer:\"_queueRender\"},restamp:{type:Boolean,value:false,observer:\"_queueRender\"},notifyDomChange:{type:Boolean}},behaviors:[Polymer.Templatizer],_queueRender:function(){this._debounceTemplate(this._render)},detached:function(){if(!this.parentNode||this.parentNode.nodeType==Node.DOCUMENT_FRAGMENT_NODE&&(!Polymer.Settings.hasShadow||!(this.parentNode instanceof ShadowRoot)))this._teardownInstance()},attached:function(){if(this[\"if\"]&&\nthis.ctor)this.async(this._ensureInstance)},render:function(){this._flushTemplates()},_render:function(){if(this[\"if\"]){if(!this.ctor)this.templatize(this);this._ensureInstance();this._showHideChildren()}else if(this.restamp)this._teardownInstance();if(!this.restamp&&this._instance)this._showHideChildren();if(this[\"if\"]!=this._lastIf){if(!Polymer.Settings.suppressTemplateNotifications||this.notifyDomChange)this.fire(\"dom-change\");this._lastIf=this[\"if\"]}},_ensureInstance:function(){var parentNode=\nPolymer.dom(this).parentNode;if(parentNode){var parent=Polymer.dom(parentNode);if(!this._instance){this._instance=this.stamp();var root=this._instance.root;parent.insertBefore(root,this)}else{var c$=this._instance._children;if(c$&&c$.length){var lastChild=Polymer.dom(this).previousSibling;if(lastChild!==c$[c$.length-1])for(var i=0,n;i<c$.length&&(n=c$[i]);i++)parent.insertBefore(n,this)}}}},_teardownInstance:function(){if(this._instance){var c$=this._instance._children;if(c$&&c$.length){var parent=\nPolymer.dom(Polymer.dom(c$[0]).parentNode);for(var i=0,n;i<c$.length&&(n=c$[i]);i++)parent.removeChild(n)}this._instance=null}},_showHideChildren:function(){var hidden=this.__hideTemplateChildren__||!this[\"if\"];if(this._instance)this._instance._showHideChildren(hidden)},_forwardParentProp:function(prop,value){if(this._instance)this._instance.__setProperty(prop,value,true)},_forwardParentPath:function(path,value){if(this._instance)this._instance._notifyPath(path,value,true)}});\nPolymer({is:\"dom-bind\",properties:{notifyDomChange:{type:Boolean}},\"extends\":\"template\",_template:null,created:function(){var self=this;Polymer.RenderStatus.whenReady(function(){if(document.readyState==\"loading\")document.addEventListener(\"DOMContentLoaded\",function(){self._markImportsReady()});else self._markImportsReady()})},_ensureReady:function(){if(!this._readied)this._readySelf()},_markImportsReady:function(){this._importsReady=true;this._ensureReady()},_registerFeatures:function(){this._prepConstructor()},\n_insertChildren:function(){var parentDom=Polymer.dom(Polymer.dom(this).parentNode);parentDom.insertBefore(this.root,this)},_removeChildren:function(){if(this._children)for(var i=0;i<this._children.length;i++)this.root.appendChild(this._children[i])},_initFeatures:function(){},_scopeElementClass:function(element,selector){if(this.dataHost)return this.dataHost._scopeElementClass(element,selector);else return selector},_configureInstanceProperties:function(){},_prepConfigure:function(){var config={};\nfor(var prop in this._propertyEffects)config[prop]=this[prop];var setupConfigure=this._setupConfigure;this._setupConfigure=function(){setupConfigure.call(this,config)}},attached:function(){if(this._importsReady)this.render()},detached:function(){this._removeChildren()},render:function(){this._ensureReady();if(!this._children){this._template=this;this._prepAnnotations();this._prepEffects();this._prepBehaviors();this._prepConfigure();this._prepBindings();this._prepPropertyInfo();Polymer.Base._initFeatures.call(this);\nthis._children=Polymer.TreeApi.arrayCopyChildNodes(this.root)}this._insertChildren();if(!Polymer.Settings.suppressTemplateNotifications||this.notifyDomChange)this.fire(\"dom-change\")}});\n'use strict';var d,f={scope:{},u3:function(a,b,c){if(null==a)throw new TypeError(\"The 'this' value for String.prototype.\"+c+\" must not be null or undefined\");if(b instanceof RegExp)throw new TypeError(\"First argument to String.prototype.\"+c+\" must not be a regular expression\");return a+\"\"}};\nf.defineProperty=\"function\"==typeof Object.defineProperties?Object.defineProperty:function(a,b,c){if(c.get||c.set)throw new TypeError(\"ES3 does not support getters and setters.\");a!=Array.prototype&&a!=Object.prototype&&(a[b]=c.value)};f.KL=function(a){return\"undefined\"!=typeof window&&window===a?a:\"undefined\"!=typeof global&&null!=global?global:a};f.global=f.KL(this);\nf.si=function(a,b){if(b){var c=f.global;a=a.split(\".\");for(var e=0;e<a.length-1;e++){var g=a[e];g in c||(c[g]={});c=c[g]}a=a[a.length-1];e=c[a];b=b(e);b!=e&&null!=b&&f.defineProperty(c,a,{configurable:!0,writable:!0,value:b})}};f.EE=\"jscomp_symbol_\";f.iB=function(){f.iB=function(){};f.global.Symbol||(f.global.Symbol=f.Symbol)};f.mW=0;f.Symbol=function(a){return f.EE+(a||\"\")+f.mW++};\nf.gm=function(){f.iB();var a=f.global.Symbol.iterator;a||(a=f.global.Symbol.iterator=f.global.Symbol(\"iterator\"));\"function\"!=typeof Array.prototype[a]&&f.defineProperty(Array.prototype,a,{configurable:!0,writable:!0,value:function(){return f.Jw(this)}});f.gm=function(){}};f.Jw=function(a){var b=0;return f.MN(function(){return b<a.length?{done:!1,value:a[b++]}:{done:!0}})};f.MN=function(a){f.gm();a={next:a};a[f.global.Symbol.iterator]=function(){return this};return a};f.aa=f.aa||{};\nf.LN=function(a,b){f.gm();a instanceof String&&(a+=\"\");var c=0,e={next:function(){if(c<a.length){var g=c++;return{value:b(g,a[g]),done:!1}}e.next=function(){return{done:!0,value:void 0}};return e.next()}};e[Symbol.iterator]=function(){return e};return e};f.si(\"Array.prototype.entries\",function(a){return a?a:a=function(){return f.LN(this,function(a,c){return[a,c]})}},\"es6-impl\",\"es3\");\nf.si(\"Array.prototype.fill\",function(a){return a?a:a=function(a,c,e){var b=this.length||0;0>c&&(c=Math.max(0,b+c));if(null==e||e>b)e=b;e=Number(e);0>e&&(e=Math.max(0,b+e));for(c=Number(c||0);c<e;c++)this[c]=a;return this}},\"es6-impl\",\"es3\");f.si(\"Math.sign\",function(a){return a?a:a=function(a){a=Number(a);return 0===a||isNaN(a)?a:0<a?1:-1}},\"es6-impl\",\"es3\");f.si(\"Math.log10\",function(a){return a?a:a=function(a){return Math.log(a)/Math.LN10}},\"es6-impl\",\"es3\");\nf.si(\"Math.log2\",function(a){return a?a:a=function(a){return Math.log(a)/Math.LN2}},\"es6-impl\",\"es3\");f.a6=function(a,b,c){a instanceof String&&(a=String(a));for(var e=a.length,g=0;g<e;g++){var k=a[g];if(b.call(c,k,g,a))return{uf:g,Ak:k}}return{uf:-1,Ak:void 0}};f.NO=function(a,b){return Object.prototype.hasOwnProperty.call(a,b)};\nf.si(\"Object.assign\",function(a){return a?a:a=function(a,c){for(var b=1;b<arguments.length;b++){var g=arguments[b];if(g)for(var k in g)f.NO(g,k)&&(a[k]=g[k])}return a}},\"es6-impl\",\"es3\");f.si(\"Array.from\",function(a){return a?a:a=function(a,c,e){f.gm();c=null!=c?c:function(a){return a};var b=[],k=a[Symbol.iterator];if(\"function\"==typeof k)for(a=k.call(a);!(k=a.next()).done;)b.push(c.call(e,k.value));else for(var k=a.length,m=0;m<k;m++)b.push(c.call(e,a[m]));return b}},\"es6-impl\",\"es3\");\nf.IB=function(a){f.gm();var b=a[Symbol.iterator];return b?b.call(a):f.Jw(a)};f.oD=!0;f.wD=!1;\nf.si(\"Promise\",function(a){function b(){this.di=null}if(a&&!f.wD)return a;b.prototype.Mw=function(a){null==this.di&&(this.di=[],this.QJ());this.di.push(a);return this};b.prototype.QJ=function(){var a=this;this.Nw(function(){a.RK()})};var c=f.global.setTimeout;b.prototype.Nw=function(a){c(a,0)};b.prototype.RK=function(){for(;this.di&&this.di.length;){var a=this.di;this.di=[];for(var b=0;b<a.length;++b){var c=a[b];delete a[b];try{c()}catch(v){this.RJ(v)}}}this.di=null};b.prototype.RJ=function(a){this.Nw(function(){throw a;\n})};var e={Ju:0,hu:1,$u:2},g=function(a){this.Bm=e.Ju;this.Fs=void 0;this.nm=[];var b=this.nr();try{a(b.resolve,b.reject)}catch(q){b.reject(q)}};g.prototype.nr=function(){function a(a){return function(e){c||(c=!0,a.call(b,e))}}var b=this,c=!1;return{resolve:a(this.SP),reject:a(this.Cs)}};g.prototype.SP=function(a){if(a===this)this.Cs(new TypeError(\"A Promise cannot resolve to itself\"));else if(a instanceof g)this.TV(a);else{var b;a:switch(typeof a){case \"object\":b=null!=a;break a;case \"function\":b=\n!0;break a;default:b=!1}b?this.RP(a):this.Ix(a)}};g.prototype.RP=function(a){var b=void 0;try{b=a.then}catch(q){this.Cs(q);return}\"function\"==typeof b?this.UV(b,a):this.Ix(a)};g.prototype.Cs=function(a){this.xC(e.$u,a)};g.prototype.Ix=function(a){this.xC(e.hu,a)};g.prototype.xC=function(a,b){if(this.Bm!=e.Ju)throw Error(\"Cannot settle(\"+a+\", \"+b|\"): Promise already settled in state\"+this.Bm);this.Bm=a;this.Fs=b;this.SK()};g.prototype.SK=function(){if(null!=this.nm){for(var a=this.nm,b=0;b<a.length;++b)a[b].call(),\na[b]=null;this.nm=null}};var k=new b;g.prototype.TV=function(a){var b=this.nr();a.co(b.resolve,b.reject)};g.prototype.UV=function(a,b){var c=this.nr();try{a.call(b,c.resolve,c.reject)}catch(v){c.reject(v)}};g.prototype.then=function(a,b){function c(a,b){return\"function\"==typeof a?function(b){try{e(a(b))}catch(K){k(K)}}:b}var e,k,n=new g(function(a,b){e=a;k=b});this.co(c(a,e),c(b,k));return n};g.prototype.catch=function(a){return this.then(void 0,a)};g.prototype.co=function(a,b){function c(){switch(g.Bm){case e.hu:a(g.Fs);\nbreak;case e.$u:b(g.Fs);break;default:throw Error(\"Unexpected state: \"+g.Bm);}}var g=this;null==this.nm?k.Mw(c):this.nm.push(function(){k.Mw(c)})};g.resolve=function(a){return a instanceof g?a:new g(function(b){b(a)})};g.reject=function(a){return new g(function(b,c){c(a)})};g.race=function(a){return new g(function(b,c){for(var e=f.IB(a),k=e.next();!k.done;k=e.next())g.resolve(k.value).co(b,c)})};g.all=function(a){var b=f.IB(a),c=b.next();return c.done?g.resolve([]):new g(function(a,e){function k(b){return function(c){n[b]=\nc;m--;0==m&&a(n)}}var n=[],m=0;do n.push(void 0),m++,g.resolve(c.value).co(k(n.length-1),e),c=b.next();while(!c.done)})};f.oD&&(g.$jscomp$new$AsyncExecutor=function(){return new b});return g},\"es6-impl\",\"es3\");var h=h||{};h.global=this;h.Pe=function(a){return void 0!==a};h.xr=function(a,b,c){a=a.split(\".\");c=c||h.global;a[0]in c||!c.execScript||c.execScript(\"var \"+a[0]);for(var e;a.length&&(e=a.shift());)!a.length&&h.Pe(b)?c[e]=b:c=c[e]&&c[e]!==Object.prototype[e]?c[e]:c[e]={}};\nh.define=function(a,b){h.xr(a,b)};h.Mh=!0;h.yY=\"en\";h.Qp=!0;h.DE=!1;h.$t=!h.Mh;h.bu=!1;h.haa=function(a){if(h.es())throw Error(\"goog.provide can not be used within a goog.module.\");h.hx(a)};h.hx=function(a,b){h.xr(a,b)};h.WE=/^[a-zA-Z_$][a-zA-Z0-9._$]*$/;\nh.module=function(a){if(!h.Hb(a)||!a||-1==a.search(h.WE))throw Error(\"Invalid module identifier\");if(!h.es())throw Error(\"Module \"+a+\" has been loaded incorrectly. Note, modules cannot be loaded as normal scripts. They require some kind of pre-processing step. You're likely trying to load a module via a script tag or as a part of a concatenated bundle without rewriting the module. For more info see: https://github.com/google/closure-library/wiki/goog.module:-an-ES6-module-like-alternative-to-goog.provide.\");if(h.gg.ts)throw Error(\"goog.module may only be called once per module.\");\nh.gg.ts=a};h.module.get=function(){return null};h.module.x6=function(){return null};h.gg=null;h.es=function(){return null!=h.gg};h.module.qr=function(){h.gg.qr=!0};h.wC=function(a){if(h.$t)throw a=a||\"\",Error(\"Importing test-only code into non-debug environment\"+(a?\": \"+a:\".\"));};h.h6=function(){};h.C6=function(a,b){a=a.split(\".\");b=b||h.global;for(var c;c=a.shift();)if(h.Ch(b[c]))b=b[c];else return null;return b};h.M6=function(a,b){b=b||h.global;for(var c in a)b[c]=a[c]};\nh.O1=function(a,b,c,e){if(h.Yt){var g;a=a.replace(/\\\\/g,\"/\");var k=h.dg;e&&\"boolean\"!==typeof e||(e=e?{module:\"goog\"}:{});for(var m=0;g=b[m];m++)k.mm[g]=a,k.ns[a]=e;for(e=0;b=c[e];e++)a in k.qj||(k.qj[a]={}),k.qj[a][b]=!0}};h.rda=!1;h.xX=!0;h.$N=function(a){h.global.console&&h.global.console.error(a)};h.Daa=function(){};h.ci=\"\";h.FO=function(){};h.J1=function(){throw Error(\"unimplemented abstract method\");};\nh.P1=function(a){a.cs=void 0;a.w6=function(){if(a.cs)return a.cs;h.Mh&&(h.lB[h.lB.length]=a);return a.cs=new a}};h.lB=[];h.TD=!0;h.xE=h.Mh;h.ZN={};h.Yt=!1;h.dv=\"detect\";h.IE=\"transpile.js\";\nh.Yt&&(h.dg={ns:{},mm:{},qj:{},MC:{},Gt:{},deferred:{}},h.gB=function(){var a=h.global.document;return null!=a&&\"write\"in a},h.VK=function(){if(h.Pe(h.global.cD))h.ci=h.global.cD;else if(h.gB())for(var a=h.global.document,a=a.getElementsByTagName(\"SCRIPT\"),b=a.length-1;0<=b;--b){var c=a[b],c=c.src,e=c.lastIndexOf(\"?\"),e=-1==e?c.length:e;if(\"base.js\"==c.substr(e-7,7)){h.ci=c.substr(0,e-7);break}}},h.bs=function(a,b){var c=h.global.fX||h.KW;c(a,b)&&(h.dg.Gt[a]=!0)},h.PD=!(h.global.atob||!h.global.document||\n!h.global.document.all),h.dN=function(a,b,c){a='goog.retrieveAndExec_(\"'+a+'\", '+b+\", \"+c+\");\";h.bs(\"\",a)},h.ys=[],h.Ida=function(a,b){return h.TD&&h.Pe(h.global.JSON)?\"goog.loadModule(\"+h.global.JSON.stringify(b+\"\\n//# sourceURL\\x3d\"+a+\"\\n\")+\");\":'goog.loadModule(function(exports) {\"use strict\";'+b+\"\\n;return exports});\\n//# sourceURL\\x3d\"+a+\"\\n\"},h.YN=function(){var a=h.ys.length;if(0<a){var b=h.ys;h.ys=[];for(var c=0;c<a;c++){var e=b[c];h.NB(e)}}},h.E8=function(a){h.pB(a)&&h.GJ(a)&&(a=h.Kr(a),\nh.NB(h.ci+a))},h.pB=function(a){var b=(a=h.Kr(a))&&h.dg.ns[a]||{},c=b.lang||\"es3\";return a&&(\"goog\"==b.module||h.SB(c))?(a=h.ci+a,a in h.dg.deferred):!1},h.GJ=function(a){if((a=h.Kr(a))&&a in h.dg.qj)for(var b in h.dg.qj[a])if(!h.CN(b)&&!h.pB(b))return!1;return!0},h.NB=function(a){if(a in h.dg.deferred){var b=h.dg.deferred[a];delete h.dg.deferred[a];h.globalEval(b)}},h.j8=function(){},h.JW=function(a){h.global.document.write('\\x3cscript type\\x3d\"text/javascript\" src\\x3d\"'+a+'\"\\x3e\\x3c/script\\x3e')},\nh.LJ=function(a){var b=h.global.document,c=b.createElement(\"script\");c.type=\"text/javascript\";c.src=a;c.defer=!1;c.async=!1;b.head.appendChild(c)},h.KW=function(a,b){if(h.gB()){var c=h.global.document;if(!h.bu&&\"complete\"==c.readyState){if(c=/\\bdeps.js$/.test(a))return!1;throw Error('Cannot write \"'+a+'\" after document load');}void 0===b?h.PD?(b=\" onreadystatechange\\x3d'goog.onScriptLoad_(this, \"+ ++h.EB+\")' \",c.write('\\x3cscript type\\x3d\"text/javascript\" src\\x3d\"'+a+'\"'+b+\"\\x3e\\x3c/script\\x3e\")):\nh.bu?h.LJ(a):h.JW(a):c.write('\\x3cscript type\\x3d\"text/javascript\"\\x3e'+h.bP(b)+\"\\x3c/script\\x3e\");return!0}return!1},h.bP=function(a){return a.replace(/<\\/(SCRIPT)/ig,\"\\\\x3c\\\\$1\")},h.SB=function(a){if(\"always\"==h.dv)return!0;if(\"never\"==h.dv)return!1;h.So||(h.So=h.wK());if(a in h.So)return h.So[a];throw Error(\"Unknown language mode: \"+a);},h.So=null,h.EB=0,h.k$=function(a,b){\"complete\"==a.readyState&&h.EB==b&&h.YN();return!0},h.Jda=function(a){function b(a){if(!(a in g.Gt||a in g.MC)){g.MC[a]=!0;\nif(a in g.qj)for(var k in g.qj[a])if(!h.CN(k))if(k in g.mm)b(g.mm[k]);else throw Error(\"Undefined nameToPath for \"+k);a in e||(e[a]=!0,c.push(a))}}var c=[],e={},g=h.dg;b(a);for(a=0;a<c.length;a++){var k=c[a];h.dg.Gt[k]=!0}var m=h.gg;h.gg=null;for(a=0;a<c.length;a++)if(k=c[a]){var n=g.ns[k]||{},q=n.lang||\"es3\",q=h.SB(q);\"goog\"==n.module||q?h.dN(h.ci+k,\"goog\"==n.module,q):h.bs(h.ci+k)}else throw h.gg=m,Error(\"Undefined script input\");h.gg=m},h.Kr=function(a){return a in h.dg.mm?h.dg.mm[a]:null},h.VK(),\nh.global.gX||h.bs(h.ci+\"deps.js\"));h.Vr=null;h.AW=function(){if(null==h.Vr){var a;try{a=!(0,eval)('\"use strict\";let x \\x3d 1; function f() { return typeof x; };f() \\x3d\\x3d \"number\";')}catch(b){a=!1}h.Vr=a}return h.Vr};h.EW=function(a){return\"(function(){\"+a+\"\\n;})();\\n\"};\nh.i8=function(a){var b=h.gg;try{h.gg={ts:void 0,qr:!1};var c;if(h.isFunction(a))c=a.call(void 0,{});else if(h.Hb(a))h.AW()&&(a=h.EW(a)),c=h.XN.call(void 0,a);else throw Error(\"Invalid module definition\");var e=h.gg.ts;if(!h.Hb(e)||!e)throw Error('Invalid module name \"'+e+'\"');h.gg.qr?h.hx(e,c):h.xE&&Object.seal&&\"object\"==typeof c&&null!=c&&Object.seal(c);h.ZN[e]=c}finally{h.gg=b}};h.XN=function(a){var b={};(0,eval)(a);return b};\nh.F9=function(a){a=a.split(\"/\");for(var b=0;b<a.length;)\".\"==a[b]?a.splice(b,1):b&&\"..\"==a[b]&&a[b-1]&&\"..\"!=a[b-1]?a.splice(--b,2):b++;return a.join(\"/\")};h.VN=function(a){if(h.global.eD)return h.global.eD(a);try{var b=new h.global.XMLHttpRequest;b.open(\"get\",a,!1);b.send();return 0==b.status||200==b.status?b.responseText:null}catch(c){return null}};h.Gaa=function(){};\nh.cda=function(a,b){var c=h.global.$jscomp;c||(h.global.$jscomp=c={});var e=c.Bt;if(!e){var g=h.ci+h.IE,k=h.VN(g);if(k){(0,eval)(k+\"\\n//# sourceURL\\x3d\"+g);if(h.global.$gwtExport&&h.global.$gwtExport.$jscomp&&!h.global.$gwtExport.$jscomp.transpile)throw Error('The transpiler did not properly export the \"transpile\" method. $gwtExport: '+JSON.stringify(h.global.$gwtExport));h.global.$jscomp.Bt=h.global.$gwtExport.$jscomp.transpile;c=h.global.$jscomp;e=c.Bt}}if(!e)var m=\" requires transpilation but no transpiler was found.\",\nm=m+' Please add \"//javascript/closure:transpiler\" as a data dependency to ensure it is included.',e=c.Bt=function(a,b){h.$N(b+m);return a};return e(a,b)};\nh.df=function(a){var b=typeof a;if(\"object\"==b)if(a){if(a instanceof Array)return\"array\";if(a instanceof Object)return b;var c=Object.prototype.toString.call(a);if(\"[object Window]\"==c)return\"object\";if(\"[object Array]\"==c||\"number\"==typeof a.length&&\"undefined\"!=typeof a.splice&&\"undefined\"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable(\"splice\"))return\"array\";if(\"[object Function]\"==c||\"undefined\"!=typeof a.call&&\"undefined\"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable(\"call\"))return\"function\"}else return\"null\";\nelse if(\"function\"==b&&\"undefined\"==typeof a.call)return\"object\";return b};h.O7=function(a){return null===a};h.Ch=function(a){return null!=a};h.isArray=function(a){return\"array\"==h.df(a)};h.Gd=function(a){var b=h.df(a);return\"array\"==b||\"object\"==b&&\"number\"==typeof a.length};h.E7=function(a){return h.mj(a)&&\"function\"==typeof a.getFullYear};h.Hb=function(a){return\"string\"==typeof a};h.sk=function(a){return\"boolean\"==typeof a};h.ni=function(a){return\"number\"==typeof a};\nh.isFunction=function(a){return\"function\"==h.df(a)};h.mj=function(a){var b=typeof a;return\"object\"==b&&null!=a||\"function\"==b};h.VA=function(a){return a[h.Ki]||(a[h.Ki]=++h.uW)};h.Q6=function(a){return!!a[h.Ki]};h.yP=function(a){null!==a&&\"removeAttribute\"in a&&a.removeAttribute(h.Ki);try{delete a[h.Ki]}catch(b){}};h.Ki=\"closure_uid_\"+(1E9*Math.random()>>>0);h.uW=0;h.t6=h.VA;h.zaa=h.yP;\nh.gK=function(a){var b=h.df(a);if(\"object\"==b||\"array\"==b){if(a.clone)return a.clone();var b=\"array\"==b?[]:{},c;for(c in a)b[c]=h.gK(a[c]);return b}return a};h.YJ=function(a,b,c){return a.call.apply(a.bind,arguments)};h.XJ=function(a,b,c){if(!a)throw Error();if(2<arguments.length){var e=Array.prototype.slice.call(arguments,2);return function(){var c=Array.prototype.slice.call(arguments);Array.prototype.unshift.apply(c,e);return a.apply(b,c)}}return function(){return a.apply(b,arguments)}};\nh.bind=function(a,b,c){Function.prototype.bind&&-1!=Function.prototype.bind.toString().indexOf(\"native code\")?h.bind=h.YJ:h.bind=h.XJ;return h.bind.apply(null,arguments)};h.xs=function(a,b){var c=Array.prototype.slice.call(arguments,1);return function(){var b=c.slice();b.push.apply(b,arguments);return a.apply(this,b)}};h.mixin=function(a,b){for(var c in b)a[c]=b[c]};h.now=h.Qp&&Date.now||function(){return+new Date};\nh.globalEval=function(a){if(h.global.execScript)h.global.execScript(a,\"JavaScript\");else if(h.global.eval){if(null==h.po)if(h.global.eval(\"var _evalTest_ \\x3d 1;\"),\"undefined\"!=typeof h.global._evalTest_){try{delete h.global._evalTest_}catch(e){}h.po=!0}else h.po=!1;if(h.po)h.global.eval(a);else{var b=h.global.document,c=b.createElement(\"SCRIPT\");c.type=\"text/javascript\";c.defer=!1;c.appendChild(b.createTextNode(a));b.body.appendChild(c);b.body.removeChild(c)}}else throw Error(\"goog.globalEval not available\");\n};h.po=null;h.q6=function(a,b){if(\".\"==String(a).charAt(0))throw Error('className passed in goog.getCssName must not start with \".\". You passed: '+a);var c=function(a){return h.nx[a]||a},e=function(a){a=a.split(\"-\");for(var b=[],e=0;e<a.length;e++)b.push(c(a[e]));return b.join(\"-\")},e=h.nx?\"BY_WHOLE\"==h.zK?c:e:function(a){return a};a=b?a+\"-\"+e(b):e(a);return h.global.dD?h.global.dD(a):a};h.hba=function(a,b){h.nx=a;h.zK=b};\nh.A6=function(a,b){b&&(a=a.replace(/\\{\\$([^}]+)}/g,function(a,e){return null!=b&&e in b?b[e]:a}));return a};h.B6=function(a){return a};h.bc=function(a,b,c){h.xr(a,b,c)};h.Fg=function(a,b,c){a[b]=c};h.da=function(a,b){function c(){}c.prototype=b.prototype;a.ap=b.prototype;a.prototype=new c;a.prototype.constructor=a;a.base=function(a,c,k){for(var e=Array(arguments.length-2),g=2;g<arguments.length;g++)e[g-2]=arguments[g];return b.prototype[c].apply(a,e)}};\nh.base=function(a,b,c){var e=arguments.callee.caller;if(h.DE||h.Mh&&!e)throw Error(\"arguments.caller not defined.  goog.base() cannot be used with strict mode code. See http://www.ecma-international.org/ecma-262/5.1/#sec-C\");if(e.ap){for(var g=Array(arguments.length-1),k=1;k<arguments.length;k++)g[k-1]=arguments[k];return e.ap.constructor.apply(a,g)}g=Array(arguments.length-2);for(k=2;k<arguments.length;k++)g[k-2]=arguments[k];for(var k=!1,m=a.constructor;m;m=m.ap&&m.ap.constructor)if(m.prototype[b]===\ne)k=!0;else if(k)return m.prototype[b].apply(a,g);if(a[b]===e)return a.constructor.prototype[b].apply(a,g);throw Error(\"goog.base called from a method of one name to a method of a different name\");};h.scope=function(a){if(h.es())throw Error(\"goog.scope is not supported within a goog.module.\");a.call(h.global)};\nh.sg=function(a,b){var c=b.constructor,e=b.hW;c&&c!=Object.prototype.constructor||(c=function(){throw Error(\"cannot instantiate an interface (no constructor defined).\");});c=h.sg.xK(c,a);a&&h.da(c,a);delete b.constructor;delete b.hW;h.sg.Hw(c.prototype,b);null!=e&&(e instanceof Function?e(c):h.sg.Hw(c,e));return c};h.sg.wE=h.Mh;\nh.sg.xK=function(a,b){if(!h.sg.wE)return a;var c=!h.sg.HN(b),e=function(){var b=a.apply(this,arguments)||this;b[h.Ki]=b[h.Ki];this.constructor===e&&c&&Object.seal instanceof Function&&Object.seal(b);return b};return e};h.sg.HN=function(a){return a&&a.prototype&&a.prototype[h.PE]};h.sg.Gu=\"constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf\".split(\" \");\nh.sg.Hw=function(a,b){for(var c in b)Object.prototype.hasOwnProperty.call(b,c)&&(a[c]=b[c]);for(var e=0;e<h.sg.Gu.length;e++)c=h.sg.Gu[e],Object.prototype.hasOwnProperty.call(b,c)&&(a[c]=b[c])};h.uca=function(){};h.PE=\"goog_defineClass_legacy_unsealable\";\nh.wK=function(){function a(a,b){e?c[a]=!0:b()?c[a]=!1:e=c[a]=!0}function b(a){try{return!!(0,eval)(a)}catch(k){return!1}}var c={es3:!1},e=!1;a(\"es5\",function(){return b(\"[1,].length\\x3d\\x3d1\")});a(\"es6\",function(){return b('(()\\x3d\\x3e{\"use strict\";class X{constructor(){if(new.target!\\x3dString)throw 1;this.x\\x3d42}}let q\\x3dReflect.construct(X,[],String);if(q.x!\\x3d42||!(q instanceof String))throw 1;for(const a of[2,3]){if(a\\x3d\\x3d2)continue;function f(z\\x3d{a}){let a\\x3d0;return z.a}{function f(){return 0;}}return f()\\x3d\\x3d3}})()')});a(\"es6-impl\",\nfunction(){return!0});a(\"es7\",function(){return b(\"2 ** 2 \\x3d\\x3d 4\")});a(\"es8\",function(){return b(\"async () \\x3d\\x3e 1, true\")});return c};var l={Vb:{}};l.Vb.Ic=function(a,b){this.Zb=a;this.uc=b};d=l.Vb.Ic.prototype;d.hK=function(a){return this.uc<a.uc||this.uc==a.uc&&this.Zb<a.Zb?-1:this.uc==a.uc&&this.Zb==a.Zb?0:1};d.oC=function(){var a=this.uc>>>1,b=this.Zb>>>1|(this.uc&1)<<31;return new l.Vb.Ic(b>>>0,a>>>0)};\nd.FB=function(){var a=this.Zb<<1,b=this.uc<<1|this.Zb>>>31;return new l.Vb.Ic(a>>>0,b>>>0)};d.yO=function(){return!!(this.uc&2147483648)};d.zero=function(){return 0==this.Zb&&0==this.uc};d.add=function(a){var b=(this.Zb+a.Zb&4294967295)>>>0;a=((this.uc+a.uc&4294967295)>>>0)+(4294967296<=this.Zb+a.Zb?1:0);return new l.Vb.Ic(b>>>0,a>>>0)};d.sub=function(a){var b=(this.Zb-a.Zb&4294967295)>>>0;a=((this.uc-a.uc&4294967295)>>>0)-(0>this.Zb-a.Zb?1:0);return new l.Vb.Ic(b>>>0,a>>>0)};\nl.Vb.Ic.RB=function(a,b){var c=a&65535;a>>>=16;var e=b&65535,g=b>>>16;b=c*e+65536*(c*g&65535)+65536*(a*e&65535);for(c=a*g+(c*g>>>16)+(a*e>>>16);4294967296<=b;)b-=4294967296,c+=1;return new l.Vb.Ic(b>>>0,c>>>0)};l.Vb.Ic.prototype.zO=function(a){var b=l.Vb.Ic.RB(this.Zb,a);a=l.Vb.Ic.RB(this.uc,a);a.uc=a.Zb;a.Zb=0;return b.add(a)};\nl.Vb.Ic.prototype.OK=function(a){if(0==a)return[];for(var b=new l.Vb.Ic(0,0),c=new l.Vb.Ic(this.Zb,this.uc),e=new l.Vb.Ic(a,0),g=new l.Vb.Ic(1,0);!e.yO();)e=e.FB(),g=g.FB();for(;!g.zero();)0>=e.hK(c)&&(b=b.add(g),c=c.sub(e)),e=e.oC(),g=g.oC();return[b,c]};l.Vb.Ic.prototype.toString=function(){for(var a=\"\",b=this;!b.zero();)var c=b.OK(10),b=c[0],c=c[1],a=c.Zb+a;\"\"==a&&(a=\"0\");return a};\nl.Vb.Ic.Hx=function(a){for(var b=new l.Vb.Ic(0,0),c=new l.Vb.Ic(0,0),e=0;e<a.length;e++){if(\"0\">a[e]||\"9\"<a[e])return null;var g=parseInt(a[e],10);c.Zb=g;b=b.zO(10).add(c)}return b};l.Vb.Ic.prototype.clone=function(){return new l.Vb.Ic(this.Zb,this.uc)};l.Vb.lh=function(a,b){this.Zb=a;this.uc=b};l.Vb.lh.prototype.add=function(a){var b=(this.Zb+a.Zb&4294967295)>>>0;a=((this.uc+a.uc&4294967295)>>>0)+(4294967296<=this.Zb+a.Zb?1:0);return new l.Vb.lh(b>>>0,a>>>0)};\nl.Vb.lh.prototype.sub=function(a){var b=(this.Zb-a.Zb&4294967295)>>>0;a=((this.uc-a.uc&4294967295)>>>0)-(0>this.Zb-a.Zb?1:0);return new l.Vb.lh(b>>>0,a>>>0)};l.Vb.lh.prototype.clone=function(){return new l.Vb.lh(this.Zb,this.uc)};l.Vb.lh.prototype.toString=function(){var a=0!=(this.uc&2147483648),b=new l.Vb.Ic(this.Zb,this.uc);a&&(b=(new l.Vb.Ic(0,0)).sub(b));return(a?\"-\":\"\")+b.toString()};\nl.Vb.lh.Hx=function(a){var b=0<a.length&&\"-\"==a[0];b&&(a=a.substring(1));a=l.Vb.Ic.Hx(a);if(null===a)return null;b&&(a=(new l.Vb.Ic(0,0)).sub(a));return new l.Vb.lh(a.Zb,a.uc)};l.xa={};l.oX=function(){};l.aX=function(){};l.xa.yD={Gj:-1,kD:1,FLOAT:2,MD:3,NE:4,LD:5,ih:6,hh:7,BOOL:8,Uk:9,WX:10,WD:11,XC:12,ME:13,nD:14,yE:15,zE:16,AE:17,BE:18,pD:30,XE:31};l.xa.kb={Gj:-1,Xe:0,ih:1,jg:2,Tk:3,Jk:4,hh:5};\nl.xa.UX=function(a){var b=l.xa.yD,c=l.xa.kb;switch(a){case b.LD:case b.MD:case b.ME:case b.NE:case b.AE:case b.BE:case b.BOOL:case b.nD:case b.XE:return c.Xe;case b.kD:case b.ih:case b.zE:case b.pD:return c.ih;case b.Uk:case b.WD:case b.XC:return c.jg;case b.FLOAT:case b.hh:case b.yE:return c.hh;default:return c.Gj}};l.xa.Tm=-1;l.xa.PX=1.401298464324817E-45;l.xa.sD=1.1754943508222875E-38;l.xa.vp=3.4028234663852886E38;l.xa.QX=4.9E-324;l.xa.tD=2.2250738585072014E-308;l.xa.wp=1.7976931348623157E308;\nl.xa.JE=1048576;l.xa.KE=8388608;l.xa.Tg=2147483648;l.xa.Xf=4294967296;l.xa.ev=4503599627370496;l.xa.Mj=0x7fffffffffffffff;l.xa.Rp=1.8446744073709552E19;l.xa.z_=\"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\";h.debug={};h.debug.Error=function(a){if(Error.captureStackTrace)Error.captureStackTrace(this,h.debug.Error);else{var b=Error().stack;b&&(this.stack=b)}a&&(this.message=String(a))};h.da(h.debug.Error,Error);h.debug.Error.prototype.name=\"CustomError\";h.dom={};\nh.dom.dE={mD:1,VW:2,e_:3,bX:4,zX:5,yX:6,jZ:7,hX:8,qX:9,sX:10,rX:11,TY:12};h.json={};h.json.Tp=!1;h.json.IN=function(a){if(/^\\s*$/.test(a))return!1;var b=/\\\\[\"\\\\\\/bfnrtu]/g,c=/(?:\"[^\"\\\\\\n\\r\\u2028\\u2029\\x00-\\x08\\x0a-\\x1f]*\"|true|false|null|-?\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d+)?)[\\s\\u2028\\u2029]*(?=:|,|]|}|$)/g,e=/(?:^|:|,)(?:[\\s\\u2028\\u2029]*\\[)+/g,g=/^[\\],:{}\\s\\u2028\\u2029]*$/;return g.test(a.replace(b,\"@\").replace(c,\"]\").replace(e,\"\"))};\nh.json.parse=h.json.Tp?h.global.JSON.parse:function(a){a=String(a);if(h.json.IN(a))try{return(0,eval)(\"(\"+a+\")\")}catch(b){}throw Error(\"Invalid JSON string: \"+a);};h.json.yW=h.json.Tp?h.global.JSON.parse:function(a){return(0,eval)(\"(\"+a+\")\")};h.json.serialize=h.json.Tp?h.global.JSON.stringify:function(a,b){return(new h.json.pg(b)).serialize(a)};h.json.pg=function(a){this.Ro=a};h.json.pg.prototype.serialize=function(a){var b=[];this.Is(a,b);return b.join(\"\")};\nh.json.pg.prototype.Is=function(a,b){if(null==a)b.push(\"null\");else{if(\"object\"==typeof a){if(h.isArray(a)){this.serializeArray(a,b);return}if(a instanceof String||a instanceof Number||a instanceof Boolean)a=a.valueOf();else{this.ZP(a,b);return}}switch(typeof a){case \"string\":this.tC(a,b);break;case \"number\":this.YP(a,b);break;case \"boolean\":b.push(String(a));break;case \"function\":b.push(\"null\");break;default:throw Error(\"Unknown type: \"+typeof a);}}};\nh.json.pg.Zw={'\"':'\\\\\"',\"\\\\\":\"\\\\\\\\\",\"/\":\"\\\\/\",\"\\b\":\"\\\\b\",\"\\f\":\"\\\\f\",\"\\n\":\"\\\\n\",\"\\r\":\"\\\\r\",\"\\t\":\"\\\\t\",\"\\x0B\":\"\\\\u000b\"};h.json.pg.fK=/\\uffff/.test(\"\\uffff\")?/[\\\\\\\"\\x00-\\x1f\\x7f-\\uffff]/g:/[\\\\\\\"\\x00-\\x1f\\x7f-\\xff]/g;h.json.pg.prototype.tC=function(a,b){b.push('\"',a.replace(h.json.pg.fK,function(a){var b=h.json.pg.Zw[a];b||(b=\"\\\\u\"+(a.charCodeAt(0)|65536).toString(16).substr(1),h.json.pg.Zw[a]=b);return b}),'\"')};h.json.pg.prototype.YP=function(a,b){b.push(isFinite(a)&&!isNaN(a)?String(a):\"null\")};\nh.json.pg.prototype.serializeArray=function(a,b){var c=a.length;b.push(\"[\");for(var e=\"\",g=0;g<c;g++)b.push(e),e=a[g],this.Is(this.Ro?this.Ro.call(a,String(g),e):e,b),e=\",\";b.push(\"]\")};h.json.pg.prototype.ZP=function(a,b){b.push(\"{\");var c=\"\",e;for(e in a)if(Object.prototype.hasOwnProperty.call(a,e)){var g=a[e];\"function\"!=typeof g&&(b.push(c),this.tC(e,b),b.push(\":\"),this.Is(this.Ro?this.Ro.call(a,e,g):g,b),c=\",\")}b.push(\"}\")};h.object={};\nh.object.is=function(a,b){return a===b?0!==a||1/a===1/b:a!==a&&b!==b};h.object.forEach=function(a,b,c){for(var e in a)b.call(c,a[e],e,a)};h.object.filter=function(a,b,c){var e={},g;for(g in a)b.call(c,a[g],g,a)&&(e[g]=a[g]);return e};h.object.map=function(a,b,c){var e={},g;for(g in a)e[g]=b.call(c,a[g],g,a);return e};h.object.some=function(a,b,c){for(var e in a)if(b.call(c,a[e],e,a))return!0;return!1};h.object.every=function(a,b,c){for(var e in a)if(!b.call(c,a[e],e,a))return!1;return!0};\nh.object.zh=function(a){var b=0,c;for(c in a)b++;return b};h.object.o6=function(a){for(var b in a)return b};h.object.p6=function(a){for(var b in a)return a[b]};h.object.contains=function(a,b){return h.object.ej(a,b)};h.object.Lc=function(a){var b=[],c=0,e;for(e in a)b[c++]=a[e];return b};h.object.getKeys=function(a){var b=[],c=0,e;for(e in a)b[c++]=e;return b};h.object.L6=function(a,b){for(var c=h.Gd(b),e=c?b:arguments,c=c?0:1;c<e.length&&(a=a[e[c]],h.Pe(a));c++);return a};\nh.object.dj=function(a,b){return null!==a&&b in a};h.object.ej=function(a,b){for(var c in a)if(a[c]==b)return!0;return!1};h.object.XK=function(a,b,c){for(var e in a)if(b.call(c,a[e],e,a))return e};h.object.c6=function(a,b,c){return(b=h.object.XK(a,b,c))&&a[b]};h.object.Zc=function(a){for(var b in a)return!1;return!0};h.object.clear=function(a){for(var b in a)delete a[b]};h.object.remove=function(a,b){var c;(c=b in a)&&delete a[b];return c};\nh.object.add=function(a,b,c){if(null!==a&&b in a)throw Error('The object already contains the key \"'+b+'\"');h.object.set(a,b,c)};h.object.get=function(a,b,c){return null!==a&&b in a?a[b]:c};h.object.set=function(a,b,c){a[b]=c};h.object.kba=function(a,b,c){return b in a?a[b]:a[b]=c};h.object.mba=function(a,b,c){if(b in a)return a[b];c=c();return a[b]=c};h.object.ii=function(a,b){for(var c in a)if(!(c in b)||a[c]!==b[c])return!1;for(c in b)if(!(c in a))return!1;return!0};\nh.object.clone=function(a){var b={},c;for(c in a)b[c]=a[c];return b};h.object.xW=function(a){var b=h.df(a);if(\"object\"==b||\"array\"==b){if(h.isFunction(a.clone))return a.clone();var b=\"array\"==b?[]:{},c;for(c in a)b[c]=h.object.xW(a[c]);return b}return a};h.object.transpose=function(a){var b={},c;for(c in a)b[a[c]]=c;return b};h.object.Ku=\"constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf\".split(\" \");\nh.object.extend=function(a,b){for(var c,e,g=1;g<arguments.length;g++){e=arguments[g];for(c in e)a[c]=e[c];for(var k=0;k<h.object.Ku.length;k++)c=h.object.Ku[k],Object.prototype.hasOwnProperty.call(e,c)&&(a[c]=e[c])}};h.object.create=function(a){var b=arguments.length;if(1==b&&h.isArray(arguments[0]))return h.object.create.apply(null,arguments[0]);if(b%2)throw Error(\"Uneven number of arguments\");for(var c={},e=0;e<b;e+=2)c[arguments[e]]=arguments[e+1];return c};\nh.object.yK=function(a){var b=arguments.length;if(1==b&&h.isArray(arguments[0]))return h.object.yK.apply(null,arguments[0]);for(var c={},e=0;e<b;e++)c[arguments[e]]=!0;return c};h.object.x4=function(a){var b=a;Object.isFrozen&&!Object.isFrozen(a)&&(b=Object.create(a),Object.freeze(b));return b};h.object.K7=function(a){return!!Object.isFrozen&&Object.isFrozen(a)};\nh.object.n6=function(a,b){if(!a)return[];if(!Object.getOwnPropertyNames||!Object.getPrototypeOf)return h.object.getKeys(a);for(var c={};a&&(a!==Object.prototype||b);){for(var e=Object.getOwnPropertyNames(a),g=0;g<e.length;g++)c[e[g]]=!0;a=Object.getPrototypeOf(a)}return h.object.getKeys(c)};h.Ih={};h.Ih.object=function(a,b){return b};h.Ih.st=function(a){h.Ih.st[\" \"](a);return a};h.Ih.st[\" \"]=h.FO;h.Ih.b3=function(a,b){try{return h.Ih.st(a[b]),!0}catch(c){}return!1};\nh.Ih.cache=function(a,b,c,e){e=e?e(b):b;return Object.prototype.hasOwnProperty.call(a,e)?a[e]:a[e]=c(b)};h.ca={};h.ca.qp=!1;h.ca.vD=!1;h.ca.QE={ZD:\"\\u00a0\"};h.ca.startsWith=function(a,b){return 0==a.lastIndexOf(b,0)};h.ca.endsWith=function(a,b){var c=a.length-b.length;return 0<=c&&a.indexOf(b,c)==c};h.ca.l3=function(a,b){return 0==h.ca.Yw(b,a.substr(0,b.length))};h.ca.i3=function(a,b){return 0==h.ca.Yw(b,a.substr(a.length-b.length,b.length))};h.ca.j3=function(a,b){return a.toLowerCase()==b.toLowerCase()};\nh.ca.kW=function(a,b){for(var c=a.split(\"%s\"),e=\"\",g=Array.prototype.slice.call(arguments,1);g.length&&1<c.length;)e+=c.shift()+g.shift();return e+c.join(\"%s\")};h.ca.z3=function(a){return a.replace(/[\\s\\xa0]+/g,\" \").replace(/^\\s+|\\s+$/g,\"\")};h.ca.Co=function(a){return/^[\\s\\xa0]*$/.test(a)};h.ca.I7=function(a){return 0==a.length};h.ca.Zc=h.ca.Co;h.ca.rN=function(a){return h.ca.Co(h.ca.bO(a))};h.ca.H7=h.ca.rN;h.ca.C7=function(a){return!/[^\\t\\n\\r ]/.test(a)};h.ca.A7=function(a){return!/[^a-zA-Z]/.test(a)};\nh.ca.isNumeric=function(a){return!/[^0-9]/.test(a)};h.ca.B7=function(a){return!/[^a-zA-Z0-9]/.test(a)};h.ca.Q7=function(a){return\" \"==a};h.ca.S7=function(a){return 1==a.length&&\" \"<=a&&\"~\">=a||\"\\u0080\"<=a&&\"\\ufffd\">=a};h.ca.dca=function(a){return a.replace(/(\\r\\n|\\r|\\n)+/g,\" \")};h.ca.g3=function(a){return a.replace(/(\\r\\n|\\r|\\n)/g,\"\\n\")};h.ca.H9=function(a){return a.replace(/\\xa0|\\s/g,\" \")};h.ca.G9=function(a){return a.replace(/\\xa0|[ \\t]+/g,\" \")};\nh.ca.y3=function(a){return a.replace(/[\\t\\r\\n ]+/g,\" \").replace(/^[\\t\\r\\n ]+|[\\t\\r\\n ]+$/g,\"\")};h.ca.trim=h.Qp&&String.prototype.trim?function(a){return a.trim()}:function(a){return a.replace(/^[\\s\\xa0]+|[\\s\\xa0]+$/g,\"\")};h.ca.trimLeft=function(a){return a.replace(/^[\\s\\xa0]+/,\"\")};h.ca.trimRight=function(a){return a.replace(/[\\s\\xa0]+$/,\"\")};h.ca.Yw=function(a,b){a=String(a).toLowerCase();b=String(b).toLowerCase();return a<b?-1:a==b?0:1};\nh.ca.UB=function(a,b,c){if(a==b)return 0;if(!a)return-1;if(!b)return 1;for(var e=a.toLowerCase().match(c),g=b.toLowerCase().match(c),k=Math.min(e.length,g.length),m=0;m<k;m++){c=e[m];var n=g[m];if(c!=n)return a=parseInt(c,10),!isNaN(a)&&(b=parseInt(n,10),!isNaN(b)&&a-b)?a-b:c<n?-1:1}return e.length!=g.length?e.length-g.length:a<b?-1:1};h.ca.x7=function(a,b){return h.ca.UB(a,b,/\\d+|\\D+/g)};h.ca.$K=function(a,b){return h.ca.UB(a,b,/\\d+|\\.\\d+|\\D+/g)};h.ca.Z9=h.ca.$K;h.ca.Hm=function(a){return encodeURIComponent(String(a))};\nh.ca.ep=function(a){return decodeURIComponent(a.replace(/\\+/g,\" \"))};h.ca.AO=function(a,b){return a.replace(/(\\r\\n|\\r|\\n)/g,b?\"\\x3cbr /\\x3e\":\"\\x3cbr\\x3e\")};\nh.ca.$r=function(a,b){if(b)a=a.replace(h.ca.It,\"\\x26amp;\").replace(h.ca.Au,\"\\x26lt;\").replace(h.ca.ju,\"\\x26gt;\").replace(h.ca.Yu,\"\\x26quot;\").replace(h.ca.av,\"\\x26#39;\").replace(h.ca.Du,\"\\x26#0;\"),h.ca.qp&&(a=a.replace(h.ca.eu,\"\\x26#101;\"));else{if(!h.ca.SC.test(a))return a;-1!=a.indexOf(\"\\x26\")&&(a=a.replace(h.ca.It,\"\\x26amp;\"));-1!=a.indexOf(\"\\x3c\")&&(a=a.replace(h.ca.Au,\"\\x26lt;\"));-1!=a.indexOf(\"\\x3e\")&&(a=a.replace(h.ca.ju,\"\\x26gt;\"));-1!=a.indexOf('\"')&&(a=a.replace(h.ca.Yu,\"\\x26quot;\"));-1!=\na.indexOf(\"'\")&&(a=a.replace(h.ca.av,\"\\x26#39;\"));-1!=a.indexOf(\"\\x00\")&&(a=a.replace(h.ca.Du,\"\\x26#0;\"));h.ca.qp&&-1!=a.indexOf(\"e\")&&(a=a.replace(h.ca.eu,\"\\x26#101;\"))}return a};h.ca.It=/&/g;h.ca.Au=/</g;h.ca.ju=/>/g;h.ca.Yu=/\"/g;h.ca.av=/'/g;h.ca.Du=/\\x00/g;h.ca.eu=/e/g;h.ca.SC=h.ca.qp?/[\\x00&<>\"'e]/:/[\\x00&<>\"']/;h.ca.IC=function(a){return h.ca.contains(a,\"\\x26\")?!h.ca.vD&&\"document\"in h.global?h.ca.JC(a):h.ca.vW(a):a};h.ca.kda=function(a,b){return h.ca.contains(a,\"\\x26\")?h.ca.JC(a,b):a};\nh.ca.JC=function(a,b){var c={\"\\x26amp;\":\"\\x26\",\"\\x26lt;\":\"\\x3c\",\"\\x26gt;\":\"\\x3e\",\"\\x26quot;\":'\"'},e;e=b?b.createElement(\"div\"):h.global.document.createElement(\"div\");return a.replace(h.ca.HD,function(a,b){var g=c[a];if(g)return g;\"#\"==b.charAt(0)&&(b=Number(\"0\"+b.substr(1)),isNaN(b)||(g=String.fromCharCode(b)));g||(e.innerHTML=a+\" \",g=e.firstChild.nodeValue.slice(0,-1));return c[a]=g})};\nh.ca.vW=function(a){return a.replace(/&([^;]+);/g,function(a,c){switch(c){case \"amp\":return\"\\x26\";case \"lt\":return\"\\x3c\";case \"gt\":return\"\\x3e\";case \"quot\":return'\"';default:return\"#\"!=c.charAt(0)||(c=Number(\"0\"+c.substr(1)),isNaN(c))?a:String.fromCharCode(c)}})};h.ca.HD=/&([^;\\s<&]+);?/g;h.ca.Fda=function(a,b){return h.ca.AO(a.replace(/  /g,\" \\x26#160;\"),b)};h.ca.eaa=function(a){return a.replace(/(^|[\\n ]) /g,\"$1\"+h.ca.QE.ZD)};\nh.ca.eca=function(a,b){for(var c=b.length,e=0;e<c;e++){var g=1==c?b:b.charAt(e);if(a.charAt(0)==g&&a.charAt(a.length-1)==g)return a.substring(1,a.length-1)}return a};h.ca.truncate=function(a,b,c){c&&(a=h.ca.IC(a));a.length>b&&(a=a.substring(0,b-3)+\"...\");c&&(a=h.ca.$r(a));return a};\nh.ca.ida=function(a,b,c,e){c&&(a=h.ca.IC(a));if(e&&a.length>b){e>b&&(e=b);var g=a.length-e;b-=e;a=a.substring(0,b)+\"...\"+a.substring(g)}else a.length>b&&(g=Math.floor(b/2),e=a.length-g,g+=b%2,a=a.substring(0,g)+\"...\"+a.substring(e));c&&(a=h.ca.$r(a));return a};h.ca.tt={\"\\x00\":\"\\\\0\",\"\\b\":\"\\\\b\",\"\\f\":\"\\\\f\",\"\\n\":\"\\\\n\",\"\\r\":\"\\\\r\",\"\\t\":\"\\\\t\",\"\\x0B\":\"\\\\x0B\",'\"':'\\\\\"',\"\\\\\":\"\\\\\\\\\",\"\\x3c\":\"\\x3c\"};h.ca.Fo={\"'\":\"\\\\'\"};\nh.ca.quote=function(a){a=String(a);for(var b=['\"'],c=0;c<a.length;c++){var e=a.charAt(c),g=e.charCodeAt(0);b[c+1]=h.ca.tt[e]||(31<g&&127>g?e:h.ca.Ax(e))}b.push('\"');return b.join(\"\")};h.ca.w5=function(a){for(var b=[],c=0;c<a.length;c++)b[c]=h.ca.Ax(a.charAt(c));return b.join(\"\")};\nh.ca.Ax=function(a){if(a in h.ca.Fo)return h.ca.Fo[a];if(a in h.ca.tt)return h.ca.Fo[a]=h.ca.tt[a];var b,c=a.charCodeAt(0);if(31<c&&127>c)b=a;else{if(256>c){if(b=\"\\\\x\",16>c||256<c)b+=\"0\"}else b=\"\\\\u\",4096>c&&(b+=\"0\");b+=c.toString(16).toUpperCase()}return h.ca.Fo[a]=b};h.ca.contains=function(a,b){return-1!=a.indexOf(b)};h.ca.dK=function(a,b){return h.ca.contains(a.toLowerCase(),b.toLowerCase())};h.ca.p4=function(a,b){return a&&b?a.split(b).length-1:0};\nh.ca.xk=function(a,b,c){var e=a;0<=b&&b<a.length&&0<c&&(e=a.substr(0,b)+a.substr(b+c,a.length-b-c));return e};h.ca.remove=function(a,b){return a.replace(b,\"\")};h.ca.removeAll=function(a,b){b=new RegExp(h.ca.Bs(b),\"g\");return a.replace(b,\"\")};h.ca.replaceAll=function(a,b,c){b=new RegExp(h.ca.Bs(b),\"g\");return a.replace(b,c.replace(/\\$/g,\"$$$$\"))};h.ca.Bs=function(a){return String(a).replace(/([-()\\[\\]{}+?*.$\\^|,:#<!\\\\])/g,\"\\\\$1\").replace(/\\x08/g,\"\\\\x08\")};\nh.ca.repeat=String.prototype.repeat?function(a,b){return a.repeat(b)}:function(a,b){return Array(b+1).join(a)};h.ca.o$=function(a,b,c){a=h.Pe(c)?a.toFixed(c):String(a);c=a.indexOf(\".\");-1==c&&(c=a.length);return h.ca.repeat(\"0\",Math.max(0,b-c))+a};h.ca.bO=function(a){return null==a?\"\":String(a)};h.ca.ZJ=function(a){return Array.prototype.join.call(arguments,\"\")};h.ca.eA=function(){return Math.floor(2147483648*Math.random()).toString(36)+Math.abs(Math.floor(2147483648*Math.random())^h.now()).toString(36)};\nh.ca.yl=function(a,b){var c=0;a=h.ca.trim(String(a)).split(\".\");b=h.ca.trim(String(b)).split(\".\");for(var e=Math.max(a.length,b.length),g=0;0==c&&g<e;g++){var k=a[g]||\"\",m=b[g]||\"\";do{k=/(\\d*)(\\D*)(.*)/.exec(k)||[\"\",\"\",\"\",\"\"];m=/(\\d*)(\\D*)(.*)/.exec(m)||[\"\",\"\",\"\",\"\"];if(0==k[0].length&&0==m[0].length)break;var c=0==k[1].length?0:parseInt(k[1],10),n=0==m[1].length?0:parseInt(m[1],10),c=h.ca.jr(c,n)||h.ca.jr(0==k[2].length,0==m[2].length)||h.ca.jr(k[2],m[2]),k=k[3],m=m[3]}while(0==c)}return c};\nh.ca.jr=function(a,b){return a<b?-1:a>b?1:0};h.ca.U6=function(a){for(var b=0,c=0;c<a.length;++c)b=31*b+a.charCodeAt(c)>>>0;return b};h.ca.wW=2147483648*Math.random()|0;h.ca.z4=function(){return\"goog_\"+h.ca.wW++};h.ca.Dca=function(a){var b=Number(a);return 0==b&&h.ca.Co(a)?NaN:b};h.ca.M7=function(a){return/^[a-z]+([A-Z][a-z]*)*$/.test(a)};h.ca.T7=function(a){return/^([A-Z][a-z]*)+$/.test(a)};h.ca.Bca=function(a){return String(a).replace(/\\-([a-z])/g,function(a,c){return c.toUpperCase()})};\nh.ca.Eca=function(a){return String(a).replace(/([A-Z])/g,\"-$1\").toLowerCase()};h.ca.Fca=function(a,b){b=(b=h.Hb(b)?h.ca.Bs(b):\"\\\\s\")?\"|[\"+b+\"]+\":\"\";b=new RegExp(\"(^\"+b+\")([a-z])\",\"g\");return a.replace(b,function(a,b,g){return b+g.toUpperCase()})};h.ca.h3=function(a){return String(a.charAt(0)).toUpperCase()+String(a.substr(1)).toLowerCase()};h.ca.parseInt=function(a){isFinite(a)&&(a=String(a));return h.Hb(a)?/^\\s*-?0x/i.test(a)?parseInt(a,16):parseInt(a,10):NaN};\nh.ca.Hba=function(a,b,c){a=a.split(b);for(var e=[];0<c&&a.length;)e.push(a.shift()),c--;a.length&&e.push(a.join(b));return e};h.ca.e8=function(a,b){if(b)\"string\"==typeof b&&(b=[b]);else return a;for(var c=-1,e=0;e<b.length;e++)if(\"\"!=b[e]){var g=a.lastIndexOf(b[e]);g>c&&(c=g)}return-1==c?a:a.slice(c+1)};\nh.ca.l5=function(a,b){var c=[],e=[];if(a==b)return 0;if(!a.length||!b.length)return Math.max(a.length,b.length);for(var g=0;g<b.length+1;g++)c[g]=g;for(g=0;g<a.length;g++){e[0]=g+1;for(var k=0;k<b.length;k++){var m=Number(a[g]!=b[k]);e[k+1]=Math.min(e[k]+1,c[k+1]+1,c[k]+m)}for(k=0;k<c.length;k++)c[k]=e[k]}return e[b.length]};var d3={};\n(function(){function a(a){return function(b,c){return Eb(a(b),c)}}function b(a,b,c){var p=Math.abs(b-a)/Math.max(0,c);c=Math.pow(10,Math.floor(Math.log(p)/Math.LN10));p/=c;p>=pm?c*=10:p>=qm?c*=5:p>=rm&&(c*=2);return b<a?-c:c}function c(a){return a.length}function e(a,b,c){a=a(c);return\"translate(\"+(isFinite(a)?a:b(c))+\",0)\"}function g(a,b,c){a=a(c);return\"translate(0,\"+(isFinite(a)?a:b(c))+\")\"}function k(a){var b=a.bandwidth()/2;a.round()&&(b=Math.round(b));return function(c){return a(c)+b}}function m(){return!this.Vp}\nfunction n(a,b){function c(c){var z=null==t?b.ticks?b.ticks.apply(b,p):b.domain():t,I=null==R?b.tickFormat?b.tickFormat.apply(b,p):yh:R,r=Math.max(da,0)+n,P=1===a||3===a?e:g,H=b.range(),F=H[0]+.5,H=H[H.length-1]+.5,ca=(b.bandwidth?k:yh)(b.copy()),qa=c.selection?c.selection():c,T=qa.selectAll(\".domain\").data([null]),z=qa.selectAll(\".tick\").data(z,b).order(),A=z.exit(),L=z.enter().append(\"g\").attr(\"class\",\"tick\"),ja=z.select(\"line\"),M=z.select(\"text\"),G=1===a||4===a?-1:1,fa,Y=4===a||2===a?(fa=\"x\",\"y\"):\n(fa=\"y\",\"x\"),T=T.merge(T.enter().insert(\"path\",\".tick\").attr(\"class\",\"domain\").attr(\"stroke\",\"#000\")),z=z.merge(L),ja=ja.merge(L.append(\"line\").attr(\"stroke\",\"#000\").attr(fa+\"2\",G*da).attr(Y+\"1\",.5).attr(Y+\"2\",.5)),M=M.merge(L.append(\"text\").attr(\"fill\",\"#000\").attr(fa,G*r).attr(Y,.5).attr(\"dy\",1===a?\"0em\":3===a?\"0.71em\":\"0.32em\"));c!==qa&&(T=T.transition(c),z=z.transition(c),ja=ja.transition(c),M=M.transition(c),A=A.transition(c).attr(\"opacity\",1E-6).attr(\"transform\",function(a){return P(ca,this.parentNode.Vp||\nca,a)}),L.attr(\"opacity\",1E-6).attr(\"transform\",function(a){return P(this.parentNode.Vp||ca,ca,a)}));A.remove();T.attr(\"d\",4===a||2==a?\"M\"+G*X+\",\"+F+\"H0.5V\"+H+\"H\"+G*X:\"M\"+F+\",\"+G*X+\"V0.5H\"+H+\"V\"+G*X);z.attr(\"opacity\",1).attr(\"transform\",function(a){return P(ca,ca,a)});ja.attr(fa+\"2\",G*da);M.attr(fa,G*r).text(I);qa.filter(m).attr(\"fill\",\"none\").attr(\"font-size\",10).attr(\"font-family\",\"sans-serif\").attr(\"text-anchor\",2===a?\"start\":4===a?\"end\":\"middle\");qa.each(function(){this.Vp=ca})}var p=[],t=null,\nR=null,da=6,X=6,n=3;c.scale=function(a){return arguments.length?(b=a,c):b};c.ticks=function(){return p=bf.call(arguments),c};c.tickArguments=function(a){return arguments.length?(p=null==a?[]:bf.call(a),c):p.slice()};c.tickValues=function(a){return arguments.length?(t=null==a?null:bf.call(a),c):t&&t.slice()};c.tickFormat=function(a){return arguments.length?(R=a,c):R};c.tickSize=function(a){return arguments.length?(da=X=+a,c):da};c.tickSizeInner=function(a){return arguments.length?(da=+a,c):da};c.tickSizeOuter=\nfunction(a){return arguments.length?(X=+a,c):X};c.tickPadding=function(a){return arguments.length?(n=+a,c):n};return c}function q(a){return n(1,a)}function v(a){return n(2,a)}function B(a){return n(3,a)}function C(a){return n(4,a)}function E(){for(var a=0,b=arguments.length,c={},e;a<b;++a){if(!(e=arguments[a]+\"\")||e in c)throw Error(\"illegal type: \"+e);c[e]=[]}return new W(c)}function W(a){this.Fa=a}function J(a,b){return a.trim().split(/^|\\s+/).map(function(a){var c=\"\",p=a.indexOf(\".\");0<=p&&(c=\na.slice(p+1),a=a.slice(0,p));if(a&&!b.hasOwnProperty(a))throw Error(\"unknown type: \"+a);return{type:a,name:c}})}function K(a,b,c){for(var p=0,t=a.length;p<t;++p)if(a[p].name===b){a[p]=sm;a=a.slice(0,p).concat(a.slice(p+1));break}null!=c&&a.push({name:b,value:c});return a}function O(a){return function(){var b=this.ownerDocument,c=this.namespaceURI;return\"http://www.w3.org/1999/xhtml\"===c&&\"http://www.w3.org/1999/xhtml\"===b.documentElement.namespaceURI?b.createElement(a):b.createElementNS(c,a)}}function Q(a){return function(){return this.ownerDocument.createElementNS(a.space,\na.local)}}function ka(){return new U}function U(){this.Fa=\"@\"+(++tm).toString(36)}function aa(a,b,c){a=na(a,b,c);return function(b){var c=b.relatedTarget;c&&(c===this||c.compareDocumentPosition(this)&8)||a.call(this,b)}}function na(a,b,c){return function(p){var t=d3.event;d3.event=p;try{a.call(this,this.__data__,b,c)}finally{d3.event=t}}}function Ka(a){return a.trim().split(/^|\\s+/).map(function(a){var b=\"\",c=a.indexOf(\".\");0<=c&&(b=a.slice(c+1),a=a.slice(0,c));return{type:a,name:b}})}function ma(a){return function(){var b=\nthis.__on;if(b){for(var c=0,p=-1,e=b.length,g;c<e;++c)(g=b[c],a.type&&g.type!==a.type||g.name!==a.name)?b[++p]=g:this.removeEventListener(g.type,g.listener,g.capture);++p?b.length=p:delete this.__on}}}function cf(a,b,c){var p=zh.hasOwnProperty(a.type)?aa:na;return function(t,e,z){t=this.__on;var I;e=p(b,e,z);if(t){z=0;for(var g=t.length;z<g;++z)if((I=t[z]).type===a.type&&I.name===a.name){this.removeEventListener(I.type,I.listener,I.capture);this.addEventListener(I.type,I.listener=e,I.capture=c);I.value=\nb;return}}this.addEventListener(a.type,e,c);I={type:a.type,name:a.name,value:b,listener:e,capture:c};t?t.push(I):this.__on=[I]}}function Ya(a,b,c,e){var p=d3.event;a.sourceEvent=d3.event;d3.event=a;try{return b.apply(c,e)}finally{d3.event=p}}function df(){}function ef(){return[]}function Fb(a,b){this.ownerDocument=a.ownerDocument;this.namespaceURI=a.namespaceURI;this.Vg=null;this.Ye=a;this.__data__=b}function Dc(a,b,c,e,g,R){for(var p=0,t,z=b.length,I=R.length;p<I;++p)(t=b[p])?(t.__data__=R[p],e[p]=\nt):c[p]=new Fb(a,R[p]);for(;p<z;++p)if(t=b[p])g[p]=t}function vd(a,b,c,e,g,R,k){var p,t,z={},u=b.length,I=R.length,r=Array(u),P;for(p=0;p<u;++p)if(t=b[p])r[p]=P=\"$\"+k.call(t,t.__data__,p,b),P in z?g[p]=t:z[P]=t;for(p=0;p<I;++p)P=\"$\"+k.call(a,R[p],p,R),(t=z[P])?(e[p]=t,t.__data__=R[p],z[P]=null):c[p]=new Fb(a,R[p]);for(p=0;p<u;++p)(t=b[p])&&z[r[p]]===t&&(g[p]=t)}function wd(a,b){return a<b?-1:a>b?1:a>=b?0:NaN}function ta(a){return function(){this.removeAttribute(a)}}function Gb(a){return function(){this.removeAttributeNS(a.space,\na.local)}}function Hb(a,b){return function(){this.setAttribute(a,b)}}function um(a,b){return function(){this.setAttributeNS(a.space,a.local,b)}}function vm(a,b){return function(){var c=b.apply(this,arguments);null==c?this.removeAttribute(a):this.setAttribute(a,c)}}function wm(a,b){return function(){var c=b.apply(this,arguments);null==c?this.removeAttributeNS(a.space,a.local):this.setAttributeNS(a.space,a.local,c)}}function xm(a){return function(){this.style.removeProperty(a)}}function ym(a,b,c){return function(){this.style.setProperty(a,\nb,c)}}function zm(a,b,c){return function(){var p=b.apply(this,arguments);null==p?this.style.removeProperty(a):this.style.setProperty(a,p,c)}}function Am(a){return function(){delete this[a]}}function Bm(a,b){return function(){this[a]=b}}function Cm(a,b){return function(){var c=b.apply(this,arguments);null==c?delete this[a]:this[a]=c}}function ff(a){return a.classList||new Ah(a)}function Ah(a){this.Vv=a;this.Wi=(a.getAttribute(\"class\")||\"\").trim().split(/^|\\s+/)}function Bh(a,b){a=ff(a);for(var c=-1,\np=b.length;++c<p;)a.add(b[c])}function Ch(a,b){a=ff(a);for(var c=-1,p=b.length;++c<p;)a.remove(b[c])}function Dm(a){return function(){Bh(this,a)}}function Em(a){return function(){Ch(this,a)}}function Fm(a,b){return function(){(b.apply(this,arguments)?Bh:Ch)(this,a)}}function Gm(){this.textContent=\"\"}function Hm(a){return function(){this.textContent=a}}function Im(a){return function(){var b=a.apply(this,arguments);this.textContent=null==b?\"\":b}}function Jm(){this.innerHTML=\"\"}function Km(a){return function(){this.innerHTML=\na}}function Lm(a){return function(){var b=a.apply(this,arguments);this.innerHTML=null==b?\"\":b}}function Mm(){this.nextSibling&&this.parentNode.appendChild(this)}function Nm(){this.previousSibling&&this.parentNode.insertBefore(this,this.parentNode.firstChild)}function Om(){return null}function Pm(){var a=this.parentNode;a&&a.removeChild(this)}function Dh(a,b,c){var p=$b(a),t=p.CustomEvent;t?t=new t(b,c):(t=p.document.createEvent(\"Event\"),c?(t.initEvent(b,c.bubbles,c.cancelable),t.detail=c.detail):\nt.initEvent(b,!1,!1));a.dispatchEvent(t)}function Qm(a,b){return function(){return Dh(this,a,b)}}function Rm(a,b){return function(){return Dh(this,a,b.apply(this,arguments))}}function Ga(a,b){this.Dd=a;this.If=b}function Ib(){return new Ga([[document.documentElement]],gf)}function xd(a,b){var c=a.document.documentElement,p=Ma(a).on(\"dragstart.drag\",null);b&&(p.on(\"click.drag\",ac,!0),setTimeout(function(){p.on(\"click.drag\",null)},0));if(\"onselectstart\"in c)p.on(\"selectstart.drag\",null);else c.style.MozUserSelect=\nc.iv,delete c.iv}function hf(a,b,c,e,g,R,k,X,n,m){this.target=a;this.type=b;this.subject=c;this.identifier=e;this.active=g;this.x=R;this.y=k;this.dx=X;this.dy=n;this.Fa=m}function Sm(){return!d3.event.button}function Tm(){return this.parentNode}function Um(a){return null==a?{x:d3.event.x,y:d3.event.y}:a}function Ec(a,b){a=Object.create(a.prototype);for(var c in b)a[c]=b[c];return a}function rb(){}function sb(a){var b;a=(a+\"\").trim().toLowerCase();return(b=Vm.exec(a))?(b=parseInt(b[1],16),new za(b>>\n8&15|b>>4&240,b>>4&15|b&240,(b&15)<<4|b&15,1)):(b=Wm.exec(a))?Eh(parseInt(b[1],16)):(b=Xm.exec(a))?new za(b[1],b[2],b[3],1):(b=Ym.exec(a))?new za(255*b[1]/100,255*b[2]/100,255*b[3]/100,1):(b=Zm.exec(a))?Fh(b[1],b[2],b[3],b[4]):(b=$m.exec(a))?Fh(255*b[1]/100,255*b[2]/100,255*b[3]/100,b[4]):(b=an.exec(a))?Gh(b[1],b[2]/100,b[3]/100,1):(b=bn.exec(a))?Gh(b[1],b[2]/100,b[3]/100,b[4]):Hh.hasOwnProperty(a)?Eh(Hh[a]):\"transparent\"===a?new za(NaN,NaN,NaN,0):null}function Eh(a){return new za(a>>16&255,a>>8&\n255,a&255,1)}function Fh(a,b,c,e){0>=e&&(a=b=c=NaN);return new za(a,b,c,e)}function jf(a){a instanceof rb||(a=sb(a));if(!a)return new za;a=a.rgb();return new za(a.r,a.g,a.b,a.opacity)}function Fc(a,b,c,e){return 1===arguments.length?jf(a):new za(a,b,c,null==e?1:e)}function za(a,b,c,e){this.r=+a;this.g=+b;this.b=+c;this.opacity=+e}function Gh(a,b,c,e){0>=e?a=b=c=NaN:0>=c||1<=c?a=b=NaN:0>=b&&(a=NaN);return new db(a,b,c,e)}function cn(a){if(a instanceof db)return new db(a.h,a.s,a.l,a.opacity);a instanceof\nrb||(a=sb(a));if(!a)return new db;if(a instanceof db)return a;a=a.rgb();var b=a.r/255,c=a.g/255,p=a.b/255,e=Math.min(b,c,p),g=Math.max(b,c,p),k=NaN,X=g-e,n=(g+e)/2;X?(k=b===g?(c-p)/X+6*(c<p):c===g?(p-b)/X+2:(b-c)/X+4,X/=.5>n?g+e:2-g-e,k*=60):X=0<n&&1>n?0:k;return new db(k,X,n,a.opacity)}function yd(a,b,c,e){return 1===arguments.length?cn(a):new db(a,b,c,null==e?1:e)}function db(a,b,c,e){this.h=+a;this.s=+b;this.l=+c;this.opacity=+e}function kf(a,b,c){return 255*(60>a?b+(c-b)*a/60:180>a?c:240>a?b+\n(c-b)*(240-a)/60:b)}function lf(a){if(a instanceof kb)return new kb(a.l,a.a,a.b,a.opacity);if(a instanceof tb){var b=a.h*Ih;return new kb(a.l,Math.cos(b)*a.c,Math.sin(b)*a.c,a.opacity)}a instanceof za||(a=jf(a));var c=mf(a.r),p=mf(a.g),e=mf(a.b),b=nf((.4124564*c+.3575761*p+.1804375*e)/.95047),g=nf((.2126729*c+.7151522*p+.072175*e)/1),c=nf((.0193339*c+.119192*p+.9503041*e)/1.08883);return new kb(116*g-16,500*(b-g),200*(g-c),a.opacity)}function zd(a,b,c,e){return 1===arguments.length?lf(a):new kb(a,\nb,c,null==e?1:e)}function kb(a,b,c,e){this.l=+a;this.a=+b;this.b=+c;this.opacity=+e}function nf(a){return a>dn?Math.pow(a,1/3):a/Jh+Kh}function of(a){return a>bc?a*a*a:Jh*(a-Kh)}function pf(a){return 255*(.0031308>=a?12.92*a:1.055*Math.pow(a,1/2.4)-.055)}function mf(a){return.04045>=(a/=255)?a/12.92:Math.pow((a+.055)/1.055,2.4)}function Ad(a,b,c,e){var p;if(1===arguments.length)if(p=a,p instanceof tb)p=new tb(p.h,p.c,p.l,p.opacity);else{p instanceof kb||(p=lf(p));var t=Math.atan2(p.b,p.a)*Lh;p=new tb(0>\nt?t+360:t,Math.sqrt(p.a*p.a+p.b*p.b),p.l,p.opacity)}else p=new tb(a,b,c,null==e?1:e);return p}function tb(a,b,c,e){this.h=+a;this.c=+b;this.l=+c;this.opacity=+e}function Za(a,b,c,e){var p;if(1===arguments.length)if(p=a,p instanceof Jb)p=new Jb(p.h,p.s,p.l,p.opacity);else{p instanceof za||(p=jf(p));var t=p.r/255,z=p.g/255,g=p.b/255,t=(Mh*g+-1.7884503806*t-3.5172982438*z)/(Mh+-1.7884503806-3.5172982438),g=g-t,I=(1.97294*(z-t)- -.29227*g)/-.90649,g=(z=Math.sqrt(I*I+g*g)/(1.97294*t*(1-t)))?Math.atan2(I,\ng)*Lh-120:NaN;p=new Jb(0>g?g+360:g,z,t,p.opacity)}else p=new Jb(a,b,c,null==e?1:e);return p}function Jb(a,b,c,e){this.h=+a;this.s=+b;this.l=+c;this.opacity=+e}function Nh(a,b,c,e,g){var p=a*a,t=p*a;return((1-3*a+3*p-t)*b+(4-6*p+3*t)*c+(1+3*a+3*p-3*t)*e+t*g)/6}function Oh(a,b){return function(c){return a+c*b}}function en(a,b,c){return a=Math.pow(a,c),b=Math.pow(b,c)-a,c=1/c,function(p){return Math.pow(a+p*b,c)}}function qf(a,b){var c=b-a;return c?Oh(a,180<c||-180>c?c-360*Math.round(c/360):c):Bd(isNaN(a)?\nb:a)}function fn(a){return 1===(a=+a)?ya:function(b,c){return c-b?en(b,c,a):Bd(isNaN(b)?c:b)}}function ya(a,b){var c=b-a;return c?Oh(a,c):Bd(isNaN(a)?b:a)}function Ph(a){return function(b){var c=b.length,p=Array(c),e=Array(c),t=Array(c),g,k;for(g=0;g<c;++g)k=Fc(b[g]),p[g]=k.r||0,e[g]=k.g||0,t[g]=k.b||0;p=a(p);e=a(e);t=a(t);k.opacity=1;return function(a){k.r=p(a);k.g=e(a);k.b=t(a);return k+\"\"}}}function gn(a){return function(){return a}}function hn(a){return function(b){return a(b)+\"\"}}function jn(a){if(\"none\"===\na)return rf;Gc||(Gc=document.createElement(\"DIV\"),sf=document.documentElement,Qh=document.defaultView);Gc.style.transform=a;a=Qh.getComputedStyle(sf.appendChild(Gc),null).getPropertyValue(\"transform\");sf.removeChild(Gc);a=a.slice(7,-1).split(\",\");return Rh(+a[0],+a[1],+a[2],+a[3],+a[4],+a[5])}function kn(a){if(null==a)return rf;Cd||(Cd=document.createElementNS(\"http://www.w3.org/2000/svg\",\"g\"));Cd.setAttribute(\"transform\",a);if(!(a=Cd.transform.baseVal.consolidate()))return rf;a=a.matrix;return Rh(a.a,\na.b,a.c,a.d,a.e,a.f)}function Sh(a,b,c,e){function p(a){return a.length?a.pop()+\" \":\"\"}function t(a,p,e,t,z,g){a!==e||p!==t?(z=z.push(\"translate(\",null,b,null,c),g.push({uf:z-4,x:Na(a,e)},{uf:z-2,x:Na(p,t)})):(e||t)&&z.push(\"translate(\"+e+b+t+c)}function z(a,b,c,t){a!==b?(180<a-b?b+=360:180<b-a&&(a+=360),t.push({uf:c.push(p(c)+\"rotate(\",null,e)-2,x:Na(a,b)})):b&&c.push(p(c)+\"rotate(\"+b+e)}function g(a,b,c,t){a!==b?t.push({uf:c.push(p(c)+\"skewX(\",null,e)-2,x:Na(a,b)}):b&&c.push(p(c)+\"skewX(\"+b+e)}\nfunction I(a,b,c,e,t,z){a!==c||b!==e?(t=t.push(p(t)+\"scale(\",null,\",\",null,\")\"),z.push({uf:t-4,x:Na(a,c)},{uf:t-2,x:Na(b,e)})):1===c&&1===e||t.push(p(t)+\"scale(\"+c+\",\"+e+\")\")}return function(b,c){var p=[],e=[];b=a(b);c=a(c);t(b.zt,b.At,c.zt,c.At,p,e);z(b.rotate,c.rotate,p,e);g(b.skewX,c.skewX,p,e);I(b.Gs,b.Hs,c.Gs,c.Hs,p,e);b=c=null;return function(a){for(var b=-1,c=e.length,t;++b<c;)p[(t=e[b]).uf]=t.x(a);return p.join(\"\")}}}function Th(a){return((a=Math.exp(a))+1/a)/2}function Uh(a){return function(b,\nc){var p=a((b=yd(b)).h,(c=yd(c)).h),e=ya(b.s,c.s),t=ya(b.l,c.l),z=ya(b.opacity,c.opacity);return function(a){b.h=p(a);b.s=e(a);b.l=t(a);b.opacity=z(a);return b+\"\"}}}function ln(a,b){var c=ya((a=zd(a)).l,(b=zd(b)).l),p=ya(a.a,b.a),e=ya(a.b,b.b),t=ya(a.opacity,b.opacity);return function(b){a.l=c(b);a.a=p(b);a.b=e(b);a.opacity=t(b);return a+\"\"}}function Vh(a){return function(b,c){var p=a((b=Ad(b)).h,(c=Ad(c)).h),e=ya(b.c,c.c),t=ya(b.l,c.l),z=ya(b.opacity,c.opacity);return function(a){b.h=p(a);b.c=e(a);\nb.l=t(a);b.opacity=z(a);return b+\"\"}}}function Wh(a){return function z(b){function c(c,p){var e=a((c=Za(c)).h,(p=Za(p)).h),z=ya(c.s,p.s),g=ya(c.l,p.l),u=ya(c.opacity,p.opacity);return function(a){c.h=e(a);c.s=z(a);c.l=g(Math.pow(a,b));c.opacity=u(a);return c+\"\"}}b=+b;c.gamma=z;return c}(1)}function cc(){return ub||(Xh(mn),ub=tf.now()+uf)}function mn(){ub=0}function Hc(){this.$f=this.ml=this.Vg=null}function Dd(a,b,c){var p=new Hc;p.restart(a,b,c);return p}function Yh(){cc();++dc;for(var a=Ed,b;a;)0<=\n(b=ub-a.ml)&&a.$f.call(null,b),a=a.Vg;--dc}function Zh(){ub=(Fd=tf.now())+uf;dc=Ic=0;try{Yh()}finally{dc=0;for(var a,b=Ed,c,e=Infinity;b;)b.$f?(e>b.ml&&(e=b.ml),a=b,b=b.Vg):(c=b.Vg,b.Vg=null,b=a?a.Vg=c:Ed=c);Jc=a;vf(e);ub=0}}function nn(){var a=tf.now(),b=a-Fd;1E3<b&&(uf-=b,Fd=a)}function vf(a){if(!dc){Ic&&(Ic=clearTimeout(Ic));var b=a-ub;24<b?(Infinity>a&&(Ic=setTimeout(Zh,b)),Kc&&(Kc=clearInterval(Kc))):(Kc||(Fd=ub,Kc=setInterval(nn,1E3)),dc=1,Xh(Zh))}}function wf(a,b){a=a.zg;if(!a||!(a=a[b])||\n0<a.state)throw Error(\"too late\");return a}function Kb(a,b){a=a.zg;if(!a||!(a=a[b])||2<a.state)throw Error(\"too late\");return a}function lb(a,b){a=a.zg;if(!a||!(a=a[b]))throw Error(\"too late\");return a}function on(a,b,c){function p(a){c.state=1;c.timer.restart(e,c.delay,c.time);c.delay<=a&&e(a-c.delay)}function e(p){var u,I,r,P;if(1!==c.state)return z();for(u in g)if(P=g[u],P.name===c.name){if(3===P.state)return xf(e);4===P.state?(P.state=6,P.timer.stop(),P.on.call(\"interrupt\",a,a.__data__,P.index,\nP.group),delete g[u]):+u<b&&(P.state=6,P.timer.stop(),delete g[u])}xf(function(){3===c.state&&(c.state=4,c.timer.restart(t,c.delay,c.time),t(p))});c.state=2;c.on.call(\"start\",a,a.__data__,c.index,c.group);if(2===c.state){c.state=3;k=Array(r=c.tween.length);u=0;for(I=-1;u<r;++u)if(P=c.tween[u].value.call(a,a.__data__,c.index,c.group))k[++I]=P;k.length=I+1}}function t(b){b=b<c.duration?c.ease.call(null,b/c.duration):(c.timer.restart(z),c.state=5,1);for(var p=-1,e=k.length;++p<e;)k[p].call(null,b);5===\nc.state&&(c.on.call(\"end\",a,a.__data__,c.index,c.group),z())}function z(){c.state=6;c.timer.stop();delete g[b];for(var p in g)return;delete a.zg}var g=a.zg,k;g[b]=c;c.timer=Dd(p,0,c.time)}function pn(a,b){var c,p;return function(){var e=Kb(this,a),t=e.tween;if(t!==c){p=c=t;for(var t=0,z=p.length;t<z;++t)if(p[t].name===b){p=p.slice();p.splice(t,1);break}}e.tween=p}}function qn(a,b,c){var p,e;if(\"function\"!==typeof c)throw Error();return function(){var t=Kb(this,a),z=t.tween;if(z!==p){e=(p=z).slice();\nfor(var z={name:b,value:c},g=0,I=e.length;g<I;++g)if(e[g].name===b){e[g]=z;break}g===I&&e.push(z)}t.tween=e}}function yf(a,b,c){var p=a.Kc;a.each(function(){var a=Kb(this,p);(a.value||(a.value={}))[b]=c.apply(this,arguments)});return function(a){return lb(a,p).value[b]}}function rn(a){return function(){this.removeAttribute(a)}}function sn(a){return function(){this.removeAttributeNS(a.space,a.local)}}function tn(a,b,c){var p,e;return function(){var t=this.getAttribute(a);return t===c?null:t===p?e:\ne=b(p=t,c)}}function un(a,b,c){var p,e;return function(){var t=this.getAttributeNS(a.space,a.local);return t===c?null:t===p?e:e=b(p=t,c)}}function vn(a,b,c){var p,e,t;return function(){var z,g=c(this);if(null==g)return void this.removeAttribute(a);z=this.getAttribute(a);return z===g?null:z===p&&g===e?t:t=b(p=z,e=g)}}function wn(a,b,c){var p,e,t;return function(){var z,g=c(this);if(null==g)return void this.removeAttributeNS(a.space,a.local);z=this.getAttributeNS(a.space,a.local);return z===g?null:\nz===p&&g===e?t:t=b(p=z,e=g)}}function xn(a,b){function c(){var c=this,p=b.apply(c,arguments);return p&&function(b){c.setAttributeNS(a.space,a.local,p(b))}}c.uh=b;return c}function yn(a,b){function c(){var c=this,p=b.apply(c,arguments);return p&&function(b){c.setAttribute(a,p(b))}}c.uh=b;return c}function zn(a,b){return function(){wf(this,a).delay=+b.apply(this,arguments)}}function An(a,b){return b=+b,function(){wf(this,a).delay=b}}function Bn(a,b){return function(){Kb(this,a).duration=+b.apply(this,\narguments)}}function Cn(a,b){return b=+b,function(){Kb(this,a).duration=b}}function Dn(a,b){if(\"function\"!==typeof b)throw Error();return function(){Kb(this,a).ease=b}}function En(a){return(a+\"\").trim().split(/^|\\s+/).every(function(a){var b=a.indexOf(\".\");0<=b&&(a=a.slice(0,b));return!a||\"start\"===a})}function Fn(a,b,c){var p,e,t=En(b)?wf:Kb;return function(){var z=t(this,a),g=z.on;if(g!==p)(e=(p=g).copy()).on(b,c);z.on=e}}function Gn(a){return function(){var b=this.parentNode,c;for(c in this.zg)if(+c!==\na)return;b&&b.removeChild(this)}}function Hn(a,b){var c,p,e;return function(){var t=$b(this).getComputedStyle(this,null),z=t.getPropertyValue(a),t=(this.style.removeProperty(a),t.getPropertyValue(a));return z===t?null:z===c&&t===p?e:e=b(c=z,p=t)}}function In(a){return function(){this.style.removeProperty(a)}}function Jn(a,b,c){var p,e;return function(){var t=$b(this).getComputedStyle(this,null).getPropertyValue(a);return t===c?null:t===p?e:e=b(p=t,c)}}function Kn(a,b,c){var p,e,t;return function(){var z=\n$b(this).getComputedStyle(this,null),g=z.getPropertyValue(a),I=c(this);null==I&&(I=(this.style.removeProperty(a),z.getPropertyValue(a)));return g===I?null:g===p&&I===e?t:t=b(p=g,e=I)}}function Ln(a,b,c){function p(){var p=this,e=b.apply(p,arguments);return e&&function(b){p.style.setProperty(a,e(b),c)}}p.uh=b;return p}function Mn(a){return function(){this.textContent=a}}function Nn(a){return function(){var b=a(this);this.textContent=null==b?\"\":b}}function eb(a,b,c,e){this.Dd=a;this.If=b;this.Uj=c;\nthis.Kc=e}function $h(a){return Ib().transition(a)}function On(a){return+a}function Pn(a){return a*a}function Qn(a){return a*(2-a)}function ai(a){return(1>=(a*=2)?a*a:--a*(2-a)+1)/2}function Rn(a){return a*a*a}function Sn(a){return--a*a*a+1}function zf(a){return(1>=(a*=2)?a*a*a:(a-=2)*a*a+2)/2}function Tn(a){return 1-Math.cos(a*bi)}function Un(a){return Math.sin(a*bi)}function ci(a){return(1-Math.cos(di*a))/2}function Vn(a){return Math.pow(2,10*a-10)}function Wn(a){return 1-Math.pow(2,-10*a)}function ei(a){return(1>=\n(a*=2)?Math.pow(2,10*a-10):2-Math.pow(2,10-10*a))/2}function Xn(a){return 1-Math.sqrt(1-a*a)}function Yn(a){return Math.sqrt(1- --a*a)}function fi(a){return(1>=(a*=2)?1-Math.sqrt(1-a*a):Math.sqrt(1-(a-=2)*a)+1)/2}function Zn(a){return 1-Lc(1-a)}function Lc(a){return(a=+a)<Af?Gd*a*a:a<$n?Gd*(a-=ao)*a+.75:a<bo?Gd*(a-=co)*a+.9375:Gd*(a-=eo)*a+.984375}function fo(a){return(1>=(a*=2)?1-Lc(1-a):Lc(a-1)+1)/2}function Mc(a){return{type:a}}function go(){return!d3.event.button}function ho(){var a=this.ownerSVGElement||\nthis;return[[0,0],[a.width.baseVal.value,a.height.baseVal.value]]}function Bf(a){for(;!a.__brush;)if(!(a=a.parentNode))return;return a.__brush}function Cf(a){return a[0][0]===a[1][0]||a[0][1]===a[1][1]}function io(a){return(a=a.__brush)?a.LK.No(a.selection):null}function jo(){return Df(Hd)}function ko(){return Df(Id)}function Df(a){function b(b){var p=b.property(\"__brush\",k).selectAll(\".overlay\").data([Mc(\"overlay\")]);p.enter().append(\"rect\").attr(\"class\",\"overlay\").attr(\"pointer-events\",\"all\").attr(\"cursor\",\nmb.overlay).merge(p).each(function(){var a=Bf(this).extent;Ma(this).attr(\"x\",a[0][0]).attr(\"y\",a[0][1]).attr(\"width\",a[1][0]-a[0][0]).attr(\"height\",a[1][1]-a[0][1])});b.selectAll(\".selection\").data([Mc(\"selection\")]).enter().append(\"rect\").attr(\"class\",\"selection\").attr(\"cursor\",mb.selection).attr(\"fill\",\"#777\").attr(\"fill-opacity\",.3).attr(\"stroke\",\"#fff\").attr(\"shape-rendering\",\"crispEdges\");p=b.selectAll(\".handle\").data(a.Ur,function(a){return a.type});p.exit().remove();p.enter().append(\"rect\").attr(\"class\",\nfunction(a){return\"handle handle--\"+a.type}).attr(\"cursor\",function(a){return mb[a.type]});b.each(c).attr(\"fill\",\"none\").attr(\"pointer-events\",\"all\").style(\"-webkit-tap-highlight-color\",\"rgba(0,0,0,0)\").on(\"mousedown.brush touchstart.brush\",g)}function c(){var a=Ma(this),b=Bf(this).selection;b?(a.selectAll(\".selection\").style(\"display\",null).attr(\"x\",b[0][0]).attr(\"y\",b[0][1]).attr(\"width\",b[1][0]-b[0][0]).attr(\"height\",b[1][1]-b[0][1]),a.selectAll(\".handle\").style(\"display\",null).attr(\"x\",function(a){return\"e\"===\na.type[a.type.length-1]?b[1][0]-u/2:b[0][0]-u/2}).attr(\"y\",function(a){return\"s\"===a.type[0]?b[1][1]-u/2:b[0][1]-u/2}).attr(\"width\",function(a){return\"n\"===a.type||\"s\"===a.type?b[1][0]-b[0][0]+u:u}).attr(\"height\",function(a){return\"e\"===a.type||\"w\"===a.type?b[1][1]-b[0][1]+u:u})):a.selectAll(\".selection,.handle\").style(\"display\",\"none\").attr(\"x\",null).attr(\"y\",null).attr(\"width\",null).attr(\"height\",null)}function p(a,b){return a.__brush.zx||new e(a,b)}function e(a,b){this.Kh=a;this.Wq=b;this.state=\na.__brush;this.active=0}function g(){function b(){var a=vb(u);!aa||ka||ta||(Math.abs(a[0]-ma[0])>Math.abs(a[1]-ma[1])?ta=!0:ka=!0);ma=a;na=!0;Jd();e()}function e(){var a;Q=ma[0]-Nc[0];U=ma[1]-Nc[1];switch(P){case Ef:case gi:R&&(Q=Math.max(Y-fa,Math.min(E-J,Q)),q=fa+Q,C=J+Q);k&&(U=Math.max(jb-v,Math.min(W-O,U)),B=v+U,K=O+U);break;case ec:0>R?(Q=Math.max(Y-fa,Math.min(E-fa,Q)),q=fa+Q,C=J):0<R&&(Q=Math.max(Y-J,Math.min(E-J,Q)),q=fa,C=J+Q);0>k?(U=Math.max(jb-v,Math.min(W-v,U)),B=v+U,K=O):0<k&&(U=Math.max(jb-\nO,Math.min(W-O,U)),B=v,K=O+U);break;case fc:R&&(q=Math.max(Y,Math.min(E,fa-Q*R)),C=Math.max(Y,Math.min(E,J+Q*R))),k&&(B=Math.max(jb,Math.min(W,v-U*k)),K=Math.max(jb,Math.min(W,O+U*k)))}C<q&&(R*=-1,a=fa,fa=J,J=a,a=q,q=C,C=a,I in hi&&Oc.attr(\"cursor\",mb[I=hi[I]]));K<B&&(k*=-1,a=v,v=O,O=a,a=B,B=K,K=a,I in ii&&Oc.attr(\"cursor\",mb[I=ii[I]]));da.selection&&(X=da.selection);ka&&(q=X[0][0],C=X[1][0]);ta&&(B=X[0][1],K=X[1][1]);if(X[0][0]!==q||X[0][1]!==B||X[1][0]!==C||X[1][1]!==K)da.selection=[[q,B],[C,K]],\nc.call(u),Ka.brush()}function t(){d3.event.stopImmediatePropagation();if(d3.event.touches){if(d3.event.touches.length)return;y&&clearTimeout(y);y=setTimeout(function(){y=null},500);N.on(\"touchmove.brush touchend.brush touchcancel.brush\",null)}else xd(d3.event.view,na),no.on(\"keydown.brush keyup.brush mousemove.brush mouseup.brush\",null);N.attr(\"pointer-events\",\"all\");Oc.attr(\"cursor\",mb.overlay);da.selection&&(X=da.selection);Cf(X)&&(da.selection=null,c.call(u));Ka.end()}function z(){switch(d3.event.keyCode){case 16:aa=\nR&&k;break;case 18:P===ec&&(R&&(J=C-Q*R,fa=q+Q*R),k&&(O=K-U*k,v=B+U*k),P=fc,e());break;case 32:if(P===ec||P===fc)0>R?J=C-Q:0<R&&(fa=q-Q),0>k?O=K-U:0<k&&(v=B-U),P=Ef,Oc.attr(\"cursor\",mb.selection),e();break;default:return}Jd()}function g(){switch(d3.event.keyCode){case 16:aa&&(ka=ta=aa=!1,e());break;case 18:P===fc&&(0>R?J=C:0<R&&(fa=q),0>k?O=K:0<k&&(v=B),P=ec,e());break;case 32:P===Ef&&(d3.event.altKey?(R&&(J=C-Q*R,fa=q+Q*R),k&&(O=K-U*k,v=B+U*k),P=fc):(0>R?J=C:0<R&&(fa=q),0>k?O=K:0<k&&(v=B),P=ec),\nOc.attr(\"cursor\",mb[I]),e());break;default:return}Jd()}if(d3.event.touches){if(d3.event.changedTouches.length<d3.event.touches.length)return Jd()}else if(y)return;if(m.apply(this,arguments)){var u=this,I=d3.event.target.__data__.type,P=\"selection\"===(d3.event.metaKey?I=\"overlay\":I)?gi:d3.event.altKey?fc:ec,R=a===Id?null:oo[I],k=a===Hd?null:po[I],da=Bf(u),n=da.extent,X=da.selection,Y=n[0][0],fa,q,jb=n[0][1],v,B,E=n[1][0],J,C,W=n[1][1],O,K,Q,U,na,aa=R&&k&&d3.event.shiftKey,ka,ta,Nc=vb(u),ma=Nc,Ka=p(u,\narguments).$q();\"overlay\"===I?da.selection=X=[[fa=a===Id?Y:Nc[0],v=a===Hd?jb:Nc[1]],[J=a===Id?E:fa,O=a===Hd?W:v]]:(fa=X[0][0],v=X[0][1],J=X[1][0],O=X[1][1]);q=fa;B=v;C=J;K=O;var N=Ma(u).attr(\"pointer-events\",\"none\"),Oc=N.selectAll(\".overlay\").attr(\"cursor\",mb[I]);if(d3.event.touches)N.on(\"touchmove.brush\",b,!0).on(\"touchend.brush touchcancel.brush\",t,!0);else{var no=Ma(d3.event.view).on(\"keydown.brush\",z,!0).on(\"keyup.brush\",g,!0).on(\"mousemove.brush\",b,!0).on(\"mouseup.brush\",t,!0);Kd(d3.event.view)}d3.event.stopImmediatePropagation();\nLb(u);c.call(u);Ka.start()}}function k(){var b=this.__brush||{selection:null};b.extent=n.apply(this,arguments);b.LK=a;return b}var n=ho,m=go,q=E(b,\"start\",\"brush\",\"end\"),u=6,y;b.move=function(b,e){b.selection?b.on(\"start.brush\",function(){p(this,arguments).$q().start()}).on(\"interrupt.brush end.brush\",function(){p(this,arguments).end()}).tween(\"brush\",function(){function b(a){z.selection=1===a&&Cf(u)?null:I(a);c.call(t);r.brush()}var t=this,z=t.__brush,r=p(t,arguments),g=z.selection,u=a.input(\"function\"===\ntypeof e?e.apply(this,arguments):e,z.extent),I=Pc(g,u);return g&&u?b:b(1)}):b.each(function(){var b=this,t=arguments,z=b.__brush,r=a.input(\"function\"===typeof e?e.apply(b,t):e,z.extent),t=p(b,t).$q();Lb(b);z.selection=null==r||Cf(r)?null:r;c.call(b);t.start().brush().end()})};e.prototype={$q:function(){1===++this.active&&(this.state.zx=this,this.AC=!0);return this},start:function(){this.AC&&(this.AC=!1,this.gj(\"start\"));return this},brush:function(){this.gj(\"brush\");return this},end:function(){0===\n--this.active&&(delete this.state.zx,this.gj(\"end\"));return this},gj:function(c){Ya(new qo(b,c,a.No(this.state.selection)),q.apply,q,[c,this.Kh,this.Wq])}};b.extent=function(a){return arguments.length?(n=\"function\"===typeof a?a:ji([[+a[0][0],+a[0][1]],[+a[1][0],+a[1][1]]]),b):n};b.filter=function(a){return arguments.length?(m=\"function\"===typeof a?a:ji(!!a),b):m};b.handleSize=function(a){return arguments.length?(u=+a,b):u};b.on=function(){var a=q.on.apply(q,arguments);return a===q?b:a};return b}function ro(a){return function(b,\nc){return a(b.source.value+b.target.value,c.source.value+c.target.value)}}function Ff(){this.ub=this.xb=this.Sa=this.Va=null;this.Fa=\"\"}function Mb(){return new Ff}function so(a){return a.source}function to(a){return a.target}function uo(a){return a.radius}function vo(a){return a.startAngle}function wo(a){return a.endAngle}function Ld(){}function fb(a,b){var c=new Ld;if(a instanceof Ld)a.each(function(a,b){c.set(b,a)});else if(Array.isArray(a)){var p=-1,e=a.length,t;if(null==b)for(;++p<e;)c.set(p,\na[p]);else for(;++p<e;)c.set(b(t=a[p],p,a),t)}else if(a)for(p in a)c.set(p,a[p]);return c}function xo(){return{}}function yo(a,b,c){a[b]=c}function ki(){return fb()}function li(a,b,c){a.set(b,c)}function Md(){}function mi(a,b){var c=new Md;if(a instanceof Md)a.each(function(a){c.add(a)});else if(a){var p=-1,e=a.length;if(null==b)for(;++p<e;)c.add(a[p]);else for(;++p<e;)c.add(b(a[p],p,a))}return c}function ni(a){return new Function(\"d\",\"return {\"+a.map(function(a,b){return JSON.stringify(a)+\": d[\"+\nb+\"]\"}).join(\",\")+\"}\")}function zo(a,b){var c=ni(a);return function(p,e){return b(c(p),e,a)}}function Ao(a){var b=Object.create(null),c=[];a.forEach(function(a){for(var p in a)p in b||c.push(b[p]=p)});return c}function oi(a,b,c,e){if(isNaN(b)||isNaN(c))return a;var p,t=a.ve;e={data:e};var z=a.ub,g=a.xb,I=a.Sa,k=a.Va,u,y,r,w,H,F;if(!t)return a.ve=e,a;for(;t.length;)if((H=b>=(u=(z+I)/2))?z=u:I=u,(F=c>=(y=(g+k)/2))?g=y:k=y,p=t,!(t=t[H|=F<<1]))return p[H]=e,a;r=+a.tc.call(null,t.data);w=+a.ce.call(null,\nt.data);if(b===r&&c===w)return e.next=t,p?p[H]=e:a.ve=e,a;do p=p?p[H]=Array(4):a.ve=Array(4),(H=b>=(u=(z+I)/2))?z=u:I=u,(F=c>=(y=(g+k)/2))?g=y:k=y;while((H|=F<<1)===(F=(w>=y)<<1|r>=u));return p[F]=t,p[H]=e,a}function Bo(a){var b,c,p=a.length,e,g,k=Array(p),n=Array(p),m=Infinity,q=Infinity,u=-Infinity,y=-Infinity;for(c=0;c<p;++c)isNaN(e=+this.tc.call(null,b=a[c]))||isNaN(g=+this.ce.call(null,b))||(k[c]=e,n[c]=g,e<m&&(m=e),e>u&&(u=e),g<q&&(q=g),g>y&&(y=g));u<m&&(m=this.ub,u=this.Sa);y<q&&(q=this.xb,\ny=this.Va);this.cover(m,q).cover(u,y);for(c=0;c<p;++c)oi(this,k[c],n[c],a[c]);return this}function Co(a){for(var b=0,c=a.length;b<c;++b)this.remove(a[b]);return this}function Do(a){return a[0]}function Eo(a){return a[1]}function Nd(a,b,c){b=new Gf(null==b?Do:b,null==c?Eo:c,NaN,NaN,NaN,NaN);return null==a?b:b.addAll(a)}function Gf(a,b,c,e,g,R){this.tc=a;this.ce=b;this.ub=c;this.xb=e;this.Sa=g;this.Va=R;this.ve=void 0}function pi(a){for(var b={data:a.data},c=b;a=a.next;)c=c.next={data:a.data};return b}\nfunction Fo(a){return a.x+a.vx}function Go(a){return a.y+a.vy}function Ho(a){return a.index}function qi(a,b){a=a.get(b);if(!a)throw Error(\"missing: \"+b);return a}function Io(a){return a.x}function Jo(a){return a.y}function ri(a){if(!(b=Ko.exec(a)))throw Error(\"invalid format: \"+a);var b;a=b[1]||\" \";var c=b[2]||\"\\x3e\",e=b[3]||\"-\",p=b[4]||\"\",g=!!b[5],k=b[6]&&+b[6],n=!!b[7],m=b[8]&&+b[8].slice(1);b=b[9]||\"\";\"n\"===b?(n=!0,b=\"g\"):si[b]||(b=\"\");if(g||\"0\"===a&&\"\\x3d\"===c)g=!0,a=\"0\",c=\"\\x3d\";this.fill=a;\nthis.align=c;this.sign=e;this.symbol=p;this.zero=g;this.width=k;this.comma=n;this.precision=m;this.type=b}function Lo(a){return a}function ti(a){Od=ui(a);d3.format=Od.format;d3.formatPrefix=Od.formatPrefix;return Od}function $a(){this.reset()}function vi(a,b,c){var e=a.s=b+c,p=e-b,e=e-p;a.t=b-e+(c-p)}function wi(a){return 1<a?0:-1>a?ha:Math.acos(a)}function Oa(a){return 1<a?ra:-1>a?-ra:Math.asin(a)}function xi(a){return(a=N(a/2))*a}function sa(){}function Pd(a,b){if(a&&yi.hasOwnProperty(a.type))yi[a.type](a,\nb)}function Hf(a,b,c){var e=-1;c=a.length-c;var p;for(b.lineStart();++e<c;)p=a[e],b.point(p[0],p[1],p[2]);b.lineEnd()}function zi(a,b){var c=-1,e=a.length;for(b.polygonStart();++c<e;)Hf(a[c],b,1);b.polygonEnd()}function Mo(){gb.point=No}function Oo(){Ai(Bi,Ci)}function No(a,b){gb.point=Ai;Bi=a;Ci=b;a*=Z;b*=Z;If=a;Jf=S(b=b/2+Qd);Kf=N(b)}function Ai(a,b){a*=Z;b*=Z;b=b/2+Qd;var c=a-If,e=0<=c?1:-1,p=e*c,c=S(b);b=N(b);var t=Kf*b,g=Jf*c+t*S(p),e=t*e*N(p);Rd.add(Ba(e,g));If=a;Jf=c;Kf=b}function Sd(a){return[Ba(a[1],\na[0]),Oa(a[2])]}function Nb(a){var b=a[0];a=a[1];var c=S(a);return[c*S(b),c*N(b),N(a)]}function Td(a,b){return a[0]*b[0]+a[1]*b[1]+a[2]*b[2]}function gc(a,b){return[a[1]*b[2]-a[2]*b[1],a[2]*b[0]-a[0]*b[2],a[0]*b[1]-a[1]*b[0]]}function Lf(a,b){a[0]+=b[0];a[1]+=b[1];a[2]+=b[2]}function Ud(a,b){return[a[0]*b,a[1]*b,a[2]*b]}function Vd(a){var b=wa(a[0]*a[0]+a[1]*a[1]+a[2]*a[2]);a[0]/=b;a[1]/=b;a[2]/=b}function Mf(a,b){wb.push(nb=[ua=a,va=a]);b<Pa&&(Pa=b);b>Ta&&(Ta=b)}function Di(a,b){var c=Nb([a*Z,b*\nZ]);if(hc){var e=gc(hc,c),p=[e[1],-e[0],0],e=gc(p,e);Vd(e);var e=Sd(e),t=a-Ob,p=0<t?1:-1,g=e[0]*pa*p,t=180<ia(t);t^(p*Ob<g&&g<p*a)?(e=e[1]*pa,e>Ta&&(Ta=e)):(g=(g+360)%360-180,t^(p*Ob<g&&g<p*a))?(e=-e[1]*pa,e<Pa&&(Pa=e)):(b<Pa&&(Pa=b),b>Ta&&(Ta=b));t?a<Ob?Qa(ua,a)>Qa(ua,va)&&(va=a):Qa(a,va)>Qa(ua,va)&&(ua=a):va>=ua?(a<ua&&(ua=a),a>va&&(va=a)):a>Ob?Qa(ua,a)>Qa(ua,va)&&(va=a):Qa(a,va)>Qa(ua,va)&&(ua=a)}else wb.push(nb=[ua=a,va=a]);b<Pa&&(Pa=b);b>Ta&&(Ta=b);hc=c;Ob=a}function Ei(){ob.point=Di}function Fi(){nb[0]=\nua;nb[1]=va;ob.point=Mf;hc=null}function Gi(a,b){if(hc){var c=a-Ob;Qc.add(180<ia(c)?c+(0<c?360:-360):c)}else Hi=a,Ii=b;gb.point(a,b);Di(a,b)}function Po(){gb.lineStart()}function Qo(){Gi(Hi,Ii);gb.lineEnd();1E-6<ia(Qc)&&(ua=-(va=180));nb[0]=ua;nb[1]=va;hc=null}function Qa(a,b){return 0>(b-=a)?b+360:b}function Ro(a,b){return a[0]-b[0]}function Ji(a,b){return a[0]<=a[1]?a[0]<=b&&b<=a[1]:b<a[0]||a[1]<b}function Nf(a,b){a*=Z;b*=Z;var c=S(b);Rc(c*S(a),c*N(a),N(b))}function Rc(a,b,c){++Sc;Wd+=(a-Wd)/Sc;\nXd+=(b-Xd)/Sc;Yd+=(c-Yd)/Sc}function Ki(){ab.point=So}function So(a,b){a*=Z;b*=Z;var c=S(b);Ca=c*S(a);Da=c*N(a);Ea=N(b);ab.point=To;Rc(Ca,Da,Ea)}function To(a,b){a*=Z;b*=Z;var c=S(b),e=c*S(a);a=c*N(a);b=N(b);var p=Ba(wa((p=Da*b-Ea*a)*p+(p=Ea*e-Ca*b)*p+(p=Ca*a-Da*e)*p),Ca*e+Da*a+Ea*b);Zd+=p;$d+=p*(Ca+(Ca=e));ae+=p*(Da+(Da=a));be+=p*(Ea+(Ea=b));Rc(Ca,Da,Ea)}function Li(){ab.point=Nf}function Uo(){ab.point=Vo}function Wo(){Mi(Ni,Oi);ab.point=Nf}function Vo(a,b){Ni=a;Oi=b;a*=Z;b*=Z;ab.point=Mi;var c=\nS(b);Ca=c*S(a);Da=c*N(a);Ea=N(b);Rc(Ca,Da,Ea)}function Mi(a,b){a*=Z;b*=Z;var c=S(b),e=c*S(a);a=c*N(a);b=N(b);var c=Da*b-Ea*a,p=Ea*e-Ca*b,t=Ca*a-Da*e,g=wa(c*c+p*p+t*t),k=Ca*e+Da*a+Ea*b,n=g&&-Oa(g)/g,g=Ba(g,k);Of+=n*c;Pf+=n*p;Qf+=n*t;Zd+=g;$d+=g*(Ca+(Ca=e));ae+=g*(Da+(Da=a));be+=g*(Ea+(Ea=b));Rc(Ca,Da,Ea)}function Rf(a,b){return[a>ha?a-La:a<-ha?a+La:a,b]}function Sf(a,b,c){return(a%=La)?b||c?Pi(Qi(a),Ri(b,c)):Qi(a):b||c?Ri(b,c):Rf}function Si(a){return function(b,c){return b+=a,[b>ha?b-La:b<-ha?b+La:\nb,c]}}function Qi(a){var b=Si(a);b.invert=Si(-a);return b}function Ri(a,b){function c(a,b){var c=S(b),z=S(a)*c;a=N(a)*c;b=N(b);c=b*e+z*p;return[Ba(a*t-c*g,z*e-b*p),Oa(c*t+a*g)]}var e=S(a),p=N(a),t=S(b),g=N(b);c.invert=function(a,b){var c=S(b),z=S(a)*c;a=N(a)*c;b=N(b);c=b*t-a*g;return[Ba(a*t+b*g,z*e+c*p),Oa(c*e-z*p)]};return c}function Ti(a,b,c,e,g,k){if(c){var p=S(b),t=N(b);c*=e;if(null==g)g=b+e*La,k=b-c/2;else if(g=Ui(p,g),k=Ui(p,k),0<e?g<k:g>k)g+=e*La;for(;0<e?g>k:g<k;g-=c)b=Sd([p,-t*S(g),-t*N(g)]),\na.point(b[0],b[1])}}function Ui(a,b){b=Nb(b);b[0]-=a;Vd(b);a=wi(-b[1]);return((0>-b[2]?-a:a)+La-1E-6)%La}function ce(a,b,c,e){this.x=a;this.z=b;this.Mo=c;this.e=e;this.Ak=!1;this.n=this.p=null}function Vi(a){if(b=a.length){for(var b,c=0,e=a[0],p;++c<b;)e.n=p=a[c],p.p=e,e=p;e.n=p=a[0];p.p=e}}function Tf(a,b,c,e){function p(p,g,u,I){var r=0,w=0;if(null==p||(r=t(p,u))!==(w=t(g,u))||0>z(p,g)^0<u){do I.point(0===r||3===r?a:c,1<r?e:b);while((r=(r+u+4)%4)!==w)}else I.point(g[0],g[1])}function t(e,p){return 1E-6>\nia(e[0]-a)?0<p?0:3:1E-6>ia(e[0]-c)?0<p?2:1:1E-6>ia(e[1]-b)?0<p?1:0:0<p?3:2}function g(a,b){return z(a.x,b.x)}function z(a,b){var c=t(a,1),e=t(b,1);return c!==e?c-e:0===c?b[1]-a[1]:1===c?a[0]-b[0]:2===c?a[1]-b[1]:b[0]-a[0]}return function(t){function z(p,t){a<=p&&p<=c&&b<=t&&t<=e&&P.point(p,t)}function u(){P=R;n=[];da=[];v=!0}function I(){for(var b,c=b=0,z=da.length;c<z;++c)for(var r=da[c],u=1,I=r.length,w=r[0],k,y,R=w[0],w=w[1];u<I;++u)k=R,y=w,w=r[u],R=w[0],w=w[1],y<=e?w>e&&(R-k)*(e-y)>(w-y)*(a-k)&&\n++b:w<=e&&(R-k)*(e-y)<(w-y)*(a-k)&&--b;c=v&&b;z=(n=Uf(n)).length;if(c||z)t.polygonStart(),c&&(t.lineStart(),p(null,null,1,t),t.lineEnd()),z&&Wi(n,g,b,p,t),t.polygonEnd();P=t;n=da=A=null}function r(){B.point=k;da&&da.push(A=[]);fa=!0;Y=!1;G=q=NaN}function w(){n&&(k(X,m),M&&Y&&R.qP(),n.push(R.result()));B.point=z;Y&&P.lineEnd()}function k(p,t){var g=a<=p&&p<=c&&b<=t&&t<=e;da&&A.push([p,t]);if(fa)X=p,m=t,M=g,fa=!1,g&&(P.lineStart(),P.point(p,t));else if(g&&Y)P.point(p,t);else{var z=[G=Math.max(-1E9,\nMath.min(1E9,G)),q=Math.max(-1E9,Math.min(1E9,q))],r=[p=Math.max(-1E9,Math.min(1E9,p)),t=Math.max(-1E9,Math.min(1E9,t))];Xo(z,r,a,b,c,e)?(Y||(P.lineStart(),P.point(z[0],z[1])),P.point(r[0],r[1]),g||P.lineEnd(),v=!1):g&&(P.lineStart(),P.point(p,t),v=!1)}G=p;q=t;Y=g}var P=t,R=Xi(),n,da,A,X,m,M,G,q,Y,fa,v,B={point:z,lineStart:r,lineEnd:w,polygonStart:u,polygonEnd:I};return B}}function Yo(){ic.point=Zo;ic.lineEnd=$o}function $o(){ic.point=ic.lineEnd=sa}function Zo(a,b){a*=Z;b*=Z;Vf=a;de=N(b);ee=S(b);\nic.point=ap}function ap(a,b){a*=Z;b*=Z;var c=N(b);b=S(b);var e=ia(a-Vf),p=S(e),e=N(e),e=b*e,t=ee*c-de*b*p,p=de*c+ee*b*p;Wf.add(Ba(wa(e*e+t*t),p));Vf=a;de=c;ee=b}function Yi(a,b,c){var e=bb(a,b-1E-6,c).concat(b);return function(a){return e.map(function(b){return[a,b]})}}function Zi(a,b,c){var e=bb(a,b-1E-6,c).concat(b);return function(a){return e.map(function(b){return[b,a]})}}function $i(){function a(){return{type:\"MultiLineString\",coordinates:b()}}function b(){return bb(fe(k/r)*r,g,r).map(ca).concat(bb(fe(q/\nw)*w,m,w).map(qa)).concat(bb(fe(e/u)*u,c,u).filter(function(a){return 1E-6<ia(a%r)}).map(H)).concat(bb(fe(X/y)*y,n,y).filter(function(a){return 1E-6<ia(a%w)}).map(F))}var c,e,g,k,n,X,m,q,u=10,y=u,r=90,w=360,H,F,ca,qa,T=2.5;a.lines=function(){return b().map(function(a){return{type:\"LineString\",coordinates:a}})};a.outline=function(){return{type:\"Polygon\",coordinates:[ca(k).concat(qa(m).slice(1),ca(g).reverse().slice(1),qa(q).reverse().slice(1))]}};a.extent=function(b){return arguments.length?a.extentMajor(b).extentMinor(b):\na.extentMinor()};a.extentMajor=function(b){if(!arguments.length)return[[k,q],[g,m]];k=+b[0][0];g=+b[1][0];q=+b[0][1];m=+b[1][1];k>g&&(b=k,k=g,g=b);q>m&&(b=q,q=m,m=b);return a.precision(T)};a.extentMinor=function(b){if(!arguments.length)return[[e,X],[c,n]];e=+b[0][0];c=+b[1][0];X=+b[0][1];n=+b[1][1];e>c&&(b=e,e=c,c=b);X>n&&(b=X,X=n,n=b);return a.precision(T)};a.step=function(b){return arguments.length?a.stepMajor(b).stepMinor(b):a.stepMinor()};a.stepMajor=function(b){if(!arguments.length)return[r,\nw];r=+b[0];w=+b[1];return a};a.stepMinor=function(b){if(!arguments.length)return[u,y];u=+b[0];y=+b[1];return a};a.precision=function(b){if(!arguments.length)return T;T=+b;H=Yi(X,n,90);F=Zi(e,c,T);ca=Yi(q,m,90);qa=Zi(k,g,T);return a};return a.extentMajor([[-180,-89.999999],[180,89.999999]]).extentMinor([[-180,-80.000001],[180,80.000001]])}function bp(){return $i()()}function cp(){pb.point=dp}function dp(a,b){pb.point=aj;bj=Xf=a;cj=Yf=b}function aj(a,b){Zf.add(Yf*a-Xf*b);Xf=a;Yf=b}function ep(){aj(bj,\ncj)}function fp(a,b){a<jc&&(jc=a);a>Tc&&(Tc=a);b<ge&&(ge=b);b>he&&(he=b)}function Pb(a,b){$f+=a;ag+=b;++Uc}function dj(){Ua.point=gp}function gp(a,b){Ua.point=hp;Pb(hb=a,ib=b)}function hp(a,b){var c=a-hb,e=b-ib,c=wa(c*c+e*e);ie+=c*(hb+a)/2;je+=c*(ib+b)/2;kc+=c;Pb(hb=a,ib=b)}function ej(){Ua.point=Pb}function ip(){Ua.point=jp}function kp(){fj(gj,hj)}function jp(a,b){Ua.point=fj;Pb(gj=hb=a,hj=ib=b)}function fj(a,b){var c=a-hb,e=b-ib,c=wa(c*c+e*e);ie+=c*(hb+a)/2;je+=c*(ib+b)/2;kc+=c;c=ib*a-hb*b;bg+=\nc*(hb+a);cg+=c*(ib+b);Vc+=3*c;Pb(hb=a,ib=b)}function ij(a){this.Ia=a}function lp(a,b){Wc.point=jj;kj=Xc=a;lj=Yc=b}function jj(a,b){Xc-=a;Yc-=b;dg.add(wa(Xc*Xc+Yc*Yc));Xc=a;Yc=b}function mj(){this.Yi=[]}function nj(a){return\"m0,\"+a+\"a\"+a+\",\"+a+\" 0 1,1 0,\"+-2*a+\"a\"+a+\",\"+a+\" 0 1,1 0,\"+2*a+\"z\"}function mp(a){return 1<a.length}function np(a,b){return(0>(a=a.x)[0]?a[1]-ra-1E-6:ra-a[1])-(0>(b=b.x)[0]?b[1]-ra-1E-6:ra-b[1])}function op(a){var b=NaN,c=NaN,e=NaN,p;return{lineStart:function(){a.lineStart();\np=1},point:function(t,g){var z=0<t?ha:-ha,I=ia(t-b);if(1E-6>ia(I-ha))a.point(b,c=0<(c+g)/2?ra:-ra),a.point(e,c),a.lineEnd(),a.lineStart(),a.point(z,c),a.point(t,c),p=0;else if(e!==z&&I>=ha){1E-6>ia(b-e)&&(b-=1E-6*e);1E-6>ia(t-z)&&(t-=1E-6*z);var I=b,k=c,u=t,y=g,r,w,P=N(I-u);c=1E-6<ia(P)?lc((N(k)*(w=S(y))*N(u)-N(y)*(r=S(k))*N(I))/(r*w*P)):(k+y)/2;a.point(e,c);a.lineEnd();a.lineStart();a.point(z,c);p=0}a.point(b=t,c=g);e=z},lineEnd:function(){a.lineEnd();b=c=NaN},$w:function(){return 2-p}}}function pp(a,\nb,c,e){null==a?(c*=ra,e.point(-ha,c),e.point(0,c),e.point(ha,c),e.point(ha,0),e.point(ha,-c),e.point(0,-c),e.point(-ha,-c),e.point(-ha,0),e.point(-ha,c)):1E-6<ia(a[0]-b[0])?(a=a[0]<b[0]?ha:-ha,c=c*a/2,e.point(-a,c),e.point(0,c),e.point(a,c)):e.point(b[0],b[1])}function ke(a){return function(b){var c=new eg,e;for(e in a)c[e]=a[e];c.stream=b;return c}}function eg(){}function mc(a,b,c){var e=b[1][0]-b[0][0],p=b[1][1]-b[0][1],t=a.clipExtent&&a.clipExtent();a.scale(150).translate([0,0]);null!=t&&a.clipExtent(null);\ncb(c,a.stream(le));var g=le.result();c=Math.min(e/(g[1][0]-g[0][0]),p/(g[1][1]-g[0][1]));e=+b[0][0]+(e-c*(g[1][0]+g[0][0]))/2;b=+b[0][1]+(p-c*(g[1][1]+g[0][1]))/2;null!=t&&a.clipExtent(t);return a.scale(150*c).translate([e,b])}function oj(a){return ke({point:function(b,c){b=a(b,c);this.stream.point(b[0],b[1])}})}function pj(a,b){function c(e,p,t,g,z,k,n,u,y,r,w,H,F,m){var I=n-e,P=u-p,A=I*I+P*P;if(A>4*b&&F--){var R=g+r,da=z+w,ca=k+H,G=wa(R*R+da*da+ca*ca),X=Oa(ca/=G),Y=1E-6>ia(ia(ca)-1)||1E-6>ia(t-\ny)?(t+y)/2:Ba(da,R),q=a(Y,X),X=q[0],q=q[1],fa=X-e,v=q-p,B=P*fa-I*v;if(B*B/A>b||.3<ia((I*fa+P*v)/A-.5)||g*r+z*w+k*H<qp)c(e,p,t,g,z,k,X,q,Y,R/=G,da/=G,ca,F,m),m.point(X,q),c(X,q,Y,R,da,ca,n,u,y,r,w,H,F,m)}}return function(b){function e(c,e){c=a(c,e);b.point(c[0],c[1])}function p(){T=NaN;G.point=t;b.lineStart()}function t(e,p){var t=Nb([e,p]);p=a(e,p);c(T,A,qa,L,ja,M,T=p[0],A=p[1],qa=e,L=t[0],ja=t[1],M=t[2],16,b);b.point(T,A)}function g(){G.point=e;b.lineEnd()}function z(){p();G.point=k;G.lineEnd=u}\nfunction k(a,b){t(y=a,b);r=T;w=A;I=L;n=ja;m=M;G.point=t}function u(){c(T,A,qa,L,ja,M,r,w,y,I,n,m,16,b);G.lineEnd=g;g()}var y,r,w,I,n,m,qa,T,A,L,ja,M,G={point:e,lineStart:p,lineEnd:g,polygonStart:function(){b.polygonStart();G.lineStart=z},polygonEnd:function(){b.polygonEnd();G.lineStart=p}};return G}}function xb(a){return fg(function(){return a})()}function fg(a){function b(a){a=T(a[0]*Z,a[1]*Z);return[a[0]*n+u,y-a[1]*n]}function c(a){return(a=T.invert((a[0]-u)/n,(y-a[1])/n))&&[a[0]*pa,a[1]*pa]}function e(a,\nb){return a=k(a,b),[a[0]*n+u,y-a[1]*n]}function p(){T=Pi(qa=Sf(H,F,ca),k);var a=k(r,w);u=m-a[0]*n;y=q+a[1]*n;return g()}function g(){B=E=null;return b}var k,n=150,m=480,q=250,u,y,r=0,w=0,H=0,F=0,ca=0,qa,T,A=null,L=qj,ja=null,M,G,Xa,Y=Qb,Aa=.5,v=+Aa?pj(e,Aa):oj(e),B,E;b.stream=function(a){return B&&E===a?B:B=rp(L(qa,v(Y(E=a))))};b.clipAngle=function(a){return arguments.length?(L=+a?sp(A=a*Z,6*Z):(A=null,qj),g()):A*pa};b.clipExtent=function(a){return arguments.length?(Y=null==a?(ja=M=G=Xa=null,Qb):\nTf(ja=+a[0][0],M=+a[0][1],G=+a[1][0],Xa=+a[1][1]),g()):null==ja?null:[[ja,M],[G,Xa]]};b.scale=function(a){return arguments.length?(n=+a,p()):n};b.translate=function(a){return arguments.length?(m=+a[0],q=+a[1],p()):[m,q]};b.center=function(a){return arguments.length?(r=a[0]%360*Z,w=a[1]%360*Z,p()):[r*pa,w*pa]};b.rotate=function(a){return arguments.length?(H=a[0]%360*Z,F=a[1]%360*Z,ca=2<a.length?a[2]%360*Z:0,p()):[H*pa,F*pa,ca*pa]};b.precision=function(a){var b;arguments.length?(b=Aa=a*a,b=+b?pj(e,\nb):oj(e),b=(v=b,g())):b=wa(Aa);return b};b.fitExtent=function(a,c){return mc(b,a,c)};b.fitSize=function(a,c){return mc(b,[[0,0],a],c)};return function(){k=a.apply(this,arguments);b.invert=k.invert&&c;return p()}}function gg(a){var b=0,c=ha/3,e=fg(a);a=e(b,c);a.parallels=function(a){return arguments.length?e(b=a[0]*Z,c=a[1]*Z):[b*pa,c*pa]};return a}function tp(a){function b(a,b){return[a*c,N(b)/c]}var c=S(a);b.invert=function(a,b){return[a/c,Oa(b*c)]};return b}function rj(a,b){function c(a,b){b=wa(t-\n2*p*N(b))/p;return[b*N(a*=p),g-b*S(a)]}var e=N(a),p=(e+N(b))/2;if(1E-6>ia(p))return tp(a);var t=1+e*(2*p-e),g=wa(t)/p;c.invert=function(a,b){b=g-b;return[Ba(a,ia(b))/p*Zc(b),Oa((t-(a*a+b*b)*p*p)/(2*p))]};return c}function up(a){var b=a.length;return{point:function(c,e){for(var p=-1;++p<b;)a[p].point(c,e)},sphere:function(){for(var c=-1;++c<b;)a[c].sphere()},lineStart:function(){for(var c=-1;++c<b;)a[c].lineStart()},lineEnd:function(){for(var c=-1;++c<b;)a[c].lineEnd()},polygonStart:function(){for(var c=\n-1;++c<b;)a[c].polygonStart()},polygonEnd:function(){for(var c=-1;++c<b;)a[c].polygonEnd()}}}function sj(a){return function(b,c){var e=S(b),p=S(c),e=a(e*p);return[e*p*N(b),e*N(c)]}}function $c(a){return function(b,c){var e=wa(b*b+c*c),p=a(e),t=N(p),p=S(p);return[Ba(b*t,e*p),Oa(e&&c*t/e)]}}function me(a,b){return[a,ne(nc((ra+b)/2))]}function tj(a){var b=xb(a),c=b.scale,e=b.translate,p=b.clipExtent,g;b.scale=function(a){return arguments.length?(c(a),g&&b.clipExtent(null),b):c()};b.translate=function(a){return arguments.length?\n(e(a),g&&b.clipExtent(null),b):e()};b.clipExtent=function(a){if(!arguments.length)return g?null:p();if(g=null==a){var t=ha*c(),z=e();a=[[z[0]-t,z[1]-t],[z[0]+t,z[1]+t]]}p(a);return b};return b.clipExtent(null)}function uj(a,b){function c(a,b){0<t?b<-ra+1E-6&&(b=-ra+1E-6):b>ra-1E-6&&(b=ra-1E-6);b=t/hg(nc((ra+b)/2),p);return[b*N(p*a),t-b*S(p*a)]}var e=S(a),p=a===b?N(a):ne(e/S(b))/ne(nc((ra+b)/2)/nc((ra+a)/2)),t=e*hg(nc((ra+a)/2),p)/p;if(!p)return me;c.invert=function(a,b){b=t-b;var c=Zc(p)*wa(a*a+b*\nb);return[Ba(a,ia(b))/p*Zc(b),2*lc(hg(t/c,1/p))-ra]};return c}function ad(a,b){return[a,b]}function vj(a,b){function c(a,b){b=t-b;a*=p;return[b*N(a),t-b*S(a)]}var e=S(a),p=a===b?N(a):(e-S(b))/(b-a),t=e/p+a;if(1E-6>ia(p))return ad;c.invert=function(a,b){b=t-b;return[Ba(a,ia(b))/p*Zc(b),t-Zc(p)*wa(a*a+b*b)]};return c}function ig(a,b){var c=S(b),e=S(a)*c;return[c*N(a)/e,N(b)/e]}function oe(a,b,c,e){return 1===a&&1===b&&0===c&&0===e?Qb:ke({point:function(p,t){this.stream.point(p*a+c,t*b+e)}})}function jg(a,\nb){return[S(b)*N(a),N(b)]}function kg(a,b){var c=S(b),e=1+S(a)*c;return[c*N(a)/e,N(b)/e]}function lg(a,b){return[ne(nc((ra+b)/2)),-a]}function vp(a,b){return a.parent===b.parent?1:2}function wp(a,b){return a+b.x}function xp(a,b){return Math.max(a,b.y)}function yp(a){for(var b;b=a.children;)a=b[0];return a}function zp(a){for(var b;b=a.children;)a=b[b.length-1];return a}function Ap(a){var b=0,c=a.children,e=c&&c.length;if(e)for(;0<=--e;)b+=c[e].value;else b=1;a.value=b}function mg(a,b){var c=new oc(a);\na=+a.value&&(c.value=a.value);var e,p=[c],t,g,k,n;for(null==b&&(b=Bp);e=p.pop();)if(a&&(e.value=+e.data.value),(g=b(e.data))&&(n=g.length))for(e.children=Array(n),k=n-1;0<=k;--k)p.push(t=e.children[k]=new oc(g[k])),t.parent=e,t.depth=e.depth+1;return c.eachBefore(wj)}function Cp(){return mg(this).eachBefore(Dp)}function Bp(a){return a.children}function Dp(a){a.data=a.data.data}function wj(a){var b=0;do a.height=b;while((a=a.parent)&&a.height<++b)}function oc(a){this.data=a;this.depth=this.height=\n0;this.parent=null}function Ep(a){this.Fa=a;this.next=null}function xj(a,b){var c,e=null,p=a.head,t,g;switch(b.length){case 1:c=b[0];c={x:c.x,y:c.y,r:c.r};break;case 2:g=b[0];var k=b[1];c=g.x;t=g.y;g=g.r;var n=k.x,m=k.y,k=k.r,u=n-c,y=m-t,r=k-g,w=Math.sqrt(u*u+y*y);c={x:(c+n+u/w*r)/2,y:(t+m+y/w*r)/2,r:(w+g+k)/2};break;case 3:g=b[0];m=b[1];n=b[2];c=g.x;t=g.y;g=g.r;var y=m.x,r=m.y,H=m.r,k=n.x,w=n.y,F=n.r,n=2*(c-y),u=2*(t-r),m=2*(H-g),H=c*c+t*t-g*g-y*y-r*r+H*H,y=2*(c-k),ca=2*(t-w),r=2*(F-g),w=c*c+t*t-\ng*g-k*k-w*w+F*F,F=y*u-n*ca,k=(u*w-ca*H)/F-c,u=(ca*m-u*r)/F,w=(y*H-n*w)/F-t,n=(n*r-y*m)/F,m=u*u+n*n-1,y=2*(k*u+w*n+g);g=k*k+w*w-g*g;g=(-y-Math.sqrt(y*y-4*m*g))/(2*m);c={x:k+u*g+c,y:w+n*g+t,r:g}}for(;p;)g=p.Fa,t=p.next,(n=!c)||(n=g.x-c.x,m=g.y-c.y,k=c.r-g.r,n=k*k+1E-6>n*n+m*m,n=!n),n?(e?(a.Dm=e,e.next=null):a.head=a.Dm=null,b.push(g),c=xj(a,b),b.pop(),a.head?(p.next=a.head,a.head=p):(p.next=null,a.head=a.Dm=p),e=a.Dm,e.next=t):e=p,p=t;a.Dm=e;return c}function yj(a,b,c){var e=a.x,p=a.y,t=b.r+c.r;a=a.r+\nc.r;var g=b.x-e;b=b.y-p;var z=g*g+b*b;if(z){var k=.5+((a*=a)-(t*=t))/(2*z),t=Math.sqrt(Math.max(0,2*t*(a+z)-(a-=z)*a-t*t))/(2*z);c.x=e+k*g+t*b;c.y=p+k*b-t*g}else c.x=e+a,c.y=p}function zj(a,b){var c=b.x-a.x,e=b.y-a.y;a=a.r+b.r;return a*a-1E-6>c*c+e*e}function Aj(a,b){for(var c=a.Fa.r;a!==b;)c+=2*(a=a.next).Fa.r;return c-b.Fa.r}function Bj(a,b,c){var e=a.Fa;a=a.next.Fa;var p=e.r+a.r;b=(e.x*a.r+a.x*e.r)/p-b;c=(e.y*a.r+a.y*e.r)/p-c;return b*b+c*c}function pe(a){this.Fa=a;this.Fh=this.next=null}function Cj(a){if(!(p=\na.length))return 0;var b,c,e,p;b=a[0];b.x=0;b.y=0;if(!(1<p))return b.r;c=a[1];b.x=-c.r;c.x=b.r;c.y=0;if(!(2<p))return b.r+c.r;yj(c,b,e=a[2]);var g=b.r*b.r,k=c.r*c.r,n=e.r*e.r,m=g+k+n,q=g*b.x+k*c.x+n*e.x,k=g*b.y+k*c.y+n*e.y,u,y,r;b=new pe(b);c=new pe(c);e=new pe(e);b.next=e.Fh=c;c.next=b.Fh=e;e.next=c.Fh=b;r=3;a:for(;r<p;++r){yj(b.Fa,c.Fa,e=a[r]);e=new pe(e);g=c.next;n=b.Fh;u=c.Fa.r;y=b.Fa.r;do if(u<=y){if(zj(g.Fa,e.Fa)){u+b.Fa.r+c.Fa.r>Aj(g,c)?b=g:c=g;b.next=c;c.Fh=b;--r;continue a}u+=g.Fa.r;g=g.next}else{if(zj(n.Fa,\ne.Fa)){Aj(b,n)>y+b.Fa.r+c.Fa.r?b=n:c=n;b.next=c;c.Fh=b;--r;continue a}y+=n.Fa.r;n=n.Fh}while(g!==n.next);e.Fh=b;e.next=c;b.next=c.Fh=c=e;m+=n=e.Fa.r*e.Fa.r;q+=n*e.Fa.x;k+=n*e.Fa.y;for(g=Bj(b,u=q/m,y=k/m);(e=e.next)!==c;)(n=Bj(e,u,y))<g&&(b=e,g=n);c=b.next}b=[c.Fa];for(e=c;(e=e.next)!==c;)b.push(e.Fa);e=Dj(b);for(r=0;r<p;++r)b=a[r],b.x-=e.x,b.y-=e.y;return e.r}function qe(a){if(\"function\"!==typeof a)throw Error();return a}function Rb(){return 0}function Fp(a){return Math.sqrt(a.value)}function Ej(a){return function(b){b.children||\n(b.r=Math.max(0,+a(b)||0))}}function ng(a,b){return function(c){if(e=c.children){var e,p,t=e.length,g=a(c)*b||0,z;if(g)for(p=0;p<t;++p)e[p].r+=g;z=Cj(e);if(g)for(p=0;p<t;++p)e[p].r-=g;c.r=z+g}}}function Fj(a){return function(b){var c=b.parent;b.r*=a;c&&(b.x=c.x+a*b.x,b.y=c.y+a*b.y)}}function Gp(a){return a.id}function Hp(a){return a.parentId}function Ip(a,b){return a.parent===b.parent?1:2}function og(a){var b=a.children;return b?b[0]:a.t}function pg(a){var b=a.children;return b?b[b.length-1]:a.t}\nfunction re(a,b){this.Fa=a;this.gp=this.children=this.parent=null;this.a=this;this.s=this.c=this.ic=this.z=0;this.t=null;this.uf=b}function Jp(a){a=new re(a,0);for(var b,c=[a],e,p,g;b=c.pop();)if(p=b.Fa.children)for(b.children=Array(e=p.length),g=e-1;0<=g;--g)c.push(e=b.children[g]=new re(p[g],g)),e.parent=b;(a.parent=new re(null,0)).children=[a];return a}function Gj(a,b,c,e,g,k){for(var p=[],t=b.children,z,n,u=z=0,y=t.length,r,w=b.value,I,R,P,m,T,A;z<y;){b=g-c;r=k-e;do I=t[u++].value;while(!I&&u<\ny);R=P=I;A=Math.max(r/b,b/r)/(w*a);m=I*I*A;for(T=Math.max(P/m,m/R);u<y;++u){I+=n=t[u].value;n<R&&(R=n);n>P&&(P=n);m=I*I*A;m=Math.max(P/m,m/R);if(m>T){I-=n;break}T=m}p.push(z={value:I,wx:b<r,children:t.slice(z,u)});z.wx?bd(z,c,e,g,w?e+=r*I/w:k):se(z,c,e,w?c+=b*I/w:g,k);w-=I;z=u}return p}function Kp(a,b){return a[0]-b[0]||a[1]-b[1]}function Hj(a){for(var b=a.length,c=[0,1],e=2,p=2;p<b;++p){for(;1<e&&0>=Lp(a[c[e-2]],a[c[e-1]],a[p]);)--e;c[e++]=p}return c.slice(0,e)}function qg(a){if(!(1<=a))throw Error();\nthis.WG=a;this.$f=this._error=null;this.Wg=[];this.dl=[];this.ol=this.Ni=this.kq=this.vw=0}function Ij(a){if(!a.vw)try{for(var b=a;b.vw=b.ol&&b.Ni<b.WG;){var c=b.kq+b.Ni,e=b.Wg[c],p=e.length-1,g=e[p];e[p]=Mp(b,c);--b.ol;++b.Ni;e=g.apply(null,e);b.Wg[c]&&(b.Wg[c]=e||Np)}}catch(da){if(a.Wg[a.kq+a.Ni-1])rg(a,da);else if(!a.dl)throw da;}}function Mp(a,b){return function(c,e){a.Wg[b]&&(--a.Ni,++a.kq,a.Wg[b]=null,null==a._error&&(null!=c?rg(a,c):(a.dl[b]=e,a.ol?Ij(a):te(a))))}}function rg(a,b){var c=a.Wg.length;\na._error=b;a.dl=void 0;for(a.ol=NaN;0<=--c;)if(b=a.Wg[c])if(a.Wg[c]=null,b.abort)try{b.abort()}catch(I){}a.Ni=NaN;te(a)}function te(a){if(!a.Ni&&a.$f){var b=a.dl;a.dl=void 0;a.$f(a._error,b)}}function Jj(a){return new qg(arguments.length?+a:Infinity)}function Op(a){return function(b,c){a(null==b?c:null)}}function Pp(a,b){return function(c){return a(c.responseText,b)}}function sg(a){function b(b){var g=b+\"\",t=c.get(g);if(!t){if(p!==tg)return p;c.set(g,t=e.push(b))}return a[(t-1)%a.length]}var c=fb(),\ne=[],p=tg;a=null==a?[]:yb.call(a);b.domain=function(a){if(!arguments.length)return e.slice();e=[];c=fb();for(var p=-1,g=a.length,t,z;++p<g;)c.has(z=(t=a[p])+\"\")||c.set(z,e.push(t));return b};b.range=function(c){return arguments.length?(a=yb.call(c),b):a.slice()};b.unknown=function(a){return arguments.length?(p=a,b):p};b.copy=function(){return sg().domain(e).range(a).unknown(p)};return b}function ug(){function a(){var a=c().length,b=g[1]<g[0],p=g[b-0],t=g[1-b];k=(t-p)/Math.max(1,a-q+2*v);m&&(k=Math.floor(k));\np+=(t-p-k*(a-q))*u;n=k*(1-q);m&&(p=Math.round(p),n=Math.round(n));a=bb(a).map(function(a){return p+k*a});return e(b?a.reverse():a)}var b=sg().unknown(void 0),c=b.domain,e=b.range,g=[0,1],k,n,m=!1,q=0,v=0,u=.5;delete b.unknown;b.domain=function(b){return arguments.length?(c(b),a()):c()};b.range=function(b){return arguments.length?(g=[+b[0],+b[1]],a()):g.slice()};b.rangeRound=function(b){return g=[+b[0],+b[1]],m=!0,a()};b.bandwidth=function(){return n};b.step=function(){return k};b.round=function(b){return arguments.length?\n(m=!!b,a()):m};b.padding=function(b){return arguments.length?(q=v=Math.max(0,Math.min(1,b)),a()):q};b.paddingInner=function(b){return arguments.length?(q=Math.max(0,Math.min(1,b)),a()):q};b.paddingOuter=function(b){return arguments.length?(v=Math.max(0,Math.min(1,b)),a()):v};b.align=function(b){return arguments.length?(u=Math.max(0,Math.min(1,b)),a()):u};b.copy=function(){return ug().domain(c()).range(g).round(m).paddingInner(q).paddingOuter(v).align(u)};return a()}function Kj(a){var b=a.copy;a.padding=\na.paddingOuter;delete a.paddingInner;delete a.paddingOuter;a.copy=function(){return Kj(b())};return a}function Qp(){return Kj(ug().paddingInner(1))}function vg(a,b){return(b-=a=+a)?function(c){return(c-a)/b}:wg(b)}function Rp(a){return function(b,c){var e=a(b=+b,c=+c);return function(a){return a<=b?0:a>=c?1:e(a)}}}function Sp(a){return function(b,c){var e=a(b=+b,c=+c);return function(a){return 0>=a?b:1<=a?c:e(a)}}}function Tp(a,b,c,e){var p=a[0];a=a[1];var g=b[0];b=b[1];a<p?(p=c(a,p),g=e(b,g)):(p=\nc(p,a),g=e(g,b));return function(a){return g(p(a))}}function Up(a,b,c,e){var p=Math.min(a.length,b.length)-1,g=Array(p),t=Array(p),z=-1;a[p]<a[0]&&(a=a.slice().reverse(),b=b.slice().reverse());for(;++z<p;)g[z]=c(a[z],a[z+1]),t[z]=e(b[z],b[z+1]);return function(b){var c=Sb(a,b,1,p)-1;return t[c](g[c](b))}}function ue(a,b){return b.domain(a.domain()).range(a.range()).interpolate(a.interpolate()).clamp(a.clamp())}function ve(a,b){function c(){n=2<Math.min(p.length,g.length)?Up:Tp;m=u=null;return e}function e(b){return(m||\n(m=n(p,g,k?Rp(a):a,t)))(+b)}var p=Lj,g=Lj,t=Pc,k=!1,n,m,u;e.invert=function(a){return(u||(u=n(g,p,vg,k?Sp(b):b)))(+a)};e.domain=function(a){return arguments.length?(p=xg.call(a,Mj),c()):p.slice()};e.range=function(a){return arguments.length?(g=yb.call(a),c()):g.slice()};e.rangeRound=function(a){return g=yb.call(a),t=Nj,c()};e.clamp=function(a){return arguments.length?(k=!!a,c()):k};e.interpolate=function(a){return arguments.length?(t=a,c()):t};return c()}function cd(a){var c=a.domain;a.ticks=function(a){var b=\nc();return we(b[0],b[b.length-1],null==a?10:a)};a.tickFormat=function(a,e){var p;a:{var g=c(),t=g[0],g=g[g.length-1];a=b(t,g,null==a?10:a);e=xe(null==e?\",f\":e);switch(e.type){case \"s\":t=Math.max(Math.abs(t),Math.abs(g));null!=e.precision||isNaN(p=Oj(a,t))||(e.precision=p);p=d3.formatPrefix(e,t);break a;case \"\":case \"e\":case \"g\":case \"p\":case \"r\":null!=e.precision||isNaN(p=Pj(a,Math.max(Math.abs(t),Math.abs(g))))||(e.precision=p-(\"e\"===e.type));break;case \"f\":case \"%\":null!=e.precision||isNaN(p=Qj(a))||\n(e.precision=p-2*(\"%\"===e.type))}p=d3.format(e)}return p};a.nice=function(e){var p=c(),g=p.length-1;e=null==e?10:e;var t=p[0],k=p[g],z=b(t,k,e);z&&(z=b(Math.floor(t/z)*z,Math.ceil(k/z)*z,e),p[0]=Math.floor(t/z)*z,p[g]=Math.ceil(k/z)*z,c(p));return a};return a}function Rj(){var a=ve(vg,Na);a.copy=function(){return ue(a,Rj())};return cd(a)}function Sj(){function a(a){return+a}var b=[0,1];a.invert=a;a.domain=a.range=function(c){return arguments.length?(b=xg.call(c,Mj),a):b.slice()};a.copy=function(){return Sj().domain(b)};\nreturn cd(a)}function Vp(a,b){return(b=Math.log(b/a))?function(c){return Math.log(c/a)/b}:wg(b)}function Wp(a,b){return 0>a?function(c){return-Math.pow(-b,c)*Math.pow(-a,1-c)}:function(c){return Math.pow(b,c)*Math.pow(a,1-c)}}function Xp(a){return isFinite(a)?+(\"1e\"+a):0>a?0:a}function Tj(a){return 10===a?Xp:a===Math.E?Math.exp:function(b){return Math.pow(a,b)}}function Uj(a){return a===Math.E?Math.log:10===a&&Math.log10||2===a&&Math.log2||(a=Math.log(a),function(b){return Math.log(b)/a})}function Vj(a){return function(b){return-a(-b)}}\nfunction Wj(){function a(){g=Uj(e);k=Tj(e);0>c()[0]&&(g=Vj(g),k=Vj(k));return b}var b=ve(Vp,Wp).domain([1,10]),c=b.domain,e=10,g=Uj(10),k=Tj(10);b.base=function(b){return arguments.length?(e=+b,a()):e};b.domain=function(b){return arguments.length?(c(b),a()):c()};b.ticks=function(a){var b=c(),p=b[0],b=b[b.length-1],t;if(t=b<p)u=p,p=b,b=u;var u=g(p),z=g(b),r,w,n;r=null==a?10:+a;a=[];if(!(e%1)&&z-u<r)if(u=Math.round(u)-1,z=Math.round(z)+1,0<p)for(;u<z;++u)for(w=1,r=k(u);w<e;++w){if(n=r*w,!(n<p)){if(n>\nb)break;a.push(n)}}else for(;u<z;++u)for(w=e-1,r=k(u);1<=w;--w){if(n=r*w,!(n<p)){if(n>b)break;a.push(n)}}else a=we(u,z,Math.min(z-u,r)).map(k);return t?a.reverse():a};b.tickFormat=function(a,c){null==c&&(c=10===e?\".0e\":\",\");\"function\"!==typeof c&&(c=d3.format(c));if(Infinity===a)return c;null==a&&(a=10);var p=Math.max(1,e*a/b.ticks().length);return function(a){var b=a/k(Math.round(g(a)));b*e<e-.5&&(b*=e);return b<=p?c(a):\"\"}};b.nice=function(){return c(Xj(c(),{floor:function(a){return k(Math.floor(g(a)))},\nceil:function(a){return k(Math.ceil(g(a)))}}))};b.copy=function(){return ue(b,Wj().base(e))};return b}function pc(a,b){return 0>a?-Math.pow(-a,b):Math.pow(a,b)}function yg(){function a(a,b){return(b=pc(b,c)-(a=pc(a,c)))?function(e){return(pc(e,c)-a)/b}:wg(b)}function b(a,b){b=pc(b,c)-(a=pc(a,c));return function(e){return pc(a+b*e,1/c)}}var c=1,e=ve(a,b),g=e.domain;e.exponent=function(a){return arguments.length?(c=+a,g(g())):c};e.copy=function(){return ue(e,yg().exponent(c))};return cd(e)}function Yp(){return yg().exponent(.5)}\nfunction Yj(){function a(){var a=0,p=Math.max(1,e.length);for(g=Array(p-1);++a<p;)g[a-1]=dd(c,a/p);return b}function b(a){if(!isNaN(a=+a))return e[Sb(g,a)]}var c=[],e=[],g=[];b.invertExtent=function(a){a=e.indexOf(a);return 0>a?[NaN,NaN]:[0<a?g[a-1]:c[0],a<g.length?g[a]:c[c.length-1]]};b.domain=function(b){if(!arguments.length)return c.slice();c=[];for(var e=0,p=b.length,g;e<p;++e)(g=b[e],null==g||isNaN(g=+g))||c.push(g);c.sort(Eb);return a()};b.range=function(b){return arguments.length?(e=yb.call(b),\na()):e.slice()};b.quantiles=function(){return g.slice()};b.copy=function(){return Yj().domain(c).range(e)};return b}function Zj(){function a(a){if(a<=a)return n[Sb(k,a,0,g)]}function b(){var b=-1;for(k=Array(g);++b<g;)k[b]=((b+1)*e-(b-g)*c)/(g+1);return a}var c=0,e=1,g=1,k=[.5],n=[0,1];a.domain=function(a){return arguments.length?(c=+a[0],e=+a[1],b()):[c,e]};a.range=function(a){return arguments.length?(g=(n=yb.call(a)).length-1,b()):n.slice()};a.invertExtent=function(a){a=n.indexOf(a);return 0>a?\n[NaN,NaN]:1>a?[c,k[0]]:a>=g?[k[g-1],e]:[k[a-1],k[a]]};a.copy=function(){return Zj().domain([c,e]).range(n)};return cd(a)}function ak(){function a(a){if(a<=a)return c[Sb(b,a,0,e)]}var b=[.5],c=[0,1],e=1;a.domain=function(p){return arguments.length?(b=yb.call(p),e=Math.min(b.length,c.length-1),a):b.slice()};a.range=function(p){return arguments.length?(c=yb.call(p),e=Math.min(b.length,c.length-1),a):c.slice()};a.invertExtent=function(a){a=c.indexOf(a);return[b[a-1],b[a]]};a.copy=function(){return ak().domain(b).range(c)};\nreturn a}function xa(a,b,c,e){function p(b){return a(b=new Date(+b)),b}p.floor=p;p.ceil=function(c){return a(c=new Date(c-1)),b(c,1),a(c),c};p.round=function(a){var b=p(a),c=p.ceil(a);return a-b<c-a?b:c};p.offset=function(a,c){return b(a=new Date(+a),null==c?1:Math.floor(c)),a};p.range=function(c,e,g){var t=[];c=p.ceil(c);g=null==g?1:Math.floor(g);if(!(c<e&&0<g))return t;do t.push(new Date(+c));while(b(c,g),a(c),c<e);return t};p.filter=function(c){return xa(function(b){if(b>=b)for(;a(b),!c(b);)b.setTime(b-\n1)},function(a,e){if(a>=a)for(;0<=--e;)for(;b(a,1),!c(a););})};c&&(p.count=function(b,e){zg.setTime(+b);Ag.setTime(+e);a(zg);a(Ag);return Math.floor(c(zg,Ag))},p.every=function(a){a=Math.floor(a);return isFinite(a)&&0<a?1<a?p.filter(e?function(b){return 0===e(b)%a}:function(b){return 0===p.count(0,b)%a}):p:null});return p}function Tb(a){return xa(function(b){b.setDate(b.getDate()-(b.getDay()+7-a)%7);b.setHours(0,0,0,0)},function(a,b){a.setDate(a.getDate()+7*b)},function(a,b){return(b-a-6E4*(b.getTimezoneOffset()-\na.getTimezoneOffset()))/6048E5})}function Ub(a){return xa(function(b){b.setUTCDate(b.getUTCDate()-(b.getUTCDay()+7-a)%7);b.setUTCHours(0,0,0,0)},function(a,b){a.setUTCDate(a.getUTCDate()+7*b)},function(a,b){return(b-a)/6048E5})}function Zp(a){if(0<=a.y&&100>a.y){var b=new Date(-1,a.ic,a.d,a.kh,a.Ei,a.Sk,a.sb);b.setFullYear(a.y);return b}return new Date(a.y,a.ic,a.d,a.kh,a.Ei,a.Sk,a.sb)}function Bg(a){if(0<=a.y&&100>a.y){var b=new Date(Date.UTC(-1,a.ic,a.d,a.kh,a.Ei,a.Sk,a.sb));b.setUTCFullYear(a.y);\nreturn b}return new Date(Date.UTC(a.y,a.ic,a.d,a.kh,a.Ei,a.Sk,a.sb))}function Cg(a){return{y:a,ic:0,d:1,kh:0,Ei:0,Sk:0,sb:0}}function bk(a){function b(a,b){return function(c){var e=[],p=-1,g=0,t=a.length,r,u;for(c instanceof Date||(c=new Date(+c));++p<t;)if(37===a.charCodeAt(p)){e.push(a.slice(g,p));null!=(g=ck[r=a.charAt(++p)])?r=a.charAt(++p):g=\"e\"===r?\" \":\"0\";if(u=b[r])r=u(c,g);e.push(r);g=p+1}e.push(a.slice(g,p));return e.join(\"\")}}function c(a,b){return function(c){var p=Cg(1900),g=e(p,a,c+=\n\"\",0);if(g!=c.length)return null;\"p\"in p&&(p.kh=p.kh%12+12*p.p);if(\"W\"in p||\"U\"in p)\"w\"in p||(p.w=\"W\"in p?1:0),c=\"Z\"in p?Bg(Cg(p.y)).getUTCDay():b(Cg(p.y)).getDay(),p.ic=0,p.d=\"W\"in p?(p.w+6)%7+7*p.W-(c+5)%7:p.w+7*p.U-(c+6)%7;return\"Z\"in p?(p.kh+=p.Z/100|0,p.Ei+=p.Z%100,Bg(p)):b(p)}}function e(a,b,c,e){for(var p=0,g=b.length,t=c.length,r;p<g;){if(e>=t)return-1;r=b.charCodeAt(p++);if(37===r){if(r=b.charAt(p++),r=Ka[r in ck?b.charAt(p++):r],!r||0>(e=r(a,c,e)))return-1}else if(r!=c.charCodeAt(e++))return-1}return e}\nfunction p(a,b,c){return(b=J.exec(b.slice(c)))?(a.p=C[b[0].toLowerCase()],c+b[0].length):-1}function g(a,b,c){return(b=K.exec(b.slice(c)))?(a.w=Q[b[0].toLowerCase()],c+b[0].length):-1}function k(a,b,c){return(b=W.exec(b.slice(c)))?(a.w=O[b[0].toLowerCase()],c+b[0].length):-1}function n(a,b,c){return(b=na.exec(b.slice(c)))?(a.ic=ka[b[0].toLowerCase()],c+b[0].length):-1}function m(a,b,c){return(b=U.exec(b.slice(c)))?(a.ic=aa[b[0].toLowerCase()],c+b[0].length):-1}function q(a,b,c){return e(a,M,b,c)}\nfunction u(a,b,c){return e(a,G,b,c)}function y(a,b,c){return e(a,Xa,b,c)}function r(a){return v[a.getDay()]}function w(a){return Aa[a.getDay()]}function H(a){return E[a.getMonth()]}function F(a){return B[a.getMonth()]}function ca(a){return Y[+(12<=a.getHours())]}function qa(a){return v[a.getUTCDay()]}function T(a){return Aa[a.getUTCDay()]}function A(a){return E[a.getUTCMonth()]}function L(a){return B[a.getUTCMonth()]}function ja(a){return Y[+(12<=a.getUTCHours())]}var M=a.dateTime,G=a.date,Xa=a.time,\nY=a.periods,Aa=a.days,v=a.shortDays,B=a.months,E=a.shortMonths,J=ed(Y),C=fd(Y),W=ed(Aa),O=fd(Aa),K=ed(v),Q=fd(v),U=ed(B),aa=fd(B),na=ed(E),ka=fd(E),ta={a:r,A:w,b:H,B:F,c:null,d:dk,e:dk,H:$p,I:aq,j:bq,L:cq,m:dq,M:eq,p:ca,S:fq,U:gq,w:hq,W:iq,x:null,X:null,y:jq,Y:kq,Z:lq,\"%\":ek},ma={a:qa,A:T,b:A,B:L,c:null,d:fk,e:fk,H:mq,I:nq,j:oq,L:pq,m:qq,M:rq,p:ja,S:sq,U:tq,w:uq,W:vq,x:null,X:null,y:wq,Y:xq,Z:yq,\"%\":ek},Ka={a:g,A:k,b:n,B:m,c:q,d:gk,e:gk,H:hk,I:hk,j:zq,L:Aq,m:Bq,M:Cq,p:p,S:Dq,U:Eq,w:Fq,W:Gq,x:u,X:y,\ny:Hq,Y:Iq,Z:Jq,\"%\":Kq};ta.x=b(G,ta);ta.X=b(Xa,ta);ta.c=b(M,ta);ma.x=b(G,ma);ma.X=b(Xa,ma);ma.c=b(M,ma);return{format:function(a){var c=b(a+=\"\",ta);c.toString=function(){return a};return c},parse:function(a){var b=c(a+=\"\",Zp);b.toString=function(){return a};return b},utcFormat:function(a){var c=b(a+=\"\",ma);c.toString=function(){return a};return c},utcParse:function(a){var b=c(a,Bg);b.toString=function(){return a};return b}}}function oa(a,b,c){var e=0>a?\"-\":\"\";a=(e?-a:a)+\"\";var p=a.length;return e+\n(p<c?Array(c-p+1).join(b)+a:a)}function Lq(a){return a.replace(Mq,\"\\\\$\\x26\")}function ed(a){return new RegExp(\"^(?:\"+a.map(Lq).join(\"|\")+\")\",\"i\")}function fd(a){for(var b={},c=-1,e=a.length;++c<e;)b[a[c].toLowerCase()]=c;return b}function Fq(a,b,c){return(b=Va.exec(b.slice(c,c+1)))?(a.w=+b[0],c+b[0].length):-1}function Eq(a,b,c){return(b=Va.exec(b.slice(c)))?(a.U=+b[0],c+b[0].length):-1}function Gq(a,b,c){return(b=Va.exec(b.slice(c)))?(a.W=+b[0],c+b[0].length):-1}function Iq(a,b,c){return(b=Va.exec(b.slice(c,\nc+4)))?(a.y=+b[0],c+b[0].length):-1}function Hq(a,b,c){return(b=Va.exec(b.slice(c,c+2)))?(a.y=+b[0]+(68<+b[0]?1900:2E3),c+b[0].length):-1}function Jq(a,b,c){return(b=/^(Z)|([+-]\\d\\d)(?:\\:?(\\d\\d))?/.exec(b.slice(c,c+6)))?(a.Z=b[1]?0:-(b[2]+(b[3]||\"00\")),c+b[0].length):-1}function Bq(a,b,c){return(b=Va.exec(b.slice(c,c+2)))?(a.ic=b[0]-1,c+b[0].length):-1}function gk(a,b,c){return(b=Va.exec(b.slice(c,c+2)))?(a.d=+b[0],c+b[0].length):-1}function zq(a,b,c){return(b=Va.exec(b.slice(c,c+3)))?(a.ic=0,a.d=\n+b[0],c+b[0].length):-1}function hk(a,b,c){return(b=Va.exec(b.slice(c,c+2)))?(a.kh=+b[0],c+b[0].length):-1}function Cq(a,b,c){return(b=Va.exec(b.slice(c,c+2)))?(a.Ei=+b[0],c+b[0].length):-1}function Dq(a,b,c){return(b=Va.exec(b.slice(c,c+2)))?(a.Sk=+b[0],c+b[0].length):-1}function Aq(a,b,c){return(b=Va.exec(b.slice(c,c+3)))?(a.sb=+b[0],c+b[0].length):-1}function Kq(a,b,c){return(a=Nq.exec(b.slice(c,c+1)))?c+a[0].length:-1}function dk(a,b){return oa(a.getDate(),b,2)}function $p(a,b){return oa(a.getHours(),\nb,2)}function aq(a,b){return oa(a.getHours()%12||12,b,2)}function bq(a,b){return oa(1+ye.count(Vb(a),a),b,3)}function cq(a,b){return oa(a.getMilliseconds(),b,3)}function dq(a,b){return oa(a.getMonth()+1,b,2)}function eq(a,b){return oa(a.getMinutes(),b,2)}function fq(a,b){return oa(a.getSeconds(),b,2)}function gq(a,b){return oa(gd.count(Vb(a),a),b,2)}function hq(a){return a.getDay()}function iq(a,b){return oa(Dg.count(Vb(a),a),b,2)}function jq(a,b){return oa(a.getFullYear()%100,b,2)}function kq(a,\nb){return oa(a.getFullYear()%1E4,b,4)}function lq(a){a=a.getTimezoneOffset();return(0<a?\"-\":(a*=-1,\"+\"))+oa(a/60|0,\"0\",2)+oa(a%60,\"0\",2)}function fk(a,b){return oa(a.getUTCDate(),b,2)}function mq(a,b){return oa(a.getUTCHours(),b,2)}function nq(a,b){return oa(a.getUTCHours()%12||12,b,2)}function oq(a,b){return oa(1+ze.count(Wb(a),a),b,3)}function pq(a,b){return oa(a.getUTCMilliseconds(),b,3)}function qq(a,b){return oa(a.getUTCMonth()+1,b,2)}function rq(a,b){return oa(a.getUTCMinutes(),b,2)}function sq(a,\nb){return oa(a.getUTCSeconds(),b,2)}function tq(a,b){return oa(hd.count(Wb(a),a),b,2)}function uq(a){return a.getUTCDay()}function vq(a,b){return oa(Eg.count(Wb(a),a),b,2)}function wq(a,b){return oa(a.getUTCFullYear()%100,b,2)}function xq(a,b){return oa(a.getUTCFullYear()%1E4,b,4)}function yq(){return\"+0000\"}function ek(){return\"%\"}function ik(a){qc=bk(a);d3.timeFormat=qc.format;d3.timeParse=qc.parse;d3.utcFormat=qc.utcFormat;d3.utcParse=qc.utcParse;return qc}function Oq(a){return a.toISOString()}\nfunction Pq(a){a=new Date(a);return isNaN(a)?null:a}function Qq(a){return new Date(a)}function Rq(a){return a instanceof Date?+a:+new Date(+a)}function Fg(a,c,e,g,k,n,m,q,v){function p(b){return(m(b)<b?H:n(b)<b?F:k(b)<b?I:g(b)<b?P:c(b)<b?e(b)<b?T:A:a(b)<b?L:R)(b)}function t(c,e,p,g){null==c&&(c=10);if(\"number\"===typeof c){g=Math.abs(p-e)/c;var r=Gg(function(a){return a[2]}).right(M,g);r===M.length?(g=b(e/31536E6,p/31536E6,c),c=a):r?(r=M[g/M[r-1][2]<M[r][2]/g?r-1:r],g=r[1],c=r[0]):(g=b(e,p,c),c=q)}return null==\ng?c:c.every(g)}var z=ve(vg,Na),r=z.invert,w=z.domain,H=v(\".%L\"),F=v(\":%S\"),I=v(\"%I:%M\"),P=v(\"%I %p\"),T=v(\"%a %d\"),A=v(\"%b %d\"),L=v(\"%B\"),R=v(\"%Y\"),M=[[m,1,1E3],[m,5,5E3],[m,15,15E3],[m,30,3E4],[n,1,6E4],[n,5,3E5],[n,15,9E5],[n,30,18E5],[k,1,36E5],[k,3,108E5],[k,6,216E5],[k,12,432E5],[g,1,864E5],[g,2,1728E5],[e,1,6048E5],[c,1,2592E6],[c,3,7776E6],[a,1,31536E6]];z.invert=function(a){return new Date(r(a))};z.domain=function(a){return arguments.length?w(xg.call(a,Rq)):w().map(Qq)};z.ticks=function(a,\nb){var c=w(),e=c[0],c=c[c.length-1],p=c<e,g;p&&(g=e,e=c,c=g);g=(g=t(a,e,c,b))?g.range(e,c+1):[];return p?g.reverse():g};z.tickFormat=function(a,b){return null==b?p:v(b)};z.nice=function(a,b){var c=w();return(a=t(a,c[0],c[c.length-1],b))?w(Xj(c,a)):z};z.copy=function(){return ue(z,Fg(a,c,e,g,k,n,m,q,v))};return z}function Ae(a){var b=a.length;return function(c){return a[Math.max(0,Math.min(b-1,Math.floor(c*b)))]}}function jk(a){function b(b){b=(b-c)/(e-c);return a(p?Math.max(0,Math.min(1,b)):b)}var c=\n0,e=1,p=!1;b.domain=function(a){return arguments.length?(c=+a[0],e=+a[1],b):[c,e]};b.clamp=function(a){return arguments.length?(p=!!a,b):p};b.interpolator=function(c){return arguments.length?(a=c,b):a};b.copy=function(){return jk(a).domain([c,e]).clamp(p)};return cd(b)}function Sq(a){return a.innerRadius}function Tq(a){return a.outerRadius}function Uq(a){return a.startAngle}function Vq(a){return a.endAngle}function Wq(a){return a&&a.padAngle}function kk(a){return 1<=a?Be:-1>=a?-Be:Math.asin(a)}function Ce(a,\nb,c,e,g,k,n){var p=a-c,t=b-e;n=(n?k:-k)/Math.sqrt(p*p+t*t);var t=n*t,p=-n*p,z=a+t,u=b+p,y=c+t,r=e+p;c=(z+y)/2;e=(u+r)/2;b=y-z;a=r-u;n=b*b+a*a;k=g-k;var r=z*r-y*u,w=(0>a?-1:1)*Math.sqrt(Math.max(0,k*k*n-r*r)),z=(r*a-b*w)/n,u=(-r*b-a*w)/n,y=(r*a+b*w)/n;b=(-r*b+a*w)/n;a=z-c;n=u-e;c=y-c;e=b-e;a*a+n*n>c*c+e*e&&(z=y,u=b);return{cx:z,cy:u,bh:-t,dh:-p,wi:z*(g/k-1),yi:u*(g/k-1)}}function lk(a){this.Ia=a}function mk(a){return a[0]}function nk(a){return a[1]}function ok(a){this.Uh=a}function Hg(a){function b(b){return new ok(a(b))}\nb.Uh=a;return b}function id(a){var b=a.curve;a.angle=a.x;delete a.x;a.radius=a.y;delete a.y;a.curve=function(a){return arguments.length?b(Hg(a)):b().Uh};return a}function De(a,b,c){a.Ia.bezierCurveTo((2*a.ub+a.Sa)/3,(2*a.xb+a.Va)/3,(a.ub+2*a.Sa)/3,(a.xb+2*a.Va)/3,(a.ub+4*a.Sa+b)/6,(a.xb+4*a.Va+c)/6)}function Ee(a){this.Ia=a}function pk(a){this.Ia=a}function qk(a){this.Ia=a}function rk(a,b){this.bq=new Ee(a);this.sn=b}function Fe(a,b,c){a.Ia.bezierCurveTo(a.Sa+a.Tj*(a.Mb-a.ub),a.Va+a.Tj*(a.Nb-a.xb),\na.Mb+a.Tj*(a.Sa-b),a.Nb+a.Tj*(a.Va-c),a.Mb,a.Nb)}function Ig(a,b){this.Ia=a;this.Tj=(1-b)/6}function Jg(a,b){this.Ia=a;this.Tj=(1-b)/6}function Kg(a,b){this.Ia=a;this.Tj=(1-b)/6}function Lg(a,b,c){var e=a.Sa,g=a.Va,p=a.Mb,t=a.Nb;if(1E-12<a.sh)var k=2*a.Wh+3*a.sh*a.qg+a.Hf,z=3*a.sh*(a.sh+a.qg),e=(e*k-a.ub*a.Hf+a.Mb*a.Wh)/z,g=(g*k-a.xb*a.Hf+a.Nb*a.Wh)/z;1E-12<a.rg&&(k=2*a.Cg+3*a.rg*a.qg+a.Hf,z=3*a.rg*(a.rg+a.qg),p=(p*k+a.Sa*a.Cg-b*a.Hf)/z,t=(t*k+a.Va*a.Cg-c*a.Hf)/z);a.Ia.bezierCurveTo(e,g,p,t,a.Mb,\na.Nb)}function sk(a,b){this.Ia=a;this.bl=b}function tk(a,b){this.Ia=a;this.bl=b}function uk(a,b){this.Ia=a;this.bl=b}function vk(a){this.Ia=a}function wk(a,b,c){var e=a.Sa-a.ub,g=b-a.Sa;b=(a.Va-a.xb)/(e||0>g&&-0);a=(c-a.Va)/(g||0>e&&-0);e=(b*g+a*e)/(e+g);return((0>b?-1:1)+(0>a?-1:1))*Math.min(Math.abs(b),Math.abs(a),.5*Math.abs(e))||0}function xk(a,b){var c=a.Sa-a.ub;return c?(3*(a.Va-a.xb)/c-b)/2:b}function Mg(a,b,c){var e=a.ub,g=a.xb,p=a.Sa,t=a.Va,k=(p-e)/3;a.Ia.bezierCurveTo(e+k,g+k*b,p-k,t-k*\nc,p,t)}function Ge(a){this.Ia=a}function yk(a){this.Ia=new zk(a)}function zk(a){this.Ia=a}function Xq(a){return new Ge(a)}function Yq(a){return new yk(a)}function Ak(a){this.Ia=a}function Bk(a){var b,c=a.length-1,e,g=Array(c),p=Array(c),k=Array(c);g[0]=0;p[0]=2;k[0]=a[0]+2*a[1];for(b=1;b<c-1;++b)g[b]=1,p[b]=4,k[b]=4*a[b]+2*a[b+1];g[c-1]=2;p[c-1]=7;k[c-1]=8*a[c-1]+a[c];for(b=1;b<c;++b)e=g[b]/p[b-1],p[b]-=e,k[b]-=e*k[b-1];g[c-1]=k[c-1]/p[c-1];for(b=c-2;0<=b;--b)g[b]=(k[b]-g[b+1])/p[b];p[c-1]=(a[c]+\ng[c-1])/2;for(b=0;b<c-1;++b)p[b]=2*a[b+1]-g[b+1];return[g,p]}function He(a,b){this.Ia=a;this.Zi=b}function Zq(a){return new He(a,0)}function $q(a){return new He(a,1)}function ar(a,b){return a[b]}function Ck(a){for(var b=0,c=-1,e=a.length,g;++c<e;)if(g=+a[c][1])b+=g;return b}function br(a){return a[0]}function cr(a){return a[1]}function Ie(){this.Fa=null}function Je(a){a.qd=a.qb=a.sb=a.ac=a.Ue=a.pe=null}function jd(a,b){var c=b;b=b.ac;var e=c.qd;e?e.sb===c?e.sb=b:e.ac=b:a.Fa=b;b.qd=e;c.qd=b;c.ac=b.sb;\nc.ac&&(c.ac.qd=c);b.sb=c}function kd(a,b){var c=b;b=b.sb;var e=c.qd;e?e.sb===c?e.sb=b:e.ac=b:a.Fa=b;b.qd=e;c.qd=b;c.sb=b.ac;c.sb&&(c.sb.qd=c);b.ac=c}function Dk(a){for(;a.sb;)a=a.sb;return a}function ld(a,b,c,e){var g=[null,null],p=Fa.push(g)-1;g.left=a;g.right=b;c&&Ke(g,a,b,c);e&&Ke(g,b,a,e);Ra[a.index].halfedges.push(p);Ra[b.index].halfedges.push(p);return g}function md(a,b,c){b=[b,c];b.left=a;return b}function Ke(a,b,c,e){a[0]||a[1]?a.left===c?a[1]=e:a[0]=e:(a[0]=e,a.left=b,a.right=c)}function dr(a,\nb,c,e,g){var p=a[0],k=a[1],t=p[0],p=p[1],n=k[0],z=k[1],k=0,u=1,n=n-t,z=z-p;b-=t;if(n||!(0<b)){b/=n;if(0>n){if(b<k)return;b<u&&(u=b)}else if(0<n){if(b>u)return;b>k&&(k=b)}b=e-t;if(n||!(0>b)){b/=n;if(0>n){if(b>u)return;b>k&&(k=b)}else if(0<n){if(b<k)return;b<u&&(u=b)}b=c-p;if(z||!(0<b)){b/=z;if(0>z){if(b<k)return;b<u&&(u=b)}else if(0<z){if(b>u)return;b>k&&(k=b)}b=g-p;if(z||!(0>b)){b/=z;if(0>z){if(b>u)return;b>k&&(k=b)}else if(0<z){if(b<k)return;b<u&&(u=b)}if(!(0<k||1>u))return!0;0<k&&(a[0]=[t+k*n,p+\nk*z]);1>u&&(a[1]=[t+u*n,p+u*z]);return!0}}}}}function er(a,b,c,e,g){var p=a[1];if(p)return!0;var k=a[0],t=a.left,n=a.right,p=t[0],t=t[1],z=n[0],n=n[1],u=(p+z)/2,y=(t+n)/2,r;if(n===t){if(u<b||u>=e)return;if(p>z){if(!k)k=[u,c];else if(k[1]>=g)return;p=[u,g]}else{if(!k)k=[u,g];else if(k[1]<c)return;p=[u,c]}}else if(r=(p-z)/(n-t),u=y-r*u,-1>r||1<r)if(p>z){if(!k)k=[(c-u)/r,c];else if(k[1]>=g)return;p=[(g-u)/r,g]}else{if(!k)k=[(g-u)/r,g];else if(k[1]<c)return;p=[(c-u)/r,c]}else if(t<n){if(!k)k=[b,r*b+u];\nelse if(k[0]>=e)return;p=[e,r*e+u]}else{if(!k)k=[e,r*e+u];else if(k[0]<b)return;p=[b,r*b+u]}a[0]=k;a[1]=p;return!0}function fr(a,b){a=a.site;var c=b.left,e=b.right;a===e&&(e=c,c=a);if(e)return Math.atan2(e[1]-c[1],e[0]-c[0]);a===c?(c=b[1],e=b[0]):(c=b[0],e=b[1]);return Math.atan2(c[0]-e[0],e[1]-c[1])}function Ek(a,b){return b[+(b.left!==a.site)]}function gr(){for(var a=0,b=Ra.length,c,e,g,k;a<b;++a)if((c=Ra[a])&&(k=(e=c.halfedges).length)){var n=Array(k),m=Array(k);for(g=0;g<k;++g)n[g]=g,m[g]=fr(c,\nFa[e[g]]);n.sort(function(a,b){return m[b]-m[a]});for(g=0;g<k;++g)m[g]=e[n[g]];for(g=0;g<k;++g)e[g]=m[g]}}function hr(){Je(this);this.x=this.y=this.arc=this.site=this.cy=null}function rc(a){var b=a.Ue,c=a.pe;if(b&&c){var e=b.site,b=a.site,g=c.site;if(e!==g){var c=b[0],p=b[1],k=e[0]-c,n=e[1]-p,e=g[0]-c,m=g[1]-p,g=2*(k*m-n*e);if(!(g>=-ir)){var q=k*k+n*n,u=e*e+m*m,n=(m*q-n*u)/g,e=(k*u-e*q)/g,k=Fk.pop()||new hr;k.arc=a;k.site=b;k.x=n+c;k.y=(k.cy=e+p)+Math.sqrt(n*n+e*e);a.Yg=k;a=null;for(b=nd.Fa;b;)if(k.y<\nb.y||k.y===b.y&&k.x<=b.x)if(b.sb)b=b.sb;else{a=b.Ue;break}else if(b.ac)b=b.ac;else{a=b;break}nd.insert(a,k);a||(Ng=k)}}}}function sc(a){var b=a.Yg;b&&(b.Ue||(Ng=b.pe),nd.remove(b),Fk.push(b),Je(b),a.Yg=null)}function jr(){Je(this);this.gi=this.site=this.Yg=null}function Gk(a){var b=Hk.pop()||new jr;b.site=a;return b}function Og(a){sc(a);tc.remove(a);Hk.push(a);Je(a)}function Ik(a,b){var c=a.site,e=c[0],g=c[1],p=g-b;if(!p)return e;a=a.Ue;if(!a)return-Infinity;c=a.site;a=c[0];c=c[1];b=c-b;if(!b)return a;\nvar k=a-e,t=1/p-1/b,n=k/b;return t?(-n+Math.sqrt(n*n-2*t*(k*k/(-2*b)-c+b/2+g-p/2)))/t+e:(e+a)/2}function kr(a,b){return b[1]-a[1]||b[0]-a[0]}function Pg(a,b){var c=a.sort(kr).pop(),e,g,p;Fa=[];Ra=Array(a.length);tc=new Ie;for(nd=new Ie;;)if(p=Ng,c&&(!p||c[1]<p.y||c[1]===p.y&&c[0]<p.x)){if(c[0]!==e||c[1]!==g){var k,t;g=e=void 0;p=c;for(var n=p[0],m=p[1],u=tc.Fa;u;)if(t=Ik(u,m)-n,t>la)u=u.sb;else if((k=u.pe)?k=Ik(k,m):(k=u.site,k=k[1]===m?k[0]:Infinity),k=n-k,k>la){if(!u.ac){g=u;break}u=u.ac}else{t>\n-la?(g=u.Ue,e=u):k>-la?(g=u,e=u.pe):g=e=u;break}Ra[p.index]={site:p,halfedges:[]};t=Gk(p);tc.insert(g,t);if(g||e)if(g===e)sc(g),e=Gk(g.site),tc.insert(t,e),t.gi=e.gi=ld(g.site,t.site),rc(g),rc(e);else if(e){sc(g);sc(e);n=g.site;u=n[0];k=n[1];var y=p[0]-u,r=p[1]-k,m=e.site,w=m[0]-u,H=m[1]-k,F=2*(y*H-r*w),ca=y*y+r*r,q=w*w+H*H,u=[(H*ca-r*q)/F+u,(y*q-w*ca)/F+k];Ke(e.gi,n,m,u);t.gi=ld(n,p,null,u);e.gi=ld(p,m,null,u);rc(g);rc(e)}else t.gi=ld(g.site,t.site);e=c[0];g=c[1]}c=a.pop()}else if(p){m=p.arc;p=m.Yg;\nn=p.x;u=p.cy;p=[n,u];y=m.Ue;k=m.pe;t=[m];Og(m);for(m=y;m.Yg&&Math.abs(n-m.Yg.x)<la&&Math.abs(u-m.Yg.cy)<la;)y=m.Ue,t.unshift(m),Og(m),m=y;t.unshift(m);sc(m);for(y=k;y.Yg&&Math.abs(n-y.Yg.x)<la&&Math.abs(u-y.Yg.cy)<la;)k=y.pe,t.push(y),Og(y),y=k;t.push(y);sc(y);u=t.length;for(n=1;n<u;++n)y=t[n],m=t[n-1],Ke(y.gi,m.site,y.site,p);m=t[0];y=t[u-1];y.gi=ld(m.site,y.site,null,p);rc(m);rc(y)}else break;gr();if(b){g=+b[0][0];e=+b[0][1];a=+b[1][0];c=+b[1][1];b=g;p=e;t=a;for(var n=c,m=Fa.length,T;m--;)er(T=\nFa[m],b,p,t,n)&&dr(T,b,p,t,n)&&(Math.abs(T[0][0]-T[1][0])>la||Math.abs(T[0][1]-T[1][1])>la)||delete Fa[m];b=g;T=e;g=c;var c=Ra.length,A;e=!0;for(p=0;p<c;++p)if(t=Ra[p]){A=t.site;m=t.halfedges;for(n=m.length;n--;)Fa[m[n]]||m.splice(n,1);n=0;for(u=m.length;n<u;)if(k=Fa[m[n]],y=k[+(k.left===t.site)],r=y[0],w=y[1],H=Ek(t,Fa[m[++n%u]]),k=H[0],H=H[1],Math.abs(r-k)>la||Math.abs(w-H)>la)m.splice(n,0,Fa.push(md(A,y,Math.abs(r-b)<la&&g-w>la?[b,Math.abs(k-b)<la?H:g]:Math.abs(w-g)<la&&a-r>la?[Math.abs(H-g)<la?\nk:a,g]:Math.abs(r-a)<la&&w-T>la?[a,Math.abs(k-a)<la?H:T]:Math.abs(w-T)<la&&r-b>la?[Math.abs(H-T)<la?k:b,T]:null))-1),++u;u&&(e=!1)}if(e){n=Infinity;p=0;for(e=null;p<c;++p)if(t=Ra[p])A=t.site,m=A[0]-b,u=A[1]-T,m=m*m+u*u,m<n&&(n=m,e=t);e&&(p=[b,T],b=[b,g],g=[a,g],T=[a,T],e.halfedges.push(Fa.push(md(A=e.site,p,b))-1,Fa.push(md(A,b,g))-1,Fa.push(md(A,g,T))-1,Fa.push(md(A,T,p))-1))}for(p=0;p<c;++p)if(t=Ra[p])t.halfedges.length||delete Ra[p]}this.edges=Fa;this.cells=Ra;tc=nd=Fa=Ra=null}function lr(a,b,\nc){this.target=a;this.type=b;this.transform=c}function qb(a,b,c){this.k=a;this.x=b;this.y=c}function Jk(a){return a.__zoom||Qg}function mr(){return!d3.event.button}function nr(){var a=this,b;a instanceof SVGElement?(a=a.ownerSVGElement||a,b=a.width.baseVal.value,a=a.height.baseVal.value):(b=a.clientWidth,a=a.clientHeight);return[[0,0],[b,a]]}function Kk(){return this.__zoom||Qg}var Eb=function(a,b){return a<b?-1:a>b?1:a>=b?0:NaN},Gg=function(b){1===b.length&&(b=a(b));return{left:function(a,c,e,g){null==\ne&&(e=0);null==g&&(g=a.length);for(;e<g;){var p=e+g>>>1;0>b(a[p],c)?e=p+1:g=p}return e},right:function(a,c,e,g){null==e&&(e=0);null==g&&(g=a.length);for(;e<g;){var p=e+g>>>1;0<b(a[p],c)?g=p:e=p+1}return e}}},Lk=Gg(Eb),Sb=Lk.right,or=Lk.left,pr=function(a,b){return b<a?-1:b>a?1:b>=a?0:NaN},zb=function(a){return null===a?NaN:+a},Mk=function(a,b){var c=a.length,e=0,g,p,k=0,t=-1,n=0;if(null==b)for(;++t<c;)isNaN(g=zb(a[t]))||(p=g-e,e+=p/++n,k+=p*(g-e));else for(;++t<c;)isNaN(g=zb(b(a[t],t,a)))||(p=g-e,\ne+=p/++n,k+=p*(g-e));if(1<n)return k/(n-1)},Nk=function(a,b){return(a=Mk(a,b))?Math.sqrt(a):a},Ok=function(a,b){var c=-1,e=a.length,g,p,k;if(null==b){for(;++c<e;)if(null!=(p=a[c])&&p>=p){g=k=p;break}for(;++c<e;)null!=(p=a[c])&&(g>p&&(g=p),k<p&&(k=p))}else{for(;++c<e;)if(null!=(p=b(a[c],c,a))&&p>=p){g=k=p;break}for(;++c<e;)null!=(p=b(a[c],c,a))&&(g>p&&(g=p),k<p&&(k=p))}return[g,k]},Pk=Array.prototype,qr=Pk.slice,rr=Pk.map,Le=function(a){return function(){return a}},sr=function(a){return a},bb=function(a,\nb,c){a=+a;b=+b;c=2>(g=arguments.length)?(b=a,a=0,1):3>g?1:+c;for(var e=-1,g=Math.max(0,Math.ceil((b-a)/c))|0,p=Array(g);++e<g;)p[e]=a+e*c;return p},pm=Math.sqrt(50),qm=Math.sqrt(10),rm=Math.sqrt(2),we=function(a,c,e){e=b(a,c,e);return bb(Math.ceil(a/e)*e,Math.floor(c/e)*e+e/2,e)},Qk=function(a){return Math.ceil(Math.log(a.length)/Math.LN2)+1},tr=function(){function a(a){var g,p=a.length,k,t=Array(p);for(g=0;g<p;++g)t[g]=b(a[g],g,a);g=c(t);var n=g[0],u=g[1],y=e(t,n,u);Array.isArray(y)||(y=we(n,u,y));\nfor(var r=y.length;y[0]<=n;)y.shift(),--r;for(;y[r-1]>=u;)y.pop(),--r;var w=Array(r+1);for(g=0;g<=r;++g)k=w[g]=[],k.x0=0<g?y[g-1]:n,k.x1=g<r?y[g]:u;for(g=0;g<p;++g)k=t[g],n<=k&&k<=u&&w[Sb(y,k,0,r)].push(a[g]);return w}var b=sr,c=Ok,e=Qk;a.value=function(c){return arguments.length?(b=\"function\"===typeof c?c:Le(c),a):b};a.domain=function(b){return arguments.length?(c=\"function\"===typeof b?b:Le([b[0],b[1]]),a):c};a.thresholds=function(b){return arguments.length?(e=\"function\"===typeof b?b:Array.isArray(b)?\nLe(qr.call(b)):Le(b),a):e};return a},dd=function(a,b,c){null==c&&(c=zb);if(e=a.length){if(0>=(b=+b)||2>e)return+c(a[0],0,a);if(1<=b)return+c(a[e-1],e-1,a);var e;b*=e-1;e=Math.floor(b);var g=+c(a[e],e,a);a=+c(a[e+1],e+1,a);return g+(a-g)*(b-e)}},ur=function(a,b,c){a=rr.call(a,zb).sort(Eb);return Math.ceil((c-b)/(2*(dd(a,.75)-dd(a,.25))*Math.pow(a.length,-1/3)))},vr=function(a,b,c){return Math.ceil((c-b)/(3.5*Nk(a)*Math.pow(a.length,-1/3)))},wr=function(a,b){var c=-1,e=a.length,g,p;if(null==b){for(;++c<\ne;)if(null!=(p=a[c])&&p>=p){g=p;break}for(;++c<e;)null!=(p=a[c])&&p>g&&(g=p)}else{for(;++c<e;)if(null!=(p=b(a[c],c,a))&&p>=p){g=p;break}for(;++c<e;)null!=(p=b(a[c],c,a))&&p>g&&(g=p)}return g},xr=function(a,b){var c=0,e=a.length,g,p=-1,k=e;if(null==b)for(;++p<e;)isNaN(g=zb(a[p]))?--k:c+=g;else for(;++p<e;)isNaN(g=zb(b(a[p],p,a)))?--k:c+=g;if(k)return c/k},yr=function(a,b){var c=[],e=a.length,g,p=-1;if(null==b)for(;++p<e;)isNaN(g=zb(a[p]))||c.push(g);else for(;++p<e;)isNaN(g=zb(b(a[p],p,a)))||c.push(g);\nreturn dd(c.sort(Eb),.5)},Uf=function(a){var b=a.length,c;c=-1;for(var e=0,g,p;++c<b;)e+=a[c].length;for(g=Array(e);0<=--b;)for(p=a[b],c=p.length;0<=--c;)g[--e]=p[c];return g},Rk=function(a,b){var c=-1,e=a.length,g,p;if(null==b){for(;++c<e;)if(null!=(p=a[c])&&p>=p){g=p;break}for(;++c<e;)null!=(p=a[c])&&g>p&&(g=p)}else{for(;++c<e;)if(null!=(p=b(a[c],c,a))&&p>=p){g=p;break}for(;++c<e;)null!=(p=b(a[c],c,a))&&g>p&&(g=p)}return g},zr=function(a){for(var b=0,c=a.length-1,e=a[0],g=Array(0>c?0:c);b<c;)g[b]=\n[e,e=a[++b]];return g},Ar=function(a,b){for(var c=b.length,e=Array(c);c--;)e[c]=a[b[c]];return e},Br=function(a,b){if(e=a.length){var c=0,e,g=0,p,k=a[g];for(b||(b=Eb);++c<e;)if(0>b(p=a[c],k)||0!==b(k,k))k=p,g=c;if(0===b(k,k))return g}},Cr=function(a,b,c){c=(null==c?a.length:c)-(b=null==b?0:+b);for(var e,g;c;)g=Math.random()*c--|0,e=a[c+b],a[c+b]=a[g+b],a[g+b]=e;return a},Dr=function(a,b){var c=0,e=a.length,g,p=-1;if(null==b)for(;++p<e;){if(g=+a[p])c+=g}else for(;++p<e;)if(g=+b(a[p],p,a))c+=g;return c},\nSk=function(a){if(!(k=a.length))return[];for(var b=-1,e=Rk(a,c),g=Array(e);++b<e;)for(var p=-1,k,n=g[b]=Array(k);++p<k;)n[p]=a[p][b];return g},Er=function(){return Sk(arguments)},bf=Array.prototype.slice,yh=function(a){return a},sm={value:function(){}};W.prototype=E.prototype={constructor:W,on:function(a,b){var c=this.Fa,e=J(a+\"\",c),g,p=-1,k=e.length;if(2>arguments.length)for(;++p<k;){var n;if(n=g=(a=e[p]).type){a:{n=c[g];for(var t=0,m=n.length;t<m;++t)if((g=n[t]).name===a.name){g=g.value;break a}g=\nvoid 0}n=g}if(n)return g}else{if(null!=b&&\"function\"!==typeof b)throw Error(\"invalid callback: \"+b);for(;++p<k;)if(g=(a=e[p]).type)c[g]=K(c[g],a.name,b);else if(null==b)for(g in c)c[g]=K(c[g],a.name,null);return this}},copy:function(){var a={},b=this.Fa,c;for(c in b)a[c]=b[c].slice();return new W(a)},call:function(a,b){if(0<(g=arguments.length-2))for(var c=Array(g),e=0,g,p;e<g;++e)c[e]=arguments[e+2];if(!this.Fa.hasOwnProperty(a))throw Error(\"unknown type: \"+a);p=this.Fa[a];e=0;for(g=p.length;e<g;++e)p[e].value.apply(b,\nc)},apply:function(a,b,c){if(!this.Fa.hasOwnProperty(a))throw Error(\"unknown type: \"+a);a=this.Fa[a];for(var e=0,g=a.length;e<g;++e)a[e].value.apply(b,c)}};var Sa={svg:\"http://www.w3.org/2000/svg\",xhtml:\"http://www.w3.org/1999/xhtml\",xlink:\"http://www.w3.org/1999/xlink\",xml:\"http://www.w3.org/XML/1998/namespace\",xmlns:\"http://www.w3.org/2000/xmlns/\"},od=function(a){var b=a+=\"\",c=b.indexOf(\":\");0<=c&&\"xmlns\"!==(b=a.slice(0,c))&&(a=a.slice(c+1));return Sa.hasOwnProperty(b)?{space:Sa[b],local:a}:a},\nRg=function(a){a=od(a);return(a.local?Q:O)(a)},tm=0;U.prototype=ka.prototype={constructor:U,get:function(a){for(var b=this.Fa;!(b in a);)if(!(a=a.parentNode))return;return a[b]},set:function(a,b){return a[this.Fa]=b},remove:function(a){return this.Fa in a&&delete a[this.Fa]},toString:function(){return this.Fa}};var Tk=function(a){return function(){return this.matches(a)}};if(\"undefined\"!==typeof document){var pd=document.documentElement;if(!pd.matches)var Fr=pd.webkitMatchesSelector||pd.msMatchesSelector||\npd.mozMatchesSelector||pd.oMatchesSelector,Tk=function(a){return function(){return Fr.call(this,a)}}}var Sg=Tk,zh={};d3.event=null;if(\"undefined\"!==typeof document){var Gr=document.documentElement;\"onmouseenter\"in Gr||(zh={mouseenter:\"mouseover\",mouseleave:\"mouseout\"})}var Hr=function(a,b,c){var e=Ka(a+\"\"),g,p=e.length,k;if(2>arguments.length){var n=this.node().__on;if(n)for(var t=0,m=n.length,u;t<m;++t)for(g=0,u=n[t];g<p;++g)if((k=e[g]).type===u.type&&k.name===u.name)return u.value}else{n=b?cf:ma;\nnull==c&&(c=!1);for(g=0;g<p;++g)this.each(n(e[g],b,c));return this}},Tg=function(){for(var a=d3.event,b;b=a.sourceEvent;)a=b;return a},Ug=function(a,b){var c=a.ownerSVGElement||a;if(c.createSVGPoint)return c=c.createSVGPoint(),c.x=b.clientX,c.y=b.clientY,c=c.matrixTransform(a.getScreenCTM().inverse()),[c.x,c.y];c=a.getBoundingClientRect();return[b.clientX-c.left-a.clientLeft,b.clientY-c.top-a.clientTop]},vb=function(a){var b=Tg();b.changedTouches&&(b=b.changedTouches[0]);return Ug(a,b)},Me=function(a){return null==\na?df:function(){return this.querySelector(a)}},Ir=function(a){\"function\"!==typeof a&&(a=Me(a));for(var b=this.Dd,c=b.length,e=Array(c),g=0;g<c;++g)for(var p=b[g],k=p.length,n=e[g]=Array(k),m,q,u=0;u<k;++u)(m=p[u])&&(q=a.call(m,m.__data__,u,p))&&(\"__data__\"in m&&(q.__data__=m.__data__),n[u]=q);return new Ga(e,this.If)},Vg=function(a){return null==a?ef:function(){return this.querySelectorAll(a)}},Jr=function(a){\"function\"!==typeof a&&(a=Vg(a));for(var b=this.Dd,c=b.length,e=[],g=[],p=0;p<c;++p)for(var k=\nb[p],n=k.length,m,q=0;q<n;++q)if(m=k[q])e.push(a.call(m,m.__data__,q,k)),g.push(m);return new Ga(e,g)},Kr=function(a){\"function\"!==typeof a&&(a=Sg(a));for(var b=this.Dd,c=b.length,e=Array(c),g=0;g<c;++g)for(var p=b[g],k=p.length,n=e[g]=[],m,q=0;q<k;++q)(m=p[q])&&a.call(m,m.__data__,q,p)&&n.push(m);return new Ga(e,this.If)},Uk=function(a){return Array(a.length)},Lr=function(){return new Ga(this.DF||this.Dd.map(Uk),this.If)};Fb.prototype={constructor:Fb,appendChild:function(a){return this.Ye.insertBefore(a,\nthis.Vg)},insertBefore:function(a,b){return this.Ye.insertBefore(a,b)},querySelector:function(a){return this.Ye.querySelector(a)},querySelectorAll:function(a){return this.Ye.querySelectorAll(a)}};var Mr=function(a){return function(){return a}},Nr=function(a,b){if(!a)return w=Array(this.size()),m=-1,this.each(function(a){w[++m]=a}),w;var c=b?vd:Dc,e=this.If,g=this.Dd;\"function\"!==typeof a&&(a=Mr(a));for(var p=g.length,k=Array(p),n=Array(p),t=Array(p),m=0;m<p;++m){var u=e[m],y=g[m],r=y.length,w=a.call(u,\nu&&u.__data__,m,e),H=w.length,F=n[m]=Array(H),ca=k[m]=Array(H),r=t[m]=Array(r);c(u,y,F,ca,r,w,b);for(var y=u=0,q;u<H;++u)if(r=F[u]){for(u>=y&&(y=u+1);!(q=ca[y])&&++y<H;);r.Vg=q||null}}k=new Ga(k,e);k.DF=n;k.EF=t;return k},Or=function(){return new Ga(this.EF||this.Dd.map(Uk),this.If)},Pr=function(a){var b=this.Dd;a=a.Dd;for(var c=b.length,e=a.length,e=Math.min(c,e),g=Array(c),p=0;p<e;++p)for(var k=b[p],n=a[p],m=k.length,q=g[p]=Array(m),u,y=0;y<m;++y)if(u=k[y]||n[y])q[y]=u;for(;p<c;++p)g[p]=b[p];return new Ga(g,\nthis.If)},Qr=function(){for(var a=this.Dd,b=-1,c=a.length;++b<c;)for(var e=a[b],g=e.length-1,k=e[g],n;0<=--g;)if(n=e[g])k&&k!==n.nextSibling&&k.parentNode.insertBefore(n,k),k=n;return this},Rr=function(a){function b(b,c){return b&&c?a(b.__data__,c.__data__):!b-!c}a||(a=wd);for(var c=this.Dd,e=c.length,g=Array(e),p=0;p<e;++p){for(var k=c[p],n=k.length,m=g[p]=Array(n),q,u=0;u<n;++u)if(q=k[u])m[u]=q;m.sort(b)}return(new Ga(g,this.If)).order()},Sr=function(){var a=arguments[0];arguments[0]=this;a.apply(null,\narguments);return this},Tr=function(){var a=Array(this.size()),b=-1;this.each(function(){a[++b]=this});return a},Ur=function(){for(var a=this.Dd,b=0,c=a.length;b<c;++b)for(var e=a[b],g=0,k=e.length;g<k;++g){var n=e[g];if(n)return n}return null},Vr=function(){var a=0;this.each(function(){++a});return a},Wr=function(){return!this.node()},Xr=function(a){for(var b=this.Dd,c=0,e=b.length;c<e;++c)for(var g=b[c],k=0,p=g.length,n;k<p;++k)(n=g[k])&&a.call(n,n.__data__,k,g);return this},Yr=function(a,b){var c=\nod(a);if(2>arguments.length){var e=this.node();return c.local?e.getAttributeNS(c.space,c.local):e.getAttribute(c)}return this.each((null==b?c.local?Gb:ta:\"function\"===typeof b?c.local?wm:vm:c.local?um:Hb)(c,b))},$b=function(a){return a.ownerDocument&&a.ownerDocument.defaultView||a.document&&a||a.defaultView},Zr=function(a,b,c){var e;return 1<arguments.length?this.each((null==b?xm:\"function\"===typeof b?zm:ym)(a,b,null==c?\"\":c)):$b(e=this.node()).getComputedStyle(e,null).getPropertyValue(a)},$r=function(a,\nb){return 1<arguments.length?this.each((null==b?Am:\"function\"===typeof b?Cm:Bm)(a,b)):this.node()[a]};Ah.prototype={add:function(a){var b=this.Wi.indexOf(a);0>b&&(this.Wi.push(a),this.Vv.setAttribute(\"class\",this.Wi.join(\" \")))},remove:function(a){a=this.Wi.indexOf(a);0<=a&&(this.Wi.splice(a,1),this.Vv.setAttribute(\"class\",this.Wi.join(\" \")))},contains:function(a){return 0<=this.Wi.indexOf(a)}};var as=function(a,b){var c=(a+\"\").trim().split(/^|\\s+/);if(2>arguments.length){for(var e=ff(this.node()),\ng=-1,k=c.length;++g<k;)if(!e.contains(c[g]))return!1;return!0}return this.each((\"function\"===typeof b?Fm:b?Dm:Em)(c,b))},bs=function(a){return arguments.length?this.each(null==a?Gm:(\"function\"===typeof a?Im:Hm)(a)):this.node().textContent},cs=function(a){return arguments.length?this.each(null==a?Jm:(\"function\"===typeof a?Lm:Km)(a)):this.node().innerHTML},ds=function(){return this.each(Mm)},es=function(){return this.each(Nm)},fs=function(a){var b=\"function\"===typeof a?a:Rg(a);return this.select(function(){return this.appendChild(b.apply(this,\narguments))})},gs=function(a,b){var c=\"function\"===typeof a?a:Rg(a),e=null==b?Om:\"function\"===typeof b?b:Me(b);return this.select(function(){return this.insertBefore(c.apply(this,arguments),e.apply(this,arguments)||null)})},hs=function(){return this.each(Pm)},is=function(a){return arguments.length?this.property(\"__data__\",a):this.node().__data__},js=function(a,b){return this.each((\"function\"===typeof b?Rm:Qm)(a,b))},gf=[null];Ga.prototype=Ib.prototype={constructor:Ga,select:Ir,selectAll:Jr,filter:Kr,\ndata:Nr,enter:Lr,exit:Or,merge:Pr,order:Qr,sort:Rr,call:Sr,nodes:Tr,node:Ur,size:Vr,empty:Wr,each:Xr,attr:Yr,style:Zr,property:$r,classed:as,text:bs,html:cs,raise:ds,lower:es,append:fs,insert:gs,remove:hs,datum:is,on:Hr,dispatch:js};var Ma=function(a){return\"string\"===typeof a?new Ga([[document.querySelector(a)]],[document.documentElement]):new Ga([[a]],gf)},ks=function(a){return\"string\"===typeof a?new Ga([document.querySelectorAll(a)],[document.documentElement]):new Ga([null==a?[]:a],gf)},Ne=function(a,\nb,c){3>arguments.length&&(c=b,b=Tg().changedTouches);for(var e=0,g=b?b.length:0,k;e<g;++e)if((k=b[e]).identifier===c)return Ug(a,k);return null},ls=function(a,b){null==b&&(b=Tg().touches);for(var c=0,e=b?b.length:0,g=Array(e);c<e;++c)g[c]=Ug(a,b[c]);return g},ac=function(){d3.event.preventDefault();d3.event.stopImmediatePropagation()},Kd=function(a){var b=a.document.documentElement;a=Ma(a).on(\"dragstart.drag\",ac,!0);if(\"onselectstart\"in b)a.on(\"selectstart.drag\",ac,!0);else b.iv=b.style.MozUserSelect,\nb.style.MozUserSelect=\"none\"},Wg=function(a){return function(){return a}};hf.prototype.on=function(){var a=this.Fa.on.apply(this.Fa,arguments);return a===this.Fa?this:a};var ms=function(){function a(a){a.on(\"mousedown.drag\",b).on(\"touchstart.drag\",g).on(\"touchmove.drag\",k).on(\"touchend.drag touchcancel.drag\",n).style(\"-webkit-tap-highlight-color\",\"rgba(0,0,0,0)\")}function b(){if(!F&&q.apply(this,arguments)){var a=m(\"mouse\",v.apply(this,arguments),vb,this,arguments);a&&(Ma(d3.event.view).on(\"mousemove.drag\",\nc,!0).on(\"mouseup.drag\",e,!0),Kd(d3.event.view),d3.event.stopImmediatePropagation(),H=!1,a(\"start\"))}}function c(){ac();H=!0;y.mouse(\"drag\")}function e(){Ma(d3.event.view).on(\"mousemove.drag mouseup.drag\",null);xd(d3.event.view,H);ac();y.mouse(\"end\")}function g(){if(q.apply(this,arguments)){var a=d3.event.changedTouches,b=v.apply(this,arguments),c=a.length,e,g;for(e=0;e<c;++e)if(g=m(a[e].identifier,b,Ne,this,arguments))d3.event.stopImmediatePropagation(),g(\"start\")}}function k(){var a=d3.event.changedTouches,\nb=a.length,c,e;for(c=0;c<b;++c)if(e=y[a[c].identifier])ac(),e(\"drag\")}function n(){var a=d3.event.changedTouches,b=a.length,c,e;F&&clearTimeout(F);F=setTimeout(function(){F=null},500);for(c=0;c<b;++c)if(e=y[a[c].identifier])d3.event.stopImmediatePropagation(),e(\"end\")}function m(b,c,e,g,k){var p=e(c,b),n,A,m,t=r.copy();if(Ya(new hf(a,\"beforestart\",n,b,w,p[0],p[1],0,0,t),function(){if(null==(d3.event.subject=n=u.apply(g,k)))return!1;A=n.x-p[0]||0;m=n.y-p[1]||0;return!0}))return function lo(r){var u=\np,H;switch(r){case \"start\":y[b]=lo;H=w++;break;case \"end\":delete y[b],--w;case \"drag\":p=e(c,b),H=w}Ya(new hf(a,r,n,b,H,p[0]+A,p[1]+m,p[0]-u[0],p[1]-u[1],t),t.apply,t,[r,g,k])}}var q=Sm,v=Tm,u=Um,y={},r=E(\"start\",\"drag\",\"end\"),w=0,H,F;a.filter=function(b){return arguments.length?(q=\"function\"===typeof b?b:Wg(!!b),a):q};a.container=function(b){return arguments.length?(v=\"function\"===typeof b?b:Wg(b),a):v};a.subject=function(b){return arguments.length?(u=\"function\"===typeof b?b:Wg(b),a):u};a.on=function(){var b=\nr.on.apply(r,arguments);return b===r?a:b};return a},uc=function(a,b,c){a.prototype=b.prototype=c;c.constructor=a},vc=1/.7,Vm=/^#([0-9a-f]{3})$/,Wm=/^#([0-9a-f]{6})$/,Xm=/^rgb\\(\\s*([+-]?\\d+)\\s*,\\s*([+-]?\\d+)\\s*,\\s*([+-]?\\d+)\\s*\\)$/,Ym=/^rgb\\(\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)%\\s*,\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)%\\s*,\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)%\\s*\\)$/,Zm=/^rgba\\(\\s*([+-]?\\d+)\\s*,\\s*([+-]?\\d+)\\s*,\\s*([+-]?\\d+)\\s*,\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)\\s*\\)$/,$m=/^rgba\\(\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)%\\s*,\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)%\\s*,\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)%\\s*,\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)\\s*\\)$/,\nan=/^hsl\\(\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)\\s*,\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)%\\s*,\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)%\\s*\\)$/,bn=/^hsla\\(\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)\\s*,\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)%\\s*,\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)%\\s*,\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)\\s*\\)$/,Hh={aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,\nburlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,\ndarkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,\nlightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,\nmediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,\nred:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074};uc(rb,sb,{displayable:function(){return this.rgb().displayable()},\ntoString:function(){return this.rgb()+\"\"}});uc(za,Fc,Ec(rb,{brighter:function(a){a=null==a?vc:Math.pow(vc,a);return new za(this.r*a,this.g*a,this.b*a,this.opacity)},darker:function(a){a=null==a?.7:Math.pow(.7,a);return new za(this.r*a,this.g*a,this.b*a,this.opacity)},rgb:function(){return this},displayable:function(){return 0<=this.r&&255>=this.r&&0<=this.g&&255>=this.g&&0<=this.b&&255>=this.b&&0<=this.opacity&&1>=this.opacity},toString:function(){var a=this.opacity,a=isNaN(a)?1:Math.max(0,Math.min(1,\na));return(1===a?\"rgb(\":\"rgba(\")+Math.max(0,Math.min(255,Math.round(this.r)||0))+\", \"+Math.max(0,Math.min(255,Math.round(this.g)||0))+\", \"+Math.max(0,Math.min(255,Math.round(this.b)||0))+(1===a?\")\":\", \"+a+\")\")}}));uc(db,yd,Ec(rb,{brighter:function(a){a=null==a?vc:Math.pow(vc,a);return new db(this.h,this.s,this.l*a,this.opacity)},darker:function(a){a=null==a?.7:Math.pow(.7,a);return new db(this.h,this.s,this.l*a,this.opacity)},rgb:function(){var a=this.h%360+360*(0>this.h),b=isNaN(a)||isNaN(this.s)?\n0:this.s,c=this.l,b=c+(.5>c?c:1-c)*b,c=2*c-b;return new za(kf(240<=a?a-240:a+120,c,b),kf(a,c,b),kf(120>a?a+240:a-120,c,b),this.opacity)},displayable:function(){return(0<=this.s&&1>=this.s||isNaN(this.s))&&0<=this.l&&1>=this.l&&0<=this.opacity&&1>=this.opacity}}));var Ih=Math.PI/180,Lh=180/Math.PI,Kh=4/29,bc=6/29,Jh=3*bc*bc,dn=bc*bc*bc;uc(kb,zd,Ec(rb,{brighter:function(a){return new kb(this.l+18*(null==a?1:a),this.a,this.b,this.opacity)},darker:function(a){return new kb(this.l-18*(null==a?1:a),this.a,\nthis.b,this.opacity)},rgb:function(){var a=(this.l+16)/116,b=isNaN(this.a)?a:a+this.a/500,c=isNaN(this.b)?a:a-this.b/200,a=1*of(a),b=.95047*of(b),c=1.08883*of(c);return new za(pf(3.2404542*b-1.5371385*a-.4985314*c),pf(-.969266*b+1.8760108*a+.041556*c),pf(.0556434*b-.2040259*a+1.0572252*c),this.opacity)}}));uc(tb,Ad,Ec(rb,{brighter:function(a){return new tb(this.h,this.c,this.l+18*(null==a?1:a),this.opacity)},darker:function(a){return new tb(this.h,this.c,this.l-18*(null==a?1:a),this.opacity)},rgb:function(){return lf(this).rgb()}}));\nvar Mh=1.78277*-.29227-.1347134789;uc(Jb,Za,Ec(rb,{brighter:function(a){a=null==a?vc:Math.pow(vc,a);return new Jb(this.h,this.s,this.l*a,this.opacity)},darker:function(a){a=null==a?.7:Math.pow(.7,a);return new Jb(this.h,this.s,this.l*a,this.opacity)},rgb:function(){var a=isNaN(this.h)?0:(this.h+120)*Ih,b=+this.l,c=isNaN(this.s)?0:this.s*b*(1-b),e=Math.cos(a),a=Math.sin(a);return new za(255*(b+c*(-.14861*e+1.78277*a)),255*(b+c*(-.29227*e+-.90649*a)),255*(b+1.97294*c*e),this.opacity)}}));var Vk=function(a){var b=\na.length-1;return function(c){var e=0>=c?c=0:1<=c?(c=1,b-1):Math.floor(c*b),g=a[e],k=a[e+1],p=0<e?a[e-1]:2*g-k,n=e<b-1?a[e+2]:2*k-g;return Nh((c-e/b)*b,p,g,k,n)}},Wk=function(a){var b=a.length;return function(c){var e=Math.floor((0>(c%=1)?++c:c)*b),g=a[(e+b-1)%b],k=a[e%b],p=a[(e+1)%b],n=a[(e+2)%b];return Nh((c-e/b)*b,g,k,p,n)}},Bd=function(a){return function(){return a}},qd=function t(a){function b(a,b){var e=c((a=Fc(a)).r,(b=Fc(b)).r),g=c(a.g,b.g),k=c(a.b,b.b),u=ya(a.opacity,b.opacity);return function(b){a.r=\ne(b);a.g=g(b);a.b=k(b);a.opacity=u(b);return a+\"\"}}var c=fn(a);b.gamma=t;return b}(1),ns=Ph(Vk),os=Ph(Wk),Xk=function(a,b){var c=b?b.length:0,e=a?Math.min(c,a.length):0,g=Array(c),k=Array(c),n;for(n=0;n<e;++n)g[n]=Pc(a[n],b[n]);for(;n<c;++n)k[n]=b[n];return function(a){for(n=0;n<e;++n)k[n]=g[n](a);return k}},Yk=function(a,b){var c=new Date;return a=+a,b-=a,function(e){return c.setTime(a+b*e),c}},Na=function(a,b){return a=+a,b-=a,function(c){return a+b*c}},Zk=function(a,b){var c={},e={},g;if(null===\na||\"object\"!==typeof a)a={};if(null===b||\"object\"!==typeof b)b={};for(g in b)g in a?c[g]=Pc(a[g],b[g]):e[g]=b[g];return function(a){for(g in c)e[g]=c[g](a);return e}},Xg=/[-+]?(?:\\d+\\.?\\d*|\\.?\\d+)(?:[eE][-+]?\\d+)?/g,Yg=new RegExp(Xg.source,\"g\"),Zg=function(a,b){var c=Xg.lastIndex=Yg.lastIndex=0,e,g,k,n=-1,m=[],t=[];a+=\"\";for(b+=\"\";(e=Xg.exec(a))&&(g=Yg.exec(b));)(k=g.index)>c&&(k=b.slice(c,k),m[n]?m[n]+=k:m[++n]=k),(e=e[0])===(g=g[0])?m[n]?m[n]+=g:m[++n]=g:(m[++n]=null,t.push({uf:n,x:Na(e,g)})),c=\nYg.lastIndex;c<b.length&&(k=b.slice(c),m[n]?m[n]+=k:m[++n]=k);return 2>m.length?t[0]?hn(t[0].x):gn(b):(b=t.length,function(a){for(var c=0,e;c<b;++c)m[(e=t[c]).uf]=e.x(a);return m.join(\"\")})},Pc=function(a,b){var c=typeof b,e;return null==b||\"boolean\"===c?Bd(b):(\"number\"===c?Na:\"string\"===c?(e=sb(b))?(b=e,qd):Zg:b instanceof sb?qd:b instanceof Date?Yk:Array.isArray(b)?Xk:isNaN(b)?Zk:Na)(a,b)},Nj=function(a,b){return a=+a,b-=a,function(c){return Math.round(a+b*c)}},$k=180/Math.PI,rf={zt:0,At:0,rotate:0,\nskewX:0,Gs:1,Hs:1},Rh=function(a,b,c,e,g,k){var n,m,t;if(n=Math.sqrt(a*a+b*b))a/=n,b/=n;if(t=a*c+b*e)c-=a*t,e-=b*t;if(m=Math.sqrt(c*c+e*e))c/=m,e/=m,t/=m;a*e<b*c&&(a=-a,b=-b,t=-t,n=-n);return{zt:g,At:k,rotate:Math.atan2(b,a)*$k,skewX:Math.atan(t)*$k,Gs:n,Hs:m}},Gc,sf,Qh,Cd,al=Sh(jn,\"px, \",\"px)\",\"deg)\"),bl=Sh(kn,\", \",\")\",\")\"),rd=Math.SQRT2,cl=function(a,b){var c=a[0],e=a[1],g=a[2];a=b[0];var k=b[1];b=b[2];var n=a-c,m=k-e,k=n*n+m*m,t;if(1E-12>k)t=Math.log(b/g)/rd,b=function(a){return[c+a*n,e+a*m,g*\nMath.exp(rd*a*t)]};else{var u=Math.sqrt(k);a=(b*b-g*g+4*k)/(4*g*u);b=(b*b-g*g-4*k)/(4*b*u);var y=Math.log(Math.sqrt(a*a+1)-a);b=Math.log(Math.sqrt(b*b+1)-b);t=(b-y)/rd;b=function(a){a*=t;var b=Th(y),k,r=y;k=((r=Math.exp(r))-1/r)/2;var q=rd*a+y,r=((q=Math.exp(2*q))-1)/(q+1);k=g/(2*u)*(b*r-k);return[c+k*n,e+k*m,g*b/Th(rd*a+y)]}}b.duration=1E3*t;return b},ps=Uh(qf),qs=Uh(ya),rs=Vh(qf),ss=Vh(ya),ts=Wh(qf),Oe=Wh(ya),us=function(a,b){for(var c=Array(b),e=0;e<b;++e)c[e]=a(e/(b-1));return c},dc=0,Ic=0,Kc=\n0,Ed,Jc,Fd=0,ub=0,uf=0,tf=\"object\"===typeof performance&&performance.now?performance:Date,Xh=\"function\"===typeof requestAnimationFrame?requestAnimationFrame:function(a){setTimeout(a,17)};Hc.prototype=Dd.prototype={constructor:Hc,restart:function(a,b,c){if(\"function\"!==typeof a)throw new TypeError(\"callback is not a function\");c=(null==c?cc():+c)+(null==b?0:+b);this.Vg||Jc===this||(Jc?Jc.Vg=this:Ed=this,Jc=this);this.$f=a;this.ml=c;vf()},stop:function(){this.$f&&(this.$f=null,this.ml=Infinity,vf())}};\nvar xf=function(a,b,c){var e=new Hc;b=null==b?0:+b;e.restart(function(c){e.stop();a(c+b)},b,c);return e},vs=function(a,b,c){var e=new Hc,g=b;if(null==b)return e.restart(a,b,c),e;b=+b;c=null==c?cc():+c;e.restart(function X(k){k+=g;e.restart(X,g+=b,c);a(k)},b,c);return e},ws=E(\"start\",\"end\",\"interrupt\"),xs=[],Pe=function(a,b,c,e,g,k){var n=a.zg;if(!n)a.zg={};else if(c in n)return;on(a,c,{name:b,index:e,group:g,on:ws,tween:xs,time:k.time,delay:k.delay,duration:k.duration,ease:k.ease,timer:null,state:0})},\nLb=function(a,b){var c=a.zg,e,g,k=!0,n;if(c){b=null==b?null:b+\"\";for(n in c)(e=c[n]).name!==b?k=!1:(g=2<e.state&&5>e.state,e.state=6,e.timer.stop(),g&&e.on.call(\"interrupt\",a,a.__data__,e.index,e.group),delete c[n]);k&&delete a.zg}},ys=function(a){return this.each(function(){Lb(this,a)})},zs=function(a,b){var c=this.Kc;a+=\"\";if(2>arguments.length){for(var c=lb(this.node(),c).tween,e=0,g=c.length,k;e<g;++e)if((k=c[e]).name===a)return k.value;return null}return this.each((null==b?pn:qn)(c,a,b))},dl=\nfunction(a,b){var c;return(\"number\"===typeof b?Na:b instanceof sb?qd:(c=sb(b))?(b=c,qd):Zg)(a,b)},As=function(a,b){var c=od(a),e=\"transform\"===c?bl:dl;return this.attrTween(a,\"function\"===typeof b?(c.local?wn:vn)(c,e,yf(this,\"attr.\"+a,b)):null==b?(c.local?sn:rn)(c):(c.local?un:tn)(c,e,b))},Bs=function(a,b){var c=\"attr.\"+a;if(2>arguments.length)return(c=this.tween(c))&&c.uh;if(null==b)return this.tween(c,null);if(\"function\"!==typeof b)throw Error();var e=od(a);return this.tween(c,(e.local?xn:yn)(e,\nb))},Cs=function(a){var b=this.Kc;return arguments.length?this.each((\"function\"===typeof a?zn:An)(b,a)):lb(this.node(),b).delay},Ds=function(a){var b=this.Kc;return arguments.length?this.each((\"function\"===typeof a?Bn:Cn)(b,a)):lb(this.node(),b).duration},Es=function(a){var b=this.Kc;return arguments.length?this.each(Dn(b,a)):lb(this.node(),b).ease},Fs=function(a){\"function\"!==typeof a&&(a=Sg(a));for(var b=this.Dd,c=b.length,e=Array(c),g=0;g<c;++g)for(var k=b[g],n=k.length,m=e[g]=[],t,u=0;u<n;++u)(t=\nk[u])&&a.call(t,t.__data__,u,k)&&m.push(t);return new eb(e,this.If,this.Uj,this.Kc)},Gs=function(a){if(a.Kc!==this.Kc)throw Error();var b=this.Dd;a=a.Dd;for(var c=b.length,e=a.length,e=Math.min(c,e),g=Array(c),k=0;k<e;++k)for(var n=b[k],m=a[k],t=n.length,u=g[k]=Array(t),y,r=0;r<t;++r)if(y=n[r]||m[r])u[r]=y;for(;k<c;++k)g[k]=b[k];return new eb(g,this.If,this.Uj,this.Kc)},Hs=function(a,b){var c=this.Kc;return 2>arguments.length?lb(this.node(),c).on.on(a):this.each(Fn(c,a,b))},Is=function(){return this.on(\"end.remove\",\nGn(this.Kc))},Js=function(a){var b=this.Uj,c=this.Kc;\"function\"!==typeof a&&(a=Me(a));for(var e=this.Dd,g=e.length,k=Array(g),n=0;n<g;++n)for(var m=e[n],t=m.length,u=k[n]=Array(t),y,r,w=0;w<t;++w)(y=m[w])&&(r=a.call(y,y.__data__,w,m))&&(\"__data__\"in y&&(r.__data__=y.__data__),u[w]=r,Pe(u[w],b,c,w,u,lb(y,c)));return new eb(k,this.If,b,c)},Ks=function(a){var b=this.Uj,c=this.Kc;\"function\"!==typeof a&&(a=Vg(a));for(var e=this.Dd,g=e.length,k=[],n=[],m=0;m<g;++m)for(var t=e[m],u=t.length,y,r=0;r<u;++r)if(y=\nt[r]){for(var w=a.call(y,y.__data__,r,t),H,F=lb(y,c),q=0,qa=w.length;q<qa;++q)(H=w[q])&&Pe(H,b,c,q,w,F);k.push(w);n.push(y)}return new eb(k,n,b,c)},Ls=Ib.prototype.constructor,Ms=function(){return new Ls(this.Dd,this.If)},Ns=function(a,b,c){var e=\"transform\"===(a+=\"\")?al:dl;return null==b?this.styleTween(a,Hn(a,e)).on(\"end.style.\"+a,In(a)):this.styleTween(a,\"function\"===typeof b?Kn(a,e,yf(this,\"style.\"+a,b)):Jn(a,e,b),c)},Os=function(a,b,c){var e=\"style.\"+(a+=\"\");if(2>arguments.length)return(e=this.tween(e))&&\ne.uh;if(null==b)return this.tween(e,null);if(\"function\"!==typeof b)throw Error();return this.tween(e,Ln(a,b,null==c?\"\":c))},Ps=function(a){return this.tween(\"text\",\"function\"===typeof a?Nn(yf(this,\"text\",a)):Mn(null==a?\"\":a+\"\"))},Qs=function(){for(var a=this.Uj,b=this.Kc,c=++el,e=this.Dd,g=e.length,k=0;k<g;++k)for(var n=e[k],m=n.length,q,u=0;u<m;++u)if(q=n[u]){var y=lb(q,b);Pe(q,a,c,u,n,{time:y.time+y.delay+y.duration,delay:0,duration:y.duration,ease:y.ease})}return new eb(e,this.If,a,c)},el=0,wc=\nIb.prototype;eb.prototype=$h.prototype={constructor:eb,select:Js,selectAll:Ks,filter:Fs,merge:Gs,selection:Ms,transition:Qs,call:wc.call,nodes:wc.nodes,node:wc.node,size:wc.size,empty:wc.empty,each:wc.each,on:Hs,attr:As,attrTween:Bs,style:Ns,styleTween:Os,text:Ps,remove:Is,tween:zs,delay:Cs,duration:Ds,ease:Es};var Rs=function z(a){function b(b){return Math.pow(b,a)}a=+a;b.exponent=z;return b}(3),Ss=function I(a){function b(b){return 1-Math.pow(1-b,a)}a=+a;b.exponent=I;return b}(3),fl=function P(a){function b(b){return(1>=\n(b*=2)?Math.pow(b,a):2-Math.pow(2-b,a))/2}a=+a;b.exponent=P;return b}(3),di=Math.PI,bi=di/2,Af=4/11,ao=6/11,$n=8/11,co=9/11,bo=10/11,eo=21/22,Gd=1/Af/Af,Ts=function R(a){function b(b){return b*b*((a+1)*b-a)}a=+a;b.overshoot=R;return b}(1.70158),Us=function da(a){function b(b){return--b*b*((a+1)*b+a)+1}a=+a;b.overshoot=da;return b}(1.70158),gl=function X(a){function b(b){return(1>(b*=2)?b*b*((a+1)*b-a):(b-=2)*b*((a+1)*b+a)+2)/2}a=+a;b.overshoot=X;return b}(1.70158),xc=2*Math.PI,Vs=function fa(a,b){function c(c){return a*\nMath.pow(2,10*--c)*Math.sin((e-c)/b)}var e=Math.asin(1/(a=Math.max(1,a)))*(b/=xc);c.amplitude=function(a){return fa(a,b*xc)};c.period=function(b){return fa(a,b)};return c}(1,.3),hl=function jb(a,b){function c(c){return 1-a*Math.pow(2,-10*(c=+c))*Math.sin((c+e)/b)}var e=Math.asin(1/(a=Math.max(1,a)))*(b/=xc);c.amplitude=function(a){return jb(a,b*xc)};c.period=function(b){return jb(a,b)};return c}(1,.3),Ws=function u(a,b){function c(c){return(0>(c=2*c-1)?a*Math.pow(2,10*c)*Math.sin((e-c)/b):2-a*Math.pow(2,\n-10*c)*Math.sin((e+c)/b))/2}var e=Math.asin(1/(a=Math.max(1,a)))*(b/=xc);c.amplitude=function(a){return u(a,b*xc)};c.period=function(b){return u(a,b)};return c}(1,.3),$g={time:null,delay:0,duration:250,ease:zf},Xs=function(a){var b,c;a instanceof eb?(b=a.Kc,a=a.Uj):(b=++el,(c=$g).time=cc(),a=null==a?null:a+\"\");for(var e=this.Dd,g=e.length,k=0;k<g;++k)for(var u=e[k],n=u.length,m,A=0;A<n;++A)if(m=u[A]){var L=m,q=a,M=b,G=A,v=u,Y;if(!(Y=c))a:{Y=void 0;for(var Aa=b;!(Y=m.zg)||!(Y=Y[Aa]);)if(!(m=m.parentNode)){Y=\n($g.time=cc(),$g);break a}}Pe(L,q,M,G,v,Y)}return new eb(e,this.If,a,b)};Ib.prototype.interrupt=ys;Ib.prototype.transition=Xs;var Ys=[null],Zs=function(a,b){var c=a.zg,e,g;if(c)for(g in b=null==b?null:b+\"\",c)if(1<(e=c[g]).state&&e.name===b)return new eb([[a]],Ys,b,+g);return null},ji=function(a){return function(){return a}},qo=function(a,b,c){this.target=a;this.type=b;this.selection=c},Jd=function(){d3.event.preventDefault();d3.event.stopImmediatePropagation()},gi={name:\"drag\"},Ef={name:\"space\"},\nec={name:\"handle\"},fc={name:\"center\"},Hd={name:\"x\",Ur:[\"e\",\"w\"].map(Mc),input:function(a,b){return a&&[[a[0],b[0][1]],[a[1],b[1][1]]]},No:function(a){return a&&[a[0][0],a[1][0]]}},Id={name:\"y\",Ur:[\"n\",\"s\"].map(Mc),input:function(a,b){return a&&[[b[0][0],a[0]],[b[1][0],a[1]]]},No:function(a){return a&&[a[0][1],a[1][1]]}},$s={name:\"xy\",Ur:\"n e s w nw ne se sw\".split(\" \").map(Mc),input:function(a){return a},No:function(a){return a}},mb={overlay:\"crosshair\",selection:\"move\",n:\"ns-resize\",e:\"ew-resize\",\ns:\"ns-resize\",w:\"ew-resize\",nw:\"nwse-resize\",ne:\"nesw-resize\",se:\"nwse-resize\",sw:\"nesw-resize\"},hi={e:\"w\",w:\"e\",nw:\"ne\",ne:\"nw\",se:\"sw\",sw:\"se\"},ii={n:\"s\",s:\"n\",nw:\"sw\",ne:\"se\",se:\"ne\",sw:\"nw\"},oo={overlay:1,selection:1,n:null,e:1,s:null,w:-1,nw:-1,ne:1,se:1,sw:-1},po={overlay:1,selection:1,n:-1,e:null,s:1,w:null,nw:-1,ne:-1,se:1,sw:1},at=function(){return Df($s)},il=Math.cos,jl=Math.sin,kl=Math.PI,Qe=kl/2,ll=2*kl,ml=Math.max,bt=function(){function a(a){var k=a.length,r=[],u=bb(k),n=[],w=[],m=w.groups=\nArray(k),y=Array(k*k),H,F,q,v,B,E;H=0;for(B=-1;++B<k;){F=0;for(E=-1;++E<k;)F+=a[B][E];r.push(F);n.push(bb(k));H+=F}c&&u.sort(function(a,b){return c(r[a],r[b])});e&&n.forEach(function(b,c){b.sort(function(b,g){return e(a[c][b],a[c][g])})});v=(H=ml(0,ll-b*k)/H)?b:ll/k;F=0;for(B=-1;++B<k;){q=F;for(E=-1;++E<k;){var J=u[B],C=n[J][E],W=a[J][C],O=F,K=F+=W*H;y[C*k+J]={index:J,subindex:C,startAngle:O,endAngle:K,value:W}}m[J]={index:J,startAngle:q,endAngle:F,value:r[J]};F+=v}for(B=-1;++B<k;)for(E=B-1;++E<k;)u=\ny[E*k+B],n=y[B*k+E],(u.value||n.value)&&w.push(u.value<n.value?{source:n,target:u}:{source:u,target:n});return g?w.sort(g):w}var b=0,c=null,e=null,g=null;a.padAngle=function(c){return arguments.length?(b=ml(0,c),a):b};a.sortGroups=function(b){return arguments.length?(c=b,a):c};a.sortSubgroups=function(b){return arguments.length?(e=b,a):e};a.sortChords=function(b){return arguments.length?(null==b?g=null:(g=ro(b)).Fa=b,a):g&&g.Fa};return a},ct=Array.prototype.slice,ah=function(a){return function(){return a}},\nbh=Math.PI,ch=2*bh,dt=ch-1E-6;Ff.prototype=Mb.prototype={constructor:Ff,moveTo:function(a,b){this.Fa+=\"M\"+(this.ub=this.Sa=+a)+\",\"+(this.xb=this.Va=+b)},closePath:function(){null!==this.Sa&&(this.Sa=this.ub,this.Va=this.xb,this.Fa+=\"Z\")},lineTo:function(a,b){this.Fa+=\"L\"+(this.Sa=+a)+\",\"+(this.Va=+b)},quadraticCurveTo:function(a,b,c,e){this.Fa+=\"Q\"+ +a+\",\"+ +b+\",\"+(this.Sa=+c)+\",\"+(this.Va=+e)},bezierCurveTo:function(a,b,c,e,g,k){this.Fa+=\"C\"+ +a+\",\"+ +b+\",\"+ +c+\",\"+ +e+\",\"+(this.Sa=+g)+\",\"+(this.Va=\n+k)},arcTo:function(a,b,c,e,g){a=+a;b=+b;c=+c;e=+e;g=+g;var k=this.Sa,r=this.Va,u=c-a,n=e-b,w=k-a,m=r-b,y=w*w+m*m;if(0>g)throw Error(\"negative radius: \"+g);if(null===this.Sa)this.Fa+=\"M\"+(this.Sa=a)+\",\"+(this.Va=b);else if(1E-6<y)if(1E-6<Math.abs(m*u-n*w)&&g){c-=k;e-=r;var H=u*u+n*n,q=c*c+e*e,r=Math.sqrt(H),k=Math.sqrt(y),y=g*Math.tan((bh-Math.acos((H+y-q)/(2*r*k)))/2),k=y/k,y=y/r;1E-6<Math.abs(k-1)&&(this.Fa+=\"L\"+(a+k*w)+\",\"+(b+k*m));this.Fa+=\"A\"+g+\",\"+g+\",0,0,\"+ +(m*c>w*e)+\",\"+(this.Sa=a+y*u)+\",\"+\n(this.Va=b+y*n)}else this.Fa+=\"L\"+(this.Sa=a)+\",\"+(this.Va=b)},arc:function(a,b,c,e,g,k){a=+a;b=+b;c=+c;var r=c*Math.cos(e),u=c*Math.sin(e),n=a+r,w=b+u,m=1^k;e=k?e-g:g-e;if(0>c)throw Error(\"negative radius: \"+c);if(null===this.Sa)this.Fa+=\"M\"+n+\",\"+w;else if(1E-6<Math.abs(this.Sa-n)||1E-6<Math.abs(this.Va-w))this.Fa+=\"L\"+n+\",\"+w;c&&(e>dt?this.Fa+=\"A\"+c+\",\"+c+\",0,1,\"+m+\",\"+(a-r)+\",\"+(b-u)+\"A\"+c+\",\"+c+\",0,1,\"+m+\",\"+(this.Sa=n)+\",\"+(this.Va=w):(0>e&&(e=e%ch+ch),this.Fa+=\"A\"+c+\",\"+c+\",0,\"+ +(e>=bh)+\",\"+\nm+\",\"+(this.Sa=a+c*Math.cos(g))+\",\"+(this.Va=b+c*Math.sin(g))))},rect:function(a,b,c,e){this.Fa+=\"M\"+(this.ub=this.Sa=+a)+\",\"+(this.xb=this.Va=+b)+\"h\"+ +c+\"v\"+ +e+\"h\"+-c+\"Z\"},toString:function(){return this.Fa}};var et=function(){function a(){var a,r=ct.call(arguments),u=b.apply(this,r),w=c.apply(this,r),u=+e.apply(this,(r[0]=u,r)),m=g.apply(this,r)-Qe,y=k.apply(this,r)-Qe,H=u*il(m),q=u*jl(m),w=+e.apply(this,(r[0]=w,r)),F=g.apply(this,r)-Qe,r=k.apply(this,r)-Qe;n||(n=a=Mb());n.moveTo(H,q);n.arc(0,\n0,u,m,y);if(m!==F||y!==r)n.quadraticCurveTo(0,0,w*il(F),w*jl(F)),n.arc(0,0,w,F,r);n.quadraticCurveTo(0,0,H,q);n.closePath();if(a)return n=null,a+\"\"||null}var b=so,c=to,e=uo,g=vo,k=wo,n=null;a.radius=function(b){return arguments.length?(e=\"function\"===typeof b?b:ah(+b),a):e};a.startAngle=function(b){return arguments.length?(g=\"function\"===typeof b?b:ah(+b),a):g};a.endAngle=function(b){return arguments.length?(k=\"function\"===typeof b?b:ah(+b),a):k};a.source=function(c){return arguments.length?(b=c,\na):b};a.target=function(b){return arguments.length?(c=b,a):c};a.context=function(b){return arguments.length?(n=null==b?null:b,a):n};return a};Ld.prototype=fb.prototype={constructor:Ld,has:function(a){return\"$\"+a in this},get:function(a){return this[\"$\"+a]},set:function(a,b){this[\"$\"+a]=b;return this},remove:function(a){a=\"$\"+a;return a in this&&delete this[a]},clear:function(){for(var a in this)\"$\"===a[0]&&delete this[a]},keys:function(){var a=[],b;for(b in this)\"$\"===b[0]&&a.push(b.slice(1));return a},\nvalues:function(){var a=[],b;for(b in this)\"$\"===b[0]&&a.push(this[b]);return a},entries:function(){var a=[],b;for(b in this)\"$\"===b[0]&&a.push({key:b.slice(1),value:this[b]});return a},size:function(){var a=0,b;for(b in this)\"$\"===b[0]&&++a;return a},empty:function(){for(var a in this)if(\"$\"===a[0])return!1;return!0},each:function(a){for(var b in this)\"$\"===b[0]&&a(this[b],b.slice(1),this)}};var ft=function(){function a(b,e,r,n){if(e>=c.length)return null!=k?k(b):null!=g?b.sort(g):b;for(var u=-1,\nw=b.length,m=c[e++],A,y,H=fb(),q,F=r();++u<w;)(q=H.get(A=m(y=b[u])+\"\"))?q.push(y):H.set(A,[y]);H.each(function(b,c){n(F,c,a(b,e,r,n))});return F}function b(a,g){if(++g>c.length)return a;var r,n=e[g-1];null!=k&&g>=c.length?r=a.entries():(r=[],a.each(function(a,c){r.push({key:c,values:b(a,g)})}));return null!=n?r.sort(function(a,b){return n(a.key,b.key)}):r}var c=[],e=[],g,k,n;return n={object:function(b){return a(b,0,xo,yo)},map:function(b){return a(b,0,ki,li)},entries:function(c){return b(a(c,0,ki,\nli),0)},key:function(a){c.push(a);return n},sortKeys:function(a){e[c.length-1]=a;return n},sortValues:function(a){g=a;return n},rollup:function(a){k=a;return n}}},Xb=fb.prototype;Md.prototype=mi.prototype={constructor:Md,has:Xb.has,add:function(a){a+=\"\";this[\"$\"+a]=a;return this},remove:Xb.remove,clear:Xb.clear,values:Xb.keys,size:Xb.size,empty:Xb.empty,each:Xb.each};var gt=function(a){var b=[],c;for(c in a)b.push(c);return b},ht=function(a){var b=[],c;for(c in a)b.push(a[c]);return b},it=function(a){var b=\n[],c;for(c in a)b.push({key:c,value:a[c]});return b},dh=function(a){function b(a,b){var e,g;a=c(a,function(a,c){if(e)return e(a,c-1);g=a;e=b?zo(a,b):ni(a)});a.columns=g;return a}function c(a,b){function c(){if(n>=r)return g;if(A)return A=!1,e;var b=n,c;if(34===a.charCodeAt(b)){for(var k=b;k++<r;)if(34===a.charCodeAt(k)){if(34!==a.charCodeAt(k+1))break;++k}n=k+2;c=a.charCodeAt(k+1);13===c?(A=!0,10===a.charCodeAt(k+2)&&++n):10===c&&(A=!0);return a.slice(b+1,k).replace(/\"\"/g,'\"')}for(;n<r;){k=1;c=a.charCodeAt(n++);\nif(10===c)A=!0;else if(13===c)A=!0,10===a.charCodeAt(n)&&(++n,++k);else if(c!==m)continue;return a.slice(b,n-k)}return a.slice(b)}for(var e={},g={},k=[],r=a.length,n=0,u=0,w,A;(w=c())!==g;){for(var y=[];w!==e&&w!==g;)y.push(w),w=c();b&&null==(y=b(y,u++))||k.push(y)}return k}function e(b,c){null==c&&(c=Ao(b));return[c.map(n).join(a)].concat(b.map(function(b){return c.map(function(a){return n(b[a])}).join(a)})).join(\"\\n\")}function g(a){return a.map(k).join(\"\\n\")}function k(b){return b.map(n).join(a)}\nfunction n(a){return null==a?\"\":u.test(a+=\"\")?'\"'+a.replace(/\\\"/g,'\"\"')+'\"':a}var u=new RegExp('[\"'+a+\"\\n]\"),m=a.charCodeAt(0);return{parse:b,parseRows:c,format:e,formatRows:g}},Re=dh(\",\"),nl=Re.parse,jt=Re.parseRows,kt=Re.format,lt=Re.formatRows,Se=dh(\"\\t\"),ol=Se.parse,mt=Se.parseRows,nt=Se.format,ot=Se.formatRows,pt=function(a,b){function c(){var c,g=e.length,k,r=0,n=0;for(c=0;c<g;++c)k=e[c],r+=k.x,n+=k.y;r=r/g-a;n=n/g-b;for(c=0;c<g;++c)k=e[c],k.x-=r,k.y-=n}var e;null==a&&(a=0);null==b&&(b=0);c.initialize=\nfunction(a){e=a};c.x=function(b){return arguments.length?(a=+b,c):a};c.y=function(a){return arguments.length?(b=+a,c):b};return c},Ha=function(a){return function(){return a}},Ab=function(){return 1E-6*(Math.random()-.5)},qt=function(a){var b=+this.tc.call(null,a),c=+this.ce.call(null,a);return oi(this.cover(b,c),b,c,a)},rt=function(a,b){if(isNaN(a=+a)||isNaN(b=+b))return this;var c=this.ub,e=this.xb,g=this.Sa,k=this.Va;if(isNaN(c))g=(c=Math.floor(a))+1,k=(e=Math.floor(b))+1;else if(c>a||a>g||e>b||\nb>k){var n=g-c,u=this.ve,m,A;switch(A=(b<(e+k)/2)<<1|a<(c+g)/2){case 0:do m=Array(4),m[A]=u,u=m;while(n*=2,g=c+n,k=e+n,a>g||b>k);break;case 1:do m=Array(4),m[A]=u,u=m;while(n*=2,c=g-n,k=e+n,c>a||b>k);break;case 2:do m=Array(4),m[A]=u,u=m;while(n*=2,g=c+n,e=k-n,a>g||e>b);break;case 3:do m=Array(4),m[A]=u,u=m;while(n*=2,c=g-n,e=k-n,c>a||e>b)}this.ve&&this.ve.length&&(this.ve=u)}else return this;this.ub=c;this.xb=e;this.Sa=g;this.Va=k;return this},st=function(){var a=[];this.visit(function(b){if(!b.length){do a.push(b.data);\nwhile(b=b.next)}});return a},tt=function(a){return arguments.length?this.cover(+a[0][0],+a[0][1]).cover(+a[1][0],+a[1][1]):isNaN(this.ub)?void 0:[[this.ub,this.xb],[this.Sa,this.Va]]},Ia=function(a,b,c,e,g){this.node=a;this.x0=b;this.y0=c;this.x1=e;this.y1=g},ut=function(a,b,c){var e,g=this.ub,k=this.xb,r,n,u,m,y=this.Sa,q=this.Va,M=[],G=this.ve,v;G&&M.push(new Ia(G,g,k,y,q));null==c?c=Infinity:(g=a-c,k=b-c,y=a+c,q=b+c,c*=c);for(;v=M.pop();)if(!(!(G=v.node)||(r=v.x0)>y||(n=v.y0)>q||(u=v.x1)<g||(m=\nv.y1)<k))if(G.length){v=(r+u)/2;var Y=(n+m)/2;M.push(new Ia(G[3],v,Y,u,m),new Ia(G[2],r,Y,v,m),new Ia(G[1],v,n,u,Y),new Ia(G[0],r,n,v,Y));if(G=(b>=Y)<<1|a>=v)v=M[M.length-1],M[M.length-1]=M[M.length-1-G],M[M.length-1-G]=v}else v=a-+this.tc.call(null,G.data),Y=b-+this.ce.call(null,G.data),v=v*v+Y*Y,v<c&&(e=Math.sqrt(c=v),g=a-e,k=b-e,y=a+e,q=b+e,e=G.data);return e},vt=function(a){if(isNaN(A=+this.tc.call(null,a))||isNaN(q=+this.ce.call(null,a)))return this;var b,c=this.ve,e,g,k=this.ub,n=this.xb,u=\nthis.Sa,m=this.Va,A,q,ja,M,G,v,Y;if(!c)return this;if(c.length)for(;;){(G=A>=(ja=(k+u)/2))?k=ja:u=ja;(v=q>=(M=(n+m)/2))?n=M:m=M;if(!(b=c,c=c[G|=v<<1]))return this;if(!c.length)break;if(b[G+1&3]||b[G+2&3]||b[G+3&3])e=b,Y=G}for(;c.data!==a;)if(!(g=c,c=c.next))return this;(a=c.next)&&delete c.next;if(g)return a?g.next=a:delete g.next,this;if(!b)return this.ve=a,this;a?b[G]=a:delete b[G];(c=b[0]||b[1]||b[2]||b[3])&&c===(b[3]||b[2]||b[1]||b[0])&&!c.length&&(e?e[Y]=c:this.ve=c);return this},wt=function(){return this.ve},\nxt=function(){var a=0;this.visit(function(b){if(!b.length){do++a;while(b=b.next)}});return a},yt=function(a){var b=[],c,e=this.ve,g,k,n,u;for(e&&b.push(new Ia(e,this.ub,this.xb,this.Sa,this.Va));c=b.pop();)if(!a(e=c.node,k=c.x0,n=c.y0,u=c.x1,c=c.y1)&&e.length){var m=(k+u)/2,A=(n+c)/2;(g=e[3])&&b.push(new Ia(g,m,A,u,c));(g=e[2])&&b.push(new Ia(g,k,A,m,c));(g=e[1])&&b.push(new Ia(g,m,n,u,A));(g=e[0])&&b.push(new Ia(g,k,n,m,A))}return this},zt=function(a){var b=[],c=[],e;for(this.ve&&b.push(new Ia(this.ve,\nthis.ub,this.xb,this.Sa,this.Va));e=b.pop();){var g=e.node;if(g.length){var k,n=e.x0,u=e.y0,m=e.x1,A=e.y1,q=(n+m)/2,ja=(u+A)/2;(k=g[0])&&b.push(new Ia(k,n,u,q,ja));(k=g[1])&&b.push(new Ia(k,q,u,m,ja));(k=g[2])&&b.push(new Ia(k,n,ja,q,A));(k=g[3])&&b.push(new Ia(k,q,ja,m,A))}c.push(e)}for(;e=c.pop();)a(e.node,e.x0,e.y0,e.x1,e.y1);return this},At=function(a){return arguments.length?(this.tc=a,this):this.tc},Bt=function(a){return arguments.length?(this.ce=a,this):this.ce},Ja=Nd.prototype=Gf.prototype;\nJa.copy=function(){var a=new Gf(this.tc,this.ce,this.ub,this.xb,this.Sa,this.Va),b=this.ve,c,e;if(!b)return a;if(!b.length)return a.ve=pi(b),a;for(c=[{source:b,target:a.ve=Array(4)}];b=c.pop();)for(var g=0;4>g;++g)if(e=b.source[g])e.length?c.push({source:e,target:b.target[g]=Array(4)}):b.target[g]=pi(e);return a};Ja.add=qt;Ja.addAll=Bo;Ja.cover=rt;Ja.data=st;Ja.extent=tt;Ja.find=ut;Ja.remove=vt;Ja.removeAll=Co;Ja.root=wt;Ja.size=xt;Ja.visit=yt;Ja.visitAfter=zt;Ja.x=At;Ja.y=Bt;var Ct=function(a){function b(){function a(a,\nb,c,e,g){var k=a.data;a=a.r;var r=q+a;if(k)k.index>m.index&&(b=w-k.x-k.vx,c=y-k.y-k.vy,e=b*b+c*c,e<r*r&&(0===b&&(b=Ab(),e+=b*b),0===c&&(c=Ab(),e+=c*c),e=(r-(e=Math.sqrt(e)))/e*n,m.vx+=(b*=e)*(r=(a*=a)/(H+a)),m.vy+=(c*=e)*r,k.vx-=b*(r=1-r),k.vy-=c*r));else return b>w+r||e<w-r||c>y+r||g<y-r}for(var b,e=g.length,r,m,w,y,q,H,F=0;F<u;++F)for(r=Nd(g,Fo,Go).visitAfter(c),b=0;b<e;++b)m=g[b],q=k[m.index],H=q*q,w=m.x+m.vx,y=m.y+m.vy,r.visit(a)}function c(a){if(a.data)return a.r=k[a.data.index];for(var b=a.r=\n0;4>b;++b)a[b]&&a[b].r>a.r&&(a.r=a[b].r)}function e(){if(g){var b,c=g.length,e;k=Array(c);for(b=0;b<c;++b)e=g[b],k[e.index]=+a(e,b,g)}}var g,k,n=1,u=1;\"function\"!==typeof a&&(a=Ha(null==a?1:+a));b.initialize=function(a){g=a;e()};b.iterations=function(a){return arguments.length?(u=+a,b):u};b.strength=function(a){return arguments.length?(n=+a,b):n};b.radius=function(c){return arguments.length?(a=\"function\"===typeof c?c:Ha(+c),e(),b):a};return b},Dt=function(a){function b(a){return 1/Math.min(M[a.source.index],\nM[a.target.index])}function c(b){for(var c=0,e=a.length;c<B;++c)for(var g=0,k,r,n,u,w;g<e;++g)k=a[g],r=k.source,k=k.target,n=k.x+k.vx-r.x-r.vx||Ab(),u=k.y+k.vy-r.y-r.vy||Ab(),w=Math.sqrt(n*n+u*u),w=(w-q[g])/w*b*m[g],n*=w,u*=w,k.vx-=n*(w=G[g]),k.vy-=u*w,r.vx+=n*(w=1-w),r.vy+=u*w}function e(){if(v){var b,c=v.length,e=a.length,r=fb(v,n);b=0;for(M=Array(c);b<e;++b)c=a[b],c.index=b,\"object\"!==typeof c.source&&(c.source=qi(r,c.source)),\"object\"!==typeof c.target&&(c.target=qi(r,c.target)),M[c.source.index]=\n(M[c.source.index]||0)+1,M[c.target.index]=(M[c.target.index]||0)+1;b=0;for(G=Array(e);b<e;++b)c=a[b],G[b]=M[c.source.index]/(M[c.source.index]+M[c.target.index]);m=Array(e);g();q=Array(e);k()}}function g(){if(v)for(var b=0,c=a.length;b<c;++b)m[b]=+u(a[b],b,a)}function k(){if(v)for(var b=0,c=a.length;b<c;++b)q[b]=+A(a[b],b,a)}var n=Ho,u=b,m,A=Ha(30),q,v,M,G,B=1;null==a&&(a=[]);c.initialize=function(a){v=a;e()};c.links=function(b){return arguments.length?(a=b,e(),c):a};c.id=function(a){return arguments.length?\n(n=a,c):n};c.iterations=function(a){return arguments.length?(B=+a,c):B};c.strength=function(a){return arguments.length?(u=\"function\"===typeof a?a:Ha(+a),g(),c):u};c.distance=function(a){return arguments.length?(A=\"function\"===typeof a?a:Ha(+a),k(),c):A};return c},Et=Math.PI*(3-Math.sqrt(5)),Ft=function(a){function b(){c();G.call(\"tick\",k);n<u&&(M.stop(),G.call(\"end\",k))}function c(){var b,c=a.length,e;n+=(A-n)*m;v.each(function(a){a(n)});for(b=0;b<c;++b)e=a[b],null==e.fx?e.x+=e.vx*=q:(e.x=e.fx,e.vx=\n0),null==e.fy?e.y+=e.vy*=q:(e.y=e.fy,e.vy=0)}function e(){for(var b=0,c=a.length,e;b<c;++b){e=a[b];e.index=b;if(isNaN(e.x)||isNaN(e.y)){var g=10*Math.sqrt(b),k=b*Et;e.x=g*Math.cos(k);e.y=g*Math.sin(k)}if(isNaN(e.vx)||isNaN(e.vy))e.vx=e.vy=0}}function g(b){b.initialize&&b.initialize(a);return b}var k,n=1,u=.001,m=1-Math.pow(u,1/300),A=0,q=.6,v=fb(),M=Dd(b),G=E(\"tick\",\"end\");null==a&&(a=[]);e();return k={tick:c,restart:function(){return M.restart(b),k},stop:function(){return M.stop(),k},nodes:function(b){return arguments.length?\n(a=b,e(),v.each(g),k):a},alpha:function(a){return arguments.length?(n=+a,k):n},alphaMin:function(a){return arguments.length?(u=+a,k):u},alphaDecay:function(a){return arguments.length?(m=+a,k):+m},alphaTarget:function(a){return arguments.length?(A=+a,k):A},velocityDecay:function(a){return arguments.length?(q=1-a,k):1-q},force:function(a,b){return 1<arguments.length?(null==b?v.remove(a):v.set(a,g(b)),k):v.get(a)},find:function(b,c,e){var g,k=a.length,r,n,u,m;e=null==e?Infinity:e*e;for(g=0;g<k;++g)u=\na[g],r=b-u.x,n=c-u.y,r=r*r+n*n,r<e&&(m=u,e=r);return m},on:function(a,b){return 1<arguments.length?(G.on(a,b),k):G.on(a)}}},Gt=function(){function a(a){var b,r=g.length,u=Nd(g,Io,Jo).visitAfter(c);n=a;for(b=0;b<r;++b)k=g[b],u.visit(e)}function b(){if(g){var a,b=g.length,c;q=Array(b);for(a=0;a<b;++a)c=g[a],q[c.index]=+m(c,a,g)}}function c(a){var b=0,c,e,g,k,r;if(a.length){for(g=k=r=0;4>r;++r)(c=a[r])&&(e=c.value)&&(b+=e,g+=e*c.x,k+=e*c.y);a.x=g/b;a.y=k/b}else{c=a;c.x=c.data.x;c.y=c.data.y;do b+=q[c.data.index];\nwhile(c=c.next)}a.value=b}function e(a,b,c,e){if(!a.value)return!0;var g=a.x-k.x,r=a.y-k.y;b=e-b;e=g*g+r*r;if(b*b/v<e)return e<L&&(0===g&&(g=Ab(),e+=g*g),0===r&&(r=Ab(),e+=r*r),e<A&&(e=Math.sqrt(A*e)),k.vx+=g*a.value*n/e,k.vy+=r*a.value*n/e),!0;if(!(a.length||e>=L)){if(a.data!==k||a.next)0===g&&(g=Ab(),e+=g*g),0===r&&(r=Ab(),e+=r*r),e<A&&(e=Math.sqrt(A*e));do a.data!==k&&(b=q[a.data.index]*n/e,k.vx+=g*b,k.vy+=r*b);while(a=a.next)}}var g,k,n,m=Ha(-30),q,A=1,L=Infinity,v=.81;a.initialize=function(a){g=\na;b()};a.strength=function(c){return arguments.length?(m=\"function\"===typeof c?c:Ha(+c),b(),a):m};a.distanceMin=function(b){return arguments.length?(A=b*b,a):Math.sqrt(A)};a.distanceMax=function(b){return arguments.length?(L=b*b,a):Math.sqrt(L)};a.theta=function(b){return arguments.length?(v=b*b,a):Math.sqrt(v)};return a},Ht=function(a){function b(a){for(var b=0,c=g.length,e;b<c;++b)e=g[b],e.vx+=(n[b]-e.x)*k[b]*a}function c(){if(g){var b,c=g.length;k=Array(c);n=Array(c);for(b=0;b<c;++b)k[b]=isNaN(n[b]=\n+a(g[b],b,g))?0:+e(g[b],b,g)}}var e=Ha(.1),g,k,n;\"function\"!==typeof a&&(a=Ha(null==a?0:+a));b.initialize=function(a){g=a;c()};b.strength=function(a){return arguments.length?(e=\"function\"===typeof a?a:Ha(+a),c(),b):e};b.x=function(e){return arguments.length?(a=\"function\"===typeof e?e:Ha(+e),c(),b):a};return b},It=function(a){function b(a){for(var b=0,c=g.length,e;b<c;++b)e=g[b],e.vy+=(n[b]-e.y)*k[b]*a}function c(){if(g){var b,c=g.length;k=Array(c);n=Array(c);for(b=0;b<c;++b)k[b]=isNaN(n[b]=+a(g[b],\nb,g))?0:+e(g[b],b,g)}}var e=Ha(.1),g,k,n;\"function\"!==typeof a&&(a=Ha(null==a?0:+a));b.initialize=function(a){g=a;c()};b.strength=function(a){return arguments.length?(e=\"function\"===typeof a?a:Ha(+a),c(),b):e};b.y=function(e){return arguments.length?(a=\"function\"===typeof e?e:Ha(+e),c(),b):a};return b},Te=function(a,b){if(0>(b=(a=b?a.toExponential(b-1):a.toExponential()).indexOf(\"e\")))return null;var c=a.slice(0,b);return[1<c.length?c[0]+c.slice(2):c,+a.slice(b+1)]},yc=function(a){return a=Te(Math.abs(a)),\na?a[1]:NaN},Jt=function(a,b){return function(c,e){for(var g=c.length,k=[],n=0,r=a[0],m=0;0<g&&0<r;){m+r+1>e&&(r=Math.max(1,e-m));k.push(c.substring(g-=r,g+r));if((m+=r+1)>e)break;r=a[n=(n+1)%a.length]}return k.reverse().join(b)}},Kt=function(a,b){a=a.toPrecision(b);b=a.length;var c=1,e=-1,g;a:for(;c<b;++c)switch(a[c]){case \".\":e=g=c;break;case \"0\":0===e&&(e=c);g=c;break;case \"e\":break a;default:0<e&&(e=0)}return 0<e?a.slice(0,e)+a.slice(g+1):a},pl,Lt=function(a,b){var c=Te(a,b);if(!c)return a+\"\";\nvar e=c[0],c=c[1],c=c-(pl=3*Math.max(-8,Math.min(8,Math.floor(c/3))))+1,g=e.length;return c===g?e:c>g?e+Array(c-g+1).join(\"0\"):0<c?e.slice(0,c)+\".\"+e.slice(c):\"0.\"+Array(1-c).join(\"0\")+Te(a,Math.max(0,b+c-1))[0]},ql=function(a,b){b=Te(a,b);if(!b)return a+\"\";a=b[0];b=b[1];return 0>b?\"0.\"+Array(-b).join(\"0\")+a:a.length>b+1?a.slice(0,b+1)+\".\"+a.slice(b+1):a+Array(b-a.length+2).join(\"0\")},si={\"\":Kt,\"%\":function(a,b){return(100*a).toFixed(b)},b:function(a){return Math.round(a).toString(2)},c:function(a){return a+\n\"\"},d:function(a){return Math.round(a).toString(10)},e:function(a,b){return a.toExponential(b)},f:function(a,b){return a.toFixed(b)},g:function(a,b){return a.toPrecision(b)},o:function(a){return Math.round(a).toString(8)},p:function(a,b){return ql(100*a,b)},r:ql,s:Lt,X:function(a){return Math.round(a).toString(16).toUpperCase()},x:function(a){return Math.round(a).toString(16)}},Ko=/^(?:(.)?([<>=^]))?([+\\-\\( ])?([$#])?(0)?(\\d+)?(,)?(\\.\\d+)?([a-z%])?$/i,xe=function(a){return new ri(a)};ri.prototype.toString=\nfunction(){return this.fill+this.align+this.sign+this.symbol+(this.zero?\"0\":\"\")+(null==this.width?\"\":Math.max(1,this.width|0))+(this.comma?\",\":\"\")+(null==this.precision?\"\":\".\"+Math.max(0,this.precision|0))+this.type};var rl=\"y z a f p n \\u00b5 m  k M G T P E Z Y\".split(\" \"),ui=function(a){function b(a){function b(a){var b=H,g=v,m,A,G;if(\"c\"===F)g=B(a)+g,a=\"\";else{a=+a;var L=(0>a||0>1/a)&&(a*=-1,!0);a=B(a,y);if(L)for(m=-1,A=a.length,L=!1;++m<A;)if(G=a.charCodeAt(m),48<G&&58>G||\"x\"===F&&96<G&&103>G||\n\"X\"===F&&64<G&&71>G){L=!0;break}b=(L?\"(\"===r?r:\"-\":\"-\"===r||\"(\"===r?\"\":r)+b;g=g+(\"s\"===F?rl[8+pl/3]:\"\")+(L&&\"(\"===r?\")\":\"\");if(ca)for(m=-1,A=a.length;++m<A;)if(G=a.charCodeAt(m),48>G||57<G){g=(46===G?k+a.slice(m+1):a.slice(m))+g;a=a.slice(0,m);break}}q&&!u&&(a=e(a,Infinity));m=b.length+a.length+g.length;A=m<w?Array(w-m+1).join(c):\"\";q&&u&&(a=e(A+a,A.length?w-g.length:Infinity),A=\"\");switch(n){case \"\\x3c\":return b+a+g+A;case \"\\x3d\":return b+A+a+g;case \"^\":return A.slice(0,m=A.length>>1)+b+a+g+A.slice(m)}return A+\nb+a+g}a=xe(a);var c=a.fill,n=a.align,r=a.sign,m=a.symbol,u=a.zero,w=a.width,q=a.comma,y=a.precision,F=a.type,H=\"$\"===m?g[0]:\"#\"===m&&/[boxX]/.test(F)?\"0\"+F.toLowerCase():\"\",v=\"$\"===m?g[1]:/[%p]/.test(F)?\"%\":\"\",B=si[F],ca=!F||/[defgprs%]/.test(F),y=null==y?F?6:12:/[gprs]/.test(F)?Math.max(1,Math.min(21,y)):Math.max(0,Math.min(20,y));b.toString=function(){return a+\"\"};return b}function c(a,c){var e=b((a=xe(a),a.type=\"f\",a));a=3*Math.max(-8,Math.min(8,Math.floor(yc(c)/3)));var g=Math.pow(10,-a),k=rl[8+\na/3];return function(a){return e(g*a)+k}}var e=a.grouping&&a.thousands?Jt(a.grouping,a.thousands):Lo,g=a.currency,k=a.decimal;return{format:b,formatPrefix:c}},Od;ti({decimal:\".\",thousands:\",\",grouping:[3],currency:[\"$\",\"\"]});var Qj=function(a){return Math.max(0,-yc(Math.abs(a)))},Oj=function(a,b){return Math.max(0,3*Math.max(-8,Math.min(8,Math.floor(yc(b)/3)))-yc(Math.abs(a)))},Pj=function(a,b){a=Math.abs(a);b=Math.abs(b)-a;return Math.max(0,yc(b)-yc(a))+1};$a.prototype={constructor:$a,reset:function(){this.s=\nthis.t=0},add:function(a){vi(Ue,a,this.t);vi(this,Ue.s,this.s);this.s?this.t+=Ue.t:this.s=Ue.t},valueOf:function(){return this.s}};var Ue=new $a,ha=Math.PI,ra=ha/2,Qd=ha/4,La=2*ha,pa=180/ha,Z=ha/180,ia=Math.abs,lc=Math.atan,Ba=Math.atan2,S=Math.cos,fe=Math.ceil,sl=Math.exp,ne=Math.log,hg=Math.pow,N=Math.sin,Zc=Math.sign||function(a){return 0<a?1:0>a?-1:0},wa=Math.sqrt,nc=Math.tan,tl={Feature:function(a,b){Pd(a.geometry,b)},FeatureCollection:function(a,b){a=a.features;for(var c=-1,e=a.length;++c<e;)Pd(a[c].geometry,\nb)}},yi={YZ:function(a,b){b.sphere()},Point:function(a,b){a=a.coordinates;b.point(a[0],a[1],a[2])},MultiPoint:function(a,b){for(var c=a.coordinates,e=-1,g=c.length;++e<g;)a=c[e],b.point(a[0],a[1],a[2])},LineString:function(a,b){Hf(a.coordinates,b,0)},MultiLineString:function(a,b){a=a.coordinates;for(var c=-1,e=a.length;++c<e;)Hf(a[c],b,0)},Polygon:function(a,b){zi(a.coordinates,b)},MultiPolygon:function(a,b){a=a.coordinates;for(var c=-1,e=a.length;++c<e;)zi(a[c],b)},GeometryCollection:function(a,\nb){a=a.geometries;for(var c=-1,e=a.length;++c<e;)Pd(a[c],b)}},cb=function(a,b){if(a&&tl.hasOwnProperty(a.type))tl[a.type](a,b);else Pd(a,b)},Rd=new $a,Ve=new $a,Bi,Ci,If,Jf,Kf,gb={point:sa,lineStart:sa,lineEnd:sa,polygonStart:function(){Rd.reset();gb.lineStart=Mo;gb.lineEnd=Oo},polygonEnd:function(){var a=+Rd;Ve.add(0>a?La+a:a);this.lineStart=this.lineEnd=this.point=sa},sphere:function(){Ve.add(La)}},Mt=function(a){Ve.reset();cb(a,gb);return 2*Ve},ua,Pa,va,Ta,Ob,Hi,Ii,hc,Qc=new $a,wb,nb,ob={point:Mf,\nlineStart:Ei,lineEnd:Fi,polygonStart:function(){ob.point=Gi;ob.lineStart=Po;ob.lineEnd=Qo;Qc.reset();gb.polygonStart()},polygonEnd:function(){gb.polygonEnd();ob.point=Mf;ob.lineStart=Ei;ob.lineEnd=Fi;0>Rd?(ua=-(va=180),Pa=-(Ta=90)):1E-6<Qc?Ta=90:-1E-6>Qc&&(Pa=-90);nb[0]=ua;nb[1]=va}},Nt=function(a){var b,c,e,g,k,n;Ta=va=-(ua=Pa=Infinity);wb=[];cb(a,ob);if(b=wb.length){wb.sort(Ro);a=1;c=wb[0];for(g=[c];a<b;++a)e=wb[a],Ji(c,e[0])||Ji(c,e[1])?(Qa(c[0],e[1])>Qa(c[0],c[1])&&(c[1]=e[1]),Qa(e[0],c[1])>Qa(c[0],\nc[1])&&(c[0]=e[0])):g.push(c=e);k=-Infinity;b=g.length-1;a=0;for(c=g[b];a<=b;c=e,++a)e=g[a],(n=Qa(c[1],e[0]))>k&&(k=n,ua=e[0],va=c[1])}wb=nb=null;return Infinity===ua||Infinity===Pa?[[NaN,NaN],[NaN,NaN]]:[[ua,Pa],[va,Ta]]},Sc,Zd,Wd,Xd,Yd,$d,ae,be,Of,Pf,Qf,Ni,Oi,Ca,Da,Ea,ab={sphere:sa,point:Nf,lineStart:Ki,lineEnd:Li,polygonStart:function(){ab.lineStart=Uo;ab.lineEnd=Wo},polygonEnd:function(){ab.lineStart=Ki;ab.lineEnd=Li}},Ot=function(a){Sc=Zd=Wd=Xd=Yd=$d=ae=be=Of=Pf=Qf=0;cb(a,ab);a=Of;var b=Pf,c=\nQf,e=a*a+b*b+c*c;return 1E-12>e&&(a=$d,b=ae,c=be,1E-6>Zd&&(a=Wd,b=Xd,c=Yd),e=a*a+b*b+c*c,1E-12>e)?[NaN,NaN]:[Ba(b,a)*pa,Oa(c/wa(e))*pa]},zc=function(a){return function(){return a}},Pi=function(a,b){function c(c,e){return c=a(c,e),b(c[0],c[1])}a.invert&&b.invert&&(c.invert=function(c,e){return c=b.invert(c,e),c&&a.invert(c[0],c[1])});return c};Rf.invert=Rf;var Pt=function(a){function b(b){b=a(b[0]*Z,b[1]*Z);return b[0]*=pa,b[1]*=pa,b}a=Sf(a[0]*Z,a[1]*Z,2<a.length?a[2]*Z:0);b.invert=function(b){b=a.invert(b[0]*\nZ,b[1]*Z);return b[0]*=pa,b[1]*=pa,b};return b},Qt=function(){function a(a,b){k.push(a=n(a,b));a[0]*=pa;a[1]*=pa}function b(){var a=c.apply(this,arguments),b=e.apply(this,arguments)*Z,r=g.apply(this,arguments)*Z;k=[];n=Sf(-a[0]*Z,-a[1]*Z,0).invert;Ti(m,b,r,1);a={type:\"Polygon\",coordinates:[k]};k=n=null;return a}var c=zc([0,0]),e=zc(90),g=zc(6),k,n,m={point:a};b.center=function(a){return arguments.length?(c=\"function\"===typeof a?a:zc([+a[0],+a[1]]),b):c};b.radius=function(a){return arguments.length?\n(e=\"function\"===typeof a?a:zc(+a),b):e};b.precision=function(a){return arguments.length?(g=\"function\"===typeof a?a:zc(+a),b):g};return b},Xi=function(){var a=[],b;return{point:function(a,c){b.push([a,c])},lineStart:function(){a.push(b=[])},lineEnd:sa,qP:function(){1<a.length&&a.push(a.pop().concat(a.shift()))},result:function(){var c=a;a=[];b=null;return c}}},Xo=function(a,b,c,e,g,k){var n=a[0],r=a[1],m=b[0],w=b[1],u=0,q=1,m=m-n,w=w-r;c-=n;if(m||!(0<c)){c/=m;if(0>m){if(c<u)return;c<q&&(q=c)}else if(0<\nm){if(c>q)return;c>u&&(u=c)}c=g-n;if(m||!(0>c)){c/=m;if(0>m){if(c>q)return;c>u&&(u=c)}else if(0<m){if(c<u)return;c<q&&(q=c)}c=e-r;if(w||!(0<c)){c/=w;if(0>w){if(c<u)return;c<q&&(q=c)}else if(0<w){if(c>q)return;c>u&&(u=c)}c=k-r;if(w||!(0>c)){c/=w;if(0>w){if(c>q)return;c>u&&(u=c)}else if(0<w){if(c<u)return;c<q&&(q=c)}0<u&&(a[0]=n+u*m,a[1]=r+u*w);1>q&&(b[0]=n+q*m,b[1]=r+q*w);return!0}}}}},We=function(a,b){return 1E-6>ia(a[0]-b[0])&&1E-6>ia(a[1]-b[1])},Wi=function(a,b,c,e,g){var k=[],n=[],r;a.forEach(function(a){if(!(0>=\n(b=a.length-1))){var b,c=a[0],e=a[b];if(We(c,e)){g.lineStart();for(r=0;r<b;++r)g.point((c=a[r])[0],c[1]);g.lineEnd()}else k.push(b=new ce(c,a,null,!0)),n.push(b.Mo=new ce(c,null,b,!1)),k.push(b=new ce(e,a,null,!1)),n.push(b.Mo=new ce(e,null,b,!0))}});if(k.length){n.sort(b);Vi(k);Vi(n);r=0;for(a=n.length;r<a;++r)n[r].e=c=!c;c=k[0];for(var m;;){for(var w=c,u=!0;w.Ak;)if((w=w.n)===c)return;b=w.z;g.lineStart();do{w.Ak=w.Mo.Ak=!0;if(w.e){if(u)for(r=0,a=b.length;r<a;++r)g.point((m=b[r])[0],m[1]);else e(w.x,\nw.n.x,1,g);w=w.n}else{if(u)for(b=w.p.z,r=b.length-1;0<=r;--r)g.point((m=b[r])[0],m[1]);else e(w.x,w.p.x,-1,g);w=w.p}w=w.Mo;b=w.z;u=!u}while(!w.Ak);g.lineEnd()}}},Rt=function(){var a=0,b=0,c=960,e=500,g,k,n;return n={stream:function(n){return g&&k===n?g:g=Tf(a,b,c,e)(k=n)},extent:function(r){return arguments.length?(a=+r[0][0],b=+r[0][1],c=+r[1][0],e=+r[1][1],g=k=null,n):[[a,b],[c,e]]}}},Wf=new $a,Vf,de,ee,ic={sphere:sa,point:sa,lineStart:Yo,lineEnd:sa,polygonStart:sa,polygonEnd:sa},ul=function(a){Wf.reset();\ncb(a,ic);return+Wf},eh=[null,null],St={type:\"LineString\",coordinates:eh},Tt=function(a,b){eh[0]=a;eh[1]=b;return ul(St)},Ut=function(a,b){var c=a[0]*Z,e=a[1]*Z;a=b[0]*Z;b=b[1]*Z;var g=S(e),k=N(e),n=S(b),m=N(b),u=g*S(c),A=g*N(c),q=n*S(a),v=n*N(a),y=2*Oa(wa(xi(b-e)+g*n*xi(a-c))),G=N(y);a=y?function(a){var b=N(a*=y)/G,c=N(y-a)/G;a=c*u+b*q;var e=c*A+b*v,b=c*k+b*m;return[Ba(e,a)*pa,Ba(b,wa(a*a+e*e))*pa]}:function(){return[c*pa,e*pa]};a.distance=y;return a},Qb=function(a){return a},fh=new $a,Zf=new $a,\nbj,cj,Xf,Yf,pb={point:sa,lineStart:sa,lineEnd:sa,polygonStart:function(){pb.lineStart=cp;pb.lineEnd=ep},polygonEnd:function(){pb.lineStart=pb.lineEnd=pb.point=sa;fh.add(ia(Zf));Zf.reset()},result:function(){var a=fh/2;fh.reset();return a}},jc=Infinity,ge=jc,Tc=-jc,he=Tc,le={point:fp,lineStart:sa,lineEnd:sa,polygonStart:sa,polygonEnd:sa,result:function(){var a=[[jc,ge],[Tc,he]];Tc=he=-(ge=jc=Infinity);return a}},$f=0,ag=0,Uc=0,ie=0,je=0,kc=0,bg=0,cg=0,Vc=0,gj,hj,hb,ib,Ua={point:Pb,lineStart:dj,lineEnd:ej,\npolygonStart:function(){Ua.lineStart=ip;Ua.lineEnd=kp},polygonEnd:function(){Ua.point=Pb;Ua.lineStart=dj;Ua.lineEnd=ej},result:function(){var a=Vc?[bg/Vc,cg/Vc]:kc?[ie/kc,je/kc]:Uc?[$f/Uc,ag/Uc]:[NaN,NaN];$f=ag=Uc=ie=je=kc=bg=cg=Vc=0;return a}};ij.prototype={xq:4.5,pointRadius:function(a){return this.xq=a,this},polygonStart:function(){this.Ta=0},polygonEnd:function(){this.Ta=NaN},lineStart:function(){this.Ha=0},lineEnd:function(){0===this.Ta&&this.Ia.closePath();this.Ha=NaN},point:function(a,b){switch(this.Ha){case 0:this.Ia.moveTo(a,\nb);this.Ha=1;break;case 1:this.Ia.lineTo(a,b);break;default:this.Ia.moveTo(a+this.xq,b),this.Ia.arc(a,b,this.xq,0,La)}},result:sa};var dg=new $a,gh,kj,lj,Xc,Yc,Wc={point:sa,lineStart:function(){Wc.point=lp},lineEnd:function(){gh&&jj(kj,lj);Wc.point=sa},polygonStart:function(){gh=!0},polygonEnd:function(){gh=null},result:function(){var a=+dg;dg.reset();return a}};mj.prototype={wv:nj(4.5),pointRadius:function(a){return this.wv=nj(a),this},polygonStart:function(){this.Ta=0},polygonEnd:function(){this.Ta=\nNaN},lineStart:function(){this.Ha=0},lineEnd:function(){0===this.Ta&&this.Yi.push(\"Z\");this.Ha=NaN},point:function(a,b){switch(this.Ha){case 0:this.Yi.push(\"M\",a,\",\",b);this.Ha=1;break;case 1:this.Yi.push(\"L\",a,\",\",b);break;default:this.Yi.push(\"M\",a,\",\",b,this.wv)}},result:function(){if(this.Yi.length){var a=this.Yi.join(\"\");this.Yi=[];return a}}};var Vt=function(a,b){function c(a){a&&(\"function\"===typeof e&&k.pointRadius(+e.apply(this,arguments)),cb(a,g(k)));return k.result()}var e=4.5,g,k;c.area=\nfunction(a){cb(a,g(pb));return pb.result()};c.measure=function(a){cb(a,g(Wc));return Wc.result()};c.bounds=function(a){cb(a,g(le));return le.result()};c.centroid=function(a){cb(a,g(Ua));return Ua.result()};c.projection=function(b){return arguments.length?(g=null==b?(a=null,Qb):(a=b).stream,c):a};c.context=function(a){if(!arguments.length)return b;k=null==a?(b=null,new mj):new ij(b=a);\"function\"!==typeof e&&k.pointRadius(e);return c};c.pointRadius=function(a){if(!arguments.length)return e;e=\"function\"===\ntypeof a?a:(k.pointRadius(+a),+a);return c};return c.projection(a).context(b)},hh=new $a,vl=function(a,b,c,e){return function(g,k){function n(b,c){var e=g(b,c);a(b=e[0],c=e[1])&&k.point(b,c)}function r(a,b){a=g(a,b);G.point(a[0],a[1])}function m(){W.point=r;G.lineStart()}function w(){W.point=n;G.lineEnd()}function u(a,b){C.push([a,b]);a=g(a,b);H.point(a[0],a[1])}function q(){H.lineStart();C=[]}function v(){u(C[0][0],C[0][1]);H.lineEnd();var a=H.$w(),b=F.result(),c=b.length,e;C.pop();E.push(C);C=null;\nif(c)if(a&1){if(c=b[0],0<(b=c.length-1)){B||(k.polygonStart(),B=!0);k.lineStart();for(a=0;a<b;++a)k.point((e=c[a])[0],e[1]);k.lineEnd()}}else 1<c&&a&2&&b.push(b.pop().concat(b.shift())),J.push(b.filter(mp))}var G=b(k),y=g.invert(e[0],e[1]),F=Xi(),H=b(F),B=!1,E,J,C,W={point:n,lineStart:m,lineEnd:w,polygonStart:function(){W.point=u;W.lineStart=q;W.lineEnd=v;J=[];E=[]},polygonEnd:function(){W.point=n;W.lineStart=m;W.lineEnd=w;J=Uf(J);var a;a=E;var b=y[0],e=y[1],g=[N(b),-S(b),0],r=0,u=0;hh.reset();for(var A=\n0,q=a.length;A<q;++A)if(v=(G=a[A]).length)for(var G,v,L=G[v-1],F=L[0],M=L[1]/2+Qd,H=N(M),ja=S(M),M=0;M<v;++M,F=C,H=ca,ja=Y,L=T){var T=G[M],C=T[0],Y=T[1]/2+Qd,ca=N(Y),Y=S(Y),O=C-F,K=0<=O?1:-1,Xa=K*O,Aa=Xa>ha,H=H*ca;hh.add(Ba(H*K*N(Xa),ja*Y+H*S(Xa)));r+=Aa?O+K*La:O;Aa^F>=b^C>=b&&(L=gc(Nb(L),Nb(T)),Vd(L),F=gc(g,L),Vd(F),F=(Aa^0<=O?-1:1)*Oa(F[2]),e>F||e===F&&(L[0]||L[1]))&&(u+=Aa^0<=O?1:-1)}a=(-1E-6>r||1E-6>r&&-1E-6>hh)^u&1;J.length?(B||(k.polygonStart(),B=!0),Wi(J,np,a,c,k)):a&&(B||(k.polygonStart(),\nB=!0),k.lineStart(),c(null,null,1,k),k.lineEnd());B&&(k.polygonEnd(),B=!1);J=E=null},sphere:function(){k.polygonStart();k.lineStart();c(null,null,1,k);k.lineEnd();k.polygonEnd()}};return W}},qj=vl(function(){return!0},op,pp,[-ha,-ra]),sp=function(a,b){function c(c,e,g,k){Ti(k,a,b,g,c,e)}function e(a,b){return S(a)*S(b)>m}function g(a){var b,c,g,r,m;return{lineStart:function(){r=g=!1;m=1},point:function(w,q){var G=[w,q],v=e(w,q);q=u?v?0:n(w,q):v?n(w+(0>w?ha:-ha),q):0;!b&&(r=g=v)&&a.lineStart();v!==\ng&&(w=k(b,G),We(b,w)||We(G,w))&&(G[0]+=1E-6,G[1]+=1E-6,v=e(G[0],G[1]));if(v!==g)m=0,v?(a.lineStart(),w=k(G,b),a.point(w[0],w[1])):(w=k(b,G),a.point(w[0],w[1]),a.lineEnd()),b=w;else if(A&&b&&u^v){var y;q&c||!(y=k(G,b,!0))||(m=0,u?(a.lineStart(),a.point(y[0][0],y[0][1]),a.point(y[1][0],y[1][1]),a.lineEnd()):(a.point(y[1][0],y[1][1]),a.lineEnd(),a.lineStart(),a.point(y[0][0],y[0][1])))}!v||b&&We(b,G)||a.point(G[0],G[1]);b=G;g=v;c=q},lineEnd:function(){g&&a.lineEnd();b=null},$w:function(){return m|(r&&\ng)<<1}}}function k(a,b,c){var e=Nb(a),g=Nb(b),k=[1,0,0],e=gc(e,g),g=Td(e,e),n=e[0],r=g-n*n;if(!r)return!c&&a;g=m*g/r;r=-m*n/r;n=gc(k,e);k=Ud(k,g);e=Ud(e,r);Lf(k,e);e=n;g=Td(k,e);n=Td(e,e);r=g*g-n*(Td(k,k)-1);if(!(0>r)){var w=wa(r),r=Ud(e,(-g-w)/n);Lf(r,k);r=Sd(r);if(!c)return r;c=a[0];var A=b[0];a=a[1];b=b[1];var u;A<c&&(u=c,c=A,A=u);var q=A-c,v=1E-6>ia(q-ha),y=v||1E-6>q;!v&&b<a&&(u=a,a=b,b=u);if(y?v?0<a+b^r[1]<(1E-6>ia(r[0]-c)?a:b):a<=r[1]&&r[1]<=b:q>ha^(c<=r[0]&&r[0]<=A))return b=Ud(e,(-g+w)/n),\nLf(b,k),[r,Sd(b)]}}function n(b,c){var e=u?a:ha-a,g=0;b<-e?g|=1:b>e&&(g|=2);c<-e?g|=4:c>e&&(g|=8);return g}var m=S(a),u=0<m,A=1E-6<ia(m);return vl(e,g,c,u?[0,-a]:[-ha,a-ha])},Wt=function(a){return{stream:ke(a)}};eg.prototype={constructor:eg,point:function(a,b){this.stream.point(a,b)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}};\nvar qp=S(30*Z),rp=ke({point:function(a,b){this.stream.point(a*Z,b*Z)}}),Xe=function(){return gg(rj).scale(155.424).center([0,33.6442])},wl=function(){return Xe().parallels([29.5,45.5]).scale(1070).translate([480,250]).rotate([96,0]).center([-.6,38.7])},Xt=function(){function a(a){var b=a[0];a=a[1];return v=null,(k.point(b,a),v)||(m.point(b,a),v)||(A.point(b,a),v)}function b(){c=e=null;return a}var c,e,g=wl(),k,n=Xe().rotate([154,0]).center([-2,58.5]).parallels([55,65]),m,q=Xe().rotate([157,0]).center([-3,\n19.9]).parallels([8,18]),A,v,B={point:function(a,b){v=[a,b]}};a.invert=function(a){var b=g.scale(),c=g.translate(),e=(a[0]-c[0])/b,b=(a[1]-c[1])/b;return(.12<=b&&.234>b&&-.425<=e&&-.214>e?n:.166<=b&&.234>b&&-.214<=e&&-.115>e?q:g).invert(a)};a.stream=function(a){return c&&e===a?c:c=up([g.stream(e=a),n.stream(a),q.stream(a)])};a.precision=function(a){if(!arguments.length)return g.precision();g.precision(a);n.precision(a);q.precision(a);return b()};a.scale=function(b){if(!arguments.length)return g.scale();\ng.scale(b);n.scale(.35*b);q.scale(b);return a.translate(g.translate())};a.translate=function(a){if(!arguments.length)return g.translate();var c=g.scale(),e=+a[0],r=+a[1];k=g.translate(a).clipExtent([[e-.455*c,r-.238*c],[e+.455*c,r+.238*c]]).stream(B);m=n.translate([e-.307*c,r+.201*c]).clipExtent([[e-.425*c+1E-6,r+.12*c+1E-6],[e-.214*c-1E-6,r+.234*c-1E-6]]).stream(B);A=q.translate([e-.205*c,r+.212*c]).clipExtent([[e-.214*c+1E-6,r+.166*c+1E-6],[e-.115*c-1E-6,r+.234*c-1E-6]]).stream(B);return b()};a.fitExtent=\nfunction(b,c){return mc(a,b,c)};a.fitSize=function(b,c){return mc(a,[[0,0],b],c)};return a.scale(1070)},ih=sj(function(a){return wa(2/(1+a))});ih.invert=$c(function(a){return 2*Oa(a/2)});var Yt=function(){return xb(ih).scale(124.75).clipAngle(179.999)},jh=sj(function(a){return(a=wi(a))&&a/N(a)});jh.invert=$c(function(a){return a});var Zt=function(){return xb(jh).scale(79.4188).clipAngle(179.999)};me.invert=function(a,b){return[a,2*lc(sl(b))-ra]};var $t=function(){return tj(me).scale(961/La)},au=function(){return gg(uj).scale(109.5).parallels([30,\n30])};ad.invert=ad;var bu=function(){return xb(ad).scale(152.63)},cu=function(){return gg(vj).scale(131.154).center([0,13.9389])};ig.invert=$c(lc);var du=function(){return xb(ig).scale(144.049).clipAngle(60)},eu=function(){function a(){M=G=null;return E}var b=1,c=0,e=0,g=1,k=1,n=Qb,m=null,q,A,v,B=Qb,M,G,E;return E={stream:function(a){return M&&G===a?M:M=n(B(G=a))},clipExtent:function(b){return arguments.length?(B=null==b?(m=q=A=v=null,Qb):Tf(m=+b[0][0],q=+b[0][1],A=+b[1][0],v=+b[1][1]),a()):null==\nm?null:[[m,q],[A,v]]},scale:function(r){return arguments.length?(n=oe((b=+r)*g,b*k,c,e),a()):b},translate:function(r){return arguments.length?(n=oe(b*g,b*k,c=+r[0],e=+r[1]),a()):[c,e]},reflectX:function(r){return arguments.length?(n=oe(b*(g=r?-1:1),b*k,c,e),a()):0>g},reflectY:function(r){return arguments.length?(n=oe(b*g,b*(k=r?-1:1),c,e),a()):0>k},fitExtent:function(a,b){return mc(E,a,b)},fitSize:function(a,b){return mc(E,[[0,0],a],b)}}};jg.invert=$c(Oa);var fu=function(){return xb(jg).scale(249.5).clipAngle(90.000001)};\nkg.invert=$c(function(a){return 2*lc(a)});var gu=function(){return xb(kg).scale(250).clipAngle(142)};lg.invert=function(a,b){return[-b,2*lc(sl(a))-ra]};var hu=function(){var a=tj(lg),b=a.center,c=a.rotate;a.center=function(a){return arguments.length?b([-a[1],a[0]]):(a=b(),[a[1],-a[0]])};a.rotate=function(a){return arguments.length?c([a[0],a[1],2<a.length?a[2]+90:90]):(a=c(),[a[0],a[1],a[2]-90])};return c([0,0,90]).scale(159.155)},iu=function(){function a(a){var k,n=0;a.eachAfter(function(a){var c=\na.children;if(c){var e;e=c;e=e.reduce(wp,0)/e.length;a.x=e;a.y=1+c.reduce(xp,0)}else a.x=k?n+=b(a,k):0,a.y=0,k=a});var r=yp(a),m=zp(a),w=r.x-b(r,m)/2,q=m.x+b(m,r)/2;return a.eachAfter(g?function(b){b.x=(b.x-a.x)*c;b.y=(a.y-b.y)*e}:function(b){b.x=(b.x-w)/(q-w)*c;b.y=(1-(a.y?b.y/a.y:1))*e})}var b=vp,c=1,e=1,g=!1;a.separation=function(c){return arguments.length?(b=c,a):b};a.size=function(b){return arguments.length?(g=!1,c=+b[0],e=+b[1],a):g?null:[c,e]};a.nodeSize=function(b){return arguments.length?\n(g=!0,c=+b[0],e=+b[1],a):g?[c,e]:null};return a},ju=function(){return this.eachAfter(Ap)},ku=function(a){var b=this,c,e=[b],g,k;do for(c=e.reverse(),e=[];b=c.pop();)if(a(b),b=b.children)for(g=0,k=b.length;g<k;++g)e.push(b[g]);while(e.length);return this},lu=function(a){for(var b=this,c=[b],e;b=c.pop();)if(a(b),b=b.children)for(e=b.length-1;0<=e;--e)c.push(b[e]);return this},mu=function(a){for(var b=this,c=[b],e=[],g,k;b=c.pop();)if(e.push(b),b=b.children)for(g=0,k=b.length;g<k;++g)c.push(b[g]);for(;b=\ne.pop();)a(b);return this},nu=function(a){return this.eachAfter(function(b){for(var c=+a(b.data)||0,e=b.children,g=e&&e.length;0<=--g;)c+=e[g].value;b.value=c})},ou=function(a){return this.eachBefore(function(b){b.children&&b.children.sort(a)})},pu=function(a){var b=this,c;c=b;var e=a;if(c!==e){var g=c.ancestors(),k=e.ancestors(),n=null;c=g.pop();for(e=k.pop();c===e;)n=c,c=g.pop(),e=k.pop();c=n}for(e=[b];b!==c;)b=b.parent,e.push(b);for(b=e.length;a!==c;)e.splice(b,0,a),a=a.parent;return e},qu=function(){for(var a=\nthis,b=[a];a=a.parent;)b.push(a);return b},ru=function(){var a=[];this.each(function(b){a.push(b)});return a},su=function(){var a=[];this.eachBefore(function(b){b.children||a.push(b)});return a},tu=function(){var a=this,b=[];a.each(function(c){c!==a&&b.push({source:c.parent,target:c})});return b};oc.prototype=mg.prototype={constructor:oc,count:ju,each:ku,eachAfter:mu,eachBefore:lu,sum:nu,sort:ou,path:pu,ancestors:qu,descendants:ru,leaves:su,links:tu,copy:Cp};var Dj=function(a){for(var b,c=(a=a.slice()).length,\ne=null,g=e;c;){var k=new Ep(a[c-1]),g=g?g.next=k:e=k;a[b]=a[--c]}b={head:e,Dm:g};return xj(b,[])},uu=function(a){Cj(a);return a},Ac=function(a){return function(){return a}},vu=function(){function a(a){a.x=c/2;a.y=e/2;b?a.eachBefore(Ej(b)).eachAfter(ng(g,.5)).eachBefore(Fj(1)):a.eachBefore(Ej(Fp)).eachAfter(ng(Rb,1)).eachAfter(ng(g,a.r/Math.min(c,e))).eachBefore(Fj(Math.min(c,e)/(2*a.r)));return a}var b=null,c=1,e=1,g=Rb;a.radius=function(c){return arguments.length?(b=null==c?null:qe(c),a):b};a.size=\nfunction(b){return arguments.length?(c=+b[0],e=+b[1],a):[c,e]};a.padding=function(b){return arguments.length?(g=\"function\"===typeof b?b:Ac(+b),a):g};return a},xl=function(a){a.x0=Math.round(a.x0);a.y0=Math.round(a.y0);a.x1=Math.round(a.x1);a.y1=Math.round(a.y1)},bd=function(a,b,c,e,g){var k=a.children,n=-1,r=k.length;for(e=a.value&&(e-b)/a.value;++n<r;)a=k[n],a.y0=c,a.y1=g,a.x0=b,a.x1=b+=a.value*e},wu=function(){function a(a){var n=a.height+1;a.x0=a.y0=g;a.x1=c;a.y1=e/n;a.eachBefore(b(e,n));k&&a.eachBefore(xl);\nreturn a}function b(a,b){return function(c){c.children&&bd(c,c.x0,a*(c.depth+1)/b,c.x1,a*(c.depth+2)/b);var e=c.x0,k=c.y0,n=c.x1-g,r=c.y1-g;n<e&&(e=n=(e+n)/2);r<k&&(k=r=(k+r)/2);c.x0=e;c.y0=k;c.x1=n;c.y1=r}}var c=1,e=1,g=0,k=!1;a.round=function(b){return arguments.length?(k=!!b,a):k};a.size=function(b){return arguments.length?(c=+b[0],e=+b[1],a):[c,e]};a.padding=function(b){return arguments.length?(g=+b,a):g};return a},xu={depth:-1},yl={},yu=function(){function a(a){var e,g,k=a.length,n,r,m=Array(k),\nw,q={};for(g=0;g<k;++g)e=a[g],r=m[g]=new oc(e),null!=(w=b(e,g,a))&&(w+=\"\")&&(e=\"$\"+(r.id=w),q[e]=e in q?yl:r);for(g=0;g<k;++g)if(r=m[g],w=c(a[g],g,a),null!=w&&(w+=\"\")){e=q[\"$\"+w];if(!e)throw Error(\"missing: \"+w);if(e===yl)throw Error(\"ambiguous: \"+w);e.children?e.children.push(r):e.children=[r];r.parent=e}else{if(n)throw Error(\"multiple roots\");n=r}if(!n)throw Error(\"no root\");n.parent=xu;n.eachBefore(function(a){a.depth=a.parent.depth+1;--k}).eachBefore(wj);n.parent=null;if(0<k)throw Error(\"cycle\");\nreturn n}var b=Gp,c=Hp;a.id=function(c){return arguments.length?(b=qe(c),a):b};a.parentId=function(b){return arguments.length?(c=qe(b),a):c};return a};re.prototype=Object.create(oc.prototype);var zu=function(){function a(a){var r=Jp(a);r.eachAfter(b);r.parent.ic=-r.z;r.eachBefore(c);if(m)a.eachBefore(e);else{var w=a,q=a,u=a;a.eachBefore(function(a){a.x<w.x&&(w=a);a.x>q.x&&(q=a);a.depth>u.depth&&(u=a)});var r=w===q?1:g(w,q)/2,v=r-w.x,B=k/(q.x+r+v),E=n/(u.depth||1);a.eachBefore(function(a){a.x=(a.x+\nv)*B;a.y=a.depth*E})}return a}function b(a){var b=a.children,c=a.parent.children,e=a.uf?c[a.uf-1]:null;if(b){for(var k=0,n=0,r=a.children,m=r.length,w;0<=--m;)w=r[m],w.z+=k,w.ic+=k,k+=w.s+(n+=w.c);b=(b[0].z+b[b.length-1].z)/2;e?(a.z=e.z+g(a.Fa,e.Fa),a.ic=a.z-b):a.z=b}else e&&(a.z=e.z+g(a.Fa,e.Fa));b=a.parent;k=a;a=a.parent.gp||c[0];if(e){n=c=k;r=c.parent.children[0];m=c.ic;w=n.ic;for(var q=e.ic,u=r.ic,v;e=pg(e),c=og(c),e&&c;){r=og(r);n=pg(n);n.a=k;v=e.z+q-c.z-m+g(e.Fa,c.Fa);if(0<v){var B=e.a.parent===\nk.parent?e.a:a,E=k,F=v,y=F/(E.uf-B.uf);E.c-=y;E.s+=F;B.c+=y;E.z+=F;E.ic+=F;m+=v;w+=v}q+=e.ic;m+=c.ic;u+=r.ic;w+=n.ic}e&&!pg(n)&&(n.t=e,n.ic+=q-w);c&&!og(r)&&(r.t=c,r.ic+=m-u,a=k)}k=a;b.gp=k}function c(a){a.Fa.x=a.z+a.parent.ic;a.ic+=a.parent.ic}function e(a){a.x*=k;a.y=a.depth*n}var g=Ip,k=1,n=1,m=null;a.separation=function(b){return arguments.length?(g=b,a):g};a.size=function(b){return arguments.length?(m=!1,k=+b[0],n=+b[1],a):m?null:[k,n]};a.nodeSize=function(b){return arguments.length?(m=!0,k=\n+b[0],n=+b[1],a):m?[k,n]:null};return a},se=function(a,b,c,e,g){var k=a.children,n=-1,r=k.length;for(g=a.value&&(g-c)/a.value;++n<r;)a=k[n],a.x0=b,a.x1=e,a.y0=c,a.y1=c+=a.value*g},zl=(1+Math.sqrt(5))/2,Al=function y(a){function b(b,c,e,g,k){Gj(a,b,c,e,g,k)}b.ratio=function(a){return y(1<(a=+a)?a:1)};return b}(zl),Au=function(){function a(a){a.x0=a.y0=0;a.x1=g;a.y1=k;a.eachBefore(b);n=[0];e&&a.eachBefore(xl);return a}function b(a){var b=n[a.depth],e=a.x0+b,g=a.y0+b,k=a.x1-b,r=a.y1-b;k<e&&(e=k=(e+k)/\n2);r<g&&(g=r=(g+r)/2);a.x0=e;a.y0=g;a.x1=k;a.y1=r;a.children&&(b=n[a.depth+1]=m(a)/2,e+=E(a)-b,g+=q(a)-b,k-=v(a)-b,r-=B(a)-b,k<e&&(e=k=(e+k)/2),r<g&&(g=r=(g+r)/2),c(a,e,g,k,r))}var c=Al,e=!1,g=1,k=1,n=[0],m=Rb,q=Rb,v=Rb,B=Rb,E=Rb;a.round=function(b){return arguments.length?(e=!!b,a):e};a.size=function(b){return arguments.length?(g=+b[0],k=+b[1],a):[g,k]};a.tile=function(b){return arguments.length?(c=qe(b),a):c};a.padding=function(b){return arguments.length?a.paddingInner(b).paddingOuter(b):a.paddingInner()};\na.paddingInner=function(b){return arguments.length?(m=\"function\"===typeof b?b:Ac(+b),a):m};a.paddingOuter=function(b){return arguments.length?a.paddingTop(b).paddingRight(b).paddingBottom(b).paddingLeft(b):a.paddingTop()};a.paddingTop=function(b){return arguments.length?(q=\"function\"===typeof b?b:Ac(+b),a):q};a.paddingRight=function(b){return arguments.length?(v=\"function\"===typeof b?b:Ac(+b),a):v};a.paddingBottom=function(b){return arguments.length?(B=\"function\"===typeof b?b:Ac(+b),a):B};a.paddingLeft=\nfunction(b){return arguments.length?(E=\"function\"===typeof b?b:Ac(+b),a):E};return a},Bu=function(a,b,c,e,g){function k(a,b,c,e,g,r,m){if(a>=b-1)a=n[a],a.x0=e,a.y0=g,a.x1=r,a.y1=m;else{for(var q=w[a],A=c/2+q,v=a+1,B=b-1;v<B;){var E=v+B>>>1;w[E]<A?v=E+1:B=E}q=w[v]-q;A=c-q;m-g>r-e?(c=(g*A+m*q)/c,k(a,v,q,e,g,r,c),k(v,b,A,e,c,r,m)):(c=(e*A+r*q)/c,k(a,v,q,e,g,c,m),k(v,b,A,c,g,r,m))}}var n=a.children,r,m=n.length,q,w=Array(m+1);for(w[0]=q=r=0;r<m;++r)w[r+1]=q+=n[r].value;k(0,m,a.value,b,c,e,g)},Cu=function(a,\nb,c,e,g){(a.depth&1?se:bd)(a,b,c,e,g)},Du=function r(a){function b(b,c,e,g,k){if((n=b.XG)&&n.ratio===a)for(var n,r,m,q=-1,w,A=n.length,v=b.value;++q<A;){b=n[q];r=b.children;m=b.value=0;for(w=r.length;m<w;++m)b.value+=r[m].value;b.wx?bd(b,c,e,g,e+=(k-e)*b.value/v):se(b,c,e,c+=(g-c)*b.value/v,k);v-=b.value}else b.XG=n=Gj(a,b,c,e,g,k),n.ratio=a}b.ratio=function(a){return r(1<(a=+a)?a:1)};return b}(zl),Eu=function(a){for(var b=-1,c=a.length,e,g=a[c-1],k=0;++b<c;)e=g,g=a[b],k+=e[1]*g[0]-e[0]*g[1];return k/\n2},Fu=function(a){for(var b=-1,c=a.length,e=0,g=0,k,n=a[c-1],r,m=0;++b<c;)k=n,n=a[b],m+=r=k[0]*n[1]-n[0]*k[1],e+=(k[0]+n[0])*r,g+=(k[1]+n[1])*r;return m*=3,[e/m,g/m]},Lp=function(a,b,c){return(b[0]-a[0])*(c[1]-a[1])-(b[1]-a[1])*(c[0]-a[0])},Gu=function(a){if(3>(c=a.length))return null;var b,c,e=Array(c),g=Array(c);for(b=0;b<c;++b)e[b]=[+a[b][0],+a[b][1],b];e.sort(Kp);for(b=0;b<c;++b)g[b]=[e[b][0],-e[b][1]];c=Hj(e);var g=Hj(g),k=g[0]===c[0],n=g[g.length-1]===c[c.length-1],r=[];for(b=c.length-1;0<=\nb;--b)r.push(a[e[c[b]][2]]);for(b=+k;b<g.length-n;++b)r.push(a[e[g[b]][2]]);return r},Hu=function(a,b){var c=a.length,e=a[c-1],g=b[0];b=b[1];for(var k=e[0],n=e[1],r,m=!1,q=0;q<c;++q)e=a[q],r=e[0],e=e[1],e>b!==n>b&&g<(k-r)*(b-e)/(n-e)+r&&(m=!m),k=r,n=e;return m},Iu=function(a){for(var b=-1,c=a.length,e=a[c-1],g,k,n=e[0],e=e[1],r=0;++b<c;)g=n,k=e,e=a[b],n=e[0],e=e[1],g-=n,k-=e,r+=Math.sqrt(g*g+k*k);return r},Ju=[].slice,Np={};qg.prototype=Jj.prototype={constructor:qg,defer:function(a){if(\"function\"!==\ntypeof a||this.$f)throw Error();if(null!=this._error)return this;var b=Ju.call(arguments,1);b.push(a);++this.ol;this.Wg.push(b);Ij(this);return this},abort:function(){null==this._error&&rg(this,Error(\"abort\"));return this},await:function(a){if(\"function\"!==typeof a||this.$f)throw Error();this.$f=function(b,c){a.apply(null,[b].concat(c))};te(this);return this},awaitAll:function(a){if(\"function\"!==typeof a||this.$f)throw Error();this.$f=a;te(this);return this}};var Ku=function(a,b){a=null==a?0:+a;b=\nnull==b?1:+b;1===arguments.length?(b=a,a=0):b-=a;return function(){return Math.random()*b+a}},Bl=function(a,b){var c,e;a=null==a?0:+a;b=null==b?1:+b;return function(){var g;if(null!=c)g=c,c=null;else{do c=2*Math.random()-1,g=2*Math.random()-1,e=c*c+g*g;while(!e||1<e)}return a+b*g*Math.sqrt(-2*Math.log(e)/e)}},Lu=function(){var a=Bl.apply(this,arguments);return function(){return Math.exp(a())}},Cl=function(a){return function(){for(var b=0,c=0;c<a;++c)b+=Math.random();return b}},Mu=function(a){var b=\nCl(a);return function(){return b()/a}},Nu=function(a){return function(){return-Math.log(1-Math.random())/a}},kh=function(a,b){function c(a){var b=m.status,c,k;if(k=!b)k=(k=m.responseType)&&\"text\"!==k?m.response:m.responseText;if(k||200<=b&&300>b||304===b){if(w)try{c=w.call(e,m)}catch(mo){g.call(\"error\",e,mo);return}else c=m;g.call(\"load\",e,c)}else g.call(\"error\",e,a)}var e,g=E(\"beforesend\",\"progress\",\"load\",\"error\"),k,n=fb(),m=new XMLHttpRequest,r=null,q=null,w,v,B=0;\"undefined\"===typeof XDomainRequest||\n\"withCredentials\"in m||!/^(http(s)?:)?\\/\\//.test(a)||(m=new XDomainRequest);\"onload\"in m?m.onload=m.onerror=m.ontimeout=c:m.onreadystatechange=function(a){3<m.readyState&&c(a)};m.onprogress=function(a){g.call(\"progress\",e,a)};e={header:function(a,b){a=(a+\"\").toLowerCase();if(2>arguments.length)return n.get(a);null==b?n.remove(a):n.set(a,b+\"\");return e},mimeType:function(a){if(!arguments.length)return k;k=null==a?null:a+\"\";return e},responseType:function(a){if(!arguments.length)return v;v=a;return e},\ntimeout:function(a){if(!arguments.length)return B;B=+a;return e},user:function(a){return 1>arguments.length?r:(r=null==a?null:a+\"\",e)},password:function(a){return 1>arguments.length?q:(q=null==a?null:a+\"\",e)},response:function(a){w=a;return e},get:function(a,b){return e.send(\"GET\",a,b)},post:function(a,b){return e.send(\"POST\",a,b)},send:function(b,c,w){m.open(b,a,!0,r,q);null==k||n.has(\"accept\")||n.set(\"accept\",k+\",*/*\");m.setRequestHeader&&n.each(function(a,b){m.setRequestHeader(b,a)});null!=k&&\nm.overrideMimeType&&m.overrideMimeType(k);null!=v&&(m.responseType=v);0<B&&(m.timeout=B);null==w&&\"function\"===typeof c&&(w=c,c=null);null!=w&&1===w.length&&(w=Op(w));if(null!=w)e.on(\"error\",w).on(\"load\",function(a){w(null,a)});g.call(\"beforesend\",e,m);m.send(null==c?null:c);return e},abort:function(){m.abort();return e},on:function(){var a=g.on.apply(g,arguments);return a===g?e:a}};if(null!=b){if(\"function\"!==typeof b)throw Error(\"invalid callback: \"+b);return e.get(b)}return e},Ye=function(a,b){return function(c,\ne){c=kh(c).mimeType(a).response(b);if(null!=e){if(\"function\"!==typeof e)throw Error(\"invalid callback: \"+e);return c.get(e)}return c}},Ou=Ye(\"text/html\",function(a){return document.createRange().createContextualFragment(a.responseText)}),Pu=Ye(\"application/json\",function(a){return JSON.parse(a.responseText)}),Qu=Ye(\"text/plain\",function(a){return a.responseText}),Ru=Ye(\"application/xml\",function(a){a=a.responseXML;if(!a)throw Error(\"parse error\");return a}),Dl=function(a,b){return function(c,e,g){3>\narguments.length&&(g=e,e=null);var k=kh(c).mimeType(a);k.row=function(a){return arguments.length?k.response(Pp(b,e=a)):e};k.row(e);return g?k.get(g):k}},Su=Dl(\"text/csv\",nl),Tu=Dl(\"text/tab-separated-values\",ol),El=Array.prototype,xg=El.map,yb=El.slice,tg={name:\"implicit\"},wg=function(a){return function(){return a}},Mj=function(a){return+a},Lj=[0,1],Xj=function(a,b){a=a.slice();var c=0,e=a.length-1,g=a[c],k=a[e],n;k<g&&(n=c,c=e,e=n,n=g,g=k,k=n);a[c]=b.floor(g);a[e]=b.ceil(k);return a},zg=new Date,\nAg=new Date,Yb=xa(function(){},function(a,b){a.setTime(+a+b)},function(a,b){return b-a});Yb.every=function(a){a=Math.floor(a);return isFinite(a)&&0<a?1<a?xa(function(b){b.setTime(Math.floor(b/a)*a)},function(b,c){b.setTime(+b+c*a)},function(b,c){return(c-b)/a}):Yb:null};var Fl=Yb.range,sd=xa(function(a){a.setTime(1E3*Math.floor(a/1E3))},function(a,b){a.setTime(+a+1E3*b)},function(a,b){return(b-a)/1E3},function(a){return a.getUTCSeconds()}),Gl=sd.range,lh=xa(function(a){a.setTime(6E4*Math.floor(a/\n6E4))},function(a,b){a.setTime(+a+6E4*b)},function(a,b){return(b-a)/6E4},function(a){return a.getMinutes()}),Uu=lh.range,mh=xa(function(a){var b=6E4*a.getTimezoneOffset()%36E5;0>b&&(b+=36E5);a.setTime(36E5*Math.floor((+a-b)/36E5)+b)},function(a,b){a.setTime(+a+36E5*b)},function(a,b){return(b-a)/36E5},function(a){return a.getHours()}),Vu=mh.range,ye=xa(function(a){a.setHours(0,0,0,0)},function(a,b){a.setDate(a.getDate()+b)},function(a,b){return(b-a-6E4*(b.getTimezoneOffset()-a.getTimezoneOffset()))/\n864E5},function(a){return a.getDate()-1}),Wu=ye.range,gd=Tb(0),Dg=Tb(1),Hl=Tb(2),Il=Tb(3),Jl=Tb(4),Kl=Tb(5),Ll=Tb(6),Ml=gd.range,Xu=Dg.range,Yu=Hl.range,Zu=Il.range,$u=Jl.range,av=Kl.range,bv=Ll.range,nh=xa(function(a){a.setDate(1);a.setHours(0,0,0,0)},function(a,b){a.setMonth(a.getMonth()+b)},function(a,b){return b.getMonth()-a.getMonth()+12*(b.getFullYear()-a.getFullYear())},function(a){return a.getMonth()}),cv=nh.range,Vb=xa(function(a){a.setMonth(0,1);a.setHours(0,0,0,0)},function(a,b){a.setFullYear(a.getFullYear()+\nb)},function(a,b){return b.getFullYear()-a.getFullYear()},function(a){return a.getFullYear()});Vb.every=function(a){return isFinite(a=Math.floor(a))&&0<a?xa(function(b){b.setFullYear(Math.floor(b.getFullYear()/a)*a);b.setMonth(0,1);b.setHours(0,0,0,0)},function(b,c){b.setFullYear(b.getFullYear()+c*a)}):null};var dv=Vb.range,oh=xa(function(a){a.setUTCSeconds(0,0)},function(a,b){a.setTime(+a+6E4*b)},function(a,b){return(b-a)/6E4},function(a){return a.getUTCMinutes()}),ev=oh.range,ph=xa(function(a){a.setUTCMinutes(0,\n0,0)},function(a,b){a.setTime(+a+36E5*b)},function(a,b){return(b-a)/36E5},function(a){return a.getUTCHours()}),fv=ph.range,ze=xa(function(a){a.setUTCHours(0,0,0,0)},function(a,b){a.setUTCDate(a.getUTCDate()+b)},function(a,b){return(b-a)/864E5},function(a){return a.getUTCDate()-1}),gv=ze.range,hd=Ub(0),Eg=Ub(1),Nl=Ub(2),Ol=Ub(3),Pl=Ub(4),Ql=Ub(5),Rl=Ub(6),Sl=hd.range,hv=Eg.range,iv=Nl.range,jv=Ol.range,kv=Pl.range,lv=Ql.range,mv=Rl.range,qh=xa(function(a){a.setUTCDate(1);a.setUTCHours(0,0,0,0)},function(a,\nb){a.setUTCMonth(a.getUTCMonth()+b)},function(a,b){return b.getUTCMonth()-a.getUTCMonth()+12*(b.getUTCFullYear()-a.getUTCFullYear())},function(a){return a.getUTCMonth()}),nv=qh.range,Wb=xa(function(a){a.setUTCMonth(0,1);a.setUTCHours(0,0,0,0)},function(a,b){a.setUTCFullYear(a.getUTCFullYear()+b)},function(a,b){return b.getUTCFullYear()-a.getUTCFullYear()},function(a){return a.getUTCFullYear()});Wb.every=function(a){return isFinite(a=Math.floor(a))&&0<a?xa(function(b){b.setUTCFullYear(Math.floor(b.getUTCFullYear()/\na)*a);b.setUTCMonth(0,1);b.setUTCHours(0,0,0,0)},function(b,c){b.setUTCFullYear(b.getUTCFullYear()+c*a)}):null};var ov=Wb.range,ck={\"-\":\"\",_:\" \",0:\"0\"},Va=/^\\s*\\d+/,Nq=/^%/,Mq=/[\\\\\\^\\$\\*\\+\\?\\|\\[\\]\\(\\)\\.\\{\\}]/g,qc;ik({dateTime:\"%x, %X\",date:\"%-m/%-d/%Y\",time:\"%-I:%M:%S %p\",periods:[\"AM\",\"PM\"],days:\"Sunday Monday Tuesday Wednesday Thursday Friday Saturday\".split(\" \"),shortDays:\"Sun Mon Tue Wed Thu Fri Sat\".split(\" \"),months:\"January February March April May June July August September October November December\".split(\" \"),\nshortMonths:\"Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec\".split(\" \")});var pv=Date.prototype.toISOString?Oq:d3.utcFormat(\"%Y-%m-%dT%H:%M:%S.%LZ\"),qv=+new Date(\"2000-01-01T00:00:00.000Z\")?Pq:d3.utcParse(\"%Y-%m-%dT%H:%M:%S.%LZ\"),rv=function(){return Fg(Vb,nh,gd,ye,mh,lh,sd,Yb,d3.timeFormat).domain([new Date(2E3,0,1),new Date(2E3,0,2)])},sv=function(){return Fg(Wb,qh,hd,ze,ph,oh,sd,Yb,d3.utcFormat).domain([Date.UTC(2E3,0,1),Date.UTC(2E3,0,2)])},Bb=function(a){return a.match(/.{6}/g).map(function(a){return\"#\"+\na})},tv=Bb(\"1f77b4ff7f0e2ca02cd627289467bd8c564be377c27f7f7fbcbd2217becf\"),uv=Bb(\"393b795254a36b6ecf9c9ede6379398ca252b5cf6bcedb9c8c6d31bd9e39e7ba52e7cb94843c39ad494ad6616be7969c7b4173a55194ce6dbdde9ed6\"),vv=Bb(\"3182bd6baed69ecae1c6dbefe6550dfd8d3cfdae6bfdd0a231a35474c476a1d99bc7e9c0756bb19e9ac8bcbddcdadaeb636363969696bdbdbdd9d9d9\"),wv=Bb(\"1f77b4aec7e8ff7f0effbb782ca02c98df8ad62728ff98969467bdc5b0d58c564bc49c94e377c2f7b6d27f7f7fc7c7c7bcbd22dbdb8d17becf9edae5\"),xv=Oe(Za(300,.5,0),Za(-240,.5,1)),yv=\nOe(Za(-100,.75,.35),Za(80,1.5,.8)),zv=Oe(Za(260,.75,.35),Za(80,1.5,.8)),Ze=Za(),Av=function(a){if(0>a||1<a)a-=Math.floor(a);var b=Math.abs(a-.5);Ze.h=360*a-100;Ze.s=1.5-1.5*b;Ze.l=.8-.9*b;return Ze+\"\"},Bv=Ae(Bb(\"44015444025645045745055946075a46085c460a5d460b5e470d60470e6147106347116447136548146748166848176948186a481a6c481b6d481c6e481d6f481f70482071482173482374482475482576482677482878482979472a7a472c7a472d7b472e7c472f7d46307e46327e46337f463480453581453781453882443983443a83443b84433d84433e85423f854240864241864142874144874045884046883f47883f48893e49893e4a893e4c8a3d4d8a3d4e8a3c4f8a3c508b3b518b3b528b3a538b3a548c39558c39568c38588c38598c375a8c375b8d365c8d365d8d355e8d355f8d34608d34618d33628d33638d32648e32658e31668e31678e31688e30698e306a8e2f6b8e2f6c8e2e6d8e2e6e8e2e6f8e2d708e2d718e2c718e2c728e2c738e2b748e2b758e2a768e2a778e2a788e29798e297a8e297b8e287c8e287d8e277e8e277f8e27808e26818e26828e26828e25838e25848e25858e24868e24878e23888e23898e238a8d228b8d228c8d228d8d218e8d218f8d21908d21918c20928c20928c20938c1f948c1f958b1f968b1f978b1f988b1f998a1f9a8a1e9b8a1e9c891e9d891f9e891f9f881fa0881fa1881fa1871fa28720a38620a48621a58521a68522a78522a88423a98324aa8325ab8225ac8226ad8127ad8128ae8029af7f2ab07f2cb17e2db27d2eb37c2fb47c31b57b32b67a34b67935b77937b87838b9773aba763bbb753dbc743fbc7340bd7242be7144bf7046c06f48c16e4ac16d4cc26c4ec36b50c46a52c56954c56856c66758c7655ac8645cc8635ec96260ca6063cb5f65cb5e67cc5c69cd5b6ccd5a6ece5870cf5773d05675d05477d1537ad1517cd2507fd34e81d34d84d44b86d54989d5488bd6468ed64590d74393d74195d84098d83e9bd93c9dd93ba0da39a2da37a5db36a8db34aadc32addc30b0dd2fb2dd2db5de2bb8de29bade28bddf26c0df25c2df23c5e021c8e020cae11fcde11dd0e11cd2e21bd5e21ad8e219dae319dde318dfe318e2e418e5e419e7e419eae51aece51befe51cf1e51df4e61ef6e620f8e621fbe723fde725\")),\nCv=Ae(Bb(\"00000401000501010601010802010902020b02020d03030f03031204041405041606051806051a07061c08071e0907200a08220b09240c09260d0a290e0b2b100b2d110c2f120d31130d34140e36150e38160f3b180f3d19103f1a10421c10441d11471e114920114b21114e22115024125325125527125829115a2a115c2c115f2d11612f116331116533106734106936106b38106c390f6e3b0f703d0f713f0f72400f74420f75440f764510774710784910784a10794c117a4e117b4f127b51127c52137c54137d56147d57157e59157e5a167e5c167f5d177f5f187f601880621980641a80651a80671b80681c816a1c816b1d816d1d816e1e81701f81721f817320817521817621817822817922827b23827c23827e24828025828125818326818426818627818827818928818b29818c29818e2a81902a81912b81932b80942c80962c80982d80992d809b2e7f9c2e7f9e2f7fa02f7fa1307ea3307ea5317ea6317da8327daa337dab337cad347cae347bb0357bb2357bb3367ab5367ab73779b83779ba3878bc3978bd3977bf3a77c03a76c23b75c43c75c53c74c73d73c83e73ca3e72cc3f71cd4071cf4070d0416fd2426fd3436ed5446dd6456cd8456cd9466bdb476adc4869de4968df4a68e04c67e24d66e34e65e44f64e55064e75263e85362e95462ea5661eb5760ec5860ed5a5fee5b5eef5d5ef05f5ef1605df2625df2645cf3655cf4675cf4695cf56b5cf66c5cf66e5cf7705cf7725cf8745cf8765cf9785df9795df97b5dfa7d5efa7f5efa815ffb835ffb8560fb8761fc8961fc8a62fc8c63fc8e64fc9065fd9266fd9467fd9668fd9869fd9a6afd9b6bfe9d6cfe9f6dfea16efea36ffea571fea772fea973feaa74feac76feae77feb078feb27afeb47bfeb67cfeb77efeb97ffebb81febd82febf84fec185fec287fec488fec68afec88cfeca8dfecc8ffecd90fecf92fed194fed395fed597fed799fed89afdda9cfddc9efddea0fde0a1fde2a3fde3a5fde5a7fde7a9fde9aafdebacfcecaefceeb0fcf0b2fcf2b4fcf4b6fcf6b8fcf7b9fcf9bbfcfbbdfcfdbf\")),\nDv=Ae(Bb(\"00000401000501010601010802010a02020c02020e03021004031204031405041706041907051b08051d09061f0a07220b07240c08260d08290e092b10092d110a30120a32140b34150b37160b39180c3c190c3e1b0c411c0c431e0c451f0c48210c4a230c4c240c4f260c51280b53290b552b0b572d0b592f0a5b310a5c320a5e340a5f3609613809623909633b09643d09653e0966400a67420a68440a68450a69470b6a490b6a4a0c6b4c0c6b4d0d6c4f0d6c510e6c520e6d540f6d550f6d57106e59106e5a116e5c126e5d126e5f136e61136e62146e64156e65156e67166e69166e6a176e6c186e6d186e6f196e71196e721a6e741a6e751b6e771c6d781c6d7a1d6d7c1d6d7d1e6d7f1e6c801f6c82206c84206b85216b87216b88226a8a226a8c23698d23698f24699025689225689326679526679727669827669a28659b29649d29649f2a63a02a63a22b62a32c61a52c60a62d60a82e5fa92e5eab2f5ead305dae305cb0315bb1325ab3325ab43359b63458b73557b93556ba3655bc3754bd3853bf3952c03a51c13a50c33b4fc43c4ec63d4dc73e4cc83f4bca404acb4149cc4248ce4347cf4446d04545d24644d34743d44842d54a41d74b3fd84c3ed94d3dda4e3cdb503bdd513ade5238df5337e05536e15635e25734e35933e45a31e55c30e65d2fe75e2ee8602de9612bea632aeb6429eb6628ec6726ed6925ee6a24ef6c23ef6e21f06f20f1711ff1731df2741cf3761bf37819f47918f57b17f57d15f67e14f68013f78212f78410f8850ff8870ef8890cf98b0bf98c0af98e09fa9008fa9207fa9407fb9606fb9706fb9906fb9b06fb9d07fc9f07fca108fca309fca50afca60cfca80dfcaa0ffcac11fcae12fcb014fcb216fcb418fbb61afbb81dfbba1ffbbc21fbbe23fac026fac228fac42afac62df9c72ff9c932f9cb35f8cd37f8cf3af7d13df7d340f6d543f6d746f5d949f5db4cf4dd4ff4df53f4e156f3e35af3e55df2e661f2e865f2ea69f1ec6df1ed71f1ef75f1f179f2f27df2f482f3f586f3f68af4f88ef5f992f6fa96f8fb9af9fc9dfafda1fcffa4\")),\nEv=Ae(Bb(\"0d088710078813078916078a19068c1b068d1d068e20068f2206902406912605912805922a05932c05942e05952f059631059733059735049837049938049a3a049a3c049b3e049c3f049c41049d43039e44039e46039f48039f4903a04b03a14c02a14e02a25002a25102a35302a35502a45601a45801a45901a55b01a55c01a65e01a66001a66100a76300a76400a76600a76700a86900a86a00a86c00a86e00a86f00a87100a87201a87401a87501a87701a87801a87a02a87b02a87d03a87e03a88004a88104a78305a78405a78606a68707a68808a68a09a58b0aa58d0ba58e0ca48f0da4910ea3920fa39410a29511a19613a19814a099159f9a169f9c179e9d189d9e199da01a9ca11b9ba21d9aa31e9aa51f99a62098a72197a82296aa2395ab2494ac2694ad2793ae2892b02991b12a90b22b8fb32c8eb42e8db52f8cb6308bb7318ab83289ba3388bb3488bc3587bd3786be3885bf3984c03a83c13b82c23c81c33d80c43e7fc5407ec6417dc7427cc8437bc9447aca457acb4679cc4778cc4977cd4a76ce4b75cf4c74d04d73d14e72d24f71d35171d45270d5536fd5546ed6556dd7566cd8576bd9586ada5a6ada5b69db5c68dc5d67dd5e66de5f65de6164df6263e06363e16462e26561e26660e3685fe4695ee56a5de56b5de66c5ce76e5be76f5ae87059e97158e97257ea7457eb7556eb7655ec7754ed7953ed7a52ee7b51ef7c51ef7e50f07f4ff0804ef1814df1834cf2844bf3854bf3874af48849f48948f58b47f58c46f68d45f68f44f79044f79143f79342f89441f89540f9973ff9983ef99a3efa9b3dfa9c3cfa9e3bfb9f3afba139fba238fca338fca537fca636fca835fca934fdab33fdac33fdae32fdaf31fdb130fdb22ffdb42ffdb52efeb72dfeb82cfeba2cfebb2bfebd2afebe2afec029fdc229fdc328fdc527fdc627fdc827fdca26fdcb26fccd25fcce25fcd025fcd225fbd324fbd524fbd724fad824fada24f9dc24f9dd25f8df25f8e125f7e225f7e425f6e626f6e826f5e926f5eb27f4ed27f3ee27f3f027f2f227f1f426f1f525f0f724f0f921\")),\nea=function(a){return function(){return a}},Zb=Math.PI,Be=Zb/2,Cb=2*Zb,Fv=function(){function a(){var a,r,A=+b.apply(this,arguments),v=+c.apply(this,arguments),w=k.apply(this,arguments)-Be,B=n.apply(this,arguments)-Be,E=Math.abs(B-w),J=B>w;q||(q=a=Mb());v<A&&(r=v,v=A,A=r);if(1E-12<v)if(E>Cb-1E-12)q.moveTo(v*Math.cos(w),v*Math.sin(w)),q.arc(0,0,v,w,B,!J),1E-12<A&&(q.moveTo(A*Math.cos(B),A*Math.sin(B)),q.arc(0,0,A,B,w,J));else{var C=w,L=B;r=w;var W=B,O=E,K=E,Q=m.apply(this,arguments)/2,U=1E-12<Q&&(g?\n+g.apply(this,arguments):Math.sqrt(A*A+v*v)),H=Math.min(Math.abs(v-A)/2,+e.apply(this,arguments)),F=H,aa=H;if(1E-12<U){var na=kk(U/A*Math.sin(Q)),Q=kk(U/v*Math.sin(Q));1E-12<(O-=2*na)?(na*=J?1:-1,r+=na,W-=na):(O=0,r=W=(w+B)/2);1E-12<(K-=2*Q)?(Q*=J?1:-1,C+=Q,L-=Q):(K=0,C=L=(w+B)/2)}w=v*Math.cos(C);B=v*Math.sin(C);na=A*Math.cos(W);Q=A*Math.sin(W);if(1E-12<H){var T=v*Math.cos(L),ka=v*Math.sin(L),ta=A*Math.cos(r),ca=A*Math.sin(r);if(E<Zb){1E-12<O?(F=ta-w,aa=ca-B,E=na-T,U=Q-ka,E=(E*(B-ka)-U*(w-T))/(U*\nF-E*aa),F=[w+E*F,B+E*aa]):F=[na,Q];var aa=w-F[0],E=B-F[1],U=T-F[0],ma=ka-F[1],aa=1/Math.sin(Math.acos((aa*U+E*ma)/(Math.sqrt(aa*aa+E*E)*Math.sqrt(U*U+ma*ma)))/2),E=Math.sqrt(F[0]*F[0]+F[1]*F[1]),F=Math.min(H,(A-E)/(aa-1)),aa=Math.min(H,(v-E)/(aa+1))}}1E-12<K?1E-12<aa?(C=Ce(ta,ca,w,B,v,aa,J),L=Ce(T,ka,na,Q,v,aa,J),q.moveTo(C.cx+C.bh,C.cy+C.dh),aa<H?q.arc(C.cx,C.cy,aa,Math.atan2(C.dh,C.bh),Math.atan2(L.dh,L.bh),!J):(q.arc(C.cx,C.cy,aa,Math.atan2(C.dh,C.bh),Math.atan2(C.yi,C.wi),!J),q.arc(0,0,v,Math.atan2(C.cy+\nC.yi,C.cx+C.wi),Math.atan2(L.cy+L.yi,L.cx+L.wi),!J),q.arc(L.cx,L.cy,aa,Math.atan2(L.yi,L.wi),Math.atan2(L.dh,L.bh),!J))):(q.moveTo(w,B),q.arc(0,0,v,C,L,!J)):q.moveTo(w,B);1E-12<A&&1E-12<O?1E-12<F?(C=Ce(na,Q,T,ka,A,-F,J),L=Ce(w,B,ta,ca,A,-F,J),q.lineTo(C.cx+C.bh,C.cy+C.dh),F<H?q.arc(C.cx,C.cy,F,Math.atan2(C.dh,C.bh),Math.atan2(L.dh,L.bh),!J):(q.arc(C.cx,C.cy,F,Math.atan2(C.dh,C.bh),Math.atan2(C.yi,C.wi),!J),q.arc(0,0,A,Math.atan2(C.cy+C.yi,C.cx+C.wi),Math.atan2(L.cy+L.yi,L.cx+L.wi),J),q.arc(L.cx,L.cy,\nF,Math.atan2(L.yi,L.wi),Math.atan2(L.dh,L.bh),!J))):q.arc(0,0,A,W,r,J):q.lineTo(na,Q)}else q.moveTo(0,0);q.closePath();if(a)return q=null,a+\"\"||null}var b=Sq,c=Tq,e=ea(0),g=null,k=Uq,n=Vq,m=Wq,q=null;a.centroid=function(){var a=(+b.apply(this,arguments)+ +c.apply(this,arguments))/2,e=(+k.apply(this,arguments)+ +n.apply(this,arguments))/2-Zb/2;return[Math.cos(e)*a,Math.sin(e)*a]};a.innerRadius=function(c){return arguments.length?(b=\"function\"===typeof c?c:ea(+c),a):b};a.outerRadius=function(b){return arguments.length?\n(c=\"function\"===typeof b?b:ea(+b),a):c};a.cornerRadius=function(b){return arguments.length?(e=\"function\"===typeof b?b:ea(+b),a):e};a.padRadius=function(b){return arguments.length?(g=null==b?null:\"function\"===typeof b?b:ea(+b),a):g};a.startAngle=function(b){return arguments.length?(k=\"function\"===typeof b?b:ea(+b),a):k};a.endAngle=function(b){return arguments.length?(n=\"function\"===typeof b?b:ea(+b),a):n};a.padAngle=function(b){return arguments.length?(m=\"function\"===typeof b?b:ea(+b),a):m};a.context=\nfunction(b){return arguments.length?(q=null==b?null:b,a):q};return a};lk.prototype={areaStart:function(){this.Ta=0},areaEnd:function(){this.Ta=NaN},lineStart:function(){this.Ha=0},lineEnd:function(){(this.Ta||0!==this.Ta&&1===this.Ha)&&this.Ia.closePath();this.Ta=1-this.Ta},point:function(a,b){a=+a;b=+b;switch(this.Ha){case 0:this.Ha=1;this.Ta?this.Ia.lineTo(a,b):this.Ia.moveTo(a,b);break;case 1:this.Ha=2;default:this.Ia.lineTo(a,b)}}};var $e=function(a){return new lk(a)},rh=function(){function a(a){var m,\nr=a.length,q,A=!1,v;null==g&&(n=k(v=Mb()));for(m=0;m<=r;++m)!(m<r&&e(q=a[m],m,a))===A&&((A=!A)?n.lineStart():n.lineEnd()),A&&n.point(+b(q,m,a),+c(q,m,a));if(v)return n=null,v+\"\"||null}var b=mk,c=nk,e=ea(!0),g=null,k=$e,n=null;a.x=function(c){return arguments.length?(b=\"function\"===typeof c?c:ea(+c),a):b};a.y=function(b){return arguments.length?(c=\"function\"===typeof b?b:ea(+b),a):c};a.defined=function(b){return arguments.length?(e=\"function\"===typeof b?b:ea(!!b),a):e};a.curve=function(b){return arguments.length?\n(k=b,null!=g&&(n=k(g)),a):k};a.context=function(b){return arguments.length?(null==b?g=n=null:n=k(g=b),a):g};return a},Tl=function(){function a(a){var b,r,A,w=a.length,B,E=!1,C,J=Array(w),L=Array(w);null==m&&(v=q(C=Mb()));for(b=0;b<=w;++b){if(!(b<w&&n(B=a[b],b,a))===E)if(E=!E)r=b,v.areaStart(),v.lineStart();else{v.lineEnd();v.lineStart();for(A=b-1;A>=r;--A)v.point(J[A],L[A]);v.lineEnd();v.areaEnd()}E&&(J[b]=+c(B,b,a),L[b]=+g(B,b,a),v.point(e?+e(B,b,a):J[b],k?+k(B,b,a):L[b]))}if(C)return v=null,C+\"\"||\nnull}function b(){return rh().defined(n).curve(q).context(m)}var c=mk,e=null,g=ea(0),k=nk,n=ea(!0),m=null,q=$e,v=null;a.x=function(b){return arguments.length?(c=\"function\"===typeof b?b:ea(+b),e=null,a):c};a.x0=function(b){return arguments.length?(c=\"function\"===typeof b?b:ea(+b),a):c};a.x1=function(b){return arguments.length?(e=null==b?null:\"function\"===typeof b?b:ea(+b),a):e};a.y=function(b){return arguments.length?(g=\"function\"===typeof b?b:ea(+b),k=null,a):g};a.y0=function(b){return arguments.length?\n(g=\"function\"===typeof b?b:ea(+b),a):g};a.y1=function(b){return arguments.length?(k=null==b?null:\"function\"===typeof b?b:ea(+b),a):k};a.lineX0=a.lineY0=function(){return b().x(c).y(g)};a.lineY1=function(){return b().x(c).y(k)};a.lineX1=function(){return b().x(e).y(g)};a.defined=function(b){return arguments.length?(n=\"function\"===typeof b?b:ea(!!b),a):n};a.curve=function(b){return arguments.length?(q=b,null!=m&&(v=q(m)),a):q};a.context=function(b){return arguments.length?(null==b?m=v=null:v=q(m=b),\na):m};return a},Gv=function(a,b){return b<a?-1:b>a?1:b>=a?0:NaN},Hv=function(a){return a},Iv=function(){function a(a){var m,q=a.length,r,A;r=0;var v=Array(q),w=Array(q),B=+g.apply(this,arguments);A=Math.min(Cb,Math.max(-Cb,k.apply(this,arguments)-B));var E,C=Math.min(Math.abs(A)/q,n.apply(this,arguments)),J=C*(0>A?-1:1),W;for(m=0;m<q;++m)0<(W=w[v[m]=m]=+b(a[m],m,a))&&(r+=W);null!=c?v.sort(function(a,b){return c(w[a],w[b])}):null!=e&&v.sort(function(b,c){return e(a[b],a[c])});m=0;for(A=r?(A-q*J)/r:\n0;m<q;++m,B=E)r=v[m],W=w[r],E=B+(0<W?W*A:0)+J,w[r]={data:a[r],index:m,value:W,startAngle:B,endAngle:E,padAngle:C};return w}var b=Hv,c=Gv,e=null,g=ea(0),k=ea(Cb),n=ea(0);a.value=function(c){return arguments.length?(b=\"function\"===typeof c?c:ea(+c),a):b};a.sortValues=function(b){return arguments.length?(c=b,e=null,a):c};a.sort=function(b){return arguments.length?(e=b,c=null,a):e};a.startAngle=function(b){return arguments.length?(g=\"function\"===typeof b?b:ea(+b),a):g};a.endAngle=function(b){return arguments.length?\n(k=\"function\"===typeof b?b:ea(+b),a):k};a.padAngle=function(b){return arguments.length?(n=\"function\"===typeof b?b:ea(+b),a):n};return a},Ul=Hg($e);ok.prototype={areaStart:function(){this.Uh.areaStart()},areaEnd:function(){this.Uh.areaEnd()},lineStart:function(){this.Uh.lineStart()},lineEnd:function(){this.Uh.lineEnd()},point:function(a,b){this.Uh.point(b*Math.sin(a),b*-Math.cos(a))}};var Jv=function(){return id(rh().curve(Ul))},Kv=function(){var a=Tl().curve(Ul),b=a.curve,c=a.lineX0,e=a.lineX1,g=\na.lineY0,k=a.lineY1;a.angle=a.x;delete a.x;a.startAngle=a.x0;delete a.x0;a.endAngle=a.x1;delete a.x1;a.radius=a.y;delete a.y;a.innerRadius=a.y0;delete a.y0;a.outerRadius=a.y1;delete a.y1;a.lineStartAngle=function(){return id(c())};delete a.lineX0;a.lineEndAngle=function(){return id(e())};delete a.lineX1;a.lineInnerRadius=function(){return id(g())};delete a.lineY0;a.lineOuterRadius=function(){return id(k())};delete a.lineY1;a.curve=function(a){return arguments.length?b(Hg(a)):b().Uh};return a},sh=\n{draw:function(a,b){b=Math.sqrt(b/Zb);a.moveTo(b,0);a.arc(0,0,b,0,Cb)}},Vl={draw:function(a,b){b=Math.sqrt(b/5)/2;a.moveTo(-3*b,-b);a.lineTo(-b,-b);a.lineTo(-b,-3*b);a.lineTo(b,-3*b);a.lineTo(b,-b);a.lineTo(3*b,-b);a.lineTo(3*b,b);a.lineTo(b,b);a.lineTo(b,3*b);a.lineTo(-b,3*b);a.lineTo(-b,b);a.lineTo(-3*b,b);a.closePath()}},Wl=Math.sqrt(1/3),Lv=2*Wl,Xl={draw:function(a,b){b=Math.sqrt(b/Lv);var c=b*Wl;a.moveTo(0,-b);a.lineTo(c,0);a.lineTo(0,b);a.lineTo(-c,0);a.closePath()}},Yl=Math.sin(Zb/10)/Math.sin(7*\nZb/10),Mv=Math.sin(Cb/10)*Yl,Nv=-Math.cos(Cb/10)*Yl,Zl={draw:function(a,b){b=Math.sqrt(.8908130915292852*b);var c=Mv*b,e=Nv*b;a.moveTo(0,-b);a.lineTo(c,e);for(var g=1;5>g;++g){var k=Cb*g/5,n=Math.cos(k),k=Math.sin(k);a.lineTo(k*b,-n*b);a.lineTo(n*c-k*e,k*c+n*e)}a.closePath()}},$l={draw:function(a,b){b=Math.sqrt(b);var c=-b/2;a.rect(c,c,b,b)}},th=Math.sqrt(3),am={draw:function(a,b){b=-Math.sqrt(b/(3*th));a.moveTo(0,2*b);a.lineTo(-th*b,-b);a.lineTo(th*b,-b);a.closePath()}},Wa=Math.sqrt(3)/2,uh=1/Math.sqrt(12),\nOv=3*(uh/2+1),bm={draw:function(a,b){var c=Math.sqrt(b/Ov);b=c/2;var e=c*uh,g=b,c=c*uh+c,k=-g,n=c;a.moveTo(b,e);a.lineTo(g,c);a.lineTo(k,n);a.lineTo(-.5*b-Wa*e,Wa*b+-.5*e);a.lineTo(-.5*g-Wa*c,Wa*g+-.5*c);a.lineTo(-.5*k-Wa*n,Wa*k+-.5*n);a.lineTo(-.5*b+Wa*e,-.5*e-Wa*b);a.lineTo(-.5*g+Wa*c,-.5*c-Wa*g);a.lineTo(-.5*k+Wa*n,-.5*n-Wa*k);a.closePath()}},Pv=[sh,Vl,Xl,$l,Zl,am,bm],Qv=function(){function a(){var a;e||(e=a=Mb());b.apply(this,arguments).draw(e,+c.apply(this,arguments));if(a)return e=null,a+\"\"||\nnull}var b=ea(sh),c=ea(64),e=null;a.type=function(c){return arguments.length?(b=\"function\"===typeof c?c:ea(c),a):b};a.size=function(b){return arguments.length?(c=\"function\"===typeof b?b:ea(+b),a):c};a.context=function(b){return arguments.length?(e=null==b?null:b,a):e};return a},Db=function(){};Ee.prototype={areaStart:function(){this.Ta=0},areaEnd:function(){this.Ta=NaN},lineStart:function(){this.ub=this.Sa=this.xb=this.Va=NaN;this.Ha=0},lineEnd:function(){switch(this.Ha){case 3:De(this,this.Sa,this.Va);\ncase 2:this.Ia.lineTo(this.Sa,this.Va)}(this.Ta||0!==this.Ta&&1===this.Ha)&&this.Ia.closePath();this.Ta=1-this.Ta},point:function(a,b){a=+a;b=+b;switch(this.Ha){case 0:this.Ha=1;this.Ta?this.Ia.lineTo(a,b):this.Ia.moveTo(a,b);break;case 1:this.Ha=2;break;case 2:this.Ha=3,this.Ia.lineTo((5*this.ub+this.Sa)/6,(5*this.xb+this.Va)/6);default:De(this,a,b)}this.ub=this.Sa;this.Sa=a;this.xb=this.Va;this.Va=b}};var Rv=function(a){return new Ee(a)};pk.prototype={areaStart:Db,areaEnd:Db,lineStart:function(){this.ub=\nthis.Sa=this.Mb=this.Lf=this.ai=this.xb=this.Va=this.Nb=this.Mf=this.bi=NaN;this.Ha=0},lineEnd:function(){switch(this.Ha){case 1:this.Ia.moveTo(this.Mb,this.Nb);this.Ia.closePath();break;case 2:this.Ia.moveTo((this.Mb+2*this.Lf)/3,(this.Nb+2*this.Mf)/3);this.Ia.lineTo((this.Lf+2*this.Mb)/3,(this.Mf+2*this.Nb)/3);this.Ia.closePath();break;case 3:this.point(this.Mb,this.Nb),this.point(this.Lf,this.Mf),this.point(this.ai,this.bi)}},point:function(a,b){a=+a;b=+b;switch(this.Ha){case 0:this.Ha=1;this.Mb=\na;this.Nb=b;break;case 1:this.Ha=2;this.Lf=a;this.Mf=b;break;case 2:this.Ha=3;this.ai=a;this.bi=b;this.Ia.moveTo((this.ub+4*this.Sa+a)/6,(this.xb+4*this.Va+b)/6);break;default:De(this,a,b)}this.ub=this.Sa;this.Sa=a;this.xb=this.Va;this.Va=b}};var Sv=function(a){return new pk(a)};qk.prototype={areaStart:function(){this.Ta=0},areaEnd:function(){this.Ta=NaN},lineStart:function(){this.ub=this.Sa=this.xb=this.Va=NaN;this.Ha=0},lineEnd:function(){(this.Ta||0!==this.Ta&&3===this.Ha)&&this.Ia.closePath();\nthis.Ta=1-this.Ta},point:function(a,b){a=+a;b=+b;switch(this.Ha){case 0:this.Ha=1;break;case 1:this.Ha=2;break;case 2:this.Ha=3;var c=(this.ub+4*this.Sa+a)/6,e=(this.xb+4*this.Va+b)/6;this.Ta?this.Ia.lineTo(c,e):this.Ia.moveTo(c,e);break;case 3:this.Ha=4;default:De(this,a,b)}this.ub=this.Sa;this.Sa=a;this.xb=this.Va;this.Va=b}};var Tv=function(a){return new qk(a)};rk.prototype={lineStart:function(){this.tc=[];this.ce=[];this.bq.lineStart()},lineEnd:function(){var a=this.tc,b=this.ce,c=a.length-1;\nif(0<c)for(var e=a[0],g=b[0],k=a[c]-e,n=b[c]-g,m=-1,q;++m<=c;)q=m/c,this.bq.point(this.sn*a[m]+(1-this.sn)*(e+q*k),this.sn*b[m]+(1-this.sn)*(g+q*n));this.tc=this.ce=null;this.bq.lineEnd()},point:function(a,b){this.tc.push(+a);this.ce.push(+b)}};var Uv=function w(a){function b(b){return 1===a?new Ee(b):new rk(b,a)}b.beta=function(a){return w(+a)};return b}(.85);Ig.prototype={areaStart:function(){this.Ta=0},areaEnd:function(){this.Ta=NaN},lineStart:function(){this.ub=this.Sa=this.Mb=this.xb=this.Va=\nthis.Nb=NaN;this.Ha=0},lineEnd:function(){switch(this.Ha){case 2:this.Ia.lineTo(this.Mb,this.Nb);break;case 3:Fe(this,this.Sa,this.Va)}(this.Ta||0!==this.Ta&&1===this.Ha)&&this.Ia.closePath();this.Ta=1-this.Ta},point:function(a,b){a=+a;b=+b;switch(this.Ha){case 0:this.Ha=1;this.Ta?this.Ia.lineTo(a,b):this.Ia.moveTo(a,b);break;case 1:this.Ha=2;this.Sa=a;this.Va=b;break;case 2:this.Ha=3;default:Fe(this,a,b)}this.ub=this.Sa;this.Sa=this.Mb;this.Mb=a;this.xb=this.Va;this.Va=this.Nb;this.Nb=b}};var Vv=\nfunction H(a){function b(b){return new Ig(b,a)}b.tension=function(a){return H(+a)};return b}(0);Jg.prototype={areaStart:Db,areaEnd:Db,lineStart:function(){this.ub=this.Sa=this.Mb=this.Lf=this.ai=this.pl=this.xb=this.Va=this.Nb=this.Mf=this.bi=this.ql=NaN;this.Ha=0},lineEnd:function(){switch(this.Ha){case 1:this.Ia.moveTo(this.Lf,this.Mf);this.Ia.closePath();break;case 2:this.Ia.lineTo(this.Lf,this.Mf);this.Ia.closePath();break;case 3:this.point(this.Lf,this.Mf),this.point(this.ai,this.bi),this.point(this.pl,\nthis.ql)}},point:function(a,b){a=+a;b=+b;switch(this.Ha){case 0:this.Ha=1;this.Lf=a;this.Mf=b;break;case 1:this.Ha=2;this.Ia.moveTo(this.ai=a,this.bi=b);break;case 2:this.Ha=3;this.pl=a;this.ql=b;break;default:Fe(this,a,b)}this.ub=this.Sa;this.Sa=this.Mb;this.Mb=a;this.xb=this.Va;this.Va=this.Nb;this.Nb=b}};var Wv=function F(a){function b(b){return new Jg(b,a)}b.tension=function(a){return F(+a)};return b}(0);Kg.prototype={areaStart:function(){this.Ta=0},areaEnd:function(){this.Ta=NaN},lineStart:function(){this.ub=\nthis.Sa=this.Mb=this.xb=this.Va=this.Nb=NaN;this.Ha=0},lineEnd:function(){(this.Ta||0!==this.Ta&&3===this.Ha)&&this.Ia.closePath();this.Ta=1-this.Ta},point:function(a,b){a=+a;b=+b;switch(this.Ha){case 0:this.Ha=1;break;case 1:this.Ha=2;break;case 2:this.Ha=3;this.Ta?this.Ia.lineTo(this.Mb,this.Nb):this.Ia.moveTo(this.Mb,this.Nb);break;case 3:this.Ha=4;default:Fe(this,a,b)}this.ub=this.Sa;this.Sa=this.Mb;this.Mb=a;this.xb=this.Va;this.Va=this.Nb;this.Nb=b}};var Xv=function ca(a){function b(b){return new Kg(b,\na)}b.tension=function(a){return ca(+a)};return b}(0);sk.prototype={areaStart:function(){this.Ta=0},areaEnd:function(){this.Ta=NaN},lineStart:function(){this.ub=this.Sa=this.Mb=this.xb=this.Va=this.Nb=NaN;this.sh=this.qg=this.rg=this.Wh=this.Hf=this.Cg=this.Ha=0},lineEnd:function(){switch(this.Ha){case 2:this.Ia.lineTo(this.Mb,this.Nb);break;case 3:this.point(this.Mb,this.Nb)}(this.Ta||0!==this.Ta&&1===this.Ha)&&this.Ia.closePath();this.Ta=1-this.Ta},point:function(a,b){a=+a;b=+b;if(this.Ha){var c=\nthis.Mb-a,e=this.Nb-b;this.rg=Math.sqrt(this.Cg=Math.pow(c*c+e*e,this.bl))}switch(this.Ha){case 0:this.Ha=1;this.Ta?this.Ia.lineTo(a,b):this.Ia.moveTo(a,b);break;case 1:this.Ha=2;break;case 2:this.Ha=3;default:Lg(this,a,b)}this.sh=this.qg;this.qg=this.rg;this.Wh=this.Hf;this.Hf=this.Cg;this.ub=this.Sa;this.Sa=this.Mb;this.Mb=a;this.xb=this.Va;this.Va=this.Nb;this.Nb=b}};var Yv=function qa(a){function b(b){return a?new sk(b,a):new Ig(b,0)}b.alpha=function(a){return qa(+a)};return b}(.5);tk.prototype=\n{areaStart:Db,areaEnd:Db,lineStart:function(){this.ub=this.Sa=this.Mb=this.Lf=this.ai=this.pl=this.xb=this.Va=this.Nb=this.Mf=this.bi=this.ql=NaN;this.sh=this.qg=this.rg=this.Wh=this.Hf=this.Cg=this.Ha=0},lineEnd:function(){switch(this.Ha){case 1:this.Ia.moveTo(this.Lf,this.Mf);this.Ia.closePath();break;case 2:this.Ia.lineTo(this.Lf,this.Mf);this.Ia.closePath();break;case 3:this.point(this.Lf,this.Mf),this.point(this.ai,this.bi),this.point(this.pl,this.ql)}},point:function(a,b){a=+a;b=+b;if(this.Ha){var c=\nthis.Mb-a,e=this.Nb-b;this.rg=Math.sqrt(this.Cg=Math.pow(c*c+e*e,this.bl))}switch(this.Ha){case 0:this.Ha=1;this.Lf=a;this.Mf=b;break;case 1:this.Ha=2;this.Ia.moveTo(this.ai=a,this.bi=b);break;case 2:this.Ha=3;this.pl=a;this.ql=b;break;default:Lg(this,a,b)}this.sh=this.qg;this.qg=this.rg;this.Wh=this.Hf;this.Hf=this.Cg;this.ub=this.Sa;this.Sa=this.Mb;this.Mb=a;this.xb=this.Va;this.Va=this.Nb;this.Nb=b}};var Zv=function T(a){function b(b){return a?new tk(b,a):new Jg(b,0)}b.alpha=function(a){return T(+a)};\nreturn b}(.5);uk.prototype={areaStart:function(){this.Ta=0},areaEnd:function(){this.Ta=NaN},lineStart:function(){this.ub=this.Sa=this.Mb=this.xb=this.Va=this.Nb=NaN;this.sh=this.qg=this.rg=this.Wh=this.Hf=this.Cg=this.Ha=0},lineEnd:function(){(this.Ta||0!==this.Ta&&3===this.Ha)&&this.Ia.closePath();this.Ta=1-this.Ta},point:function(a,b){a=+a;b=+b;if(this.Ha){var c=this.Mb-a,e=this.Nb-b;this.rg=Math.sqrt(this.Cg=Math.pow(c*c+e*e,this.bl))}switch(this.Ha){case 0:this.Ha=1;break;case 1:this.Ha=2;break;\ncase 2:this.Ha=3;this.Ta?this.Ia.lineTo(this.Mb,this.Nb):this.Ia.moveTo(this.Mb,this.Nb);break;case 3:this.Ha=4;default:Lg(this,a,b)}this.sh=this.qg;this.qg=this.rg;this.Wh=this.Hf;this.Hf=this.Cg;this.ub=this.Sa;this.Sa=this.Mb;this.Mb=a;this.xb=this.Va;this.Va=this.Nb;this.Nb=b}};var $v=function A(a){function b(b){return a?new uk(b,a):new Kg(b,0)}b.alpha=function(a){return A(+a)};return b}(.5);vk.prototype={areaStart:Db,areaEnd:Db,lineStart:function(){this.Ha=0},lineEnd:function(){this.Ha&&this.Ia.closePath()},\npoint:function(a,b){a=+a;b=+b;this.Ha?this.Ia.lineTo(a,b):(this.Ha=1,this.Ia.moveTo(a,b))}};var aw=function(a){return new vk(a)};Ge.prototype={areaStart:function(){this.Ta=0},areaEnd:function(){this.Ta=NaN},lineStart:function(){this.ub=this.Sa=this.xb=this.Va=this.Pn=NaN;this.Ha=0},lineEnd:function(){switch(this.Ha){case 2:this.Ia.lineTo(this.Sa,this.Va);break;case 3:Mg(this,this.Pn,xk(this,this.Pn))}(this.Ta||0!==this.Ta&&1===this.Ha)&&this.Ia.closePath();this.Ta=1-this.Ta},point:function(a,b){var c=\nNaN;a=+a;b=+b;if(a!==this.Sa||b!==this.Va){switch(this.Ha){case 0:this.Ha=1;this.Ta?this.Ia.lineTo(a,b):this.Ia.moveTo(a,b);break;case 1:this.Ha=2;break;case 2:this.Ha=3;Mg(this,xk(this,c=wk(this,a,b)),c);break;default:Mg(this,this.Pn,c=wk(this,a,b))}this.ub=this.Sa;this.Sa=a;this.xb=this.Va;this.Va=b;this.Pn=c}}};(yk.prototype=Object.create(Ge.prototype)).point=function(a,b){Ge.prototype.point.call(this,b,a)};zk.prototype={moveTo:function(a,b){this.Ia.moveTo(b,a)},closePath:function(){this.Ia.closePath()},\nlineTo:function(a,b){this.Ia.lineTo(b,a)},bezierCurveTo:function(a,b,c,e,g,k){this.Ia.bezierCurveTo(b,a,e,c,k,g)}};Ak.prototype={areaStart:function(){this.Ta=0},areaEnd:function(){this.Ta=NaN},lineStart:function(){this.tc=[];this.ce=[]},lineEnd:function(){var a=this.tc,b=this.ce,c=a.length;if(c)if(this.Ta?this.Ia.lineTo(a[0],b[0]):this.Ia.moveTo(a[0],b[0]),2===c)this.Ia.lineTo(a[1],b[1]);else for(var e=Bk(a),g=Bk(b),k=0,n=1;n<c;++k,++n)this.Ia.bezierCurveTo(e[0][k],g[0][k],e[1][k],g[1][k],a[n],b[n]);\n(this.Ta||0!==this.Ta&&1===c)&&this.Ia.closePath();this.Ta=1-this.Ta;this.tc=this.ce=null},point:function(a,b){this.tc.push(+a);this.ce.push(+b)}};var bw=function(a){return new Ak(a)};He.prototype={areaStart:function(){this.Ta=0},areaEnd:function(){this.Ta=NaN},lineStart:function(){this.tc=this.ce=NaN;this.Ha=0},lineEnd:function(){0<this.Zi&&1>this.Zi&&2===this.Ha&&this.Ia.lineTo(this.tc,this.ce);(this.Ta||0!==this.Ta&&1===this.Ha)&&this.Ia.closePath();0<=this.Ta&&(this.Zi=1-this.Zi,this.Ta=1-this.Ta)},\npoint:function(a,b){a=+a;b=+b;switch(this.Ha){case 0:this.Ha=1;this.Ta?this.Ia.lineTo(a,b):this.Ia.moveTo(a,b);break;case 1:this.Ha=2;default:if(0>=this.Zi)this.Ia.lineTo(this.tc,b),this.Ia.lineTo(a,b);else{var c=this.tc*(1-this.Zi)+a*this.Zi;this.Ia.lineTo(c,this.ce);this.Ia.lineTo(c,b)}}this.tc=a;this.ce=b}};var cw=function(a){return new He(a,.5)},cm=Array.prototype.slice,Bc=function(a,b){if(1<(k=a.length))for(var c=1,e,g=a[b[0]],k,n=g.length;c<k;++c){e=g;for(var g=a[b[c]],m=0;m<n;++m)g[m][1]+=\ng[m][0]=isNaN(e[m][1])?e[m][0]:e[m][1]}},Cc=function(a){a=a.length;for(var b=Array(a);0<=--a;)b[a]=a;return b},dw=function(){function a(a){var k=b.apply(this,arguments),n,m=a.length,q=k.length,v=Array(q);for(n=0;n<q;++n){for(var A=k[n],B=v[n]=Array(m),E=0,C;E<m;++E)B[E]=C=[0,+g(a[E],A,E,a)],C.data=a[E];B.key=A}n=0;for(k=c(v);n<q;++n)v[k[n]].index=n;e(v,k);return v}var b=ea([]),c=Cc,e=Bc,g=ar;a.keys=function(c){return arguments.length?(b=\"function\"===typeof c?c:ea(cm.call(c)),a):b};a.value=function(b){return arguments.length?\n(g=\"function\"===typeof b?b:ea(+b),a):g};a.order=function(b){return arguments.length?(c=null==b?Cc:\"function\"===typeof b?b:ea(cm.call(b)),a):c};a.offset=function(b){return arguments.length?(e=null==b?Bc:b,a):e};return a},ew=function(a,b){if(0<(e=a.length)){for(var c,e,g=0,k=a[0].length,n;g<k;++g){for(n=c=0;c<e;++c)n+=a[c][g][1]||0;if(n)for(c=0;c<e;++c)a[c][g][1]/=n}Bc(a,b)}},fw=function(a,b){if(0<(g=a.length)){for(var c=0,e=a[b[0]],g,k=e.length;c<k;++c){for(var n=0,m=0;n<g;++n)m+=a[n][c][1]||0;e[c][1]+=\ne[c][0]=-m/2}Bc(a,b)}},gw=function(a,b){if(0<(n=a.length)&&0<(k=(g=a[b[0]]).length)){for(var c=0,e=1,g,k,n;e<k;++e){for(var m=0,q=0,v=0;m<n;++m){for(var A=a[b[m]],B=A[e][1]||0,A=A[e-1][1]||0,A=(B-A)/2,E=0;E<m;++E)var C=a[b[E]],J=C[e][1]||0,C=C[e-1][1]||0,A=A+(J-C);q+=B;v+=A*B}g[e-1][1]+=g[e-1][0]=c;q&&(c-=v/q)}g[e-1][1]+=g[e-1][0]=c;Bc(a,b)}},dm=function(a){var b=a.map(Ck);return Cc(a).sort(function(a,c){return b[a]-b[c]})},hw=function(a){return dm(a).reverse()},iw=function(a){var b=a.length,c,e=\na.map(Ck),g=Cc(a).sort(function(a,b){return e[b]-e[a]}),k=0,n=0,m=[],q=[];for(a=0;a<b;++a)c=g[a],k<n?(k+=e[c],m.push(c)):(n+=e[c],q.push(c));return q.reverse().concat(m)},jw=function(a){return Cc(a).reverse()},em=function(a){return function(){return a}};Ie.prototype={constructor:Ie,insert:function(a,b){var c,e;if(a){b.Ue=a;if(b.pe=a.pe)a.pe.Ue=b;a.pe=b;if(a.ac){for(a=a.ac;a.sb;)a=a.sb;a.sb=b}else a.ac=b;c=a}else this.Fa?(a=Dk(this.Fa),b.Ue=null,b.pe=a,a.Ue=a.sb=b,c=a):(b.Ue=b.pe=null,this.Fa=b,c=\nnull);b.sb=b.ac=null;b.qd=c;b.qb=!0;for(a=b;c&&c.qb;)b=c.qd,c===b.sb?(e=b.ac)&&e.qb?(c.qb=e.qb=!1,b.qb=!0,a=b):(a===c.ac&&(jd(this,c),a=c,c=a.qd),c.qb=!1,b.qb=!0,kd(this,b)):(e=b.sb)&&e.qb?(c.qb=e.qb=!1,b.qb=!0,a=b):(a===c.sb&&(kd(this,c),a=c,c=a.qd),c.qb=!1,b.qb=!0,jd(this,b)),c=a.qd;this.Fa.qb=!1},remove:function(a){a.pe&&(a.pe.Ue=a.Ue);a.Ue&&(a.Ue.pe=a.pe);a.pe=a.Ue=null;var b=a.qd,c=a.sb,e=a.ac,g,k;g=c?e?Dk(e):c:e;b?b.sb===a?b.sb=g:b.ac=g:this.Fa=g;c&&e?(k=g.qb,g.qb=a.qb,g.sb=c,c.qd=g,g!==e?(b=\ng.qd,g.qd=a.qd,a=g.ac,b.sb=a,g.ac=e,e.qd=g):(g.qd=b,b=g,a=g.ac)):(k=a.qb,a=g);a&&(a.qd=b);if(!k)if(a&&a.qb)a.qb=!1;else{do{if(a===this.Fa)break;if(a===b.sb){if(a=b.ac,a.qb&&(a.qb=!1,b.qb=!0,jd(this,b),a=b.ac),a.sb&&a.sb.qb||a.ac&&a.ac.qb){a.ac&&a.ac.qb||(a.sb.qb=!1,a.qb=!0,kd(this,a),a=b.ac);a.qb=b.qb;b.qb=a.ac.qb=!1;jd(this,b);a=this.Fa;break}}else if(a=b.sb,a.qb&&(a.qb=!1,b.qb=!0,kd(this,b),a=b.sb),a.sb&&a.sb.qb||a.ac&&a.ac.qb){a.sb&&a.sb.qb||(a.ac.qb=!1,a.qb=!0,jd(this,a),a=b.sb);a.qb=b.qb;b.qb=\na.sb.qb=!1;kd(this,b);a=this.Fa;break}a.qb=!0;a=b;b=b.qd}while(!a.qb);a&&(a.qb=!1)}}};var Fk=[],Ng,Hk=[],la=1E-6,ir=1E-12,tc,Ra,nd,Fa;Pg.prototype={constructor:Pg,polygons:function(){var a=this.edges;return this.cells.map(function(b){var c=b.halfedges.map(function(c){return Ek(b,a[c])});c.data=b.site.data;return c})},triangles:function(){var a=[],b=this.edges;this.cells.forEach(function(c,e){if(n=(g=c.halfedges).length){c=c.site;for(var g,k=-1,n,m,q=b[g[n-1]],q=q.left===c?q.right:q.left;++k<n;)m=\nq,q=b[g[k]],q=q.left===c?q.right:q.left,m&&q&&e<m.index&&e<q.index&&0>(c[0]-q[0])*(m[1]-c[1])-(c[0]-m[0])*(q[1]-c[1])&&a.push([c.data,m.data,q.data])}});return a},links:function(){return this.edges.filter(function(a){return a.right}).map(function(a){return{source:a.left.data,target:a.right.data}})},find:function(a,b,c){var e=this,g,k=e.NF||0;g=e.cells.length;for(var n;!(n=e.cells[k]);)if(++k>=g)return null;g=a-n.site[0];var m=b-n.site[1],q=g*g+m*m;do n=e.cells[g=k],k=null,n.halfedges.forEach(function(c){var g=\ne.edges[c];c=g.left;if(c!==n.site&&c||(c=g.right)){var g=a-c[0],m=b-c[1],g=g*g+m*m;g<q&&(q=g,k=c.index)}});while(null!==k);e.NF=g;return null==c||q<=c*c?n.site:null}};var kw=function(){function a(a){return new Pg(a.map(function(e,g){var k=[Math.round(b(e,g,a)/la)*la,Math.round(c(e,g,a)/la)*la];k.index=g;k.data=e;return k}),e)}var b=br,c=cr,e=null;a.polygons=function(b){return a(b).polygons()};a.links=function(b){return a(b).links()};a.triangles=function(b){return a(b).triangles()};a.x=function(c){return arguments.length?\n(b=\"function\"===typeof c?c:em(+c),a):b};a.y=function(b){return arguments.length?(c=\"function\"===typeof b?b:em(+b),a):c};a.extent=function(b){return arguments.length?(e=null==b?null:[[+b[0][0],+b[0][1]],[+b[1][0],+b[1][1]]],a):e&&[[e[0][0],e[0][1]],[e[1][0],e[1][1]]]};a.size=function(b){return arguments.length?(e=null==b?null:[[0,0],[+b[0],+b[1]]],a):e&&[e[1][0]-e[0][0],e[1][1]-e[0][1]]};return a},fm=function(a){return function(){return a}};qb.prototype={constructor:qb,scale:function(a){return 1===\na?this:new qb(this.k*a,this.x,this.y)},translate:function(a,b){return 0===a&0===b?this:new qb(this.k,this.x+this.k*a,this.y+this.k*b)},apply:function(a){return[a[0]*this.k+this.x,a[1]*this.k+this.y]},applyX:function(a){return a*this.k+this.x},applyY:function(a){return a*this.k+this.y},invert:function(a){return[(a[0]-this.x)/this.k,(a[1]-this.y)/this.k]},invertX:function(a){return(a-this.x)/this.k},invertY:function(a){return(a-this.y)/this.k},rescaleX:function(a){return a.copy().domain(a.range().map(this.invertX,\nthis).map(a.invert,a))},rescaleY:function(a){return a.copy().domain(a.range().map(this.invertY,this).map(a.invert,a))},toString:function(){return\"translate(\"+this.x+\",\"+this.y+\") scale(\"+this.k+\")\"}};var Qg=new qb(1,0,0);Jk.prototype=qb.prototype;var td=function(){d3.event.preventDefault();d3.event.stopImmediatePropagation()},lw=function(){function a(a){a.on(\"wheel.zoom\",q).on(\"mousedown.zoom\",v).on(\"dblclick.zoom\",B).on(\"touchstart.zoom\",C).on(\"touchmove.zoom\",J).on(\"touchend.zoom touchcancel.zoom\",\nW).style(\"-webkit-tap-highlight-color\",\"rgba(0,0,0,0)\").property(\"__zoom\",Kk)}function b(a,b){b=Math.max(K,Math.min(U,b));return b===a.k?a:new qb(b,a.x,a.y)}function c(a,b,c){var e=b[0]-c[0]*a.k;b=b[1]-c[1]*a.k;return e===a.x&&b===a.y?a:new qb(a.k,e,b)}function e(a,b){var c=a.invertX(b[0][0])-aa,e=a.invertX(b[1][0])-na,g=a.invertY(b[0][1])-ka;b=a.invertY(b[1][1])-ta;return a.translate(e>c?(c+e)/2:Math.min(0,c)||Math.max(0,e),b>g?(g+b)/2:Math.min(0,g)||Math.max(0,b))}function g(a){return[(+a[0][0]+\n+a[1][0])/2,(+a[0][1]+ +a[1][1])/2]}function k(a,b,c){a.on(\"start.zoom\",function(){n(this,arguments).start()}).on(\"interrupt.zoom end.zoom\",function(){n(this,arguments).end()}).tween(\"zoom\",function(){var a=this,e=arguments,k=n(a,e),m=Q.apply(a,e),q=c||g(m),v=Math.max(m[1][0]-m[0][0],m[1][1]-m[0][1]),m=a.__zoom,B=\"function\"===typeof b?b.apply(a,e):b,E=Ka(m.invert(q).concat(v/m.k),B.invert(q).concat(v/B.k));return function(a){if(1===a)a=B;else{a=E(a);var b=v/a[2];a=new qb(b,q[0]-a[0]*b,q[1]-a[1]*b)}k.zoom(null,\na)}})}function n(a,b){for(var c=0,e=N.length,g;c<e;++c)if((g=N[c]).Kh===a)return g;return new m(a,b)}function m(a,b){this.Kh=a;this.Wq=b;this.index=-1;this.active=0;this.extent=Q.apply(a,b)}function q(){function a(){g.Et=null;g.end()}if(O.apply(this,arguments)){var g=n(this,arguments),k=this.__zoom,m=Math.max(K,Math.min(U,k.k*Math.pow(2,-d3.event.deltaY*(d3.event.deltaMode?120:1)/500))),q=vb(this);if(g.Et){if(g.mouse[0][0]!==q[0]||g.mouse[0][1]!==q[1])g.mouse[1]=k.invert(g.mouse[0]=q);clearTimeout(g.Et)}else{if(k.k===\nm)return;g.mouse=[q,k.invert(q)];Lb(this);g.start()}td();g.Et=setTimeout(a,150);g.zoom(\"mouse\",e(c(b(k,m),g.mouse[0],g.mouse[1]),g.extent))}}function v(){function a(){td();g.xO=!0;g.zoom(\"mouse\",e(c(g.Kh.__zoom,g.mouse[0]=vb(g.Kh),g.mouse[1]),g.extent))}function b(){k.on(\"mousemove.zoom mouseup.zoom\",null);xd(d3.event.view,g.xO);td();g.end()}if(!Hb&&O.apply(this,arguments)){var g=n(this,arguments),k=Ma(d3.event.view).on(\"mousemove.zoom\",a,!0).on(\"mouseup.zoom\",b,!0),m=vb(this);Kd(d3.event.view);d3.event.stopImmediatePropagation();\ng.mouse=[m,this.__zoom.invert(m)];Lb(this);g.start()}}function B(){if(O.apply(this,arguments)){var g=this.__zoom,n=vb(this),m=g.invert(n),q=g.k*(d3.event.shiftKey?.5:2),g=e(c(b(g,q),n,m),Q.apply(this,arguments));td();0<ma?Ma(this).transition().duration(ma).call(k,g,n):Ma(this).call(a.transform,g)}}function C(){if(O.apply(this,arguments)){var a=n(this,arguments),b=d3.event.changedTouches,c,e=b.length,g,k,m;d3.event.stopImmediatePropagation();for(g=0;g<e;++g)(k=b[g],m=Ne(this,b,k.identifier),m=[m,this.__zoom.invert(m),\nk.identifier],a.Qe)?a.cf||(a.cf=m):(a.Qe=m,c=!0);if(S&&(S=clearTimeout(S),!a.cf)){a.end();(m=Ma(this).on(\"dblclick.zoom\"))&&m.apply(this,arguments);return}c&&(S=setTimeout(function(){S=null},500),Lb(this),a.start())}}function J(){var a=n(this,arguments),g=d3.event.changedTouches,k=g.length,m,q,v,B;td();S&&(S=clearTimeout(S));for(m=0;m<k;++m)q=g[m],v=Ne(this,g,q.identifier),a.Qe&&a.Qe[2]===q.identifier?a.Qe[0]=v:a.cf&&a.cf[2]===q.identifier&&(a.cf[0]=v);q=a.Kh.__zoom;if(a.cf){v=a.Qe[0];g=a.Qe[1];m=\na.cf[0];k=a.cf[1];B=(B=m[0]-v[0])*B+(B=m[1]-v[1])*B;var E=(E=k[0]-g[0])*E+(E=k[1]-g[1])*E;q=b(q,Math.sqrt(B/E));v=[(v[0]+m[0])/2,(v[1]+m[1])/2];B=[(g[0]+k[0])/2,(g[1]+k[1])/2]}else if(a.Qe)v=a.Qe[0],B=a.Qe[1];else return;a.zoom(\"touch\",e(c(q,v,B),a.extent))}function W(){var a=n(this,arguments),b=d3.event.changedTouches,c=b.length,e,g;d3.event.stopImmediatePropagation();Hb&&clearTimeout(Hb);Hb=setTimeout(function(){Hb=null},500);for(e=0;e<c;++e)g=b[e],a.Qe&&a.Qe[2]===g.identifier?delete a.Qe:a.cf&&\na.cf[2]===g.identifier&&delete a.cf;a.cf&&!a.Qe&&(a.Qe=a.cf,delete a.cf);a.Qe||a.end()}var O=mr,Q=nr,K=0,U=Infinity,aa=-U,na=U,ka=aa,ta=na,ma=250,Ka=cl,N=[],Gb=E(\"start\",\"zoom\",\"end\"),S,Hb;a.transform=function(a,b){var c=a.selection?a.selection():a;c.property(\"__zoom\",Kk);a!==c?k(a,b):c.interrupt().each(function(){n(this,arguments).start().zoom(null,\"function\"===typeof b?b.apply(this,arguments):b).end()})};a.scaleBy=function(b,c){a.scaleTo(b,function(){var a=this.__zoom.k,b=\"function\"===typeof c?\nc.apply(this,arguments):c;return a*b})};a.scaleTo=function(k,n){a.transform(k,function(){var a=Q.apply(this,arguments),k=this.__zoom,m=g(a),q=k.invert(m),v=\"function\"===typeof n?n.apply(this,arguments):n;return e(c(b(k,v),m,q),a)})};a.translateBy=function(b,c,g){a.transform(b,function(){return e(this.__zoom.translate(\"function\"===typeof c?c.apply(this,arguments):c,\"function\"===typeof g?g.apply(this,arguments):g),Q.apply(this,arguments))})};m.prototype={start:function(){1===++this.active&&(this.index=\nN.push(this)-1,this.gj(\"start\"));return this},zoom:function(a,b){this.mouse&&\"mouse\"!==a&&(this.mouse[1]=b.invert(this.mouse[0]));this.Qe&&\"touch\"!==a&&(this.Qe[1]=b.invert(this.Qe[0]));this.cf&&\"touch\"!==a&&(this.cf[1]=b.invert(this.cf[0]));this.Kh.__zoom=b;this.gj(\"zoom\");return this},end:function(){0===--this.active&&(N.splice(this.index,1),this.index=-1,this.gj(\"end\"));return this},gj:function(b){Ya(new lr(a,b,this.Kh.__zoom),Gb.apply,Gb,[b,this.Kh,this.Wq])}};a.filter=function(b){return arguments.length?\n(O=\"function\"===typeof b?b:fm(!!b),a):O};a.extent=function(b){return arguments.length?(Q=\"function\"===typeof b?b:fm([[+b[0][0],+b[0][1]],[+b[1][0],+b[1][1]]]),a):Q};a.scaleExtent=function(b){return arguments.length?(K=+b[0],U=+b[1],a):[K,U]};a.translateExtent=function(b){return arguments.length?(aa=+b[0][0],na=+b[1][0],ka=+b[0][1],ta=+b[1][1],a):[[aa,ka],[na,ta]]};a.duration=function(b){return arguments.length?(ma=+b,a):ma};a.interpolate=function(b){return arguments.length?(Ka=b,a):Ka};a.on=function(){var b=\nGb.on.apply(Gb,arguments);return b===Gb?a:b};return a};d3.version=\"4.6.0\";d3.bisect=Sb;d3.bisectRight=Sb;d3.bisectLeft=or;d3.ascending=Eb;d3.bisector=Gg;d3.descending=pr;d3.deviation=Nk;d3.extent=Ok;d3.histogram=tr;d3.thresholdFreedmanDiaconis=ur;d3.thresholdScott=vr;d3.thresholdSturges=Qk;d3.max=wr;d3.mean=xr;d3.median=yr;d3.merge=Uf;d3.min=Rk;d3.pairs=zr;d3.permute=Ar;d3.quantile=dd;d3.range=bb;d3.scan=Br;d3.shuffle=Cr;d3.sum=Dr;d3.ticks=we;d3.tickStep=b;d3.transpose=Sk;d3.variance=Mk;d3.zip=Er;\nd3.axisTop=q;d3.axisRight=v;d3.axisBottom=B;d3.axisLeft=C;d3.brush=at;d3.brushX=jo;d3.brushY=ko;d3.brushSelection=io;d3.chord=bt;d3.ribbon=et;d3.nest=ft;d3.set=mi;d3.map=fb;d3.keys=gt;d3.values=ht;d3.entries=it;d3.color=sb;d3.rgb=Fc;d3.hsl=yd;d3.lab=zd;d3.hcl=Ad;d3.cubehelix=Za;d3.dispatch=E;d3.drag=ms;d3.dragDisable=Kd;d3.dragEnable=xd;d3.dsvFormat=dh;d3.csvParse=nl;d3.csvParseRows=jt;d3.csvFormat=kt;d3.csvFormatRows=lt;d3.tsvParse=ol;d3.tsvParseRows=mt;d3.tsvFormat=nt;d3.tsvFormatRows=ot;d3.easeLinear=\nOn;d3.easeQuad=ai;d3.easeQuadIn=Pn;d3.easeQuadOut=Qn;d3.easeQuadInOut=ai;d3.easeCubic=zf;d3.easeCubicIn=Rn;d3.easeCubicOut=Sn;d3.easeCubicInOut=zf;d3.easePoly=fl;d3.easePolyIn=Rs;d3.easePolyOut=Ss;d3.easePolyInOut=fl;d3.easeSin=ci;d3.easeSinIn=Tn;d3.easeSinOut=Un;d3.easeSinInOut=ci;d3.easeExp=ei;d3.easeExpIn=Vn;d3.easeExpOut=Wn;d3.easeExpInOut=ei;d3.easeCircle=fi;d3.easeCircleIn=Xn;d3.easeCircleOut=Yn;d3.easeCircleInOut=fi;d3.easeBounce=Lc;d3.easeBounceIn=Zn;d3.easeBounceOut=Lc;d3.easeBounceInOut=\nfo;d3.easeBack=gl;d3.easeBackIn=Ts;d3.easeBackOut=Us;d3.easeBackInOut=gl;d3.easeElastic=hl;d3.easeElasticIn=Vs;d3.easeElasticOut=hl;d3.easeElasticInOut=Ws;d3.forceCenter=pt;d3.forceCollide=Ct;d3.forceLink=Dt;d3.forceManyBody=Gt;d3.forceSimulation=Ft;d3.forceX=Ht;d3.forceY=It;d3.formatDefaultLocale=ti;d3.formatLocale=ui;d3.formatSpecifier=xe;d3.precisionFixed=Qj;d3.precisionPrefix=Oj;d3.precisionRound=Pj;d3.geoArea=Mt;d3.geoBounds=Nt;d3.geoCentroid=Ot;d3.geoCircle=Qt;d3.geoClipExtent=Rt;d3.geoDistance=\nTt;d3.geoGraticule=$i;d3.geoGraticule10=bp;d3.geoInterpolate=Ut;d3.geoLength=ul;d3.geoPath=Vt;d3.geoAlbers=wl;d3.geoAlbersUsa=Xt;d3.geoAzimuthalEqualArea=Yt;d3.geoAzimuthalEqualAreaRaw=ih;d3.geoAzimuthalEquidistant=Zt;d3.geoAzimuthalEquidistantRaw=jh;d3.geoConicConformal=au;d3.geoConicConformalRaw=uj;d3.geoConicEqualArea=Xe;d3.geoConicEqualAreaRaw=rj;d3.geoConicEquidistant=cu;d3.geoConicEquidistantRaw=vj;d3.geoEquirectangular=bu;d3.geoEquirectangularRaw=ad;d3.geoGnomonic=du;d3.geoGnomonicRaw=ig;d3.geoIdentity=\neu;d3.geoProjection=xb;d3.geoProjectionMutator=fg;d3.geoMercator=$t;d3.geoMercatorRaw=me;d3.geoOrthographic=fu;d3.geoOrthographicRaw=jg;d3.geoStereographic=gu;d3.geoStereographicRaw=kg;d3.geoTransverseMercator=hu;d3.geoTransverseMercatorRaw=lg;d3.geoRotation=Pt;d3.geoStream=cb;d3.geoTransform=Wt;d3.cluster=iu;d3.hierarchy=mg;d3.pack=vu;d3.packSiblings=uu;d3.packEnclose=Dj;d3.partition=wu;d3.stratify=yu;d3.tree=zu;d3.treemap=Au;d3.treemapBinary=Bu;d3.treemapDice=bd;d3.treemapSlice=se;d3.treemapSliceDice=\nCu;d3.treemapSquarify=Al;d3.treemapResquarify=Du;d3.interpolate=Pc;d3.interpolateArray=Xk;d3.interpolateBasis=Vk;d3.interpolateBasisClosed=Wk;d3.interpolateDate=Yk;d3.interpolateNumber=Na;d3.interpolateObject=Zk;d3.interpolateRound=Nj;d3.interpolateString=Zg;d3.interpolateTransformCss=al;d3.interpolateTransformSvg=bl;d3.interpolateZoom=cl;d3.interpolateRgb=qd;d3.interpolateRgbBasis=ns;d3.interpolateRgbBasisClosed=os;d3.interpolateHsl=ps;d3.interpolateHslLong=qs;d3.interpolateLab=ln;d3.interpolateHcl=\nrs;d3.interpolateHclLong=ss;d3.interpolateCubehelix=ts;d3.interpolateCubehelixLong=Oe;d3.quantize=us;d3.path=Mb;d3.polygonArea=Eu;d3.polygonCentroid=Fu;d3.polygonHull=Gu;d3.polygonContains=Hu;d3.polygonLength=Iu;d3.quadtree=Nd;d3.queue=Jj;d3.randomUniform=Ku;d3.randomNormal=Bl;d3.randomLogNormal=Lu;d3.randomBates=Mu;d3.randomIrwinHall=Cl;d3.randomExponential=Nu;d3.request=kh;d3.html=Ou;d3.json=Pu;d3.text=Qu;d3.xml=Ru;d3.csv=Su;d3.tsv=Tu;d3.scaleBand=ug;d3.scalePoint=Qp;d3.scaleIdentity=Sj;d3.scaleLinear=\nRj;d3.scaleLog=Wj;d3.scaleOrdinal=sg;d3.scaleImplicit=tg;d3.scalePow=yg;d3.scaleSqrt=Yp;d3.scaleQuantile=Yj;d3.scaleQuantize=Zj;d3.scaleThreshold=ak;d3.scaleTime=rv;d3.scaleUtc=sv;d3.schemeCategory10=tv;d3.schemeCategory20b=uv;d3.schemeCategory20c=vv;d3.schemeCategory20=wv;d3.interpolateCubehelixDefault=xv;d3.interpolateRainbow=Av;d3.interpolateWarm=yv;d3.interpolateCool=zv;d3.interpolateViridis=Bv;d3.interpolateMagma=Cv;d3.interpolateInferno=Dv;d3.interpolatePlasma=Ev;d3.scaleSequential=jk;d3.creator=\nRg;d3.local=ka;d3.matcher=Sg;d3.mouse=vb;d3.namespace=od;d3.namespaces=Sa;d3.select=Ma;d3.selectAll=ks;d3.selection=Ib;d3.selector=Me;d3.selectorAll=Vg;d3.touch=Ne;d3.touches=ls;d3.window=$b;d3.customEvent=Ya;d3.arc=Fv;d3.area=Tl;d3.line=rh;d3.pie=Iv;d3.radialArea=Kv;d3.radialLine=Jv;d3.symbol=Qv;d3.symbols=Pv;d3.symbolCircle=sh;d3.symbolCross=Vl;d3.symbolDiamond=Xl;d3.symbolSquare=$l;d3.symbolStar=Zl;d3.symbolTriangle=am;d3.symbolWye=bm;d3.curveBasisClosed=Sv;d3.curveBasisOpen=Tv;d3.curveBasis=Rv;\nd3.curveBundle=Uv;d3.curveCardinalClosed=Wv;d3.curveCardinalOpen=Xv;d3.curveCardinal=Vv;d3.curveCatmullRomClosed=Zv;d3.curveCatmullRomOpen=$v;d3.curveCatmullRom=Yv;d3.curveLinearClosed=aw;d3.curveLinear=$e;d3.curveMonotoneX=Xq;d3.curveMonotoneY=Yq;d3.curveNatural=bw;d3.curveStep=cw;d3.curveStepAfter=$q;d3.curveStepBefore=Zq;d3.stack=dw;d3.stackOffsetExpand=ew;d3.stackOffsetNone=Bc;d3.stackOffsetSilhouette=fw;d3.stackOffsetWiggle=gw;d3.stackOrderAscending=dm;d3.stackOrderDescending=hw;d3.stackOrderInsideOut=\niw;d3.stackOrderNone=Cc;d3.stackOrderReverse=jw;d3.timeInterval=xa;d3.timeMillisecond=Yb;d3.timeMilliseconds=Fl;d3.utcMillisecond=Yb;d3.utcMilliseconds=Fl;d3.timeSecond=sd;d3.timeSeconds=Gl;d3.utcSecond=sd;d3.utcSeconds=Gl;d3.timeMinute=lh;d3.timeMinutes=Uu;d3.timeHour=mh;d3.timeHours=Vu;d3.timeDay=ye;d3.timeDays=Wu;d3.timeWeek=gd;d3.timeWeeks=Ml;d3.timeSunday=gd;d3.timeSundays=Ml;d3.timeMonday=Dg;d3.timeMondays=Xu;d3.timeTuesday=Hl;d3.timeTuesdays=Yu;d3.timeWednesday=Il;d3.timeWednesdays=Zu;d3.timeThursday=\nJl;d3.timeThursdays=$u;d3.timeFriday=Kl;d3.timeFridays=av;d3.timeSaturday=Ll;d3.timeSaturdays=bv;d3.timeMonth=nh;d3.timeMonths=cv;d3.timeYear=Vb;d3.timeYears=dv;d3.utcMinute=oh;d3.utcMinutes=ev;d3.utcHour=ph;d3.utcHours=fv;d3.utcDay=ze;d3.utcDays=gv;d3.utcWeek=hd;d3.utcWeeks=Sl;d3.utcSunday=hd;d3.utcSundays=Sl;d3.utcMonday=Eg;d3.utcMondays=hv;d3.utcTuesday=Nl;d3.utcTuesdays=iv;d3.utcWednesday=Ol;d3.utcWednesdays=jv;d3.utcThursday=Pl;d3.utcThursdays=kv;d3.utcFriday=Ql;d3.utcFridays=lv;d3.utcSaturday=\nRl;d3.utcSaturdays=mv;d3.utcMonth=qh;d3.utcMonths=nv;d3.utcYear=Wb;d3.utcYears=ov;d3.timeFormatDefaultLocale=ik;d3.timeFormatLocale=bk;d3.isoFormat=pv;d3.isoParse=qv;d3.now=cc;d3.timer=Dd;d3.timerFlush=Yh;d3.timeout=xf;d3.interval=vs;d3.transition=$h;d3.active=Zs;d3.interrupt=Lb;d3.voronoi=kw;d3.zoom=lw;d3.zoomTransform=Jk;d3.zoomIdentity=Qg;Sa.svg=Sa.svg;Sa.xhtml=Sa.xhtml;Sa.xlink=Sa.xlink;Sa.xml=Sa.xml;Sa.xmlns=Sa.xmlns})();h.R={};h.R.wg=h.Mh;\nh.R.Qm=function(a,b){b.unshift(a);h.debug.Error.call(this,h.ca.kW.apply(null,b));b.shift()};h.da(h.R.Qm,h.debug.Error);h.R.Qm.prototype.name=\"AssertionError\";h.R.hD=function(a){throw a;};h.R.wr=h.R.hD;h.R.wh=function(a,b,c,e){var g=\"Assertion failed\";if(c)var g=g+(\": \"+c),k=e;else a&&(g+=\": \"+a,k=b);a=new h.R.Qm(\"\"+g,k||[]);h.R.wr(a)};h.R.iba=function(a){h.R.wg&&(h.R.wr=a)};h.R.assert=function(a,b,c){h.R.wg&&!a&&h.R.wh(\"\",null,b,Array.prototype.slice.call(arguments,2));return a};\nh.R.fail=function(a,b){h.R.wg&&h.R.wr(new h.R.Qm(\"Failure\"+(a?\": \"+a:\"\"),Array.prototype.slice.call(arguments,1)))};h.R.ul=function(a,b,c){h.R.wg&&!h.ni(a)&&h.R.wh(\"Expected number but got %s: %s.\",[h.df(a),a],b,Array.prototype.slice.call(arguments,2));return a};h.R.Lw=function(a,b,c){h.R.wg&&!h.Hb(a)&&h.R.wh(\"Expected string but got %s: %s.\",[h.df(a),a],b,Array.prototype.slice.call(arguments,2));return a};\nh.R.d2=function(a,b,c){h.R.wg&&!h.isFunction(a)&&h.R.wh(\"Expected function but got %s: %s.\",[h.df(a),a],b,Array.prototype.slice.call(arguments,2));return a};h.R.e2=function(a,b,c){h.R.wg&&!h.mj(a)&&h.R.wh(\"Expected object but got %s: %s.\",[h.df(a),a],b,Array.prototype.slice.call(arguments,2));return a};h.R.NJ=function(a,b,c){h.R.wg&&!h.isArray(a)&&h.R.wh(\"Expected array but got %s: %s.\",[h.df(a),a],b,Array.prototype.slice.call(arguments,2));return a};\nh.R.b2=function(a,b,c){h.R.wg&&!h.sk(a)&&h.R.wh(\"Expected boolean but got %s: %s.\",[h.df(a),a],b,Array.prototype.slice.call(arguments,2));return a};h.R.c2=function(a,b,c){!h.R.wg||h.mj(a)&&a.nodeType==h.dom.dE.mD||h.R.wh(\"Expected Element but got %s: %s.\",[h.df(a),a],b,Array.prototype.slice.call(arguments,2));return a};h.R.Xq=function(a,b,c,e){!h.R.wg||a instanceof b||h.R.wh(\"Expected instanceof %s but got %s.\",[h.R.UA(b),h.R.UA(a)],c,Array.prototype.slice.call(arguments,3));return a};\nh.R.f2=function(){for(var a in Object.prototype)h.R.fail(a+\" should not be enumerable in Object.prototype.\")};h.R.UA=function(a){return a instanceof Function?a.displayName||a.name||\"unknown type name\":a instanceof Object?a.constructor.displayName||a.constructor.name||Object.prototype.toString.call(a):null===a?\"null\":typeof a};h.la={};h.la.userAgent={};h.la.userAgent.util={};h.la.userAgent.util.Cz=function(){var a=h.la.userAgent.util.$L();return a&&(a=a.userAgent)?a:\"\"};h.la.userAgent.util.$L=function(){return h.global.navigator};\nh.la.userAgent.util.LC=h.la.userAgent.util.Cz();h.la.userAgent.util.lba=function(a){h.la.userAgent.util.LC=a||h.la.userAgent.util.Cz()};h.la.userAgent.util.nk=function(){return h.la.userAgent.util.LC};h.la.userAgent.util.lc=function(a){var b=h.la.userAgent.util.nk();return h.ca.contains(b,a)};h.la.userAgent.util.hO=function(a){var b=h.la.userAgent.util.nk();return h.ca.dK(b,a)};\nh.la.userAgent.util.Bx=function(a){for(var b=/(\\w[\\w ]+)\\/([^\\s]+)\\s*(?:\\((.*?)\\))?/g,c=[],e;e=b.exec(a);)c.push([e[1],e[2],e[3]||void 0]);return c};l.Map=function(a,b){this.vh=a;this.Bk=b;this.jc={};this.tl=!0;0<this.vh.length&&this.WN()};l.Map.prototype.WN=function(){for(var a=0;a<this.vh.length;a++){var b=this.vh[a],c=b[0],b=b[1];this.jc[c.toString()]=new l.Map.fu(c,b)}this.tl=!0};\nl.Map.prototype.toArray=function(){if(this.tl){if(this.Bk){var a=this.jc,b;for(b in a)if(Object.prototype.hasOwnProperty.call(a,b)){var c=a[b].Aj;c&&c.toArray()}}}else{this.vh.length=0;a=this.Cm();a.sort();for(b=0;b<a.length;b++){var e=this.jc[a[b]];(c=e.Aj)&&c.toArray();this.vh.push([e.key,e.value])}this.tl=!0}return this.vh};\nl.Map.prototype.C=function(a,b){for(var c=this.toArray(),e=[],g=0;g<c.length;g++){var k=this.jc[c[g][0].toString()];this.Lm(k);var m=k.Aj;m?(h.R.assert(b),e.push([k.key,b(a,m)])):e.push([k.key,k.value])}return e};l.Map.l6=function(a,b,c){b=new l.Map([],b);for(var e=0;e<a.length;e++){var g=a[e][0],k=c(a[e][1]);b.set(g,k)}return b};l.Map.Ek=function(a){this.fB=0;this.vh=a};l.Map.Ek.prototype.next=function(){return this.fB<this.vh.length?{done:!1,value:this.vh[this.fB++]}:{done:!0,value:void 0}};\n\"undefined\"!=typeof Symbol&&(l.Map.Ek.prototype[Symbol.iterator]=function(){return this});d=l.Map.prototype;d.clear=function(){this.jc={};this.tl=!1};d.entries=function(){var a=[],b=this.Cm();b.sort();for(var c=0;c<b.length;c++){var e=this.jc[b[c]];a.push([e.key,this.Lm(e)])}return new l.Map.Ek(a)};d.keys=function(){var a=[],b=this.Cm();b.sort();for(var c=0;c<b.length;c++){var e=this.jc[b[c]];a.push(e.key)}return new l.Map.Ek(a)};\nd.values=function(){var a=[],b=this.Cm();b.sort();for(var c=0;c<b.length;c++){var e=this.jc[b[c]];a.push(this.Lm(e))}return new l.Map.Ek(a)};d.forEach=function(a,b){var c=this.Cm();c.sort();for(var e=0;e<c.length;e++){var g=this.jc[c[e]];a.call(b,this.Lm(g),g.key,this)}};d.set=function(a,b){var c=new l.Map.fu(a);this.Bk?(c.Aj=b,c.value=b.toArray()):c.value=b;this.jc[a.toString()]=c;this.tl=!1;return this};d.Lm=function(a){return this.Bk?(a.Aj||(a.Aj=new this.Bk(a.value)),a.Aj):a.value};\nd.get=function(a){a=a.toString();if(a=this.jc[a])return this.Lm(a)};d.has=function(a){a=a.toString();return a in this.jc};l.Map.ia=function(a,b,c,e,g){for(var k=void 0,m=void 0;b.fa()&&!b.ga();){var n=b.ka;1==n?k=c.call(b):2==n&&(a.Bk?(m=new a.Bk,e.call(b,m,g)):m=e.call(b))}h.R.assert(void 0!=k);h.R.assert(void 0!=m);a.set(k,m)};l.Map.prototype.Cm=function(){var a=this.jc,b=[],c;for(c in a)Object.prototype.hasOwnProperty.call(a,c)&&b.push(c);return b};\nl.Map.fu=function(a,b){this.key=a;this.value=b;this.Aj=void 0};h.aa={};h.mh=h.Qp;h.aa.eh=!1;h.aa.VO=function(a){return a[a.length-1]};h.aa.last=h.aa.VO;h.aa.indexOf=h.mh&&(h.aa.eh||Array.prototype.indexOf)?function(a,b,c){h.R.assert(null!=a.length);return Array.prototype.indexOf.call(a,b,c)}:function(a,b,c){c=null==c?0:0>c?Math.max(0,a.length+c):c;if(h.Hb(a))return h.Hb(b)&&1==b.length?a.indexOf(b,c):-1;for(;c<a.length;c++)if(c in a&&a[c]===b)return c;return-1};\nh.aa.lastIndexOf=h.mh&&(h.aa.eh||Array.prototype.lastIndexOf)?function(a,b,c){h.R.assert(null!=a.length);c=null==c?a.length-1:c;return Array.prototype.lastIndexOf.call(a,b,c)}:function(a,b,c){c=null==c?a.length-1:c;0>c&&(c=Math.max(0,a.length+c));if(h.Hb(a))return h.Hb(b)&&1==b.length?a.lastIndexOf(b,c):-1;for(;0<=c;c--)if(c in a&&a[c]===b)return c;return-1};\nh.aa.forEach=h.mh&&(h.aa.eh||Array.prototype.forEach)?function(a,b,c){h.R.assert(null!=a.length);Array.prototype.forEach.call(a,b,c)}:function(a,b,c){for(var e=a.length,g=h.Hb(a)?a.split(\"\"):a,k=0;k<e;k++)k in g&&b.call(c,g[k],k,a)};h.aa.Fx=function(a,b,c){for(var e=a.length,g=h.Hb(a)?a.split(\"\"):a,e=e-1;0<=e;--e)e in g&&b.call(c,g[e],e,a)};\nh.aa.filter=h.mh&&(h.aa.eh||Array.prototype.filter)?function(a,b,c){h.R.assert(null!=a.length);return Array.prototype.filter.call(a,b,c)}:function(a,b,c){for(var e=a.length,g=[],k=0,m=h.Hb(a)?a.split(\"\"):a,n=0;n<e;n++)if(n in m){var q=m[n];b.call(c,q,n,a)&&(g[k++]=q)}return g};\nh.aa.map=h.mh&&(h.aa.eh||Array.prototype.map)?function(a,b,c){h.R.assert(null!=a.length);return Array.prototype.map.call(a,b,c)}:function(a,b,c){for(var e=a.length,g=Array(e),k=h.Hb(a)?a.split(\"\"):a,m=0;m<e;m++)m in k&&(g[m]=b.call(c,k[m],m,a));return g};h.aa.reduce=h.mh&&(h.aa.eh||Array.prototype.reduce)?function(a,b,c,e){h.R.assert(null!=a.length);e&&(b=h.bind(b,e));return Array.prototype.reduce.call(a,b,c)}:function(a,b,c,e){var g=c;h.aa.forEach(a,function(c,m){g=b.call(e,g,c,m,a)});return g};\nh.aa.reduceRight=h.mh&&(h.aa.eh||Array.prototype.reduceRight)?function(a,b,c,e){h.R.assert(null!=a.length);h.R.assert(null!=b);e&&(b=h.bind(b,e));return Array.prototype.reduceRight.call(a,b,c)}:function(a,b,c,e){var g=c;h.aa.Fx(a,function(c,m){g=b.call(e,g,c,m,a)});return g};\nh.aa.some=h.mh&&(h.aa.eh||Array.prototype.some)?function(a,b,c){h.R.assert(null!=a.length);return Array.prototype.some.call(a,b,c)}:function(a,b,c){for(var e=a.length,g=h.Hb(a)?a.split(\"\"):a,k=0;k<e;k++)if(k in g&&b.call(c,g[k],k,a))return!0;return!1};h.aa.every=h.mh&&(h.aa.eh||Array.prototype.every)?function(a,b,c){h.R.assert(null!=a.length);return Array.prototype.every.call(a,b,c)}:function(a,b,c){for(var e=a.length,g=h.Hb(a)?a.split(\"\"):a,k=0;k<e;k++)if(k in g&&!b.call(c,g[k],k,a))return!1;return!0};\nh.aa.count=function(a,b,c){var e=0;h.aa.forEach(a,function(a,k,m){b.call(c,a,k,m)&&++e},c);return e};h.aa.find=function(a,b,c){b=h.aa.findIndex(a,b,c);return 0>b?null:h.Hb(a)?a.charAt(b):a[b]};h.aa.findIndex=function(a,b,c){for(var e=a.length,g=h.Hb(a)?a.split(\"\"):a,k=0;k<e;k++)if(k in g&&b.call(c,g[k],k,a))return k;return-1};h.aa.b6=function(a,b,c){b=h.aa.WK(a,b,c);return 0>b?null:h.Hb(a)?a.charAt(b):a[b]};\nh.aa.WK=function(a,b,c){for(var e=a.length,g=h.Hb(a)?a.split(\"\"):a,e=e-1;0<=e;e--)if(e in g&&b.call(c,g[e],e,a))return e;return-1};h.aa.contains=function(a,b){return 0<=h.aa.indexOf(a,b)};h.aa.Zc=function(a){return 0==a.length};h.aa.clear=function(a){if(!h.isArray(a))for(var b=a.length-1;0<=b;b--)delete a[b];a.length=0};h.aa.insert=function(a,b){h.aa.contains(a,b)||a.push(b)};h.aa.kB=function(a,b,c){h.aa.splice(a,c,0,b)};h.aa.v7=function(a,b,c){h.xs(h.aa.splice,a,c,0).apply(null,b)};\nh.aa.insertBefore=function(a,b,c){var e;2==arguments.length||0>(e=h.aa.indexOf(a,c))?a.push(b):h.aa.kB(a,b,e)};h.aa.remove=function(a,b){b=h.aa.indexOf(a,b);var c;(c=0<=b)&&h.aa.xk(a,b);return c};h.aa.Baa=function(a,b){b=h.aa.lastIndexOf(a,b);return 0<=b?(h.aa.xk(a,b),!0):!1};h.aa.xk=function(a,b){h.R.assert(null!=a.length);return 1==Array.prototype.splice.call(a,b,1).length};h.aa.Aaa=function(a,b,c){b=h.aa.findIndex(a,b,c);return 0<=b?(h.aa.xk(a,b),!0):!1};\nh.aa.yaa=function(a,b,c){var e=0;h.aa.Fx(a,function(g,k){b.call(c,g,k,a)&&h.aa.xk(a,k)&&e++});return e};h.aa.concat=function(a){return Array.prototype.concat.apply(Array.prototype,arguments)};h.aa.join=function(a){return Array.prototype.concat.apply(Array.prototype,arguments)};h.aa.toArray=function(a){var b=a.length;if(0<b){for(var c=Array(b),e=0;e<b;e++)c[e]=a[e];return c}return[]};h.aa.clone=h.aa.toArray;\nh.aa.extend=function(a,b){for(var c=1;c<arguments.length;c++){var e=arguments[c];if(h.Gd(e)){var g=a.length||0,k=e.length||0;a.length=g+k;for(var m=0;m<k;m++)a[g+m]=e[m]}else a.push(e)}};h.aa.splice=function(a,b,c,e){h.R.assert(null!=a.length);return Array.prototype.splice.apply(a,h.aa.slice(arguments,1))};h.aa.slice=function(a,b,c){h.R.assert(null!=a.length);return 2>=arguments.length?Array.prototype.slice.call(a,b):Array.prototype.slice.call(a,b,c)};\nh.aa.tP=function(a,b,c){b=b||a;var e=function(a){return h.mj(a)?\"o\"+h.VA(a):(typeof a).charAt(0)+a};c=c||e;for(var e={},g=0,k=0;k<a.length;){var m=a[k++],n=c(m);Object.prototype.hasOwnProperty.call(e,n)||(e[n]=!0,b[g++]=m)}b.length=g};h.aa.Sw=function(a,b,c){return h.aa.Tw(a,c||h.aa.fi,!1,b)};h.aa.F2=function(a,b,c){return h.aa.Tw(a,b,!0,void 0,c)};h.aa.Tw=function(a,b,c,e,g){for(var k=0,m=a.length,n;k<m;){var q=k+m>>1,v;v=c?b.call(g,a[q],q,a):b(e,a[q]);0<v?k=q+1:(m=q,n=!v)}return n?k:~k};\nh.aa.sort=function(a,b){a.sort(b||h.aa.fi)};h.aa.Lba=function(a,b){function c(a,b){return k(a.value,b.value)||a.index-b.index}for(var e=Array(a.length),g=0;g<a.length;g++)e[g]={index:g,value:a[g]};var k=b||h.aa.fi;h.aa.sort(e,c);for(g=0;g<a.length;g++)a[g]=e[g].value};h.aa.bW=function(a,b,c){var e=c||h.aa.fi;h.aa.sort(a,function(a,c){return e(b(a),b(c))})};h.aa.Cba=function(a,b,c){h.aa.bW(a,function(a){return a[b]},c)};\nh.aa.yB=function(a,b,c){b=b||h.aa.fi;for(var e=1;e<a.length;e++){var g=b(a[e-1],a[e]);if(0<g||0==g&&c)return!1}return!0};h.aa.ii=function(a,b,c){if(!h.Gd(a)||!h.Gd(b)||a.length!=b.length)return!1;var e=a.length;c=c||h.aa.tx;for(var g=0;g<e;g++)if(!c(a[g],b[g]))return!1;return!0};h.aa.I3=function(a,b,c){c=c||h.aa.fi;for(var e=Math.min(a.length,b.length),g=0;g<e;g++){var k=c(a[g],b[g]);if(0!=k)return k}return h.aa.fi(a.length,b.length)};h.aa.fi=function(a,b){return a>b?1:a<b?-1:0};\nh.aa.z7=function(a,b){return-h.aa.fi(a,b)};h.aa.tx=function(a,b){return a===b};h.aa.D2=function(a,b,c){c=h.aa.Sw(a,b,c);return 0>c?(h.aa.kB(a,b,-(c+1)),!0):!1};h.aa.E2=function(a,b,c){b=h.aa.Sw(a,b,c);return 0<=b?h.aa.xk(a,b):!1};h.aa.J2=function(a,b,c){for(var e={},g=0;g<a.length;g++){var k=a[g],m=b.call(c,k,g,a);h.Pe(m)&&(m=e[m]||(e[m]=[]),m.push(k))}return e};h.aa.C=function(a,b,c){var e={};h.aa.forEach(a,function(g,k){e[b.call(c,g,k,a)]=g});return e};\nh.aa.range=function(a,b,c){var e=[],g=0,k=a;c=c||1;void 0!==b&&(g=a,k=b);if(0>c*(k-g))return[];if(0<c)for(a=g;a<k;a+=c)e.push(a);else for(a=g;a>k;a+=c)e.push(a);return e};h.aa.repeat=function(a,b){for(var c=[],e=0;e<b;e++)c[e]=a;return c};h.aa.ZK=function(a){for(var b=[],c=0;c<arguments.length;c++){var e=arguments[c];if(h.isArray(e))for(var g=0;g<e.length;g+=8192)for(var k=h.aa.slice(e,g,g+8192),k=h.aa.ZK.apply(null,k),m=0;m<k.length;m++)b.push(k[m]);else b.push(e)}return b};\nh.aa.rotate=function(a,b){h.R.assert(null!=a.length);a.length&&(b%=a.length,0<b?Array.prototype.unshift.apply(a,a.splice(-b,b)):0>b&&Array.prototype.push.apply(a,a.splice(0,-b)));return a};h.aa.l9=function(a,b,c){h.R.assert(0<=b&&b<a.length);h.R.assert(0<=c&&c<a.length);b=Array.prototype.splice.call(a,b,1);Array.prototype.splice.call(a,c,0,b[0])};\nh.aa.zip=function(a){if(!arguments.length)return[];for(var b=[],c=arguments[0].length,e=1;e<arguments.length;e++)arguments[e].length<c&&(c=arguments[e].length);for(e=0;e<c;e++){for(var g=[],k=0;k<arguments.length;k++)g.push(arguments[k][e]);b.push(g)}return b};h.aa.shuffle=function(a,b){b=b||Math.random;for(var c=a.length-1;0<c;c--){var e=Math.floor(b()*(c+1)),g=a[c];a[c]=a[e];a[e]=g}};h.aa.i4=function(a,b){var c=[];h.aa.forEach(b,function(b){c.push(a[b])});return c};\nh.aa.Y3=function(a,b,c){return h.aa.concat.apply([],h.aa.map(a,b,c))};h.la.userAgent.platform={};h.la.userAgent.platform.mB=function(){return h.la.userAgent.util.lc(\"Android\")};h.la.userAgent.platform.js=function(){return h.la.userAgent.util.lc(\"iPod\")};h.la.userAgent.platform.hs=function(){return h.la.userAgent.util.lc(\"iPhone\")&&!h.la.userAgent.util.lc(\"iPod\")&&!h.la.userAgent.util.lc(\"iPad\")};h.la.userAgent.platform.gs=function(){return h.la.userAgent.util.lc(\"iPad\")};\nh.la.userAgent.platform.fs=function(){return h.la.userAgent.platform.hs()||h.la.userAgent.platform.gs()||h.la.userAgent.platform.js()};h.la.userAgent.platform.tB=function(){return h.la.userAgent.util.lc(\"Macintosh\")};h.la.userAgent.platform.wN=function(){return h.la.userAgent.util.lc(\"Linux\")};h.la.userAgent.platform.AB=function(){return h.la.userAgent.util.lc(\"Windows\")};h.la.userAgent.platform.oB=function(){return h.la.userAgent.util.lc(\"CrOS\")};\nh.la.userAgent.platform.getVersion=function(){var a=h.la.userAgent.util.nk(),b=\"\";h.la.userAgent.platform.AB()?(b=/Windows (?:NT|Phone) ([0-9.]+)/,b=(a=b.exec(a))?a[1]:\"0.0\"):h.la.userAgent.platform.fs()?(b=/(?:iPhone|iPod|iPad|CPU)\\s+OS\\s+(\\S+)/,b=(a=b.exec(a))&&a[1].replace(/_/g,\".\")):h.la.userAgent.platform.tB()?(b=/Mac OS X ([0-9_.]+)/,b=(a=b.exec(a))?a[1].replace(/_/g,\".\"):\"10\"):h.la.userAgent.platform.mB()?(b=/Android\\s+([^\\);]+)(\\)|;)/,b=(a=b.exec(a))&&a[1]):h.la.userAgent.platform.oB()&&(b=\n/(?:CrOS\\s+(?:i686|x86_64)\\s+([0-9.]+))/,b=(a=b.exec(a))&&a[1]);return b||\"\"};h.la.userAgent.platform.jm=function(a){return 0<=h.ca.yl(h.la.userAgent.platform.getVersion(),a)};h.cb={};h.cb.CC=function(a){for(var b=[],c=0,e=0;e<a.length;e++){for(var g=a.charCodeAt(e);255<g;)b[c++]=g&255,g>>=8;b[c++]=g}return b};h.cb.V2=function(a){if(8192>=a.length)return String.fromCharCode.apply(null,a);for(var b=\"\",c=0;c<a.length;c+=8192)var e=h.aa.slice(a,c,c+8192),b=b+String.fromCharCode.apply(null,e);return b};\nh.cb.U2=function(a){return h.aa.map(a,function(a){a=a.toString(16);return 1<a.length?a:\"0\"+a}).join(\"\")};h.cb.W6=function(a){h.R.assert(0==a.length%2,\"Key string length must be multiple of 2\");for(var b=[],c=0;c<a.length;c+=2)b.push(parseInt(a.substring(c,c+2),16));return b};\nh.cb.cca=function(a){for(var b=[],c=0,e=0;e<a.length;e++){var g=a.charCodeAt(e);128>g?b[c++]=g:(2048>g?b[c++]=g>>6|192:(55296==(g&64512)&&e+1<a.length&&56320==(a.charCodeAt(e+1)&64512)?(g=65536+((g&1023)<<10)+(a.charCodeAt(++e)&1023),b[c++]=g>>18|240,b[c++]=g>>12&63|128):b[c++]=g>>12|224,b[c++]=g>>6&63|128),b[c++]=g&63|128)}return b};\nh.cb.sda=function(a){for(var b=[],c=0,e=0;c<a.length;){var g=a[c++];if(128>g)b[e++]=String.fromCharCode(g);else if(191<g&&224>g){var k=a[c++];b[e++]=String.fromCharCode((g&31)<<6|k&63)}else if(239<g&&365>g){var k=a[c++],m=a[c++],n=a[c++],g=((g&7)<<18|(k&63)<<12|(m&63)<<6|n&63)-65536;b[e++]=String.fromCharCode(55296+(g>>10));b[e++]=String.fromCharCode(56320+(g&1023))}else k=a[c++],m=a[c++],b[e++]=String.fromCharCode((g&15)<<12|(k&63)<<6|m&63)}return b.join(\"\")};\nh.cb.Kda=function(a,b){h.R.assert(a.length==b.length,\"XOR array lengths must match\");for(var c=[],e=0;e<a.length;e++)c.push(a[e]^b[e]);return c};h.la.userAgent.fb={};h.la.userAgent.fb.LB=function(){return h.la.userAgent.util.lc(\"Opera\")};h.la.userAgent.fb.fO=function(){return h.la.userAgent.util.lc(\"Trident\")||h.la.userAgent.util.lc(\"MSIE\")};h.la.userAgent.fb.qs=function(){return h.la.userAgent.util.lc(\"Edge\")};h.la.userAgent.fb.eO=function(){return h.la.userAgent.util.lc(\"Firefox\")};\nh.la.userAgent.fb.MB=function(){return h.la.userAgent.util.lc(\"Safari\")&&!(h.la.userAgent.fb.os()||h.la.userAgent.fb.ps()||h.la.userAgent.fb.LB()||h.la.userAgent.fb.qs()||h.la.userAgent.fb.xB()||h.la.userAgent.util.lc(\"Android\"))};h.la.userAgent.fb.ps=function(){return h.la.userAgent.util.lc(\"Coast\")};h.la.userAgent.fb.gO=function(){return(h.la.userAgent.util.lc(\"iPad\")||h.la.userAgent.util.lc(\"iPhone\"))&&!h.la.userAgent.fb.MB()&&!h.la.userAgent.fb.os()&&!h.la.userAgent.fb.ps()&&h.la.userAgent.util.lc(\"AppleWebKit\")};\nh.la.userAgent.fb.os=function(){return(h.la.userAgent.util.lc(\"Chrome\")||h.la.userAgent.util.lc(\"CriOS\"))&&!h.la.userAgent.fb.qs()};h.la.userAgent.fb.dO=function(){return h.la.userAgent.util.lc(\"Android\")&&!(h.la.userAgent.fb.ds()||h.la.userAgent.fb.qB()||h.la.userAgent.fb.ks()||h.la.userAgent.fb.xB())};h.la.userAgent.fb.ks=h.la.userAgent.fb.LB;h.la.userAgent.fb.sB=h.la.userAgent.fb.fO;h.la.userAgent.fb.tk=h.la.userAgent.fb.qs;h.la.userAgent.fb.qB=h.la.userAgent.fb.eO;h.la.userAgent.fb.EN=h.la.userAgent.fb.MB;\nh.la.userAgent.fb.D7=h.la.userAgent.fb.ps;h.la.userAgent.fb.L7=h.la.userAgent.fb.gO;h.la.userAgent.fb.ds=h.la.userAgent.fb.os;h.la.userAgent.fb.lN=h.la.userAgent.fb.dO;h.la.userAgent.fb.xB=function(){return h.la.userAgent.util.lc(\"Silk\")};\nh.la.userAgent.fb.getVersion=function(){function a(a){a=h.aa.find(a,e);return c[a]||\"\"}var b=h.la.userAgent.util.nk();if(h.la.userAgent.fb.sB())return h.la.userAgent.fb.LL(b);var b=h.la.userAgent.util.Bx(b),c={};h.aa.forEach(b,function(a){var b=a[0];a=a[1];c[b]=a});var e=h.xs(h.object.dj,c);return h.la.userAgent.fb.ks()?a([\"Version\",\"Opera\"]):h.la.userAgent.fb.tk()?a([\"Edge\"]):h.la.userAgent.fb.ds()?a([\"Chrome\",\"CriOS\"]):(b=b[2])&&b[1]||\"\"};\nh.la.userAgent.fb.jm=function(a){return 0<=h.ca.yl(h.la.userAgent.fb.getVersion(),a)};h.la.userAgent.fb.LL=function(a){var b=/rv: *([\\d\\.]*)/.exec(a);if(b&&b[1])return b[1];var b=\"\",c=/MSIE +([\\d\\.]+)/.exec(a);if(c&&c[1])if(a=/Trident\\/(\\d.\\d)/.exec(a),\"7.0\"==c[1])if(a&&a[1])switch(a[1]){case \"4.0\":b=\"8.0\";break;case \"5.0\":b=\"9.0\";break;case \"6.0\":b=\"10.0\";break;case \"7.0\":b=\"11.0\"}else b=\"7.0\";else b=c[1];return b};h.la.userAgent.de={};h.la.userAgent.de.P7=function(){return h.la.userAgent.util.lc(\"Presto\")};\nh.la.userAgent.de.GN=function(){return h.la.userAgent.util.lc(\"Trident\")||h.la.userAgent.util.lc(\"MSIE\")};h.la.userAgent.de.tk=function(){return h.la.userAgent.util.lc(\"Edge\")};h.la.userAgent.de.zB=function(){return h.la.userAgent.util.hO(\"WebKit\")&&!h.la.userAgent.de.tk()};h.la.userAgent.de.sN=function(){return h.la.userAgent.util.lc(\"Gecko\")&&!h.la.userAgent.de.zB()&&!h.la.userAgent.de.GN()&&!h.la.userAgent.de.tk()};\nh.la.userAgent.de.getVersion=function(){var a=h.la.userAgent.util.nk();if(a){var a=h.la.userAgent.util.Bx(a),b=h.la.userAgent.de.yL(a);if(b)return\"Gecko\"==b[0]?h.la.userAgent.de.MM(a,\"Firefox\"):b[1];var a=a[0],c;if(a&&(c=a[2])&&(c=/Trident\\/([^\\s;]+)/.exec(c)))return c[1]}return\"\"};h.la.userAgent.de.yL=function(a){if(!h.la.userAgent.de.tk())return a[1];for(var b=0;b<a.length;b++){var c=a[b];if(\"Edge\"==c[0])return c}};\nh.la.userAgent.de.jm=function(a){return 0<=h.ca.yl(h.la.userAgent.de.getVersion(),a)};h.la.userAgent.de.MM=function(a,b){return(a=h.aa.find(a,function(a){return b==a[0]}))&&a[1]||\"\"};h.userAgent={};h.userAgent.jp=!1;h.userAgent.ip=!1;h.userAgent.Lt=!1;h.userAgent.Qt=!1;h.userAgent.lp=!1;h.userAgent.mp=!1;h.userAgent.UC=!1;h.userAgent.Fk=h.userAgent.jp||h.userAgent.ip||h.userAgent.Lt||h.userAgent.lp||h.userAgent.Qt||h.userAgent.mp;h.userAgent.KM=function(){return h.la.userAgent.util.nk()};\nh.userAgent.Dz=function(){return h.global.navigator||null};h.userAgent.cn=h.userAgent.Fk?h.userAgent.mp:h.la.userAgent.fb.ks();h.userAgent.Oh=h.userAgent.Fk?h.userAgent.jp:h.la.userAgent.fb.sB();h.userAgent.Rm=h.userAgent.Fk?h.userAgent.ip:h.la.userAgent.de.tk();h.userAgent.wX=h.userAgent.Rm||h.userAgent.Oh;h.userAgent.iu=h.userAgent.Fk?h.userAgent.Lt:h.la.userAgent.de.sN();h.userAgent.nn=h.userAgent.Fk?h.userAgent.Qt||h.userAgent.lp:h.la.userAgent.de.zB();\nh.userAgent.xN=function(){return h.userAgent.nn&&h.la.userAgent.util.lc(\"Mobile\")};h.userAgent.NY=h.userAgent.lp||h.userAgent.xN();h.userAgent.Np=h.userAgent.nn;h.userAgent.JK=function(){var a=h.userAgent.Dz();return a&&a.platform||\"\"};h.userAgent.gZ=h.userAgent.JK();h.userAgent.Nt=!1;h.userAgent.Rt=!1;h.userAgent.Mt=!1;h.userAgent.St=!1;h.userAgent.Dk=!1;h.userAgent.Dj=!1;h.userAgent.Cj=!1;h.userAgent.kp=!1;\nh.userAgent.nh=h.userAgent.Nt||h.userAgent.Rt||h.userAgent.Mt||h.userAgent.St||h.userAgent.Dk||h.userAgent.Dj||h.userAgent.Cj||h.userAgent.kp;h.userAgent.GY=h.userAgent.nh?h.userAgent.Nt:h.la.userAgent.platform.tB();h.userAgent.x_=h.userAgent.nh?h.userAgent.Rt:h.la.userAgent.platform.AB();h.userAgent.vN=function(){return h.la.userAgent.platform.wN()||h.la.userAgent.platform.oB()};h.userAgent.wY=h.userAgent.nh?h.userAgent.Mt:h.userAgent.vN();\nh.userAgent.KN=function(){var a=h.userAgent.Dz();return!!a&&h.ca.contains(a.appVersion||\"\",\"X11\")};h.userAgent.y_=h.userAgent.nh?h.userAgent.St:h.userAgent.KN();h.userAgent.TC=h.userAgent.nh?h.userAgent.Dk:h.la.userAgent.platform.mB();h.userAgent.OD=h.userAgent.nh?h.userAgent.Dj:h.la.userAgent.platform.hs();h.userAgent.ND=h.userAgent.nh?h.userAgent.Cj:h.la.userAgent.platform.gs();h.userAgent.jY=h.userAgent.nh?h.userAgent.kp:h.la.userAgent.platform.js();\nh.userAgent.iY=h.userAgent.nh?h.userAgent.Dj||h.userAgent.Cj||h.userAgent.kp:h.la.userAgent.platform.fs();h.userAgent.KK=function(){var a=\"\",b=h.userAgent.NM();b&&(a=b?b[1]:\"\");return h.userAgent.Oh&&(b=h.userAgent.Hy(),null!=b&&b>parseFloat(a))?String(b):a};\nh.userAgent.NM=function(){var a=h.userAgent.KM();if(h.userAgent.iu)return/rv\\:([^\\);]+)(\\)|;)/.exec(a);if(h.userAgent.Rm)return/Edge\\/([\\d\\.]+)/.exec(a);if(h.userAgent.Oh)return/\\b(?:MSIE|rv)[: ]([^\\);]+)(\\)|;)/.exec(a);if(h.userAgent.nn)return/WebKit\\/(\\S+)/.exec(a);if(h.userAgent.cn)return/(?:Version)[ \\/]?(\\S+)/.exec(a)};h.userAgent.Hy=function(){var a=h.global.document;return a?a.documentMode:void 0};h.userAgent.VERSION=h.userAgent.KK();h.userAgent.compare=function(a,b){return h.ca.yl(a,b)};\nh.userAgent.JN={};h.userAgent.jm=function(a){return h.userAgent.UC||h.Ih.cache(h.userAgent.JN,a,function(){return 0<=h.ca.yl(h.userAgent.VERSION,a)})};h.userAgent.U7=h.userAgent.jm;h.userAgent.qN=function(a){return Number(h.userAgent.jD)>=a};h.userAgent.G7=h.userAgent.qN;var ba;var ga=h.global.document,ud=h.userAgent.Hy();ba=ga&&h.userAgent.Oh?ud||(\"CSS1Compat\"==ga.compatMode?parseInt(h.userAgent.VERSION,10):5):void 0;h.userAgent.jD=ba;h.userAgent.product={};h.userAgent.product.Kt=!1;\nh.userAgent.product.Dj=!1;h.userAgent.product.Cj=!1;h.userAgent.product.Dk=!1;h.userAgent.product.Jt=!1;h.userAgent.product.Pt=!1;h.userAgent.product.Lj=h.userAgent.jp||h.userAgent.ip||h.userAgent.mp||h.userAgent.product.Kt||h.userAgent.product.Dj||h.userAgent.product.Cj||h.userAgent.product.Dk||h.userAgent.product.Jt||h.userAgent.product.Pt;h.userAgent.product.cn=h.userAgent.cn;h.userAgent.product.Oh=h.userAgent.Oh;h.userAgent.product.Rm=h.userAgent.Rm;\nh.userAgent.product.OX=h.userAgent.product.Lj?h.userAgent.product.Kt:h.la.userAgent.fb.qB();h.userAgent.product.tN=function(){return h.la.userAgent.platform.hs()||h.la.userAgent.platform.js()};h.userAgent.product.OD=h.userAgent.product.Lj?h.userAgent.product.Dj:h.userAgent.product.tN();h.userAgent.product.ND=h.userAgent.product.Lj?h.userAgent.product.Cj:h.la.userAgent.platform.gs();h.userAgent.product.TC=h.userAgent.product.Lj?h.userAgent.product.Dk:h.la.userAgent.fb.lN();\nh.userAgent.product.dX=h.userAgent.product.Lj?h.userAgent.product.Jt:h.la.userAgent.fb.ds();h.userAgent.product.FN=function(){return h.la.userAgent.fb.EN()&&!h.la.userAgent.platform.fs()};h.userAgent.product.Np=h.userAgent.product.Lj?h.userAgent.product.Pt:h.userAgent.product.FN();h.cb.pb={};h.cb.pb.xl=null;h.cb.pb.fo=null;h.cb.pb.gr=null;h.cb.pb.rp=\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\";h.cb.pb.cu=h.cb.pb.rp+\"+/\\x3d\";h.cb.pb.du=h.cb.pb.rp+\"-_.\";\nh.cb.pb.Ot=h.userAgent.iu||h.userAgent.nn&&!h.userAgent.product.Np||h.userAgent.cn;h.cb.pb.DD=h.cb.pb.Ot||\"function\"==typeof h.global.btoa;h.cb.pb.CD=h.cb.pb.Ot||!h.userAgent.product.Np&&!h.userAgent.Oh&&\"function\"==typeof h.global.atob;\nh.cb.pb.ur=function(a,b){h.R.assert(h.Gd(a),\"encodeByteArray takes an array as a parameter\");h.cb.pb.hm();b=b?h.cb.pb.gr:h.cb.pb.xl;for(var c=[],e=0;e<a.length;e+=3){var g=a[e],k=e+1<a.length,m=k?a[e+1]:0,n=e+2<a.length,q=n?a[e+2]:0,v=g>>2,g=(g&3)<<4|m>>4,m=(m&15)<<2|q>>6,q=q&63;n||(q=64,k||(m=64));c.push(b[v],b[g],b[m],b[q])}return c.join(\"\")};h.cb.pb.o5=function(a,b){return h.cb.pb.DD&&!b?h.global.btoa(a):h.cb.pb.ur(h.cb.CC(a),b)};\nh.cb.pb.T4=function(a,b){function c(a){e+=String.fromCharCode(a)}if(h.cb.pb.CD&&!b)return h.global.atob(a);var e=\"\";h.cb.pb.rr(a,c);return e};h.cb.pb.U4=function(a){function b(a){c.push(a)}var c=[];h.cb.pb.rr(a,b);return c};h.cb.pb.qx=function(a){function b(a){c[e++]=a}h.R.assert(!h.userAgent.Oh||h.userAgent.jm(\"10\"),\"Browser does not support typed arrays\");var c=new Uint8Array(Math.ceil(3*a.length/4)),e=0;h.cb.pb.rr(a,b);return c.subarray(0,e)};\nh.cb.pb.rr=function(a,b){function c(b){for(;e<a.length;){var c=a.charAt(e++),g=h.cb.pb.fo[c];if(null!=g)return g;if(!h.ca.Co(c))throw Error(\"Unknown base64 encoding at char: \"+c);}return b}h.cb.pb.hm();for(var e=0;;){var g=c(-1),k=c(0),m=c(64),n=c(64);if(64===n&&-1===g)break;g=g<<2|k>>4;b(g);64!=m&&(k=k<<4&240|m>>2,b(k),64!=n&&(m=m<<6&192|n,b(m)))}};\nh.cb.pb.hm=function(){if(!h.cb.pb.xl){h.cb.pb.xl={};h.cb.pb.fo={};h.cb.pb.gr={};for(var a=0;a<h.cb.pb.cu.length;a++)h.cb.pb.xl[a]=h.cb.pb.cu.charAt(a),h.cb.pb.fo[h.cb.pb.xl[a]]=a,h.cb.pb.gr[a]=h.cb.pb.du.charAt(a),a>=h.cb.pb.rp.length&&(h.cb.pb.fo[h.cb.pb.du.charAt(a)]=a)}};l.O={};l.O.Oc=0;l.O.Wc=0;l.O.zC=function(a){var b=a>>>0;a=Math.floor((a-b)/l.xa.Xf)>>>0;l.O.Oc=b;l.O.Wc=a};\nl.O.$o=function(a){var b=0>a;a=Math.abs(a);var c=a>>>0;a=Math.floor((a-c)/l.xa.Xf);a>>>=0;b&&(a=~a>>>0,c=~c>>>0,c+=1,4294967295<c&&(c=0,a++,4294967295<a&&(a=0)));l.O.Oc=c;l.O.Wc=a};l.O.Iba=function(a){var b=0>a;a=2*Math.abs(a);l.O.zC(a);a=l.O.Oc;var c=l.O.Wc;b&&(0==a?0==c?c=a=4294967295:(c--,a=4294967295):a--);l.O.Oc=a;l.O.Wc=c};\nl.O.cW=function(a){var b=0>a?1:0;a=b?-a:a;var c;0===a?0<1/a?(l.O.Wc=0,l.O.Oc=0):(l.O.Wc=0,l.O.Oc=2147483648):isNaN(a)?(l.O.Wc=0,l.O.Oc=2147483647):a>l.xa.vp?(l.O.Wc=0,l.O.Oc=(b<<31|2139095040)>>>0):a<l.xa.sD?(a=Math.round(a/Math.pow(2,-149)),l.O.Wc=0,l.O.Oc=(b<<31|a)>>>0):(c=Math.floor(Math.log(a)/Math.LN2),a*=Math.pow(2,-c),a=Math.round(a*l.xa.KE)&8388607,l.O.Wc=0,l.O.Oc=(b<<31|c+127<<23|a)>>>0)};\nl.O.dW=function(a){var b=0>a?1:0;a=b?-a:a;if(0===a)l.O.Wc=0<1/a?0:2147483648,l.O.Oc=0;else if(isNaN(a))l.O.Wc=2147483647,l.O.Oc=4294967295;else if(a>l.xa.wp)l.O.Wc=(b<<31|2146435072)>>>0,l.O.Oc=0;else if(a<l.xa.tD){var c=a/Math.pow(2,-1074);a=c/l.xa.Xf;l.O.Wc=(b<<31|a)>>>0;l.O.Oc=c>>>0}else{var e=Math.floor(Math.log(a)/Math.LN2);1024==e&&(e=1023);c=a*Math.pow(2,-e);a=c*l.xa.JE&1048575;c=c*l.xa.ev>>>0;l.O.Wc=(b<<31|e+1023<<20|a)>>>0;l.O.Oc=c}};\nl.O.ut=function(a){var b=a.charCodeAt(0),c=a.charCodeAt(1),e=a.charCodeAt(2),g=a.charCodeAt(3),k=a.charCodeAt(4),m=a.charCodeAt(5),n=a.charCodeAt(6);a=a.charCodeAt(7);l.O.Oc=b+(c<<8)+(e<<16)+(g<<24)>>>0;l.O.Wc=k+(m<<8)+(n<<16)+(a<<24)>>>0};l.O.km=function(a,b){return b*l.xa.Xf+a};l.O.ls=function(a,b){var c=b&2147483648;c&&(a=~a+1>>>0,b=~b>>>0,0==a&&(b=b+1>>>0));a=l.O.km(a,b);return c?-a:a};\nl.O.X7=function(a,b){var c=a&1;a=(a>>>1|b<<31)>>>0;b>>>=1;c&&(a=a+1>>>0,0==a&&(b=b+1>>>0));a=l.O.km(a,b);return c?-a:a};l.O.ON=function(a){var b=2*(a>>31)+1,c=a>>>23&255;a&=8388607;return 255==c?a?NaN:Infinity*b:0==c?b*Math.pow(2,-149)*a:b*Math.pow(2,c-150)*(a+Math.pow(2,23))};l.O.PN=function(a,b){var c=2*(b>>31)+1,e=b>>>20&2047;a=l.xa.Xf*(b&1048575)+a;return 2047==e?a?NaN:Infinity*c:0==e?c*Math.pow(2,-1074)*a:c*Math.pow(2,e-1075)*(a+l.xa.ev)};\nl.O.QN=function(a,b){var c=a>>>0&255,e=a>>>8&255,g=a>>>16&255;a=a>>>24&255;var k=b>>>0&255,m=b>>>8&255,n=b>>>16&255;b=b>>>24&255;return String.fromCharCode(c,e,g,a,k,m,n,b)};l.O.Ej=\"0123456789abcdef\".split(\"\");\nl.O.BB=function(a,b){function c(a){for(var b=1E7,c=0;7>c;c++){var b=b/10,e=a/b%10>>>0;if(0!=e||k)k=!0,m+=g[e]}}if(2097151>=b)return\"\"+(l.xa.Xf*b+a);var e=a&16777215;a=(a>>>24|b<<8)>>>0&16777215;b=b>>16&65535;e=e+6777216*a+6710656*b;a+=8147497*b;b*=2;1E7<=e&&(a+=Math.floor(e/1E7),e%=1E7);1E7<=a&&(b+=Math.floor(a/1E7),a%=1E7);var g=l.O.Ej,k=!1,m=\"\";(b||k)&&c(b);(a||k)&&c(a);(e||k)&&c(e);return m};\nl.O.RN=function(a,b){var c=b&2147483648;if(c){a=~a+1>>>0;var e=0==a?1:0;b=~b+e>>>0}a=l.O.BB(a,b);return c?\"-\"+a:a};l.O.YM=function(a,b){l.O.ut(a);a=l.O.Oc;var c=l.O.Wc;return b?l.O.RN(a,c):l.O.BB(a,c)};l.O.R6=function(a,b){for(var c=Array(a.length),e=0;e<a.length;e++)c[e]=l.O.YM(a[e],b);return c};\nl.O.FK=function(a){function b(a,b){for(var c=0;8>c&&(1!==a||0<b);c++)b=a*g[c]+b,g[c]=b&255,b>>>=8}function c(){for(var a=0;8>a;a++)g[a]=~g[a]&255}h.R.assert(0<a.length);var e=!1;\"-\"===a[0]&&(e=!0,a=a.slice(1));for(var g=[0,0,0,0,0,0,0,0],k=0;k<a.length;k++)b(10,l.O.Ej.indexOf(a[k]));e&&(c(),b(1,1));return String.fromCharCode.apply(null,g)};l.O.Gba=function(a){l.O.ut(l.O.FK(a))};\nl.O.S6=function(a){var b=Array(18);b[0]=\"0\";b[1]=\"x\";for(var c=0;8>c;c++){var e=a.charCodeAt(7-c);b[2*c+2]=l.O.Ej[e>>4];b[2*c+3]=l.O.Ej[e&15]}return a=b.join(\"\")};l.O.V6=function(a){a=a.toLowerCase();h.R.assert(18==a.length);h.R.assert(\"0\"==a[0]);h.R.assert(\"x\"==a[1]);for(var b=\"\",c=0;8>c;c++)var e=l.O.Ej.indexOf(a[2*c+2]),g=l.O.Ej.indexOf(a[2*c+3]),b=String.fromCharCode(16*e+g)+b;return b};l.O.T6=function(a,b){l.O.ut(a);a=l.O.Oc;var c=l.O.Wc;return b?l.O.ls(a,c):l.O.km(a,c)};\nl.O.Y9=function(a){l.O.$o(a);return l.O.QN(l.O.Oc,l.O.Wc)};l.O.s4=function(a,b,c){for(var e=0,g=b;g<c;g++)e+=a[g]>>7;return c-b-e};l.O.r4=function(a,b,c,e){var g=0;e=8*e+l.xa.kb.Xe;if(128>e)for(;b<c&&a[b++]==e;)for(g++;;){var k=a[b++];if(0==(k&128))break}else for(;b<c;){for(k=e;128<k;){if(a[b]!=(k&127|128))return g;b++;k>>=7}if(a[b++]!=k)break;for(g++;k=a[b++],0!=(k&128););}return g};\nl.O.kx=function(a,b,c,e,g){var k=0;if(128>e)for(;b<c&&a[b++]==e;)k++,b+=g;else for(;b<c;){for(var m=e;128<m;){if(a[b++]!=(m&127|128))return k;m>>=7}if(a[b++]!=m)break;k++;b+=g}return k};l.O.n4=function(a,b,c,e){e=8*e+l.xa.kb.hh;return l.O.kx(a,b,c,e,4)};l.O.o4=function(a,b,c,e){e=8*e+l.xa.kb.ih;return l.O.kx(a,b,c,e,8)};\nl.O.m4=function(a,b,c,e){var g=0;for(e=8*e+l.xa.kb.jg;b<c;){for(var k=e;128<k;){if(a[b++]!=(k&127|128))return g;k>>=7}if(a[b++]!=k)break;g++;for(var m=0,n=1;k=a[b++],m+=(k&127)*n,n*=128,0!=(k&128););b+=m}return g};l.O.R4=function(a){var b='\"';if(a){a=l.O.fr(a);for(var c=0;c<a.length;c++)b+=\"\\\\x\",16>a[c]&&(b+=\"0\"),b+=a[c].toString(16)}return b+'\"'};l.O.S4=function(a){return h.Hb(a)?h.ca.quote(a):a.toString()};\nl.O.CC=function(a){for(var b=new Uint8Array(a.length),c=0;c<a.length;c++){var e=a.charCodeAt(c);if(255<e)throw Error(\"Conversion error: string contains codepoint outside of byte range\");b[c]=e}return b};l.O.fr=function(a){if(a.constructor===Uint8Array)return a;if(a.constructor===ArrayBuffer)return new Uint8Array(a);if(a.constructor===Array)return new Uint8Array(a);if(a.constructor===String)return h.cb.pb.qx(a);h.R.fail(\"Type not convertible to Uint8Array.\");return new Uint8Array(0)};\nl.Di=function(a,b,c,e,g){this.qo=a;this.Ex=b;this.ctor=c;this.xt=e;this.Eo=g};l.Fj=function(a,b,c,e,g,k){this.Dx=a;this.br=b;this.cr=c;this.Rw=e;this.UJ=g;this.AN=k};l.Di.prototype.uk=function(){return!!this.ctor};l.u=function(){};l.u.ha=!0;l.u.VX=!h.$t;l.u.AD=!0;l.u.VC=!1;l.u.$m=!0;l.u.Vk=\"function\"==typeof Uint8Array;l.u.Sl=function(a,b){return b+a.Iw};\nl.u.initialize=function(a,b,c,e,g,k){a.tb=l.u.$m?null:{};b||(b=c?[c]:[]);a.OB=c?String(c):void 0;a.Iw=0===c?-1:0;a.aa=b;l.u.iO(a,e);a.lo={};if(g)for(b=0;b<g.length;b++)c=g[b],c<a.wk?(c=l.u.Sl(a,c),a.aa[c]=a.aa[c]||(l.u.$m?l.u.Ik:[])):a.Oe[c]=a.Oe[c]||(l.u.$m?l.u.Ik:[]);k&&k.length&&h.aa.forEach(k,h.xs(l.u.ex,a))};l.u.Ik=h.Mh&&Object.freeze?Object.freeze([]):[];l.u.oN=function(a){return l.u.VC?a instanceof Array:h.isArray(a)};\nl.u.iO=function(a,b){if(a.aa.length){var c=a.aa.length-1,e=a.aa[c];if(e&&\"object\"==typeof e&&!l.u.oN(e)&&!(l.u.Vk&&e instanceof Uint8Array)){a.wk=c-a.Iw;a.Oe=e;return}}-1<b?(a.wk=b,b=l.u.Sl(a,b),a.Oe=l.u.$m?null:a.aa[b]={}):a.wk=Number.MAX_VALUE};l.u.kO=function(a){var b=l.u.Sl(a,a.wk);a.aa[b]||(a.Oe=a.aa[b]={})};l.u.Ka=function(a,b,c){for(var e=[],g=0;g<a.length;g++)e[g]=b.call(a[g],c,a[g]);return e};\nl.u.pW=function(a,b,c,e,g){for(var k in c){var m=c[k],n=e.call(a,m);if(n){for(var q in m.Ex)if(m.Ex.hasOwnProperty(q))break;b[q]=m.xt?m.Eo?l.u.Ka(n,m.xt,g):m.xt(g,n):n}}};\nl.u.XP=function(a,b,c,e){for(var g in c){var k=c[g],m=k.Dx;if(!k.cr)throw Error(\"Message extension present that was generated without binary serialization support\");var n=e.call(a,m);if(n)if(m.uk())if(k.Rw)k.cr.call(b,m.qo,n,k.Rw);else throw Error(\"Message extension present holding submessage without binary support enabled, and message is being serialized to binary format\");else k.cr.call(b,m.qo,n)}};\nl.u.kP=function(a,b,c,e,g){var k=c[b.ka];if(k){c=k.Dx;if(!k.br)throw Error(\"Deserializing extension whose generated code does not support binary format\");var m;c.uk()?(m=new c.ctor,k.br.call(b,m,k.UJ)):m=k.br.call(b);c.Eo&&!k.AN?(b=e.call(a,c))?b.push(m):g.call(a,c,[m]):g.call(a,c,m)}else b.ea()};l.u.D=function(a,b){if(b<a.wk){b=l.u.Sl(a,b);var c=a.aa[b];return c===l.u.Ik?a.aa[b]=[]:c}c=a.Oe[b];return c===l.u.Ik?a.Oe[b]=[]:c};l.u.Na=function(a,b){a=l.u.D(a,b);return null==a?a:+a};\nl.u.gb=function(a,b){var c=l.u.D(a,b);a.lo||(a.lo={});if(!a.lo[b]){for(var e=0;e<c.length;e++)c[e]=+c[e];a.lo[b]=!0}return c};l.u.ao=function(a){if(null==a||h.Hb(a))return a;if(l.u.Vk&&a instanceof Uint8Array)return h.cb.pb.ur(a);h.R.fail(\"Cannot coerce to b64 string: \"+h.df(a));return null};l.u.hr=function(a){if(null==a||a instanceof Uint8Array)return a;if(h.Hb(a))return h.cb.pb.qx(a);h.R.fail(\"Cannot coerce to Uint8Array: \"+h.df(a));return null};\nl.u.W2=function(a){l.u.Kw(a);return!a.length||h.Hb(a[0])?a:h.aa.map(a,l.u.ao)};l.u.X2=function(a){l.u.Kw(a);return!a.length||a[0]instanceof Uint8Array?a:h.aa.map(a,l.u.hr)};l.u.Kw=function(a){if(h.Mh&&a&&1<a.length){var b=h.df(a[0]);h.aa.forEach(a,function(a){h.df(a)!=b&&h.R.fail(\"Inconsistent type in JSPB repeated field array. Got \"+h.df(a)+\" expected \"+b)})}};l.u.va=function(a,b,c){a=l.u.D(a,b);return null==a?c:a};l.u.s6=l.u.va;\nl.u.z6=function(a,b,c,e){a.tb||(a.tb={});if(b in a.tb)return a.tb[b];if(!c)return c=l.u.D(a,b),c||(c=[],l.u.J(a,b,c)),a.tb[b]=new l.Map(c,e)};l.u.J=function(a,b,c){b<a.wk?a.aa[l.u.Sl(a,b)]=c:a.Oe[b]=c};l.u.ib=function(a,b,c,e){a=l.u.D(a,b);void 0!=e?a.splice(e,0,c):a.push(c)};l.u.vC=function(a,b,c,e){(c=l.u.ex(a,c))&&c!==b&&void 0!==e&&(a.tb&&c in a.tb&&(a.tb[c]=void 0),l.u.J(a,c,void 0));l.u.J(a,b,e)};\nl.u.ex=function(a,b){var c,e;h.aa.forEach(b,function(b){var g=l.u.D(a,b);h.Ch(g)&&(c=b,e=g,l.u.J(a,b,void 0))});return c?(l.u.J(a,c,e),c):0};l.u.sa=function(a,b,c,e){a.tb||(a.tb={});if(!a.tb[c]){var g=l.u.D(a,c);if(e||g)a.tb[c]=new b(g)}return a.tb[c]};l.u.Ma=function(a,b,c){l.u.NC(a,b,c);b=a.tb[c];b==l.u.Ik&&(b=a.tb[c]=[]);return b};l.u.NC=function(a,b,c){a.tb||(a.tb={});if(!a.tb[c]){for(var e=l.u.D(a,c),g=[],k=0;k<e.length;k++)g[k]=new b(e[k]);a.tb[c]=g}};\nl.u.Ca=function(a,b,c){a.tb||(a.tb={});var e=c?c.toArray():c;a.tb[b]=c;l.u.J(a,b,e)};l.u.Nc=function(a,b,c,e){a.tb||(a.tb={});var g=e?e.toArray():e;a.tb[b]=e;l.u.vC(a,b,c,g)};l.u.mt=function(a,b,c){a.tb||(a.tb={});c=c||[];for(var e=[],g=0;g<c.length;g++)e[g]=c[g].toArray();a.tb[b]=c;l.u.J(a,b,e)};l.u.La=function(a,b,c,e,g){l.u.NC(a,e,b);var k=a.tb[b];k||(k=a.tb[b]=[]);c=c?c:new e;a=l.u.D(a,b);void 0!=g?(k.splice(g,0,c),a.splice(g,0,c.toArray())):(k.push(c),a.push(c.toArray()));return c};\nl.u.Cca=function(a,b,c,e){for(var g={},k=0;k<a.length;k++)g[b.call(a[k])]=c?c.call(a[k],e,a[k]):a[k];return g};l.u.prototype.DC=function(){if(this.tb)for(var a in this.tb){var b=this.tb[a];if(h.isArray(b))for(var c=0;c<b.length;c++)b[c]&&b[c].toArray();else b&&b.toArray()}};l.u.prototype.toArray=function(){this.DC();return this.aa};l.u.bn=h.global.JSON&&h.global.JSON.stringify||\"object\"===typeof JSON&&JSON.stringify;\nl.u.prototype.serialize=l.u.Vk?function(){h.R.assert(l.u.bn);var a=Uint8Array.prototype.toJSON;Uint8Array.prototype.toJSON=function(){return h.cb.pb.ur(this)};try{var b=l.u.bn.call(null,this.toArray(),l.u.Js)}finally{Uint8Array.prototype.toJSON=a}return b}:l.u.bn?function(){return l.u.bn.call(null,this.toArray(),l.u.Js)}:function(){return h.json.serialize(this.toArray(),l.u.Js)};l.u.Js=function(a,b){if(h.ni(b)){if(isNaN(b))return\"NaN\";if(Infinity===b)return\"Infinity\";if(-Infinity===b)return\"-Infinity\"}return b};\nl.u.K=function(a,b){a=new a(h.json.yW(b));h.R.Xq(a,l.u);return a};l.u.R2=function(a){var b=l.u.eC[a[0]];if(!b)throw Error(\"Unknown JsPb message type: \"+a[0]);return new b(a)};l.u.AD&&(l.u.prototype.toString=function(){this.DC();return this.aa.toString()});\nl.u.prototype.getExtension=function(a){if(this.Oe){this.tb||(this.tb={});var b=a.qo;if(a.Eo){if(a.uk())return this.tb[b]||(this.tb[b]=h.aa.map(this.Oe[b]||[],function(b){return new a.ctor(b)})),this.tb[b]}else if(a.uk())return!this.tb[b]&&this.Oe[b]&&(this.tb[b]=new a.ctor(this.Oe[b])),this.tb[b];return this.Oe[b]}};\nl.u.prototype.yR=function(a,b){var c=this;c.tb||(c.tb={});l.u.kO(c);var e=a.qo;a.Eo?(b=b||[],a.uk()?(c.tb[e]=b,c.Oe[e]=h.aa.map(b,function(a){return a.toArray()})):c.Oe[e]=b):a.uk()?(c.tb[e]=b,c.Oe[e]=b?b.toArray():b):c.Oe[e]=b;return c};l.u.a5=function(a,b){if(!(a instanceof b.constructor))throw Error(\"Messages have different types.\");var c=a.toArray();b=b.toArray();var e=[],g=0,k=c.length>b.length?c.length:b.length;a.OB&&(e[0]=a.OB,g=1);for(;g<k;g++)l.u.jo(c[g],b[g])||(e[g]=b[g]);return new a.constructor(e)};\nl.u.ii=function(a,b){return a==b||!(!a||!b)&&a instanceof b.constructor&&l.u.jo(a.toArray(),b.toArray())};l.u.bx=function(a,b){a=a||{};b=b||{};var c={},e;for(e in a)c[e]=0;for(e in b)c[e]=0;for(e in c)if(!l.u.jo(a[e],b[e]))return!1;return!0};\nl.u.jo=function(a,b){if(a==b)return!0;if(!h.mj(a)||!h.mj(b)||a.constructor!=b.constructor)return!1;if(l.u.Vk&&a.constructor===Uint8Array){if(a.length!=b.length)return!1;for(var c=0;c<a.length;c++)if(a[c]!=b[c])return!1;return!0}if(a.constructor===Array){for(var e=void 0,g=void 0,k=Math.max(a.length,b.length),c=0;c<k;c++){var m=a[c],n=b[c];m&&m.constructor==Object&&(h.R.assert(void 0===e),h.R.assert(c===a.length-1),e=m,m=void 0);n&&n.constructor==Object&&(h.R.assert(void 0===g),h.R.assert(c===b.length-\n1),g=n,n=void 0);if(!l.u.jo(m,n))return!1}return e||g?(e=e||{},g=g||{},l.u.bx(e,g)):!0}if(a.constructor===Object)return l.u.bx(a,b);throw Error(\"Invalid type in JSPB array\");};l.u.prototype.ho=function(){return l.u.ho(this)};l.u.prototype.clone=function(){return l.u.ho(this)};l.u.clone=function(a){return l.u.ho(a)};l.u.ho=function(a){return new a.constructor(l.u.ir(a.toArray()))};\nl.u.j4=function(a,b){h.R.Xq(a,l.u);h.R.Xq(b,l.u);h.R.assert(a.constructor==b.constructor,\"Copy source and target message should have the same type.\");a=l.u.clone(a);for(var c=b.toArray(),e=a.toArray(),g=c.length=0;g<e.length;g++)c[g]=e[g];b.tb=a.tb;b.Oe=a.Oe};\nl.u.ir=function(a){var b;if(h.isArray(a)){for(var c=Array(a.length),e=0;e<a.length;e++)null!=(b=a[e])&&(c[e]=\"object\"==typeof b?l.u.ir(b):b);return c}if(l.u.Vk&&a instanceof Uint8Array)return new Uint8Array(a);c={};for(e in a)null!=(b=a[e])&&(c[e]=\"object\"==typeof b?l.u.ir(b):b);return c};l.u.taa=function(a,b){l.u.eC[a]=b;b.I8=a};l.u.eC={};l.u.nj={};l.u.oi={};l.fh=function(a,b,c){this.gk=this.vs=this.vb=null;this.Wa=0;this.pi=null;this.vl=!0;this.hm(a,b,c)};\nl.fh.prototype.hm=function(a,b,c){a&&b&&(this.vb=a,this.vs=b);this.gk=c||null;this.Wa=0;this.pi=null;this.vl=!this.vb&&!this.gk;this.next()};l.fh.Nf=[];l.fh.ck=function(a,b,c){if(l.fh.Nf.length){var e=l.fh.Nf.pop();e.hm(a,b,c);return e}return new l.fh(a,b,c)};d=l.fh.prototype;d.Br=function(){this.clear();100>l.fh.Nf.length&&l.fh.Nf.push(this)};d.clear=function(){this.vb&&this.vb.Br();this.gk=this.vs=this.vb=null;this.Wa=0;this.pi=null;this.vl=!0};d.get=function(){return this.pi};d.Yq=function(){return this.vl};\nd.next=function(){var a=this.pi;this.vb?this.vb.Yq()?(this.pi=null,this.vl=!0):this.pi=this.vs.call(this.vb):this.gk&&(this.Wa==this.gk.length?(this.pi=null,this.vl=!0):this.pi=this.gk[this.Wa++]);return a};l.vg=function(a,b,c){this.Ed=null;this.Em=this.Fm=this.Wa=this.$e=this.yj=0;this.tg=!1;a&&this.vm(a,b,c)};l.vg.Nf=[];l.vg.ck=function(a,b,c){if(l.vg.Nf.length){var e=l.vg.Nf.pop();a&&e.vm(a,b,c);return e}return new l.vg(a,b,c)};d=l.vg.prototype;\nd.Br=function(){this.clear();100>l.vg.Nf.length&&l.vg.Nf.push(this)};d.clone=function(){return l.vg.ck(this.Ed,this.yj,this.$e-this.yj)};d.clear=function(){this.Ed=null;this.Wa=this.$e=this.yj=0;this.tg=!1};d.vm=function(a,b,c){this.Ed=l.O.fr(a);this.yj=h.Pe(b)?b:0;this.$e=h.Pe(c)?this.yj+c:this.Ed.length;this.Wa=this.yj};d.setEnd=function(a){this.$e=a};d.reset=function(){this.Wa=this.yj};d.Ol=function(){return this.Wa};d.YQ=function(a){this.Wa=a};\nd.advance=function(a){this.Wa+=a;h.R.assert(this.Wa<=this.$e)};d.Yq=function(){return this.Wa==this.$e};d.getError=function(){return this.tg||0>this.Wa||this.Wa>this.$e};\nd.dC=function(){for(var a,b=0,c=0,e=0;4>e;e++)if(a=this.Ed[this.Wa++],b|=(a&127)<<7*e,128>a){this.Fm=b>>>0;this.Em=0;return}a=this.Ed[this.Wa++];b|=(a&127)<<28;c|=(a&127)>>4;if(128>a)this.Fm=b>>>0,this.Em=c>>>0;else{for(e=0;5>e;e++)if(a=this.Ed[this.Wa++],c|=(a&127)<<7*e+3,128>a){this.Fm=b>>>0;this.Em=c>>>0;return}h.R.fail(\"Failed to read varint, encoding is invalid.\");this.tg=!0}};d.$V=function(){for(;this.Ed[this.Wa]&128;)this.Wa++;this.Wa++};\nd.Hh=function(){var a,b=this.Ed;a=b[this.Wa+0];var c=a&127;if(128>a)return this.Wa+=1,h.R.assert(this.Wa<=this.$e),c;a=b[this.Wa+1];c|=(a&127)<<7;if(128>a)return this.Wa+=2,h.R.assert(this.Wa<=this.$e),c;a=b[this.Wa+2];c|=(a&127)<<14;if(128>a)return this.Wa+=3,h.R.assert(this.Wa<=this.$e),c;a=b[this.Wa+3];c|=(a&127)<<21;if(128>a)return this.Wa+=4,h.R.assert(this.Wa<=this.$e),c;a=b[this.Wa+4];c|=(a&15)<<28;if(128>a)return h.R.assert(0==(a&240)),this.Wa+=5,h.R.assert(this.Wa<=this.$e),c>>>0;h.R.assert(240==\n(a&240));h.R.assert(255==b[this.Wa+5]);h.R.assert(255==b[this.Wa+6]);h.R.assert(255==b[this.Wa+7]);h.R.assert(255==b[this.Wa+8]);h.R.assert(1==b[this.Wa+9]);this.Wa+=10;h.R.assert(this.Wa<=this.$e);return c};d.bC=l.vg.prototype.Hh;d.nP=function(){this.dC();return l.O.km(this.Fm,this.Em)};d.cC=function(){this.dC();return l.O.ls(this.Fm,this.Em)};\nd.Jg=function(){var a=this.Ed[this.Wa+0],b=this.Ed[this.Wa+1],c=this.Ed[this.Wa+2],e=this.Ed[this.Wa+3];this.Wa+=4;h.R.assert(this.Wa<=this.$e);return(a<<0|b<<8|c<<16|e<<24)>>>0};d.ee=function(){var a=this.Jg(),b=this.Jg();return l.O.km(a,b)};d.Ya=function(){var a=this.Ed[this.Wa+0],b=this.Ed[this.Wa+1],c=this.Ed[this.Wa+2],e=this.Ed[this.Wa+3];this.Wa+=4;h.R.assert(this.Wa<=this.$e);return a<<0|b<<8|c<<16|e<<24};d.ad=function(){var a=this.Jg(),b=this.Jg();return l.O.ls(a,b)};\nd.ti=function(){var a=this.Jg();return l.O.ON(a,0)};d.pa=function(){var a=this.Jg(),b=this.Jg();return l.O.PN(a,b)};d.vf=function(){return!!this.Ed[this.Wa++]};d.we=function(){return this.bC()};\nd.Aa=function(a){var b=this.Ed,c=this.Wa;a=c+a;for(var e=[],g=\"\";c<a;){var k=b[c++];if(128>k)e.push(k);else if(192>k)continue;else if(224>k){var m=b[c++];e.push((k&31)<<6|m&63)}else if(240>k){var m=b[c++],n=b[c++];e.push((k&15)<<12|(m&63)<<6|n&63)}else if(248>k){var m=b[c++],n=b[c++],q=b[c++],m=(k&7)<<18|(m&63)<<12|(n&63)<<6|q&63,m=m-65536,k=(m&1023)+56320,m=(m>>10&1023)+55296;e.push(m,k)}8192<=e.length&&(g+=String.fromCharCode.apply(null,e),e.length=0)}g+=String.fromCharCode.apply(null,e);this.Wa=\nc;return g};d.qm=function(a){if(0>a||this.Wa+a>this.Ed.length)return this.tg=!0,h.R.fail(\"Invalid byte length!\"),new Uint8Array(0);var b=this.Ed.subarray(this.Wa,this.Wa+a);this.Wa+=a;h.R.assert(this.Wa<=this.$e);return b};l.Tt=function(){this.hc=[]};d=l.Tt.prototype;d.length=function(){return this.hc.length};d.end=function(){var a=this.hc;this.hc=[];return a};\nd.QC=function(a,b){h.R.assert(a==Math.floor(a));h.R.assert(b==Math.floor(b));h.R.assert(0<=a&&a<l.xa.Xf);for(h.R.assert(0<=b&&b<l.xa.Xf);0<b||127<a;)this.hc.push(a&127|128),a=(a>>>7|b<<25)>>>0,b>>>=7;this.hc.push(a)};d.MW=function(a,b){h.R.assert(a==Math.floor(a));h.R.assert(b==Math.floor(b));h.R.assert(0<=a&&a<l.xa.Xf);h.R.assert(0<=b&&b<l.xa.Xf);this.Pg(a);this.Pg(b)};d.Nm=function(a){h.R.assert(a==Math.floor(a));for(h.R.assert(0<=a&&a<l.xa.Xf);127<a;)this.hc.push(a&127|128),a>>>=7;this.hc.push(a)};\nd.Ft=function(a){h.R.assert(a==Math.floor(a));h.R.assert(a>=-l.xa.Tg&&a<l.xa.Tg);if(0<=a)this.Nm(a);else{for(var b=0;9>b;b++)this.hc.push(a&127|128),a>>=7;this.hc.push(1)}};d.OW=function(a){h.R.assert(a==Math.floor(a));h.R.assert(0<=a&&a<l.xa.Rp);l.O.$o(a);this.QC(l.O.Oc,l.O.Wc)};d.LW=function(a){h.R.assert(a==Math.floor(a));h.R.assert(a>=-l.xa.Mj&&a<l.xa.Mj);l.O.$o(a);this.QC(l.O.Oc,l.O.Wc)};\nd.Pg=function(a){h.R.assert(a==Math.floor(a));h.R.assert(0<=a&&a<l.xa.Xf);this.hc.push(a>>>0&255);this.hc.push(a>>>8&255);this.hc.push(a>>>16&255);this.hc.push(a>>>24&255)};d.ye=function(a){h.R.assert(a==Math.floor(a));h.R.assert(0<=a&&a<l.xa.Rp);l.O.zC(a);this.Pg(l.O.Oc);this.Pg(l.O.Wc)};d.$a=function(a){h.R.assert(a==Math.floor(a));h.R.assert(a>=-l.xa.Tg&&a<l.xa.Tg);this.hc.push(a>>>0&255);this.hc.push(a>>>8&255);this.hc.push(a>>>16&255);this.hc.push(a>>>24&255)};\nd.td=function(a){h.R.assert(a==Math.floor(a));h.R.assert(a>=-l.xa.Mj&&a<l.xa.Mj);l.O.$o(a);this.MW(l.O.Oc,l.O.Wc)};d.vi=function(a){h.R.assert(a>=-l.xa.vp&&a<=l.xa.vp);l.O.cW(a);this.Pg(l.O.Oc)};d.ya=function(a){h.R.assert(a>=-l.xa.wp&&a<=l.xa.wp);l.O.dW(a);this.Pg(l.O.Oc);this.Pg(l.O.Wc)};d.kf=function(a){h.R.assert(h.sk(a));this.hc.push(a?1:0)};d.xe=function(a){h.R.assert(a==Math.floor(a));h.R.assert(a>=-l.xa.Tg&&a<l.xa.Tg);this.Ft(a)};d.fp=function(a){this.hc.push.apply(this.hc,a)};\nd.Ja=function(a){for(var b=this.hc.length,c=0;c<a.length;c++){var e=a.charCodeAt(c);if(128>e)this.hc.push(e);else if(2048>e)this.hc.push(e>>6|192),this.hc.push(e&63|128);else if(65536>e)if(55296<=e&&56319>=e&&c+1<a.length){var g=a.charCodeAt(c+1);56320<=g&&57343>=g&&(e=1024*(e-55296)+g-56320+65536,this.hc.push(e>>18|240),this.hc.push(e>>12&63|128),this.hc.push(e>>6&63|128),this.hc.push(e&63|128),c++)}else this.hc.push(e>>12|224),this.hc.push(e>>6&63|128),this.hc.push(e&63|128)}return a=this.hc.length-\nb};l.ba=function(a,b,c){this.vb=l.vg.ck(a,b,c);this.ka=l.xa.Tm;this.Dc=l.xa.kb.Gj;this.tg=!1};l.ba.Nf=[];l.ba.ck=function(a,b,c){if(l.ba.Nf.length){var e=l.ba.Nf.pop();a&&e.vb.vm(a,b,c);return e}return new l.ba(a,b,c)};d=l.ba.prototype;d.ck=l.ba.ck;d.Br=function(){this.vb.clear();this.ka=l.xa.Tm;this.Dc=l.xa.kb.Gj;this.tg=!1;100>l.ba.Nf.length&&l.ba.Nf.push(this)};d.Ol=function(){return this.vb.Ol()};d.ga=function(){return this.Dc==l.xa.kb.Jk};d.getError=function(){return this.tg||this.vb.getError()};\nd.vm=function(a,b,c){this.vb.vm(a,b,c);this.ka=l.xa.Tm;this.Dc=l.xa.kb.Gj};d.reset=function(){this.vb.reset();this.ka=l.xa.Tm;this.Dc=l.xa.kb.Gj};d.advance=function(a){this.vb.advance(a)};d.fa=function(){if(this.vb.Yq())return!1;if(this.getError())return h.R.fail(\"Decoder hit an error\"),!1;var a=this.vb.Hh(),b=a>>>3,a=a&7;if(a!=l.xa.kb.Xe&&a!=l.xa.kb.hh&&a!=l.xa.kb.ih&&a!=l.xa.kb.jg&&a!=l.xa.kb.Tk&&a!=l.xa.kb.Jk)return h.R.fail(\"Invalid wire type\"),this.tg=!0,!1;this.ka=b;this.Dc=a;return!0};\nd.aW=function(){this.Dc!=l.xa.kb.Xe?(h.R.fail(\"Invalid wire type for skipVarintField\"),this.ea()):this.vb.$V()};d.WV=function(){if(this.Dc!=l.xa.kb.jg)h.R.fail(\"Invalid wire type for skipDelimitedField\"),this.ea();else{var a=this.vb.Hh();this.vb.advance(a)}};d.XV=function(){this.Dc!=l.xa.kb.hh?(h.R.fail(\"Invalid wire type for skipFixed32Field\"),this.ea()):this.vb.advance(4)};d.YV=function(){this.Dc!=l.xa.kb.ih?(h.R.fail(\"Invalid wire type for skipFixed64Field\"),this.ea()):this.vb.advance(8)};\nd.ZV=function(){var a=[this.ka];do{if(!this.fa()){h.R.fail(\"Unmatched start-group tag: stream EOF\");this.tg=!0;break}if(this.Dc==l.xa.kb.Tk)a.push(this.ka);else if(this.Dc==l.xa.kb.Jk&&this.ka!=a.pop()){h.R.fail(\"Unmatched end-group tag\");this.tg=!0;break}}while(0<a.length)};d.ea=function(){switch(this.Dc){case l.xa.kb.Xe:this.aW();break;case l.xa.kb.ih:this.YV();break;case l.xa.kb.jg:this.WV();break;case l.xa.kb.hh:this.XV();break;case l.xa.kb.Tk:this.ZV();break;default:h.R.fail(\"Invalid wire encoding for field.\")}};\nd.T=function(a,b){h.R.assert(this.Dc==l.xa.kb.jg);var c=this.vb.$e,e=this.vb.Hh(),e=this.vb.Ol()+e;this.vb.setEnd(e);b(a,this);this.vb.YQ(e);this.vb.setEnd(c)};d.lP=function(a,b,c){h.R.assert(this.Dc==l.xa.kb.Tk);h.R.assert(this.ka==a);c(b,this);this.tg||this.Dc==l.xa.kb.Jk||(h.R.fail(\"Group submessage did not end with an END_GROUP tag\"),this.tg=!0)};d.Ya=function(){h.R.assert(this.Dc==l.xa.kb.Xe);return this.vb.bC()};d.ad=function(){h.R.assert(this.Dc==l.xa.kb.Xe);return this.vb.cC()};\nd.Jg=function(){h.R.assert(this.Dc==l.xa.kb.Xe);return this.vb.Hh()};d.ee=function(){h.R.assert(this.Dc==l.xa.kb.Xe);return this.vb.nP()};d.ti=function(){h.R.assert(this.Dc==l.xa.kb.hh);return this.vb.ti()};d.pa=function(){h.R.assert(this.Dc==l.xa.kb.ih);return this.vb.pa()};d.vf=function(){h.R.assert(this.Dc==l.xa.kb.Xe);return!!this.vb.Hh()};d.we=function(){h.R.assert(this.Dc==l.xa.kb.Xe);return this.vb.cC()};d.Aa=function(){h.R.assert(this.Dc==l.xa.kb.jg);var a=this.vb.Hh();return this.vb.Aa(a)};\nd.qm=function(){h.R.assert(this.Dc==l.xa.kb.jg);var a=this.vb.Hh();return this.vb.qm(a)};d.mP=function(a){h.R.assert(this.Dc==l.xa.kb.jg);for(var b=this.vb.Hh(),b=this.vb.Ol()+b,c=[];this.vb.Ol()<b;)c.push(a.call(this.vb));return c};d.rm=function(){return this.mP(this.vb.pa)};l.Bi=function(){this.Yn=[];this.Lh=0;this.Ze=new l.Tt};d=l.Bi.prototype;d.MJ=function(a){var b=this.Ze.end();this.Yn.push(b);this.Yn.push(a);this.Lh+=b.length+a.length};\nd.ar=function(a){this.hg(a,l.xa.kb.jg);a=this.Ze.end();this.Yn.push(a);this.Lh+=a.length;a.push(this.Lh);return a};d.vr=function(a){var b=a.pop(),b=this.Lh+this.Ze.length()-b;for(h.R.assert(0<=b);127<b;)a.push(b&127|128),b>>>=7,this.Lh++;a.push(b);this.Lh++};d.reset=function(){this.Yn=[];this.Ze.end();this.Lh=0};d.hg=function(a,b){h.R.assert(1<=a&&a==Math.floor(a));a=8*a+b;this.Ze.Nm(a)};d.NW=function(a,b){null!=b&&(this.hg(a,l.xa.kb.Xe),this.Ze.Nm(b))};\nd.OC=function(a,b){null!=b&&(this.hg(a,l.xa.kb.Xe),this.Ze.Ft(b))};d.RC=function(a,b){null!=b&&(this.hg(a,l.xa.kb.Xe),this.Ze.OW(b))};d.PC=function(a,b){null!=b&&(this.hg(a,l.xa.kb.Xe),this.Ze.LW(b))};d.$a=function(a,b){null!=b&&(h.R.assert(b>=-l.xa.Tg&&b<l.xa.Tg),this.OC(a,b))};d.td=function(a,b){null!=b&&(h.R.assert(b>=-l.xa.Mj&&b<l.xa.Mj),this.PC(a,b))};d.Pg=function(a,b){null!=b&&(h.R.assert(0<=b&&b<l.xa.Xf),this.NW(a,b))};d.ye=function(a,b){null!=b&&(h.R.assert(0<=b&&b<l.xa.Rp),this.RC(a,b))};\nd.vi=function(a,b){null!=b&&(this.hg(a,l.xa.kb.hh),this.Ze.vi(b))};d.ya=function(a,b){null!=b&&(this.hg(a,l.xa.kb.ih),this.Ze.ya(b))};d.kf=function(a,b){null!=b&&(h.R.assert(h.sk(b)),this.hg(a,l.xa.kb.Xe),this.Ze.kf(b))};d.xe=function(a,b){null!=b&&(h.R.assert(b>=-l.xa.Tg&&b<l.xa.Tg),this.hg(a,l.xa.kb.Xe),this.Ze.Ft(b))};d.Ja=function(a,b){null!=b&&(a=this.ar(a),this.Ze.Ja(b),this.vr(a))};d.fp=function(a,b){null!=b&&(b=l.O.fr(b),this.hg(a,l.xa.kb.jg),this.Ze.Nm(b.length),this.MJ(b))};\nd.oa=function(a,b,c){null!=b&&(a=this.ar(a),c(b,this),this.vr(a))};d.GW=function(a,b){if(null!=b)for(var c=0;c<b.length;c++)this.OC(a,b[c])};d.HW=function(a,b){if(null!=b)for(var c=0;c<b.length;c++)this.PC(a,b[c])};d.IW=function(a,b){if(null!=b)for(var c=0;c<b.length;c++)this.RC(a,b[c])};d.bd=function(a,b){if(null!=b)for(var c=0;c<b.length;c++)this.ya(a,b[c])};d.oc=function(a,b){if(null!=b)for(var c=0;c<b.length;c++)this.Ja(a,b[c])};\nd.Oa=function(a,b,c){if(null!=b)for(var e=0;e<b.length;e++){var g=this.ar(a);c(b[e],this);this.vr(g)}};d.FW=function(a,b,c){if(null!=b)for(var e=0;e<b.length;e++)this.hg(a,l.xa.kb.Tk),c(b[e],this),this.hg(a,l.xa.kb.Jk)};d.Mm=function(a,b){if(null!=b&&b.length)for(this.hg(a,l.xa.kb.jg),this.Ze.Nm(8*b.length),a=0;a<b.length;a++)this.Ze.ya(b[a])};var x={i:{}};x.i.za={};x.i.za.me=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.za.me,l.u);\nl.u.ha&&(x.i.za.me.prototype.C=function(a){return x.i.za.me.C(a,this)},x.i.za.me.C=function(a,b){var c={o9:l.u.D(b,1),tda:l.u.D(b,2)};a&&(c.ja=b);return c});x.i.za.me.ia=function(a){a=new l.ba(a);var b=new x.i.za.me;return x.i.za.me.F(b,a)};x.i.za.me.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.$S(c);break;case 2:c=b.Aa();a.HV(c);break;default:b.ea()}}return a};x.i.za.me.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Ja(1,c);c=l.u.D(a,2);null!=c&&b.Ja(2,c)};\nx.i.za.me.prototype.$S=function(a){l.u.J(this,1,a)};x.i.za.me.prototype.HV=function(a){l.u.J(this,2,a)};x.i.za.me.K=function(a){return l.u.K(x.i.za.me,a)};x.i.za.nf=function(a){l.u.initialize(this,a,0,-1,x.i.za.nf.na,null)};h.da(x.i.za.nf,l.u);x.i.za.nf.na=[1];l.u.ha&&(x.i.za.nf.prototype.C=function(a){return x.i.za.nf.C(a,this)},x.i.za.nf.C=function(a,b){var c={U5:l.u.Ka(b.Wy(),x.i.za.me.C,a)};a&&(c.ja=b);return c});\nx.i.za.nf.ia=function(a){a=new l.ba(a);var b=new x.i.za.nf;return x.i.za.nf.F(b,a)};x.i.za.nf.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.za.me;b.T(c,x.i.za.me.F);a.mI(c);break;default:b.ea()}}return a};x.i.za.nf.G=function(a,b){a=a.Wy();0<a.length&&b.Oa(1,a,x.i.za.me.G)};x.i.za.nf.prototype.Wy=function(){return l.u.Ma(this,x.i.za.me,1)};x.i.za.nf.prototype.mI=function(a,b){return l.u.La(this,1,a,x.i.za.me,b)};x.i.za.nf.K=function(a){return l.u.K(x.i.za.nf,a)};\nx.i.za.kd=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.za.kd,l.u);l.u.ha&&(x.i.za.kd.prototype.C=function(a){return x.i.za.kd.C(a,this)},x.i.za.kd.C=function(a,b){var c={name:l.u.D(b,1),value:l.u.D(b,2)};a&&(c.ja=b);return c});x.i.za.kd.ia=function(a){a=new l.ba(a);var b=new x.i.za.kd;return x.i.za.kd.F(b,a)};x.i.za.kd.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.fe(c);break;case 2:c=b.Aa();a.setValue(c);break;default:b.ea()}}return a};\nx.i.za.kd.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Ja(1,c);c=l.u.D(a,2);null!=c&&b.Ja(2,c)};x.i.za.kd.prototype.getName=function(){return l.u.D(this,1)};x.i.za.kd.prototype.fe=function(a){l.u.J(this,1,a)};x.i.za.kd.prototype.getValue=function(){return l.u.D(this,2)};x.i.za.kd.prototype.setValue=function(a){l.u.J(this,2,a)};x.i.za.kd.K=function(a){return l.u.K(x.i.za.kd,a)};x.i.za.vd=function(a){l.u.initialize(this,a,0,-1,x.i.za.vd.na,null)};h.da(x.i.za.vd,l.u);x.i.za.vd.na=[1,2];\nl.u.ha&&(x.i.za.vd.prototype.C=function(a){return x.i.za.vd.C(a,this)},x.i.za.vd.C=function(a,b){var c={Cx:l.u.Ka(b.Zg(),x.i.za.kd.C,a),L8:l.u.gb(b,2),aK:l.u.D(b,3)};a&&(c.ja=b);return c});x.i.za.vd.ia=function(a){a=new l.ba(a);var b=new x.i.za.vd;return x.i.za.vd.F(b,a)};x.i.za.vd.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.za.kd;b.T(c,x.i.za.kd.F);a.sl(c);break;case 2:c=b.pa();a.BI(c);break;case 3:c=b.vf();a.uC(c);break;default:b.ea()}}return a};\nx.i.za.vd.G=function(a,b){var c;c=a.Zg();0<c.length&&b.Oa(1,c,x.i.za.kd.G);c=a.Bh();0<c.length&&b.bd(2,c);c=l.u.D(a,3);null!=c&&b.kf(3,c)};d=x.i.za.vd.prototype;d.Zg=function(){return l.u.Ma(this,x.i.za.kd,1)};d.Us=function(a){l.u.mt(this,1,a)};d.sl=function(a,b){return l.u.La(this,1,a,x.i.za.kd,b)};d.Bh=function(){return l.u.gb(this,2)};d.GS=function(a){l.u.J(this,2,a||[])};d.BI=function(a,b){l.u.ib(this,2,a,b)};d.to=function(){return l.u.D(this,3)};d.uC=function(a){l.u.J(this,3,a)};\nx.i.za.vd.K=function(a){return l.u.K(x.i.za.vd,a)};x.i.za.Te=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.za.Te,l.u);l.u.ha&&(x.i.za.Te.prototype.C=function(a){return x.i.za.Te.C(a,this)},x.i.za.Te.C=function(a,b){var c={Zq:l.u.D(b,1),pO:l.u.D(b,2),Qba:l.u.D(b,3),q5:l.u.D(b,4),Pba:l.u.D(b,5),p5:l.u.D(b,6)};a&&(c.ja=b);return c});x.i.za.Te.ia=function(a){a=new l.ba(a);var b=new x.i.za.Te;return x.i.za.Te.F(b,a)};\nx.i.za.Te.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.rj(c);break;case 2:c=b.Aa();a.$s(c);break;case 3:c=b.ad();a.TU(c);break;case 4:c=b.ad();a.qR(c);break;case 5:c=b.Ya();a.SU(c);break;case 6:c=b.Ya();a.pR(c);break;default:b.ea()}}return a};x.i.za.Te.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Ja(1,c);c=l.u.D(a,2);null!=c&&b.Ja(2,c);c=l.u.D(a,3);null!=c&&b.td(3,c);c=l.u.D(a,4);null!=c&&b.td(4,c);c=l.u.D(a,5);null!=c&&b.$a(5,c);c=l.u.D(a,6);null!=c&&b.$a(6,c)};\nd=x.i.za.Te.prototype;d.Jl=function(){return l.u.D(this,1)};d.rj=function(a){l.u.J(this,1,a)};d.$s=function(a){l.u.J(this,2,a)};d.TU=function(a){l.u.J(this,3,a)};d.qR=function(a){l.u.J(this,4,a)};d.SU=function(a){l.u.J(this,5,a)};d.pR=function(a){l.u.J(this,6,a)};x.i.za.Te.K=function(a){return l.u.K(x.i.za.Te,a)};x.i.za.oe=function(a){l.u.initialize(this,a,0,-1,x.i.za.oe.na,null)};h.da(x.i.za.oe,l.u);x.i.za.oe.na=[2,3];\nl.u.ha&&(x.i.za.oe.prototype.C=function(a){return x.i.za.oe.C(a,this)},x.i.za.oe.C=function(a,b){var c,e={c9:(c=b.yz())&&x.i.za.Te.C(a,c),J8:l.u.D(b,2),J4:l.u.Ka(b.By(),x.i.za.vd.C,a)};a&&(e.ja=b);return e});x.i.za.oe.ia=function(a){a=new l.ba(a);var b=new x.i.za.oe;return x.i.za.oe.F(b,a)};\nx.i.za.oe.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.za.Te;b.T(c,x.i.za.Te.F);a.TS(c);break;case 2:c=b.Aa();a.zI(c);break;case 3:c=new x.i.za.vd;b.T(c,x.i.za.vd.F);a.QH(c);break;default:b.ea()}}return a};x.i.za.oe.G=function(a,b){var c;c=a.yz();null!=c&&b.oa(1,c,x.i.za.Te.G);c=a.VL();0<c.length&&b.oc(2,c);c=a.By();0<c.length&&b.Oa(3,c,x.i.za.vd.G)};d=x.i.za.oe.prototype;d.yz=function(){return l.u.sa(this,x.i.za.Te,1)};d.TS=function(a){l.u.Ca(this,1,a)};\nd.VL=function(){return l.u.D(this,2)};d.zI=function(a,b){l.u.ib(this,2,a,b)};d.By=function(){return l.u.Ma(this,x.i.za.vd,3)};d.QH=function(a,b){return l.u.La(this,3,a,x.i.za.vd,b)};x.i.za.oe.K=function(a){return l.u.K(x.i.za.oe,a)};\nvar D={Event:{Ut:\"change\",bD:\"click\",au:\"dblclick\",xu:\"keyup\",KD:\"immediate-value-change\",fv:\"update-focus-range\",Op:\"select\",Vt:\"clear-selection\",kY:\"iron-select\",$Y:\"onmouseover\"},Pf:{Kj:\"Overall\",gu:\"feature\",o_:\"weighted examples\",ZC:\"calibration\",Cu:\"model_id\",yu:\"links\"},Nh:5,Pk:{Uk:0,FLOAT:1,INT:2,GD:3,Mp:4,an:5},HB:function(a,b){var c=[];a.forEach(function(a){c.push(b(a))});return c.join(\"_X_\")},Vy:function(a){a=a?a.Zg():null;return a&&0!=a.length?a=D.HB(a,function(a){return h.R.Lw(a.getName())}):\nD.Pf.Kj},Ah:function(a){var b=D.Vy(a);if(b==D.Pf.Kj)return b;a=a.Zg();var c=D.HB(a,function(a){return h.R.Lw(a.getValue())});return(1<a.length?\"XX_\":\"\")+b+\":\"+c}};D.ei=d3;h.bc(\"lantern.d3v4\",D.ei);D.data={};D.data.Sh=function(){};h.Fg(D.data.Sh.prototype,\"getDataTable\",D.data.Sh.prototype.getDataTable);h.Fg(D.data.Sh.prototype,\"getHeader\",D.data.Sh.prototype.Gr);h.Fg(D.data.Sh.prototype,\"getFormats\",D.data.Sh.prototype.Fr);h.Fg(D.data.Sh.prototype,\"readyToRender\",D.data.Sh.prototype.zs);\nD.Jb=function(a,b){if(!Array.isArray(b))throw\"invalid non-array input data\";this.metrics_=a;this.tf=b;this.yr={};this.tf.forEach(function(a){var b=a.Ah();this.yr[b]=a}.bind(this))};D.Jb.bv={Wt:\"p\",JSON:\"j\",IZ:\"colab\"};D.Jb.vK=function(a,b){return b.map(function(b){return D.Jb.Xw(a,JSON.parse(b.metricValues),b.feature)})};\nD.Jb.Xw=function(a,b,c){var e=c?c.split(\":\"):[D.Pf.Kj];a=a.map(function(a){return a==D.Pf.ZC?b.averageLabel?b.averageRefinedPrediction/b.averageLabel:0:b[a]});return new D.Jb.Series(e[0],c||D.Pf.Kj,a,!1)};D.Jb.prototype.ki=function(a){return this.metrics_.indexOf(a)};D.Jb.prototype.lk=function(){return this.metrics_};D.Jb.prototype.qM=function(){return this.tf};h.Fg(D.Jb.prototype,\"getSeriesList\",D.Jb.prototype.qM);D.Jb.prototype.filter=function(a){return new D.Jb(this.metrics_,this.tf.filter(a))};\nD.Jb.prototype.getColumnRange=function(a){var b=this.ki(a);return this.tf.reduce(function(a,e){e=e.Bh();return{min:Math.min(a.min,e[b]),max:Math.max(a.max,e[b])}},{min:Infinity,max:-Infinity})};h.Fg(D.Jb.prototype,\"getColumnRange\",D.Jb.prototype.getColumnRange);D.Jb.prototype.vB=function(){return 0<this.tf.length&&this.tf[0].Ah()==D.Pf.Kj};h.Fg(D.Jb.prototype,\"isOverallColumn\",D.Jb.prototype.vB);d=D.Jb.prototype;d.Xr=function(){return this.tf.some(function(a){return a.to()})};\nd.lA=function(a){h.R.assert(a in this.yr);return this.yr[a]};d.Hl=function(a){return this.lA(a).Bh()};d.WL=function(a,b){b=this.ki(b);h.R.assert(0<=b);return this.Hl(a)[b]};d.jk=function(){return this.tf.map(function(a){return a.Ah()})};d.rL=function(a,b){var c=this.Hl(a),c=[a].concat(c);b&&c.push(a);return c};d.getDataTable=function(a){var b=[],c=this.Xr();this.tf.forEach(function(e){\"\"!==a&&e.Hg()!=a||b.push(this.rL(e.Ah(),c))}.bind(this));return b};d.Zc=function(){return!this.tf.length||!this.metrics_.length};\nd.ii=function(a){var b=a.tf;if(this.metrics_!==a.lk()||this.tf.length!=b.length)return!1;for(a=0;a<this.tf.length;a++)if(this.tf[a]!==b[a])return!1;return!0};d.zs=function(){return!this.Zc()};d.Gr=function(a){a=[D.Pf.gu].concat(a);this.Xr()&&a.push(D.Pf.yu);return a};d.Fr=function(a){a=Object.assign({},a);a[D.Pf.gu]={type:D.Pk.Mp};return a};d.Gw=function(a,b){(b=b.transform)&&b.withDataSeries&&(a=b.withDataSeries(this.lA(a)));return a};\nD.Jb.Vw=function(a,b,c){var e=D.Jb.bv;switch(c){case e.JSON:b=b.map(function(b){return D.Jb.Xw(a,b.metrics,b.slice)});break;case e.Wt:b=b.map(D.Jb.Series.dL);break;default:b=D.Jb.vK(a,b)}return new D.Jb(a,b)};D.Jb.Series=function(a,b,c,e){this.jK=a;this.TK=b;this.BW=c;this.RM=e};D.Jb.Series.prototype.Hg=function(){return this.jK};D.Jb.Series.prototype.Ah=function(){return this.TK};D.Jb.Series.prototype.Bh=function(){return this.BW};h.Fg(D.Jb.Series.prototype,\"getMetricValuesList\",D.Jb.Series.prototype.Bh);\nD.Jb.Series.prototype.to=function(){return this.RM};D.Jb.Series.dL=function(a){return new D.Jb.Series(D.Vy(a),D.Ah(a),a.Bh(),!!a.to())};h.wC(\"goog.testing.stacktrace\");h.ra={};h.ra.Pa={};h.ra.Pa.jh=function(a,b,c,e){this.lr=a;this.Lo=b;this.Ew=c;this.vk=e};h.ra.Pa.jh.prototype.getName=function(){return this.Lo};h.ra.Pa.jh.prototype.nN=function(){return!this.Lo||\"[object Object]\"==this.lr};\nh.ra.Pa.jh.prototype.nW=function(){var a=h.ra.Pa.aN,b=h.ra.Pa.jO,b=[this.lr?a(this.lr)+\".\":\"\",this.Lo?a(b(this.Lo)):\"anonymous\",this.Ew?\" [as \"+a(b(this.Ew))+\"]\":\"\"];this.vk&&(b.push(\" at \"),b.push(a(this.vk)));return b.join(\"\")};h.ra.Pa.UD=20;h.ra.Pa.VD=5E5;h.ra.Pa.Sf=\"[a-zA-Z_$][\\\\w$]*\";h.ra.Pa.RE=\"(?: \\\\[as (\"+h.ra.Pa.Sf+\")\\\\])?\";h.ra.Pa.SE=\"(?:((?:new )?(?:\\\\[object Object\\\\]|\"+h.ra.Pa.Sf+\"(?:\\\\.\"+h.ra.Pa.Sf+\")*))\\\\.)?\";h.ra.Pa.UE=\"(?:new )?(?:\"+h.ra.Pa.Sf+\"|\\x3canonymous\\x3e)\";\nh.ra.Pa.TE=\" \"+h.ra.Pa.SE+\"(\"+h.ra.Pa.UE+\")\"+h.ra.Pa.RE;h.ra.Pa.Sp=\"((?:http|https|file)://[^\\\\s)]+|javascript:.*)\";h.ra.Pa.aD=\" (?:\\\\(unknown source\\\\)|\\\\(native\\\\)|\\\\((.+)\\\\)|(.+))\";h.ra.Pa.VE=new RegExp(\"^    at(?:\"+h.ra.Pa.TE+\")?\"+h.ra.Pa.aD+\"$\");h.ra.Pa.qD=\"(\"+h.ra.Pa.Sf+\"(?:\\\\.\"+h.ra.Pa.Sf+\")*)?(\\\\(.*\\\\))?@\";h.ra.Pa.rD=new RegExp(\"^\"+h.ra.Pa.qD+\"(?::0|\"+h.ra.Pa.Sp+\")$\");h.ra.Pa.eE=\"\\x3canonymous function(?:\\\\: (?:(\"+h.ra.Pa.Sf+\"(?:\\\\.\"+h.ra.Pa.Sf+\")*)\\\\.)?(\"+h.ra.Pa.Sf+\"))?\\x3e\";\nh.ra.Pa.fE=\"(?:(?:(\"+h.ra.Pa.Sf+\")|\"+h.ra.Pa.eE+\")(\\\\(.*\\\\)))?@\";h.ra.Pa.gE=new RegExp(\"^\"+h.ra.Pa.fE+h.ra.Pa.Sp+\"?$\");h.ra.Pa.xD=new RegExp(\"^function (\"+h.ra.Pa.Sf+\")\");h.ra.Pa.ID=\"(\"+h.ra.Pa.Sf+\"(?:\\\\.\"+h.ra.Pa.Sf+\")*(?:\\\\s+\\\\w+)*)\";h.ra.Pa.JD=new RegExp(\"^   at \"+h.ra.Pa.ID+\"\\\\s*\\\\((eval code:[^)]*|Unknown script code:[^)]*|\"+h.ra.Pa.Sp+\")\\\\)?$\");\nh.ra.Pa.cL=function(){for(var a=[],b=arguments.callee.caller,c=0;b&&c<h.ra.Pa.UD;){var e=Function.prototype.toString.call(b),e=(e=e.match(h.ra.Pa.xD))?e[1]:\"\";a.push(new h.ra.Pa.jh(\"\",e,\"\",\"\"));try{b=b.caller}catch(g){break}c++}return a};\nh.ra.Pa.UO=function(a){var b=a.match(h.ra.Pa.VE);return b?new h.ra.Pa.jh(b[1]||\"\",b[2]||\"\",b[3]||\"\",b[4]||b[5]||b[6]||\"\"):a.length>h.ra.Pa.VD?null:(b=a.match(h.ra.Pa.rD))?new h.ra.Pa.jh(\"\",b[1]||\"\",\"\",b[3]||\"\"):(b=a.match(h.ra.Pa.gE))?new h.ra.Pa.jh(b[2]||\"\",b[1]||b[3]||\"\",\"\",b[5]||\"\"):(b=a.match(h.ra.Pa.JD))?new h.ra.Pa.jh(\"\",b[1]||\"\",\"\",b[2]||\"\"):null};h.ra.Pa.eR=function(a){h.ra.Pa.ux=a};h.ra.Pa.jO=function(a){return h.ra.Pa.ux?h.ra.Pa.ux(a):a};\nh.ra.Pa.aN=function(a){return a.replace(/&/g,\"\\x26amp;\").replace(/</g,\"\\x26lt;\").replace(/>/g,\"\\x26gt;\").replace(/\"/g,\"\\x26quot;\")};h.ra.Pa.Gx=function(a){for(var b=a.length-1;a[b]&&a[b].nN();)b--;for(var c=-1,e=0;e<a.length;e++)if(a[e]&&\"_assert\"==a[e].getName()){c=e;break}for(var g=[],e=c+1;e<=b;e++)g.push(\"\\x3e \"),a[e]?g.push(a[e].nW()):g.push(\"(unknown)\"),g.push(\"\\n\");return g.join(\"\")};\nh.ra.Pa.XB=function(a){a=a.replace(/\\s*$/,\"\").split(\"\\n\");for(var b=[],c=0;c<a.length;c++)b.push(h.ra.Pa.UO(a[c]));return b};h.ra.Pa.f3=function(a){a=h.ra.Pa.XB(a);return h.ra.Pa.Gx(a)};h.ra.Pa.ZL=function(){var a=Error();if(a.stack)return a.stack;try{null.x()}catch(b){return b.stack}return\"\"};h.ra.Pa.get=function(){var a=h.ra.Pa.ZL(),a=a?h.isArray(a)?h.ra.Pa.bK(a):h.ra.Pa.XB(a):h.ra.Pa.cL();return h.ra.Pa.Gx(a)};\nh.ra.Pa.bK=function(a){for(var b=[],c=0;c<a.length;c++){var e=a[c],g=e.getFunctionName()||\"unknown\",k=e.getFileName(),e=k?k+\":\"+e.getLineNumber()+\":\"+e.getColumnNumber():\"unknown\";b.push(new h.ra.Pa.jh(\"\",g,\"\",e))}return b};h.bc(\"setDeobfuscateFunctionName\",h.ra.Pa.eR);h.wC(\"goog.testing.JsUnitException\");h.ra.R={};\nvar af=function(a,b){return a==b},vh=function(a,b){return a.toString()===b.toString()},wh={String:af,Number:af,Boolean:af,Date:function(a,b){return a.getTime()==b.getTime()},RegExp:vh,Function:vh};h.ra.R.VB=function(a,b,c){return Math.abs(a-b)<=c};h.ra.R.$O={Number:h.ra.R.VB};\nvar _trueTypeOf=function(a){var b=typeof a;try{switch(b){case \"object\":if(null==a){b=\"null\";break}case \"function\":switch(a.constructor){case (new String(\"\")).constructor:b=\"String\";break;case (new Boolean(!0)).constructor:b=\"Boolean\";break;case (new Number(0)).constructor:b=\"Number\";break;case [].constructor:b=\"Array\";break;case RegExp().constructor:b=\"RegExp\";break;case (new Date).constructor:b=\"Date\";break;case Function:b=\"Function\";break;default:var c=a.constructor.toString().match(/function\\s*([^( ]+)\\(/);\nc&&(b=c[1])}}}catch(e){}finally{b=b.substr(0,1).toUpperCase()+b.substr(1)}return b},_displayStringForValue=function(a){var b;try{b=\"\\x3c\"+String(a)+\"\\x3e\"}catch(c){b=\"\\x3ctoString failed: \"+c.message+\"\\x3e\"}null!==a&&void 0!==a&&(b+=\" (\"+_trueTypeOf(a)+\")\");return b},xh=function(a){h.ra.R.pm(\"Call to fail()\",a)},gm=function(a,b){return b.length==a+1?b[0]:null},hm=function(a,b,c){return c.length==b+1?c[a]:c[a-1]},_validateArguments=function(a,b){a=b.length==a||b.length==a+1&&h.Hb(b[0]);_assert(null,\na,\"Incorrect arguments passed to assert function\")},_getCurrentTestCase=function(){var a=h.global.G_testRunner;return a?a.wca:null},_assert=function(a,b,c){b||h.ra.R.pm(a,c)};\nh.ra.R.ji=function(a,b){var c=\"Expected \"+_displayStringForValue(a)+\" but was \"+_displayStringForValue(b);if(\"string\"==typeof a&&\"string\"==typeof b){for(var e=Math.min(a.length,b.length),g=0;g<e&&a.charAt(g)==b.charAt(g);)g++;for(var k=0;k<e&&a.charAt(a.length-k-1)==b.charAt(b.length-k-1);)k++;g+k>e&&(k=0);if(2<g||2<k)e=function(a){var b=Math.max(0,g-2),c=Math.min(a.length,a.length-(k-2));return(0<b?\"...\":\"\")+a.substring(b,c)+(c<a.length?\"...\":\"\")},c+=\"\\nDifference was at position \"+g+\". Expected [\"+\ne(a)+\"] vs. actual [\"+e(b)+\"]\"}return c};\nvar im=function(a,b){_validateArguments(1,arguments);var c=gm(1,arguments),e=hm(1,1,arguments);_assert(c,h.sk(e),\"Bad argument to assert(boolean)\");_assert(c,e,\"Call to assert(boolean) with false\")},jm=function(a,b){_validateArguments(1,arguments);var c=hm(1,1,arguments),e=gm(1,arguments);_assert(e,\"function\"==typeof c,\"Argument passed to assertThrows is not a function\");try{c()}catch(g){return g&&h.Hb(g.stacktrace)&&h.Hb(g.message)&&(c=g.message.length-g.stacktrace.length,g.message.indexOf(g.stacktrace,\nc)==c&&(g.message=g.message.substr(0,c-14))),c=_getCurrentTestCase(),g&&g.isJsUnitException&&c&&c.O5&&h.ra.R.pm(e,\"Function passed to assertThrows caught a JsUnitException (usually from an assert or call to fail()). If this is expected, use assertThrowsJsUnitException instead.\"),g}h.ra.R.pm(e,\"No exception thrown from function passed to assertThrows\")},km=function(a,b){_validateArguments(1,arguments);var c=gm(1,arguments),e=hm(1,1,arguments);_assert(c,\"function\"==typeof e,\"Argument passed to assertNotThrows is not a function\");\ntry{return e()}catch(g){c=c?c+\"\\n\":\"\",c+=\"A non expected exception was thrown from function passed to assertNotThrows\",e=g.stack||g.stacktrace||g.toString(),h.ra.R.pm(c,e)}},lm=function(a,b){try{h.ra.R.cK(a)}catch(c){return(a=_getCurrentTestCase())?a.y7(c):h.global.console.error(\"Failed to remove expected exception: no test case is installed.\"),c.uN||xh(\"Expected a JsUnitException\"),\"undefined\"!=typeof b&&c.message!=b&&xh(\"Expected message [\"+b+\"] but got [\"+c.message+\"]\"),c}a=\"Expected a failure\";\n\"undefined\"!=typeof b&&(a+=\": \"+b);throw new h.ra.Ok(a);},mm=function(a,b){_validateArguments(1,arguments);var c=gm(1,arguments),e=hm(1,1,arguments);_assert(c,h.sk(e),\"Bad argument to assertTrue(boolean)\");_assert(c,e,\"Call to assertTrue(boolean) with false\")},nm=function(a,b){_validateArguments(1,arguments);var c=gm(1,arguments),e=hm(1,1,arguments);_assert(c,h.sk(e),\"Bad argument to assertFalse(boolean)\");_assert(c,!e,\"Call to assertFalse(boolean) with true\")},om=function(a,b,c){_validateArguments(2,\narguments);var e=hm(1,2,arguments),g=hm(2,2,arguments);_assert(gm(2,arguments),e===g,h.ra.R.ji(e,g))},mw=function(a,b,c){_validateArguments(2,arguments);var e=hm(1,2,arguments),g=hm(2,2,arguments);_assert(gm(2,arguments),e!==g,\"Expected not to be \"+_displayStringForValue(g))},nw=function(a,b){_validateArguments(1,arguments);var c=hm(1,1,arguments);_assert(gm(1,arguments),null===c,h.ra.R.ji(null,c))},ow=function(a,b){_validateArguments(1,arguments);var c=hm(1,1,arguments);_assert(gm(1,arguments),null!==\nc,\"Expected not to be \"+_displayStringForValue(null))},pw=function(a,b){_validateArguments(1,arguments);var c=hm(1,1,arguments);_assert(gm(1,arguments),void 0===c,h.ra.R.ji(void 0,c))},qw=function(a,b){_validateArguments(1,arguments);var c=hm(1,1,arguments);_assert(gm(1,arguments),void 0!==c,\"Expected not to be \"+_displayStringForValue(void 0))},rw=function(a,b){_validateArguments(1,arguments);ow.apply(null,arguments);qw.apply(null,arguments)},sw=function(a,b){_validateArguments(1,arguments);var c=\nhm(1,1,arguments);_assert(gm(1,arguments),void 0!==c&&null!==c&&\"string\"==typeof c&&\"\"!==c,\"Expected non-empty string but was \"+_displayStringForValue(c))},tw=function(a,b){_validateArguments(1,arguments);var c=hm(1,1,arguments);_assert(gm(1,arguments),isNaN(c),\"Expected NaN\")},uw=function(a,b){_validateArguments(1,arguments);var c=hm(1,1,arguments);_assert(gm(1,arguments),!isNaN(c),\"Expected not NaN\")};\nh.ra.R.cK=function(a){var b=h.global.G_testRunner,c=b.logTestFailure;try{b.logTestFailure=void 0,a()}finally{b.logTestFailure=c}};h.ra.R.sp=null;h.ra.R.tp=\"\";\nh.ra.R.zr=function(a,b,c){function e(a,b,c){for(var e=0;e<m.length;++e){var q=m[e]===a,v=n[e]===b;if(q||v){q&&v||k.push(\"Asymmetric cycle detected at \"+c);return}}m.push(a);n.push(b);g(a,b,c);m.pop();n.pop()}function g(a,b,c){if(a!==b){var g=_trueTypeOf(a),n=_trueTypeOf(b);if(g==n){var m=\"Array\"==g,v=q(g,a,b);if(v!=h.ra.R.sp)v!=h.ra.R.tp&&k.push(c+\": \"+v);else if(m&&a.length!=b.length)k.push(c+\": Expected \"+a.length+\"-element array but got a \"+b.length+\"-element array\");else{var B=c+(m?\"[%s]\":c?\".%s\":\n\"%s\");if(\"undefined\"!=typeof Map&&a instanceof Map||\"undefined\"!=typeof Set&&a instanceof Set)a.forEach(function(a,g){b.has(g)?b.get&&e(a,b.get(g),B.replace(\"%s\",g)):k.push(g+\" not present in actual \"+(c||n))}),b.forEach(function(b,e){a.has(e)||k.push(e+\" not present in expected \"+(c||g))});else if(a.__iterator__)h.isFunction(a.ii)?a.ii(b)||k.push(\"equals() returned false for \"+(c||g)):a.jc?e(a.jc,b.jc,B.replace(\"%s\",\"map_\")):k.push(\"unable to check \"+(c||g)+\" for equality: it has an iterator we do not know how to handle. please add an equals method\");\nelse{for(var C in a)m&&h.ra.R.nB(C)||(C in b?e(a[C],b[C],B.replace(\"%s\",C)):k.push(\"property \"+C+\" not present in actual \"+(c||n)));for(C in b)m&&h.ra.R.nB(C)||C in a||k.push(\"property \"+C+\" not present in expected \"+(c||g));if(m)for(C=0;C<a.length;C++)e(a[C],b[C],B.replace(\"%s\",String(C)))}}}else k.push(c+\" \"+h.ra.R.ji(a,b))}}var k=[],m=[],n=[],q=c||function(a,b,c){a=wh[a];return a?(a=a(b,c))?h.ra.R.tp:h.ra.R.ji(b,c):h.ra.R.sp};e(a,b,\"\");return 0==k.length?null:h.ra.R.ji(a,b)+\"\\n   \"+k.join(\"\\n   \")};\nvar vw=function(a,b,c){_validateArguments(2,arguments);var e=hm(1,2,arguments),g=hm(2,2,arguments),k=gm(2,arguments)?gm(2,arguments):\"\",e=h.ra.R.zr(e,g);_assert(k,!e,e)},ww=function(a,b,c,e){_validateArguments(3,arguments);var g=hm(1,3,arguments),k=hm(2,3,arguments),m=hm(3,3,arguments),n=gm(3,arguments)?gm(3,arguments):\"\",q=function(a,b,c){a=h.ra.R.$O[a];return a?(a=a(b,c,m))?h.ra.R.tp:h.ra.R.ji(b,c)+\" which was more than \"+m+\" away\":h.ra.R.sp},g=h.ra.R.zr(g,k,q);_assert(n,!g,g)},xw=function(a,b,\nc){_validateArguments(2,arguments);var e=hm(1,2,arguments),g=hm(2,2,arguments),k=gm(2,arguments)?gm(2,arguments):\"\",e=h.ra.R.zr(e,g);_assert(k,e,\"Objects should not be equal\")},yw=function(a,b,c){_validateArguments(2,arguments);var e=hm(1,2,arguments),g=hm(2,2,arguments),k=gm(2,arguments)?gm(2,arguments):\"\",m=_trueTypeOf(e);_assert(k,\"Array\"==m,\"Expected an array for assertArrayEquals but found a \"+m);m=_trueTypeOf(g);_assert(k,\"Array\"==m,\"Expected an array for assertArrayEquals but found a \"+m);\nvw(k,Array.prototype.concat.call(e),Array.prototype.concat.call(g))},zw=function(a,b,c){_validateArguments(2,arguments);var e=hm(1,2,arguments),g=hm(2,2,arguments),k=gm(2,arguments)?gm(2,arguments):\"\";if(e){om(\"length mismatch: \"+k,e.length,g.length);for(var m=0;m<e.length;++m)om(\"mismatch at index \"+m+\": \"+k,e[m],g[m])}else im(k,!g)},Bw=function(a,b,c,e){_validateArguments(3,arguments);var g=hm(1,3,arguments),k=hm(2,3,arguments),m=hm(3,3,arguments),n=gm(3,arguments)?gm(3,arguments):\"\";if(g){om(\"length mismatch: \"+\nn,g.length,k.length);for(var q=0;q<g.length;++q)Aw(n,g[q],k[q],m)}else im(n,!k)},Cw=function(a,b,c){_validateArguments(2,arguments);var e=hm(1,2,arguments),g=hm(2,2,arguments),k=gm(2,arguments);mm(\"Bad arguments to assertSameElements(opt_message, expected: ArrayLike, actual: ArrayLike)\",h.Gd(e)&&h.Gd(g));e=h.ra.R.wt(e);g=h.ra.R.wt(g);_assert(k,e.length==g.length,\"Expected \"+e.length+\" elements: [\"+e+\"], got \"+g.length+\" elements: [\"+g+\"]\");for(var m=h.ra.R.wt(e),n=0;n<g.length;n++){var q=h.ra.R.hB(m,\ng[n]);_assert(k,-1!=q,\"Expected [\"+e+\"], got [\"+g+\"]\");m.splice(q,1)}},Dw=function(a,b){_validateArguments(1,arguments);var c=hm(1,1,arguments);c||_assert(gm(1,arguments),!1,\"Expected to evaluate to true\")},Ew=function(a,b){_validateArguments(1,arguments);var c=hm(1,1,arguments);c&&_assert(gm(1,arguments),!1,\"Expected to evaluate to false\")},Gw=function(a,b,c){_validateArguments(2,arguments);var e=hm(1,2,arguments),g=hm(2,2,arguments),e=Fw(e),g=Fw(g);_assert(gm(2,arguments),e===g,h.ra.R.ji(e,g))},\nHw=function(a,b,c){_validateArguments(2,arguments);var e=hm(1,2,arguments),g=hm(2,2,arguments),k=gm(2,arguments),m;for(m in e)_assert(k,m in g,\"Expected hash had key \"+m+\" that was not found\"),_assert(k,e[m]==g[m],\"Value for key \"+m+\" mismatch - expected \\x3d \"+e[m]+\", actual \\x3d \"+g[m]);for(m in g)_assert(k,m in e,\"Actual hash had key \"+m+\" that was not expected\")},Aw=function(a,b,c,e){_validateArguments(3,arguments);var g=hm(1,3,arguments),k=hm(2,3,arguments),m=hm(3,3,arguments);_assert(gm(3,arguments),\nh.ra.R.VB(g,k,m),\"Expected \"+g+\", but got \"+k+\" which was more than \"+m+\" away\")},Iw=function(a,b,c){_validateArguments(2,arguments);var e=hm(1,2,arguments),g=hm(2,2,arguments);_assert(gm(2,arguments),h.ra.R.jx(g,e),\"Expected '\"+g+\"' to contain '\"+e+\"'\")},Jw=function(a,b,c){_validateArguments(2,arguments);var e=hm(1,2,arguments),g=hm(2,2,arguments);_assert(gm(2,arguments),!h.ra.R.jx(g,e),\"Expected '\"+g+\"' not to contain '\"+e+\"'\")},Kw=function(a,b,c){_validateArguments(2,arguments);var e=hm(1,2,arguments),\ng=hm(2,2,arguments);\"string\"==typeof e&&(e=new RegExp(e));_assert(gm(2,arguments),e.test(g),\"Expected '\"+g+\"' to match RegExp \"+e.toString())};h.ra.R.wt=function(a){for(var b=[],c=0;c<a.length;c++)b[c]=a[c];return b};h.ra.R.hB=function(a,b){if(a.indexOf)return a.indexOf(b);for(var c=0;c<a.length;c++)if(a[c]===b)return c;return-1};h.ra.R.jx=function(a,b){return-1!=h.ra.R.hB(a,b)};var Fw=function(a){var b=document.createElement(\"DIV\");b.innerHTML=a;return b.innerHTML.replace(/^\\s+|\\s+$/g,\"\")};\nh.ra.R.pm=function(a,b){a=new h.ra.Ok(a,b);if(b=_getCurrentTestCase())b.oaa(a);else throw h.global.console.error(\"Failed to save thrown exception: no test case is installed.\"),a;};h.ra.R.nB=function(a){return(a|0)==a};h.ra.Ok=function(a,b){this.uN=!0;this.message=(a?a:\"\")+(a&&b?\"\\n\":\"\")+(b?b:\"\");h.ra.Pa.get();Error.captureStackTrace?Error.captureStackTrace(this,h.ra.Ok):this.stack=Error().stack||\"\"};h.da(h.ra.Ok,Error);h.ra.Ok.prototype.toString=function(){return this.message};h.bc(\"fail\",xh);\nh.bc(\"assert\",im);h.bc(\"assertThrows\",jm);h.bc(\"assertNotThrows\",km);h.bc(\"assertThrowsJsUnitException\",lm);h.bc(\"assertTrue\",mm);h.bc(\"assertFalse\",nm);h.bc(\"assertEquals\",om);h.bc(\"assertNotEquals\",mw);h.bc(\"assertNull\",nw);h.bc(\"assertNotNull\",ow);h.bc(\"assertUndefined\",pw);h.bc(\"assertNotUndefined\",qw);h.bc(\"assertNotNullNorUndefined\",rw);h.bc(\"assertNonEmptyString\",sw);h.bc(\"assertNaN\",tw);h.bc(\"assertNotNaN\",uw);h.bc(\"assertObjectEquals\",vw);h.bc(\"assertObjectRoughlyEquals\",ww);\nh.bc(\"assertObjectNotEquals\",xw);h.bc(\"assertArrayEquals\",yw);h.bc(\"assertElementsEquals\",zw);h.bc(\"assertElementsRoughlyEqual\",Bw);h.bc(\"assertSameElements\",Cw);h.bc(\"assertEvaluatesToTrue\",Dw);h.bc(\"assertEvaluatesToFalse\",Ew);h.bc(\"assertHTMLEquals\",Gw);h.bc(\"assertHashEquals\",Hw);h.bc(\"assertRoughlyEquals\",Aw);h.bc(\"assertContains\",Iw);h.bc(\"assertNotContains\",Jw);h.bc(\"assertRegExp\",Kw);D.Wf=function(a){this.Dh=a};\nD.Wf.prototype.UL=function(a,b){return this.Dh.map(function(c){return[c.id,c.data.WL(a,b)]})};h.Fg(D.Wf.prototype,\"getMetricDataTable\",D.Wf.prototype.UL);D.Wf.prototype.getDataTable=function(a){return this.Dh.map(function(b){var c=b.data.Hl(a);return[b.id].concat(c)})};\nD.Wf.prototype.jk=function(){var a={};this.Dh.forEach(function(b){b=b.data.jk();b.forEach(function(b){b in a?a[b]++:a[b]=1})});return Object.keys(a).filter(function(b){var c=a[b]==this.Dh.length;if(!c)throw'feature \"'+b+'\" is not present in all models';return c}.bind(this))};h.Fg(D.Wf.prototype,\"getFeatures\",D.Wf.prototype.jk);\nD.Wf.prototype.lk=function(){var a={};this.Dh.forEach(function(b){b=b.data.lk();b.forEach(function(b){b in a?a[b]++:a[b]=1})});return Object.keys(a).filter(function(b){var c=a[b]==this.Dh.length;if(!c)throw'metric \"'+b+'\" is not present in all models';return c}.bind(this))};D.Wf.prototype.XL=function(){return this.Dh.map(function(a){return a.id})};h.Fg(D.Wf.prototype,\"getModelIds\",D.Wf.prototype.XL);d=D.Wf.prototype;d.Zc=function(){return!this.Dh.length||this.Dh[0].data.Zc()};\nd.zs=function(a){return!this.Zc()&&\"\"!=a};d.Gr=function(a){return[D.Pf.Cu].concat(a)};d.Fr=function(a){a=Object.assign({},a);a[D.Pf.Cu]={type:D.Pk.Mp};return a};d.Gw=function(a){return a};D.test={};D.test.Event={Ut:\"change\",bD:\"click\",au:\"dblclick\",xu:\"keyup\",Op:\"select\",Vt:\"clear-selection\"};\nD.test.J6=function(){return{metrics:[\"weighted_examples\",\"metric_a\",\"metric_b\"],slices:[{af:{name:\"col\",value:\"1\"},wf:[4,.333,.002]},{af:{name:\"col\",value:\"2\"},wf:[9,.997,.753]},{af:{name:\"col\",value:\"3\"},wf:[1,1.14,.198]},{af:{name:\"col\",value:\"4\"},wf:[12,.18,.332]}]}};\nD.test.H6=function(a,b){for(var c=[\"weighted_examples\"],e=0;e<b;e++)c.push(\"metric_\"+String.fromCharCode(97+e));for(var g=[],e=0;e<a;e++){for(var k=[Math.ceil(100*Math.random())],m=0;m<b;m++)k.push(Math.random());g.push({af:{name:\"col\",value:\"\"+(e+1)},wf:k})}return{metrics:c,slices:g}};\nD.test.K6=function(){return[{metrics:[\"weighted_examples\",\"metric_a\",\"metric_b\",\"metric_c\"],slices:[{af:{name:\"Overall\",value:\"\"},wf:[100,1,1,1]},{af:{name:\"col\",value:\"1\"},wf:[4,.333,.002,.183]},{af:{name:\"col\",value:\"2\"},wf:[9,.997,.753,.629]}]},{metrics:[\"weighted_examples\",\"metric_a\",\"metric_b\",\"metric_c\"],slices:[{af:{name:\"Overall\",value:\"\"},wf:[200,.999,.999,.999]},{af:{name:\"col\",value:\"1\"},wf:[2,.111,.009,.215]},{af:{name:\"col\",value:\"2\"},wf:[5,.666,.831,.731]}]},{metrics:[\"weighted_examples\",\n\"metric_a\",\"metric_b\",\"metric_c\"],slices:[{af:{name:\"Overall\",value:\"\"},wf:[300,.888,.888,.888]},{af:{name:\"col\",value:\"1\"},wf:[2,.222,.012,.091]},{af:{name:\"col\",value:\"2\"},wf:[5,.777,.353,.662]}]}]};\nD.test.I6=function(a,b,c){for(var e,g=[\"weighted_examples\"],k=0;k<c;k++)g.push(\"metric_\"+String.fromCharCode(97+k));e=[];for(k=0;k<a;k++){for(var m=[],n=0;n<b+1;n++){var q;q=0==n?{name:\"Overall\",value:\"\"}:{name:\"col\",value:\"\"+n};for(var v=[Math.ceil(100*Math.random())],B=0;B<c;B++)v.push(Math.random());m.push({af:q,wf:v})}e.push({metrics:g,slices:m})}return e};\nD.test.EK=function(a){return a.slices.map(function(a){var b=[];if(a.af){var e=new x.i.za.kd;e.fe(a.af.name);e.setValue(a.af.value);b.push(e)}e=new x.i.za.vd;e.Us(b);e.GS(a.wf);a.aK&&e.uC(!0);return e})};D.test.DK=function(a){return D.Jb.Vw(a.metrics,D.test.EK(a),D.Jb.bv.Wt)};D.test.fba=function(a){a=a.map(function(a,c){return{id:\"version_\"+(c+1),data:D.test.DK(a)}});return new D.Wf(a)};\nD.test.xL=function(a,b,c){c=void 0==c?{}:c;a=a.getElementsByTagName(b);b=[];for(var e=0;e<a.length;e++){var g=!0,k;for(k in c){var m=c[k];switch(k){case \"textContent\":var n=a[e].textContent.match(/^\\s*(\\S+.*\\S+|\\S+)\\s*$/),g=g&(n&&n[1]===m);break;case \"class\":g&=a[e].classList.contains(m);break;case \"visible\":g&=m?\"none\"!=a[e].style.display:\"none\"==a[e].style.display;break;default:g&=a[e].getAttribute(k)===c[k]}if(!g)break}g&&b.push(a[e])}return b};\nD.test.F5=function(a,b,c,e){a=D.test.xL(a,c,e);om(a.length,b)};D.test.fireEvent=function(a,b,c){a.dispatchEvent(new CustomEvent(b,{detail:c}))};h.gc={};h.gc.cj=function(a){return function(){return a}};h.gc.LX=h.gc.cj(!1);h.gc.i_=h.gc.cj(!0);h.gc.UY=h.gc.cj(null);h.gc.bN=function(a){return a};h.gc.error=function(a){return function(){throw Error(a);}};h.gc.fail=function(a){return function(){throw a;}};\nh.gc.lock=function(a,b){b=b||0;return function(){return a.apply(this,Array.prototype.slice.call(arguments,0,b))}};h.gc.I9=function(a){return function(){return arguments[a]}};h.gc.u$=function(a,b){var c=Array.prototype.slice.call(arguments,1);return function(){var b=Array.prototype.slice.call(arguments);b.push.apply(b,c);return a.apply(this,b)}};h.gc.Hda=function(a,b){return h.gc.rC(a,h.gc.cj(b))};h.gc.t5=function(a,b){return function(c){return b?a==c:a===c}};\nh.gc.J3=function(a,b){var c=arguments,e=c.length;return function(){var a;e&&(a=c[e-1].apply(this,arguments));for(var b=e-2;0<=b;b--)a=c[b].call(this,a);return a}};h.gc.rC=function(a){var b=arguments,c=b.length;return function(){for(var a,g=0;g<c;g++)a=b[g].apply(this,arguments);return a}};h.gc.T1=function(a){var b=arguments,c=b.length;return function(){for(var a=0;a<c;a++)if(!b[a].apply(this,arguments))return!1;return!0}};\nh.gc.m$=function(a){var b=arguments,c=b.length;return function(){for(var a=0;a<c;a++)if(b[a].apply(this,arguments))return!0;return!1}};h.gc.not=function(a){return function(){return!a.apply(this,arguments)}};h.gc.create=function(a,b){var c=function(){};c.prototype=a.prototype;c=new c;a.apply(c,Array.prototype.slice.call(arguments,1));return c};h.gc.YC=!0;h.gc.Y2=function(a){var b=!1,c;return function(){if(!h.gc.YC)return a();b||(c=a(),b=!0);return c}};\nh.gc.once=function(a){var b=a;return function(){if(b){var a=b;b=null;a()}}};h.gc.debounce=function(a,b,c){var e=0;return function(g){h.global.clearTimeout(e);var k=arguments;e=h.global.setTimeout(function(){a.apply(c,k)},b)}};h.gc.Aca=function(a,b,c){var e=0,g=!1,k=[],m=function(){e=0;g&&(g=!1,n())},n=function(){e=h.global.setTimeout(m,b);a.apply(c,k)};return function(a){k=arguments;e?g=!0:n()}};\nh.gc.raa=function(a,b,c){var e=0,g=function(){e=0};return function(k){e||(e=h.global.setTimeout(g,b),a.apply(c,arguments))}};h.uri={};h.uri.O={};h.uri.O.Gk={Ht:38,EQUAL:61,BD:35,qE:63};h.uri.O.$n=function(a,b,c,e,g,k,m){var n=\"\";a&&(n+=a+\":\");c&&(n+=\"//\",b&&(n+=b+\"@\"),n+=c,e&&(n+=\":\"+e));g&&(n+=g);k&&(n+=\"?\"+k);m&&(n+=\"#\"+m);return n};h.uri.O.eW=/^(?:([^:/?#.]+):)?(?:\\/\\/(?:([^/?#]*)@)?([^/#?]*?)(?::([0-9]+))?(?=[/#?]|$))?([^?#]+)?(?:\\?([^#]*))?(?:#([\\s\\S]*))?$/;\nh.uri.O.Ib={Ii:1,mn:2,gh:3,oh:4,Fp:5,kn:6,xp:7};h.uri.O.split=function(a){return a.match(h.uri.O.eW)};h.uri.O.oo=function(a,b){return a?b?decodeURI(a):decodeURIComponent(a):a};h.uri.O.hk=function(a,b){return h.uri.O.split(b)[a]||null};h.uri.O.bm=function(a){return h.uri.O.hk(h.uri.O.Ib.Ii,a)};h.uri.O.r6=function(a){a=h.uri.O.bm(a);!a&&h.global.self&&h.global.self.location&&(a=h.global.self.location.protocol,a=a.substr(0,a.length-1));return a?a.toLowerCase():\"\"};\nh.uri.O.LM=function(a){return h.uri.O.hk(h.uri.O.Ib.mn,a)};h.uri.O.yo=function(a){return h.uri.O.oo(h.uri.O.LM(a))};h.uri.O.vL=function(a){return h.uri.O.hk(h.uri.O.Ib.gh,a)};h.uri.O.uo=function(a){return h.uri.O.oo(h.uri.O.vL(a),!0)};h.uri.O.wo=function(a){return Number(h.uri.O.hk(h.uri.O.Ib.oh,a))||null};h.uri.O.eM=function(a){return h.uri.O.hk(h.uri.O.Ib.Fp,a)};h.uri.O.ij=function(a){return h.uri.O.oo(h.uri.O.eM(a),!0)};h.uri.O.Mr=function(a){return h.uri.O.hk(h.uri.O.Ib.kn,a)};\nh.uri.O.JL=function(a){var b=a.indexOf(\"#\");return 0>b?null:a.substr(b+1)};h.uri.O.jba=function(a,b){return h.uri.O.uP(a)+(b?\"#\"+b:\"\")};h.uri.O.vo=function(a){return h.uri.O.oo(h.uri.O.JL(a))};h.uri.O.u6=function(a){a=h.uri.O.split(a);return h.uri.O.$n(a[h.uri.O.Ib.Ii],a[h.uri.O.Ib.mn],a[h.uri.O.Ib.gh],a[h.uri.O.Ib.oh])};h.uri.O.D6=function(a){a=h.uri.O.split(a);return h.uri.O.$n(a[h.uri.O.Ib.Ii],null,a[h.uri.O.Ib.gh],a[h.uri.O.Ib.oh])};\nh.uri.O.G6=function(a){a=h.uri.O.split(a);return h.uri.O.$n(null,null,null,null,a[h.uri.O.Ib.Fp],a[h.uri.O.Ib.kn],a[h.uri.O.Ib.xp])};h.uri.O.uP=function(a){var b=a.indexOf(\"#\");return 0>b?a:a.substr(0,b)};h.uri.O.ZM=function(a,b){a=h.uri.O.split(a);b=h.uri.O.split(b);return a[h.uri.O.Ib.gh]==b[h.uri.O.Ib.gh]&&a[h.uri.O.Ib.Ii]==b[h.uri.O.Ib.Ii]&&a[h.uri.O.Ib.oh]==b[h.uri.O.Ib.oh]};\nh.uri.O.OJ=function(a){h.R.assert(0>a.indexOf(\"#\")&&0>a.indexOf(\"?\"),\"goog.uri.utils: Fragment or query identifiers are not supported: [%s]\",a)};h.uri.O.SO=function(a,b){if(a){a=a.split(\"\\x26\");for(var c=0;c<a.length;c++){var e=a[c].indexOf(\"\\x3d\"),g,k=null;0<=e?(g=a[c].substring(0,e),k=a[c].substring(e+1)):g=a[c];b(g,k?h.ca.ep(k):\"\")}}};h.uri.O.Vq=function(a){if(a[1]){var b=a[0],c=b.indexOf(\"#\");0<=c&&(a.push(b.substr(c)),a[0]=b=b.substr(0,c));c=b.indexOf(\"?\");0>c?a[1]=\"?\":c==b.length-1&&(a[1]=void 0)}return a.join(\"\")};\nh.uri.O.Uq=function(a,b,c){if(h.isArray(b)){h.R.NJ(b);for(var e=0;e<b.length;e++)h.uri.O.Uq(a,String(b[e]),c)}else null!=b&&c.push(\"\\x26\",a,\"\"===b?\"\":\"\\x3d\",h.ca.Hm(b))};h.uri.O.dr=function(a,b,c){h.R.assert(0==Math.max(b.length-(c||0),0)%2,\"goog.uri.utils: Key/value lists must be even in length.\");for(c=c||0;c<b.length;c+=2)h.uri.O.Uq(b[c],b[c+1],a);return a};h.uri.O.S2=function(a,b){a=h.uri.O.dr([],a,b);a[0]=\"\";return a.join(\"\")};h.uri.O.Ww=function(a,b){for(var c in b)h.uri.O.Uq(c,b[c],a);return a};\nh.uri.O.T2=function(a){a=h.uri.O.Ww([],a);a[0]=\"\";return a.join(\"\")};h.uri.O.Y1=function(a,b){return h.uri.O.Vq(2==arguments.length?h.uri.O.dr([a],arguments[1],0):h.uri.O.dr([a],arguments,1))};h.uri.O.Z1=function(a,b){return h.uri.O.Vq(h.uri.O.Ww([a],b))};h.uri.O.KJ=function(a,b,c){a=[a,\"\\x26\",b];h.Ch(c)&&a.push(\"\\x3d\",h.ca.Hm(c));return h.uri.O.Vq(a)};\nh.uri.O.ro=function(a,b,c,e){for(var g=c.length;0<=(b=a.indexOf(c,b))&&b<e;){var k=a.charCodeAt(b-1);if(k==h.uri.O.Gk.Ht||k==h.uri.O.Gk.qE)if(k=a.charCodeAt(b+g),!k||k==h.uri.O.Gk.EQUAL||k==h.uri.O.Gk.Ht||k==h.uri.O.Gk.BD)return b;b+=g+1}return-1};h.uri.O.Ao=/#|$/;h.uri.O.P6=function(a,b){return 0<=h.uri.O.ro(a,0,b,a.search(h.uri.O.Ao))};\nh.uri.O.E6=function(a,b){var c=a.search(h.uri.O.Ao),e=h.uri.O.ro(a,0,b,c);if(0>e)return null;var g=a.indexOf(\"\\x26\",e);if(0>g||g>c)g=c;e+=b.length+1;return h.ca.ep(a.substr(e,g-e))};h.uri.O.F6=function(a,b){for(var c=a.search(h.uri.O.Ao),e=0,g,k=[];0<=(g=h.uri.O.ro(a,e,b,c));){e=a.indexOf(\"\\x26\",g);if(0>e||e>c)e=c;g+=b.length+1;k.push(h.ca.ep(a.substr(g,e-g)))}return k};h.uri.O.sW=/[?&]($|#)/;\nh.uri.O.wP=function(a,b){for(var c=a.search(h.uri.O.Ao),e=0,g,k=[];0<=(g=h.uri.O.ro(a,e,b,c));)k.push(a.substring(e,g)),e=Math.min(a.indexOf(\"\\x26\",g)+1||c,c);k.push(a.substr(e));return k.join(\"\").replace(h.uri.O.sW,\"$1\")};h.uri.O.HT=function(a,b,c){return h.uri.O.KJ(h.uri.O.wP(a,b),b,c)};h.uri.O.a2=function(a,b){h.uri.O.OJ(a);h.ca.endsWith(a,\"/\")&&(a=a.substr(0,a.length-1));h.ca.startsWith(b,\"/\")&&(b=b.substr(1));return h.ca.ZJ(a,\"/\",b)};\nh.uri.O.uj=function(a,b){h.ca.startsWith(b,\"/\")||(b=\"/\"+b);a=h.uri.O.split(a);return h.uri.O.$n(a[h.uri.O.Ib.Ii],a[h.uri.O.Ib.mn],a[h.uri.O.Ib.gh],a[h.uri.O.Ib.oh],b,a[h.uri.O.Ib.kn],a[h.uri.O.Ib.xp])};h.uri.O.cv={Zu:\"zx\"};h.uri.O.cO=function(a){return h.uri.O.HT(a,h.uri.O.cv.Zu,h.ca.eA())};h.Ab={};h.Ab.paa=function(a){return Math.floor(Math.random()*a)};h.Ab.lda=function(a,b){return a+Math.random()*(b-a)};h.Ab.clamp=function(a,b,c){return Math.min(Math.max(a,b),c)};\nh.Ab.PB=function(a,b){a%=b;return 0>a*b?a+b:a};h.Ab.h8=function(a,b,c){return a+c*(b-a)};h.Ab.p9=function(a,b,c){return Math.abs(a-b)<=(c||1E-6)};h.Ab.vt=function(a){return h.Ab.PB(a,360)};h.Ab.Mba=function(a){return h.Ab.PB(a,2*Math.PI)};h.Ab.FC=function(a){return a*Math.PI/180};h.Ab.oW=function(a){return 180*a/Math.PI};h.Ab.V1=function(a,b){return b*Math.cos(h.Ab.FC(a))};h.Ab.W1=function(a,b){return b*Math.sin(h.Ab.FC(a))};h.Ab.angle=function(a,b,c,e){return h.Ab.vt(h.Ab.oW(Math.atan2(e-b,c-a)))};\nh.Ab.U1=function(a,b){a=h.Ab.vt(b)-h.Ab.vt(a);180<a?a-=360:-180>=a&&(a=360+a);return a};h.Ab.sign=function(a){return 0<a?1:0>a?-1:a};\nh.Ab.o8=function(a,b,c,e){c=c||function(a,b){return a==b};e=e||function(b){return a[b]};for(var g=a.length,k=b.length,m=[],n=0;n<g+1;n++)m[n]=[],m[n][0]=0;for(var q=0;q<k+1;q++)m[0][q]=0;for(n=1;n<=g;n++)for(q=1;q<=k;q++)c(a[n-1],b[q-1])?m[n][q]=m[n-1][q-1]+1:m[n][q]=Math.max(m[n-1][q],m[n][q-1]);for(var v=[],n=g,q=k;0<n&&0<q;)c(a[n-1],b[q-1])?(v.unshift(e(n-1,q-1)),n--,q--):m[n-1][q]>m[n][q-1]?n--:q--;return v};h.Ab.sum=function(a){return h.aa.reduce(arguments,function(a,c){return a+c},0)};\nh.Ab.Pw=function(a){return h.Ab.sum.apply(null,arguments)/arguments.length};h.Ab.VP=function(a){var b=arguments.length;if(2>b)return 0;var c=h.Ab.Pw.apply(null,arguments);return b=h.Ab.sum.apply(null,h.aa.map(arguments,function(a){return Math.pow(a-c,2)}))/(b-1)};h.Ab.fW=function(a){return Math.sqrt(h.Ab.VP.apply(null,arguments))};h.Ab.Do=function(a){return isFinite(a)&&0==a%1};h.Ab.J7=function(a){return isFinite(a)&&!isNaN(a)};h.Ab.N7=function(a){return 0==a&&0>1/a};\nh.Ab.k8=function(a){if(0<a){var b=Math.round(Math.log(a)*Math.LOG10E);return b-(parseFloat(\"1e\"+b)>a?1:0)}return 0==a?-Infinity:NaN};h.Ab.Raa=function(a,b){h.R.assert(!h.Pe(b)||0<b);return Math.floor(a+(b||2E-15))};h.Ab.Qaa=function(a,b){h.R.assert(!h.Pe(b)||0<b);return Math.ceil(a-(b||2E-15))};h.Eb={};h.Eb.zh=function(a){return a.zh&&\"function\"==typeof a.zh?a.zh():h.Gd(a)||h.Hb(a)?a.length:h.object.zh(a)};\nh.Eb.Lc=function(a){if(a.Lc&&\"function\"==typeof a.Lc)return a.Lc();if(h.Hb(a))return a.split(\"\");if(h.Gd(a)){for(var b=[],c=a.length,e=0;e<c;e++)b.push(a[e]);return b}return h.object.Lc(a)};h.Eb.getKeys=function(a){if(a.getKeys&&\"function\"==typeof a.getKeys)return a.getKeys();if(!a.Lc||\"function\"!=typeof a.Lc){if(h.Gd(a)||h.Hb(a)){var b=[];a=a.length;for(var c=0;c<a;c++)b.push(c);return b}return h.object.getKeys(a)}};\nh.Eb.contains=function(a,b){return a.contains&&\"function\"==typeof a.contains?a.contains(b):a.ej&&\"function\"==typeof a.ej?a.ej(b):h.Gd(a)||h.Hb(a)?h.aa.contains(a,b):h.object.ej(a,b)};h.Eb.Zc=function(a){return a.Zc&&\"function\"==typeof a.Zc?a.Zc():h.Gd(a)||h.Hb(a)?h.aa.Zc(a):h.object.Zc(a)};h.Eb.clear=function(a){a.clear&&\"function\"==typeof a.clear?a.clear():h.Gd(a)?h.aa.clear(a):h.object.clear(a)};\nh.Eb.forEach=function(a,b,c){if(a.forEach&&\"function\"==typeof a.forEach)a.forEach(b,c);else if(h.Gd(a)||h.Hb(a))h.aa.forEach(a,b,c);else for(var e=h.Eb.getKeys(a),g=h.Eb.Lc(a),k=g.length,m=0;m<k;m++)b.call(c,g[m],e&&e[m],a)};\nh.Eb.filter=function(a,b,c){if(\"function\"==typeof a.filter)return a.filter(b,c);if(h.Gd(a)||h.Hb(a))return h.aa.filter(a,b,c);var e,g=h.Eb.getKeys(a),k=h.Eb.Lc(a),m=k.length;if(g){e={};for(var n=0;n<m;n++)b.call(c,k[n],g[n],a)&&(e[g[n]]=k[n])}else for(e=[],n=0;n<m;n++)b.call(c,k[n],void 0,a)&&e.push(k[n]);return e};\nh.Eb.map=function(a,b,c){if(\"function\"==typeof a.map)return a.map(b,c);if(h.Gd(a)||h.Hb(a))return h.aa.map(a,b,c);var e,g=h.Eb.getKeys(a),k=h.Eb.Lc(a),m=k.length;if(g){e={};for(var n=0;n<m;n++)e[g[n]]=b.call(c,k[n],g[n],a)}else for(e=[],n=0;n<m;n++)e[n]=b.call(c,k[n],void 0,a);return e};\nh.Eb.some=function(a,b,c){if(\"function\"==typeof a.some)return a.some(b,c);if(h.Gd(a)||h.Hb(a))return h.aa.some(a,b,c);for(var e=h.Eb.getKeys(a),g=h.Eb.Lc(a),k=g.length,m=0;m<k;m++)if(b.call(c,g[m],e&&e[m],a))return!0;return!1};h.Eb.every=function(a,b,c){if(\"function\"==typeof a.every)return a.every(b,c);if(h.Gd(a)||h.Hb(a))return h.aa.every(a,b,c);for(var e=h.Eb.getKeys(a),g=h.Eb.Lc(a),k=g.length,m=0;m<k;m++)if(!b.call(c,g[m],e&&e[m],a))return!1;return!0};h.ta={};\nh.ta.We=\"StopIteration\"in h.global?h.global.StopIteration:{message:\"StopIteration\",stack:\"\"};h.ta.Iterator=function(){};h.ta.Iterator.prototype.next=function(){throw h.ta.We;};h.ta.Iterator.prototype.Wp=function(){return this};h.ta.Hd=function(a){if(a instanceof h.ta.Iterator)return a;if(\"function\"==typeof a.Wp)return a.Wp(!1);if(h.Gd(a)){var b=0,c=new h.ta.Iterator;c.next=function(){for(;;){if(b>=a.length)throw h.ta.We;if(b in a)return a[b++];b++}};return c}throw Error(\"Not implemented\");};\nh.ta.forEach=function(a,b,c){if(h.Gd(a))try{h.aa.forEach(a,b,c)}catch(e){if(e!==h.ta.We)throw e;}else{a=h.ta.Hd(a);try{for(;;)b.call(c,a.next(),void 0,a)}catch(e){if(e!==h.ta.We)throw e;}}};h.ta.filter=function(a,b,c){var e=h.ta.Hd(a);a=new h.ta.Iterator;a.next=function(){for(;;){var a=e.next();if(b.call(c,a,void 0,e))return a}};return a};h.ta.Y5=function(a,b,c){return h.ta.filter(a,h.gc.not(b),c)};\nh.ta.range=function(a,b,c){var e=0,g=a,k=c||1;1<arguments.length&&(e=a,g=b);if(0==k)throw Error(\"Range step argument must not be zero\");var m=new h.ta.Iterator;m.next=function(){if(0<k&&e>=g||0>k&&e<=g)throw h.ta.We;var a=e;e+=k;return a};return m};h.ta.join=function(a,b){return h.ta.toArray(a).join(b)};h.ta.map=function(a,b,c){var e=h.ta.Hd(a);a=new h.ta.Iterator;a.next=function(){var a=e.next();return b.call(c,a,void 0,e)};return a};\nh.ta.reduce=function(a,b,c,e){var g=c;h.ta.forEach(a,function(a){g=b.call(e,g,a)});return g};h.ta.some=function(a,b,c){a=h.ta.Hd(a);try{for(;;)if(b.call(c,a.next(),void 0,a))return!0}catch(e){if(e!==h.ta.We)throw e;}return!1};h.ta.every=function(a,b,c){a=h.ta.Hd(a);try{for(;;)if(!b.call(c,a.next(),void 0,a))return!1}catch(e){if(e!==h.ta.We)throw e;}return!0};h.ta.p3=function(a){return h.ta.eK(arguments)};\nh.ta.eK=function(a){var b=h.ta.Hd(a);a=new h.ta.Iterator;var c=null;a.next=function(){for(;;){if(null==c){var a=b.next();c=h.ta.Hd(a)}try{return c.next()}catch(g){if(g!==h.ta.We)throw g;c=null}}};return a};h.ta.i5=function(a,b,c){var e=h.ta.Hd(a);a=new h.ta.Iterator;var g=!0;a.next=function(){for(;;){var a=e.next();if(!g||!b.call(c,a,void 0,e))return g=!1,a}};return a};\nh.ta.vca=function(a,b,c){var e=h.ta.Hd(a);a=new h.ta.Iterator;a.next=function(){var a=e.next();if(b.call(c,a,void 0,e))return a;throw h.ta.We;};return a};h.ta.toArray=function(a){if(h.Gd(a))return h.aa.toArray(a);a=h.ta.Hd(a);var b=[];h.ta.forEach(a,function(a){b.push(a)});return b};h.ta.ii=function(a,b,c){var e={};a=h.ta.RW(e,a,b);var g=c||h.aa.tx;return h.ta.every(a,function(a){return g(a[0],a[1])})};h.ta.DO=function(a,b){try{return h.ta.Hd(a).next()}catch(c){if(c!=h.ta.We)throw c;return b}};\nh.ta.product=function(a){var b=h.aa.some(arguments,function(a){return!a.length});if(b||!arguments.length)return new h.ta.Iterator;var b=new h.ta.Iterator,c=arguments,e=h.aa.repeat(0,c.length);b.next=function(){if(e){for(var a=h.aa.map(e,function(a,b){return c[b][a]}),b=e.length-1;0<=b;b--){h.R.assert(e);if(e[b]<c[b].length-1){e[b]++;break}if(0==b){e=null;break}e[b]=0}return a}throw h.ta.We;};return b};\nh.ta.E4=function(a){var b=h.ta.Hd(a),c=[],e=0;a=new h.ta.Iterator;var g=!1;a.next=function(){var a=null;if(!g)try{return a=b.next(),c.push(a),a}catch(m){if(m!=h.ta.We||h.aa.Zc(c))throw m;g=!0}a=c[e];e=(e+1)%c.length;return a};return a};h.ta.count=function(a,b){var c=a||0,e=h.Pe(b)?b:1;a=new h.ta.Iterator;a.next=function(){var a=c;c+=e;return a};return a};h.ta.repeat=function(a){var b=new h.ta.Iterator;b.next=h.gc.cj(a);return b};\nh.ta.K1=function(a){var b=h.ta.Hd(a),c=0;a=new h.ta.Iterator;a.next=function(){return c+=b.next()};return a};h.ta.zip=function(a){var b=arguments,c=new h.ta.Iterator;if(0<b.length){var e=h.aa.map(b,h.ta.Hd);c.next=function(){var a=h.aa.map(e,function(a){return a.next()});return a}}return c};\nh.ta.RW=function(a,b){var c=h.aa.slice(arguments,1),e=new h.ta.Iterator;if(0<c.length){var g=h.aa.map(c,h.ta.Hd);e.next=function(){var b=!1,c=h.aa.map(g,function(c){var e;try{e=c.next(),b=!0}catch(v){if(v!==h.ta.We)throw v;e=a}return e});if(!b)throw h.ta.We;return c}}return e};h.ta.L3=function(a,b){var c=h.ta.Hd(b);return h.ta.filter(a,function(){return!!c.next()})};h.ta.Sm=function(a,b){this.iterator=h.ta.Hd(a);this.DB=b||h.gc.bN};h.da(h.ta.Sm,h.ta.Iterator);\nh.ta.Sm.prototype.next=function(){for(;this.Bl==this.EC;)this.mo=this.iterator.next(),this.Bl=this.DB(this.mo);this.EC=this.Bl;return[this.Bl,this.QM(this.EC)]};h.ta.Sm.prototype.QM=function(a){for(var b=[];this.Bl==a;){b.push(this.mo);try{this.mo=this.iterator.next()}catch(c){if(c!==h.ta.We)throw c;break}this.Bl=this.DB(this.mo)}return b};h.ta.O6=function(a,b){return new h.ta.Sm(a,b)};\nh.ta.Nba=function(a,b,c){var e=h.ta.Hd(a);a=new h.ta.Iterator;a.next=function(){var a=h.ta.toArray(e.next());return b.apply(c,h.aa.concat(a,void 0,e))};return a};h.ta.tee=function(a,b){var c=h.ta.Hd(a);a=h.ni(b)?b:2;var e=h.aa.map(h.aa.range(a),function(){return[]}),g=function(){var a=c.next();h.aa.forEach(e,function(b){b.push(a)})};a=function(a){var b=new h.ta.Iterator;b.next=function(){h.aa.Zc(a)&&g();h.R.assert(!h.aa.Zc(a));return a.shift()};return b};return h.aa.map(e,a)};\nh.ta.s5=function(a,b){return h.ta.zip(h.ta.count(b),a)};h.ta.TN=function(a,b){h.R.assert(h.Ab.Do(b)&&0<=b);var c=h.ta.Hd(a);a=new h.ta.Iterator;var e=b;a.next=function(){if(0<e--)return c.next();throw h.ta.We;};return a};h.ta.pK=function(a,b){h.R.assert(h.Ab.Do(b)&&0<=b);for(a=h.ta.Hd(a);0<b--;)h.ta.DO(a,null);return a};h.ta.slice=function(a,b,c){h.R.assert(h.Ab.Do(b)&&0<=b);a=h.ta.pK(a,b);h.ni(c)&&(h.R.assert(h.Ab.Do(c)&&c>=b),a=h.ta.TN(a,c-b));return a};\nh.ta.SM=function(a){var b=[];h.aa.tP(a,b);return a.length!=b.length};h.ta.WO=function(a,b){a=h.ta.toArray(a);b=h.ni(b)?b:a.length;b=h.aa.repeat(a,b);b=h.ta.product.apply(void 0,b);return h.ta.filter(b,function(a){return!h.ta.SM(a)})};h.ta.F3=function(a,b){function c(a){return e[a]}var e=h.ta.toArray(a);a=h.ta.range(e.length);b=h.ta.WO(a,b);var g=h.ta.filter(b,function(a){return h.aa.yB(a)});b=new h.ta.Iterator;b.next=function(){return h.aa.map(g.next(),c)};return b};\nh.ta.G3=function(a,b){function c(a){return e[a]}var e=h.ta.toArray(a);a=h.aa.range(e.length);b=h.aa.repeat(a,b);b=h.ta.product.apply(void 0,b);var g=h.ta.filter(b,function(a){return h.aa.yB(a)});b=new h.ta.Iterator;b.next=function(){return h.aa.map(g.next(),c)};return b};h.Eb.Map=function(a,b){this.jc={};this.Mc=[];this.Im=this.Cc=0;var c=arguments.length;if(1<c){if(c%2)throw Error(\"Uneven number of arguments\");for(var e=0;e<c;e+=2)this.set(arguments[e],arguments[e+1])}else a&&this.addAll(a)};d=h.Eb.Map.prototype;\nd.zh=function(){return this.Cc};d.Lc=function(){this.ek();for(var a=[],b=0;b<this.Mc.length;b++){var c=this.Mc[b];a.push(this.jc[c])}return a};d.getKeys=function(){this.ek();return this.Mc.concat()};d.dj=function(a){return h.Eb.Map.jj(this.jc,a)};d.ej=function(a){for(var b=0;b<this.Mc.length;b++){var c=this.Mc[b];if(h.Eb.Map.jj(this.jc,c)&&this.jc[c]==a)return!0}return!1};\nd.ii=function(a,b){if(this===a)return!0;if(this.Cc!=a.zh())return!1;b=b||h.Eb.Map.HK;this.ek();for(var c,e=0;c=this.Mc[e];e++)if(!b(this.get(c),a.get(c)))return!1;return!0};h.Eb.Map.HK=function(a,b){return a===b};d=h.Eb.Map.prototype;d.Zc=function(){return 0==this.Cc};d.clear=function(){this.jc={};this.Im=this.Cc=this.Mc.length=0};d.remove=function(a){return h.Eb.Map.jj(this.jc,a)?(delete this.jc[a],this.Cc--,this.Im++,this.Mc.length>2*this.Cc&&this.ek(),!0):!1};\nd.ek=function(){if(this.Cc!=this.Mc.length){for(var a=0,b=0;a<this.Mc.length;){var c=this.Mc[a];h.Eb.Map.jj(this.jc,c)&&(this.Mc[b++]=c);a++}this.Mc.length=b}if(this.Cc!=this.Mc.length){for(var e={},b=a=0;a<this.Mc.length;)c=this.Mc[a],h.Eb.Map.jj(e,c)||(this.Mc[b++]=c,e[c]=1),a++;this.Mc.length=b}};d.get=function(a,b){return h.Eb.Map.jj(this.jc,a)?this.jc[a]:b};d.set=function(a,b){h.Eb.Map.jj(this.jc,a)||(this.Cc++,this.Mc.push(a),this.Im++);this.jc[a]=b};\nd.addAll=function(a){var b;a instanceof h.Eb.Map?(b=a.getKeys(),a=a.Lc()):(b=h.object.getKeys(a),a=h.object.Lc(a));for(var c=0;c<b.length;c++)this.set(b[c],a[c])};d.forEach=function(a,b){for(var c=this.getKeys(),e=0;e<c.length;e++){var g=c[e],k=this.get(g);a.call(b,k,g,this)}};d.clone=function(){return new h.Eb.Map(this)};d.transpose=function(){for(var a=new h.Eb.Map,b=0;b<this.Mc.length;b++){var c=this.Mc[b],e=this.jc[c];a.set(e,c)}return a};\nd.C=function(){this.ek();for(var a={},b=0;b<this.Mc.length;b++){var c=this.Mc[b];a[c]=this.jc[c]}return a};d.Wp=function(a){this.ek();var b=0,c=this.Im,e=this,g=new h.ta.Iterator;g.next=function(){if(c!=e.Im)throw Error(\"The map has changed since the iterator was created\");if(b>=e.Mc.length)throw h.ta.We;var g=e.Mc[b++];return a?g:e.jc[g]};return g};h.Eb.Map.jj=function(a,b){return Object.prototype.hasOwnProperty.call(a,b)};\nh.ab=function(a,b){this.tr=this.Dt=this.yk=\"\";this.Po=null;this.Ar=this.vk=\"\";this.ug=this.DN=!1;var c;a instanceof h.ab?(this.ug=h.Pe(b)?b:a.ug,this.Wo(a.bm()),this.Xo(a.yo()),this.To(a.uo()),this.Vo(a.wo()),this.uj(a.ij()),this.zm(a.Mr().clone()),this.Uo(a.vo())):a&&(c=h.uri.O.split(String(a)))?(this.ug=!!b,this.Wo(c[h.uri.O.Ib.Ii]||\"\",!0),this.Xo(c[h.uri.O.Ib.mn]||\"\",!0),this.To(c[h.uri.O.Ib.gh]||\"\",!0),this.Vo(c[h.uri.O.Ib.oh]),this.uj(c[h.uri.O.Ib.Fp]||\"\",!0),this.zm(c[h.uri.O.Ib.kn]||\"\",!0),\nthis.Uo(c[h.uri.O.Ib.xp]||\"\",!0)):(this.ug=!!b,this.Gh=new h.ab.Sg(null,null,this.ug))};h.ab.ZO=!1;h.ab.rE=h.uri.O.cv.Zu;d=h.ab.prototype;\nd.toString=function(){var a=[],b=this.bm();b&&a.push(h.ab.Gl(b,h.ab.aC,!0),\":\");var c=this.uo();if(c||\"file\"==b)a.push(\"//\"),(b=this.yo())&&a.push(h.ab.Gl(b,h.ab.aC,!0),\"@\"),a.push(h.ab.fC(h.ca.Hm(c))),c=this.wo(),null!=c&&a.push(\":\",String(c));if(c=this.ij())this.Wr()&&\"/\"!=c.charAt(0)&&a.push(\"/\"),a.push(h.ab.Gl(c,\"/\"==c.charAt(0)?h.ab.gP:h.ab.jP,!0));(c=this.Ky())&&a.push(\"?\",c);(c=this.vo())&&a.push(\"#\",h.ab.Gl(c,h.ab.hP));return a.join(\"\")};\nd.resolve=function(a){var b=this.clone(),c=a.WM();c?b.Wo(a.bm()):c=a.XM();c?b.Xo(a.yo()):c=a.Wr();c?b.To(a.uo()):c=a.UM();var e=a.ij();if(c)b.Vo(a.wo());else if(c=a.Yr()){if(\"/\"!=e.charAt(0))if(this.Wr()&&!this.Yr())e=\"/\"+e;else{var g=b.ij().lastIndexOf(\"/\");-1!=g&&(e=b.ij().substr(0,g+1)+e)}e=h.ab.sP(e)}c?b.uj(e):c=a.VM();c?b.zm(a.Mr().clone()):c=a.TM();c&&b.Uo(a.vo());return b};d.clone=function(){return new h.ab(this)};d.bm=function(){return this.yk};\nd.Wo=function(a,b){this.xh();if(this.yk=b?h.ab.El(a,!0):a)this.yk=this.yk.replace(/:$/,\"\");return this};d.WM=function(){return!!this.yk};d.yo=function(){return this.Dt};d.Xo=function(a,b){this.xh();this.Dt=b?h.ab.El(a):a;return this};d.XM=function(){return!!this.Dt};d.uo=function(){return this.tr};d.To=function(a,b){this.xh();this.tr=b?h.ab.El(a,!0):a;return this};d.Wr=function(){return!!this.tr};d.wo=function(){return this.Po};\nd.Vo=function(a){this.xh();if(a){a=Number(a);if(isNaN(a)||0>a)throw Error(\"Bad port number \"+a);this.Po=a}else this.Po=null;return this};d.UM=function(){return null!=this.Po};d.ij=function(){return this.vk};d.uj=function(a,b){this.xh();this.vk=b?h.ab.El(a,!0):a;return this};d.Yr=function(){return!!this.vk};d.VM=function(){return\"\"!==this.Gh.toString()};\nd.zm=function(a,b){this.xh();a instanceof h.ab.Sg?(this.Gh=a,this.Gh.Ws(this.ug)):(b||(a=h.ab.Gl(a,h.ab.iP)),this.Gh=new h.ab.Sg(a,null,this.ug));return this};d.setQuery=function(a,b){return this.zm(a,b)};d.Ky=function(){return this.Gh.toString()};d.Mr=function(){return this.Gh};d.getQuery=function(){return this.Ky()};d.IT=function(a,b){this.xh();this.Gh.set(a,b);return this};d.vo=function(){return this.Ar};d.Uo=function(a,b){this.xh();this.Ar=b?h.ab.El(a):a;return this};d.TM=function(){return!!this.Ar};\nd.cO=function(){this.xh();this.IT(h.ab.rE,h.ca.eA());return this};d.xh=function(){if(this.DN)throw Error(\"Tried to modify a read-only Uri\");};d.Ws=function(a){this.ug=a;this.Gh&&this.Gh.Ws(a);return this};h.ab.parse=function(a,b){return a instanceof h.ab?a.clone():new h.ab(a,b)};h.ab.create=function(a,b,c,e,g,k,m,n){n=new h.ab(null,n);a&&n.Wo(a);b&&n.Xo(b);c&&n.To(c);e&&n.Vo(e);g&&n.uj(g);k&&n.zm(k);m&&n.Uo(m);return n};\nh.ab.resolve=function(a,b){a instanceof h.ab||(a=h.ab.parse(a));b instanceof h.ab||(b=h.ab.parse(b));return a.resolve(b)};h.ab.sP=function(a){if(\"..\"==a||\".\"==a)return\"\";if(h.ca.contains(a,\"./\")||h.ca.contains(a,\"/.\")){var b=h.ca.startsWith(a,\"/\");a=a.split(\"/\");for(var c=[],e=0;e<a.length;){var g=a[e++];\".\"==g?b&&e==a.length&&c.push(\"\"):\"..\"==g?((1<c.length||1==c.length&&\"\"!=c[0])&&c.pop(),b&&e==a.length&&c.push(\"\")):(c.push(g),b=!0)}return c.join(\"/\")}return a};\nh.ab.El=function(a,b){return a?b?decodeURI(a.replace(/%25/g,\"%2525\")):decodeURIComponent(a):\"\"};h.ab.Gl=function(a,b,c){return h.Hb(a)?(a=encodeURI(a).replace(b,h.ab.PK),c&&(a=h.ab.fC(a)),a):null};h.ab.PK=function(a){a=a.charCodeAt(0);return\"%\"+(a>>4&15).toString(16)+(a&15).toString(16)};h.ab.fC=function(a){return a.replace(/%25([0-9a-fA-F]{2})/g,\"%$1\")};h.ab.aC=/[#\\/\\?@]/g;h.ab.jP=/[\\#\\?:]/g;h.ab.gP=/[\\#\\?]/g;h.ab.iP=/[\\#\\?@]/g;h.ab.hP=/#/g;\nh.ab.ZM=function(a,b){a=h.uri.O.split(a);b=h.uri.O.split(b);return a[h.uri.O.Ib.gh]==b[h.uri.O.Ib.gh]&&a[h.uri.O.Ib.oh]==b[h.uri.O.Ib.oh]};h.ab.Sg=function(a,b,c){this.Cc=this.sd=null;this.hi=a||null;this.ug=!!c};h.ab.Sg.prototype.yh=function(){if(!this.sd&&(this.sd=new h.Eb.Map,this.Cc=0,this.hi)){var a=this;h.uri.O.SO(this.hi,function(b,c){a.add(h.ca.ep(b),c)})}};\nh.ab.Sg.w4=function(a,b,c){b=h.Eb.getKeys(a);if(\"undefined\"==typeof b)throw Error(\"Keys are undefined\");c=new h.ab.Sg(null,null,c);a=h.Eb.Lc(a);for(var e=0;e<b.length;e++){var g=b[e],k=a[e];h.isArray(k)?c.Yo(g,k):c.add(g,k)}return c};h.ab.Sg.v4=function(a,b,c,e){if(a.length!=b.length)throw Error(\"Mismatched lengths for keys/values\");c=new h.ab.Sg(null,null,e);for(e=0;e<a.length;e++)c.add(a[e],b[e]);return c};d=h.ab.Sg.prototype;d.zh=function(){this.yh();return this.Cc};\nd.add=function(a,b){this.yh();this.qk();a=this.kk(a);var c=this.sd.get(a);c||this.sd.set(a,c=[]);c.push(b);this.Cc=h.R.ul(this.Cc)+1;return this};d.remove=function(a){this.yh();a=this.kk(a);return this.sd.dj(a)?(this.qk(),this.Cc=h.R.ul(this.Cc)-this.sd.get(a).length,this.sd.remove(a)):!1};d.clear=function(){this.qk();this.sd=null;this.Cc=0};d.Zc=function(){this.yh();return 0==this.Cc};d.dj=function(a){this.yh();a=this.kk(a);return this.sd.dj(a)};\nd.ej=function(a){var b=this.Lc();return h.aa.contains(b,a)};d.getKeys=function(){this.yh();for(var a=this.sd.Lc(),b=this.sd.getKeys(),c=[],e=0;e<b.length;e++)for(var g=a[e],k=0;k<g.length;k++)c.push(b[e]);return c};d.Lc=function(a){this.yh();var b=[];if(h.Hb(a))this.dj(a)&&(b=h.aa.concat(b,this.sd.get(this.kk(a))));else{a=this.sd.Lc();for(var c=0;c<a.length;c++)b=h.aa.concat(b,a[c])}return b};\nd.set=function(a,b){this.yh();this.qk();a=this.kk(a);this.dj(a)&&(this.Cc=h.R.ul(this.Cc)-this.sd.get(a).length);this.sd.set(a,[b]);this.Cc=h.R.ul(this.Cc)+1;return this};d.get=function(a,b){a=a?this.Lc(a):[];return h.ab.ZO?0<a.length?a[0]:b:0<a.length?String(a[0]):b};d.Yo=function(a,b){this.remove(a);0<b.length&&(this.qk(),this.sd.set(this.kk(a),h.aa.clone(b)),this.Cc=h.R.ul(this.Cc)+b.length)};\nd.toString=function(){if(this.hi)return this.hi;if(!this.sd)return\"\";for(var a=[],b=this.sd.getKeys(),c=0;c<b.length;c++)for(var e=b[c],g=h.ca.Hm(e),e=this.Lc(e),k=0;k<e.length;k++){var m=g;\"\"!==e[k]&&(m+=\"\\x3d\"+h.ca.Hm(e[k]));a.push(m)}return this.hi=a.join(\"\\x26\")};d.qk=function(){this.hi=null};d.clone=function(){var a=new h.ab.Sg;a.hi=this.hi;this.sd&&(a.sd=this.sd.clone(),a.Cc=this.Cc);return a};d.kk=function(a){a=String(a);this.ug&&(a=a.toLowerCase());return a};\nd.Ws=function(a){var b=a&&!this.ug;b&&(this.yh(),this.qk(),this.sd.forEach(function(a,b){var c=b.toLowerCase();b!=c&&(this.remove(b),this.Yo(c,a))},this));this.ug=a};d.extend=function(a){for(var b=0;b<arguments.length;b++){var c=arguments[b];h.Eb.forEach(c,function(a,b){this.add(b,a)},this)}};x.google={};x.google.N={};x.google.N.ge=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.google.N.ge,l.u);\nl.u.ha&&(x.google.N.ge.prototype.C=function(a){return x.google.N.ge.C(a,this)},x.google.N.ge.C=function(a,b){var c={jda:l.u.va(b,1,\"\"),value:b.Qr()};a&&(c.ja=b);return c});x.google.N.ge.ia=function(a){a=new l.ba(a);var b=new x.google.N.ge;return x.google.N.ge.F(b,a)};x.google.N.ge.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.pt(c);break;case 2:c=b.qm();a.setValue(c);break;default:b.ea()}}return a};\nx.google.N.ge.G=function(a,b){var c;c=a.TA();0<c.length&&b.Ja(1,c);c=a.Rr();0<c.length&&b.fp(2,c)};d=x.google.N.ge.prototype;d.TA=function(){return l.u.va(this,1,\"\")};d.pt=function(a){l.u.J(this,1,a)};d.getValue=function(){return l.u.va(this,2,\"\")};d.Qr=function(){return l.u.ao(this.getValue())};d.Rr=function(){return l.u.hr(this.getValue())};d.setValue=function(a){l.u.J(this,2,a)};x.google.N.ge.K=function(a){return l.u.K(x.google.N.ge,a)};x.google.N.ge.prototype.getTypeName=function(){return this.TA().split(\"/\").pop()};\nx.google.N.ge.prototype.pack=function(a,b,c){c||(c=\"type.googleapis.com/\");\"/\"!=c.substr(-1)?this.pt(c+\"/\"+b):this.pt(c+b);this.setValue(a)};x.google.N.Ba=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.google.N.Ba,l.u);l.u.ha&&(x.google.N.Ba.prototype.C=function(a){return x.google.N.Ba.C(a,this)},x.google.N.Ba.C=function(a,b){var c={value:+l.u.va(b,1,0)};a&&(c.ja=b);return c});x.google.N.Ba.ia=function(a){a=new l.ba(a);var b=new x.google.N.Ba;return x.google.N.Ba.F(b,a)};\nx.google.N.Ba.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.pa();a.setValue(c);break;default:b.ea()}}return a};x.google.N.Ba.G=function(a,b){a=a.getValue();0!==a&&b.ya(1,a)};x.google.N.Ba.prototype.getValue=function(){return+l.u.va(this,1,0)};x.google.N.Ba.prototype.setValue=function(a){l.u.J(this,1,a)};x.google.N.Ba.K=function(a){return l.u.K(x.google.N.Ba,a)};x.google.N.Rf=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.google.N.Rf,l.u);\nl.u.ha&&(x.google.N.Rf.prototype.C=function(a){return x.google.N.Rf.C(a,this)},x.google.N.Rf.C=function(a,b){var c={value:+l.u.va(b,1,0)};a&&(c.ja=b);return c});x.google.N.Rf.ia=function(a){a=new l.ba(a);var b=new x.google.N.Rf;return x.google.N.Rf.F(b,a)};x.google.N.Rf.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.ti();a.setValue(c);break;default:b.ea()}}return a};x.google.N.Rf.G=function(a,b){a=a.getValue();0!==a&&b.vi(1,a)};\nx.google.N.Rf.prototype.getValue=function(){return+l.u.va(this,1,0)};x.google.N.Rf.prototype.setValue=function(a){l.u.J(this,1,a)};x.google.N.Rf.K=function(a){return l.u.K(x.google.N.Rf,a)};x.google.N.Tf=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.google.N.Tf,l.u);l.u.ha&&(x.google.N.Tf.prototype.C=function(a){return x.google.N.Tf.C(a,this)},x.google.N.Tf.C=function(a,b){var c={value:l.u.va(b,1,0)};a&&(c.ja=b);return c});\nx.google.N.Tf.ia=function(a){a=new l.ba(a);var b=new x.google.N.Tf;return x.google.N.Tf.F(b,a)};x.google.N.Tf.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.ad();a.setValue(c);break;default:b.ea()}}return a};x.google.N.Tf.G=function(a,b){a=a.getValue();0!==a&&b.td(1,a)};x.google.N.Tf.prototype.getValue=function(){return l.u.va(this,1,0)};x.google.N.Tf.prototype.setValue=function(a){l.u.J(this,1,a)};x.google.N.Tf.K=function(a){return l.u.K(x.google.N.Tf,a)};\nx.google.N.Zf=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.google.N.Zf,l.u);l.u.ha&&(x.google.N.Zf.prototype.C=function(a){return x.google.N.Zf.C(a,this)},x.google.N.Zf.C=function(a,b){var c={value:l.u.va(b,1,0)};a&&(c.ja=b);return c});x.google.N.Zf.ia=function(a){a=new l.ba(a);var b=new x.google.N.Zf;return x.google.N.Zf.F(b,a)};x.google.N.Zf.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.ee();a.setValue(c);break;default:b.ea()}}return a};\nx.google.N.Zf.G=function(a,b){a=a.getValue();0!==a&&b.ye(1,a)};x.google.N.Zf.prototype.getValue=function(){return l.u.va(this,1,0)};x.google.N.Zf.prototype.setValue=function(a){l.u.J(this,1,a)};x.google.N.Zf.K=function(a){return l.u.K(x.google.N.Zf,a)};x.google.N.qc=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.google.N.qc,l.u);l.u.ha&&(x.google.N.qc.prototype.C=function(a){return x.google.N.qc.C(a,this)},x.google.N.qc.C=function(a,b){var c={value:l.u.va(b,1,0)};a&&(c.ja=b);return c});\nx.google.N.qc.ia=function(a){a=new l.ba(a);var b=new x.google.N.qc;return x.google.N.qc.F(b,a)};x.google.N.qc.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Ya();a.setValue(c);break;default:b.ea()}}return a};x.google.N.qc.G=function(a,b){a=a.getValue();0!==a&&b.$a(1,a)};x.google.N.qc.prototype.getValue=function(){return l.u.va(this,1,0)};x.google.N.qc.prototype.setValue=function(a){l.u.J(this,1,a)};x.google.N.qc.K=function(a){return l.u.K(x.google.N.qc,a)};\nx.google.N.Yf=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.google.N.Yf,l.u);l.u.ha&&(x.google.N.Yf.prototype.C=function(a){return x.google.N.Yf.C(a,this)},x.google.N.Yf.C=function(a,b){var c={value:l.u.va(b,1,0)};a&&(c.ja=b);return c});x.google.N.Yf.ia=function(a){a=new l.ba(a);var b=new x.google.N.Yf;return x.google.N.Yf.F(b,a)};x.google.N.Yf.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Jg();a.setValue(c);break;default:b.ea()}}return a};\nx.google.N.Yf.G=function(a,b){a=a.getValue();0!==a&&b.Pg(1,a)};x.google.N.Yf.prototype.getValue=function(){return l.u.va(this,1,0)};x.google.N.Yf.prototype.setValue=function(a){l.u.J(this,1,a)};x.google.N.Yf.K=function(a){return l.u.K(x.google.N.Yf,a)};x.google.N.Of=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.google.N.Of,l.u);l.u.ha&&(x.google.N.Of.prototype.C=function(a){return x.google.N.Of.C(a,this)},x.google.N.Of.C=function(a,b){var c={value:l.u.va(b,1,!1)};a&&(c.ja=b);return c});\nx.google.N.Of.ia=function(a){a=new l.ba(a);var b=new x.google.N.Of;return x.google.N.Of.F(b,a)};x.google.N.Of.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.vf();a.setValue(c);break;default:b.ea()}}return a};x.google.N.Of.G=function(a,b){(a=a.getValue())&&b.kf(1,a)};x.google.N.Of.prototype.getValue=function(){return l.u.va(this,1,!1)};x.google.N.Of.prototype.setValue=function(a){l.u.J(this,1,a)};x.google.N.Of.K=function(a){return l.u.K(x.google.N.Of,a)};\nx.google.N.Ke=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.google.N.Ke,l.u);l.u.ha&&(x.google.N.Ke.prototype.C=function(a){return x.google.N.Ke.C(a,this)},x.google.N.Ke.C=function(a,b){var c={value:l.u.va(b,1,\"\")};a&&(c.ja=b);return c});x.google.N.Ke.ia=function(a){a=new l.ba(a);var b=new x.google.N.Ke;return x.google.N.Ke.F(b,a)};x.google.N.Ke.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.setValue(c);break;default:b.ea()}}return a};\nx.google.N.Ke.G=function(a,b){a=a.getValue();0<a.length&&b.Ja(1,a)};x.google.N.Ke.prototype.getValue=function(){return l.u.va(this,1,\"\")};x.google.N.Ke.prototype.setValue=function(a){l.u.J(this,1,a)};x.google.N.Ke.K=function(a){return l.u.K(x.google.N.Ke,a)};x.google.N.mf=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.google.N.mf,l.u);l.u.ha&&(x.google.N.mf.prototype.C=function(a){return x.google.N.mf.C(a,this)},x.google.N.mf.C=function(a,b){var c={value:b.Qr()};a&&(c.ja=b);return c});\nx.google.N.mf.ia=function(a){a=new l.ba(a);var b=new x.google.N.mf;return x.google.N.mf.F(b,a)};x.google.N.mf.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.qm();a.setValue(c);break;default:b.ea()}}return a};x.google.N.mf.G=function(a,b){a=a.Rr();0<a.length&&b.fp(1,a)};x.google.N.mf.prototype.getValue=function(){return l.u.va(this,1,\"\")};x.google.N.mf.prototype.Qr=function(){return l.u.ao(this.getValue())};x.google.N.mf.prototype.Rr=function(){return l.u.hr(this.getValue())};\nx.google.N.mf.prototype.setValue=function(a){l.u.J(this,1,a)};x.google.N.mf.K=function(a){return l.u.K(x.google.N.mf,a)};x.qa={};x.qa.Yc=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.qa.Yc,l.u);l.u.ha&&(x.qa.Yc.prototype.C=function(a){return x.qa.Yc.C(a,this)},x.qa.Yc.C=function(a,b){var c={O8:+l.u.va(b,1,0),S8:l.u.Na(b,2),W$:+l.u.va(b,3,.1),sca:l.u.va(b,4,!0),T8:l.u.D(b,5),H5:l.u.D(b,6),n5:l.u.D(b,7)};a&&(c.ja=b);return c});\nx.qa.Yc.ia=function(a){a=new l.ba(a);var b=new x.qa.Yc;return x.qa.Yc.F(b,a)};x.qa.Yc.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.pa();a.JS(c);break;case 2:c=b.pa();a.NS(c);break;case 3:c=b.pa();a.dU(c);break;case 4:c=b.vf();a.eV(c);break;case 5:c=b.Ya();a.OS(c);break;case 6:c=b.Aa();a.wR(c);break;case 7:c=b.vf();a.oR(c);break;default:b.ea()}}return a};\nx.qa.Yc.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.ya(1,c);c=l.u.D(a,2);null!=c&&b.ya(2,c);c=l.u.D(a,3);null!=c&&b.ya(3,c);c=l.u.D(a,4);null!=c&&b.kf(4,c);c=l.u.D(a,5);null!=c&&b.$a(5,c);c=l.u.D(a,6);null!=c&&b.Ja(6,c);c=l.u.D(a,7);null!=c&&b.kf(7,c)};d=x.qa.Yc.prototype;d.JS=function(a){l.u.J(this,1,a)};d.NS=function(a){l.u.J(this,2,a)};d.dU=function(a){l.u.J(this,3,a)};d.eV=function(a){l.u.J(this,4,a)};d.OS=function(a){l.u.J(this,5,a)};d.wR=function(a){l.u.J(this,6,a)};\nd.oR=function(a){l.u.J(this,7,a)};x.qa.Yc.K=function(a){return l.u.K(x.qa.Yc,a)};x.qa.eb=function(a){l.u.initialize(this,a,0,-1,x.qa.eb.na,null)};h.da(x.qa.eb,l.u);x.qa.eb.na=[1,2,3,4];l.u.ha&&(x.qa.eb.prototype.C=function(a){return x.qa.eb.C(a,this)},x.qa.eb.C=function(a,b){var c={fca:l.u.Ka(b.BA(),x.qa.eb.Tb.C,a),lca:l.u.Ka(b.DA(),x.qa.eb.Tb.C,a),hca:l.u.Ka(b.CA(),x.qa.eb.Tb.C,a),nca:l.u.Ka(b.EA(),x.qa.eb.Tb.C,a),sO:l.u.D(b,5),tO:l.u.D(b,6)};a&&(c.ja=b);return c});\nx.qa.eb.ia=function(a){a=new l.ba(a);var b=new x.qa.eb;return x.qa.eb.F(b,a)};x.qa.eb.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.qa.eb.Tb;b.T(c,x.qa.eb.Tb.F);a.pJ(c);break;case 2:c=new x.qa.eb.Tb;b.T(c,x.qa.eb.Tb.F);a.uJ(c);break;case 3:c=new x.qa.eb.Tb;b.T(c,x.qa.eb.Tb.F);a.rJ(c);break;case 4:c=new x.qa.eb.Tb;b.T(c,x.qa.eb.Tb.F);a.wJ(c);break;case 5:c=b.Ya();a.bt(c);break;case 6:c=b.Ya();a.ct(c);break;default:b.ea()}}return a};\nx.qa.eb.G=function(a,b){var c;c=a.BA();0<c.length&&b.Oa(1,c,x.qa.eb.Tb.G);c=a.DA();0<c.length&&b.Oa(2,c,x.qa.eb.Tb.G);c=a.CA();0<c.length&&b.Oa(3,c,x.qa.eb.Tb.G);c=a.EA();0<c.length&&b.Oa(4,c,x.qa.eb.Tb.G);c=l.u.D(a,5);null!=c&&b.$a(5,c);c=l.u.D(a,6);null!=c&&b.$a(6,c)};d=x.qa.eb.prototype;d.BA=function(){return l.u.Ma(this,x.qa.eb.Tb,1)};d.pJ=function(a,b){return l.u.La(this,1,a,x.qa.eb.Tb,b)};d.DA=function(){return l.u.Ma(this,x.qa.eb.Tb,2)};\nd.uJ=function(a,b){return l.u.La(this,2,a,x.qa.eb.Tb,b)};d.CA=function(){return l.u.Ma(this,x.qa.eb.Tb,3)};d.rJ=function(a,b){return l.u.La(this,3,a,x.qa.eb.Tb,b)};d.EA=function(){return l.u.Ma(this,x.qa.eb.Tb,4)};d.wJ=function(a,b){return l.u.La(this,4,a,x.qa.eb.Tb,b)};d.bt=function(a){l.u.J(this,5,a)};d.ct=function(a){l.u.J(this,6,a)};x.qa.eb.K=function(a){return l.u.K(x.qa.eb,a)};x.qa.eb.Tb=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.qa.eb.Tb,l.u);\nl.u.ha&&(x.qa.eb.Tb.prototype.C=function(a){return x.qa.eb.Tb.C(a,this)},x.qa.eb.Tb.C=function(a,b){var c={aj:l.u.D(b,1),lowerBound:l.u.Na(b,2),upperBound:l.u.Na(b,3),n7:l.u.D(b,4)};a&&(c.ja=b);return c});x.qa.eb.Tb.ia=function(a){a=new l.ba(a);var b=new x.qa.eb.Tb;return x.qa.eb.Tb.F(b,a)};x.qa.eb.Tb.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.xf(c);break;case 2:c=b.pa();a.tj(c);break;case 3:c=b.pa();a.xj(c);break;case 4:c=b.vf();a.YR(c);break;default:b.ea()}}return a};\nx.qa.eb.Tb.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Ja(1,c);c=l.u.D(a,2);null!=c&&b.ya(2,c);c=l.u.D(a,3);null!=c&&b.ya(3,c);c=l.u.D(a,4);null!=c&&b.kf(4,c)};d=x.qa.eb.Tb.prototype;d.Hg=function(){return l.u.D(this,1)};d.xf=function(a){l.u.J(this,1,a)};d.Xl=function(){return l.u.Na(this,2)};d.tj=function(a){l.u.J(this,2,a)};d.em=function(){return l.u.Na(this,3)};d.xj=function(a){l.u.J(this,3,a)};d.YR=function(a){l.u.J(this,4,a)};x.qa.eb.Tb.K=function(a){return l.u.K(x.qa.eb.Tb,a)};\nx.qa.te=function(a){l.u.initialize(this,a,0,-1,x.qa.te.na,null)};h.da(x.qa.te,l.u);x.qa.te.na=[5,6];l.u.ha&&(x.qa.te.prototype.C=function(a){return x.qa.te.C(a,this)},x.qa.te.C=function(a,b){var c={K9:l.u.va(b,1,7),L9:l.u.va(b,2,14),u4:+l.u.va(b,3,3),t4:+l.u.va(b,4,.3),cN:l.u.D(b,5),UP:l.u.D(b,6)};a&&(c.ja=b);return c});x.qa.te.ia=function(a){a=new l.ba(a);var b=new x.qa.te;return x.qa.te.F(b,a)};\nx.qa.te.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Ya();a.nT(c);break;case 2:c=b.Ya();a.oT(c);break;case 3:c=b.pa();a.UQ(c);break;case 4:c=b.pa();a.TQ(c);break;case 5:c=b.Aa();a.Oq(c);break;case 6:c=b.Aa();a.Sq(c);break;default:b.ea()}}return a};x.qa.te.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.$a(1,c);c=l.u.D(a,2);null!=c&&b.$a(2,c);c=l.u.D(a,3);null!=c&&b.ya(3,c);c=l.u.D(a,4);null!=c&&b.ya(4,c);c=a.Hr();0<c.length&&b.oc(5,c);c=a.Or();0<c.length&&b.oc(6,c)};d=x.qa.te.prototype;\nd.nT=function(a){l.u.J(this,1,a)};d.oT=function(a){l.u.J(this,2,a)};d.UQ=function(a){l.u.J(this,3,a)};d.TQ=function(a){l.u.J(this,4,a)};d.Hr=function(){return l.u.D(this,5)};d.Oq=function(a,b){l.u.ib(this,5,a,b)};d.Or=function(){return l.u.D(this,6)};d.Sq=function(a,b){l.u.ib(this,6,a,b)};x.qa.te.K=function(a){return l.u.K(x.qa.te,a)};x.qa.Tc=function(a){l.u.initialize(this,a,0,-1,x.qa.Tc.na,null)};h.da(x.qa.Tc,l.u);x.qa.Tc.na=[9,6,8];\nl.u.ha&&(x.qa.Tc.prototype.C=function(a){return x.qa.Tc.C(a,this)},x.qa.Tc.C=function(a,b){var c={Gda:l.u.va(b,1,10),sO:l.u.va(b,2,1),tO:l.u.D(b,3),P8:+l.u.va(b,4,.05),Mda:+l.u.va(b,5,5),UP:l.u.D(b,9),cN:l.u.D(b,6),o7:l.u.D(b,8),k9:l.u.va(b,7,1)};a&&(c.ja=b);return c});x.qa.Tc.ia=function(a){a=new l.ba(a);var b=new x.qa.Tc;return x.qa.Tc.F(b,a)};\nx.qa.Tc.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Ya();a.QV(c);break;case 2:c=b.Ya();a.bt(c);break;case 3:c=b.Ya();a.ct(c);break;case 4:c=b.pa();a.KS(c);break;case 5:c=b.pa();a.SV(c);break;case 9:c=b.Aa();a.Sq(c);break;case 6:c=b.Aa();a.Oq(c);break;case 8:c=b.Aa();a.qI(c);break;case 7:c=b.Ya();a.YS(c);break;default:b.ea()}}return a};\nx.qa.Tc.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.$a(1,c);c=l.u.D(a,2);null!=c&&b.$a(2,c);c=l.u.D(a,3);null!=c&&b.$a(3,c);c=l.u.D(a,4);null!=c&&b.ya(4,c);c=l.u.D(a,5);null!=c&&b.ya(5,c);c=a.Or();0<c.length&&b.oc(9,c);c=a.Hr();0<c.length&&b.oc(6,c);c=a.ML();0<c.length&&b.oc(8,c);c=l.u.D(a,7);null!=c&&b.$a(7,c)};d=x.qa.Tc.prototype;d.QV=function(a){l.u.J(this,1,a)};d.bt=function(a){l.u.J(this,2,a)};d.ct=function(a){l.u.J(this,3,a)};d.KS=function(a){l.u.J(this,4,a)};\nd.SV=function(a){l.u.J(this,5,a)};d.Or=function(){return l.u.D(this,9)};d.Sq=function(a,b){l.u.ib(this,9,a,b)};d.Hr=function(){return l.u.D(this,6)};d.Oq=function(a,b){l.u.ib(this,6,a,b)};d.ML=function(){return l.u.D(this,8)};d.qI=function(a,b){l.u.ib(this,8,a,b)};d.YS=function(a){l.u.J(this,7,a)};x.qa.Tc.K=function(a){return l.u.K(x.qa.Tc,a)};x.qa.Af=function(a){l.u.initialize(this,a,0,-1,x.qa.Af.na,null)};h.da(x.qa.Af,l.u);x.qa.Af.na=[2,8];\nl.u.ha&&(x.qa.Af.prototype.C=function(a){return x.qa.Af.C(a,this)},x.qa.Af.C=function(a,b){var c,e={z$:l.u.va(b,1,300),I5:l.u.D(b,2),Z2:(c=b.ey())&&x.qa.Yc.C(a,c),W8:l.u.Ka(b.uz(),x.qa.Yc.C,a),qba:(c=b.pA())&&x.qa.eb.C(a,c),pba:(c=b.oA())&&x.qa.te.C(a,c),oba:(c=b.nA())&&x.qa.Tc.C(a,c)};a&&(e.ja=b);return e});x.qa.Af.ia=function(a){a=new l.ba(a);var b=new x.qa.Af;return x.qa.Af.F(b,a)};\nx.qa.Af.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Ya();a.OT(c);break;case 2:c=b.Aa();a.fI(c);break;case 3:c=new x.qa.Yc;b.T(c,x.qa.Yc.F);a.zQ(c);break;case 8:c=new x.qa.Yc;b.T(c,x.qa.Yc.F);a.CI(c);break;case 4:c=new x.qa.eb;b.T(c,x.qa.eb.F);a.FU(c);break;case 6:c=new x.qa.te;b.T(c,x.qa.te.F);a.EU(c);break;case 7:c=new x.qa.Tc;b.T(c,x.qa.Tc.F);a.DU(c);break;default:b.ea()}}return a};\nx.qa.Af.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.$a(1,c);c=a.CL();0<c.length&&b.oc(2,c);c=a.ey();null!=c&&b.oa(3,c,x.qa.Yc.G);c=a.uz();0<c.length&&b.Oa(8,c,x.qa.Yc.G);c=a.pA();null!=c&&b.oa(4,c,x.qa.eb.G);c=a.oA();null!=c&&b.oa(6,c,x.qa.te.G);c=a.nA();null!=c&&b.oa(7,c,x.qa.Tc.G)};d=x.qa.Af.prototype;d.OT=function(a){l.u.J(this,1,a)};d.CL=function(){return l.u.D(this,2)};d.fI=function(a,b){l.u.ib(this,2,a,b)};d.ey=function(){return l.u.sa(this,x.qa.Yc,3)};d.zQ=function(a){l.u.Ca(this,3,a)};\nd.uz=function(){return l.u.Ma(this,x.qa.Yc,8)};d.CI=function(a,b){return l.u.La(this,8,a,x.qa.Yc,b)};d.pA=function(){return l.u.sa(this,x.qa.eb,4)};d.FU=function(a){l.u.Ca(this,4,a)};d.oA=function(){return l.u.sa(this,x.qa.te,6)};d.EU=function(a){l.u.Ca(this,6,a)};d.nA=function(){return l.u.sa(this,x.qa.Tc,7)};d.DU=function(a){l.u.Ca(this,7,a)};x.qa.Af.K=function(a){return l.u.K(x.qa.Af,a)};x.i.Hc=function(a){l.u.initialize(this,a,0,-1,x.i.Hc.na,null)};h.da(x.i.Hc,l.u);x.i.Hc.na=[4];\nl.u.ha&&(x.i.Hc.prototype.C=function(a){return x.i.Hc.C(a,this)},x.i.Hc.C=function(a,b){var c={W7:l.u.D(b,1),o3:l.u.D(b,2),Fba:l.u.D(b,3),d9:l.u.D(b,4),user:l.u.D(b,5)};a&&(c.ja=b);return c});x.i.Hc.ia=function(a){a=new l.ba(a);var b=new x.i.Hc;return x.i.Hc.F(b,a)};x.i.Hc.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.eS(c);break;case 2:c=b.Aa();a.setCell(c);break;case 3:c=b.Aa();a.NU(c);break;case 4:c=b.Aa();a.GI(c);break;case 5:c=b.Aa();a.GV(c);break;default:b.ea()}}return a};\nx.i.Hc.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Ja(1,c);c=l.u.D(a,2);null!=c&&b.Ja(2,c);c=l.u.D(a,3);null!=c&&b.Ja(3,c);c=a.YL();0<c.length&&b.oc(4,c);c=l.u.D(a,5);null!=c&&b.Ja(5,c)};d=x.i.Hc.prototype;d.eS=function(a){l.u.J(this,1,a)};d.setCell=function(a){l.u.J(this,2,a)};d.NU=function(a){l.u.J(this,3,a)};d.YL=function(){return l.u.D(this,4)};d.GI=function(a,b){l.u.ib(this,4,a,b)};d.GV=function(a){l.u.J(this,5,a)};x.i.Hc.K=function(a){return l.u.K(x.i.Hc,a)};\nx.i.rf=function(a){l.u.initialize(this,a,0,-1,x.i.rf.na,null)};h.da(x.i.rf,l.u);x.i.rf.na=[1];l.u.ha&&(x.i.rf.prototype.C=function(a){return x.i.rf.C(a,this)},x.i.rf.C=function(a,b){var c={NN:l.u.Ka(b.Ul(),x.i.Hc.C,a)};a&&(c.ja=b);return c});x.i.rf.ia=function(a){a=new l.ba(a);var b=new x.i.rf;return x.i.rf.F(b,a)};x.i.rf.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.Hc;b.T(c,x.i.Hc.F);a.Pq(c);break;default:b.ea()}}return a};\nx.i.rf.G=function(a,b){a=a.Ul();0<a.length&&b.Oa(1,a,x.i.Hc.G)};x.i.rf.prototype.Ul=function(){return l.u.Ma(this,x.i.Hc,1)};x.i.rf.prototype.Pq=function(a,b){return l.u.La(this,1,a,x.i.Hc,b)};x.i.rf.K=function(a){return l.u.K(x.i.rf,a)};x.jb={};x.jb.lb={};x.jb.lb.mb=function(a){l.u.initialize(this,a,0,1,null,null)};h.da(x.jb.lb.mb,l.u);\nl.u.ha&&(x.jb.lb.mb.prototype.C=function(a){return x.jb.lb.mb.C(a,this)},x.jb.lb.mb.C=function(a,b){var c={};l.u.pW(b,c,l.u.nj,x.jb.lb.mb.prototype.getExtension,a);a&&(c.ja=b);return c});x.jb.lb.mb.ia=function(a){a=new l.ba(a);var b=new x.jb.lb.mb;return x.jb.lb.mb.F(b,a)};x.jb.lb.mb.F=function(a,b){for(;b.fa()&&!b.ga();)l.u.kP(a,b,l.u.oi,x.jb.lb.mb.prototype.getExtension,x.jb.lb.mb.prototype.yR);return a};x.jb.lb.mb.G=function(a,b){l.u.XP(a,b,l.u.oi,x.jb.lb.mb.prototype.getExtension)};\nx.jb.lb.mb.K=function(a){return l.u.K(x.jb.lb.mb,a)};x.V={};x.V.Wb=function(a){l.u.initialize(this,a,0,-1,null,x.V.Wb.Ob)};h.da(x.V.Wb,l.u);x.V.Wb.Ob=[[1,2,3,4,5,6,7,8,9,10]];x.V.Wb.FY={EY:0,DY:1,RZ:2,hZ:3,AY:4,cY:5,dZ:6,ZW:7,FX:8,eZ:9,v_:10};\nl.u.ha&&(x.V.Wb.prototype.C=function(a){return x.V.Wb.C(a,this)},x.V.Wb.C=function(a,b){var c,e={lm:(c=b.eg())&&x.google.N.ge.C(a,c),Jba:(c=b.uA())&&x.V.jf.C(a,c),XO:(c=b.Zl())&&x.V.gf.C(a,c),aO:(c=b.Wl())&&x.V.ef.C(a,c),m7:(c=b.fz())&&x.V.Pd.C(a,c),p$:(c=b.Mz())&&x.V.He.C(a,c),A2:(c=b.Vx())&&x.V.Jd.C(a,c),L5:(c=b.Ty())&&x.V.De.C(a,c),q$:(c=b.Nz())&&x.V.ff.C(a,c),Cda:(c=b.$A())&&x.V.be.C(a,c)};a&&(e.ja=b);return e});x.V.Wb.ia=function(a){a=new l.ba(a);var b=new x.V.Wb;return x.V.Wb.F(b,a)};\nx.V.Wb.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.google.N.ge;b.T(c,x.google.N.ge.F);a.Ng(c);break;case 2:c=new x.V.jf;b.T(c,x.V.jf.F);a.OU(c);break;case 3:c=new x.V.gf;b.T(c,x.V.gf.F);a.gt(c);break;case 4:c=new x.V.ef;b.T(c,x.V.ef.F);a.Zs(c);break;case 5:c=new x.V.Pd;b.T(c,x.V.Pd.F);a.XR(c);break;case 6:c=new x.V.He;b.T(c,x.V.He.F);a.FT(c);break;case 7:c=new x.V.Jd;b.T(c,x.V.Jd.F);a.rQ(c);break;case 8:c=new x.V.De;b.T(c,x.V.De.F);a.xR(c);break;case 9:c=new x.V.ff;\nb.T(c,x.V.ff.F);a.GT(c);break;case 10:c=new x.V.be;b.T(c,x.V.be.F);a.OV(c);break;default:b.ea()}}return a};\nx.V.Wb.G=function(a,b){var c;c=a.eg();null!=c&&b.oa(1,c,x.google.N.ge.G);c=a.uA();null!=c&&b.oa(2,c,x.V.jf.G);c=a.Zl();null!=c&&b.oa(3,c,x.V.gf.G);c=a.Wl();null!=c&&b.oa(4,c,x.V.ef.G);c=a.fz();null!=c&&b.oa(5,c,x.V.Pd.G);c=a.Mz();null!=c&&b.oa(6,c,x.V.He.G);c=a.Vx();null!=c&&b.oa(7,c,x.V.Jd.G);c=a.Ty();null!=c&&b.oa(8,c,x.V.De.G);c=a.Nz();null!=c&&b.oa(9,c,x.V.ff.G);c=a.$A();null!=c&&b.oa(10,c,x.V.be.G)};d=x.V.Wb.prototype;d.eg=function(){return l.u.sa(this,x.google.N.ge,1)};\nd.Ng=function(a){l.u.Nc(this,1,x.V.Wb.Ob[0],a)};d.uA=function(){return l.u.sa(this,x.V.jf,2)};d.OU=function(a){l.u.Nc(this,2,x.V.Wb.Ob[0],a)};d.Zl=function(){return l.u.sa(this,x.V.gf,3)};d.gt=function(a){l.u.Nc(this,3,x.V.Wb.Ob[0],a)};d.Wl=function(){return l.u.sa(this,x.V.ef,4)};d.Zs=function(a){l.u.Nc(this,4,x.V.Wb.Ob[0],a)};d.fz=function(){return l.u.sa(this,x.V.Pd,5)};d.XR=function(a){l.u.Nc(this,5,x.V.Wb.Ob[0],a)};d.Mz=function(){return l.u.sa(this,x.V.He,6)};\nd.FT=function(a){l.u.Nc(this,6,x.V.Wb.Ob[0],a)};d.Vx=function(){return l.u.sa(this,x.V.Jd,7)};d.rQ=function(a){l.u.Nc(this,7,x.V.Wb.Ob[0],a)};d.Ty=function(){return l.u.sa(this,x.V.De,8)};d.xR=function(a){l.u.Nc(this,8,x.V.Wb.Ob[0],a)};d.Nz=function(){return l.u.sa(this,x.V.ff,9)};d.GT=function(a){l.u.Nc(this,9,x.V.Wb.Ob[0],a)};d.$A=function(){return l.u.sa(this,x.V.be,10)};d.OV=function(a){l.u.Nc(this,10,x.V.Wb.Ob[0],a)};x.V.Wb.K=function(a){return l.u.K(x.V.Wb,a)};\nx.V.jf=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.V.jf,l.u);l.u.ha&&(x.V.jf.prototype.C=function(a){return x.V.jf.C(a,this)},x.V.jf.C=function(a,b){var c={};a&&(c.ja=b);return c});x.V.jf.ia=function(a){a=new l.ba(a);var b=new x.V.jf;return x.V.jf.F(b,a)};x.V.jf.F=function(a,b){for(;b.fa()&&!b.ga();)b.ea();return a};x.V.jf.G=function(){};x.V.jf.K=function(a){return l.u.K(x.V.jf,a)};x.V.gf=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.V.gf,l.u);\nl.u.ha&&(x.V.gf.prototype.C=function(a){return x.V.gf.C(a,this)},x.V.gf.C=function(a,b){var c={};a&&(c.ja=b);return c});x.V.gf.ia=function(a){a=new l.ba(a);var b=new x.V.gf;return x.V.gf.F(b,a)};x.V.gf.F=function(a,b){for(;b.fa()&&!b.ga();)b.ea();return a};x.V.gf.G=function(){};x.V.gf.K=function(a){return l.u.K(x.V.gf,a)};x.V.ef=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.V.ef,l.u);\nl.u.ha&&(x.V.ef.prototype.C=function(a){return x.V.ef.C(a,this)},x.V.ef.C=function(a,b){var c={};a&&(c.ja=b);return c});x.V.ef.ia=function(a){a=new l.ba(a);var b=new x.V.ef;return x.V.ef.F(b,a)};x.V.ef.F=function(a,b){for(;b.fa()&&!b.ga();)b.ea();return a};x.V.ef.G=function(){};x.V.ef.K=function(a){return l.u.K(x.V.ef,a)};x.V.Pd=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.V.Pd,l.u);\nl.u.ha&&(x.V.Pd.prototype.C=function(a){return x.V.Pd.C(a,this)},x.V.Pd.C=function(a,b){var c={w8:+l.u.va(b,1,0),u7:+l.u.va(b,2,0)};a&&(c.ja=b);return c});x.V.Pd.ia=function(a){a=new l.ba(a);var b=new x.V.Pd;return x.V.Pd.F(b,a)};x.V.Pd.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.pa();a.xS(c);break;case 2:c=b.pa();a.bS(c);break;default:b.ea()}}return a};x.V.Pd.G=function(a,b){var c;c=a.TL();0!==c&&b.ya(1,c);c=a.OL();0!==c&&b.ya(2,c)};\nx.V.Pd.prototype.TL=function(){return+l.u.va(this,1,0)};x.V.Pd.prototype.xS=function(a){l.u.J(this,1,a)};x.V.Pd.prototype.OL=function(){return+l.u.va(this,2,0)};x.V.Pd.prototype.bS=function(a){l.u.J(this,2,a)};x.V.Pd.K=function(a){return l.u.K(x.V.Pd,a)};x.V.He=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.V.He,l.u);l.u.ha&&(x.V.He.prototype.C=function(a){return x.V.He.C(a,this)},x.V.He.C=function(a,b){var c={iK:+l.u.va(b,1,0)};a&&(c.ja=b);return c});\nx.V.He.ia=function(a){a=new l.ba(a);var b=new x.V.He;return x.V.He.F(b,a)};x.V.He.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.pa();a.Ms(c);break;default:b.ea()}}return a};x.V.He.G=function(a,b){a=a.Cr();0!==a&&b.ya(1,a)};x.V.He.prototype.Cr=function(){return+l.u.va(this,1,0)};x.V.He.prototype.Ms=function(a){l.u.J(this,1,a)};x.V.He.K=function(a){return l.u.K(x.V.He,a)};x.V.ff=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.V.ff,l.u);\nl.u.ha&&(x.V.ff.prototype.C=function(a){return x.V.ff.C(a,this)},x.V.ff.C=function(a,b){var c={};a&&(c.ja=b);return c});x.V.ff.ia=function(a){a=new l.ba(a);var b=new x.V.ff;return x.V.ff.F(b,a)};x.V.ff.F=function(a,b){for(;b.fa()&&!b.ga();)b.ea();return a};x.V.ff.G=function(){};x.V.ff.K=function(a){return l.u.K(x.V.ff,a)};x.V.De=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.V.De,l.u);\nl.u.ha&&(x.V.De.prototype.C=function(a){return x.V.De.C(a,this)},x.V.De.C=function(a,b){var c={iK:+l.u.va(b,1,0)};a&&(c.ja=b);return c});x.V.De.ia=function(a){a=new l.ba(a);var b=new x.V.De;return x.V.De.F(b,a)};x.V.De.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.pa();a.Ms(c);break;default:b.ea()}}return a};x.V.De.G=function(a,b){a=a.Cr();0!==a&&b.ya(1,a)};x.V.De.prototype.Cr=function(){return+l.u.va(this,1,0)};x.V.De.prototype.Ms=function(a){l.u.J(this,1,a)};\nx.V.De.K=function(a){return l.u.K(x.V.De,a)};x.V.Cd=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.V.Cd,l.u);l.u.ha&&(x.V.Cd.prototype.C=function(a){return x.V.Cd.C(a,this)},x.V.Cd.C=function(a,b){var c,e={weight:+l.u.va(b,1,0),lm:(c=b.eg())&&x.V.Wb.C(a,c)};a&&(e.ja=b);return e});x.V.Cd.ia=function(a){a=new l.ba(a);var b=new x.V.Cd;return x.V.Cd.F(b,a)};\nx.V.Cd.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.pa();a.qt(c);break;case 2:c=new x.V.Wb;b.T(c,x.V.Wb.F);a.Ng(c);break;default:b.ea()}}return a};x.V.Cd.G=function(a,b){var c;c=a.Sr();0!==c&&b.ya(1,c);c=a.eg();null!=c&&b.oa(2,c,x.V.Wb.G)};x.V.Cd.prototype.Sr=function(){return+l.u.va(this,1,0)};x.V.Cd.prototype.qt=function(a){l.u.J(this,1,a)};x.V.Cd.prototype.eg=function(){return l.u.sa(this,x.V.Wb,2)};x.V.Cd.prototype.Ng=function(a){l.u.Ca(this,2,a)};\nx.V.Cd.K=function(a){return l.u.K(x.V.Cd,a)};x.V.be=function(a){l.u.initialize(this,a,0,-1,x.V.be.na,null)};h.da(x.V.be,l.u);x.V.be.na=[1];l.u.ha&&(x.V.be.prototype.C=function(a){return x.V.be.C(a,this)},x.V.be.C=function(a,b){var c={Q1:l.u.Ka(b.Jx(),x.V.Cd.C,a)};a&&(c.ja=b);return c});x.V.be.ia=function(a){a=new l.ba(a);var b=new x.V.be;return x.V.be.F(b,a)};x.V.be.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.V.Cd;b.T(c,x.V.Cd.F);a.sH(c);break;default:b.ea()}}return a};\nx.V.be.G=function(a,b){a=a.Jx();0<a.length&&b.Oa(1,a,x.V.Cd.G)};x.V.be.prototype.Jx=function(){return l.u.Ma(this,x.V.Cd,1)};x.V.be.prototype.sH=function(a,b){return l.u.La(this,1,a,x.V.Cd,b)};x.V.be.K=function(a){return l.u.K(x.V.be,a)};x.V.Jd=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.V.Jd,l.u);l.u.ha&&(x.V.Jd.prototype.C=function(a){return x.V.Jd.C(a,this)},x.V.Jd.C=function(a,b){var c={I$:+l.u.va(b,1,0),u9:+l.u.va(b,2,0)};a&&(c.ja=b);return c});\nx.V.Jd.ia=function(a){a=new l.ba(a);var b=new x.V.Jd;return x.V.Jd.F(b,a)};x.V.Jd.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.pa();a.UT(c);break;case 2:c=b.pa();a.eT(c);break;default:b.ea()}}return a};x.V.Jd.G=function(a,b){var c;c=a.hM();0!==c&&b.ya(1,c);c=a.bM();0!==c&&b.ya(2,c)};x.V.Jd.prototype.hM=function(){return+l.u.va(this,1,0)};x.V.Jd.prototype.UT=function(a){l.u.J(this,1,a)};x.V.Jd.prototype.bM=function(){return+l.u.va(this,2,0)};\nx.V.Jd.prototype.eT=function(a){l.u.J(this,2,a)};x.V.Jd.K=function(a){return l.u.K(x.V.Jd,a)};x.i.nb=function(a){l.u.initialize(this,a,0,-1,x.i.nb.na,null)};h.da(x.i.nb,l.u);x.i.nb.na=[1,2,7];l.u.ha&&(x.i.nb.prototype.C=function(a){return x.i.nb.C(a,this)},x.i.nb.C=function(a,b){var c={H2:l.u.gb(b,1),O2:l.u.D(b,2),h5:l.u.gb(b,7),min:+l.u.D(b,3),max:+l.u.D(b,4),sum:+l.u.D(b,5),rca:+l.u.D(b,6)};a&&(c.ja=b);return c});x.i.nb.ia=function(a){a=new l.ba(a);var b=new x.i.nb;return x.i.nb.F(b,a)};\nx.i.nb.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.pa();a.BH(c);break;case 2:c=b.ad();a.EH(c);break;case 7:c=b.pa();a.XH(c);break;case 3:c=b.pa();a.IS(c);break;case 4:c=b.pa();a.wS(c);break;case 5:c=b.pa();a.wj(c);break;case 6:c=b.pa();a.dV(c);break;default:b.ea()}}return a};\nx.i.nb.G=function(a,b){var c;c=a.kL();0<c.length&&b.bd(1,c);c=a.lL();0<c.length&&b.HW(2,c);c=a.wL();0<c.length&&b.bd(7,c);c=l.u.D(a,3);null!=c&&b.ya(3,c);c=l.u.D(a,4);null!=c&&b.ya(4,c);c=l.u.D(a,5);null!=c&&b.ya(5,c);c=l.u.D(a,6);null!=c&&b.ya(6,c)};d=x.i.nb.prototype;d.kL=function(){return l.u.gb(this,1)};d.BH=function(a,b){l.u.ib(this,1,a,b)};d.lL=function(){return l.u.D(this,2)};d.EH=function(a,b){l.u.ib(this,2,a,b)};d.wL=function(){return l.u.gb(this,7)};d.XH=function(a,b){l.u.ib(this,7,a,b)};\nd.IS=function(a){l.u.J(this,3,a)};d.wS=function(a){l.u.J(this,4,a)};d.wj=function(a){l.u.J(this,5,a)};d.dV=function(a){l.u.J(this,6,a)};x.i.nb.K=function(a){return l.u.K(x.i.nb,a)};x.i.wd=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.wd,l.u);l.u.ha&&(x.i.wd.prototype.C=function(a){return x.i.wd.C(a,this)},x.i.wd.C=function(a,b){var c={l8:+l.u.D(b,1),m8:+l.u.D(b,2),numBuckets:l.u.D(b,3)};a&&(c.ja=b);return c});x.i.wd.ia=function(a){a=new l.ba(a);var b=new x.i.wd;return x.i.wd.F(b,a)};\nx.i.wd.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.pa();a.pS(c);break;case 2:c=b.pa();a.qS(c);break;case 3:c=b.Ya();a.xm(c);break;default:b.ea()}}return a};x.i.wd.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.ya(1,c);c=l.u.D(a,2);null!=c&&b.ya(2,c);c=l.u.D(a,3);null!=c&&b.$a(3,c)};x.i.wd.$c=new l.Di(14413783,{$c:0},x.i.wd,x.i.wd.C,0);l.u.oi[14413783]=new l.Fj(x.i.wd.$c,l.ba.prototype.T,l.Bi.prototype.oa,x.i.wd.G,x.i.wd.F,!1);l.u.nj[14413783]=x.i.wd.$c;\nx.i.wd.prototype.pS=function(a){l.u.J(this,1,a)};x.i.wd.prototype.qS=function(a){l.u.J(this,2,a)};x.i.wd.prototype.xm=function(a){l.u.J(this,3,a)};x.i.wd.K=function(a){return l.u.K(x.i.wd,a)};x.i.xd=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.xd,l.u);l.u.ha&&(x.i.xd.prototype.C=function(a){return x.i.xd.C(a,this)},x.i.xd.C=function(a,b){var c={mean:+l.u.D(b,1),fW:+l.u.D(b,2),numBuckets:l.u.D(b,3)};a&&(c.ja=b);return c});\nx.i.xd.ia=function(a){a=new l.ba(a);var b=new x.i.xd;return x.i.xd.F(b,a)};x.i.xd.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.pa();a.FS(c);break;case 2:c=b.pa();a.QU(c);break;case 3:c=b.Ya();a.xm(c);break;default:b.ea()}}return a};x.i.xd.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.ya(1,c);c=l.u.D(a,2);null!=c&&b.ya(2,c);c=l.u.D(a,3);null!=c&&b.$a(3,c)};x.i.xd.$c=new l.Di(19393435,{$c:0},x.i.xd,x.i.xd.C,0);\nl.u.oi[19393435]=new l.Fj(x.i.xd.$c,l.ba.prototype.T,l.Bi.prototype.oa,x.i.xd.G,x.i.xd.F,!1);l.u.nj[19393435]=x.i.xd.$c;x.i.xd.prototype.FS=function(a){l.u.J(this,1,a)};x.i.xd.prototype.QU=function(a){l.u.J(this,2,a)};x.i.xd.prototype.xm=function(a){l.u.J(this,3,a)};x.i.xd.K=function(a){return l.u.K(x.i.xd,a)};x.i.hd=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.hd,l.u);\nl.u.ha&&(x.i.hd.prototype.C=function(a){return x.i.hd.C(a,this)},x.i.hd.C=function(a,b){var c={K2:+l.u.D(b,1),Q2:+l.u.D(b,2),P2:+l.u.D(b,3),numBuckets:+l.u.D(b,4)};a&&(c.ja=b);return c});x.i.hd.ia=function(a){a=new l.ba(a);var b=new x.i.hd;return x.i.hd.F(b,a)};x.i.hd.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.pa();a.vQ(c);break;case 2:c=b.pa();a.yQ(c);break;case 3:c=b.pa();a.xQ(c);break;case 4:c=b.pa();a.xm(c);break;default:b.ea()}}return a};\nx.i.hd.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.ya(1,c);c=l.u.D(a,2);null!=c&&b.ya(2,c);c=l.u.D(a,3);null!=c&&b.ya(3,c);c=l.u.D(a,4);null!=c&&b.ya(4,c)};x.i.hd.$c=new l.Di(14410962,{$c:0},x.i.hd,x.i.hd.C,0);l.u.oi[14410962]=new l.Fj(x.i.hd.$c,l.ba.prototype.T,l.Bi.prototype.oa,x.i.hd.G,x.i.hd.F,!1);l.u.nj[14410962]=x.i.hd.$c;x.i.hd.prototype.vQ=function(a){l.u.J(this,1,a)};x.i.hd.prototype.yQ=function(a){l.u.J(this,2,a)};x.i.hd.prototype.xQ=function(a){l.u.J(this,3,a)};\nx.i.hd.prototype.xm=function(a){l.u.J(this,4,a)};x.i.hd.K=function(a){return l.u.K(x.i.hd,a)};x.i.gd=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.gd,l.u);l.u.ha&&(x.i.gd.prototype.C=function(a){return x.i.gd.C(a,this)},x.i.gd.C=function(a,b){var c,e={J$:(c=b.Rz())&&x.jb.lb.mb.C(a,c),v9:(c=b.Ez())&&x.jb.lb.mb.C(a,c)};a&&(e.ja=b);return e});x.i.gd.ia=function(a){a=new l.ba(a);var b=new x.i.gd;return x.i.gd.F(b,a)};\nx.i.gd.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.jb.lb.mb;b.T(c,x.jb.lb.mb.F);a.VT(c);break;case 2:c=new x.jb.lb.mb;b.T(c,x.jb.lb.mb.F);a.fT(c);break;default:b.ea()}}return a};x.i.gd.G=function(a,b){var c;c=a.Rz();null!=c&&b.oa(1,c,x.jb.lb.mb.G);c=a.Ez();null!=c&&b.oa(2,c,x.jb.lb.mb.G)};x.i.gd.$c=new l.Di(13180573,{$c:0},x.i.gd,x.i.gd.C,0);l.u.oi[13180573]=new l.Fj(x.i.gd.$c,l.ba.prototype.T,l.Bi.prototype.oa,x.i.gd.G,x.i.gd.F,!1);l.u.nj[13180573]=x.i.gd.$c;\nx.i.gd.prototype.Rz=function(){return l.u.sa(this,x.jb.lb.mb,1,1)};x.i.gd.prototype.VT=function(a){l.u.Ca(this,1,a)};x.i.gd.prototype.Ez=function(){return l.u.sa(this,x.jb.lb.mb,2)};x.i.gd.prototype.fT=function(a){l.u.Ca(this,2,a)};x.i.gd.K=function(a){return l.u.K(x.i.gd,a)};x.i.Qc=function(a){l.u.initialize(this,a,0,-1,x.i.Qc.na,null)};h.da(x.i.Qc,l.u);x.i.Qc.na=[1,2];\nl.u.ha&&(x.i.Qc.prototype.C=function(a){return x.i.Qc.C(a,this)},x.i.Qc.C=function(a,b){var c={mda:l.u.gb(b,1),J9:l.u.D(b,2)};a&&(c.ja=b);return c});x.i.Qc.ia=function(a){a=new l.ba(a);var b=new x.i.Qc;return x.i.Qc.F(b,a)};x.i.Qc.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.pa();a.BJ(c);break;case 2:c=b.Ya();a.LI(c);break;default:b.ea()}}return a};x.i.Qc.G=function(a,b){var c;c=a.IM();0<c.length&&b.bd(1,c);c=a.cM();0<c.length&&b.GW(2,c)};\nx.i.Qc.$c=new l.Di(14460333,{$c:0},x.i.Qc,x.i.Qc.C,0);l.u.oi[14460333]=new l.Fj(x.i.Qc.$c,l.ba.prototype.T,l.Bi.prototype.oa,x.i.Qc.G,x.i.Qc.F,!1);l.u.nj[14460333]=x.i.Qc.$c;x.i.Qc.prototype.IM=function(){return l.u.gb(this,1)};x.i.Qc.prototype.BJ=function(a,b){l.u.ib(this,1,a,b)};x.i.Qc.prototype.cM=function(){return l.u.D(this,2)};x.i.Qc.prototype.LI=function(a,b){l.u.ib(this,2,a,b)};x.i.Qc.K=function(a){return l.u.K(x.i.Qc,a)};x.i.Qf=function(a){l.u.initialize(this,a,0,-1,null,null)};\nh.da(x.i.Qf,l.u);l.u.ha&&(x.i.Qf.prototype.C=function(a){return x.i.Qf.C(a,this)},x.i.Qf.C=function(a,b){var c,e={Y6:(c=b.$y())&&x.jb.lb.mb.C(a,c)};a&&(e.ja=b);return e});x.i.Qf.ia=function(a){a=new l.ba(a);var b=new x.i.Qf;return x.i.Qf.F(b,a)};x.i.Qf.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.jb.lb.mb;b.T(c,x.jb.lb.mb.F);a.KR(c);break;default:b.ea()}}return a};x.i.Qf.G=function(a,b){a=a.$y();null!=a&&b.oa(1,a,x.jb.lb.mb.G)};\nx.i.Qf.prototype.$y=function(){return l.u.sa(this,x.jb.lb.mb,1,1)};x.i.Qf.prototype.KR=function(a){l.u.Ca(this,1,a)};x.i.Qf.K=function(a){return l.u.K(x.i.Qf,a)};x.Xa={};x.Xa.Ec=function(a){l.u.initialize(this,a,0,-1,x.Xa.Ec.na,null)};h.da(x.Xa.Ec,l.u);x.Xa.Ec.na=[1,9];\nl.u.ha&&(x.Xa.Ec.prototype.C=function(a){return x.Xa.Ec.C(a,this)},x.Xa.Ec.C=function(a,b){var c,e={Cx:l.u.Ka(b.Zg(),x.jb.lb.mb.C,a),nba:l.u.D(b,2),F7:l.u.va(b,3,!1),startTime:l.u.va(b,4,0),endTime:l.u.va(b,5,0x7fffffffffffffff),Uaa:+l.u.va(b,7,1),R1:(c=b.Kx())&&x.jb.lb.mb.C(a,c),X1:l.u.D(b,9)};a&&(e.ja=b);return e});x.Xa.Ec.ia=function(a){a=new l.ba(a);var b=new x.Xa.Ec;return x.Xa.Ec.F(b,a)};\nx.Xa.Ec.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.jb.lb.mb;b.T(c,x.jb.lb.mb.F);a.sl(c);break;case 2:c=b.Aa();a.CU(c);break;case 3:c=b.vf();a.dS(c);break;case 4:c=b.ad();a.vj(c);break;case 5:c=b.ad();a.sj(c);break;case 7:c=b.pa();a.yU(c);break;case 8:c=new x.jb.lb.mb;b.T(c,x.jb.lb.mb.F);a.eQ(c);break;case 9:c=b.Aa();a.uH(c);break;default:b.ea()}}return a};\nx.Xa.Ec.G=function(a,b){var c;c=a.Zg();0<c.length&&b.Oa(1,c,x.jb.lb.mb.G);c=l.u.D(a,2);null!=c&&b.Ja(2,c);c=l.u.D(a,3);null!=c&&b.kf(3,c);c=l.u.D(a,4);null!=c&&b.td(4,c);c=l.u.D(a,5);null!=c&&b.td(5,c);c=l.u.D(a,7);null!=c&&b.ya(7,c);c=a.Kx();null!=c&&b.oa(8,c,x.jb.lb.mb.G);c=a.gL();0<c.length&&b.oc(9,c)};d=x.Xa.Ec.prototype;d.Zg=function(){return l.u.Ma(this,x.jb.lb.mb,1)};d.Us=function(a){l.u.mt(this,1,a)};d.sl=function(a,b){return l.u.La(this,1,a,x.jb.lb.mb,b)};d.CU=function(a){l.u.J(this,2,a)};\nd.dS=function(a){l.u.J(this,3,a)};d.getStartTime=function(){return l.u.va(this,4,0)};d.vj=function(a){l.u.J(this,4,a)};d.sj=function(a){l.u.J(this,5,a)};d.yU=function(a){l.u.J(this,7,a)};d.Kx=function(){return l.u.sa(this,x.jb.lb.mb,8)};d.eQ=function(a){l.u.Ca(this,8,a)};d.gL=function(){return l.u.D(this,9)};d.uH=function(a,b){l.u.ib(this,9,a,b)};x.Xa.Ec.K=function(a){return l.u.K(x.Xa.Ec,a)};x.Xa.wb=function(a){l.u.initialize(this,a,0,-1,x.Xa.wb.na,null)};h.da(x.Xa.wb,l.u);x.Xa.wb.na=[1];\nl.u.ha&&(x.Xa.wb.prototype.C=function(a){return x.Xa.wb.C(a,this)},x.Xa.wb.C=function(a,b){var c={h2:l.u.Ka(b.Nx(),x.Xa.wb.Xc.C,a),B4:l.u.va(b,4,!1),A4:l.u.va(b,5,!1),y4:l.u.va(b,6,!1)};a&&(c.ja=b);return c});x.Xa.wb.ia=function(a){a=new l.ba(a);var b=new x.Xa.wb;return x.Xa.wb.F(b,a)};\nx.Xa.wb.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.Xa.wb.Xc;b.lP(1,c,x.Xa.wb.Xc.F);a.vH(c);break;case 4:c=b.vf();a.XQ(c);break;case 5:c=b.vf();a.WQ(c);break;case 6:c=b.vf();a.VQ(c);break;default:b.ea()}}return a};x.Xa.wb.G=function(a,b){var c;c=a.Nx();0<c.length&&b.FW(1,c,x.Xa.wb.Xc.G);c=l.u.D(a,4);null!=c&&b.kf(4,c);c=l.u.D(a,5);null!=c&&b.kf(5,c);c=l.u.D(a,6);null!=c&&b.kf(6,c)};x.Xa.wb.$c=new l.Di(19252665,{$c:0},x.Xa.wb,x.Xa.wb.C,0);\nl.u.oi[19252665]=new l.Fj(x.Xa.wb.$c,l.ba.prototype.T,l.Bi.prototype.oa,x.Xa.wb.G,x.Xa.wb.F,!1);l.u.nj[19252665]=x.Xa.wb.$c;d=x.Xa.wb.prototype;d.Nx=function(){return l.u.Ma(this,x.Xa.wb.Xc,1)};d.vH=function(a,b){return l.u.La(this,1,a,x.Xa.wb.Xc,b)};d.XQ=function(a){l.u.J(this,4,a)};d.WQ=function(a){l.u.J(this,5,a)};d.VQ=function(a){l.u.J(this,6,a)};x.Xa.wb.K=function(a){return l.u.K(x.Xa.wb,a)};x.Xa.wb.Xc=function(a){l.u.initialize(this,a,0,-1,x.Xa.wb.Xc.na,null)};h.da(x.Xa.wb.Xc,l.u);\nx.Xa.wb.Xc.na=[1,2];l.u.ha&&(x.Xa.wb.Xc.prototype.C=function(a){return x.Xa.wb.Xc.C(a,this)},x.Xa.wb.Xc.C=function(a,b){var c={SJ:l.u.Ka(b.Il(),x.Xa.Ec.C,a),Z3:l.u.Ka(b.oy(),x.jb.lb.mb.C,a)};a&&(c.ja=b);return c});x.Xa.wb.Xc.ia=function(a){a=new l.ba(a);var b=new x.Xa.wb.Xc;return x.Xa.wb.Xc.F(b,a)};x.Xa.wb.Xc.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 2:c=new x.Xa.Ec;b.T(c,x.Xa.Ec.F);a.Lq(c);break;case 3:c=new x.jb.lb.mb;b.T(c,x.jb.lb.mb.F);a.KH(c);break;default:b.ea()}}return a};\nx.Xa.wb.Xc.G=function(a,b){var c;c=a.Il();0<c.length&&b.Oa(2,c,x.Xa.Ec.G);c=a.oy();0<c.length&&b.Oa(3,c,x.jb.lb.mb.G)};x.Xa.wb.Xc.prototype.Il=function(){return l.u.Ma(this,x.Xa.Ec,1)};x.Xa.wb.Xc.prototype.Lq=function(a,b){return l.u.La(this,1,a,x.Xa.Ec,b)};x.Xa.wb.Xc.prototype.oy=function(){return l.u.Ma(this,x.jb.lb.mb,2)};x.Xa.wb.Xc.prototype.KH=function(a,b){return l.u.La(this,2,a,x.jb.lb.mb,b)};x.Xa.wb.Xc.K=function(a){return l.u.K(x.Xa.wb.Xc,a)};\nx.i.Zd=function(a){l.u.initialize(this,a,0,-1,null,x.i.Zd.Ob)};h.da(x.i.Zd,l.u);x.i.Zd.Ob=[[1,2]];x.i.Zd.a_={TZ:0,fZ:1,hY:2};l.u.ha&&(x.i.Zd.prototype.C=function(a){return x.i.Zd.C(a,this)},x.i.Zd.C=function(a,b){var c,e={y$:(c=b.Oz())&&x.i.wc.C(a,c),iN:(c=b.Tl())&&x.i.Rc.C(a,c)};a&&(e.ja=b);return e});x.i.Zd.ia=function(a){a=new l.ba(a);var b=new x.i.Zd;return x.i.Zd.F(b,a)};\nx.i.Zd.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.wc;b.T(c,x.i.wc.F);a.NT(c);break;case 2:c=new x.i.Rc;b.T(c,x.i.Rc.F);a.Xs(c);break;default:b.ea()}}return a};x.i.Zd.G=function(a,b){var c;c=a.Oz();null!=c&&b.oa(1,c,x.i.wc.G);c=a.Tl();null!=c&&b.oa(2,c,x.i.Rc.G)};x.i.Zd.prototype.Oz=function(){return l.u.sa(this,x.i.wc,1)};x.i.Zd.prototype.NT=function(a){l.u.Nc(this,1,x.i.Zd.Ob[0],a)};x.i.Zd.prototype.Tl=function(){return l.u.sa(this,x.i.Rc,2)};\nx.i.Zd.prototype.Xs=function(a){l.u.Nc(this,2,x.i.Zd.Ob[0],a)};x.i.Zd.K=function(a){return l.u.K(x.i.Zd,a)};x.i.wc=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.wc,l.u);l.u.ha&&(x.i.wc.prototype.C=function(a){return x.i.wc.C(a,this)},x.i.wc.C=function(a,b){var c,e={I4:(c=b.Ay())&&x.i.Gc.C(a,c),rO:(c=b.Yl())&&x.i.Rb.C(a,c),Tba:(c=b.yA())&&x.i.mc.C(a,c)};a&&(e.ja=b);return e});x.i.wc.ia=function(a){a=new l.ba(a);var b=new x.i.wc;return x.i.wc.F(b,a)};\nx.i.wc.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.Gc;b.T(c,x.i.Gc.F);a.aR(c);break;case 2:c=new x.i.Rb;b.T(c,x.i.Rb.F);a.at(c);break;case 3:c=new x.i.mc;b.T(c,x.i.mc.F);a.VU(c);break;default:b.ea()}}return a};x.i.wc.G=function(a,b){var c;c=a.Ay();null!=c&&b.oa(1,c,x.i.Gc.G);c=a.Yl();null!=c&&b.oa(2,c,x.i.Rb.G);c=a.yA();null!=c&&b.oa(3,c,x.i.mc.G)};d=x.i.wc.prototype;d.Ay=function(){return l.u.sa(this,x.i.Gc,1)};d.aR=function(a){l.u.Ca(this,1,a)};\nd.Yl=function(){return l.u.sa(this,x.i.Rb,2)};d.at=function(a){l.u.Ca(this,2,a)};d.yA=function(){return l.u.sa(this,x.i.mc,3)};d.VU=function(a){l.u.Ca(this,3,a)};x.i.wc.K=function(a){return l.u.K(x.i.wc,a)};x.i.ig=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.ig,l.u);\nl.u.ha&&(x.i.ig.prototype.C=function(a){return x.i.ig.C(a,this)},x.i.ig.C=function(a,b){var c,e={y5:(c=b.My())&&x.i.Gc.C(a,c),g4:(c=b.uy())&&x.i.Rb.C(a,c),dda:(c=b.RA())&&x.i.Rb.C(a,c),h4:(c=b.wy())&&x.i.mc.C(a,c),eda:(c=b.SA())&&x.i.mc.C(a,c),H3:(c=b.ny())&&x.i.ke.C(a,c)};a&&(e.ja=b);return e});x.i.ig.ia=function(a){a=new l.ba(a);var b=new x.i.ig;return x.i.ig.F(b,a)};\nx.i.ig.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.Gc;b.T(c,x.i.Gc.F);a.tR(c);break;case 2:c=new x.i.Rb;b.T(c,x.i.Rb.F);a.QQ(c);break;case 3:c=new x.i.Rb;b.T(c,x.i.Rb.F);a.zV(c);break;case 4:c=new x.i.mc;b.T(c,x.i.mc.F);a.RQ(c);break;case 5:c=new x.i.mc;b.T(c,x.i.mc.F);a.AV(c);break;case 6:c=new x.i.ke;b.T(c,x.i.ke.F);a.LQ(c);break;default:b.ea()}}return a};\nx.i.ig.G=function(a,b){var c;c=a.My();null!=c&&b.oa(1,c,x.i.Gc.G);c=a.uy();null!=c&&b.oa(2,c,x.i.Rb.G);c=a.RA();null!=c&&b.oa(3,c,x.i.Rb.G);c=a.wy();null!=c&&b.oa(4,c,x.i.mc.G);c=a.SA();null!=c&&b.oa(5,c,x.i.mc.G);c=a.ny();null!=c&&b.oa(6,c,x.i.ke.G)};d=x.i.ig.prototype;d.My=function(){return l.u.sa(this,x.i.Gc,1)};d.tR=function(a){l.u.Ca(this,1,a)};d.uy=function(){return l.u.sa(this,x.i.Rb,2)};d.QQ=function(a){l.u.Ca(this,2,a)};d.RA=function(){return l.u.sa(this,x.i.Rb,3)};\nd.zV=function(a){l.u.Ca(this,3,a)};d.wy=function(){return l.u.sa(this,x.i.mc,4)};d.RQ=function(a){l.u.Ca(this,4,a)};d.SA=function(){return l.u.sa(this,x.i.mc,5)};d.AV=function(a){l.u.Ca(this,5,a)};d.ny=function(){return l.u.sa(this,x.i.ke,6)};d.LQ=function(a){l.u.Ca(this,6,a)};x.i.ig.K=function(a){return l.u.K(x.i.ig,a)};x.i.Rc=function(a){l.u.initialize(this,a,0,-1,x.i.Rc.na,null)};h.da(x.i.Rc,l.u);x.i.Rc.na=[2];\nl.u.ha&&(x.i.Rc.prototype.C=function(a){return x.i.Rc.C(a,this)},x.i.Rc.C=function(a,b){var c,e={rO:(c=b.Yl())&&x.i.Rb.C(a,c),uaa:l.u.Ka(b.gA(),x.i.rc.C,a),Sca:(c=b.MA())&&x.i.rc.C(a,c),lm:(c=b.eg())&&x.V.Wb.C(a,c)};a&&(e.ja=b);return e});x.i.Rc.ia=function(a){a=new l.ba(a);var b=new x.i.Rc;return x.i.Rc.F(b,a)};\nx.i.Rc.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.Rb;b.T(c,x.i.Rb.F);a.at(c);break;case 2:c=new x.i.rc;b.T(c,x.i.rc.F);a.ZI(c);break;case 3:c=new x.i.rc;b.T(c,x.i.rc.F);a.tV(c);break;case 4:c=new x.V.Wb;b.T(c,x.V.Wb.F);a.Ng(c);break;default:b.ea()}}return a};x.i.Rc.G=function(a,b){var c;c=a.Yl();null!=c&&b.oa(1,c,x.i.Rb.G);c=a.gA();0<c.length&&b.Oa(2,c,x.i.rc.G);c=a.MA();null!=c&&b.oa(3,c,x.i.rc.G);c=a.eg();null!=c&&b.oa(4,c,x.V.Wb.G)};d=x.i.Rc.prototype;\nd.Yl=function(){return l.u.sa(this,x.i.Rb,1)};d.at=function(a){l.u.Ca(this,1,a)};d.gA=function(){return l.u.Ma(this,x.i.rc,2)};d.ZI=function(a,b){return l.u.La(this,2,a,x.i.rc,b)};d.MA=function(){return l.u.sa(this,x.i.rc,3)};d.tV=function(a){l.u.Ca(this,3,a)};d.eg=function(){return l.u.sa(this,x.V.Wb,4)};d.Ng=function(a){l.u.Ca(this,4,a)};x.i.Rc.K=function(a){return l.u.K(x.i.Rc,a)};x.i.Id=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.Id,l.u);\nl.u.ha&&(x.i.Id.prototype.C=function(a){return x.i.Id.C(a,this)},x.i.Id.C=function(a,b){var c={Zq:l.u.va(b,1,\"\"),rP:l.u.va(b,2,\"\")};a&&(c.ja=b);return c});x.i.Id.ia=function(a){a=new l.ba(a);var b=new x.i.Id;return x.i.Id.F(b,a)};x.i.Id.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.rj(c);break;case 2:c=b.Aa();a.lt(c);break;default:b.ea()}}return a};x.i.Id.G=function(a,b){var c;c=a.Jl();0<c.length&&b.Ja(1,c);c=a.xo();0<c.length&&b.Ja(2,c)};\nx.i.Id.prototype.Jl=function(){return l.u.va(this,1,\"\")};x.i.Id.prototype.rj=function(a){l.u.J(this,1,a)};x.i.Id.prototype.xo=function(){return l.u.va(this,2,\"\")};x.i.Id.prototype.lt=function(a){l.u.J(this,2,a)};x.i.Id.K=function(a){return l.u.K(x.i.Id,a)};x.i.Rb=function(a){l.u.initialize(this,a,0,-1,null,x.i.Rb.Ob)};h.da(x.i.Rb,l.u);x.i.Rb.Ob=[[3,4]];x.i.Rb.vE={uE:0,CZ:3,SW:4};\nl.u.ha&&(x.i.Rb.prototype.C=function(a){return x.i.Rb.C(a,this)},x.i.Rb.C=function(a,b){var c,e={rP:(c=b.xo())&&x.i.Id.C(a,c),I1:l.u.va(b,4,\"\"),TJ:(c=b.Kl())&&x.i.yc.C(a,c),xaa:l.u.va(b,1,\"\")};a&&(e.ja=b);return e});x.i.Rb.ia=function(a){a=new l.ba(a);var b=new x.i.Rb;return x.i.Rb.F(b,a)};\nx.i.Rb.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 3:c=new x.i.Id;b.T(c,x.i.Id.F);a.lt(c);break;case 4:c=b.Aa();a.aQ(c);break;case 2:c=new x.i.yc;b.T(c,x.i.yc.F);a.Ls(c);break;case 1:c=b.Aa();a.uU(c);break;default:b.ea()}}return a};x.i.Rb.G=function(a,b){var c;c=a.xo();null!=c&&b.oa(3,c,x.i.Id.G);c=l.u.D(a,4);null!=c&&b.Ja(4,c);c=a.Kl();null!=c&&b.oa(2,c,x.i.yc.G);c=a.nM();0<c.length&&b.Ja(1,c)};d=x.i.Rb.prototype;d.xo=function(){return l.u.sa(this,x.i.Id,3)};\nd.lt=function(a){l.u.Nc(this,3,x.i.Rb.Ob[0],a)};d.aQ=function(a){l.u.vC(this,4,x.i.Rb.Ob[0],a)};d.Kl=function(){return l.u.sa(this,x.i.yc,2)};d.Ls=function(a){l.u.Ca(this,2,a)};d.nM=function(){return l.u.va(this,1,\"\")};d.uU=function(a){l.u.J(this,1,a)};x.i.Rb.K=function(a){return l.u.K(x.i.Rb,a)};x.i.Bd=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.Bd,l.u);\nl.u.ha&&(x.i.Bd.prototype.C=function(a){return x.i.Bd.C(a,this)},x.i.Bd.C=function(a,b){var c={A3:l.u.va(b,1,\"\"),value:l.u.va(b,2,\"\")};a&&(c.ja=b);return c});x.i.Bd.ia=function(a){a=new l.ba(a);var b=new x.i.Bd;return x.i.Bd.F(b,a)};x.i.Bd.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.IQ(c);break;case 2:c=b.Aa();a.setValue(c);break;default:b.ea()}}return a};x.i.Bd.G=function(a,b){var c;c=a.oL();0<c.length&&b.Ja(1,c);c=a.getValue();0<c.length&&b.Ja(2,c)};\nx.i.Bd.prototype.oL=function(){return l.u.va(this,1,\"\")};x.i.Bd.prototype.IQ=function(a){l.u.J(this,1,a)};x.i.Bd.prototype.getValue=function(){return l.u.va(this,2,\"\")};x.i.Bd.prototype.setValue=function(a){l.u.J(this,2,a)};x.i.Bd.K=function(a){return l.u.K(x.i.Bd,a)};x.i.ud=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.ud,l.u);l.u.ha&&(x.i.ud.prototype.C=function(a){return x.i.ud.C(a,this)},x.i.ud.C=function(a,b){var c={Fl:l.u.va(b,1,0),version:l.u.va(b,2,0)};a&&(c.ja=b);return c});\nx.i.ud.ia=function(a){a=new l.ba(a);var b=new x.i.ud;return x.i.ud.F(b,a)};x.i.ud.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Ya();a.Mg(c);break;case 2:c=b.Ya();a.setVersion(c);break;default:b.ea()}}return a};x.i.ud.G=function(a,b){var c;c=a.ik();0!==c&&b.$a(1,c);c=a.getVersion();0!==c&&b.$a(2,c)};x.i.ud.prototype.ik=function(){return l.u.va(this,1,0)};x.i.ud.prototype.Mg=function(a){l.u.J(this,1,a)};x.i.ud.prototype.getVersion=function(){return l.u.va(this,2,0)};\nx.i.ud.prototype.setVersion=function(a){l.u.J(this,2,a)};x.i.ud.K=function(a){return l.u.K(x.i.ud,a)};x.i.yb=function(a){l.u.initialize(this,a,0,-1,null,x.i.yb.Ob)};h.da(x.i.yb,l.u);x.i.yb.Ob=[[1]];x.i.yb.vE={uE:0,NX:1};l.u.ha&&(x.i.yb.prototype.C=function(a){return x.i.yb.C(a,this)},x.i.yb.C=function(a,b){var c,e={X5:(c=b.Xy())&&x.i.yb.Od.C(a,c)};a&&(e.ja=b);return e});x.i.yb.ia=function(a){a=new l.ba(a);var b=new x.i.yb;return x.i.yb.F(b,a)};\nx.i.yb.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.yb.Od;b.T(c,x.i.yb.Od.F);a.DR(c);break;default:b.ea()}}return a};x.i.yb.G=function(a,b){a=a.Xy();null!=a&&b.oa(1,a,x.i.yb.Od.G)};x.i.yb.prototype.Xy=function(){return l.u.sa(this,x.i.yb.Od,1)};x.i.yb.prototype.DR=function(a){l.u.Nc(this,1,x.i.yb.Ob[0],a)};x.i.yb.K=function(a){return l.u.K(x.i.yb,a)};x.i.yb.Od=function(a){l.u.initialize(this,a,0,-1,x.i.yb.Od.na,null)};h.da(x.i.yb.Od,l.u);x.i.yb.Od.na=[1];\nl.u.ha&&(x.i.yb.Od.prototype.C=function(a){return x.i.yb.Od.C(a,this)},x.i.yb.Od.C=function(a,b){var c={W5:l.u.D(b,1)};a&&(c.ja=b);return c});x.i.yb.Od.ia=function(a){a=new l.ba(a);var b=new x.i.yb.Od;return x.i.yb.Od.F(b,a)};x.i.yb.Od.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.nI(c);break;default:b.ea()}}return a};x.i.yb.Od.G=function(a,b){a=a.IL();0<a.length&&b.oc(1,a)};x.i.yb.Od.prototype.IL=function(){return l.u.D(this,1)};\nx.i.yb.Od.prototype.nI=function(a,b){l.u.ib(this,1,a,b)};x.i.yb.Od.K=function(a){return l.u.K(x.i.yb.Od,a)};x.i.Gc=function(a){l.u.initialize(this,a,0,-1,x.i.Gc.na,null)};h.da(x.i.Gc,l.u);x.i.Gc.na=[6,2];l.u.ha&&(x.i.Gc.prototype.C=function(a){return x.i.Gc.C(a,this)},x.i.Gc.C=function(a,b){var c,e={q7:(c=b.hz())&&x.i.yb.C(a,c),zba:l.u.Ka(b.rA(),x.i.Bd.C,a),Zq:l.u.va(b,1,\"\"),Q4:l.u.Ka(b.Ey(),x.i.ud.C,a),m3:l.u.va(b,5,0)};a&&(e.ja=b);return e});\nx.i.Gc.ia=function(a){a=new l.ba(a);var b=new x.i.Gc;return x.i.Gc.F(b,a)};x.i.Gc.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 7:c=new x.i.yb;b.T(c,x.i.yb.F);a.$R(c);break;case 6:c=new x.i.Bd;b.T(c,x.i.Bd.F);a.hJ(c);break;case 1:c=b.Aa();a.rj(c);break;case 2:c=new x.i.ud;b.T(c,x.i.ud.F);a.UH(c);break;case 5:c=b.we();a.CQ(c);break;default:b.ea()}}return a};\nx.i.Gc.G=function(a,b){var c;c=a.hz();null!=c&&b.oa(7,c,x.i.yb.G);c=a.rA();0<c.length&&b.Oa(6,c,x.i.Bd.G);c=a.Jl();0<c.length&&b.Ja(1,c);c=a.Ey();0<c.length&&b.Oa(2,c,x.i.ud.G);c=a.nL();0!==c&&b.xe(5,c)};d=x.i.Gc.prototype;d.hz=function(){return l.u.sa(this,x.i.yb,7)};d.$R=function(a){l.u.Ca(this,7,a)};d.rA=function(){return l.u.Ma(this,x.i.Bd,6)};d.hJ=function(a,b){return l.u.La(this,6,a,x.i.Bd,b)};d.Jl=function(){return l.u.va(this,1,\"\")};d.rj=function(a){l.u.J(this,1,a)};\nd.Ey=function(){return l.u.Ma(this,x.i.ud,2)};d.UH=function(a,b){return l.u.La(this,2,a,x.i.ud,b)};d.nL=function(){return l.u.va(this,5,0)};d.CQ=function(a){l.u.J(this,5,a)};x.i.Gc.K=function(a){return l.u.K(x.i.Gc,a)};x.i.Gc.kX={Ai:0,f_:1,aY:2};x.i.Je=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.Je,l.u);\nl.u.ha&&(x.i.Je.prototype.C=function(a){return x.i.Je.C(a,this)},x.i.Je.C=function(a,b){var c,e={k:(c=b.lz())&&x.google.N.qc.C(a,c),value:+l.u.va(b,2,0),Lca:+l.u.va(b,3,0)};a&&(e.ja=b);return e});x.i.Je.ia=function(a){a=new l.ba(a);var b=new x.i.Je;return x.i.Je.F(b,a)};x.i.Je.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.google.N.qc;b.T(c,x.google.N.qc.F);a.fS(c);break;case 2:c=b.pa();a.setValue(c);break;case 3:c=b.pa();a.mV(c);break;default:b.ea()}}return a};\nx.i.Je.G=function(a,b){var c;c=a.lz();null!=c&&b.oa(1,c,x.google.N.qc.G);c=a.getValue();0!==c&&b.ya(2,c);c=a.EM();0!==c&&b.ya(3,c)};d=x.i.Je.prototype;d.lz=function(){return l.u.sa(this,x.google.N.qc,1)};d.fS=function(a){l.u.Ca(this,1,a)};d.getValue=function(){return+l.u.va(this,2,0)};d.setValue=function(a){l.u.J(this,2,a)};d.EM=function(){return+l.u.va(this,3,0)};d.mV=function(a){l.u.J(this,3,a)};x.i.Je.K=function(a){return l.u.K(x.i.Je,a)};\nx.i.mc=function(a){l.u.initialize(this,a,0,-1,x.i.mc.na,null)};h.da(x.i.mc,l.u);x.i.mc.na=[16,11,12,20];\nl.u.ha&&(x.i.mc.prototype.C=function(a){return x.i.mc.C(a,this)},x.i.mc.C=function(a,b){var c,e={XO:(c=b.Zl())&&x.google.N.Ba.C(a,c),Kba:(c=b.vA())&&x.google.N.Ba.C(a,c),aO:(c=b.Wl())&&x.google.N.Ba.C(a,c),C$:(c=b.Qz())&&x.google.N.Ba.C(a,c),o2:(c=b.Sx())&&x.google.N.Ba.C(a,c),n2:(c=b.Rx())&&x.google.N.Ba.C(a,c),Oca:(c=b.IA())&&x.google.N.Ba.C(a,c),wl:(c=b.Gg())&&x.google.N.Ba.C(a,c),I2:(c=b.Zx())&&x.i.Re.C(a,c),$B:(c=b.mk())&&x.google.N.Ba.C(a,c),kaa:(c=b.cA())&&x.google.N.Ba.C(a,c),jaa:(c=b.bA())&&\nx.google.N.Ba.C(a,c),Kca:(c=b.HA())&&x.google.N.Ba.C(a,c),G2:l.u.Ka(b.Yx(),x.i.Ga.C,a),C2:(c=b.Xx())&&x.i.dd.C(a,c),d4:(c=b.ty())&&x.i.Za.C(a,c),L2:l.u.Ka(b.$x(),x.i.Pc.C,a),M2:l.u.Ka(b.ay(),x.i.Pc.C,a),P$:l.u.Ka(b.Tz(),x.i.Je.C,a),j2:(c=b.Ox())&&x.google.N.Ba.C(a,c)};a&&(e.ja=b);return e});x.i.mc.ia=function(a){a=new l.ba(a);var b=new x.i.mc;return x.i.mc.F(b,a)};\nx.i.mc.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.google.N.Ba;b.T(c,x.google.N.Ba.F);a.gt(c);break;case 2:c=new x.google.N.Ba;b.T(c,x.google.N.Ba.F);a.PU(c);break;case 3:c=new x.google.N.Ba;b.T(c,x.google.N.Ba.F);a.Zs(c);break;case 4:c=new x.google.N.Ba;b.T(c,x.google.N.Ba.F);a.PT(c);break;case 5:c=new x.google.N.Ba;b.T(c,x.google.N.Ba.F);a.lQ(c);break;case 6:c=new x.google.N.Ba;b.T(c,x.google.N.Ba.F);a.kQ(c);break;case 7:c=new x.google.N.Ba;b.T(c,x.google.N.Ba.F);\na.pV(c);break;case 8:c=new x.google.N.Ba;b.T(c,x.google.N.Ba.F);a.Kg(c);break;case 17:c=new x.i.Re;b.T(c,x.i.Re.F);a.uQ(c);break;case 9:c=new x.google.N.Ba;b.T(c,x.google.N.Ba.F);a.ym(c);break;case 14:c=new x.google.N.Ba;b.T(c,x.google.N.Ba.F);a.pU(c);break;case 15:c=new x.google.N.Ba;b.T(c,x.google.N.Ba.F);a.oU(c);break;case 19:c=new x.google.N.Ba;b.T(c,x.google.N.Ba.F);a.lV(c);break;case 16:c=new x.i.Ga;b.T(c,x.i.Ga.F);a.AH(c);break;case 18:c=new x.i.dd;b.T(c,x.i.dd.F);a.tQ(c);break;case 10:c=new x.i.Za;\nb.T(c,x.i.Za.F);a.OQ(c);break;case 11:c=new x.i.Pc;b.T(c,x.i.Pc.F);a.CH(c);break;case 12:c=new x.i.Pc;b.T(c,x.i.Pc.F);a.DH(c);break;case 20:c=new x.i.Je;b.T(c,x.i.Je.F);a.WI(c);break;case 13:c=new x.google.N.Ba;b.T(c,x.google.N.Ba.F);a.hQ(c);break;default:b.ea()}}return a};\nx.i.mc.G=function(a,b){var c;c=a.Zl();null!=c&&b.oa(1,c,x.google.N.Ba.G);c=a.vA();null!=c&&b.oa(2,c,x.google.N.Ba.G);c=a.Wl();null!=c&&b.oa(3,c,x.google.N.Ba.G);c=a.Qz();null!=c&&b.oa(4,c,x.google.N.Ba.G);c=a.Sx();null!=c&&b.oa(5,c,x.google.N.Ba.G);c=a.Rx();null!=c&&b.oa(6,c,x.google.N.Ba.G);c=a.IA();null!=c&&b.oa(7,c,x.google.N.Ba.G);c=a.Gg();null!=c&&b.oa(8,c,x.google.N.Ba.G);c=a.Zx();null!=c&&b.oa(17,c,x.i.Re.G);c=a.mk();null!=c&&b.oa(9,c,x.google.N.Ba.G);c=a.cA();null!=c&&b.oa(14,c,x.google.N.Ba.G);\nc=a.bA();null!=c&&b.oa(15,c,x.google.N.Ba.G);c=a.HA();null!=c&&b.oa(19,c,x.google.N.Ba.G);c=a.Yx();0<c.length&&b.Oa(16,c,x.i.Ga.G);c=a.Xx();null!=c&&b.oa(18,c,x.i.dd.G);c=a.ty();null!=c&&b.oa(10,c,x.i.Za.G);c=a.$x();0<c.length&&b.Oa(11,c,x.i.Pc.G);c=a.ay();0<c.length&&b.Oa(12,c,x.i.Pc.G);c=a.Tz();0<c.length&&b.Oa(20,c,x.i.Je.G);c=a.Ox();null!=c&&b.oa(13,c,x.google.N.Ba.G)};d=x.i.mc.prototype;d.Zl=function(){return l.u.sa(this,x.google.N.Ba,1)};d.gt=function(a){l.u.Ca(this,1,a)};\nd.vA=function(){return l.u.sa(this,x.google.N.Ba,2)};d.PU=function(a){l.u.Ca(this,2,a)};d.Wl=function(){return l.u.sa(this,x.google.N.Ba,3)};d.Zs=function(a){l.u.Ca(this,3,a)};d.Qz=function(){return l.u.sa(this,x.google.N.Ba,4)};d.PT=function(a){l.u.Ca(this,4,a)};d.Sx=function(){return l.u.sa(this,x.google.N.Ba,5)};d.lQ=function(a){l.u.Ca(this,5,a)};d.Rx=function(){return l.u.sa(this,x.google.N.Ba,6)};d.kQ=function(a){l.u.Ca(this,6,a)};d.IA=function(){return l.u.sa(this,x.google.N.Ba,7)};\nd.pV=function(a){l.u.Ca(this,7,a)};d.Gg=function(){return l.u.sa(this,x.google.N.Ba,8)};d.Kg=function(a){l.u.Ca(this,8,a)};d.Zx=function(){return l.u.sa(this,x.i.Re,17)};d.uQ=function(a){l.u.Ca(this,17,a)};d.mk=function(){return l.u.sa(this,x.google.N.Ba,9)};d.ym=function(a){l.u.Ca(this,9,a)};d.cA=function(){return l.u.sa(this,x.google.N.Ba,14)};d.pU=function(a){l.u.Ca(this,14,a)};d.bA=function(){return l.u.sa(this,x.google.N.Ba,15)};d.oU=function(a){l.u.Ca(this,15,a)};\nd.HA=function(){return l.u.sa(this,x.google.N.Ba,19)};d.lV=function(a){l.u.Ca(this,19,a)};d.Yx=function(){return l.u.Ma(this,x.i.Ga,16)};d.AH=function(a,b){return l.u.La(this,16,a,x.i.Ga,b)};d.Xx=function(){return l.u.sa(this,x.i.dd,18)};d.tQ=function(a){l.u.Ca(this,18,a)};d.ty=function(){return l.u.sa(this,x.i.Za,10)};d.OQ=function(a){l.u.Ca(this,10,a)};d.$x=function(){return l.u.Ma(this,x.i.Pc,11)};d.CH=function(a,b){return l.u.La(this,11,a,x.i.Pc,b)};d.ay=function(){return l.u.Ma(this,x.i.Pc,12)};\nd.DH=function(a,b){return l.u.La(this,12,a,x.i.Pc,b)};d.Tz=function(){return l.u.Ma(this,x.i.Je,20)};d.WI=function(a,b){return l.u.La(this,20,a,x.i.Je,b)};d.Ox=function(){return l.u.sa(this,x.google.N.Ba,13)};d.hQ=function(a){l.u.Ca(this,13,a)};x.i.mc.K=function(a){return l.u.K(x.i.mc,a)};x.i.Za=function(a){l.u.initialize(this,a,0,-1,null,x.i.Za.Ob)};h.da(x.i.Za,l.u);x.i.Za.Ob=[[1,2]];x.i.Za.lX={eX:0,$W:1,PY:2};\nl.u.ha&&(x.i.Za.prototype.C=function(a){return x.i.Za.C(a,this)},x.i.Za.C=function(a,b){var c,e={B2:(c=b.Wx())&&x.i.Za.Kd.C(a,c),n9:(c=b.Bz())&&x.i.Za.nd.C(a,c)};a&&(e.ja=b);return e});x.i.Za.ia=function(a){a=new l.ba(a);var b=new x.i.Za;return x.i.Za.F(b,a)};x.i.Za.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.Za.Kd;b.T(c,x.i.Za.Kd.F);a.sQ(c);break;case 2:c=new x.i.Za.nd;b.T(c,x.i.Za.nd.F);a.ZS(c);break;default:b.ea()}}return a};\nx.i.Za.G=function(a,b){var c;c=a.Wx();null!=c&&b.oa(1,c,x.i.Za.Kd.G);c=a.Bz();null!=c&&b.oa(2,c,x.i.Za.nd.G)};x.i.Za.prototype.Wx=function(){return l.u.sa(this,x.i.Za.Kd,1)};x.i.Za.prototype.sQ=function(a){l.u.Nc(this,1,x.i.Za.Ob[0],a)};x.i.Za.prototype.Bz=function(){return l.u.sa(this,x.i.Za.nd,2)};x.i.Za.prototype.ZS=function(a){l.u.Nc(this,2,x.i.Za.Ob[0],a)};x.i.Za.K=function(a){return l.u.K(x.i.Za,a)};x.i.Za.Kd=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.Za.Kd,l.u);\nl.u.ha&&(x.i.Za.Kd.prototype.C=function(a){return x.i.Za.Kd.C(a,this)},x.i.Za.Kd.C=function(a,b){var c,e={TJ:(c=b.Kl())&&x.i.yc.C(a,c),matrix:(c=b.rz())&&x.i.dd.C(a,c)};a&&(e.ja=b);return e});x.i.Za.Kd.ia=function(a){a=new l.ba(a);var b=new x.i.Za.Kd;return x.i.Za.Kd.F(b,a)};x.i.Za.Kd.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.yc;b.T(c,x.i.yc.F);a.Ls(c);break;case 2:c=new x.i.dd;b.T(c,x.i.dd.F);a.setMatrix(c);break;default:b.ea()}}return a};\nx.i.Za.Kd.G=function(a,b){var c;c=a.Kl();null!=c&&b.oa(1,c,x.i.yc.G);c=a.rz();null!=c&&b.oa(2,c,x.i.dd.G)};x.i.Za.Kd.prototype.Kl=function(){return l.u.sa(this,x.i.yc,1)};x.i.Za.Kd.prototype.Ls=function(a){l.u.Ca(this,1,a)};x.i.Za.Kd.prototype.rz=function(){return l.u.sa(this,x.i.dd,2)};x.i.Za.Kd.prototype.setMatrix=function(a){l.u.Ca(this,2,a)};x.i.Za.Kd.K=function(a){return l.u.K(x.i.Za.Kd,a)};x.i.Za.nd=function(a){l.u.initialize(this,a,0,-1,x.i.Za.nd.na,null)};h.da(x.i.Za.nd,l.u);\nx.i.Za.nd.na=[1];l.u.ha&&(x.i.Za.nd.prototype.C=function(a){return x.i.Za.nd.C(a,this)},x.i.Za.nd.C=function(a,b){var c,e={daa:l.u.gb(b,1),N2:(c=b.by())&&x.i.ed.C(a,c)};a&&(e.ja=b);return e});x.i.Za.nd.ia=function(a){a=new l.ba(a);var b=new x.i.Za.nd;return x.i.Za.nd.F(b,a)};x.i.Za.nd.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.rm();a.kU(c);break;case 2:c=new x.i.ed;b.T(c,x.i.ed.F);a.wQ(c);break;default:b.ea()}}return a};\nx.i.Za.nd.G=function(a,b){var c;c=a.mM();0<c.length&&b.Mm(1,c);c=a.by();null!=c&&b.oa(2,c,x.i.ed.G)};x.i.Za.nd.prototype.mM=function(){return l.u.gb(this,1)};x.i.Za.nd.prototype.kU=function(a){l.u.J(this,1,a||[])};x.i.Za.nd.prototype.by=function(){return l.u.sa(this,x.i.ed,2)};x.i.Za.nd.prototype.wQ=function(a){l.u.Ca(this,2,a)};x.i.Za.nd.K=function(a){return l.u.K(x.i.Za.nd,a)};x.i.Re=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.Re,l.u);\nl.u.ha&&(x.i.Re.prototype.C=function(a){return x.i.Re.C(a,this)},x.i.Re.C=function(a,b){var c,e={lowerBound:(c=b.Xl())&&x.google.N.Ba.C(a,c),upperBound:(c=b.em())&&x.google.N.Ba.C(a,c),value:(c=b.getValue())&&x.google.N.Ba.C(a,c)};a&&(e.ja=b);return e});x.i.Re.ia=function(a){a=new l.ba(a);var b=new x.i.Re;return x.i.Re.F(b,a)};\nx.i.Re.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.google.N.Ba;b.T(c,x.google.N.Ba.F);a.tj(c);break;case 2:c=new x.google.N.Ba;b.T(c,x.google.N.Ba.F);a.xj(c);break;case 3:c=new x.google.N.Ba;b.T(c,x.google.N.Ba.F);a.setValue(c);break;default:b.ea()}}return a};x.i.Re.G=function(a,b){var c;c=a.Xl();null!=c&&b.oa(1,c,x.google.N.Ba.G);c=a.em();null!=c&&b.oa(2,c,x.google.N.Ba.G);c=a.getValue();null!=c&&b.oa(3,c,x.google.N.Ba.G)};d=x.i.Re.prototype;\nd.Xl=function(){return l.u.sa(this,x.google.N.Ba,1)};d.tj=function(a){l.u.Ca(this,1,a)};d.em=function(){return l.u.sa(this,x.google.N.Ba,2)};d.xj=function(a){l.u.Ca(this,2,a)};d.getValue=function(){return l.u.sa(this,x.google.N.Ba,3)};d.setValue=function(a){l.u.Ca(this,3,a)};x.i.Re.K=function(a){return l.u.K(x.i.Re,a)};x.i.Ga=function(a){l.u.initialize(this,a,0,-1,null,x.i.Ga.Ob)};h.da(x.i.Ga,l.u);x.i.Ga.Ob=[[1,2,3,4]];x.i.Ga.aF={$E:0,fD:1,sE:2,tE:3,gD:4};\nl.u.ha&&(x.i.Ga.prototype.C=function(a){return x.i.Ga.C(a,this)},x.i.Ga.C=function(a,b){var c,e={cj:(c=b.Nl())&&x.i.Ga.cc.C(a,c),oP:(c=b.$l())&&x.i.Ga.dc.C(a,c),pP:(c=b.am())&&x.i.Ga.ec.C(a,c),BK:(c=b.Pl())&&x.i.Ga.Bb.C(a,c),CK:(c=b.Ql())&&x.google.N.qc.C(a,c),value:+l.u.va(b,6,0)};a&&(e.ja=b);return e});x.i.Ga.ia=function(a){a=new l.ba(a);var b=new x.i.Ga;return x.i.Ga.F(b,a)};\nx.i.Ga.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.Ga.cc;b.T(c,x.i.Ga.cc.F);a.Os(c);break;case 2:c=new x.i.Ga.dc;b.T(c,x.i.Ga.dc.F);a.jt(c);break;case 3:c=new x.i.Ga.ec;b.T(c,x.i.Ga.ec.F);a.kt(c);break;case 4:c=new x.i.Ga.Bb;b.T(c,x.i.Ga.Bb.F);a.Ps(c);break;case 5:c=new x.google.N.qc;b.T(c,x.google.N.qc.F);a.Qs(c);break;case 6:c=b.pa();a.setValue(c);break;default:b.ea()}}return a};\nx.i.Ga.G=function(a,b){var c;c=a.Nl();null!=c&&b.oa(1,c,x.i.Ga.cc.G);c=a.$l();null!=c&&b.oa(2,c,x.i.Ga.dc.G);c=a.am();null!=c&&b.oa(3,c,x.i.Ga.ec.G);c=a.Pl();null!=c&&b.oa(4,c,x.i.Ga.Bb.G);c=a.Ql();null!=c&&b.oa(5,c,x.google.N.qc.G);c=a.getValue();0!==c&&b.ya(6,c)};d=x.i.Ga.prototype;d.Nl=function(){return l.u.sa(this,x.i.Ga.cc,1)};d.Os=function(a){l.u.Nc(this,1,x.i.Ga.Ob[0],a)};d.$l=function(){return l.u.sa(this,x.i.Ga.dc,2)};d.jt=function(a){l.u.Nc(this,2,x.i.Ga.Ob[0],a)};\nd.am=function(){return l.u.sa(this,x.i.Ga.ec,3)};d.kt=function(a){l.u.Nc(this,3,x.i.Ga.Ob[0],a)};d.Pl=function(){return l.u.sa(this,x.i.Ga.Bb,4)};d.Ps=function(a){l.u.Nc(this,4,x.i.Ga.Ob[0],a)};d.Ql=function(){return l.u.sa(this,x.google.N.qc,5)};d.Qs=function(a){l.u.Ca(this,5,a)};d.getValue=function(){return+l.u.va(this,6,0)};d.setValue=function(a){l.u.J(this,6,a)};x.i.Ga.K=function(a){return l.u.K(x.i.Ga,a)};x.i.Ga.cc=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.Ga.cc,l.u);\nl.u.ha&&(x.i.Ga.cc.prototype.C=function(a){return x.i.Ga.cc.C(a,this)},x.i.Ga.cc.C=function(a,b){var c={};a&&(c.ja=b);return c});x.i.Ga.cc.ia=function(a){a=new l.ba(a);var b=new x.i.Ga.cc;return x.i.Ga.cc.F(b,a)};x.i.Ga.cc.F=function(a,b){for(;b.fa()&&!b.ga();)b.ea();return a};x.i.Ga.cc.G=function(){};x.i.Ga.cc.K=function(a){return l.u.K(x.i.Ga.cc,a)};x.i.Ga.dc=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.Ga.dc,l.u);\nl.u.ha&&(x.i.Ga.dc.prototype.C=function(a){return x.i.Ga.dc.C(a,this)},x.i.Ga.dc.C=function(a,b){var c={};a&&(c.ja=b);return c});x.i.Ga.dc.ia=function(a){a=new l.ba(a);var b=new x.i.Ga.dc;return x.i.Ga.dc.F(b,a)};x.i.Ga.dc.F=function(a,b){for(;b.fa()&&!b.ga();)b.ea();return a};x.i.Ga.dc.G=function(){};x.i.Ga.dc.K=function(a){return l.u.K(x.i.Ga.dc,a)};x.i.Ga.ec=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.Ga.ec,l.u);\nl.u.ha&&(x.i.Ga.ec.prototype.C=function(a){return x.i.Ga.ec.C(a,this)},x.i.Ga.ec.C=function(a,b){var c={};a&&(c.ja=b);return c});x.i.Ga.ec.ia=function(a){a=new l.ba(a);var b=new x.i.Ga.ec;return x.i.Ga.ec.F(b,a)};x.i.Ga.ec.F=function(a,b){for(;b.fa()&&!b.ga();)b.ea();return a};x.i.Ga.ec.G=function(){};x.i.Ga.ec.K=function(a){return l.u.K(x.i.Ga.ec,a)};x.i.Ga.Bb=function(a){l.u.initialize(this,a,0,-1,x.i.Ga.Bb.na,null)};h.da(x.i.Ga.Bb,l.u);x.i.Ga.Bb.na=[1];\nl.u.ha&&(x.i.Ga.Bb.prototype.C=function(a){return x.i.Ga.Bb.C(a,this)},x.i.Ga.Bb.C=function(a,b){var c={DW:l.u.gb(b,1)};a&&(c.ja=b);return c});x.i.Ga.Bb.ia=function(a){a=new l.ba(a);var b=new x.i.Ga.Bb;return x.i.Ga.Bb.F(b,a)};x.i.Ga.Bb.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.rm();a.rt(c);break;default:b.ea()}}return a};x.i.Ga.Bb.G=function(a,b){a=a.Tr();0<a.length&&b.Mm(1,a)};x.i.Ga.Bb.prototype.Tr=function(){return l.u.gb(this,1)};\nx.i.Ga.Bb.prototype.rt=function(a){l.u.J(this,1,a||[])};x.i.Ga.Bb.K=function(a){return l.u.K(x.i.Ga.Bb,a)};x.i.Vd=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.Vd,l.u);l.u.ha&&(x.i.Vd.prototype.C=function(a){return x.i.Vd.C(a,this)},x.i.Vd.C=function(a,b){var c,e={aj:(c=b.Hg())&&x.google.N.Ke.C(a,c),type:l.u.va(b,2,0),sign:l.u.va(b,3,0),weight:+l.u.va(b,4,0)};a&&(e.ja=b);return e});x.i.Vd.ia=function(a){a=new l.ba(a);var b=new x.i.Vd;return x.i.Vd.F(b,a)};\nx.i.Vd.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.google.N.Ke;b.T(c,x.google.N.Ke.F);a.xf(c);break;case 2:c=b.we();a.yf(c);break;case 3:c=b.we();a.IU(c);break;case 4:c=b.pa();a.qt(c);break;default:b.ea()}}return a};x.i.Vd.G=function(a,b){var c;c=a.Hg();null!=c&&b.oa(1,c,x.google.N.Ke.G);c=a.mi();0!==c&&b.xe(2,c);c=a.tM();0!==c&&b.xe(3,c);c=a.Sr();0!==c&&b.ya(4,c)};d=x.i.Vd.prototype;d.Hg=function(){return l.u.sa(this,x.google.N.Ke,1)};\nd.xf=function(a){l.u.Ca(this,1,a)};d.mi=function(){return l.u.va(this,2,0)};d.yf=function(a){l.u.J(this,2,a)};d.tM=function(){return l.u.va(this,3,0)};d.IU=function(a){l.u.J(this,3,a)};d.Sr=function(){return+l.u.va(this,4,0)};d.qt=function(a){l.u.J(this,4,a)};x.i.Vd.K=function(a){return l.u.K(x.i.Vd,a)};x.i.Vd.yg={sY:0,tY:1,uY:2};x.i.Vd.WZ={Ai:0,lE:1,$D:2};x.i.rc=function(a){l.u.initialize(this,a,0,-1,x.i.rc.na,null)};h.da(x.i.rc,l.u);x.i.rc.na=[1];\nl.u.ha&&(x.i.rc.prototype.C=function(a){return x.i.rc.C(a,this)},x.i.rc.C=function(a,b){var c={vaa:l.u.Ka(b.hA(),x.i.Vd.C,a),value:+l.u.va(b,2,0)};a&&(c.ja=b);return c});x.i.rc.ia=function(a){a=new l.ba(a);var b=new x.i.rc;return x.i.rc.F(b,a)};x.i.rc.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.Vd;b.T(c,x.i.Vd.F);a.$I(c);break;case 2:c=b.pa();a.setValue(c);break;default:b.ea()}}return a};\nx.i.rc.G=function(a,b){var c;c=a.hA();0<c.length&&b.Oa(1,c,x.i.Vd.G);c=a.getValue();0!==c&&b.ya(2,c)};x.i.rc.prototype.hA=function(){return l.u.Ma(this,x.i.Vd,1)};x.i.rc.prototype.$I=function(a,b){return l.u.La(this,1,a,x.i.Vd,b)};x.i.rc.prototype.getValue=function(){return+l.u.va(this,2,0)};x.i.rc.prototype.setValue=function(a){l.u.J(this,2,a)};x.i.rc.K=function(a){return l.u.K(x.i.rc,a)};x.i.yc=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.yc,l.u);\nl.u.ha&&(x.i.yc.prototype.C=function(a){return x.i.yc.C(a,this)},x.i.yc.C=function(a,b){var c={caa:+l.u.va(b,1,0),zca:l.u.va(b,2,0)};a&&(c.ja=b);return c});x.i.yc.ia=function(a){a=new l.ba(a);var b=new x.i.yc;return x.i.yc.F(b,a)};x.i.yc.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.pa();a.jU(c);break;case 2:c=b.we();a.gV(c);break;default:b.ea()}}return a};x.i.yc.G=function(a,b){var c;c=a.lM();0!==c&&b.ya(1,c);c=a.DM();0!==c&&b.xe(2,c)};\nx.i.yc.prototype.lM=function(){return+l.u.va(this,1,0)};x.i.yc.prototype.jU=function(a){l.u.J(this,1,a)};x.i.yc.prototype.DM=function(){return l.u.va(this,2,0)};x.i.yc.prototype.gV=function(a){l.u.J(this,2,a)};x.i.yc.K=function(a){return l.u.K(x.i.yc,a)};x.i.yc.k_={l_:0,lE:1,$D:2};x.i.dd=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.dd,l.u);\nl.u.ha&&(x.i.dd.prototype.C=function(a){return x.i.dd.C(a,this)},x.i.dd.C=function(a,b){var c={hda:+l.u.va(b,1,0),R5:+l.u.va(b,2,0),fda:+l.u.va(b,3,0),P5:+l.u.va(b,4,0)};a&&(c.ja=b);return c});x.i.dd.ia=function(a){a=new l.ba(a);var b=new x.i.dd;return x.i.dd.F(b,a)};x.i.dd.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.pa();a.CV(c);break;case 2:c=b.pa();a.AR(c);break;case 3:c=b.pa();a.BV(c);break;case 4:c=b.pa();a.zR(c);break;default:b.ea()}}return a};\nx.i.dd.G=function(a,b){var c;c=a.HM();0!==c&&b.ya(1,c);c=a.GL();0!==c&&b.ya(2,c);c=a.FM();0!==c&&b.ya(3,c);c=a.EL();0!==c&&b.ya(4,c)};d=x.i.dd.prototype;d.HM=function(){return+l.u.va(this,1,0)};d.CV=function(a){l.u.J(this,1,a)};d.GL=function(){return+l.u.va(this,2,0)};d.AR=function(a){l.u.J(this,2,a)};d.FM=function(){return+l.u.va(this,3,0)};d.BV=function(a){l.u.J(this,3,a)};d.EL=function(){return+l.u.va(this,4,0)};d.zR=function(a){l.u.J(this,4,a)};x.i.dd.K=function(a){return l.u.K(x.i.dd,a)};\nx.i.ed=function(a){l.u.initialize(this,a,0,-1,x.i.ed.na,null)};h.da(x.i.ed,l.u);x.i.ed.na=[1,2];l.u.ha&&(x.i.ed.prototype.C=function(a){return x.i.ed.C(a,this)},x.i.ed.C=function(a,b){var c={t9:l.u.gb(b,1),H$:l.u.gb(b,2)};a&&(c.ja=b);return c});x.i.ed.ia=function(a){a=new l.ba(a);var b=new x.i.ed;return x.i.ed.F(b,a)};x.i.ed.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.rm();a.dT(c);break;case 2:c=b.rm();a.TT(c);break;default:b.ea()}}return a};\nx.i.ed.G=function(a,b){var c;c=a.aM();0<c.length&&b.Mm(1,c);c=a.gM();0<c.length&&b.Mm(2,c)};x.i.ed.prototype.aM=function(){return l.u.gb(this,1)};x.i.ed.prototype.dT=function(a){l.u.J(this,1,a||[])};x.i.ed.prototype.gM=function(){return l.u.gb(this,2)};x.i.ed.prototype.TT=function(a){l.u.J(this,2,a||[])};x.i.ed.K=function(a){return l.u.K(x.i.ed,a)};x.i.Pc=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.Pc,l.u);\nl.u.ha&&(x.i.Pc.prototype.C=function(a){return x.i.Pc.C(a,this)},x.i.Pc.C=function(a,b){var c,e={r8:+l.u.va(b,1,0),pda:+l.u.va(b,2,0),X9:(c=b.Iz())&&x.google.N.Ba.C(a,c),Pca:(c=b.JA())&&x.google.N.Ba.C(a,c),Rca:(c=b.LA())&&x.google.N.Ba.C(a,c),Qca:(c=b.KA())&&x.google.N.Ba.C(a,c)};a&&(e.ja=b);return e});x.i.Pc.ia=function(a){a=new l.ba(a);var b=new x.i.Pc;return x.i.Pc.F(b,a)};\nx.i.Pc.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.pa();a.sS(c);break;case 2:c=b.pa();a.DV(c);break;case 3:c=new x.google.N.Ba;b.T(c,x.google.N.Ba.F);a.zT(c);break;case 4:c=new x.google.N.Ba;b.T(c,x.google.N.Ba.F);a.qV(c);break;case 5:c=new x.google.N.Ba;b.T(c,x.google.N.Ba.F);a.sV(c);break;case 6:c=new x.google.N.Ba;b.T(c,x.google.N.Ba.F);a.rV(c);break;default:b.ea()}}return a};\nx.i.Pc.G=function(a,b){var c;c=a.SL();0!==c&&b.ya(1,c);c=a.JM();0!==c&&b.ya(2,c);c=a.Iz();null!=c&&b.oa(3,c,x.google.N.Ba.G);c=a.JA();null!=c&&b.oa(4,c,x.google.N.Ba.G);c=a.LA();null!=c&&b.oa(5,c,x.google.N.Ba.G);c=a.KA();null!=c&&b.oa(6,c,x.google.N.Ba.G)};d=x.i.Pc.prototype;d.SL=function(){return+l.u.va(this,1,0)};d.sS=function(a){l.u.J(this,1,a)};d.JM=function(){return+l.u.va(this,2,0)};d.DV=function(a){l.u.J(this,2,a)};d.Iz=function(){return l.u.sa(this,x.google.N.Ba,3)};\nd.zT=function(a){l.u.Ca(this,3,a)};d.JA=function(){return l.u.sa(this,x.google.N.Ba,4)};d.qV=function(a){l.u.Ca(this,4,a)};d.LA=function(){return l.u.sa(this,x.google.N.Ba,5)};d.sV=function(a){l.u.Ca(this,5,a)};d.KA=function(){return l.u.sa(this,x.google.N.Ba,6)};d.rV=function(a){l.u.Ca(this,6,a)};x.i.Pc.K=function(a){return l.u.K(x.i.Pc,a)};x.i.ua=function(a){l.u.initialize(this,a,0,-1,null,x.i.ua.Ob)};h.da(x.i.ua,l.u);x.i.ua.Ob=[[1,2,3,4,7]];x.i.ua.aF={$E:0,BZ:1,sE:2,tE:3,gD:4,fD:7};\nl.u.ha&&(x.i.ua.prototype.C=function(a){return x.i.ua.C(a,this)},x.i.ua.C=function(a,b){var c,e={qaa:(c=b.fA())&&x.i.ua.hf.C(a,c),oP:(c=b.$l())&&x.i.ua.dc.C(a,c),pP:(c=b.am())&&x.i.ua.ec.C(a,c),BK:(c=b.Pl())&&x.i.ua.Bb.C(a,c),cj:(c=b.Nl())&&x.i.ua.cc.C(a,c),CK:(c=b.Ql())&&x.google.N.qc.C(a,c),value:+l.u.va(b,6,0)};a&&(e.ja=b);return e});x.i.ua.ia=function(a){a=new l.ba(a);var b=new x.i.ua;return x.i.ua.F(b,a)};\nx.i.ua.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.ua.hf;b.T(c,x.i.ua.hf.F);a.sU(c);break;case 2:c=new x.i.ua.dc;b.T(c,x.i.ua.dc.F);a.jt(c);break;case 3:c=new x.i.ua.ec;b.T(c,x.i.ua.ec.F);a.kt(c);break;case 4:c=new x.i.ua.Bb;b.T(c,x.i.ua.Bb.F);a.Ps(c);break;case 7:c=new x.i.ua.cc;b.T(c,x.i.ua.cc.F);a.Os(c);break;case 5:c=new x.google.N.qc;b.T(c,x.google.N.qc.F);a.Qs(c);break;case 6:c=b.pa();a.setValue(c);break;default:b.ea()}}return a};\nx.i.ua.G=function(a,b){var c;c=a.fA();null!=c&&b.oa(1,c,x.i.ua.hf.G);c=a.$l();null!=c&&b.oa(2,c,x.i.ua.dc.G);c=a.am();null!=c&&b.oa(3,c,x.i.ua.ec.G);c=a.Pl();null!=c&&b.oa(4,c,x.i.ua.Bb.G);c=a.Nl();null!=c&&b.oa(7,c,x.i.ua.cc.G);c=a.Ql();null!=c&&b.oa(5,c,x.google.N.qc.G);c=a.getValue();0!==c&&b.ya(6,c)};d=x.i.ua.prototype;d.fA=function(){return l.u.sa(this,x.i.ua.hf,1)};d.sU=function(a){l.u.Nc(this,1,x.i.ua.Ob[0],a)};d.$l=function(){return l.u.sa(this,x.i.ua.dc,2)};\nd.jt=function(a){l.u.Nc(this,2,x.i.ua.Ob[0],a)};d.am=function(){return l.u.sa(this,x.i.ua.ec,3)};d.kt=function(a){l.u.Nc(this,3,x.i.ua.Ob[0],a)};d.Pl=function(){return l.u.sa(this,x.i.ua.Bb,4)};d.Ps=function(a){l.u.Nc(this,4,x.i.ua.Ob[0],a)};d.Nl=function(){return l.u.sa(this,x.i.ua.cc,7)};d.Os=function(a){l.u.Nc(this,7,x.i.ua.Ob[0],a)};d.Ql=function(){return l.u.sa(this,x.google.N.qc,5)};d.Qs=function(a){l.u.Ca(this,5,a)};d.getValue=function(){return+l.u.va(this,6,0)};\nd.setValue=function(a){l.u.J(this,6,a)};x.i.ua.K=function(a){return l.u.K(x.i.ua,a)};x.i.ua.hf=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.ua.hf,l.u);l.u.ha&&(x.i.ua.hf.prototype.C=function(a){return x.i.ua.hf.C(a,this)},x.i.ua.hf.C=function(a,b){var c={};a&&(c.ja=b);return c});x.i.ua.hf.ia=function(a){a=new l.ba(a);var b=new x.i.ua.hf;return x.i.ua.hf.F(b,a)};x.i.ua.hf.F=function(a,b){for(;b.fa()&&!b.ga();)b.ea();return a};x.i.ua.hf.G=function(){};\nx.i.ua.hf.K=function(a){return l.u.K(x.i.ua.hf,a)};x.i.ua.dc=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.ua.dc,l.u);l.u.ha&&(x.i.ua.dc.prototype.C=function(a){return x.i.ua.dc.C(a,this)},x.i.ua.dc.C=function(a,b){var c={};a&&(c.ja=b);return c});x.i.ua.dc.ia=function(a){a=new l.ba(a);var b=new x.i.ua.dc;return x.i.ua.dc.F(b,a)};x.i.ua.dc.F=function(a,b){for(;b.fa()&&!b.ga();)b.ea();return a};x.i.ua.dc.G=function(){};x.i.ua.dc.K=function(a){return l.u.K(x.i.ua.dc,a)};\nx.i.ua.ec=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.ua.ec,l.u);l.u.ha&&(x.i.ua.ec.prototype.C=function(a){return x.i.ua.ec.C(a,this)},x.i.ua.ec.C=function(a,b){var c={};a&&(c.ja=b);return c});x.i.ua.ec.ia=function(a){a=new l.ba(a);var b=new x.i.ua.ec;return x.i.ua.ec.F(b,a)};x.i.ua.ec.F=function(a,b){for(;b.fa()&&!b.ga();)b.ea();return a};x.i.ua.ec.G=function(){};x.i.ua.ec.K=function(a){return l.u.K(x.i.ua.ec,a)};x.i.ua.Bb=function(a){l.u.initialize(this,a,0,-1,x.i.ua.Bb.na,null)};\nh.da(x.i.ua.Bb,l.u);x.i.ua.Bb.na=[1];l.u.ha&&(x.i.ua.Bb.prototype.C=function(a){return x.i.ua.Bb.C(a,this)},x.i.ua.Bb.C=function(a,b){var c={DW:l.u.gb(b,1)};a&&(c.ja=b);return c});x.i.ua.Bb.ia=function(a){a=new l.ba(a);var b=new x.i.ua.Bb;return x.i.ua.Bb.F(b,a)};x.i.ua.Bb.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.rm();a.rt(c);break;default:b.ea()}}return a};x.i.ua.Bb.G=function(a,b){a=a.Tr();0<a.length&&b.Mm(1,a)};\nx.i.ua.Bb.prototype.Tr=function(){return l.u.gb(this,1)};x.i.ua.Bb.prototype.rt=function(a){l.u.J(this,1,a||[])};x.i.ua.Bb.K=function(a){return l.u.K(x.i.ua.Bb,a)};x.i.ua.cc=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.ua.cc,l.u);l.u.ha&&(x.i.ua.cc.prototype.C=function(a){return x.i.ua.cc.C(a,this)},x.i.ua.cc.C=function(a,b){var c={};a&&(c.ja=b);return c});x.i.ua.cc.ia=function(a){a=new l.ba(a);var b=new x.i.ua.cc;return x.i.ua.cc.F(b,a)};\nx.i.ua.cc.F=function(a,b){for(;b.fa()&&!b.ga();)b.ea();return a};x.i.ua.cc.G=function(){};x.i.ua.cc.K=function(a){return l.u.K(x.i.ua.cc,a)};x.i.ke=function(a){l.u.initialize(this,a,0,-1,x.i.ke.na,null)};h.da(x.i.ke,l.u);x.i.ke.na=[1,2,3];l.u.ha&&(x.i.ke.prototype.C=function(a){return x.i.ke.C(a,this)},x.i.ke.C=function(a,b){var c,e={q3:l.u.Ka(b.iy(),x.i.ua.C,a),laa:l.u.Ka(b.dA(),x.i.ua.C,a),w7:l.u.Ka(b.jz(),x.i.ua.C,a),m2:(c=b.Qx())&&x.google.N.Ba.C(a,c)};a&&(e.ja=b);return e});\nx.i.ke.ia=function(a){a=new l.ba(a);var b=new x.i.ke;return x.i.ke.F(b,a)};x.i.ke.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.ua;b.T(c,x.i.ua.F);a.HH(c);break;case 2:c=new x.i.ua;b.T(c,x.i.ua.F);a.YI(c);break;case 3:c=new x.i.ua;b.T(c,x.i.ua.F);a.tI(c);break;case 4:c=new x.google.N.Ba;b.T(c,x.google.N.Ba.F);a.jQ(c);break;default:b.ea()}}return a};\nx.i.ke.G=function(a,b){var c;c=a.iy();0<c.length&&b.Oa(1,c,x.i.ua.G);c=a.dA();0<c.length&&b.Oa(2,c,x.i.ua.G);c=a.jz();0<c.length&&b.Oa(3,c,x.i.ua.G);c=a.Qx();null!=c&&b.oa(4,c,x.google.N.Ba.G)};d=x.i.ke.prototype;d.iy=function(){return l.u.Ma(this,x.i.ua,1)};d.HH=function(a,b){return l.u.La(this,1,a,x.i.ua,b)};d.dA=function(){return l.u.Ma(this,x.i.ua,2)};d.YI=function(a,b){return l.u.La(this,2,a,x.i.ua,b)};d.jz=function(){return l.u.Ma(this,x.i.ua,3)};\nd.tI=function(a,b){return l.u.La(this,3,a,x.i.ua,b)};d.Qx=function(){return l.u.sa(this,x.google.N.Ba,4)};d.jQ=function(a){l.u.Ca(this,4,a)};x.i.ke.K=function(a){return l.u.K(x.i.ke,a)};x.i.vc=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.vc,l.u);l.u.ha&&(x.i.vc.prototype.C=function(a){return x.i.vc.C(a,this)},x.i.vc.C=function(a,b){var c,e={g2:(c=b.Mx())&&x.Xa.Ec.C(a,c),aj:l.u.D(b,2)};a&&(e.ja=b);return e});x.i.vc.ia=function(a){a=new l.ba(a);var b=new x.i.vc;return x.i.vc.F(b,a)};\nx.i.vc.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.Xa.Ec;b.T(c,x.Xa.Ec.F);a.fQ(c);break;case 2:c=b.Aa();a.xf(c);break;default:b.ea()}}return a};x.i.vc.G=function(a,b){var c;c=a.Mx();null!=c&&b.oa(1,c,x.Xa.Ec.G);c=l.u.D(a,2);null!=c&&b.Ja(2,c)};x.i.vc.prototype.Mx=function(){return l.u.sa(this,x.Xa.Ec,1,1)};x.i.vc.prototype.fQ=function(a){l.u.Ca(this,1,a)};x.i.vc.prototype.Hg=function(){return l.u.D(this,2)};x.i.vc.prototype.xf=function(a){l.u.J(this,2,a)};\nx.i.vc.K=function(a){return l.u.K(x.i.vc,a)};x.i.Lb=function(a){l.u.initialize(this,a,0,-1,x.i.Lb.na,null)};h.da(x.i.Lb,l.u);x.i.Lb.na=[6,7,9];l.u.ha&&(x.i.Lb.prototype.C=function(a){return x.i.Lb.C(a,this)},x.i.Lb.C=function(a,b){var c,e={cluster:l.u.D(b,1),channel:l.u.D(b,2),Saa:l.u.Na(b,3),M8:l.u.va(b,4,15),B3:l.u.va(b,5,3),SJ:l.u.Ka(b.Il(),x.i.vc.C,a),B5:l.u.Ka(b.Oy(),x.jb.lb.mb.C,a),qda:l.u.va(b,8,!0),Eda:l.u.D(b,9),v3:(c=b.ky())&&x.i.Lb.Ae.C(a,c)};a&&(e.ja=b);return e});\nx.i.Lb.ia=function(a){a=new l.ba(a);var b=new x.i.Lb;return x.i.Lb.F(b,a)};\nx.i.Lb.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.HQ(c);break;case 2:c=b.Aa();a.DQ(c);break;case 3:c=b.ti();a.xU(c);break;case 4:c=b.Ya();a.HS(c);break;case 5:c=b.we();a.JQ(c);break;case 6:c=new x.i.vc;b.T(c,x.i.vc.F);a.Lq(c);break;case 7:c=new x.jb.lb.mb;b.T(c,x.jb.lb.mb.F);a.bI(c);break;case 8:c=b.vf();a.FV(c);break;case 9:c=b.Aa();a.EJ(c);break;case 10:c=new x.i.Lb.Ae;b.T(c,x.i.Lb.Ae.F);a.FQ(c);break;default:b.ea()}}return a};\nx.i.Lb.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Ja(1,c);c=l.u.D(a,2);null!=c&&b.Ja(2,c);c=l.u.D(a,3);null!=c&&b.vi(3,c);c=l.u.D(a,4);null!=c&&b.$a(4,c);c=l.u.D(a,5);null!=c&&b.xe(5,c);c=a.Il();0<c.length&&b.Oa(6,c,x.i.vc.G);c=a.Oy();0<c.length&&b.Oa(7,c,x.jb.lb.mb.G);c=l.u.D(a,8);null!=c&&b.kf(8,c);c=a.PM();0<c.length&&b.oc(9,c);c=a.ky();null!=c&&b.oa(10,c,x.i.Lb.Ae.G)};d=x.i.Lb.prototype;d.HQ=function(a){l.u.J(this,1,a)};d.DQ=function(a){l.u.J(this,2,a)};d.xU=function(a){l.u.J(this,3,a)};\nd.HS=function(a){l.u.J(this,4,a)};d.JQ=function(a){l.u.J(this,5,a)};d.Il=function(){return l.u.Ma(this,x.i.vc,6)};d.Lq=function(a,b){return l.u.La(this,6,a,x.i.vc,b)};d.Oy=function(){return l.u.Ma(this,x.jb.lb.mb,7)};d.bI=function(a,b){return l.u.La(this,7,a,x.jb.lb.mb,b)};d.FV=function(a){l.u.J(this,8,a)};d.PM=function(){return l.u.D(this,9)};d.EJ=function(a,b){l.u.ib(this,9,a,b)};d.ky=function(){return l.u.sa(this,x.i.Lb.Ae,10)};d.FQ=function(a){l.u.Ca(this,10,a)};\nx.i.Lb.K=function(a){return l.u.K(x.i.Lb,a)};x.i.Lb.Ae=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.Lb.Ae,l.u);l.u.ha&&(x.i.Lb.Ae.prototype.C=function(a){return x.i.Lb.Ae.C(a,this)},x.i.Lb.Ae.C=function(a,b){var c={i9:l.u.D(b,1),aca:l.u.D(b,2)};a&&(c.ja=b);return c});x.i.Lb.Ae.ia=function(a){a=new l.ba(a);var b=new x.i.Lb.Ae;return x.i.Lb.Ae.F(b,a)};x.i.Lb.Ae.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.XS(c);break;case 2:c=b.vf();a.aV(c);break;default:b.ea()}}return a};\nx.i.Lb.Ae.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Ja(1,c);c=l.u.D(a,2);null!=c&&b.kf(2,c)};x.i.Lb.Ae.prototype.XS=function(a){l.u.J(this,1,a)};x.i.Lb.Ae.prototype.aV=function(a){l.u.J(this,2,a)};x.i.Lb.Ae.K=function(a){return l.u.K(x.i.Lb.Ae,a)};x.i.Gb=function(a){l.u.initialize(this,a,0,-1,x.i.Gb.na,null)};h.da(x.i.Gb,l.u);x.i.Gb.na=[8,12,9,10,11];\nl.u.ha&&(x.i.Gb.prototype.C=function(a){return x.i.Gb.C(a,this)},x.i.Gb.C=function(a,b){var c={e6:l.u.Ka(b.Yy(),x.i.Lb.C,a),C9:l.u.Ka(b.Gz(),x.i.vc.C,a),M5:l.u.D(b,9),gba:l.u.Ka(b.mA(),x.i.Gb.Fc.C,a),S1:l.u.Ka(b.Lx(),x.i.Gb.Fc.C,a)};a&&(c.ja=b);return c});x.i.Gb.ia=function(a){a=new l.ba(a);var b=new x.i.Gb;return x.i.Gb.F(b,a)};\nx.i.Gb.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 8:c=new x.i.Lb;b.T(c,x.i.Lb.F);a.oI(c);break;case 12:c=new x.i.vc;b.T(c,x.i.vc.F);a.KI(c);break;case 9:c=b.Aa();a.iI(c);break;case 10:c=new x.i.Gb.Fc;b.T(c,x.i.Gb.Fc.F);a.eJ(c);break;case 11:c=new x.i.Gb.Fc;b.T(c,x.i.Gb.Fc.F);a.tH(c);break;default:b.ea()}}return a};\nx.i.Gb.G=function(a,b){var c;c=a.Yy();0<c.length&&b.Oa(8,c,x.i.Lb.G);c=a.Gz();0<c.length&&b.Oa(12,c,x.i.vc.G);c=a.DL();0<c.length&&b.oc(9,c);c=a.mA();0<c.length&&b.Oa(10,c,x.i.Gb.Fc.G);c=a.Lx();0<c.length&&b.Oa(11,c,x.i.Gb.Fc.G)};d=x.i.Gb.prototype;d.Yy=function(){return l.u.Ma(this,x.i.Lb,8)};d.oI=function(a,b){return l.u.La(this,8,a,x.i.Lb,b)};d.Gz=function(){return l.u.Ma(this,x.i.vc,12)};d.KI=function(a,b){return l.u.La(this,12,a,x.i.vc,b)};d.DL=function(){return l.u.D(this,9)};\nd.iI=function(a,b){l.u.ib(this,9,a,b)};d.mA=function(){return l.u.Ma(this,x.i.Gb.Fc,10)};d.eJ=function(a,b){return l.u.La(this,10,a,x.i.Gb.Fc,b)};d.Lx=function(){return l.u.Ma(this,x.i.Gb.Fc,11)};d.tH=function(a,b){return l.u.La(this,11,a,x.i.Gb.Fc,b)};x.i.Gb.K=function(a){return l.u.K(x.i.Gb,a)};x.i.Gb.Fc=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.Gb.Fc,l.u);\nl.u.ha&&(x.i.Gb.Fc.prototype.C=function(a){return x.i.Gb.Fc.C(a,this)},x.i.Gb.Fc.C=function(a,b){var c={Eba:l.u.D(b,2),W4:l.u.D(b,3)};a&&(c.ja=b);return c});x.i.Gb.Fc.ia=function(a){a=new l.ba(a);var b=new x.i.Gb.Fc;return x.i.Gb.Fc.F(b,a)};x.i.Gb.Fc.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 2:c=b.Aa();a.MU(c);break;case 3:c=b.Aa();a.fR(c);break;default:b.ea()}}return a};x.i.Gb.Fc.G=function(a,b){var c;c=l.u.D(a,2);null!=c&&b.Ja(2,c);c=l.u.D(a,3);null!=c&&b.Ja(3,c)};\nx.i.Gb.Fc.prototype.MU=function(a){l.u.J(this,2,a)};x.i.Gb.Fc.prototype.fR=function(a){l.u.J(this,3,a)};x.i.Gb.Fc.K=function(a){return l.u.K(x.i.Gb.Fc,a)};x.i.qe=function(a){l.u.initialize(this,a,0,-1,x.i.qe.na,null)};h.da(x.i.qe,l.u);x.i.qe.na=[10];\nl.u.ha&&(x.i.qe.prototype.C=function(a){return x.i.qe.C(a,this)},x.i.qe.C=function(a,b){var c,e={Oba:l.u.D(b,2),j7:l.u.va(b,3,24),h7:l.u.D(b,4),N$:l.u.D(b,5),z9:l.u.D(b,6),V8:l.u.D(b,7),d7:l.u.Na(b,9),l2:l.u.Ka(b.Px(),x.i.cd.C,a),k7:l.u.D(b,8),s7:l.u.va(b,12,\"UTC\"),maa:l.u.D(b,13),D8:l.u.D(b,15),Bba:l.u.D(b,14),Dba:(c=b.tA())&&x.i.Xd.C(a,c)};a&&(e.ja=b);return e});x.i.qe.ia=function(a){a=new l.ba(a);var b=new x.i.qe;return x.i.qe.F(b,a)};\nx.i.qe.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 2:c=b.Aa();a.RU(c);break;case 3:c=b.Ya();a.UR(c);break;case 4:c=b.Ya();a.SR(c);break;case 5:c=b.Ya();a.ZT(c);break;case 6:c=b.Ya();a.jT(c);break;case 7:c=b.Ya();a.QS(c);break;case 9:c=b.ti();a.OR(c);break;case 10:c=new x.i.cd;b.T(c,x.i.cd.F);a.wH(c);break;case 8:c=b.Ya();a.VR(c);break;case 12:c=b.Aa();a.aS(c);break;case 13:c=b.Aa();a.qU(c);break;case 15:c=b.ad();a.ES(c);break;case 14:c=b.Aa();a.KU(c);break;case 16:c=new x.i.Xd;\nb.T(c,x.i.Xd.F);a.LU(c);break;default:b.ea()}}return a};\nx.i.qe.G=function(a,b){var c;c=l.u.D(a,2);null!=c&&b.Ja(2,c);c=l.u.D(a,3);null!=c&&b.$a(3,c);c=l.u.D(a,4);null!=c&&b.$a(4,c);c=l.u.D(a,5);null!=c&&b.$a(5,c);c=l.u.D(a,6);null!=c&&b.$a(6,c);c=l.u.D(a,7);null!=c&&b.$a(7,c);c=l.u.D(a,9);null!=c&&b.vi(9,c);c=a.Px();0<c.length&&b.Oa(10,c,x.i.cd.G);c=l.u.D(a,8);null!=c&&b.$a(8,c);c=l.u.D(a,12);null!=c&&b.Ja(12,c);c=l.u.D(a,13);null!=c&&b.Ja(13,c);c=l.u.D(a,15);null!=c&&b.td(15,c);c=l.u.D(a,14);null!=c&&b.Ja(14,c);c=a.tA();null!=c&&b.oa(16,c,x.i.Xd.G)};\nd=x.i.qe.prototype;d.getStartDate=function(){return l.u.D(this,2)};d.RU=function(a){l.u.J(this,2,a)};d.UR=function(a){l.u.J(this,3,a)};d.SR=function(a){l.u.J(this,4,a)};d.ZT=function(a){l.u.J(this,5,a)};d.jT=function(a){l.u.J(this,6,a)};d.QS=function(a){l.u.J(this,7,a)};d.OR=function(a){l.u.J(this,9,a)};d.Px=function(){return l.u.Ma(this,x.i.cd,10)};d.wH=function(a,b){return l.u.La(this,10,a,x.i.cd,b)};d.VR=function(a){l.u.J(this,8,a)};d.aS=function(a){l.u.J(this,12,a)};\nd.qU=function(a){l.u.J(this,13,a)};d.ES=function(a){l.u.J(this,15,a)};d.KU=function(a){l.u.J(this,14,a)};d.tA=function(){return l.u.sa(this,x.i.Xd,16)};d.LU=function(a){l.u.Ca(this,16,a)};x.i.qe.K=function(a){return l.u.K(x.i.qe,a)};x.i.Xd=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.Xd,l.u);l.u.ha&&(x.i.Xd.prototype.C=function(a){return x.i.Xd.C(a,this)},x.i.Xd.C=function(a,b){var c={naa:+l.u.va(b,1,1),Lda:+l.u.va(b,2,1),Haa:l.u.D(b,3),X4:l.u.D(b,4)};a&&(c.ja=b);return c});\nx.i.Xd.ia=function(a){a=new l.ba(a);var b=new x.i.Xd;return x.i.Xd.F(b,a)};x.i.Xd.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.ti();a.rU(c);break;case 2:c=b.ti();a.RV(c);break;case 3:c=b.Aa();a.vU(c);break;case 4:c=b.vf();a.gR(c);break;default:b.ea()}}return a};x.i.Xd.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.vi(1,c);c=l.u.D(a,2);null!=c&&b.vi(2,c);c=l.u.D(a,3);null!=c&&b.Ja(3,c);c=l.u.D(a,4);null!=c&&b.kf(4,c)};x.i.Xd.prototype.rU=function(a){l.u.J(this,1,a)};\nx.i.Xd.prototype.RV=function(a){l.u.J(this,2,a)};x.i.Xd.prototype.vU=function(a){l.u.J(this,3,a)};x.i.Xd.prototype.gR=function(a){l.u.J(this,4,a)};x.i.Xd.K=function(a){return l.u.K(x.i.Xd,a)};x.i.cd=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.cd,l.u);l.u.ha&&(x.i.cd.prototype.C=function(a){return x.i.cd.C(a,this)},x.i.cd.C=function(a,b){var c={type:l.u.D(b,1),aj:l.u.D(b,2)};a&&(c.ja=b);return c});x.i.cd.ia=function(a){a=new l.ba(a);var b=new x.i.cd;return x.i.cd.F(b,a)};\nx.i.cd.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.we();a.yf(c);break;case 2:c=b.Aa();a.xf(c);break;default:b.ea()}}return a};x.i.cd.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.xe(1,c);c=l.u.D(a,2);null!=c&&b.Ja(2,c)};x.i.cd.prototype.mi=function(){return l.u.D(this,1)};x.i.cd.prototype.yf=function(a){l.u.J(this,1,a)};x.i.cd.prototype.Hg=function(){return l.u.D(this,2)};x.i.cd.prototype.xf=function(a){l.u.J(this,2,a)};x.i.cd.K=function(a){return l.u.K(x.i.cd,a)};\nx.i.cd.XW={QZ:0,PZ:1,LZ:2};x.i.Le=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.Le,l.u);l.u.ha&&(x.i.Le.prototype.C=function(a){return x.i.Le.C(a,this)},x.i.Le.C=function(a,b){var c,e={aj:l.u.D(b,1),IO:l.u.D(b,2),R9:l.u.D(b,3),P9:l.u.D(b,4),G$:+l.u.D(b,5),s9:+l.u.D(b,6),Z6:(c=b.az())&&x.i.nb.C(a,c)};a&&(e.ja=b);return e});x.i.Le.ia=function(a){a=new l.ba(a);var b=new x.i.Le;return x.i.Le.F(b,a)};\nx.i.Le.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.xf(c);break;case 2:c=b.ad();a.ft(c);break;case 3:c=b.ad();a.uT(c);break;case 4:c=b.ad();a.sT(c);break;case 5:c=b.pa();a.ST(c);break;case 6:c=b.pa();a.cT(c);break;case 7:c=new x.i.nb;b.T(c,x.i.nb.F);a.LR(c);break;default:b.ea()}}return a};\nx.i.Le.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Ja(1,c);c=l.u.D(a,2);null!=c&&b.td(2,c);c=l.u.D(a,3);null!=c&&b.td(3,c);c=l.u.D(a,4);null!=c&&b.td(4,c);c=l.u.D(a,5);null!=c&&b.ya(5,c);c=l.u.D(a,6);null!=c&&b.ya(6,c);c=a.az();null!=c&&b.oa(7,c,x.i.nb.G)};d=x.i.Le.prototype;d.Hg=function(){return l.u.D(this,1)};d.xf=function(a){l.u.J(this,1,a)};d.ft=function(a){l.u.J(this,2,a)};d.uT=function(a){l.u.J(this,3,a)};d.sT=function(a){l.u.J(this,4,a)};d.ST=function(a){l.u.J(this,5,a)};\nd.cT=function(a){l.u.J(this,6,a)};d.az=function(){return l.u.sa(this,x.i.nb,7)};d.LR=function(a){l.u.Ca(this,7,a)};x.i.Le.K=function(a){return l.u.K(x.i.Le,a)};x.i.ae=function(a){l.u.initialize(this,a,0,-1,x.i.ae.na,null)};h.da(x.i.ae,l.u);x.i.ae.na=[1];l.u.ha&&(x.i.ae.prototype.C=function(a){return x.i.ae.C(a,this)},x.i.ae.C=function(a,b){var c={Ada:l.u.Ka(b.YA(),x.i.Le.C,a)};a&&(c.ja=b);return c});x.i.ae.ia=function(a){a=new l.ba(a);var b=new x.i.ae;return x.i.ae.F(b,a)};\nx.i.ae.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.Le;b.T(c,x.i.Le.F);a.DJ(c);break;default:b.ea()}}return a};x.i.ae.G=function(a,b){a=a.YA();0<a.length&&b.Oa(1,a,x.i.Le.G)};x.i.ae.prototype.YA=function(){return l.u.Ma(this,x.i.Le,1)};x.i.ae.prototype.DJ=function(a,b){return l.u.La(this,1,a,x.i.Le,b)};x.i.ae.K=function(a){return l.u.K(x.i.ae,a)};x.i.fc=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.fc,l.u);\nl.u.ha&&(x.i.fc.prototype.C=function(a){return x.i.fc.C(a,this)},x.i.fc.C=function(a,b){var c={Xba:l.u.D(b,1),value:+l.u.D(b,2)};a&&(c.ja=b);return c});x.i.fc.ia=function(a){a=new l.ba(a);var b=new x.i.fc;return x.i.fc.F(b,a)};x.i.fc.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.we();a.YU(c);break;case 2:c=b.pa();a.setValue(c);break;default:b.ea()}}return a};x.i.fc.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.xe(1,c);c=l.u.D(a,2);null!=c&&b.ya(2,c)};\nx.i.fc.prototype.YU=function(a){l.u.J(this,1,a)};x.i.fc.prototype.getValue=function(){return+l.u.D(this,2)};x.i.fc.prototype.setValue=function(a){l.u.J(this,2,a)};x.i.fc.K=function(a){return l.u.K(x.i.fc,a)};x.i.fc.b_={gY:0,p_:1,r_:2,s_:3,t_:4,q_:5,u_:6,w_:7};x.i.ze=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.ze,l.u);\nl.u.ha&&(x.i.ze.prototype.C=function(a){return x.i.ze.C(a,this)},x.i.ze.C=function(a,b){var c,e={V$:(c=b.Xz())&&x.i.nb.C(a,c),Y$:(c=b.Zz())&&x.i.nb.C(a,c),T$:(c=b.Vz())&&x.i.nb.C(a,c),X$:(c=b.Yz())&&x.i.nb.C(a,c),aaa:(c=b.$z())&&x.i.nb.C(a,c),a7:l.u.va(b,6,0)};a&&(e.ja=b);return e});x.i.ze.ia=function(a){a=new l.ba(a);var b=new x.i.ze;return x.i.ze.F(b,a)};\nx.i.ze.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.nb;b.T(c,x.i.nb.F);a.cU(c);break;case 2:c=new x.i.nb;b.T(c,x.i.nb.F);a.fU(c);break;case 3:c=new x.i.nb;b.T(c,x.i.nb.F);a.aU(c);break;case 4:c=new x.i.nb;b.T(c,x.i.nb.F);a.eU(c);break;case 5:c=new x.i.nb;b.T(c,x.i.nb.F);a.hU(c);break;case 6:c=b.we();a.MR(c);break;default:b.ea()}}return a};\nx.i.ze.G=function(a,b){var c;c=a.Xz();null!=c&&b.oa(1,c,x.i.nb.G);c=a.Zz();null!=c&&b.oa(2,c,x.i.nb.G);c=a.Vz();null!=c&&b.oa(3,c,x.i.nb.G);c=a.Yz();null!=c&&b.oa(4,c,x.i.nb.G);c=a.$z();null!=c&&b.oa(5,c,x.i.nb.G);c=l.u.D(a,6);null!=c&&b.xe(6,c)};d=x.i.ze.prototype;d.Xz=function(){return l.u.sa(this,x.i.nb,1,1)};d.cU=function(a){l.u.Ca(this,1,a)};d.Zz=function(){return l.u.sa(this,x.i.nb,2,1)};d.fU=function(a){l.u.Ca(this,2,a)};d.Vz=function(){return l.u.sa(this,x.i.nb,3,1)};\nd.aU=function(a){l.u.Ca(this,3,a)};d.Yz=function(){return l.u.sa(this,x.i.nb,4)};d.eU=function(a){l.u.Ca(this,4,a)};d.$z=function(){return l.u.sa(this,x.i.nb,5)};d.hU=function(a){l.u.Ca(this,5,a)};d.MR=function(a){l.u.J(this,6,a)};x.i.ze.K=function(a){return l.u.K(x.i.ze,a)};x.i.ze.eY={$X:0,ZX:1};x.i.Cf=function(a){l.u.initialize(this,a,0,-1,x.i.Cf.na,null)};h.da(x.i.Cf,l.u);x.i.Cf.na=[1,2,3,4,5,6,7,8,9,10,11,12];\nl.u.ha&&(x.i.Cf.prototype.C=function(a){return x.i.Cf.C(a,this)},x.i.Cf.C=function(a,b){var c={v2:l.u.gb(b,1),t2:l.u.gb(b,2),u2:l.u.gb(b,3),q4:l.u.gb(b,4),l4:l.u.gb(b,5),a8:l.u.gb(b,6),q8:l.u.gb(b,7),p8:l.u.gb(b,8),Q5:l.u.gb(b,9),gda:l.u.gb(b,10),Q$:l.u.gb(b,11),E$:l.u.gb(b,12),Mca:+l.u.D(b,13),Ica:+l.u.D(b,14),Hca:+l.u.D(b,16),wl:+l.u.D(b,18),Nca:l.u.Na(b,15),Jca:l.u.Na(b,17),Ow:l.u.Na(b,19)};a&&(c.ja=b);return c});x.i.Cf.ia=function(a){a=new l.ba(a);var b=new x.i.Cf;return x.i.Cf.F(b,a)};\nx.i.Cf.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.pa();a.zH(c);break;case 2:c=b.pa();a.xH(c);break;case 3:c=b.pa();a.yH(c);break;case 4:c=b.pa();a.NH(c);break;case 5:c=b.pa();a.MH(c);break;case 6:c=b.pa();a.vI(c);break;case 7:c=b.pa();a.yI(c);break;case 8:c=b.pa();a.xI(c);break;case 9:c=b.pa();a.kI(c);break;case 10:c=b.pa();a.AJ(c);break;case 11:c=b.pa();a.XI(c);break;case 12:c=b.pa();a.UI(c);break;case 13:c=b.pa();a.nV(c);break;case 14:c=b.pa();a.jV(c);break;case 16:c=\nb.pa();a.iV(c);break;case 18:c=b.pa();a.Kg(c);break;case 15:c=b.pa();a.oV(c);break;case 17:c=b.pa();a.kV(c);break;case 19:c=b.pa();a.um(c);break;default:b.ea()}}return a};\nx.i.Cf.G=function(a,b){var c;c=a.jL();0<c.length&&b.bd(1,c);c=a.hL();0<c.length&&b.bd(2,c);c=a.iL();0<c.length&&b.bd(3,c);c=a.qL();0<c.length&&b.bd(4,c);c=a.pL();0<c.length&&b.bd(5,c);c=a.PL();0<c.length&&b.bd(6,c);c=a.RL();0<c.length&&b.bd(7,c);c=a.QL();0<c.length&&b.bd(8,c);c=a.FL();0<c.length&&b.bd(9,c);c=a.GM();0<c.length&&b.bd(10,c);c=a.iM();0<c.length&&b.bd(11,c);c=a.fM();0<c.length&&b.bd(12,c);c=l.u.D(a,13);null!=c&&b.ya(13,c);c=l.u.D(a,14);null!=c&&b.ya(14,c);c=l.u.D(a,16);null!=c&&b.ya(16,\nc);c=l.u.D(a,18);null!=c&&b.ya(18,c);c=l.u.D(a,15);null!=c&&b.ya(15,c);c=l.u.D(a,17);null!=c&&b.ya(17,c);c=l.u.D(a,19);null!=c&&b.ya(19,c)};d=x.i.Cf.prototype;d.jL=function(){return l.u.gb(this,1)};d.zH=function(a,b){l.u.ib(this,1,a,b)};d.hL=function(){return l.u.gb(this,2)};d.xH=function(a,b){l.u.ib(this,2,a,b)};d.iL=function(){return l.u.gb(this,3)};d.yH=function(a,b){l.u.ib(this,3,a,b)};d.qL=function(){return l.u.gb(this,4)};d.NH=function(a,b){l.u.ib(this,4,a,b)};\nd.pL=function(){return l.u.gb(this,5)};d.MH=function(a,b){l.u.ib(this,5,a,b)};d.PL=function(){return l.u.gb(this,6)};d.vI=function(a,b){l.u.ib(this,6,a,b)};d.RL=function(){return l.u.gb(this,7)};d.yI=function(a,b){l.u.ib(this,7,a,b)};d.QL=function(){return l.u.gb(this,8)};d.xI=function(a,b){l.u.ib(this,8,a,b)};d.FL=function(){return l.u.gb(this,9)};d.kI=function(a,b){l.u.ib(this,9,a,b)};d.GM=function(){return l.u.gb(this,10)};d.AJ=function(a,b){l.u.ib(this,10,a,b)};\nd.iM=function(){return l.u.gb(this,11)};d.XI=function(a,b){l.u.ib(this,11,a,b)};d.fM=function(){return l.u.gb(this,12)};d.UI=function(a,b){l.u.ib(this,12,a,b)};d.nV=function(a){l.u.J(this,13,a)};d.jV=function(a){l.u.J(this,14,a)};d.iV=function(a){l.u.J(this,16,a)};d.Gg=function(){return+l.u.D(this,18)};d.Kg=function(a){l.u.J(this,18,a)};d.oV=function(a){l.u.J(this,15,a)};d.kV=function(a){l.u.J(this,17,a)};d.so=function(){return l.u.Na(this,19)};d.um=function(a){l.u.J(this,19,a)};\nx.i.Cf.K=function(a){return l.u.K(x.i.Cf,a)};x.i.xc=function(a){l.u.initialize(this,a,0,-1,x.i.xc.na,null)};h.da(x.i.xc,l.u);x.i.xc.na=[1,2,3];l.u.ha&&(x.i.xc.prototype.C=function(a){return x.i.xc.C(a,this)},x.i.xc.C=function(a,b){var c,e={Yba:l.u.Ka(b.AA(),x.i.fc.C,a),O$:l.u.Ka(b.Sz(),x.i.fc.C,a),A9:l.u.Ka(b.Fz(),x.i.fc.C,a),U$:(c=b.Wz())&&x.i.nb.C(a,c),a3:(c=b.gy())&&x.i.ze.C(a,c),S9:l.u.va(b,6,0),Z$:b.kM()};a&&(e.ja=b);return e});\nx.i.xc.ia=function(a){a=new l.ba(a);var b=new x.i.xc;return x.i.xc.F(b,a)};x.i.xc.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.fc;b.T(c,x.i.fc.F);a.kJ(c);break;case 2:c=new x.i.fc;b.T(c,x.i.fc.F);a.VI(c);break;case 3:c=new x.i.fc;b.T(c,x.i.fc.F);a.JI(c);break;case 4:c=new x.i.nb;b.T(c,x.i.nb.F);a.bU(c);break;case 5:c=new x.i.ze;b.T(c,x.i.ze.F);a.AQ(c);break;case 6:c=b.Ya();a.vT(c);break;case 7:c=b.qm();a.gU(c);break;default:b.ea()}}return a};\nx.i.xc.G=function(a,b){var c;c=a.AA();0<c.length&&b.Oa(1,c,x.i.fc.G);c=a.Sz();0<c.length&&b.Oa(2,c,x.i.fc.G);c=a.Fz();0<c.length&&b.Oa(3,c,x.i.fc.G);c=a.Wz();null!=c&&b.oa(4,c,x.i.nb.G);c=a.gy();null!=c&&b.oa(5,c,x.i.ze.G);c=l.u.D(a,6);null!=c&&b.$a(6,c);c=l.u.D(a,7);null!=c&&b.fp(7,c)};d=x.i.xc.prototype;d.AA=function(){return l.u.Ma(this,x.i.fc,1)};d.kJ=function(a,b){return l.u.La(this,1,a,x.i.fc,b)};d.Sz=function(){return l.u.Ma(this,x.i.fc,2)};\nd.VI=function(a,b){return l.u.La(this,2,a,x.i.fc,b)};d.Fz=function(){return l.u.Ma(this,x.i.fc,3)};d.JI=function(a,b){return l.u.La(this,3,a,x.i.fc,b)};d.Wz=function(){return l.u.sa(this,x.i.nb,4)};d.bU=function(a){l.u.Ca(this,4,a)};d.gy=function(){return l.u.sa(this,x.i.ze,5)};d.AQ=function(a){l.u.Ca(this,5,a)};d.vT=function(a){l.u.J(this,6,a)};d.jM=function(){return l.u.D(this,7)};d.kM=function(){return l.u.ao(this.jM())};d.gU=function(a){l.u.J(this,7,a)};\nx.i.xc.K=function(a){return l.u.K(x.i.xc,a)};x.i.xc.KX={MY:0,iZ:1,SY:2};x.i.Md=function(a){l.u.initialize(this,a,0,-1,x.i.Md.na,null)};h.da(x.i.Md,l.u);x.i.Md.na=[22];\nl.u.ha&&(x.i.Md.prototype.C=function(a){return x.i.Md.C(a,this)},x.i.Md.C=function(a,b){var c={aj:l.u.D(b,1),dba:+l.u.va(b,2,0),Q9:l.u.va(b,3,0),cba:+l.u.va(b,4,0),vda:l.u.D(b,5),HO:l.u.va(b,6,0),x8:+l.u.va(b,7,0),IO:l.u.va(b,8,0),C8:l.u.D(b,9),kca:l.u.Na(b,10),qca:l.u.Na(b,11),N9:l.u.Na(b,12),w3:l.u.D(b,13),L1:l.u.D(b,14),M1:l.u.D(b,15),N1:l.u.D(b,16),g7:+l.u.va(b,17,0),L$:l.u.Na(b,18),x9:l.u.Na(b,19),M$:l.u.Na(b,20),y9:l.u.Na(b,21),e3:l.u.gb(b,22)};a&&(c.ja=b);return c});\nx.i.Md.ia=function(a){a=new l.ba(a);var b=new x.i.Md;return x.i.Md.F(b,a)};\nx.i.Md.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.xf(c);break;case 2:c=b.pa();a.AU(c);break;case 3:c=b.ad();a.tT(c);break;case 4:c=b.pa();a.zU(c);break;case 5:c=b.Ya();a.JV(c);break;case 6:c=b.ad();a.et(c);break;case 7:c=b.ti();a.yS(c);break;case 8:c=b.ee();a.ft(c);break;case 9:c=b.Ya();a.DS(c);break;case 10:c=b.pa();a.bV(c);break;case 11:c=b.pa();a.cV(c);break;case 12:c=b.pa();a.qT(c);break;case 13:c=b.ee();a.GQ(c);break;case 14:c=b.ee();a.bQ(c);break;case 15:c=\nb.ee();a.cQ(c);break;case 16:c=b.ee();a.dQ(c);break;case 17:c=b.pa();a.RR(c);break;case 18:c=b.pa();a.XT(c);break;case 19:c=b.pa();a.hT(c);break;case 20:c=b.pa();a.YT(c);break;case 21:c=b.pa();a.iT(c);break;case 22:c=b.pa();a.FH(c);break;default:b.ea()}}return a};\nx.i.Md.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Ja(1,c);c=l.u.D(a,2);null!=c&&b.ya(2,c);c=l.u.D(a,3);null!=c&&b.td(3,c);c=l.u.D(a,4);null!=c&&b.ya(4,c);c=l.u.D(a,5);null!=c&&b.$a(5,c);c=l.u.D(a,6);null!=c&&b.td(6,c);c=l.u.D(a,7);null!=c&&b.vi(7,c);c=l.u.D(a,8);null!=c&&b.ye(8,c);c=l.u.D(a,9);null!=c&&b.$a(9,c);c=l.u.D(a,10);null!=c&&b.ya(10,c);c=l.u.D(a,11);null!=c&&b.ya(11,c);c=l.u.D(a,12);null!=c&&b.ya(12,c);c=l.u.D(a,13);null!=c&&b.ye(13,c);c=l.u.D(a,14);null!=c&&b.ye(14,c);c=l.u.D(a,15);\nnull!=c&&b.ye(15,c);c=l.u.D(a,16);null!=c&&b.ye(16,c);c=l.u.D(a,17);null!=c&&b.ya(17,c);c=l.u.D(a,18);null!=c&&b.ya(18,c);c=l.u.D(a,19);null!=c&&b.ya(19,c);c=l.u.D(a,20);null!=c&&b.ya(20,c);c=l.u.D(a,21);null!=c&&b.ya(21,c);c=a.mL();0<c.length&&b.bd(22,c)};d=x.i.Md.prototype;d.Hg=function(){return l.u.D(this,1)};d.xf=function(a){l.u.J(this,1,a)};d.AU=function(a){l.u.J(this,2,a)};d.tT=function(a){l.u.J(this,3,a)};d.zU=function(a){l.u.J(this,4,a)};d.JV=function(a){l.u.J(this,5,a)};\nd.et=function(a){l.u.J(this,6,a)};d.yS=function(a){l.u.J(this,7,a)};d.ft=function(a){l.u.J(this,8,a)};d.DS=function(a){l.u.J(this,9,a)};d.bV=function(a){l.u.J(this,10,a)};d.cV=function(a){l.u.J(this,11,a)};d.qT=function(a){l.u.J(this,12,a)};d.GQ=function(a){l.u.J(this,13,a)};d.bQ=function(a){l.u.J(this,14,a)};d.cQ=function(a){l.u.J(this,15,a)};d.dQ=function(a){l.u.J(this,16,a)};d.RR=function(a){l.u.J(this,17,a)};d.XT=function(a){l.u.J(this,18,a)};d.hT=function(a){l.u.J(this,19,a)};\nd.YT=function(a){l.u.J(this,20,a)};d.iT=function(a){l.u.J(this,21,a)};d.mL=function(){return l.u.gb(this,22)};d.FH=function(a,b){l.u.ib(this,22,a,b)};x.i.Md.K=function(a){return l.u.K(x.i.Md,a)};x.i.$d=function(a){l.u.initialize(this,a,0,-1,x.i.$d.na,null)};h.da(x.i.$d,l.u);x.i.$d.na=[1,2,6];\nl.u.ha&&(x.i.$d.prototype.C=function(a){return x.i.$d.C(a,this)},x.i.$d.C=function(a,b){var c,e={Vca:l.u.Ka(b.OA(),x.i.xc.C,a),c7:l.u.Ka(b.bz(),x.i.xc.C,a),xda:l.u.Na(b,3),E3:l.u.Ka(b.my(),x.i.Md.C,a),Bj:l.u.D(b,4),zda:(c=b.XA())&&x.i.ae.C(a,c)};a&&(e.ja=b);return e});x.i.$d.ia=function(a){a=new l.ba(a);var b=new x.i.$d;return x.i.$d.F(b,a)};\nx.i.$d.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.xc;b.T(c,x.i.xc.F);a.zJ(c);break;case 2:c=new x.i.xc;b.T(c,x.i.xc.F);a.pI(c);break;case 3:c=b.pa();a.LV(c);break;case 6:c=new x.i.Md;b.T(c,x.i.Md.F);a.JH(c);break;case 4:c=b.Ya();a.zf(c);break;case 5:c=new x.i.ae;b.T(c,x.i.ae.F);a.MV(c);break;default:b.ea()}}return a};\nx.i.$d.G=function(a,b){var c;c=a.OA();0<c.length&&b.Oa(1,c,x.i.xc.G);c=a.bz();0<c.length&&b.Oa(2,c,x.i.xc.G);c=l.u.D(a,3);null!=c&&b.ya(3,c);c=a.my();0<c.length&&b.Oa(6,c,x.i.Md.G);c=l.u.D(a,4);null!=c&&b.$a(4,c);c=a.XA();null!=c&&b.oa(5,c,x.i.ae.G)};d=x.i.$d.prototype;d.OA=function(){return l.u.Ma(this,x.i.xc,1)};d.zJ=function(a,b){return l.u.La(this,1,a,x.i.xc,b)};d.bz=function(){return l.u.Ma(this,x.i.xc,2)};d.pI=function(a,b){return l.u.La(this,2,a,x.i.xc,b)};d.LV=function(a){l.u.J(this,3,a)};\nd.my=function(){return l.u.Ma(this,x.i.Md,6)};d.JH=function(a,b){return l.u.La(this,6,a,x.i.Md,b)};d.zf=function(a){l.u.J(this,4,a)};d.XA=function(){return l.u.sa(this,x.i.ae,5)};d.MV=function(a){l.u.Ca(this,5,a)};x.i.$d.K=function(a){return l.u.K(x.i.$d,a)};x.i.$d.lD={g_:0,bY:1,WY:2};x.i.Ef=function(a){l.u.initialize(this,a,0,-1,x.i.Ef.na,null)};h.da(x.i.Ef,l.u);x.i.Ef.na=[3];\nl.u.ha&&(x.i.Ef.prototype.C=function(a){return x.i.Ef.C(a,this)},x.i.Ef.C=function(a,b){var c,e={tW:(c=b.dm())&&x.i.$d.C(a,c),e9:l.u.D(b,2),L4:l.u.D(b,3)};a&&(e.ja=b);return e});x.i.Ef.ia=function(a){a=new l.ba(a);var b=new x.i.Ef;return x.i.Ef.F(b,a)};x.i.Ef.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.$d;b.T(c,x.i.$d.F);a.ot(c);break;case 2:c=b.Aa();a.US(c);break;case 3:c=b.Aa();a.SH(c);break;default:b.ea()}}return a};\nx.i.Ef.G=function(a,b){var c;c=a.dm();null!=c&&b.oa(1,c,x.i.$d.G);c=l.u.D(a,2);null!=c&&b.Ja(2,c);c=a.sL();0<c.length&&b.oc(3,c)};d=x.i.Ef.prototype;d.dm=function(){return l.u.sa(this,x.i.$d,1,1)};d.ot=function(a){l.u.Ca(this,1,a)};d.US=function(a){l.u.J(this,2,a)};d.sL=function(){return l.u.D(this,3)};d.SH=function(a,b){l.u.ib(this,3,a,b)};x.i.Ef.K=function(a){return l.u.K(x.i.Ef,a)};x.i.Bf=function(a){l.u.initialize(this,a,0,-1,x.i.Bf.na,null)};h.da(x.i.Bf,l.u);x.i.Bf.na=[1,2,3,4];\nl.u.ha&&(x.i.Bf.prototype.C=function(a){return x.i.Bf.C(a,this)},x.i.Bf.C=function(a,b){var c={b$:l.u.Ka(b.Jz(),x.i.Ie.C,a),g$:l.u.Ka(b.Kz(),x.i.Ub.C,a),A5:l.u.Ka(b.Ny(),x.i.Ub.C,a),iW:l.u.Ka(b.cm(),x.i.rd.C,a)};a&&(c.ja=b);return c});x.i.Bf.ia=function(a){a=new l.ba(a);var b=new x.i.Bf;return x.i.Bf.F(b,a)};\nx.i.Bf.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.Ie;b.T(c,x.i.Ie.F);a.NI(c);break;case 2:c=new x.i.Ub;b.T(c,x.i.Ub.F);a.OI(c);break;case 3:c=new x.i.Ub;b.T(c,x.i.Ub.F);a.aI(c);break;case 4:c=new x.i.rd;b.T(c,x.i.rd.F);a.Tq(c);break;default:b.ea()}}return a};x.i.Bf.G=function(a,b){var c;c=a.Jz();0<c.length&&b.Oa(1,c,x.i.Ie.G);c=a.Kz();0<c.length&&b.Oa(2,c,x.i.Ub.G);c=a.Ny();0<c.length&&b.Oa(3,c,x.i.Ub.G);c=a.cm();0<c.length&&b.Oa(4,c,x.i.rd.G)};d=x.i.Bf.prototype;\nd.Jz=function(){return l.u.Ma(this,x.i.Ie,1)};d.NI=function(a,b){return l.u.La(this,1,a,x.i.Ie,b)};d.Kz=function(){return l.u.Ma(this,x.i.Ub,2)};d.OI=function(a,b){return l.u.La(this,2,a,x.i.Ub,b)};d.Ny=function(){return l.u.Ma(this,x.i.Ub,3)};d.aI=function(a,b){return l.u.La(this,3,a,x.i.Ub,b)};d.cm=function(){return l.u.Ma(this,x.i.rd,4)};d.Tq=function(a,b){return l.u.La(this,4,a,x.i.rd,b)};x.i.Bf.K=function(a){return l.u.K(x.i.Bf,a)};x.i.Ie=function(a){l.u.initialize(this,a,0,-1,null,null)};\nh.da(x.i.Ie,l.u);l.u.ha&&(x.i.Ie.prototype.C=function(a){return x.i.Ie.C(a,this)},x.i.Ie.C=function(a,b){var c={Bj:l.u.D(b,1),date:l.u.D(b,2),value:l.u.Na(b,3)};a&&(c.ja=b);return c});x.i.Ie.ia=function(a){a=new l.ba(a);var b=new x.i.Ie;return x.i.Ie.F(b,a)};x.i.Ie.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Ya();a.zf(c);break;case 2:c=b.Ya();a.setDate(c);break;case 3:c=b.pa();a.setValue(c);break;default:b.ea()}}return a};\nx.i.Ie.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.$a(1,c);c=l.u.D(a,2);null!=c&&b.$a(2,c);c=l.u.D(a,3);null!=c&&b.ya(3,c)};d=x.i.Ie.prototype;d.zf=function(a){l.u.J(this,1,a)};d.getDate=function(){return l.u.D(this,2)};d.setDate=function(a){l.u.J(this,2,a)};d.getValue=function(){return l.u.Na(this,3)};d.setValue=function(a){l.u.J(this,3,a)};x.i.Ie.K=function(a){return l.u.K(x.i.Ie,a)};x.i.rd=function(a){l.u.initialize(this,a,0,-1,x.i.rd.na,null)};h.da(x.i.rd,l.u);x.i.rd.na=[2];\nl.u.ha&&(x.i.rd.prototype.C=function(a){return x.i.rd.C(a,this)},x.i.rd.C=function(a,b){var c={gW:l.u.D(b,1),Jm:l.u.Ka(b.bf(),x.i.Ub.C,a)};a&&(c.ja=b);return c});x.i.rd.ia=function(a){a=new l.ba(a);var b=new x.i.rd;return x.i.rd.F(b,a)};x.i.rd.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.we();a.nt(c);break;case 2:c=new x.i.Ub;b.T(c,x.i.Ub.F);a.Eg(c);break;default:b.ea()}}return a};\nx.i.rd.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.xe(1,c);c=a.bf();0<c.length&&b.Oa(2,c,x.i.Ub.G)};x.i.rd.prototype.nt=function(a){l.u.J(this,1,a)};x.i.rd.prototype.bf=function(){return l.u.Ma(this,x.i.Ub,2)};x.i.rd.prototype.Eg=function(a,b){return l.u.La(this,2,a,x.i.Ub,b)};x.i.rd.K=function(a){return l.u.K(x.i.rd,a)};x.i.Ub=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.Ub,l.u);\nl.u.ha&&(x.i.Ub.prototype.C=function(a){return x.i.Ub.C(a,this)},x.i.Ub.C=function(a,b){var c,e={Bj:l.u.D(b,1),time:l.u.Na(b,5),tW:(c=b.dm())&&x.i.od.C(a,c),i7:(c=b.ez())&&x.i.od.C(a,c),H4:l.u.D(b,6)};a&&(e.ja=b);return e});x.i.Ub.ia=function(a){a=new l.ba(a);var b=new x.i.Ub;return x.i.Ub.F(b,a)};\nx.i.Ub.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Ya();a.zf(c);break;case 5:c=b.pa();a.setTime(c);break;case 3:c=new x.i.od;b.T(c,x.i.od.F);a.ot(c);break;case 4:c=new x.i.od;b.T(c,x.i.od.F);a.TR(c);break;case 6:c=b.Ya();a.$Q(c);break;default:b.ea()}}return a};x.i.Ub.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.$a(1,c);c=l.u.D(a,5);null!=c&&b.ya(5,c);c=a.dm();null!=c&&b.oa(3,c,x.i.od.G);c=a.ez();null!=c&&b.oa(4,c,x.i.od.G);c=l.u.D(a,6);null!=c&&b.$a(6,c)};d=x.i.Ub.prototype;\nd.zf=function(a){l.u.J(this,1,a)};d.getTime=function(){return l.u.Na(this,5)};d.setTime=function(a){l.u.J(this,5,a)};d.dm=function(){return l.u.sa(this,x.i.od,3)};d.ot=function(a){l.u.Ca(this,3,a)};d.ez=function(){return l.u.sa(this,x.i.od,4)};d.TR=function(a){l.u.Ca(this,4,a)};d.$Q=function(a){l.u.J(this,6,a)};x.i.Ub.K=function(a){return l.u.K(x.i.Ub,a)};x.i.od=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.od,l.u);\nl.u.ha&&(x.i.od.prototype.C=function(a){return x.i.od.C(a,this)},x.i.od.C=function(a,b){var c={wl:l.u.Na(b,2),i2:l.u.Na(b,8),Ow:l.u.Na(b,3),instanceCount:l.u.Na(b,5),lm:l.u.Na(b,1),r9:l.u.Na(b,6),F$:l.u.Na(b,7),eP:l.u.Na(b,4)};a&&(c.ja=b);return c});x.i.od.ia=function(a){a=new l.ba(a);var b=new x.i.od;return x.i.od.F(b,a)};\nx.i.od.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 2:c=b.pa();a.Kg(c);break;case 8:c=b.pa();a.gQ(c);break;case 3:c=b.pa();a.um(c);break;case 5:c=b.pa();a.cS(c);break;case 1:c=b.pa();a.Ng(c);break;case 6:c=b.pa();a.bT(c);break;case 7:c=b.pa();a.RT(c);break;case 4:c=b.pa();a.ht(c);break;default:b.ea()}}return a};\nx.i.od.G=function(a,b){var c;c=l.u.D(a,2);null!=c&&b.ya(2,c);c=l.u.D(a,8);null!=c&&b.ya(8,c);c=l.u.D(a,3);null!=c&&b.ya(3,c);c=l.u.D(a,5);null!=c&&b.ya(5,c);c=l.u.D(a,1);null!=c&&b.ya(1,c);c=l.u.D(a,6);null!=c&&b.ya(6,c);c=l.u.D(a,7);null!=c&&b.ya(7,c);c=l.u.D(a,4);null!=c&&b.ya(4,c)};d=x.i.od.prototype;d.Gg=function(){return l.u.Na(this,2)};d.Kg=function(a){l.u.J(this,2,a)};d.gQ=function(a){l.u.J(this,8,a)};d.so=function(){return l.u.Na(this,3)};d.um=function(a){l.u.J(this,3,a)};\nd.cS=function(a){l.u.J(this,5,a)};d.eg=function(){return l.u.Na(this,1)};d.Ng=function(a){l.u.J(this,1,a)};d.bT=function(a){l.u.J(this,6,a)};d.RT=function(a){l.u.J(this,7,a)};d.Nr=function(){return l.u.Na(this,4)};d.ht=function(a){l.u.J(this,4,a)};x.i.od.K=function(a){return l.u.K(x.i.od,a)};x.i.ZZ={ZY:1,BX:2};x.P={};x.P.Rd=function(a){l.u.initialize(this,a,0,-1,x.P.Rd.na,null)};h.da(x.P.Rd,l.u);x.P.Rd.na=[3,4,5];\nl.u.ha&&(x.P.Rd.prototype.C=function(a){return x.P.Rd.C(a,this)},x.P.Rd.C=function(a,b){var c,e={name:l.u.D(b,1),a4:l.u.D(b,2),Eaa:l.u.D(b,3),E5:l.u.D(b,4),J5:l.u.Ka(b.Ry(),x.P.Ge.C,a),y8:l.u.D(b,6),A8:l.u.D(b,7),z8:l.u.D(b,8),B8:l.u.D(b,9),m6:(c=b.Zy())&&x.P.he.C(a,c),N6:l.u.D(b,11),x5:l.u.D(b,12),T9:l.u.D(b,13),z5:l.u.D(b,14),Q8:l.u.D(b,15)};a&&(e.ja=b);return e});x.P.Rd.ia=function(a){a=new l.ba(a);var b=new x.P.Rd;return x.P.Rd.F(b,a)};\nx.P.Rd.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.fe(c);break;case 2:c=b.Aa();a.NQ(c);break;case 3:c=b.Aa();a.aJ(c);break;case 4:c=b.Aa();a.dI(c);break;case 5:c=new x.P.Ge;b.T(c,x.P.Ge.F);a.gI(c);break;case 6:c=b.Ya();a.zS(c);break;case 7:c=b.Ya();a.BS(c);break;case 8:c=b.Ya();a.AS(c);break;case 9:c=b.Ya();a.CS(c);break;case 10:c=new x.P.he;b.T(c,x.P.he.F);a.IR(c);break;case 11:c=b.Aa();a.JR(c);break;case 12:c=b.Aa();a.sR(c);break;case 13:c=b.Ya();a.wT(c);break;\ncase 14:c=b.we();a.uR(c);break;case 15:c=b.Ya();a.LS(c);break;default:b.ea()}}return a};\nx.P.Rd.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Ja(1,c);c=l.u.D(a,2);null!=c&&b.Ja(2,c);c=a.oM();0<c.length&&b.oc(3,c);c=a.AL();0<c.length&&b.oc(4,c);c=a.Ry();0<c.length&&b.Oa(5,c,x.P.Ge.G);c=l.u.D(a,6);null!=c&&b.$a(6,c);c=l.u.D(a,7);null!=c&&b.$a(7,c);c=l.u.D(a,8);null!=c&&b.$a(8,c);c=l.u.D(a,9);null!=c&&b.$a(9,c);c=a.Zy();null!=c&&b.oa(10,c,x.P.he.G);c=l.u.D(a,11);null!=c&&b.Ja(11,c);c=l.u.D(a,12);null!=c&&b.Ja(12,c);c=l.u.D(a,13);null!=c&&b.$a(13,c);c=l.u.D(a,14);null!=c&&b.xe(14,c);c=l.u.D(a,\n15);null!=c&&b.$a(15,c)};d=x.P.Rd.prototype;d.getName=function(){return l.u.D(this,1)};d.fe=function(a){l.u.J(this,1,a)};d.NQ=function(a){l.u.J(this,2,a)};d.oM=function(){return l.u.D(this,3)};d.aJ=function(a,b){l.u.ib(this,3,a,b)};d.AL=function(){return l.u.D(this,4)};d.dI=function(a,b){l.u.ib(this,4,a,b)};d.Ry=function(){return l.u.Ma(this,x.P.Ge,5)};d.gI=function(a,b){return l.u.La(this,5,a,x.P.Ge,b)};d.zS=function(a){l.u.J(this,6,a)};d.BS=function(a){l.u.J(this,7,a)};\nd.AS=function(a){l.u.J(this,8,a)};d.CS=function(a){l.u.J(this,9,a)};d.Zy=function(){return l.u.sa(this,x.P.he,10)};d.IR=function(a){l.u.Ca(this,10,a)};d.JR=function(a){l.u.J(this,11,a)};d.sR=function(a){l.u.J(this,12,a)};d.wT=function(a){l.u.J(this,13,a)};d.uR=function(a){l.u.J(this,14,a)};d.LS=function(a){l.u.J(this,15,a)};x.P.Rd.K=function(a){return l.u.K(x.P.Rd,a)};x.P.he=function(a){l.u.initialize(this,a,0,-1,x.P.he.na,null)};h.da(x.P.he,l.u);x.P.he.na=[1,2,3,4,5,6];\nl.u.ha&&(x.P.he.prototype.C=function(a){return x.P.he.C(a,this)},x.P.he.C=function(a,b){var c={K5:l.u.Ka(b.Sy(),x.P.Ac.C,a),eba:l.u.Ka(b.kA(),x.P.Ac.C,a),g8:l.u.Ka(b.oz(),x.P.Fb.C,a),Z8:l.u.Ka(b.wz(),x.P.Td.C,a),h$:l.u.Ka(b.Lz(),x.P.Bc.C,a),Wba:l.u.Ka(b.zA(),x.P.pd.C,a)};a&&(c.ja=b);return c});x.P.he.ia=function(a){a=new l.ba(a);var b=new x.P.he;return x.P.he.F(b,a)};\nx.P.he.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.P.Ac;b.T(c,x.P.Ac.F);a.hI(c);break;case 2:c=new x.P.Ac;b.T(c,x.P.Ac.F);a.dJ(c);break;case 3:c=new x.P.Fb;b.T(c,x.P.Fb.F);a.wI(c);break;case 4:c=new x.P.Td;b.T(c,x.P.Td.F);a.EI(c);break;case 5:c=new x.P.Bc;b.T(c,x.P.Bc.F);a.QI(c);break;case 6:c=new x.P.pd;b.T(c,x.P.pd.F);a.jJ(c);break;default:b.ea()}}return a};\nx.P.he.G=function(a,b){var c;c=a.Sy();0<c.length&&b.Oa(1,c,x.P.Ac.G);c=a.kA();0<c.length&&b.Oa(2,c,x.P.Ac.G);c=a.oz();0<c.length&&b.Oa(3,c,x.P.Fb.G);c=a.wz();0<c.length&&b.Oa(4,c,x.P.Td.G);c=a.Lz();0<c.length&&b.Oa(5,c,x.P.Bc.G);c=a.zA();0<c.length&&b.Oa(6,c,x.P.pd.G)};d=x.P.he.prototype;d.Sy=function(){return l.u.Ma(this,x.P.Ac,1)};d.hI=function(a,b){return l.u.La(this,1,a,x.P.Ac,b)};d.kA=function(){return l.u.Ma(this,x.P.Ac,2)};d.dJ=function(a,b){return l.u.La(this,2,a,x.P.Ac,b)};\nd.oz=function(){return l.u.Ma(this,x.P.Fb,3)};d.wI=function(a,b){return l.u.La(this,3,a,x.P.Fb,b)};d.wz=function(){return l.u.Ma(this,x.P.Td,4)};d.EI=function(a,b){return l.u.La(this,4,a,x.P.Td,b)};d.Lz=function(){return l.u.Ma(this,x.P.Bc,5)};d.QI=function(a,b){return l.u.La(this,5,a,x.P.Bc,b)};d.zA=function(){return l.u.Ma(this,x.P.pd,6)};d.jJ=function(a,b){return l.u.La(this,6,a,x.P.pd,b)};x.P.he.K=function(a){return l.u.K(x.P.he,a)};x.P.Ac=function(a){l.u.initialize(this,a,0,-1,x.P.Ac.na,null)};\nh.da(x.P.Ac,l.u);x.P.Ac.na=[5];l.u.ha&&(x.P.Ac.prototype.C=function(a){return x.P.Ac.C(a,this)},x.P.Ac.C=function(a,b){var c,e={mK:(c=b.Ml())&&x.P.Sc.C(a,c),Zca:l.u.D(b,2),Yca:l.u.D(b,3),R8:l.u.D(b,4),bba:l.u.D(b,5)};a&&(e.ja=b);return e});x.P.Ac.ia=function(a){a=new l.ba(a);var b=new x.P.Ac;return x.P.Ac.F(b,a)};\nx.P.Ac.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.P.Sc;b.T(c,x.P.Sc.F);a.Ns(c);break;case 2:c=b.Ya();a.yV(c);break;case 3:c=b.Ya();a.xV(c);break;case 4:c=b.Ya();a.MS(c);break;case 5:c=b.Aa();a.cJ(c);break;default:b.ea()}}return a};x.P.Ac.G=function(a,b){var c;c=a.Ml();null!=c&&b.oa(1,c,x.P.Sc.G);c=l.u.D(a,2);null!=c&&b.$a(2,c);c=l.u.D(a,3);null!=c&&b.$a(3,c);c=l.u.D(a,4);null!=c&&b.$a(4,c);c=a.pM();0<c.length&&b.oc(5,c)};d=x.P.Ac.prototype;\nd.Ml=function(){return l.u.sa(this,x.P.Sc,1)};d.Ns=function(a){l.u.Ca(this,1,a)};d.yV=function(a){l.u.J(this,2,a)};d.xV=function(a){l.u.J(this,3,a)};d.MS=function(a){l.u.J(this,4,a)};d.pM=function(){return l.u.D(this,5)};d.cJ=function(a,b){l.u.ib(this,5,a,b)};x.P.Ac.K=function(a){return l.u.K(x.P.Ac,a)};x.P.Fb=function(a){l.u.initialize(this,a,0,-1,x.P.Fb.na,null)};h.da(x.P.Fb,l.u);x.P.Fb.na=[3];\nl.u.ha&&(x.P.Fb.prototype.C=function(a){return x.P.Fb.C(a,this)},x.P.Fb.C=function(a,b){var c,e={mK:(c=b.Ml())&&x.P.Sc.C(a,c),f4:l.u.D(b,2),G5:l.u.D(b,3),Uba:(c=b.getStats())&&x.P.Ud.C(a,c),d6:l.u.D(b,5),N4:l.u.D(b,6),x$:l.u.Na(b,7),f9:l.u.Na(b,8),Jaa:(c=b.iA())&&x.P.Fb.re.C(a,c)};a&&(e.ja=b);return e});x.P.Fb.ia=function(a){a=new l.ba(a);var b=new x.P.Fb;return x.P.Fb.F(b,a)};\nx.P.Fb.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.P.Sc;b.T(c,x.P.Sc.F);a.Ns(c);break;case 2:c=b.Aa();a.PQ(c);break;case 3:c=b.Aa();a.eI(c);break;case 4:c=new x.P.Ud;b.T(c,x.P.Ud.F);a.WU(c);break;case 5:c=b.Ya();a.ER(c);break;case 6:c=b.Aa();a.bR(c);break;case 7:c=b.pa();a.MT(c);break;case 8:c=b.pa();a.VS(c);break;case 9:c=new x.P.Fb.re;b.T(c,x.P.Fb.re.F);a.wU(c);break;default:b.ea()}}return a};\nx.P.Fb.G=function(a,b){var c;c=a.Ml();null!=c&&b.oa(1,c,x.P.Sc.G);c=l.u.D(a,2);null!=c&&b.Ja(2,c);c=a.BL();0<c.length&&b.oc(3,c);c=a.getStats();null!=c&&b.oa(4,c,x.P.Ud.G);c=l.u.D(a,5);null!=c&&b.$a(5,c);c=l.u.D(a,6);null!=c&&b.Ja(6,c);c=l.u.D(a,7);null!=c&&b.ya(7,c);c=l.u.D(a,8);null!=c&&b.ya(8,c);c=a.iA();null!=c&&b.oa(9,c,x.P.Fb.re.G)};d=x.P.Fb.prototype;d.Ml=function(){return l.u.sa(this,x.P.Sc,1)};d.Ns=function(a){l.u.Ca(this,1,a)};d.PQ=function(a){l.u.J(this,2,a)};\nd.BL=function(){return l.u.D(this,3)};d.eI=function(a,b){l.u.ib(this,3,a,b)};d.getStats=function(){return l.u.sa(this,x.P.Ud,4)};d.WU=function(a){l.u.Ca(this,4,a)};d.ER=function(a){l.u.J(this,5,a)};d.bR=function(a){l.u.J(this,6,a)};d.MT=function(a){l.u.J(this,7,a)};d.VS=function(a){l.u.J(this,8,a)};d.iA=function(){return l.u.sa(this,x.P.Fb.re,9)};d.wU=function(a){l.u.Ca(this,9,a)};x.P.Fb.K=function(a){return l.u.K(x.P.Fb,a)};x.P.Fb.re=function(a){l.u.initialize(this,a,0,-1,null,null)};\nh.da(x.P.Fb.re,l.u);l.u.ha&&(x.P.Fb.re.prototype.C=function(a){return x.P.Fb.re.C(a,this)},x.P.Fb.re.C=function(a,b){var c={V9:l.u.D(b,1),U9:l.u.D(b,2),faa:l.u.D(b,3)};a&&(c.ja=b);return c});x.P.Fb.re.ia=function(a){a=new l.ba(a);var b=new x.P.Fb.re;return x.P.Fb.re.F(b,a)};x.P.Fb.re.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Ya();a.yT(c);break;case 2:c=b.Ya();a.xT(c);break;case 3:c=b.Ya();a.mU(c);break;default:b.ea()}}return a};\nx.P.Fb.re.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.$a(1,c);c=l.u.D(a,2);null!=c&&b.$a(2,c);c=l.u.D(a,3);null!=c&&b.$a(3,c)};x.P.Fb.re.prototype.yT=function(a){l.u.J(this,1,a)};x.P.Fb.re.prototype.xT=function(a){l.u.J(this,2,a)};x.P.Fb.re.prototype.mU=function(a){l.u.J(this,3,a)};x.P.Fb.re.K=function(a){return l.u.K(x.P.Fb.re,a)};x.P.Sc=function(a){l.u.initialize(this,a,0,-1,x.P.Sc.na,null)};h.da(x.P.Sc,l.u);x.P.Sc.na=[7,8];\nl.u.ha&&(x.P.Sc.prototype.C=function(a){return x.P.Sc.C(a,this)},x.P.Sc.C=function(a,b){var c={name:l.u.D(b,1),Y8:l.u.D(b,2),id:l.u.D(b,3),status:l.u.D(b,4),r$:l.u.D(b,5),s$:l.u.D(b,6),r7:l.u.D(b,7),a9:l.u.Ka(b.xz(),x.P.Fe.C,a),h9:l.u.D(b,9),O4:l.u.D(b,10),P4:l.u.D(b,11)};a&&(c.ja=b);return c});x.P.Sc.ia=function(a){a=new l.ba(a);var b=new x.P.Sc;return x.P.Sc.F(b,a)};\nx.P.Sc.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.fe(c);break;case 2:c=b.Aa();a.RS(c);break;case 3:c=b.Ya();a.Vs(c);break;case 4:c=b.we();a.ZU(c);break;case 5:c=b.Aa();a.JT(c);break;case 6:c=b.we();a.KT(c);break;case 7:c=b.Aa();a.rI(c);break;case 8:c=new x.P.Fe;b.T(c,x.P.Fe.F);a.FI(c);break;case 9:c=b.Aa();a.WS(c);break;case 10:c=b.Aa();a.cR(c);break;case 11:c=b.Aa();a.dR(c);break;default:b.ea()}}return a};\nx.P.Sc.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Ja(1,c);c=l.u.D(a,2);null!=c&&b.Ja(2,c);c=l.u.D(a,3);null!=c&&b.$a(3,c);c=l.u.D(a,4);null!=c&&b.xe(4,c);c=l.u.D(a,5);null!=c&&b.Ja(5,c);c=l.u.D(a,6);null!=c&&b.xe(6,c);c=a.NL();0<c.length&&b.oc(7,c);c=a.xz();0<c.length&&b.Oa(8,c,x.P.Fe.G);c=l.u.D(a,9);null!=c&&b.Ja(9,c);c=l.u.D(a,10);null!=c&&b.Ja(10,c);c=l.u.D(a,11);null!=c&&b.Ja(11,c)};d=x.P.Sc.prototype;d.getName=function(){return l.u.D(this,1)};d.fe=function(a){l.u.J(this,1,a)};\nd.RS=function(a){l.u.J(this,2,a)};d.Vs=function(a){l.u.J(this,3,a)};d.ZU=function(a){l.u.J(this,4,a)};d.JT=function(a){l.u.J(this,5,a)};d.KT=function(a){l.u.J(this,6,a)};d.NL=function(){return l.u.D(this,7)};d.rI=function(a,b){l.u.ib(this,7,a,b)};d.xz=function(){return l.u.Ma(this,x.P.Fe,8)};d.FI=function(a,b){return l.u.La(this,8,a,x.P.Fe,b)};d.WS=function(a){l.u.J(this,9,a)};d.cR=function(a){l.u.J(this,10,a)};d.dR=function(a){l.u.J(this,11,a)};x.P.Sc.K=function(a){return l.u.K(x.P.Sc,a)};\nx.P.Ud=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.P.Ud,l.u);l.u.ha&&(x.P.Ud.prototype.C=function(a){return x.P.Ud.C(a,this)},x.P.Ud.C=function(a,b){var c={e$:l.u.Na(b,1),c$:l.u.Na(b,2),f$:l.u.Na(b,3),d$:l.u.Na(b,4)};a&&(c.ja=b);return c});x.P.Ud.ia=function(a){a=new l.ba(a);var b=new x.P.Ud;return x.P.Ud.F(b,a)};\nx.P.Ud.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.pa();a.CT(c);break;case 2:c=b.pa();a.AT(c);break;case 3:c=b.pa();a.DT(c);break;case 4:c=b.pa();a.BT(c);break;default:b.ea()}}return a};x.P.Ud.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.ya(1,c);c=l.u.D(a,2);null!=c&&b.ya(2,c);c=l.u.D(a,3);null!=c&&b.ya(3,c);c=l.u.D(a,4);null!=c&&b.ya(4,c)};x.P.Ud.prototype.CT=function(a){l.u.J(this,1,a)};x.P.Ud.prototype.AT=function(a){l.u.J(this,2,a)};\nx.P.Ud.prototype.DT=function(a){l.u.J(this,3,a)};x.P.Ud.prototype.BT=function(a){l.u.J(this,4,a)};x.P.Ud.K=function(a){return l.u.K(x.P.Ud,a)};x.P.Fe=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.P.Fe,l.u);l.u.ha&&(x.P.Fe.prototype.C=function(a){return x.P.Fe.C(a,this)},x.P.Fe.C=function(a,b){var c={b9:l.u.D(b,1),name:l.u.D(b,2),value:l.u.Na(b,3)};a&&(c.ja=b);return c});x.P.Fe.ia=function(a){a=new l.ba(a);var b=new x.P.Fe;return x.P.Fe.F(b,a)};\nx.P.Fe.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.we();a.SS(c);break;case 2:c=b.Aa();a.fe(c);break;case 3:c=b.pa();a.setValue(c);break;default:b.ea()}}return a};x.P.Fe.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.xe(1,c);c=l.u.D(a,2);null!=c&&b.Ja(2,c);c=l.u.D(a,3);null!=c&&b.ya(3,c)};d=x.P.Fe.prototype;d.SS=function(a){l.u.J(this,1,a)};d.getName=function(){return l.u.D(this,2)};d.fe=function(a){l.u.J(this,2,a)};d.getValue=function(){return l.u.Na(this,3)};\nd.setValue=function(a){l.u.J(this,3,a)};x.P.Fe.K=function(a){return l.u.K(x.P.Fe,a)};x.P.Ge=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.P.Ge,l.u);l.u.ha&&(x.P.Ge.prototype.C=function(a){return x.P.Ge.C(a,this)},x.P.Ge.C=function(a,b){var c={name:l.u.D(b,1),lowerBound:l.u.Na(b,2),upperBound:l.u.Na(b,3),c5:l.u.Na(b,4)};a&&(c.ja=b);return c});x.P.Ge.ia=function(a){a=new l.ba(a);var b=new x.P.Ge;return x.P.Ge.F(b,a)};\nx.P.Ge.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.fe(c);break;case 2:c=b.pa();a.tj(c);break;case 3:c=b.pa();a.xj(c);break;case 4:c=b.pa();a.jR(c);break;default:b.ea()}}return a};x.P.Ge.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Ja(1,c);c=l.u.D(a,2);null!=c&&b.ya(2,c);c=l.u.D(a,3);null!=c&&b.ya(3,c);c=l.u.D(a,4);null!=c&&b.ya(4,c)};d=x.P.Ge.prototype;d.getName=function(){return l.u.D(this,1)};d.fe=function(a){l.u.J(this,1,a)};\nd.Xl=function(){return l.u.Na(this,2)};d.tj=function(a){l.u.J(this,2,a)};d.em=function(){return l.u.Na(this,3)};d.xj=function(a){l.u.J(this,3,a)};d.jR=function(a){l.u.J(this,4,a)};x.P.Ge.K=function(a){return l.u.K(x.P.Ge,a)};x.P.Td=function(a){l.u.initialize(this,a,0,-1,x.P.Td.na,null)};h.da(x.P.Td,l.u);x.P.Td.na=[3];l.u.ha&&(x.P.Td.prototype.C=function(a){return x.P.Td.C(a,this)},x.P.Td.C=function(a,b){var c={name:l.u.D(b,1),value:l.u.Na(b,2),bca:l.u.D(b,3)};a&&(c.ja=b);return c});\nx.P.Td.ia=function(a){a=new l.ba(a);var b=new x.P.Td;return x.P.Td.F(b,a)};x.P.Td.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.fe(c);break;case 2:c=b.pa();a.setValue(c);break;case 3:c=b.Aa();a.mJ(c);break;default:b.ea()}}return a};x.P.Td.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Ja(1,c);c=l.u.D(a,2);null!=c&&b.ya(2,c);c=a.vM();0<c.length&&b.oc(3,c)};d=x.P.Td.prototype;d.getName=function(){return l.u.D(this,1)};d.fe=function(a){l.u.J(this,1,a)};\nd.getValue=function(){return l.u.Na(this,2)};d.setValue=function(a){l.u.J(this,2,a)};d.vM=function(){return l.u.D(this,3)};d.mJ=function(a,b){l.u.ib(this,3,a,b)};x.P.Td.K=function(a){return l.u.K(x.P.Td,a)};x.P.pd=function(a){l.u.initialize(this,a,0,-1,x.P.pd.na,null)};h.da(x.P.pd,l.u);x.P.pd.na=[2];l.u.ha&&(x.P.pd.prototype.C=function(a){return x.P.pd.C(a,this)},x.P.pd.C=function(a,b){var c={gW:l.u.D(b,1),Jm:l.u.Ka(b.bf(),x.P.Bc.C,a)};a&&(c.ja=b);return c});\nx.P.pd.ia=function(a){a=new l.ba(a);var b=new x.P.pd;return x.P.pd.F(b,a)};x.P.pd.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.we();a.nt(c);break;case 2:c=new x.P.Bc;b.T(c,x.P.Bc.F);a.Eg(c);break;default:b.ea()}}return a};x.P.pd.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.xe(1,c);c=a.bf();0<c.length&&b.Oa(2,c,x.P.Bc.G)};x.P.pd.prototype.nt=function(a){l.u.J(this,1,a)};x.P.pd.prototype.bf=function(){return l.u.Ma(this,x.P.Bc,2)};\nx.P.pd.prototype.Eg=function(a,b){return l.u.La(this,2,a,x.P.Bc,b)};x.P.pd.K=function(a){return l.u.K(x.P.pd,a)};x.P.Bc=function(a){l.u.initialize(this,a,0,-1,x.P.Bc.na,null)};h.da(x.P.Bc,l.u);x.P.Bc.na=[1,2];l.u.ha&&(x.P.Bc.prototype.C=function(a){return x.P.Bc.C(a,this)},x.P.Bc.C=function(a,b){var c={qO:l.u.D(b,1),g9:l.u.Ka(b.zz(),x.i.Ub.C,a),f8:l.u.Na(b,3)};a&&(c.ja=b);return c});x.P.Bc.ia=function(a){a=new l.ba(a);var b=new x.P.Bc;return x.P.Bc.F(b,a)};\nx.P.Bc.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.Rq(c);break;case 2:c=new x.i.Ub;b.T(c,x.i.Ub.F);a.HI(c);break;case 3:c=b.pa();a.mS(c);break;default:b.ea()}}return a};x.P.Bc.G=function(a,b){var c;c=a.Ir();0<c.length&&b.oc(1,c);c=a.zz();0<c.length&&b.Oa(2,c,x.i.Ub.G);c=l.u.D(a,3);null!=c&&b.ya(3,c)};d=x.P.Bc.prototype;d.Ir=function(){return l.u.D(this,1)};d.Rq=function(a,b){l.u.ib(this,1,a,b)};d.zz=function(){return l.u.Ma(this,x.i.Ub,2)};\nd.HI=function(a,b){return l.u.La(this,2,a,x.i.Ub,b)};d.mS=function(a){l.u.J(this,3,a)};x.P.Bc.K=function(a){return l.u.K(x.P.Bc,a)};x.P.c_={EZ:1,fY:2,SZ:3,xY:4,kZ:5,DZ:6};x.P.JX={WW:1,CY:2};x.P.RY={NONE:1,EX:2,DX:3,GZ:4,SD:5,HZ:6,vY:7};x.i.Pb=function(a){l.u.initialize(this,a,0,-1,x.i.Pb.na,null)};h.da(x.i.Pb,l.u);x.i.Pb.na=[1];\nl.u.ha&&(x.i.Pb.prototype.C=function(a){return x.i.Pb.C(a,this)},x.i.Pb.C=function(a,b){var c,e={D3:l.u.Ka(b.ly(),x.i.Pb.Nd.C,a),t3:(c=b.jy())&&x.qa.Tc.C(a,c)};a&&(e.ja=b);return e});x.i.Pb.ia=function(a){a=new l.ba(a);var b=new x.i.Pb;return x.i.Pb.F(b,a)};x.i.Pb.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.Pb.Nd;b.T(c,x.i.Pb.Nd.F);a.IH(c);break;case 2:c=new x.qa.Tc;b.T(c,x.qa.Tc.F);a.EQ(c);break;default:b.ea()}}return a};\nx.i.Pb.G=function(a,b){var c;c=a.ly();0<c.length&&b.Oa(1,c,x.i.Pb.Nd.G);c=a.jy();null!=c&&b.oa(2,c,x.qa.Tc.G)};x.i.Pb.prototype.ly=function(){return l.u.Ma(this,x.i.Pb.Nd,1)};x.i.Pb.prototype.IH=function(a,b){return l.u.La(this,1,a,x.i.Pb.Nd,b)};x.i.Pb.prototype.jy=function(){return l.u.sa(this,x.qa.Tc,2)};x.i.Pb.prototype.EQ=function(a){l.u.Ca(this,2,a)};x.i.Pb.K=function(a){return l.u.K(x.i.Pb,a)};x.i.Pb.Nd=function(a){l.u.initialize(this,a,0,-1,x.i.Pb.Nd.na,null)};h.da(x.i.Pb.Nd,l.u);\nx.i.Pb.Nd.na=[2,3,4,5,6,7,8,9];l.u.ha&&(x.i.Pb.Nd.prototype.C=function(a){return x.i.Pb.Nd.C(a,this)},x.i.Pb.Nd.C=function(a,b){var c={aj:l.u.D(b,1),M4:l.u.D(b,2),gca:l.u.gb(b,3),ica:l.u.gb(b,4),mca:l.u.gb(b,5),oca:l.u.gb(b,6),jca:l.u.gb(b,7),pca:l.u.gb(b,8),W9:l.u.D(b,9)};a&&(c.ja=b);return c});x.i.Pb.Nd.ia=function(a){a=new l.ba(a);var b=new x.i.Pb.Nd;return x.i.Pb.Nd.F(b,a)};\nx.i.Pb.Nd.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.xf(c);break;case 2:c=b.Aa();a.TH(c);break;case 3:c=b.pa();a.oJ(c);break;case 4:c=b.pa();a.qJ(c);break;case 5:c=b.pa();a.tJ(c);break;case 6:c=b.pa();a.vJ(c);break;case 7:c=b.pa();a.nJ(c);break;case 8:c=b.pa();a.sJ(c);break;case 9:c=b.ee();a.MI(c);break;default:b.ea()}}return a};\nx.i.Pb.Nd.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Ja(1,c);c=a.tL();0<c.length&&b.oc(2,c);c=a.wM();0<c.length&&b.bd(3,c);c=a.xM();0<c.length&&b.bd(4,c);c=a.zM();0<c.length&&b.bd(5,c);c=a.AM();0<c.length&&b.bd(6,c);c=a.yM();0<c.length&&b.bd(7,c);c=a.BM();0<c.length&&b.bd(8,c);c=a.dM();0<c.length&&b.IW(9,c)};d=x.i.Pb.Nd.prototype;d.Hg=function(){return l.u.D(this,1)};d.xf=function(a){l.u.J(this,1,a)};d.tL=function(){return l.u.D(this,2)};d.TH=function(a,b){l.u.ib(this,2,a,b)};\nd.wM=function(){return l.u.gb(this,3)};d.oJ=function(a,b){l.u.ib(this,3,a,b)};d.xM=function(){return l.u.gb(this,4)};d.qJ=function(a,b){l.u.ib(this,4,a,b)};d.zM=function(){return l.u.gb(this,5)};d.tJ=function(a,b){l.u.ib(this,5,a,b)};d.AM=function(){return l.u.gb(this,6)};d.vJ=function(a,b){l.u.ib(this,6,a,b)};d.yM=function(){return l.u.gb(this,7)};d.nJ=function(a,b){l.u.ib(this,7,a,b)};d.BM=function(){return l.u.gb(this,8)};d.sJ=function(a,b){l.u.ib(this,8,a,b)};\nd.dM=function(){return l.u.D(this,9)};d.MI=function(a,b){l.u.ib(this,9,a,b)};x.i.Pb.Nd.K=function(a){return l.u.K(x.i.Pb.Nd,a)};x.i.Xb=function(a){l.u.initialize(this,a,0,-1,x.i.Xb.na,null)};h.da(x.i.Xb,l.u);x.i.Xb.na=[2];l.u.ha&&(x.i.Xb.prototype.C=function(a){return x.i.Xb.C(a,this)},x.i.Xb.C=function(a,b){var c={t8:l.u.D(b,1),kK:l.u.Ka(b.Ll(),x.i.Xb.Be.C,a)};a&&(c.ja=b);return c});x.i.Xb.ia=function(a){a=new l.ba(a);var b=new x.i.Xb;return x.i.Xb.F(b,a)};\nx.i.Xb.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.uS(c);break;case 2:c=new x.i.Xb.Be;b.T(c,x.i.Xb.Be.F);a.Mq(c);break;default:b.ea()}}return a};x.i.Xb.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Ja(1,c);c=a.Ll();0<c.length&&b.Oa(2,c,x.i.Xb.Be.G)};x.i.Xb.prototype.uS=function(a){l.u.J(this,1,a)};x.i.Xb.prototype.Ll=function(){return l.u.Ma(this,x.i.Xb.Be,2)};x.i.Xb.prototype.Mq=function(a,b){return l.u.La(this,2,a,x.i.Xb.Be,b)};\nx.i.Xb.K=function(a){return l.u.K(x.i.Xb,a)};x.i.Xb.Be=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.Xb.Be,l.u);l.u.ha&&(x.i.Xb.Be.prototype.C=function(a){return x.i.Xb.Be.C(a,this)},x.i.Xb.Be.C=function(a,b){var c={name:l.u.D(b,1),HO:l.u.D(b,2),lastIndex:l.u.D(b,3),rC:l.u.D(b,4),u8:l.u.D(b,5)};a&&(c.ja=b);return c});x.i.Xb.Be.ia=function(a){a=new l.ba(a);var b=new x.i.Xb.Be;return x.i.Xb.Be.F(b,a)};\nx.i.Xb.Be.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.fe(c);break;case 2:c=b.ad();a.et(c);break;case 3:c=b.ad();a.lS(c);break;case 4:c=b.ad();a.BU(c);break;case 5:c=b.ee();a.vS(c);break;default:b.ea()}}return a};x.i.Xb.Be.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Ja(1,c);c=l.u.D(a,2);null!=c&&b.td(2,c);c=l.u.D(a,3);null!=c&&b.td(3,c);c=l.u.D(a,4);null!=c&&b.td(4,c);c=l.u.D(a,5);null!=c&&b.ye(5,c)};d=x.i.Xb.Be.prototype;d.getName=function(){return l.u.D(this,1)};\nd.fe=function(a){l.u.J(this,1,a)};d.et=function(a){l.u.J(this,2,a)};d.lS=function(a){l.u.J(this,3,a)};d.BU=function(a){l.u.J(this,4,a)};d.vS=function(a){l.u.J(this,5,a)};x.i.Xb.Be.K=function(a){return l.u.K(x.i.Xb.Be,a)};x.i.Sb=function(a){l.u.initialize(this,a,0,-1,x.i.Sb.na,null)};h.da(x.i.Sb,l.u);x.i.Sb.na=[2];l.u.ha&&(x.i.Sb.prototype.C=function(a){return x.i.Sb.C(a,this)},x.i.Sb.C=function(a,b){var c={GO:l.u.D(b,1),NK:l.u.Ka(b.Rl(),x.i.Sb.Kb.C,a)};a&&(c.ja=b);return c});\nx.i.Sb.ia=function(a){a=new l.ba(a);var b=new x.i.Sb;return x.i.Sb.F(b,a)};x.i.Sb.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Jg();a.dt(c);break;case 2:c=new x.i.Sb.Kb;b.T(c,x.i.Sb.Kb.F);a.Nq(c);break;default:b.ea()}}return a};x.i.Sb.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Pg(1,c);c=a.Rl();0<c.length&&b.Oa(2,c,x.i.Sb.Kb.G)};x.i.Sb.prototype.dt=function(a){l.u.J(this,1,a)};x.i.Sb.prototype.Rl=function(){return l.u.Ma(this,x.i.Sb.Kb,2)};\nx.i.Sb.prototype.Nq=function(a,b){return l.u.La(this,2,a,x.i.Sb.Kb,b)};x.i.Sb.K=function(a){return l.u.K(x.i.Sb,a)};x.i.Sb.Kb=function(a){l.u.initialize(this,a,0,-1,x.i.Sb.Kb.na,null)};h.da(x.i.Sb.Kb,l.u);x.i.Sb.Kb.na=[7,8];l.u.ha&&(x.i.Sb.Kb.prototype.C=function(a){return x.i.Sb.Kb.C(a,this)},x.i.Sb.Kb.C=function(a,b){var c={Fl:l.u.D(b,1),Bj:l.u.D(b,2),SN:l.u.D(b,3),MK:l.u.D(b,4),creationTime:l.u.D(b,5),FJ:l.u.D(b,6),sba:l.u.D(b,7),tba:l.u.D(b,8),error:l.u.D(b,9)};a&&(c.ja=b);return c});\nx.i.Sb.Kb.ia=function(a){a=new l.ba(a);var b=new x.i.Sb.Kb;return x.i.Sb.Kb.F(b,a)};x.i.Sb.Kb.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Ya();a.Mg(c);break;case 2:c=b.Ya();a.zf(c);break;case 3:c=b.ad();a.Ys(c);break;case 4:c=b.ad();a.Rs(c);break;case 5:c=b.ad();a.Lg(c);break;case 6:c=b.ad();a.Ks(c);break;case 7:c=b.Aa();a.fJ(c);break;case 8:c=b.Aa();a.gJ(c);break;case 9:c=b.Aa();a.Jh(c);break;default:b.ea()}}return a};\nx.i.Sb.Kb.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.$a(1,c);c=l.u.D(a,2);null!=c&&b.$a(2,c);c=l.u.D(a,3);null!=c&&b.td(3,c);c=l.u.D(a,4);null!=c&&b.td(4,c);c=l.u.D(a,5);null!=c&&b.td(5,c);c=l.u.D(a,6);null!=c&&b.td(6,c);c=a.rM();0<c.length&&b.oc(7,c);c=a.sM();0<c.length&&b.oc(8,c);c=l.u.D(a,9);null!=c&&b.Ja(9,c)};d=x.i.Sb.Kb.prototype;d.ik=function(){return l.u.D(this,1)};d.Mg=function(a){l.u.J(this,1,a)};d.zf=function(a){l.u.J(this,2,a)};d.Ys=function(a){l.u.J(this,3,a)};\nd.Rs=function(a){l.u.J(this,4,a)};d.Lg=function(a){l.u.J(this,5,a)};d.Ks=function(a){l.u.J(this,6,a)};d.rM=function(){return l.u.D(this,7)};d.fJ=function(a,b){l.u.ib(this,7,a,b)};d.sM=function(){return l.u.D(this,8)};d.gJ=function(a,b){l.u.ib(this,8,a,b)};d.getError=function(){return l.u.D(this,9)};d.Jh=function(a){l.u.J(this,9,a)};x.i.Sb.Kb.K=function(a){return l.u.K(x.i.Sb.Kb,a)};x.i.Yb=function(a){l.u.initialize(this,a,0,-1,x.i.Yb.na,null)};h.da(x.i.Yb,l.u);x.i.Yb.na=[2];\nl.u.ha&&(x.i.Yb.prototype.C=function(a){return x.i.Yb.C(a,this)},x.i.Yb.C=function(a,b){var c={GO:l.u.D(b,1),NK:l.u.Ka(b.Rl(),x.i.Yb.Kb.C,a)};a&&(c.ja=b);return c});x.i.Yb.ia=function(a){a=new l.ba(a);var b=new x.i.Yb;return x.i.Yb.F(b,a)};x.i.Yb.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Jg();a.dt(c);break;case 2:c=new x.i.Yb.Kb;b.T(c,x.i.Yb.Kb.F);a.Nq(c);break;default:b.ea()}}return a};\nx.i.Yb.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Pg(1,c);c=a.Rl();0<c.length&&b.Oa(2,c,x.i.Yb.Kb.G)};x.i.Yb.prototype.dt=function(a){l.u.J(this,1,a)};x.i.Yb.prototype.Rl=function(){return l.u.Ma(this,x.i.Yb.Kb,2)};x.i.Yb.prototype.Nq=function(a,b){return l.u.La(this,2,a,x.i.Yb.Kb,b)};x.i.Yb.K=function(a){return l.u.K(x.i.Yb,a)};x.i.Yb.Kb=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.Yb.Kb,l.u);\nl.u.ha&&(x.i.Yb.Kb.prototype.C=function(a){return x.i.Yb.Kb.C(a,this)},x.i.Yb.Kb.C=function(a,b){var c={Fl:l.u.D(b,1),Bj:l.u.D(b,2),SN:l.u.D(b,3),MK:l.u.D(b,4),creationTime:l.u.D(b,5),FJ:l.u.D(b,6),K$:l.u.D(b,7),w9:l.u.D(b,8),e5:l.u.D(b,9),error:l.u.D(b,10)};a&&(c.ja=b);return c});x.i.Yb.Kb.ia=function(a){a=new l.ba(a);var b=new x.i.Yb.Kb;return x.i.Yb.Kb.F(b,a)};\nx.i.Yb.Kb.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Ya();a.Mg(c);break;case 2:c=b.Ya();a.zf(c);break;case 3:c=b.ad();a.Ys(c);break;case 4:c=b.ee();a.Rs(c);break;case 5:c=b.ee();a.Lg(c);break;case 6:c=b.ee();a.Ks(c);break;case 7:c=b.ee();a.WT(c);break;case 8:c=b.ee();a.gT(c);break;case 9:c=b.Aa();a.kR(c);break;case 10:c=b.Aa();a.Jh(c);break;default:b.ea()}}return a};\nx.i.Yb.Kb.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.$a(1,c);c=l.u.D(a,2);null!=c&&b.$a(2,c);c=l.u.D(a,3);null!=c&&b.td(3,c);c=l.u.D(a,4);null!=c&&b.ye(4,c);c=l.u.D(a,5);null!=c&&b.ye(5,c);c=l.u.D(a,6);null!=c&&b.ye(6,c);c=l.u.D(a,7);null!=c&&b.ye(7,c);c=l.u.D(a,8);null!=c&&b.ye(8,c);c=l.u.D(a,9);null!=c&&b.Ja(9,c);c=l.u.D(a,10);null!=c&&b.Ja(10,c)};d=x.i.Yb.Kb.prototype;d.ik=function(){return l.u.D(this,1)};d.Mg=function(a){l.u.J(this,1,a)};d.zf=function(a){l.u.J(this,2,a)};\nd.Ys=function(a){l.u.J(this,3,a)};d.Rs=function(a){l.u.J(this,4,a)};d.Lg=function(a){l.u.J(this,5,a)};d.Ks=function(a){l.u.J(this,6,a)};d.WT=function(a){l.u.J(this,7,a)};d.gT=function(a){l.u.J(this,8,a)};d.kR=function(a){l.u.J(this,9,a)};d.getError=function(){return l.u.D(this,10)};d.Jh=function(a){l.u.J(this,10,a)};x.i.Yb.Kb.K=function(a){return l.u.K(x.i.Yb.Kb,a)};x.i.ma=function(a){l.u.initialize(this,a,0,-1,x.i.ma.na,null)};h.da(x.i.ma,l.u);x.i.ma.na=[1,2,3,5];\nl.u.ha&&(x.i.ma.prototype.C=function(a){return x.i.ma.C(a,this)},x.i.ma.C=function(a,b){var c,e={t7:l.u.Ka(b.iz(),x.i.ma.nc.C,a),N5:l.u.Ka(b.Uy(),x.i.ma.nc.C,a),Rba:l.u.Ka(b.wA(),x.i.ma.Db.C,a),s8:(c=b.qz())&&x.i.ma.Qd.C(a,c),Uca:l.u.Ka(b.NA(),x.i.ma.zc.C,a)};a&&(e.ja=b);return e});x.i.ma.ia=function(a){a=new l.ba(a);var b=new x.i.ma;return x.i.ma.F(b,a)};\nx.i.ma.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.ma.nc;b.T(c,x.i.ma.nc.F);a.sI(c);break;case 2:c=new x.i.ma.nc;b.T(c,x.i.ma.nc.F);a.jI(c);break;case 3:c=new x.i.ma.Db;b.T(c,x.i.ma.Db.F);a.iJ(c);break;case 4:c=new x.i.ma.Qd;b.T(c,x.i.ma.Qd.F);a.tS(c);break;case 5:c=new x.i.ma.zc;b.T(c,x.i.ma.zc.F);a.yJ(c);break;default:b.ea()}}return a};\nx.i.ma.G=function(a,b){var c;c=a.iz();0<c.length&&b.Oa(1,c,x.i.ma.nc.G);c=a.Uy();0<c.length&&b.Oa(2,c,x.i.ma.nc.G);c=a.wA();0<c.length&&b.Oa(3,c,x.i.ma.Db.G);c=a.qz();null!=c&&b.oa(4,c,x.i.ma.Qd.G);c=a.NA();0<c.length&&b.Oa(5,c,x.i.ma.zc.G)};d=x.i.ma.prototype;d.iz=function(){return l.u.Ma(this,x.i.ma.nc,1)};d.sI=function(a,b){return l.u.La(this,1,a,x.i.ma.nc,b)};d.Uy=function(){return l.u.Ma(this,x.i.ma.nc,2)};d.jI=function(a,b){return l.u.La(this,2,a,x.i.ma.nc,b)};\nd.wA=function(){return l.u.Ma(this,x.i.ma.Db,3)};d.iJ=function(a,b){return l.u.La(this,3,a,x.i.ma.Db,b)};d.qz=function(){return l.u.sa(this,x.i.ma.Qd,4)};d.tS=function(a){l.u.Ca(this,4,a)};d.NA=function(){return l.u.Ma(this,x.i.ma.zc,5)};d.yJ=function(a,b){return l.u.La(this,5,a,x.i.ma.zc,b)};x.i.ma.K=function(a){return l.u.K(x.i.ma,a)};x.i.ma.Version=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.ma.Version,l.u);\nl.u.ha&&(x.i.ma.Version.prototype.C=function(a){return x.i.ma.Version.C(a,this)},x.i.ma.Version.C=function(a,b){var c={Bj:l.u.D(b,1),creationTime:l.u.D(b,2)};a&&(c.ja=b);return c});x.i.ma.Version.ia=function(a){a=new l.ba(a);var b=new x.i.ma.Version;return x.i.ma.Version.F(b,a)};x.i.ma.Version.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Ya();a.zf(c);break;case 2:c=b.Ya();a.Lg(c);break;default:b.ea()}}return a};\nx.i.ma.Version.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.$a(1,c);c=l.u.D(a,2);null!=c&&b.$a(2,c)};x.i.ma.Version.prototype.zf=function(a){l.u.J(this,1,a)};x.i.ma.Version.prototype.Lg=function(a){l.u.J(this,2,a)};x.i.ma.Version.K=function(a){return l.u.K(x.i.ma.Version,a)};x.i.ma.zc=function(a){l.u.initialize(this,a,0,-1,x.i.ma.zc.na,null)};h.da(x.i.ma.zc,l.u);x.i.ma.zc.na=[4];\nl.u.ha&&(x.i.ma.zc.prototype.C=function(a){return x.i.ma.zc.C(a,this)},x.i.ma.zc.C=function(a,b){var c={Fl:l.u.D(b,1),startTime:l.u.D(b,2),endTime:l.u.D(b,3),Jm:l.u.Ka(b.bf(),x.i.ma.Version.C,a)};a&&(c.ja=b);return c});x.i.ma.zc.ia=function(a){a=new l.ba(a);var b=new x.i.ma.zc;return x.i.ma.zc.F(b,a)};\nx.i.ma.zc.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Ya();a.Mg(c);break;case 2:c=b.Ya();a.vj(c);break;case 3:c=b.Ya();a.sj(c);break;case 4:c=new x.i.ma.Version;b.T(c,x.i.ma.Version.F);a.Eg(c);break;default:b.ea()}}return a};x.i.ma.zc.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.$a(1,c);c=l.u.D(a,2);null!=c&&b.$a(2,c);c=l.u.D(a,3);null!=c&&b.$a(3,c);c=a.bf();0<c.length&&b.Oa(4,c,x.i.ma.Version.G)};d=x.i.ma.zc.prototype;d.ik=function(){return l.u.D(this,1)};\nd.Mg=function(a){l.u.J(this,1,a)};d.getStartTime=function(){return l.u.D(this,2)};d.vj=function(a){l.u.J(this,2,a)};d.sj=function(a){l.u.J(this,3,a)};d.bf=function(){return l.u.Ma(this,x.i.ma.Version,4)};d.Eg=function(a,b){return l.u.La(this,4,a,x.i.ma.Version,b)};x.i.ma.zc.K=function(a){return l.u.K(x.i.ma.zc,a)};x.i.ma.nc=function(a){l.u.initialize(this,a,0,-1,x.i.ma.nc.na,null)};h.da(x.i.ma.nc,l.u);x.i.ma.nc.na=[2];\nl.u.ha&&(x.i.ma.nc.prototype.C=function(a){return x.i.ma.nc.C(a,this)},x.i.ma.nc.C=function(a,b){var c={type:l.u.D(b,1),b5:l.u.Ka(b.Gy(),x.i.ma.zc.C,a)};a&&(c.ja=b);return c});x.i.ma.nc.ia=function(a){a=new l.ba(a);var b=new x.i.ma.nc;return x.i.ma.nc.F(b,a)};x.i.ma.nc.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.yf(c);break;case 2:c=new x.i.ma.zc;b.T(c,x.i.ma.zc.F);a.VH(c);break;default:b.ea()}}return a};\nx.i.ma.nc.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Ja(1,c);c=a.Gy();0<c.length&&b.Oa(2,c,x.i.ma.zc.G)};x.i.ma.nc.prototype.mi=function(){return l.u.D(this,1)};x.i.ma.nc.prototype.yf=function(a){l.u.J(this,1,a)};x.i.ma.nc.prototype.Gy=function(){return l.u.Ma(this,x.i.ma.zc,2)};x.i.ma.nc.prototype.VH=function(a,b){return l.u.La(this,2,a,x.i.ma.zc,b)};x.i.ma.nc.K=function(a){return l.u.K(x.i.ma.nc,a)};x.i.ma.Db=function(a){l.u.initialize(this,a,0,-1,x.i.ma.Db.na,null)};h.da(x.i.ma.Db,l.u);\nx.i.ma.Db.na=[4];l.u.ha&&(x.i.ma.Db.prototype.C=function(a){return x.i.ma.Db.C(a,this)},x.i.ma.Db.C=function(a,b){var c={Fl:l.u.D(b,1),startTime:l.u.D(b,2),endTime:l.u.D(b,3),iW:l.u.Ka(b.cm(),x.i.ma.Db.Yd.C,a)};a&&(c.ja=b);return c});x.i.ma.Db.ia=function(a){a=new l.ba(a);var b=new x.i.ma.Db;return x.i.ma.Db.F(b,a)};\nx.i.ma.Db.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Ya();a.Mg(c);break;case 2:c=b.Ya();a.vj(c);break;case 3:c=b.Ya();a.sj(c);break;case 4:c=new x.i.ma.Db.Yd;b.T(c,x.i.ma.Db.Yd.F);a.Tq(c);break;default:b.ea()}}return a};x.i.ma.Db.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.$a(1,c);c=l.u.D(a,2);null!=c&&b.$a(2,c);c=l.u.D(a,3);null!=c&&b.$a(3,c);c=a.cm();0<c.length&&b.Oa(4,c,x.i.ma.Db.Yd.G)};d=x.i.ma.Db.prototype;d.ik=function(){return l.u.D(this,1)};\nd.Mg=function(a){l.u.J(this,1,a)};d.getStartTime=function(){return l.u.D(this,2)};d.vj=function(a){l.u.J(this,2,a)};d.sj=function(a){l.u.J(this,3,a)};d.cm=function(){return l.u.Ma(this,x.i.ma.Db.Yd,4)};d.Tq=function(a,b){return l.u.La(this,4,a,x.i.ma.Db.Yd,b)};x.i.ma.Db.K=function(a){return l.u.K(x.i.ma.Db,a)};x.i.ma.Db.Yd=function(a){l.u.initialize(this,a,0,-1,x.i.ma.Db.Yd.na,null)};h.da(x.i.ma.Db.Yd,l.u);x.i.ma.Db.Yd.na=[3];\nl.u.ha&&(x.i.ma.Db.Yd.prototype.C=function(a){return x.i.ma.Db.Yd.C(a,this)},x.i.ma.Db.Yd.C=function(a,b){var c={name:l.u.D(b,1),type:l.u.D(b,2),Jm:l.u.Ka(b.bf(),x.i.ma.Version.C,a)};a&&(c.ja=b);return c});x.i.ma.Db.Yd.ia=function(a){a=new l.ba(a);var b=new x.i.ma.Db.Yd;return x.i.ma.Db.Yd.F(b,a)};x.i.ma.Db.Yd.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.fe(c);break;case 2:c=b.Aa();a.yf(c);break;case 3:c=new x.i.ma.Version;b.T(c,x.i.ma.Version.F);a.Eg(c);break;default:b.ea()}}return a};\nx.i.ma.Db.Yd.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Ja(1,c);c=l.u.D(a,2);null!=c&&b.Ja(2,c);c=a.bf();0<c.length&&b.Oa(3,c,x.i.ma.Version.G)};d=x.i.ma.Db.Yd.prototype;d.getName=function(){return l.u.D(this,1)};d.fe=function(a){l.u.J(this,1,a)};d.mi=function(){return l.u.D(this,2)};d.yf=function(a){l.u.J(this,2,a)};d.bf=function(){return l.u.Ma(this,x.i.ma.Version,3)};d.Eg=function(a,b){return l.u.La(this,3,a,x.i.ma.Version,b)};x.i.ma.Db.Yd.K=function(a){return l.u.K(x.i.ma.Db.Yd,a)};\nx.i.ma.Qd=function(a){l.u.initialize(this,a,0,-1,x.i.ma.Qd.na,null)};h.da(x.i.ma.Qd,l.u);x.i.ma.Qd.na=[1];l.u.ha&&(x.i.ma.Qd.prototype.C=function(a){return x.i.ma.Qd.C(a,this)},x.i.ma.Qd.C=function(a,b){var c={Jm:l.u.Ka(b.bf(),x.i.ma.Version.C,a)};a&&(c.ja=b);return c});x.i.ma.Qd.ia=function(a){a=new l.ba(a);var b=new x.i.ma.Qd;return x.i.ma.Qd.F(b,a)};x.i.ma.Qd.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.ma.Version;b.T(c,x.i.ma.Version.F);a.Eg(c);break;default:b.ea()}}return a};\nx.i.ma.Qd.G=function(a,b){a=a.bf();0<a.length&&b.Oa(1,a,x.i.ma.Version.G)};x.i.ma.Qd.prototype.bf=function(){return l.u.Ma(this,x.i.ma.Version,1)};x.i.ma.Qd.prototype.Eg=function(a,b){return l.u.La(this,1,a,x.i.ma.Version,b)};x.i.ma.Qd.K=function(a){return l.u.K(x.i.ma.Qd,a)};x.i.kg=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.kg,l.u);l.u.ha&&(x.i.kg.prototype.C=function(a){return x.i.kg.C(a,this)},x.i.kg.C=function(a,b){var c={l7:l.u.D(b,1)};a&&(c.ja=b);return c});\nx.i.kg.ia=function(a){a=new l.ba(a);var b=new x.i.kg;return x.i.kg.F(b,a)};x.i.kg.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.WR(c);break;default:b.ea()}}return a};x.i.kg.G=function(a,b){a=l.u.D(a,1);null!=a&&b.Ja(1,a)};x.i.kg.prototype.WR=function(a){l.u.J(this,1,a)};x.i.kg.K=function(a){return l.u.K(x.i.kg,a)};x.i.lf=function(a){l.u.initialize(this,a,0,-1,x.i.lf.na,null)};h.da(x.i.lf,l.u);x.i.lf.na=[1];\nl.u.ha&&(x.i.lf.prototype.C=function(a){return x.i.lf.C(a,this)},x.i.lf.C=function(a,b){var c={X8:l.u.Ka(b.vz(),x.P.Rd.C,a)};a&&(c.ja=b);return c});x.i.lf.ia=function(a){a=new l.ba(a);var b=new x.i.lf;return x.i.lf.F(b,a)};x.i.lf.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.P.Rd;b.T(c,x.P.Rd.F);a.DI(c);break;default:b.ea()}}return a};x.i.lf.G=function(a,b){a=a.vz();0<a.length&&b.Oa(1,a,x.P.Rd.G)};x.i.lf.prototype.vz=function(){return l.u.Ma(this,x.P.Rd,1)};\nx.i.lf.prototype.DI=function(a,b){return l.u.La(this,1,a,x.P.Rd,b)};x.i.lf.K=function(a){return l.u.K(x.i.lf,a)};x.i.Link=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.Link,l.u);l.u.ha&&(x.i.Link.prototype.C=function(a){return x.i.Link.C(a,this)},x.i.Link.C=function(a,b){var c={id:l.u.D(b,1),url:l.u.D(b,2)};a&&(c.ja=b);return c});x.i.Link.ia=function(a){a=new l.ba(a);var b=new x.i.Link;return x.i.Link.F(b,a)};\nx.i.Link.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.Vs(c);break;case 2:c=b.Aa();a.EV(c);break;default:b.ea()}}return a};x.i.Link.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Ja(1,c);c=l.u.D(a,2);null!=c&&b.Ja(2,c)};x.i.Link.prototype.Vs=function(a){l.u.J(this,1,a)};x.i.Link.prototype.getUrl=function(){return l.u.D(this,2)};x.i.Link.prototype.EV=function(a){l.u.J(this,2,a)};x.i.Link.K=function(a){return l.u.K(x.i.Link,a)};\nx.i.Ea=function(a){l.u.initialize(this,a,0,-1,x.i.Ea.na,null)};h.da(x.i.Ea,l.u);x.i.Ea.na=[15];\nl.u.ha&&(x.i.Ea.prototype.C=function(a){return x.i.Ea.C(a,this)},x.i.Ea.C=function(a,b){var c,e={Bj:l.u.D(b,1),creationTime:l.u.D(b,2),Wca:(c=b.PA())&&x.i.Ea.$b.C(a,c),e7:(c=b.cz())&&x.i.Ea.$b.C(a,c),D9:(c=b.Hz())&&x.i.Ea.$b.C(a,c),Y7:(c=b.mz())&&x.i.Ea.$b.C(a,c),Z7:(c=b.nz())&&x.i.Ea.rb.C(a,c),S$:(c=b.Uz())&&x.i.Ea.rb.C(a,c),baa:(c=b.aA())&&x.i.Ea.rb.C(a,c),wl:(c=b.Gg())&&x.i.Ea.rb.C(a,c),Ow:(c=b.so())&&x.i.Ea.rb.C(a,c),eP:(c=b.Nr())&&x.i.Ea.rb.C(a,c),Bda:(c=b.ZA())&&x.i.Ea.rb.C(a,c),C3:l.u.D(b,\n14),UN:l.u.Ka(b.Vl(),x.i.Link.C,a),O9:l.u.Na(b,16),Xca:(c=b.QA())&&x.i.wc.C(a,c),f7:(c=b.dz())&&x.i.wc.C(a,c),iN:(c=b.Tl())&&x.i.Rc.C(a,c)};a&&(e.ja=b);return e});x.i.Ea.ia=function(a){a=new l.ba(a);var b=new x.i.Ea;return x.i.Ea.F(b,a)};\nx.i.Ea.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Ya();a.zf(c);break;case 2:c=b.ee();a.Lg(c);break;case 3:c=new x.i.Ea.$b;b.T(c,x.i.Ea.$b.F);a.vV(c);break;case 4:c=new x.i.Ea.$b;b.T(c,x.i.Ea.$b.F);a.PR(c);break;case 5:c=new x.i.Ea.$b;b.T(c,x.i.Ea.$b.F);a.lT(c);break;case 6:c=new x.i.Ea.$b;b.T(c,x.i.Ea.$b.F);a.hS(c);break;case 7:c=new x.i.Ea.rb;b.T(c,x.i.Ea.rb.F);a.iS(c);break;case 8:c=new x.i.Ea.rb;b.T(c,x.i.Ea.rb.F);a.$T(c);break;case 9:c=new x.i.Ea.rb;b.T(c,x.i.Ea.rb.F);\na.iU(c);break;case 10:c=new x.i.Ea.rb;b.T(c,x.i.Ea.rb.F);a.Kg(c);break;case 11:c=new x.i.Ea.rb;b.T(c,x.i.Ea.rb.F);a.um(c);break;case 12:c=new x.i.Ea.rb;b.T(c,x.i.Ea.rb.F);a.ht(c);break;case 13:c=new x.i.Ea.rb;b.T(c,x.i.Ea.rb.F);a.NV(c);break;case 14:c=b.vf();a.KQ(c);break;case 15:c=new x.i.Link;b.T(c,x.i.Link.F);a.Qq(c);break;case 16:c=b.pa();a.rT(c);break;case 17:c=new x.i.wc;b.T(c,x.i.wc.F);a.wV(c);break;case 18:c=new x.i.wc;b.T(c,x.i.wc.F);a.QR(c);break;case 19:c=new x.i.Rc;b.T(c,x.i.Rc.F);a.Xs(c);\nbreak;default:b.ea()}}return a};\nx.i.Ea.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.$a(1,c);c=l.u.D(a,2);null!=c&&b.ye(2,c);c=a.PA();null!=c&&b.oa(3,c,x.i.Ea.$b.G);c=a.cz();null!=c&&b.oa(4,c,x.i.Ea.$b.G);c=a.Hz();null!=c&&b.oa(5,c,x.i.Ea.$b.G);c=a.mz();null!=c&&b.oa(6,c,x.i.Ea.$b.G);c=a.nz();null!=c&&b.oa(7,c,x.i.Ea.rb.G);c=a.Uz();null!=c&&b.oa(8,c,x.i.Ea.rb.G);c=a.aA();null!=c&&b.oa(9,c,x.i.Ea.rb.G);c=a.Gg();null!=c&&b.oa(10,c,x.i.Ea.rb.G);c=a.so();null!=c&&b.oa(11,c,x.i.Ea.rb.G);c=a.Nr();null!=c&&b.oa(12,c,x.i.Ea.rb.G);c=a.ZA();\nnull!=c&&b.oa(13,c,x.i.Ea.rb.G);c=l.u.D(a,14);null!=c&&b.kf(14,c);c=a.Vl();0<c.length&&b.Oa(15,c,x.i.Link.G);c=l.u.D(a,16);null!=c&&b.ya(16,c);c=a.QA();null!=c&&b.oa(17,c,x.i.wc.G);c=a.dz();null!=c&&b.oa(18,c,x.i.wc.G);c=a.Tl();null!=c&&b.oa(19,c,x.i.Rc.G)};d=x.i.Ea.prototype;d.zf=function(a){l.u.J(this,1,a)};d.Lg=function(a){l.u.J(this,2,a)};d.PA=function(){return l.u.sa(this,x.i.Ea.$b,3)};d.vV=function(a){l.u.Ca(this,3,a)};d.cz=function(){return l.u.sa(this,x.i.Ea.$b,4)};\nd.PR=function(a){l.u.Ca(this,4,a)};d.Hz=function(){return l.u.sa(this,x.i.Ea.$b,5)};d.lT=function(a){l.u.Ca(this,5,a)};d.mz=function(){return l.u.sa(this,x.i.Ea.$b,6)};d.hS=function(a){l.u.Ca(this,6,a)};d.nz=function(){return l.u.sa(this,x.i.Ea.rb,7)};d.iS=function(a){l.u.Ca(this,7,a)};d.Uz=function(){return l.u.sa(this,x.i.Ea.rb,8)};d.$T=function(a){l.u.Ca(this,8,a)};d.aA=function(){return l.u.sa(this,x.i.Ea.rb,9)};d.iU=function(a){l.u.Ca(this,9,a)};d.Gg=function(){return l.u.sa(this,x.i.Ea.rb,10)};\nd.Kg=function(a){l.u.Ca(this,10,a)};d.so=function(){return l.u.sa(this,x.i.Ea.rb,11)};d.um=function(a){l.u.Ca(this,11,a)};d.Nr=function(){return l.u.sa(this,x.i.Ea.rb,12)};d.ht=function(a){l.u.Ca(this,12,a)};d.ZA=function(){return l.u.sa(this,x.i.Ea.rb,13)};d.NV=function(a){l.u.Ca(this,13,a)};d.KQ=function(a){l.u.J(this,14,a)};d.Vl=function(){return l.u.Ma(this,x.i.Link,15)};d.Qq=function(a,b){return l.u.La(this,15,a,x.i.Link,b)};d.rT=function(a){l.u.J(this,16,a)};\nd.QA=function(){return l.u.sa(this,x.i.wc,17)};d.wV=function(a){l.u.Ca(this,17,a)};d.dz=function(){return l.u.sa(this,x.i.wc,18)};d.QR=function(a){l.u.Ca(this,18,a)};d.Tl=function(){return l.u.sa(this,x.i.Rc,19)};d.Xs=function(a){l.u.Ca(this,19,a)};x.i.Ea.K=function(a){return l.u.K(x.i.Ea,a)};x.i.Ea.rb=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.Ea.rb,l.u);\nl.u.ha&&(x.i.Ea.rb.prototype.C=function(a){return x.i.Ea.rb.C(a,this)},x.i.Ea.rb.C=function(a,b){var c={Tca:l.u.Na(b,1),b7:l.u.Na(b,2)};a&&(c.ja=b);return c});x.i.Ea.rb.ia=function(a){a=new l.ba(a);var b=new x.i.Ea.rb;return x.i.Ea.rb.F(b,a)};x.i.Ea.rb.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.pa();a.uV(c);break;case 2:c=b.pa();a.NR(c);break;default:b.ea()}}return a};x.i.Ea.rb.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.ya(1,c);c=l.u.D(a,2);null!=c&&b.ya(2,c)};\nx.i.Ea.rb.prototype.uV=function(a){l.u.J(this,1,a)};x.i.Ea.rb.prototype.NR=function(a){l.u.J(this,2,a)};x.i.Ea.rb.K=function(a){return l.u.K(x.i.Ea.rb,a)};x.i.Ea.$b=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.Ea.$b,l.u);l.u.ha&&(x.i.Ea.$b.prototype.C=function(a){return x.i.Ea.$b.C(a,this)},x.i.Ea.$b.C=function(a,b){var c={U8:l.u.Na(b,1),D$:l.u.Na(b,2),q9:l.u.Na(b,3)};a&&(c.ja=b);return c});x.i.Ea.$b.ia=function(a){a=new l.ba(a);var b=new x.i.Ea.$b;return x.i.Ea.$b.F(b,a)};\nx.i.Ea.$b.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.pa();a.PS(c);break;case 2:c=b.pa();a.QT(c);break;case 3:c=b.pa();a.aT(c);break;default:b.ea()}}return a};x.i.Ea.$b.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.ya(1,c);c=l.u.D(a,2);null!=c&&b.ya(2,c);c=l.u.D(a,3);null!=c&&b.ya(3,c)};x.i.Ea.$b.prototype.PS=function(a){l.u.J(this,1,a)};x.i.Ea.$b.prototype.QT=function(a){l.u.J(this,2,a)};x.i.Ea.$b.prototype.aT=function(a){l.u.J(this,3,a)};\nx.i.Ea.$b.K=function(a){return l.u.K(x.i.Ea.$b,a)};x.i.Qb=function(a){l.u.initialize(this,a,0,-1,x.i.Qb.na,null)};h.da(x.i.Qb,l.u);x.i.Qb.na=[3,4,5,6];l.u.ha&&(x.i.Qb.prototype.C=function(a){return x.i.Qb.C(a,this)},x.i.Qb.C=function(a,b){var c={name:l.u.D(b,1),path:l.u.D(b,2),j5:l.u.Ka(b.Iy(),x.i.Qb.Ce.C,a),Gca:l.u.Ka(b.GA(),x.i.Link.C,a),C4:l.u.Ka(b.xy(),x.i.Link.C,a),D4:l.u.Ka(b.yy(),x.i.Link.C,a)};a&&(c.ja=b);return c});x.i.Qb.ia=function(a){a=new l.ba(a);var b=new x.i.Qb;return x.i.Qb.F(b,a)};\nx.i.Qb.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.fe(c);break;case 2:c=b.Aa();a.uj(c);break;case 3:c=new x.i.Qb.Ce;b.T(c,x.i.Qb.Ce.F);a.YH(c);break;case 4:c=new x.i.Link;b.T(c,x.i.Link.F);a.xJ(c);break;case 5:c=new x.i.Link;b.T(c,x.i.Link.F);a.OH(c);break;case 6:c=new x.i.Link;b.T(c,x.i.Link.F);a.PH(c);break;default:b.ea()}}return a};\nx.i.Qb.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Ja(1,c);c=l.u.D(a,2);null!=c&&b.Ja(2,c);c=a.Iy();0<c.length&&b.Oa(3,c,x.i.Qb.Ce.G);c=a.GA();0<c.length&&b.Oa(4,c,x.i.Link.G);c=a.xy();0<c.length&&b.Oa(5,c,x.i.Link.G);c=a.yy();0<c.length&&b.Oa(6,c,x.i.Link.G)};d=x.i.Qb.prototype;d.getName=function(){return l.u.D(this,1)};d.fe=function(a){l.u.J(this,1,a)};d.ij=function(){return l.u.D(this,2)};d.uj=function(a){l.u.J(this,2,a)};d.Yr=function(){return null!=l.u.D(this,2)};\nd.Iy=function(){return l.u.Ma(this,x.i.Qb.Ce,3)};d.YH=function(a,b){return l.u.La(this,3,a,x.i.Qb.Ce,b)};d.GA=function(){return l.u.Ma(this,x.i.Link,4)};d.xJ=function(a,b){return l.u.La(this,4,a,x.i.Link,b)};d.xy=function(){return l.u.Ma(this,x.i.Link,5)};d.OH=function(a,b){return l.u.La(this,5,a,x.i.Link,b)};d.yy=function(){return l.u.Ma(this,x.i.Link,6)};d.PH=function(a,b){return l.u.La(this,6,a,x.i.Link,b)};x.i.Qb.K=function(a){return l.u.K(x.i.Qb,a)};\nx.i.Qb.Ce=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.Qb.Ce,l.u);l.u.ha&&(x.i.Qb.Ce.prototype.C=function(a){return x.i.Qb.Ce.C(a,this)},x.i.Qb.Ce.C=function(a,b){var c={type:l.u.D(b,1),Bj:l.u.D(b,2),creationTime:l.u.D(b,3),wda:l.u.D(b,4)};a&&(c.ja=b);return c});x.i.Qb.Ce.ia=function(a){a=new l.ba(a);var b=new x.i.Qb.Ce;return x.i.Qb.Ce.F(b,a)};\nx.i.Qb.Ce.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.yf(c);break;case 2:c=b.Ya();a.zf(c);break;case 3:c=b.ee();a.Lg(c);break;case 4:c=b.Aa();a.KV(c);break;default:b.ea()}}return a};x.i.Qb.Ce.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Ja(1,c);c=l.u.D(a,2);null!=c&&b.$a(2,c);c=l.u.D(a,3);null!=c&&b.ye(3,c);c=l.u.D(a,4);null!=c&&b.Ja(4,c)};d=x.i.Qb.Ce.prototype;d.mi=function(){return l.u.D(this,1)};d.yf=function(a){l.u.J(this,1,a)};\nd.zf=function(a){l.u.J(this,2,a)};d.Lg=function(a){l.u.J(this,3,a)};d.KV=function(a){l.u.J(this,4,a)};x.i.Qb.Ce.K=function(a){return l.u.K(x.i.Qb.Ce,a)};x.i.qf=function(a){l.u.initialize(this,a,0,-1,x.i.qf.na,null)};h.da(x.i.qf,l.u);x.i.qf.na=[1];l.u.ha&&(x.i.qf.prototype.C=function(a){return x.i.qf.C(a,this)},x.i.qf.C=function(a,b){var c={j9:l.u.Ka(b.Az(),x.i.Sd.C,a)};a&&(c.ja=b);return c});x.i.qf.ia=function(a){a=new l.ba(a);var b=new x.i.qf;return x.i.qf.F(b,a)};\nx.i.qf.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.Sd;b.T(c,x.i.Sd.F);a.II(c);break;default:b.ea()}}return a};x.i.qf.G=function(a,b){a=a.Az();0<a.length&&b.Oa(1,a,x.i.Sd.G)};x.i.qf.prototype.Az=function(){return l.u.Ma(this,x.i.Sd,1)};x.i.qf.prototype.II=function(a,b){return l.u.La(this,1,a,x.i.Sd,b)};x.i.qf.K=function(a){return l.u.K(x.i.qf,a)};x.i.pf=function(a){l.u.initialize(this,a,0,-1,x.i.pf.na,null)};h.da(x.i.pf,l.u);x.i.pf.na=[1];\nl.u.ha&&(x.i.pf.prototype.C=function(a){return x.i.pf.C(a,this)},x.i.pf.C=function(a,b){var c={T5:l.u.D(b,1)};a&&(c.ja=b);return c});x.i.pf.ia=function(a){a=new l.ba(a);var b=new x.i.pf;return x.i.pf.F(b,a)};x.i.pf.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.lI(c);break;default:b.ea()}}return a};x.i.pf.G=function(a,b){a=a.HL();0<a.length&&b.oc(1,a)};x.i.pf.prototype.HL=function(){return l.u.D(this,1)};x.i.pf.prototype.lI=function(a,b){l.u.ib(this,1,a,b)};\nx.i.pf.K=function(a){return l.u.K(x.i.pf,a)};x.i.Cb=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.Cb,l.u);l.u.ha&&(x.i.Cb.prototype.C=function(a){return x.i.Cb.C(a,this)},x.i.Cb.C=function(a,b){var c,e={uda:l.u.D(b,1),c3:l.u.D(b,2),creationTime:l.u.D(b,3),v$:l.u.D(b,4),z2:l.u.D(b,5),Z4:l.u.D(b,6),Fl:l.u.D(b,7),version:l.u.D(b,8),w2:(c=b.Ux())&&x.i.Cb.md.C(a,c),Y4:(c=b.Fy())&&x.i.Cb.md.C(a,c),fP:l.u.Na(b,11),error:l.u.D(b,12)};a&&(e.ja=b);return e});\nx.i.Cb.ia=function(a){a=new l.ba(a);var b=new x.i.Cb;return x.i.Cb.F(b,a)};\nx.i.Cb.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.IV(c);break;case 2:c=b.Ya();a.BQ(c);break;case 3:c=b.ad();a.Lg(c);break;case 4:c=b.vf();a.LT(c);break;case 5:c=b.Ya();a.qQ(c);break;case 6:c=b.Ya();a.iR(c);break;case 7:c=b.Ya();a.Mg(c);break;case 8:c=b.Ya();a.setVersion(c);break;case 9:c=new x.i.Cb.md;b.T(c,x.i.Cb.md.F);a.pQ(c);break;case 10:c=new x.i.Cb.md;b.T(c,x.i.Cb.md.F);a.hR(c);break;case 11:c=b.pa();a.it(c);break;case 12:c=b.Aa();a.Jh(c);break;default:b.ea()}}return a};\nx.i.Cb.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Ja(1,c);c=l.u.D(a,2);null!=c&&b.$a(2,c);c=l.u.D(a,3);null!=c&&b.td(3,c);c=l.u.D(a,4);null!=c&&b.kf(4,c);c=l.u.D(a,5);null!=c&&b.$a(5,c);c=l.u.D(a,6);null!=c&&b.$a(6,c);c=l.u.D(a,7);null!=c&&b.$a(7,c);c=l.u.D(a,8);null!=c&&b.$a(8,c);c=a.Ux();null!=c&&b.oa(9,c,x.i.Cb.md.G);c=a.Fy();null!=c&&b.oa(10,c,x.i.Cb.md.G);c=l.u.D(a,11);null!=c&&b.ya(11,c);c=l.u.D(a,12);null!=c&&b.Ja(12,c)};d=x.i.Cb.prototype;d.IV=function(a){l.u.J(this,1,a)};\nd.BQ=function(a){l.u.J(this,2,a)};d.Lg=function(a){l.u.J(this,3,a)};d.LT=function(a){l.u.J(this,4,a)};d.qQ=function(a){l.u.J(this,5,a)};d.iR=function(a){l.u.J(this,6,a)};d.ik=function(){return l.u.D(this,7)};d.Mg=function(a){l.u.J(this,7,a)};d.getVersion=function(){return l.u.D(this,8)};d.setVersion=function(a){l.u.J(this,8,a)};d.Ux=function(){return l.u.sa(this,x.i.Cb.md,9)};d.pQ=function(a){l.u.Ca(this,9,a)};d.Fy=function(){return l.u.sa(this,x.i.Cb.md,10)};d.hR=function(a){l.u.Ca(this,10,a)};\nd.it=function(a){l.u.J(this,11,a)};d.getError=function(){return l.u.D(this,12)};d.Jh=function(a){l.u.J(this,12,a)};x.i.Cb.K=function(a){return l.u.K(x.i.Cb,a)};x.i.Cb.md=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.Cb.md,l.u);l.u.ha&&(x.i.Cb.md.prototype.C=function(a){return x.i.Cb.md.C(a,this)},x.i.Cb.md.C=function(a,b){var c={lm:l.u.Na(b,1),wl:l.u.Na(b,2),$B:l.u.Na(b,3),QK:l.u.Na(b,4),q2:l.u.Na(b,5),s2:l.u.Na(b,6)};a&&(c.ja=b);return c});\nx.i.Cb.md.ia=function(a){a=new l.ba(a);var b=new x.i.Cb.md;return x.i.Cb.md.F(b,a)};x.i.Cb.md.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.pa();a.Ng(c);break;case 2:c=b.pa();a.Kg(c);break;case 3:c=b.pa();a.ym(c);break;case 4:c=b.pa();a.Ss(c);break;case 5:c=b.pa();a.nQ(c);break;case 6:c=b.pa();a.oQ(c);break;default:b.ea()}}return a};\nx.i.Cb.md.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.ya(1,c);c=l.u.D(a,2);null!=c&&b.ya(2,c);c=l.u.D(a,3);null!=c&&b.ya(3,c);c=l.u.D(a,4);null!=c&&b.ya(4,c);c=l.u.D(a,5);null!=c&&b.ya(5,c);c=l.u.D(a,6);null!=c&&b.ya(6,c)};d=x.i.Cb.md.prototype;d.eg=function(){return l.u.Na(this,1)};d.Ng=function(a){l.u.J(this,1,a)};d.Gg=function(){return l.u.Na(this,2)};d.Kg=function(a){l.u.J(this,2,a)};d.mk=function(){return l.u.Na(this,3)};d.ym=function(a){l.u.J(this,3,a)};\nd.Er=function(){return l.u.Na(this,4)};d.Ss=function(a){l.u.J(this,4,a)};d.nQ=function(a){l.u.J(this,5,a)};d.oQ=function(a){l.u.J(this,6,a)};x.i.Cb.md.K=function(a){return l.u.K(x.i.Cb.md,a)};x.i.pc=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.pc,l.u);l.u.ha&&(x.i.pc.prototype.C=function(a){return x.i.pc.C(a,this)},x.i.pc.C=function(a,b){var c={absolute:l.u.Na(b,1),waa:l.u.Na(b,2)};a&&(c.ja=b);return c});x.i.pc.ia=function(a){a=new l.ba(a);var b=new x.i.pc;return x.i.pc.F(b,a)};\nx.i.pc.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.pa();a.$P(c);break;case 2:c=b.pa();a.tU(c);break;default:b.ea()}}return a};x.i.pc.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.ya(1,c);c=l.u.D(a,2);null!=c&&b.ya(2,c)};x.i.pc.prototype.$P=function(a){l.u.J(this,1,a)};x.i.pc.prototype.tU=function(a){l.u.J(this,2,a)};x.i.pc.K=function(a){return l.u.K(x.i.pc,a)};x.i.Jc=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.Jc,l.u);\nl.u.ha&&(x.i.Jc.prototype.C=function(a){return x.i.Jc.C(a,this)},x.i.Jc.C=function(a,b){var c={lowerBound:l.u.Na(b,1),upperBound:l.u.Na(b,2)};a&&(c.ja=b);return c});x.i.Jc.ia=function(a){a=new l.ba(a);var b=new x.i.Jc;return x.i.Jc.F(b,a)};x.i.Jc.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.pa();a.tj(c);break;case 2:c=b.pa();a.xj(c);break;default:b.ea()}}return a};x.i.Jc.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.ya(1,c);c=l.u.D(a,2);null!=c&&b.ya(2,c)};\nx.i.Jc.prototype.Xl=function(){return l.u.Na(this,1)};x.i.Jc.prototype.tj=function(a){l.u.J(this,1,a)};x.i.Jc.prototype.em=function(){return l.u.Na(this,2)};x.i.Jc.prototype.xj=function(a){l.u.J(this,2,a)};x.i.Jc.K=function(a){return l.u.K(x.i.Jc,a)};x.i.Se=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.Se,l.u);\nl.u.ha&&(x.i.Se.prototype.C=function(a){return x.i.Se.C(a,this)},x.i.Se.C=function(a,b){var c,e={lm:(c=b.eg())&&x.i.pc.C(a,c),wl:(c=b.Gg())&&x.i.pc.C(a,c),$B:(c=b.mk())&&x.i.pc.C(a,c),fP:l.u.Na(b,4),p2:(c=b.Tx())&&x.i.Jc.C(a,c),QK:(c=b.Er())&&x.i.Jc.C(a,c)};a&&(e.ja=b);return e});x.i.Se.ia=function(a){a=new l.ba(a);var b=new x.i.Se;return x.i.Se.F(b,a)};\nx.i.Se.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.pc;b.T(c,x.i.pc.F);a.Ng(c);break;case 2:c=new x.i.pc;b.T(c,x.i.pc.F);a.Kg(c);break;case 3:c=new x.i.pc;b.T(c,x.i.pc.F);a.ym(c);break;case 4:c=b.pa();a.it(c);break;case 5:c=new x.i.Jc;b.T(c,x.i.Jc.F);a.mQ(c);break;case 6:c=new x.i.Jc;b.T(c,x.i.Jc.F);a.Ss(c);break;default:b.ea()}}return a};\nx.i.Se.G=function(a,b){var c;c=a.eg();null!=c&&b.oa(1,c,x.i.pc.G);c=a.Gg();null!=c&&b.oa(2,c,x.i.pc.G);c=a.mk();null!=c&&b.oa(3,c,x.i.pc.G);c=l.u.D(a,4);null!=c&&b.ya(4,c);c=a.Tx();null!=c&&b.oa(5,c,x.i.Jc.G);c=a.Er();null!=c&&b.oa(6,c,x.i.Jc.G)};d=x.i.Se.prototype;d.eg=function(){return l.u.sa(this,x.i.pc,1)};d.Ng=function(a){l.u.Ca(this,1,a)};d.Gg=function(){return l.u.sa(this,x.i.pc,2)};d.Kg=function(a){l.u.Ca(this,2,a)};d.mk=function(){return l.u.sa(this,x.i.pc,3)};\nd.ym=function(a){l.u.Ca(this,3,a)};d.it=function(a){l.u.J(this,4,a)};d.Tx=function(){return l.u.sa(this,x.i.Jc,5)};d.mQ=function(a){l.u.Ca(this,5,a)};d.Er=function(){return l.u.sa(this,x.i.Jc,6)};d.Ss=function(a){l.u.Ca(this,6,a)};x.i.Se.K=function(a){return l.u.K(x.i.Se,a)};x.i.Gf=function(a){l.u.initialize(this,a,0,-1,x.i.Gf.na,null)};h.da(x.i.Gf,l.u);x.i.Gf.na=[2,4];\nl.u.ha&&(x.i.Gf.prototype.C=function(a){return x.i.Gf.C(a,this)},x.i.Gf.C=function(a,b){var c,e={pO:l.u.D(b,1),B$:l.u.Ka(b.Pz(),x.i.Cb.C,a),thresholds:(c=b.FA())&&x.i.Se.C(a,c),v5:l.u.D(b,4)};a&&(e.ja=b);return e});x.i.Gf.ia=function(a){a=new l.ba(a);var b=new x.i.Gf;return x.i.Gf.F(b,a)};\nx.i.Gf.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.$s(c);break;case 2:c=new x.i.Cb;b.T(c,x.i.Cb.F);a.TI(c);break;case 3:c=new x.i.Se;b.T(c,x.i.Se.F);a.hV(c);break;case 4:c=b.Aa();a.$H(c);break;default:b.ea()}}return a};x.i.Gf.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Ja(1,c);c=a.Pz();0<c.length&&b.Oa(2,c,x.i.Cb.G);c=a.FA();null!=c&&b.oa(3,c,x.i.Se.G);c=a.zL();0<c.length&&b.oc(4,c)};d=x.i.Gf.prototype;d.$s=function(a){l.u.J(this,1,a)};\nd.Pz=function(){return l.u.Ma(this,x.i.Cb,2)};d.TI=function(a,b){return l.u.La(this,2,a,x.i.Cb,b)};d.FA=function(){return l.u.sa(this,x.i.Se,3)};d.hV=function(a){l.u.Ca(this,3,a)};d.zL=function(){return l.u.D(this,4)};d.$H=function(a,b){l.u.ib(this,4,a,b)};x.i.Gf.K=function(a){return l.u.K(x.i.Gf,a)};x.i.Uf=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.Uf,l.u);\nl.u.ha&&(x.i.Uf.prototype.C=function(a){return x.i.Uf.C(a,this)},x.i.Uf.C=function(a,b){var c,e={Aba:(c=b.sA())&&x.i.za.oe.C(a,c)};a&&(e.ja=b);return e});x.i.Uf.ia=function(a){a=new l.ba(a);var b=new x.i.Uf;return x.i.Uf.F(b,a)};x.i.Uf.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.za.oe;b.T(c,x.i.za.oe.F);a.JU(c);break;default:b.ea()}}return a};x.i.Uf.G=function(a,b){a=a.sA();null!=a&&b.oa(1,a,x.i.za.oe.G)};\nx.i.Uf.prototype.sA=function(){return l.u.sa(this,x.i.za.oe,1)};x.i.Uf.prototype.JU=function(a){l.u.Ca(this,1,a)};x.i.Uf.K=function(a){return l.u.K(x.i.Uf,a)};x.i.Ra=function(a){l.u.initialize(this,a,0,-1,x.i.Ra.na,null)};h.da(x.i.Ra,l.u);x.i.Ra.na=[1];l.u.ha&&(x.i.Ra.prototype.C=function(a){return x.i.Ra.C(a,this)},x.i.Ra.C=function(a,b){var c={K8:l.u.Ka(b.sz(),x.i.Ra.zd.C,a)};a&&(c.ja=b);return c});x.i.Ra.ia=function(a){a=new l.ba(a);var b=new x.i.Ra;return x.i.Ra.F(b,a)};\nx.i.Ra.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.Ra.zd;b.T(c,x.i.Ra.zd.F);a.AI(c);break;default:b.ea()}}return a};x.i.Ra.G=function(a,b){a=a.sz();0<a.length&&b.Oa(1,a,x.i.Ra.zd.G)};x.i.Ra.prototype.sz=function(){return l.u.Ma(this,x.i.Ra.zd,1)};x.i.Ra.prototype.AI=function(a,b){return l.u.La(this,1,a,x.i.Ra.zd,b)};x.i.Ra.K=function(a){return l.u.K(x.i.Ra,a)};x.i.Ra.je=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.Ra.je,l.u);\nl.u.ha&&(x.i.Ra.je.prototype.C=function(a){return x.i.Ra.je.C(a,this)},x.i.Ra.je.C=function(a,b){var c={S5:l.u.D(b,1),Dda:l.u.Na(b,2)};a&&(c.ja=b);return c});x.i.Ra.je.ia=function(a){a=new l.ba(a);var b=new x.i.Ra.je;return x.i.Ra.je.F(b,a)};x.i.Ra.je.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.BR(c);break;case 2:c=b.pa();a.PV(c);break;default:b.ea()}}return a};x.i.Ra.je.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Ja(1,c);c=l.u.D(a,2);null!=c&&b.ya(2,c)};\nx.i.Ra.je.prototype.BR=function(a){l.u.J(this,1,a)};x.i.Ra.je.prototype.PV=function(a){l.u.J(this,2,a)};x.i.Ra.je.K=function(a){return l.u.K(x.i.Ra.je,a)};x.i.Ra.Wd=function(a){l.u.initialize(this,a,0,-1,x.i.Ra.Wd.na,null)};h.da(x.i.Ra.Wd,l.u);x.i.Ra.Wd.na=[1];l.u.ha&&(x.i.Ra.Wd.prototype.C=function(a){return x.i.Ra.Wd.C(a,this)},x.i.Ra.Wd.C=function(a,b){var c={kK:l.u.Ka(b.Ll(),x.i.Ra.je.C,a)};a&&(c.ja=b);return c});\nx.i.Ra.Wd.ia=function(a){a=new l.ba(a);var b=new x.i.Ra.Wd;return x.i.Ra.Wd.F(b,a)};x.i.Ra.Wd.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.Ra.je;b.T(c,x.i.Ra.je.F);a.Mq(c);break;default:b.ea()}}return a};x.i.Ra.Wd.G=function(a,b){a=a.Ll();0<a.length&&b.Oa(1,a,x.i.Ra.je.G)};x.i.Ra.Wd.prototype.Ll=function(){return l.u.Ma(this,x.i.Ra.je,1)};x.i.Ra.Wd.prototype.Mq=function(a,b){return l.u.La(this,1,a,x.i.Ra.je,b)};x.i.Ra.Wd.K=function(a){return l.u.K(x.i.Ra.Wd,a)};\nx.i.Ra.zd=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.Ra.zd,l.u);l.u.ha&&(x.i.Ra.zd.prototype.C=function(a){return x.i.Ra.zd.C(a,this)},x.i.Ra.zd.C=function(a,b){var c,e={key:l.u.D(b,1),value:(c=b.getValue())&&x.i.Ra.Wd.C(a,c)};a&&(e.ja=b);return e});x.i.Ra.zd.ia=function(a){a=new l.ba(a);var b=new x.i.Ra.zd;return x.i.Ra.zd.F(b,a)};\nx.i.Ra.zd.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.gS(c);break;case 2:c=new x.i.Ra.Wd;b.T(c,x.i.Ra.Wd.F);a.setValue(c);break;default:b.ea()}}return a};x.i.Ra.zd.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Ja(1,c);c=a.getValue();null!=c&&b.oa(2,c,x.i.Ra.Wd.G)};x.i.Ra.zd.prototype.getKey=function(){return l.u.D(this,1)};x.i.Ra.zd.prototype.gS=function(a){l.u.J(this,1,a)};x.i.Ra.zd.prototype.getValue=function(){return l.u.sa(this,x.i.Ra.Wd,2)};\nx.i.Ra.zd.prototype.setValue=function(a){l.u.Ca(this,2,a)};x.i.Ra.zd.K=function(a){return l.u.K(x.i.Ra.zd,a)};x.i.Sd=function(a){l.u.initialize(this,a,0,-1,x.i.Sd.na,null)};h.da(x.i.Sd,l.u);x.i.Sd.na=[2];l.u.ha&&(x.i.Sd.prototype.C=function(a){return x.i.Sd.C(a,this)},x.i.Sd.C=function(a,b){var c,e={info:(c=b.gz())&&x.i.Qb.C(a,c),Jm:l.u.Ka(b.bf(),x.i.Ea.C,a),error:l.u.D(b,3)};a&&(e.ja=b);return e});x.i.Sd.ia=function(a){a=new l.ba(a);var b=new x.i.Sd;return x.i.Sd.F(b,a)};\nx.i.Sd.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.Qb;b.T(c,x.i.Qb.F);a.ZR(c);break;case 2:c=new x.i.Ea;b.T(c,x.i.Ea.F);a.Eg(c);break;case 3:c=b.Aa();a.Jh(c);break;default:b.ea()}}return a};x.i.Sd.G=function(a,b){var c;c=a.gz();null!=c&&b.oa(1,c,x.i.Qb.G);c=a.bf();0<c.length&&b.Oa(2,c,x.i.Ea.G);c=l.u.D(a,3);null!=c&&b.Ja(3,c)};d=x.i.Sd.prototype;d.gz=function(){return l.u.sa(this,x.i.Qb,1)};d.ZR=function(a){l.u.Ca(this,1,a)};\nd.bf=function(){return l.u.Ma(this,x.i.Ea,2)};d.Eg=function(a,b){return l.u.La(this,2,a,x.i.Ea,b)};d.getError=function(){return l.u.D(this,3)};d.Jh=function(a){l.u.J(this,3,a)};x.i.Sd.K=function(a){return l.u.K(x.i.Sd,a)};x.i.wa=function(a){l.u.initialize(this,a,0,-1,x.i.wa.na,null)};h.da(x.i.wa,l.u);x.i.wa.na=[1,5,6];\nl.u.ha&&(x.i.wa.prototype.C=function(a){return x.i.wa.C(a,this)},x.i.wa.C=function(a,b){var c={yda:l.u.D(b,1),Vba:l.u.D(b,2),startTime:l.u.D(b,3),endTime:l.u.D(b,4),Cx:l.u.Ka(b.Zg(),x.i.wa.Qa.C,a),C5:l.u.Ka(b.Py(),x.i.wa.yd.C,a)};a&&(c.ja=b);return c});x.i.wa.ia=function(a){a=new l.ba(a);var b=new x.i.wa;return x.i.wa.F(b,a)};\nx.i.wa.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.CJ(c);break;case 2:c=b.Aa();a.XU(c);break;case 3:c=b.ee();a.vj(c);break;case 4:c=b.ee();a.sj(c);break;case 5:c=new x.i.wa.Qa;b.T(c,x.i.wa.Qa.F);a.sl(c);break;case 6:c=new x.i.wa.yd;b.T(c,x.i.wa.yd.F);a.cI(c);break;default:b.ea()}}return a};\nx.i.wa.G=function(a,b){var c;c=a.OM();0<c.length&&b.oc(1,c);c=l.u.D(a,2);null!=c&&b.Ja(2,c);c=l.u.D(a,3);null!=c&&b.ye(3,c);c=l.u.D(a,4);null!=c&&b.ye(4,c);c=a.Zg();0<c.length&&b.Oa(5,c,x.i.wa.Qa.G);c=a.Py();0<c.length&&b.Oa(6,c,x.i.wa.yd.G)};d=x.i.wa.prototype;d.OM=function(){return l.u.D(this,1)};d.CJ=function(a,b){l.u.ib(this,1,a,b)};d.XU=function(a){l.u.J(this,2,a)};d.getStartTime=function(){return l.u.D(this,3)};d.vj=function(a){l.u.J(this,3,a)};d.sj=function(a){l.u.J(this,4,a)};\nd.Zg=function(){return l.u.Ma(this,x.i.wa.Qa,5)};d.Us=function(a){l.u.mt(this,5,a)};d.sl=function(a,b){return l.u.La(this,5,a,x.i.wa.Qa,b)};d.Py=function(){return l.u.Ma(this,x.i.wa.yd,6)};d.cI=function(a,b){return l.u.La(this,6,a,x.i.wa.yd,b)};x.i.wa.K=function(a){return l.u.K(x.i.wa,a)};x.i.wa.Qa=function(a){l.u.initialize(this,a,0,-1,x.i.wa.Qa.na,null)};h.da(x.i.wa.Qa,l.u);x.i.wa.Qa.na=[6];\nl.u.ha&&(x.i.wa.Qa.prototype.C=function(a){return x.i.wa.Qa.C(a,this)},x.i.wa.Qa.C=function(a,b){var c,e={V5:l.u.D(b,1),D5:(c=b.Qy())&&x.i.wa.Qa.Uc.C(a,c),labels:(c=b.getLabels())&&x.i.wa.Qa.Uc.C(a,c),b8:l.u.Na(b,4),values:(c=b.Lc())&&x.i.wa.Qa.ue.C(a,c),n3:l.u.Ka(b.hy(),x.i.wa.Qa.ie.C,a)};a&&(e.ja=b);return e});x.i.wa.Qa.ia=function(a){a=new l.ba(a);var b=new x.i.wa.Qa;return x.i.wa.Qa.F(b,a)};\nx.i.wa.Qa.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.CR(c);break;case 2:c=new x.i.wa.Qa.Uc;b.T(c,x.i.wa.Qa.Uc.F);a.vR(c);break;case 3:c=new x.i.wa.Qa.Uc;b.T(c,x.i.wa.Qa.Uc.F);a.jS(c);break;case 4:c=b.pa();a.kS(c);break;case 5:c=new x.i.wa.Qa.ue;b.T(c,x.i.wa.Qa.ue.F);a.Yo(c);break;case 6:c=new x.i.wa.Qa.ie;b.T(c,x.i.wa.Qa.ie.F);a.GH(c);break;default:b.ea()}}return a};\nx.i.wa.Qa.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Ja(1,c);c=a.Qy();null!=c&&b.oa(2,c,x.i.wa.Qa.Uc.G);c=a.getLabels();null!=c&&b.oa(3,c,x.i.wa.Qa.Uc.G);c=l.u.D(a,4);null!=c&&b.ya(4,c);c=a.Lc();null!=c&&b.oa(5,c,x.i.wa.Qa.ue.G);c=a.hy();0<c.length&&b.Oa(6,c,x.i.wa.Qa.ie.G)};d=x.i.wa.Qa.prototype;d.Ah=function(){return l.u.D(this,1)};d.CR=function(a){l.u.J(this,1,a)};d.Qy=function(){return l.u.sa(this,x.i.wa.Qa.Uc,2)};d.vR=function(a){l.u.Ca(this,2,a)};\nd.getLabels=function(){return l.u.sa(this,x.i.wa.Qa.Uc,3)};d.jS=function(a){l.u.Ca(this,3,a)};d.kS=function(a){l.u.J(this,4,a)};d.Lc=function(){return l.u.sa(this,x.i.wa.Qa.ue,5)};d.Yo=function(a){l.u.Ca(this,5,a)};d.hy=function(){return l.u.Ma(this,x.i.wa.Qa.ie,6)};d.GH=function(a,b){return l.u.La(this,6,a,x.i.wa.Qa.ie,b)};x.i.wa.Qa.K=function(a){return l.u.K(x.i.wa.Qa,a)};x.i.wa.Qa.ie=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.wa.Qa.ie,l.u);\nl.u.ha&&(x.i.wa.Qa.ie.prototype.C=function(a){return x.i.wa.Qa.ie.C(a,this)},x.i.wa.Qa.ie.C=function(a,b){var c={UK:l.u.Na(b,1),gaa:l.u.Na(b,2)};a&&(c.ja=b);return c});x.i.wa.Qa.ie.ia=function(a){a=new l.ba(a);var b=new x.i.wa.Qa.ie;return x.i.wa.Qa.ie.F(b,a)};x.i.wa.Qa.ie.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.pa();a.Ts(c);break;case 2:c=b.pa();a.nU(c);break;default:b.ea()}}return a};\nx.i.wa.Qa.ie.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.ya(1,c);c=l.u.D(a,2);null!=c&&b.ya(2,c)};x.i.wa.Qa.ie.prototype.Ts=function(a){l.u.J(this,1,a)};x.i.wa.Qa.ie.prototype.nU=function(a){l.u.J(this,2,a)};x.i.wa.Qa.ie.K=function(a){return l.u.K(x.i.wa.Qa.ie,a)};x.i.wa.Qa.ue=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.wa.Qa.ue,l.u);\nl.u.ha&&(x.i.wa.Qa.ue.prototype.C=function(a){return x.i.wa.Qa.ue.C(a,this)},x.i.wa.Qa.ue.C=function(a,b){var c={sum:l.u.Na(b,1),Pw:l.u.Na(b,2),$ba:l.u.Na(b,3)};a&&(c.ja=b);return c});x.i.wa.Qa.ue.ia=function(a){a=new l.ba(a);var b=new x.i.wa.Qa.ue;return x.i.wa.Qa.ue.F(b,a)};x.i.wa.Qa.ue.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.pa();a.wj(c);break;case 2:c=b.pa();a.iQ(c);break;case 3:c=b.pa();a.$U(c);break;default:b.ea()}}return a};\nx.i.wa.Qa.ue.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.ya(1,c);c=l.u.D(a,2);null!=c&&b.ya(2,c);c=l.u.D(a,3);null!=c&&b.ya(3,c)};x.i.wa.Qa.ue.prototype.wj=function(a){l.u.J(this,1,a)};x.i.wa.Qa.ue.prototype.iQ=function(a){l.u.J(this,2,a)};x.i.wa.Qa.ue.prototype.$U=function(a){l.u.J(this,3,a)};x.i.wa.Qa.ue.K=function(a){return l.u.K(x.i.wa.Qa.ue,a)};x.i.wa.Qa.Uc=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.wa.Qa.Uc,l.u);\nl.u.ha&&(x.i.wa.Qa.Uc.prototype.C=function(a){return x.i.wa.Qa.Uc.C(a,this)},x.i.wa.Qa.Uc.C=function(a,b){var c={sum:l.u.Na(b,1),j6:l.u.Na(b,2),k6:l.u.Na(b,3)};a&&(c.ja=b);return c});x.i.wa.Qa.Uc.ia=function(a){a=new l.ba(a);var b=new x.i.wa.Qa.Uc;return x.i.wa.Qa.Uc.F(b,a)};x.i.wa.Qa.Uc.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.pa();a.wj(c);break;case 2:c=b.pa();a.GR(c);break;case 3:c=b.pa();a.HR(c);break;default:b.ea()}}return a};\nx.i.wa.Qa.Uc.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.ya(1,c);c=l.u.D(a,2);null!=c&&b.ya(2,c);c=l.u.D(a,3);null!=c&&b.ya(3,c)};x.i.wa.Qa.Uc.prototype.wj=function(a){l.u.J(this,1,a)};x.i.wa.Qa.Uc.prototype.GR=function(a){l.u.J(this,2,a)};x.i.wa.Qa.Uc.prototype.HR=function(a){l.u.J(this,3,a)};x.i.wa.Qa.Uc.K=function(a){return l.u.K(x.i.wa.Qa.Uc,a)};x.i.wa.yd=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.wa.yd,l.u);\nl.u.ha&&(x.i.wa.yd.prototype.C=function(a){return x.i.wa.yd.C(a,this)},x.i.wa.yd.C=function(a,b){var c={count:l.u.D(b,1),sum:l.u.Na(b,2),i6:l.u.Na(b,3)};a&&(c.ja=b);return c});x.i.wa.yd.ia=function(a){a=new l.ba(a);var b=new x.i.wa.yd;return x.i.wa.yd.F(b,a)};x.i.wa.yd.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Ya();a.SQ(c);break;case 2:c=b.pa();a.wj(c);break;case 3:c=b.pa();a.FR(c);break;default:b.ea()}}return a};\nx.i.wa.yd.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.$a(1,c);c=l.u.D(a,2);null!=c&&b.ya(2,c);c=l.u.D(a,3);null!=c&&b.ya(3,c)};x.i.wa.yd.prototype.zh=function(){return l.u.D(this,1)};x.i.wa.yd.prototype.SQ=function(a){l.u.J(this,1,a)};x.i.wa.yd.prototype.wj=function(a){l.u.J(this,2,a)};x.i.wa.yd.prototype.FR=function(a){l.u.J(this,3,a)};x.i.wa.yd.K=function(a){return l.u.K(x.i.wa.yd,a)};x.i.le=function(a){l.u.initialize(this,a,0,-1,x.i.le.na,null)};h.da(x.i.le,l.u);x.i.le.na=[7];\nl.u.ha&&(x.i.le.prototype.C=function(a){return x.i.le.C(a,this)},x.i.le.C=function(a,b){var c,e={G4:(c=b.zy())&&x.i.qe.C(a,c),M9:l.u.D(b,2),length:l.u.D(b,3),B9:l.u.D(b,4),i$:l.u.D(b,5),numColumns:l.u.D(b,6),b4:l.u.Ka(b.sy(),x.i.Link.C,a)};a&&(e.ja=b);return e});x.i.le.ia=function(a){a=new l.ba(a);var b=new x.i.le;return x.i.le.F(b,a)};\nx.i.le.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.qe;b.T(c,x.i.qe.F);a.ZQ(c);break;case 2:c=b.Ya();a.pT(c);break;case 3:c=b.ad();a.nS(c);break;case 4:c=b.ee();a.kT(c);break;case 5:c=b.ee();a.ET(c);break;case 6:c=b.Ya();a.mT(c);break;case 7:c=new x.i.Link;b.T(c,x.i.Link.F);a.LH(c);break;default:b.ea()}}return a};\nx.i.le.G=function(a,b){var c;c=a.zy();null!=c&&b.oa(1,c,x.i.qe.G);c=l.u.D(a,2);null!=c&&b.$a(2,c);c=l.u.D(a,3);null!=c&&b.td(3,c);c=l.u.D(a,4);null!=c&&b.ye(4,c);c=l.u.D(a,5);null!=c&&b.ye(5,c);c=l.u.D(a,6);null!=c&&b.$a(6,c);c=a.sy();0<c.length&&b.Oa(7,c,x.i.Link.G)};d=x.i.le.prototype;d.zy=function(){return l.u.sa(this,x.i.qe,1)};d.ZQ=function(a){l.u.Ca(this,1,a)};d.pT=function(a){l.u.J(this,2,a)};d.nS=function(a){l.u.J(this,3,a)};d.kT=function(a){l.u.J(this,4,a)};\nd.ET=function(a){l.u.J(this,5,a)};d.mT=function(a){l.u.J(this,6,a)};d.sy=function(){return l.u.Ma(this,x.i.Link,7)};d.LH=function(a,b){return l.u.La(this,7,a,x.i.Link,b)};x.i.le.K=function(a){return l.u.K(x.i.le,a)};x.i.Df=function(a){l.u.initialize(this,a,0,-1,x.i.Df.na,null)};h.da(x.i.Df,l.u);x.i.Df.na=[3,4];\nl.u.ha&&(x.i.Df.prototype.C=function(a){return x.i.Df.C(a,this)},x.i.Df.C=function(a,b){var c,e={name:l.u.D(b,1),Zq:l.u.D(b,2),UN:l.u.Ka(b.Vl(),x.i.Link.C,a),qO:l.u.D(b,4),gx:(c=b.qy())&&x.i.le.C(a,c)};a&&(e.ja=b);return e});x.i.Df.ia=function(a){a=new l.ba(a);var b=new x.i.Df;return x.i.Df.F(b,a)};\nx.i.Df.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.fe(c);break;case 2:c=b.Aa();a.rj(c);break;case 3:c=new x.i.Link;b.T(c,x.i.Link.F);a.Qq(c);break;case 4:c=b.Aa();a.Rq(c);break;case 5:c=new x.i.le;b.T(c,x.i.le.F);a.MQ(c);break;default:b.ea()}}return a};x.i.Df.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Ja(1,c);c=l.u.D(a,2);null!=c&&b.Ja(2,c);c=a.Vl();0<c.length&&b.Oa(3,c,x.i.Link.G);c=a.Ir();0<c.length&&b.oc(4,c);c=a.qy();null!=c&&b.oa(5,c,x.i.le.G)};d=x.i.Df.prototype;\nd.getName=function(){return l.u.D(this,1)};d.fe=function(a){l.u.J(this,1,a)};d.Jl=function(){return l.u.D(this,2)};d.rj=function(a){l.u.J(this,2,a)};d.Vl=function(){return l.u.Ma(this,x.i.Link,3)};d.Qq=function(a,b){return l.u.La(this,3,a,x.i.Link,b)};d.Ir=function(){return l.u.D(this,4)};d.Rq=function(a,b){l.u.ib(this,4,a,b)};d.qy=function(){return l.u.sa(this,x.i.le,5)};d.MQ=function(a){l.u.Ca(this,5,a)};x.i.Df.K=function(a){return l.u.K(x.i.Df,a)};\nx.i.Da=function(a){l.u.initialize(this,a,0,-1,x.i.Da.na,null)};h.da(x.i.Da,l.u);x.i.Da.na=[1,2];l.u.ha&&(x.i.Da.prototype.C=function(a){return x.i.Da.C(a,this)},x.i.Da.C=function(a,b){var c,e={V7:l.u.Ka(b.kz(),x.i.Da.ld.C,a),K4:l.u.Ka(b.Dy(),x.i.Da.fd.C,a),rba:(c=b.qA())&&x.i.Da.Ad.C(a,c)};a&&(e.ja=b);return e});x.i.Da.ia=function(a){a=new l.ba(a);var b=new x.i.Da;return x.i.Da.F(b,a)};\nx.i.Da.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.Da.ld;b.T(c,x.i.Da.ld.F);a.uI(c);break;case 2:c=new x.i.Da.fd;b.T(c,x.i.Da.fd.F);a.RH(c);break;case 3:c=new x.i.Da.Ad;b.T(c,x.i.Da.Ad.F);a.GU(c);break;default:b.ea()}}return a};x.i.Da.G=function(a,b){var c;c=a.kz();0<c.length&&b.Oa(1,c,x.i.Da.ld.G);c=a.Dy();0<c.length&&b.Oa(2,c,x.i.Da.fd.G);c=a.qA();null!=c&&b.oa(3,c,x.i.Da.Ad.G)};d=x.i.Da.prototype;d.kz=function(){return l.u.Ma(this,x.i.Da.ld,1)};\nd.uI=function(a,b){return l.u.La(this,1,a,x.i.Da.ld,b)};d.Dy=function(){return l.u.Ma(this,x.i.Da.fd,2)};d.RH=function(a,b){return l.u.La(this,2,a,x.i.Da.fd,b)};d.qA=function(){return l.u.sa(this,x.i.Da.Ad,3)};d.GU=function(a){l.u.Ca(this,3,a)};x.i.Da.K=function(a){return l.u.K(x.i.Da,a)};x.i.Da.sc=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.Da.sc,l.u);\nl.u.ha&&(x.i.Da.sc.prototype.C=function(a){return x.i.Da.sc.C(a,this)},x.i.Da.sc.C=function(a,b){var c,e={state:l.u.D(b,1),uba:l.u.D(b,2),n8:l.u.D(b,3),link:(c=b.pz())&&x.i.Link.C(a,c)};a&&(e.ja=b);return e});x.i.Da.sc.ia=function(a){a=new l.ba(a);var b=new x.i.Da.sc;return x.i.Da.sc.F(b,a)};\nx.i.Da.sc.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.we();a.setState(c);break;case 2:c=b.Aa();a.HU(c);break;case 3:c=b.Aa();a.rS(c);break;case 4:c=new x.i.Link;b.T(c,x.i.Link.F);a.oS(c);break;default:b.ea()}}return a};x.i.Da.sc.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.xe(1,c);c=l.u.D(a,2);null!=c&&b.Ja(2,c);c=l.u.D(a,3);null!=c&&b.Ja(3,c);c=a.pz();null!=c&&b.oa(4,c,x.i.Link.G)};d=x.i.Da.sc.prototype;d.getState=function(){return l.u.D(this,1)};\nd.setState=function(a){l.u.J(this,1,a)};d.HU=function(a){l.u.J(this,2,a)};d.rS=function(a){l.u.J(this,3,a)};d.pz=function(){return l.u.sa(this,x.i.Link,4)};d.oS=function(a){l.u.Ca(this,4,a)};x.i.Da.sc.K=function(a){return l.u.K(x.i.Da.sc,a)};x.i.Da.sc.$Z={YX:0,n_:1,AX:2,pX:3,LY:4};x.i.Da.ld=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.Da.ld,l.u);\nl.u.ha&&(x.i.Da.ld.prototype.C=function(a){return x.i.Da.ld.C(a,this)},x.i.Da.ld.C=function(a,b){var c,e={type:l.u.D(b,1),BC:(c=b.li())&&x.i.Da.sc.C(a,c)};a&&(e.ja=b);return e});x.i.Da.ld.ia=function(a){a=new l.ba(a);var b=new x.i.Da.ld;return x.i.Da.ld.F(b,a)};x.i.Da.ld.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.we();a.yf(c);break;case 2:c=new x.i.Da.sc;b.T(c,x.i.Da.sc.F);a.Am(c);break;default:b.ea()}}return a};\nx.i.Da.ld.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.xe(1,c);c=a.li();null!=c&&b.oa(2,c,x.i.Da.sc.G)};x.i.Da.ld.prototype.mi=function(){return l.u.D(this,1)};x.i.Da.ld.prototype.yf=function(a){l.u.J(this,1,a)};x.i.Da.ld.prototype.li=function(){return l.u.sa(this,x.i.Da.sc,2)};x.i.Da.ld.prototype.Am=function(a){l.u.Ca(this,2,a)};x.i.Da.ld.K=function(a){return l.u.K(x.i.Da.ld,a)};x.i.Da.ld.rY={JZ:0,h_:1,MX:2,SD:3,OY:4,CX:5,jX:6};x.i.Da.fd=function(a){l.u.initialize(this,a,0,-1,null,null)};\nh.da(x.i.Da.fd,l.u);l.u.ha&&(x.i.Da.fd.prototype.C=function(a){return x.i.Da.fd.C(a,this)},x.i.Da.fd.C=function(a,b){var c,e={type:l.u.D(b,1),BC:(c=b.li())&&x.i.Da.sc.C(a,c)};a&&(e.ja=b);return e});x.i.Da.fd.ia=function(a){a=new l.ba(a);var b=new x.i.Da.fd;return x.i.Da.fd.F(b,a)};x.i.Da.fd.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.we();a.yf(c);break;case 2:c=new x.i.Da.sc;b.T(c,x.i.Da.sc.F);a.Am(c);break;default:b.ea()}}return a};\nx.i.Da.fd.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.xe(1,c);c=a.li();null!=c&&b.oa(2,c,x.i.Da.sc.G)};x.i.Da.fd.prototype.mi=function(){return l.u.D(this,1)};x.i.Da.fd.prototype.yf=function(a){l.u.J(this,1,a)};x.i.Da.fd.prototype.li=function(){return l.u.sa(this,x.i.Da.sc,2)};x.i.Da.fd.prototype.Am=function(a){l.u.Ca(this,2,a)};x.i.Da.fd.K=function(a){return l.u.K(x.i.Da.fd,a)};x.i.Da.fd.lD={KZ:0,HY:1,NZ:2,OZ:3,GX:4,MZ:5};x.i.Da.Ad=function(a){l.u.initialize(this,a,0,-1,null,null)};\nh.da(x.i.Da.Ad,l.u);l.u.ha&&(x.i.Da.Ad.prototype.C=function(a){return x.i.Da.Ad.C(a,this)},x.i.Da.Ad.C=function(a,b){var c,e={type:l.u.D(b,1),BC:(c=b.li())&&x.i.Da.sc.C(a,c)};a&&(e.ja=b);return e});x.i.Da.Ad.ia=function(a){a=new l.ba(a);var b=new x.i.Da.Ad;return x.i.Da.Ad.F(b,a)};x.i.Da.Ad.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.we();a.yf(c);break;case 2:c=new x.i.Da.sc;b.T(c,x.i.Da.sc.F);a.Am(c);break;default:b.ea()}}return a};\nx.i.Da.Ad.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.xe(1,c);c=a.li();null!=c&&b.oa(2,c,x.i.Da.sc.G)};x.i.Da.Ad.prototype.mi=function(){return l.u.D(this,1)};x.i.Da.Ad.prototype.yf=function(a){l.u.J(this,1,a)};x.i.Da.Ad.prototype.li=function(){return l.u.sa(this,x.i.Da.sc,2)};x.i.Da.Ad.prototype.Am=function(a){l.u.Ca(this,2,a)};x.i.Da.Ad.K=function(a){return l.u.K(x.i.Da.Ad,a)};x.i.Da.Ad.UZ={BY:0,RX:1,iX:2};x.i.jd=function(a){l.u.initialize(this,a,0,-1,x.i.jd.na,null)};h.da(x.i.jd,l.u);\nx.i.jd.na=[1];l.u.ha&&(x.i.jd.prototype.C=function(a){return x.i.jd.C(a,this)},x.i.jd.C=function(a,b){var c={Zba:l.u.D(b,1),state:l.u.D(b,2)};a&&(c.ja=b);return c});x.i.jd.ia=function(a){a=new l.ba(a);var b=new x.i.jd;return x.i.jd.F(b,a)};x.i.jd.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.lJ(c);break;case 2:c=b.Aa();a.setState(c);break;default:b.ea()}}return a};x.i.jd.G=function(a,b){var c;c=a.uM();0<c.length&&b.oc(1,c);c=l.u.D(a,2);null!=c&&b.Ja(2,c)};\nx.i.jd.prototype.uM=function(){return l.u.D(this,1)};x.i.jd.prototype.lJ=function(a,b){l.u.ib(this,1,a,b)};x.i.jd.prototype.getState=function(){return l.u.D(this,2)};x.i.jd.prototype.setState=function(a){l.u.J(this,2,a)};x.i.jd.K=function(a){return l.u.K(x.i.jd,a)};x.i.Ee=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.Ee,l.u);\nl.u.ha&&(x.i.Ee.prototype.C=function(a){return x.i.Ee.C(a,this)},x.i.Ee.C=function(a,b){var c,e={Sba:(c=b.xA())&&x.i.Hc.C(a,c),u5:l.u.D(b,2),k5:(c=b.Jy())&&x.i.jd.C(a,c)};a&&(e.ja=b);return e});x.i.Ee.ia=function(a){a=new l.ba(a);var b=new x.i.Ee;return x.i.Ee.F(b,a)};x.i.Ee.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.Hc;b.T(c,x.i.Hc.F);a.UU(c);break;case 2:c=b.Aa();a.rR(c);break;case 3:c=new x.i.jd;b.T(c,x.i.jd.F);a.nR(c);break;default:b.ea()}}return a};\nx.i.Ee.G=function(a,b){var c;c=a.xA();null!=c&&b.oa(1,c,x.i.Hc.G);c=l.u.D(a,2);null!=c&&b.Ja(2,c);c=a.Jy();null!=c&&b.oa(3,c,x.i.jd.G)};d=x.i.Ee.prototype;d.xA=function(){return l.u.sa(this,x.i.Hc,1)};d.UU=function(a){l.u.Ca(this,1,a)};d.rR=function(a){l.u.J(this,2,a)};d.Jy=function(){return l.u.sa(this,x.i.jd,3)};d.nR=function(a){l.u.Ca(this,3,a)};x.i.Ee.K=function(a){return l.u.K(x.i.Ee,a)};x.i.Ve=function(a){l.u.initialize(this,a,0,-1,x.i.Ve.na,null)};h.da(x.i.Ve,l.u);x.i.Ve.na=[1];\nl.u.ha&&(x.i.Ve.prototype.C=function(a){return x.i.Ve.C(a,this)},x.i.Ve.C=function(a,b){var c={NN:l.u.Ka(b.Ul(),x.i.Ee.C,a),error:l.u.D(b,2)};a&&(c.ja=b);return c});x.i.Ve.ia=function(a){a=new l.ba(a);var b=new x.i.Ve;return x.i.Ve.F(b,a)};x.i.Ve.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=new x.i.Ee;b.T(c,x.i.Ee.F);a.Pq(c);break;case 2:c=b.Aa();a.Jh(c);break;default:b.ea()}}return a};\nx.i.Ve.G=function(a,b){var c;c=a.Ul();0<c.length&&b.Oa(1,c,x.i.Ee.G);c=l.u.D(a,2);null!=c&&b.Ja(2,c)};x.i.Ve.prototype.Ul=function(){return l.u.Ma(this,x.i.Ee,1)};x.i.Ve.prototype.Pq=function(a,b){return l.u.La(this,1,a,x.i.Ee,b)};x.i.Ve.prototype.getError=function(){return l.u.D(this,2)};x.i.Ve.prototype.Jh=function(a){l.u.J(this,2,a)};x.i.Ve.K=function(a){return l.u.K(x.i.Ve,a)};x.i.bb=function(a){l.u.initialize(this,a,0,-1,x.i.bb.na,null)};h.da(x.i.bb,l.u);x.i.bb.na=[3,4];\nl.u.ha&&(x.i.bb.prototype.C=function(a){return x.i.bb.C(a,this)},x.i.bb.C=function(a,b){var c={tca:l.u.D(b,1),g5:l.u.D(b,2),d5:l.u.D(b,3),Oaa:l.u.Ka(b.jA(),x.i.bb.zb.C,a)};a&&(c.ja=b);return c});x.i.bb.ia=function(a){a=new l.ba(a);var b=new x.i.bb;return x.i.bb.F(b,a)};x.i.bb.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.fV(c);break;case 2:c=b.Aa();a.mR(c);break;case 3:c=b.Aa();a.WH(c);break;case 4:c=new x.i.bb.zb;b.T(c,x.i.bb.zb.F);a.addRows(c);break;default:b.ea()}}return a};\nx.i.bb.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Ja(1,c);c=l.u.D(a,2);null!=c&&b.Ja(2,c);c=a.uL();0<c.length&&b.oc(3,c);c=a.jA();0<c.length&&b.Oa(4,c,x.i.bb.zb.G)};d=x.i.bb.prototype;d.fV=function(a){l.u.J(this,1,a)};d.mR=function(a){l.u.J(this,2,a)};d.uL=function(){return l.u.D(this,3)};d.WH=function(a,b){l.u.ib(this,3,a,b)};d.jA=function(){return l.u.Ma(this,x.i.bb.zb,4)};d.addRows=function(a,b){return l.u.La(this,4,a,x.i.bb.zb,b)};x.i.bb.K=function(a){return l.u.K(x.i.bb,a)};\nx.i.bb.zb=function(a){l.u.initialize(this,a,0,-1,x.i.bb.zb.na,null)};h.da(x.i.bb.zb,l.u);x.i.bb.zb.na=[2];l.u.ha&&(x.i.bb.zb.prototype.C=function(a){return x.i.bb.zb.C(a,this)},x.i.bb.zb.C=function(a,b){var c={f5:l.u.D(b,1),r5:l.u.Ka(b.Ly(),x.i.bb.zb.Ld.C,a)};a&&(c.ja=b);return c});x.i.bb.zb.ia=function(a){a=new l.ba(a);var b=new x.i.bb.zb;return x.i.bb.zb.F(b,a)};\nx.i.bb.zb.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.lR(c);break;case 2:c=new x.i.bb.zb.Ld;b.T(c,x.i.bb.zb.Ld.F);a.ZH(c);break;default:b.ea()}}return a};x.i.bb.zb.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Ja(1,c);c=a.Ly();0<c.length&&b.Oa(2,c,x.i.bb.zb.Ld.G)};x.i.bb.zb.prototype.lR=function(a){l.u.J(this,1,a)};x.i.bb.zb.prototype.Ly=function(){return l.u.Ma(this,x.i.bb.zb.Ld,2)};x.i.bb.zb.prototype.ZH=function(a,b){return l.u.La(this,2,a,x.i.bb.zb.Ld,b)};\nx.i.bb.zb.K=function(a){return l.u.K(x.i.bb.zb,a)};x.i.bb.zb.Ld=function(a){l.u.initialize(this,a,0,-1,null,null)};h.da(x.i.bb.zb.Ld,l.u);l.u.ha&&(x.i.bb.zb.Ld.prototype.C=function(a){return x.i.bb.zb.Ld.C(a,this)},x.i.bb.zb.Ld.C=function(a,b){var c={aj:l.u.D(b,1),UK:l.u.D(b,2)};a&&(c.ja=b);return c});x.i.bb.zb.Ld.ia=function(a){a=new l.ba(a);var b=new x.i.bb.zb.Ld;return x.i.bb.zb.Ld.F(b,a)};\nx.i.bb.zb.Ld.F=function(a,b){for(;b.fa()&&!b.ga();){var c=b.ka;switch(c){case 1:c=b.Aa();a.xf(c);break;case 2:c=b.Aa();a.Ts(c);break;default:b.ea()}}return a};x.i.bb.zb.Ld.G=function(a,b){var c;c=l.u.D(a,1);null!=c&&b.Ja(1,c);c=l.u.D(a,2);null!=c&&b.Ja(2,c)};x.i.bb.zb.Ld.prototype.Hg=function(){return l.u.D(this,1)};x.i.bb.zb.Ld.prototype.xf=function(a){l.u.J(this,1,a)};x.i.bb.zb.Ld.prototype.Ts=function(a){l.u.J(this,2,a)};x.i.bb.zb.Ld.K=function(a){return l.u.K(x.i.bb.zb.Ld,a)};D.data.Ua={};\nD.data.Ua.Xu={RD:\"k\",HE:\"totalPositives\",Li:\"value\"};D.data.Ua.Up={OE:0,FLOAT:1,op:2,Uk:3,an:4,Gp:5};D.data.Ua.pp={zu:\"lowerBound\",gv:\"upperBound\",Li:\"value\"};D.data.Ua.AP=function(a,b){var c=D.data.Ua.pp,c=a[c.Li]-b[c.Li];return{f:D.data.Ua.lx(a,b,c,\"bounded-value\"),v:c}};D.data.Ua.GP=function(a,b){var c=Math.min(a.length,b.length)-1,e=D.data.Ua.Lr(a,c)-D.data.Ua.Lr(b,c);return{f:D.data.Ua.lx([a[c]],[b[c]],e,\"precision-at-k\"),v:e}};D.data.Ua.Lr=function(a,b){var c=D.data.Ua.Xu;return a[b][c.Li]};\nD.data.Ua.CP=function(a,b){return D.data.Ua.jC(a-b,a,b)};D.data.Ua.jC=function(a,b,c){return{f:D.data.Ua.mx(D.data.Ua.ui(b),D.data.Ua.ui(c),D.data.Ua.ui(a)),v:a}};D.data.Ua.mx=function(a,b,c,e){return\"\\x3cmetric-diff diff\\x3d\"+c+\" \"+D.data.Ua.mr(\"first\",a)+\" \"+D.data.Ua.mr(\"second\",b)+(e?\" type\\x3d\"+e:\"\")+\"\\x3e\\x3c/metric-diff\\x3e\"};D.data.Ua.lx=function(a,b,c,e){return D.data.Ua.mx(JSON.stringify(a),JSON.stringify(b),D.data.Ua.ui(c),e)};D.data.Ua.mr=function(a,b){return a+'\\x3d\"'+h.ca.$r(b)+'\"'};\nD.data.Ua.lC=function(a){return{f:\"Unsupported: \"+JSON.stringify(a),v:0}};D.data.Ua.iC=function(a){return{f:D.data.Ua.ui(a),v:a}};D.data.Ua.DP=function(a){return{f:\"\"+a,v:a}};D.data.Ua.HP=function(a){var b=a.lastIndexOf(\"_\")>a.lastIndexOf(\":\")?\"_\":\":\",b=a.split(b),b=1<b.length?parseFloat(b[b.length-1]):NaN;return{f:a,v:isNaN(b)?a:b}};D.data.Ua.kC=function(a){return{f:a,v:a}};\nD.data.Ua.zP=function(a){var b=D.data.Ua.pp,c=a[b.Li];return{f:\"\\x3cbounded-value value\\x3d\"+D.data.Ua.ui(c)+\" lower-bound\\x3d\"+D.data.Ua.ui(a[b.zu])+\" upper-bound\\x3d\"+D.data.Ua.ui(a[b.gv])+\"\\x3e\\x3c/bounded-value\\x3e\",v:c}};D.data.Ua.Caa=function(){return{f:\"Null\",v:0}};D.data.Ua.ui=function(a){return a.toFixed(D.Nh)};D.data.Ua.FP=function(a){return{f:\"\\x3cprecision-at-k \"+D.data.Ua.mr(\"data\",JSON.stringify(a))+\"\\x3e\\x3c/precision-at-k\\x3e\",v:D.data.Ua.Lr(a,0)}};\nD.data.Ua.mC=function(a){var b=D.data.Ua.Up;switch(D.data.Ua.WA(a)){case b.op:return D.data.Ua.zP(a);case b.FLOAT:return D.data.Ua.iC(a);case b.Uk:return D.data.Ua.kC(a);case b.an:return D.data.Ua.IP(a.first,a.second,a.R$);case b.Gp:return D.data.Ua.FP(a);default:return h.Ch(a)?D.data.Ua.lC(a):{f:\"Null\",v:0}}};\nD.data.Ua.IP=function(a,b,c){var e=D.data.Ua.Up;switch(D.data.Ua.WA(a)){case e.op:return D.data.Ua.AP(a,b);case e.Gp:return D.data.Ua.GP(a,b);case e.FLOAT:return h.Pe(c)?D.data.Ua.jC(c,a,b):D.data.Ua.CP(a,b);default:return h.Ch(a)&&h.Ch(b)?D.data.Ua.lC({A:a,B:b}):{f:\"Null\",v:0}}};\nD.data.Ua.WA=function(a){var b=D.data.Ua.Up,c=D.data.Ua.pp;if(h.ni(a))return b.FLOAT;if(h.Hb(a))return b.Uk;if(h.mj(a)){if(h.Pe(a[c.zu])&&h.Pe(a[c.gv])&&h.Pe(a[c.Li]))return b.op;if(h.Pe(a.first)&&h.Pe(a.second))return b.an;if(D.data.Ua.BN(a))return b.Gp}return b.OE};D.data.Ua.BN=function(a){var b=D.data.Ua.Xu;if(Array.isArray(a)){for(var c=0<a.length,e=0,g;c&&(g=a[e]);e++)c=g[b.RD]&&g[b.HE]&&h.Ch(g[b.Li]);return c}return!1};\nD.data.Ua.JP=function(a,b,c){return h.Ch(a)?c?D.data.Ua.KP(b.Gw(a,c),c.type):D.data.Ua.mC(a):{f:\"Null\",v:0}};D.data.Ua.KP=function(a,b){var c=D.Pk;switch(b){case c.Mp:return D.data.Ua.HP(a);case c.INT:return D.data.Ua.DP(a);case c.FLOAT:return D.data.Ua.iC(a);case c.an:return D.data.Ua.mC(a);default:return D.data.Ua.kC(a)}};\nPolymer({is:\"gviz-loader\",properties:{staticState_:{type:Object,value:{ms:0,bB:0,CB:[],cB:[]}}},Io:function(a){var b=this;window.google&&window.google.load?(this.staticState_.ms=1,this.GB(a)):(this.staticState_.CB.push(a),this.staticState_.ms||(this.staticState_.ms=1,window.__googleApiLoaderCallbackForGvizLoader=function(){b.staticState_.CB.forEach(function(a){b.GB(a)})},a=document.createElement(\"script\"),a.type=\"text/javascript\",a.async=!0,a.src=\"https://www.google.com/jsapi?callback\\x3d__googleApiLoaderCallbackForGvizLoader\",\ndocument.head.appendChild(a)))},GB:function(a){var b=this;window.google&&window.google.visualization&&window.google.visualization.ColumnChart?a():(this.staticState_.cB.push(a),this.staticState_.bB||(this.staticState_.bB=1,window.google.load(\"visualization\",\"1\",{packages:[\"corechart\",\"table\"],callback:function(){b.staticState_.cB.forEach(function(a){a()})}})))},load:function(a){this.Io(function(){a&&a()})},create:function(a,b){var c=this;return{then:function(a){c.Io(function(){b?a(new google.visualization.ColumnChart(b)):\na()})}}},Dl:function(a){var b=this;return{then:function(c){b.Io(function(){c(google.visualization.arrayToDataTable(a))})}}},no:function(a){var b=this;return{then:function(c){b.Io(function(){c(new google.visualization.DataView(a))})}}}});var V={Ij:{}};V.Ij.Ij={};V.Ph={};V.Ph.Ph={};\n(function(){var a={},b={},c=null;Polymer.Ph=function(a){if(a)for(var b in a)switch(b){case \"type\":case \"key\":case \"value\":this[b]=a[b]}};Polymer.Ph=Polymer({is:\"iron-meta\",properties:{type:{type:String,value:\"default\",observer:\"xw\"},key:{type:String,observer:\"Qv\"},value:{type:Object,notify:!0,observer:\"Iq\"},self:{type:Boolean,observer:\"s1\"},list:{type:Array,notify:!0}},hostAttributes:{hidden:!0},factoryImpl:function(a){if(a)for(var b in a)switch(b){case \"type\":case \"key\":case \"value\":this[b]=a[b]}},\ncreated:function(){this.mG=a;this.lG=b},Qv:function(a,b){this.jw(b)},Iq:function(){this.jw(this.key)},s1:function(a){a&&(this.value=this)},xw:function(c){this.yw(this.key);a[c]||(a[c]={});this.th=a[c];b[c]||(b[c]=[]);this.list=b[c];this.gw(this.key,this.value)},er:function(a){return this.th&&this.th[a]},jw:function(a){this.yw(a);this.gw(this.key,this.value)},yw:function(a){this.gH(a,this.th,this.list)},gw:function(a,b){this.Zh(a,b,this.th,this.list)},Zh:function(a,b,c,m){a&&c&&void 0!==b&&(c[a]=b,\nm.push(b))},gH:function(a,b,c){if(a&&b&&a in b){var e=b[a];delete b[a];this.arrayDelete(c,e)}}});Polymer.Ph.y6=function(){null===c&&(c=new Polymer.Ph);return c};Polymer.tu=function(a){if(a)for(var b in a)switch(b){case \"type\":case \"key\":this[b]=a[b]}};Polymer.tu.prototype._setValue=function(){};Polymer.tu=Polymer({is:\"iron-meta-query\",properties:{type:{type:String,value:\"default\",observer:\"xw\"},key:{type:String,observer:\"Qv\"},value:{type:Object,notify:!0,readOnly:!0},list:{type:Array,notify:!0}},\nfactoryImpl:function(a){if(a)for(var b in a)switch(b){case \"type\":case \"key\":this[b]=a[b]}},created:function(){this.mG=a;this.lG=b},Qv:function(a){this._setValue(this.th&&this.th[a])},xw:function(c){this.th=a[c];this.list=b[c];this.key&&this.Qv(this.key)},er:function(a){return this.th&&this.th[a]}})})();V.pu={};V.pu.pu={};\nPolymer({is:\"iron-icon\",properties:{icon:{type:String},theme:{type:String},src:{type:String},_meta:{value:Polymer.Base.create(\"iron-meta\",{type:\"iconset\"})}},observers:[\"Aw(_meta,isAttached)\",\"Aw(theme,isAttached)\",\"YG(src,isAttached)\",\"u0(icon,isAttached)\"],bF:\"icons\",u0:function(a){a=(a||\"\").split(\":\");this.Mv=a.pop();this.Nv=a.pop()||this.bF;this.Aw()},YG:function(){this.Aw()},mH:function(){return this.icon||!this.src},Aw:function(){this.mH()?(this.rh&&this.rh.parentNode&&Polymer.dom(this.root).removeChild(this.rh),\n\"\"===this.Mv?this.Qj&&this.Qj.removeIcon(this):this.Nv&&this._meta&&((this.Qj=this._meta.er(this.Nv))?(this.Qj.applyIcon(this,this.Mv,this.theme),this.unlisten(window,\"iron-iconset-added\",\"Aw\")):this.listen(window,\"iron-iconset-added\",\"Aw\"))):(this.Qj&&this.Qj.removeIcon(this),this.rh||(this.rh=document.createElement(\"img\"),this.rh.style.width=\"100%\",this.rh.style.height=\"100%\",this.rh.draggable=!1),this.rh.src=this.src,Polymer.dom(this.root).appendChild(this.rh))}});V.qu={};V.qu.qu={};\nPolymer({is:\"iron-iconset-svg\",properties:{name:{type:String,observer:\"H0\"},size:{type:Number,value:24},rtlMirroring:{type:Boolean,value:!1}},attached:function(){this.style.display=\"none\"},v6:function(){this.En=this.Dv();return Object.keys(this.En).map(function(a){return this.name+\":\"+a},this)},applyIcon:function(a,b){a=a.root||a;this.removeIcon(a);if(b=this.oF(b,this.rtlMirroring&&this.ZG(a))){var c=Polymer.dom(a);c.insertBefore(b,c.childNodes[0]);return a.Cq=b}return null},removeIcon:function(a){a=\na.root||a;a.Cq&&(Polymer.dom(a).removeChild(a.Cq),a.Cq=null)},ZG:function(a){null==this.nv&&(a&&a.nodeType!==Node.ELEMENT_NODE&&(a=a.host),this.nv=a&&\"rtl\"===window.getComputedStyle(a).direction);return this.nv},H0:function(){new Polymer.Ph({type:\"iconset\",key:this.name,value:this});this.async(function(){this.fire(\"iron-iconset-added\",this,{node:window})})},Dv:function(){var a=Object.create(null);Polymer.dom(this).querySelectorAll(\"[id]\").forEach(function(b){a[b.id]=b});return a},oF:function(a,b){this.En=\nthis.En||this.Dv();return this.IG(this.En[a],this.size,b)},IG:function(a,b,c){if(a){a=a.cloneNode(!0);var e=document.createElementNS(\"http://www.w3.org/2000/svg\",\"svg\");b=a.getAttribute(\"viewBox\")||\"0 0 \"+b+\" \"+b;var g=\"pointer-events: none; display: block; width: 100%; height: 100%;\";c&&a.hasAttribute(\"mirror-in-rtl\")&&(g+=\"-webkit-transform:scale(-1,1);transform:scale(-1,1);\");e.setAttribute(\"viewBox\",b);e.setAttribute(\"preserveAspectRatio\",\"xMidYMid meet\");e.style.cssText=g;e.appendChild(a).removeAttribute(\"id\");\nreturn e}return null}});V.og={};V.og.YW={};V.og.nX={};V.og.vX={};V.og.HX={};V.og.dY={};V.og.lY={};V.og.og={};V.og.QY={};V.og.XY={};V.og.AZ={};V.og.XZ={};V.Jj={};V.Jj.Jj={};\nPolymer.Jj={properties:{_parentResizable:{type:Object,observer:\"c1\"},_notifyingDescendant:{type:Boolean,value:!1}},listeners:{\"iron-request-resize-notifications\":\"T0\"},created:function(){this.fl=[];this.cq=this.ri.bind(this)},attached:function(){this.fire(\"iron-request-resize-notifications\",null,{node:this,bubbles:!0,cancelable:!0});this._parentResizable||(window.addEventListener(\"resize\",this.cq),this.ri())},detached:function(){this._parentResizable?this._parentResizable.jW(this):window.removeEventListener(\"resize\",\nthis.cq);this._parentResizable=null},ri:function(){this.isAttached&&(this.fl.forEach(function(a){this.Wv(a)},this),this.Jv())},PJ:function(a){this._parentResizable=a},jW:function(a){var b=this.fl.indexOf(a);-1<b&&(this.fl.splice(b,1),this.unlisten(a,\"iron-resize\",\"L0\"))},Faa:function(){return!0},L0:function(a){this._notifyingDescendant?a.stopPropagation():Polymer.Settings.useShadow||this.Jv()},Jv:function(){this.fire(\"iron-resize\",null,{node:this,bubbles:!1})},T0:function(a){var b=a.path?a.path[0]:\na.target;b!==this&&(-1===this.fl.indexOf(b)&&(this.fl.push(b),this.listen(b,\"iron-resize\",\"L0\")),b.PJ(this),this.Wv(b),a.stopPropagation())},c1:function(a){a&&window.removeEventListener(\"resize\",this.cq)},Wv:function(a){this.isAttached&&(this._notifyingDescendant=!0,a.ri(),this._notifyingDescendant=!1)}};V.mg={};V.mg.mg={};\n(function(){function a(a,b){var c=\"\";if(a)if(a=a.toLowerCase(),\" \"===a||B.test(a))c=\"space\";else if(C.test(a))c=\"esc\";else if(1==a.length){if(!b||n.test(a))c=a}else c=v.test(a)?a.replace(\"arrow\",\"\"):\"multiply\"==a?\"*\":a;return c}function b(b,c){var e;e=c;var n=b.zo,m;if(!(m=a(e.key,n))){m=e.keyIdentifier;var v=\"\";m&&(m in g?v=g[m]:q.test(m)?(m=parseInt(m.replace(\"U+\",\"0x\"),16),v=String.fromCharCode(m).toLowerCase()):v=m.toLowerCase());m=v}m||(m=e.keyCode,v=\"\",Number(m)&&(v=65<=m&&90>=m?String.fromCharCode(32+\nm):112<=m&&123>=m?\"f\"+(m-112):48<=m&&57>=m?String(m-48):96<=m&&105>=m?String(m-96):k[m]),m=v);e=m||a(e.detail?e.detail.key:e.detail,n)||\"\";return e===b.key&&(!b.zo||!!c.shiftKey===!!b.shiftKey&&!!c.ctrlKey===!!b.ctrlKey&&!!c.altKey===!!b.altKey&&!!c.metaKey===!!b.metaKey)}function c(a){return 1===a.length?{lK:a,key:a,event:\"keydown\"}:a.split(\"+\").reduce(function(a,b){var c=b.split(\":\");b=c[0];c=c[1];b in m?(a[m[b]]=!0,a.zo=!0):(a.key=b,a.event=c||\"keydown\");return a},{lK:a.split(\":\").shift()})}function e(a){return a.trim().split(\" \").map(function(a){return c(a)})}\nvar g={\"U+0008\":\"backspace\",\"U+0009\":\"tab\",\"U+001B\":\"esc\",\"U+0020\":\"space\",\"U+007F\":\"del\"},k={8:\"backspace\",9:\"tab\",13:\"enter\",27:\"esc\",33:\"pageup\",34:\"pagedown\",35:\"end\",36:\"home\",32:\"space\",37:\"left\",38:\"up\",39:\"right\",40:\"down\",46:\"del\",106:\"*\"},m={shift:\"shiftKey\",ctrl:\"ctrlKey\",alt:\"altKey\",meta:\"metaKey\"},n=/[a-z0-9*]/,q=/U\\+/,v=/^arrow/,B=/^space(bar)?/,C=/^escape$/;Polymer.mg={properties:{keyEventTarget:{type:Object,value:function(){return this}},stopKeyboardEventPropagation:{type:Boolean,\nvalue:!1},_boundKeyHandlers:{type:Array,value:function(){return[]}},_imperativeKeyBindings:{type:Object,value:function(){return{}}}},observers:[\"Aq(keyEventTarget,_boundKeyHandlers)\"],$g:{},registered:function(){this.Jn()},attached:function(){this.uq()},detached:function(){this.Gq()},SI:function(a,b){this._imperativeKeyBindings[a]=b;this.Jn();this.Aq()},vP:function(){this._imperativeKeyBindings={};this.Jn();this.Aq()},Ho:function(a,c){c=e(c);for(var g=0;g<c.length;++g)if(b(c[g],a))return!0;return!1},\nxv:function(){var a=this.behaviors.map(function(a){return a.$g});-1===a.indexOf(this.$g)&&a.push(this.$g);return a},Jn:function(){this.Vi={};this.xv().forEach(function(a){for(var b in a)this.Zp(b,a[b])},this);for(var a in this._imperativeKeyBindings)this.Zp(a,this._imperativeKeyBindings[a]);for(var b in this.Vi)this.Vi[b].sort(function(a,b){a=a[0].zo;b=b[0].zo;return a===b?0:a?-1:1})},Zp:function(a,b){e(a).forEach(function(a){this.Vi[a.event]=this.Vi[a.event]||[];this.Vi[a.event].push([a,b])},this)},\nAq:function(){this.Gq();this.isAttached&&this.uq()},uq:function(){this.keyEventTarget&&Object.keys(this.Vi).forEach(function(a){var b=this.Vi[a],b=this.$v.bind(this,b);this._boundKeyHandlers.push([this.keyEventTarget,a,b]);this.keyEventTarget.addEventListener(a,b)},this)},Gq:function(){for(var a,b,c;this._boundKeyHandlers.length;)a=this._boundKeyHandlers.pop(),b=a[0],c=a[1],a=a[2],b.removeEventListener(c,a)},$v:function(a,c){this.stopKeyboardEventPropagation&&c.stopPropagation();if(!c.defaultPrevented)for(var e=\n0;e<a.length;e++){var g=a[e][0],k=a[e][1];if(b(g,c)&&(this.ww(g,k,c),c.defaultPrevented))break}},ww:function(a,b,c){var e=Object.create(a);e.Go=c;a=new CustomEvent(a.event,{detail:e,cancelable:!0});this[b].call(this,a);a.defaultPrevented&&c.preventDefault()}}})();V.Uu={};V.Uu.Uu={};\n(function(){function a(a){this.element=a;this.width=this.Zn.width;this.height=this.Zn.height;this.size=Math.max(this.width,this.height)}function b(a){this.element=a;this.color=window.getComputedStyle(a).color;this.Ck=document.createElement(\"div\");this.Og=document.createElement(\"div\");this.Ck.style.backgroundColor=this.color;this.Ck.classList.add(\"wave\");this.Og.classList.add(\"wave-container\");Polymer.dom(this.Og).appendChild(this.Ck);this.nC()}var c={distance:function(a,b,c,m){a-=c;b-=m;return Math.sqrt(a*\na+b*b)},now:window.performance&&window.performance.now?window.performance.now.bind(window.performance):Date.now};a.prototype={get Zn(){return this.element.getBoundingClientRect()},eL:function(a,b){var e=c.distance(a,b,0,0),g=c.distance(a,b,this.width,0),n=c.distance(a,b,0,this.height);a=c.distance(a,b,this.width,this.height);return Math.max(e,g,n,a)}};b.Zm=300;b.prototype={get recenters(){return this.element.recenters},get center(){return this.element.center},get uO(){var a;if(!this.Ko)return 0;a=\nc.now()-this.Ko;this.oj&&(a-=this.QB);return a},get QB(){return this.oj?c.now()-this.oj:0},get vO(){return this.uO/1E3},get us(){return this.QB/1E3},get wO(){return this.vO+this.us},get initialOpacity(){return this.element.initialOpacity},get opacityDecayVelocity(){return this.element.opacityDecayVelocity},get radius(){var a=this.Fd.width*this.Fd.width,c=this.Fd.height*this.Fd.height,a=1.1*Math.min(Math.sqrt(a+c),b.Zm)+5,c=1.1-a/b.Zm*.2,c=this.wO/c,a=a*(1-Math.pow(80,-c));return Math.abs(a)},get opacity(){return this.oj?\nMath.max(0,this.initialOpacity-this.us*this.opacityDecayVelocity):this.initialOpacity},get MO(){var a=.3*this.us,b=this.opacity;return Math.max(0,Math.min(a,b))},get uB(){return.01>this.opacity&&this.radius>=Math.min(this.rs,b.Zm)},get wB(){return this.opacity>=this.initialOpacity&&this.radius>=Math.min(this.rs,b.Zm)},get mN(){return this.oj?this.uB:this.wB},get HC(){return Math.min(1,this.radius/this.Fd.size*2/Math.sqrt(2))},get PW(){return this.Om?this.xi+this.HC*(this.Om-this.xi):this.xi},get QW(){return this.Pm?\nthis.zi+this.HC*(this.Pm-this.zi):this.zi},get yN(){return this.Ko&&!this.oj},nC:function(){this.Pm=this.Om=this.zi=this.xi=this.oj=this.Ko=this.rs=0;this.Fd=new a(this.element)},draw:function(){var a,b,c;this.Ck.style.opacity=this.opacity;a=this.radius/(this.Fd.size/2);b=this.PW-this.Fd.width/2;c=this.QW-this.Fd.height/2;this.Og.style.webkitTransform=\"translate(\"+b+\"px, \"+c+\"px)\";this.Og.style.transform=\"translate3d(\"+b+\"px, \"+c+\"px, 0)\";this.Ck.style.webkitTransform=\"scale(\"+a+\",\"+a+\")\";this.Ck.style.transform=\n\"scale3d(\"+a+\",\"+a+\",1)\"},fk:function(a){var b=this.Fd.width/2,e=this.Fd.height/2;this.nC();this.Ko=c.now();this.center?(this.xi=b,this.zi=e,c.distance(this.xi,this.zi,this.Om,this.Pm)):(this.xi=a?a.detail.x-this.Fd.Zn.left:this.Fd.width/2,this.zi=a?a.detail.y-this.Fd.Zn.top:this.Fd.height/2);this.recenters&&(this.Om=b,this.Pm=e,c.distance(this.xi,this.zi,this.Om,this.Pm));this.rs=this.Fd.eL(this.xi,this.zi);this.Og.style.top=(this.Fd.height-this.Fd.size)/2+\"px\";this.Og.style.left=(this.Fd.width-\nthis.Fd.size)/2+\"px\";this.Og.style.width=this.Fd.size+\"px\";this.Og.style.height=this.Fd.size+\"px\"},zk:function(){this.yN&&(this.oj=c.now())},remove:function(){Polymer.dom(this.Og.parentNode).removeChild(this.Og)}};Polymer({is:\"paper-ripple\",behaviors:[Polymer.mg],properties:{initialOpacity:{type:Number,value:.25},opacityDecayVelocity:{type:Number,value:.8},recenters:{type:Boolean,value:!1},center:{type:Boolean,value:!1},ripples:{type:Array,value:function(){return[]}},animating:{type:Boolean,readOnly:!0,\nreflectToAttribute:!0,value:!1},holdDown:{type:Boolean,value:!1,observer:\"t0\"},noink:{type:Boolean,value:!1},_animating:{type:Boolean},_boundAnimate:{type:Function,value:function(){return this.animate.bind(this)}}},get target(){var a=Polymer.dom(this).getOwnerRoot();return a=11==this.parentNode.nodeType?a.host:this.parentNode},$g:{\"enter:keydown\":\"O0\",\"space:keydown\":\"X0\",\"space:keyup\":\"Y0\"},attached:function(){this.keyEventTarget=this.target;this.listen(this.target,\"up\",\"Ct\");this.listen(this.target,\n\"down\",\"bp\")},detached:function(){this.unlisten(this.target,\"up\",\"Ct\");this.unlisten(this.target,\"down\",\"bp\")},get VV(){for(var a=0;a<this.ripples.length;++a)if(!this.ripples[a].mN)return!0;return!1},vba:function(){this.fk(null);this.async(function(){this.zk()},1)},bp:function(a){this.noink||this.fk(a)},fk:function(a){if(!(this.holdDown&&0<this.ripples.length)){var b=this.bJ();b.fk(a);this._animating||this.animate()}},Ct:function(a){this.noink||this.zk(a)},zk:function(a){this.holdDown||(this.ripples.forEach(function(b){b.zk(a)}),\nthis.animate())},JO:function(){this._animating=!1;this.$.background.style.backgroundColor=null;this.fire(\"transitionend\")},bJ:function(){var a=new b(this);Polymer.dom(this.$.waves).appendChild(a.Og);this.$.background.style.backgroundColor=a.color;this.ripples.push(a);this._setAnimating(!0);return a},xP:function(a){var b=this.ripples.indexOf(a);0>b||(this.ripples.splice(b,1),a.remove(),this.ripples.length||this._setAnimating(!1))},animate:function(){var a,b;this._animating=!0;for(a=0;a<this.ripples.length;++a)b=\nthis.ripples[a],b.draw(),this.$.background.style.opacity=b.MO,b.uB&&!b.wB&&this.xP(b);this.VV||0!==this.ripples.length?window.requestAnimationFrame(this._boundAnimate):this.JO()},O0:function(){this.bp();this.async(this.Ct,1)},X0:function(){this.bp()},Y0:function(){this.Ct()},t0:function(a,b){void 0!==b&&(a?this.fk():this.zk())}})})();V.en={};V.en.qh={};\nPolymer.qh={properties:{noink:{type:Boolean,observer:\"I0\"},_rippleContainer:{type:Object}},tn:function(){this.focused&&this.hj()},Fv:function(a){Polymer.Um.Fv.call(this,a);this.pressed&&this.hj(a)},hj:function(a){if(!this.kj()){this.Ne=this.Ri();this.Ne.noink=this.noink;var b=this._rippleContainer||this.root;b&&Polymer.dom(b).appendChild(this.Ne);if(a){var b=Polymer.dom(this._rippleContainer||this),c=Polymer.dom(a).rootTarget;b.deepContains(c)&&this.Ne.bp(a)}}},Pr:function(){this.hj();return this.Ne},\nkj:function(){return!!this.Ne},Ri:function(){return document.createElement(\"paper-ripple\")},I0:function(a){this.kj()&&(this.Ne.noink=a)}};V.mu={};V.mu.ng={};\nPolymer.ng={properties:{focused:{type:Boolean,value:!1,notify:!0,readOnly:!0,reflectToAttribute:!0},disabled:{type:Boolean,value:!1,notify:!0,observer:\"iq\",reflectToAttribute:!0},_oldTabIndex:{type:Number},_boundFocusBlurHandler:{type:Function,value:function(){return this.zn.bind(this)}}},observers:[\"lF(focused,disabled)\"],ready:function(){this.addEventListener(\"focus\",this._boundFocusBlurHandler,!0);this.addEventListener(\"blur\",this._boundFocusBlurHandler,!0)},zn:function(a){if(a.target===this)this._setFocused(\"focus\"===\na.type);else if(!this.shadowRoot){var b=Polymer.dom(a).localTarget;this.isLightDescendant(b)||this.fire(a.type,{sourceEvent:a},{node:this,bubbles:a.bubbles,cancelable:a.cancelable})}},iq:function(a){this.setAttribute(\"aria-disabled\",a?\"true\":\"false\");this.style.pointerEvents=a?\"none\":\"\";a?(this._oldTabIndex=this.tabIndex,this._setFocused(!1),this.tabIndex=-1,this.blur()):void 0!==this._oldTabIndex&&(this.tabIndex=this._oldTabIndex)},lF:function(){this.vn&&this.vn()}};V.mu.Hj={};\nPolymer.Um={properties:{pressed:{type:Boolean,readOnly:!0,value:!1,reflectToAttribute:!0,observer:\"e1\"},toggles:{type:Boolean,value:!1,reflectToAttribute:!0},active:{type:Boolean,value:!1,notify:!0,reflectToAttribute:!0},pointerDown:{type:Boolean,readOnly:!0,value:!1},receivedFocusFromKeyboard:{type:Boolean,readOnly:!0},ariaActiveAttribute:{type:String,value:\"aria-pressed\",observer:\"G_\"}},listeners:{down:\"Fv\",up:\"A1\",tap:\"v1\"},observers:[\"e0(focused)\",\"D_(active,ariaActiveAttribute)\"],$g:{\"enter:keydown\":\"gF\",\n\"space:keydown\":\"tw\",\"space:keyup\":\"uw\"},G0:/^mouse/,v1:function(){this.toggles?this.Bw(!this.active):this.active=!1},e0:function(a){this._setReceivedFocusFromKeyboard(!this.pointerDown&&a)},Bw:function(a){this.active!==a&&(this.active=a,this.fire(\"change\"))},Fv:function(){this._setPointerDown(!0);this._setPressed(!0);this._setReceivedFocusFromKeyboard(!1)},A1:function(){this._setPointerDown(!1);this._setPressed(!1)},tw:function(a){a=a.detail.Go;var b=Polymer.dom(a).localTarget;this.isLightDescendant(b)||\n(a.preventDefault(),a.stopImmediatePropagation(),this._setPressed(!0))},uw:function(a){a=a.detail.Go;a=Polymer.dom(a).localTarget;this.isLightDescendant(a)||(this.pressed&&this.gF(),this._setPressed(!1))},gF:function(){this.async(function(){this.click()},1)},e1:function(){this.gq()},G_:function(a,b){b&&b!=a&&this.hasAttribute(b)&&this.removeAttribute(b)},D_:function(a){this.toggles?this.setAttribute(this.ariaActiveAttribute,a?\"true\":\"false\"):this.removeAttribute(this.ariaActiveAttribute);this.gq()},\nvn:function(){this.disabled?this._setPressed(!1):this.gq()},gq:function(){this.tn&&this.tn()}};Polymer.Hj=[Polymer.mg,Polymer.Um];V.en.Mu={};\nPolymer.Nu={properties:{elevation:{type:Number,reflectToAttribute:!0,readOnly:!0}},observers:[\"uv(focused,disabled,active,pressed,receivedFocusFromKeyboard)\",\"Y_(receivedFocusFromKeyboard)\"],hostAttributes:{role:\"button\",tabindex:\"0\",animated:!0},uv:function(){var a=1;this.disabled?a=0:this.active||this.pressed?a=4:this.receivedFocusFromKeyboard&&(a=3);this._setElevation(a)},Y_:function(a){this.toggleClass(\"keyboard-focus\",a)},tw:function(a){Polymer.Um.tw.call(this,a);this.kj()&&1>this.Pr().ripples.length&&\nthis.Ne.bp()},uw:function(a){Polymer.Um.uw.call(this,a);this.kj()&&this.Ne.Ct()}};Polymer.Mu=[Polymer.Hj,Polymer.ng,Polymer.qh,Polymer.Nu];V.Vf={};V.Vf.FE={};V.Lp={};V.Lp.wZ={};V.Lp.Lp={};Polymer({is:\"paper-material\",properties:{elevation:{type:Number,reflectToAttribute:!0,value:1},animated:{type:Boolean,reflectToAttribute:!0,value:!1}}});V.Lu={};V.Lu.Lu={};\nPolymer({is:\"paper-button\",behaviors:[Polymer.Mu],properties:{raised:{type:Boolean,reflectToAttribute:!0,value:!1,observer:\"uv\"}},uv:function(){this.raised?Polymer.Nu.uv.apply(this):this._setElevation(0)}});V.ru={};V.ru.ru={};\nPolymer({is:\"iron-image\",properties:{src:{observer:\"YG\",type:String,value:\"\"},alt:{type:String,value:null},preventLoad:{type:Boolean,value:!1,observer:\"f1\"},sizing:{type:String,value:null,reflectToAttribute:!0},position:{type:String,value:\"center\"},preload:{type:Boolean,value:!1},placeholder:{type:String,value:null,observer:\"d1\"},fade:{type:Boolean,value:!1},loaded:{notify:!0,readOnly:!0,type:Boolean,value:!1},loading:{notify:!0,readOnly:!0,type:Boolean,value:!1},error:{notify:!0,readOnly:!0,type:Boolean,\nvalue:!1},width:{observer:\"G1\",type:Number,value:null},height:{observer:\"r0\",type:Number,value:null}},observers:[\"z1(sizing,position)\"],ready:function(){var a=this.$.img;a.onload=function(){this.$.img.src===this.Nn(this.src)&&(this._setLoading(!1),this._setLoaded(!0),this._setError(!1))}.bind(this);a.onerror=function(){this.$.img.src===this.Nn(this.src)&&(this.zq(),this._setLoading(!1),this._setLoaded(!1),this._setError(!0))}.bind(this);this.mw=\"\"},Sv:function(a){a?this.$.img.src=a:this.$.img.removeAttribute(\"src\");\nthis.$.sizedImgDiv.style.backgroundImage=a?'url(\"'+a+'\")':\"\";this._setLoading(!!a);this._setLoaded(!1);this._setError(!1)},zq:function(){this.$.img.removeAttribute(\"src\");this.$.sizedImgDiv.style.backgroundImage=\"\";this._setLoading(!1);this._setLoaded(!1);this._setError(!1)},a0:function(){return!this.preload||!this.fade&&!this.loading&&this.loaded},$_:function(){return this.preload&&this.fade&&!this.loading&&this.loaded?\"faded-out\":\"\"},V_:function(){return!this.sizing},T_:function(){return\"\"===this.alt?\n\"true\":void 0},U_:function(){if(null!==this.alt)return this.alt;if(\"\"===this.src)return\"\";var a=(new URL(this.Nn(this.src))).pathname.split(\"/\");return a[a.length-1]},W_:function(){return!!this.sizing},G1:function(){this.style.width=isNaN(this.width)?this.width:this.width+\"px\"},r0:function(){this.style.height=isNaN(this.height)?this.height:this.height+\"px\"},f1:function(){this.preventLoad||this.loaded||(this.zq(),this.Sv(this.src))},YG:function(a){var b=this.Nn(a);b!==this.mw&&(this.mw=b,this.zq(),\nthis.preventLoad||this.Sv(a))},d1:function(){this.$.placeholder.style.backgroundImage=this.placeholder?'url(\"'+this.placeholder+'\")':\"\"},z1:function(){var a=this.$.sizedImgDiv.style,b=this.$.placeholder.style;a.backgroundSize=b.backgroundSize=this.sizing;a.backgroundPosition=b.backgroundPosition=this.sizing?this.position:\"\";a.backgroundRepeat=b.backgroundRepeat=this.sizing?\"no-repeat\":\"\"},Nn:function(a){var b=this.ownerDocument.baseURI;return b?(new URL(a,b)).href:a}});V.Vf.mX={};V.Vf.tX={};\nV.Ou={};V.Ou.Ou={};\nPolymer({is:\"paper-card\",properties:{heading:{type:String,value:\"\",observer:\"q0\"},image:{type:String,value:\"\"},alt:{type:String},preloadImage:{type:Boolean,value:!1},fadeImage:{type:Boolean,value:!1},placeholderImage:{type:String,value:null},elevation:{type:Number,value:1,reflectToAttribute:!0},animatedShadow:{type:Boolean,value:!1},animated:{type:Boolean,reflectToAttribute:!0,readOnly:!0,computed:\"R_(animatedShadow)\"}},A0:function(a){return a?\"false\":\"true\"},q0:function(a){this.getAttribute(\"aria-label\");this.setAttribute(\"aria-label\",\na)},S_:function(a){return a?\" over-image\":\"\"},R_:function(a){return a}});V.Gi={};V.Gi.Rh={};\nPolymer.Rh={properties:{animationTiming:{type:Object,value:function(){return{duration:500,easing:\"cubic-bezier(0.4, 0, 0.2, 1)\",fill:\"both\"}}}},zN:!0,zj:function(a){if(a.timing)for(var b in a.timing)this.animationTiming[b]=a.timing[b];return this.animationTiming},lU:function(a,b,c){for(var e={transform:[\"webkitTransform\"],transformOrigin:[\"mozTransformOrigin\",\"webkitTransformOrigin\"]},e=e[b],g,k=0;g=e[k];k++)a.style[g]=c;a.style[b]=c},complete:function(){}};\n(function(){!function(a,b){var c={},e={},g={};!function(a){function b(a){if(\"number\"==typeof a)return a;var b={},c;for(c in a)b[c]=a[c];return b}function c(){this.BF=this.tF=0;this.FF=\"none\";this.cG=0;this.dG=1;this.yF=0;this.Dg=1;this.uF=\"normal\";this.zF=\"linear\";this.Gv=aa}function e(){return a.Bo(\"Invalid timing inputs\",\"2016-03-02\",\"TypeError exceptions will be thrown instead.\",!0)}function g(b,e){var g=new c;return e&&(g.fill=\"both\",g.duration=\"auto\"),\"number\"!=typeof b||isNaN(b)?void 0!==b&&\nObject.getOwnPropertyNames(b).forEach(function(c){\"auto\"==b[c]||(\"number\"==typeof g[c]||\"duration\"==c)&&(\"number\"!=typeof b[c]||isNaN(b[c]))||\"fill\"==c&&-1==ka.indexOf(b[c])||\"direction\"==c&&-1==U.indexOf(b[c])||\"playbackRate\"==c&&1!==b[c]&&a.Bo(\"AnimationEffectTiming.playbackRate\",\"2014-11-28\",\"Use Animation.playbackRate instead.\")||(g[c]=b[c])}):g.duration=b,g}function k(a){return\"number\"==typeof a&&(a=isNaN(a)?{duration:0}:{duration:a}),a}function C(b,c){return b=a.ws(b),g(b,c)}function E(a,b,\nc,e){return 0>a||1<a||0>c||1<c?aa:function(g){if(0==g||1==g)return g;for(var k=0,n=1;;){var m=(k+n)/2,q=3*a*(1-m)*(1-m)*m+3*c*(1-m)*m*m+m*m*m;if(1E-4>Math.abs(g-q))return 3*b*(1-m)*(1-m)*m+3*e*(1-m)*m*m+m*m*m;g>q?k=m:n=m}}}function W(a,b){return function(c){if(1<=c)return 1;var e=1/a;return c+=b*e,c-c%e}}function J(a){Ya||(Ya=document.createElement(\"div\").style);Ya.Fw=\"\";Ya.Fw=a;var b=Ya.Fw;if(\"\"==b&&e())throw new TypeError(a+\" is not a valid value for easing\");return(a=df.exec(b))?E.apply(this,a.slice(1).map(Number)):\n(a=ef.exec(b))?W(Number(a[1]),{start:na,N8:Ka,end:ma}[a[2]]):(b=cf[b])?b:aa}function K(a){return Math.abs(a.duration*a.iterations/a.playbackRate)}function O(a,b,c){return null==b?Fb:b<c.delay?Dc:b>=c.delay+a?vd:wd}function Q(a,b,c){var e=O(a,b,c);a:{var g=c.fill;switch(e){case Dc:b=\"backwards\"==g||\"both\"==g?0:null;break a;case wd:b-=c.delay;break a;case vd:b=\"forwards\"==g||\"both\"==g?a:null;break a;case Fb:b=null;break a}b=void 0}if(null===b)return null;if(0===a)return e===Dc?0:1;e=c.iterationStart*\nc.duration;b=(0>c.playbackRate?b-a:b)*c.playbackRate+e;a=c.duration;a=b===1/0||b===-(1/0)||b-e==c.duration*c.iterations&&c.iterations&&0==(c.iterations+c.iterationStart)%1?a:b%a;e=c.duration;b=0===b?0:a==e?c.iterationStart+c.iterations-1:Math.floor(b/e);e=c.duration;b=1<=b%2;a=(b=\"normal\"==c.direction||c.direction==(b?\"alternate-reverse\":\"alternate\"))?a:e-a;a/=e;a=e*c.Gv(a);return a/c.duration}var ka=[\"backwards\",\"forwards\",\"both\",\"none\"],U=[\"reverse\",\"alternate\",\"alternate-reverse\"],aa=function(a){return a};\nc.prototype={$h:function(b,c){this[\"_\"+b]=c;this.kc&&(this.kc.ak[b]=c,this.kc.Kf=a.pj(this.kc.ak),this.kc.rl=a.dk(this.kc.Kf),this.kc.hb&&this.kc.hb.hl())},get playbackRate(){return this.Dg},set delay(a){this.$h(\"delay\",a)},get delay(){return this.tF},set endDelay(a){this.$h(\"endDelay\",a)},get endDelay(){return this.BF},set fill(a){this.$h(\"fill\",a)},get fill(){return this.FF},set iterationStart(a){if((isNaN(a)||0>a)&&e())throw new TypeError(\"iterationStart must be a non-negative number, received: \"+\ntiming.iterationStart);this.$h(\"iterationStart\",a)},get iterationStart(){return this.cG},set duration(a){if(\"auto\"!=a&&(isNaN(a)||0>a)&&e())throw new TypeError(\"duration must be non-negative or auto, received: \"+a);this.$h(\"duration\",a)},get duration(){return this.yF},set direction(a){this.$h(\"direction\",a)},get direction(){return this.uF},set easing(a){this.Gv=J(a);this.$h(\"easing\",a)},get easing(){return this.zF},set iterations(a){if((isNaN(a)||0>a)&&e())throw new TypeError(\"iterations must be non-negative, received: \"+\na);this.$h(\"iterations\",a)},get iterations(){return this.dG}};var na=1,Ka=.5,ma=0,cf={ease:E(.25,.1,.25,1),\"ease-in\":E(.42,0,1,1),\"ease-out\":E(0,0,.58,1),\"ease-in-out\":E(.42,0,.58,1),\"step-start\":W(1,na),\"step-middle\":W(1,Ka),\"step-end\":W(1,ma)},Ya=null,df=/cubic-bezier\\(\\s*(-?\\d+\\.?\\d*|-?\\.\\d+)\\s*,\\s*(-?\\d+\\.?\\d*|-?\\.\\d+)\\s*,\\s*(-?\\d+\\.?\\d*|-?\\.\\d+)\\s*,\\s*(-?\\d+\\.?\\d*|-?\\.\\d+)\\s*\\)/,ef=/steps\\(\\s*(\\d+)\\s*,\\s*(start|middle|end)\\s*\\)/,Fb=0,Dc=1,vd=2,wd=3;a.io=b;a.KB=g;a.ws=k;a.pj=C;a.dk=K;a.bo=Q;a.$J=\nO;a.rW=J}(c,null);(function(a){function b(a){var b=[],c;for(c in a)if(!(c in[\"easing\",\"offset\",\"composite\"])){var e=a[c];Array.isArray(e)||(e=[e]);for(var g,k=e.length,n=0;k>n;n++)g={},\"offset\"in a?g.offset=a.offset:1==k?g.offset=1:g.offset=n/(k-1),\"easing\"in a&&(g.easing=a.easing),\"composite\"in a&&(g.nK=a.nK),g[c]=e[n],b.push(g)}return b.sort(function(a,b){return a.offset-b.offset}),b}function c(a){function c(){var a=k.length;null==k[a-1].offset&&(k[a-1].offset=1);1<a&&null==k[0].offset&&(k[0].offset=\n0);for(var b=0,c=k[0].offset,e=1;a>e;e++){var g=k[e].offset;if(null!=g){for(var n=1;e-b>n;n++)k[b+n].offset=c+(g-c)*n/(e-b);b=e;c=g}}}if(null==a)return[];window.Symbol&&Symbol.iterator&&Array.prototype.from&&a[Symbol.iterator]&&(a=Array.from(a));Array.isArray(a)||(a=b(a));var k=a.map(function(a){var b={},c;for(c in a){var k=a[c];if(\"offset\"==c){if(null!=k&&(k=Number(k),!isFinite(k)))throw new TypeError(\"keyframe offsets must be numbers.\");}else{if(\"composite\"==c)throw{type:DOMException.NOT_SUPPORTED_ERR,\nname:\"NotSupportedError\",message:\"add compositing is not supported\"};k=\"\"+k}var n=void 0,m=c,q=k,k=b,v=e[m];if(v)for(n in g.style[m]=q,v)m=v[n],q=g.style[m],k[m]=m in C?C[m][q]||q:q;else k[m]=m in C?C[m][q]||q:q}return void 0==b.offset&&(b.offset=null),b});a=!0;for(var n=-(1/0),m=0;m<k.length;m++){var q=k[m].offset;if(null!=q){if(n>q)throw{code:DOMException.INVALID_MODIFICATION_ERR,name:\"InvalidModificationError\",message:\"Keyframes are not loosely sorted by offset. Sort or specify offsets.\"};n=q}else a=\n!1}return k=k.filter(function(a){return 0<=a.offset&&1>=a.offset}),a||c(),k}var e={background:\"backgroundImage backgroundPosition backgroundSize backgroundRepeat backgroundAttachment backgroundOrigin backgroundClip backgroundColor\".split(\" \"),border:\"borderTopColor borderTopStyle borderTopWidth borderRightColor borderRightStyle borderRightWidth borderBottomColor borderBottomStyle borderBottomWidth borderLeftColor borderLeftStyle borderLeftWidth\".split(\" \"),borderBottom:[\"borderBottomWidth\",\"borderBottomStyle\",\n\"borderBottomColor\"],borderColor:[\"borderTopColor\",\"borderRightColor\",\"borderBottomColor\",\"borderLeftColor\"],borderLeft:[\"borderLeftWidth\",\"borderLeftStyle\",\"borderLeftColor\"],borderRadius:[\"borderTopLeftRadius\",\"borderTopRightRadius\",\"borderBottomRightRadius\",\"borderBottomLeftRadius\"],borderRight:[\"borderRightWidth\",\"borderRightStyle\",\"borderRightColor\"],borderTop:[\"borderTopWidth\",\"borderTopStyle\",\"borderTopColor\"],borderWidth:[\"borderTopWidth\",\"borderRightWidth\",\"borderBottomWidth\",\"borderLeftWidth\"],\nflex:[\"flexGrow\",\"flexShrink\",\"flexBasis\"],font:\"fontFamily fontSize fontStyle fontVariant fontWeight lineHeight\".split(\" \"),margin:[\"marginTop\",\"marginRight\",\"marginBottom\",\"marginLeft\"],outline:[\"outlineColor\",\"outlineStyle\",\"outlineWidth\"],padding:[\"paddingTop\",\"paddingRight\",\"paddingBottom\",\"paddingLeft\"]},g=document.createElementNS(\"http://www.w3.org/1999/xhtml\",\"div\"),k={yca:\"1px\",lO:\"3px\",xca:\"5px\"},C={borderBottomWidth:k,borderLeftWidth:k,borderRightWidth:k,borderTopWidth:k,fontSize:{\"xx-small\":\"60%\",\n\"x-small\":\"75%\",small:\"89%\",lO:\"100%\",d8:\"120%\",\"x-large\":\"150%\",\"xx-large\":\"200%\"},fontWeight:{E9:\"400\",bold:\"700\"},outlineWidth:k,textShadow:{EO:\"0px 0px 0px transparent\"},boxShadow:{EO:\"0px 0px 0px 0px transparent\"}};a.uK=b;a.TB=c})(c,null);(function(a){var b={};a.Bo=function(a,c,e,g){g=g?\"are\":\"is\";var k=new Date;c=new Date(c);return c.setMonth(c.getMonth()+3),c>k?(a in b||console.warn(\"Web Animations: \"+a+\" \"+g+\" deprecated and will stop working on \"+c.toDateString()+\". \"+e),b[a]=!0,!1):!0};\na.IK=function(b,c,e,g){var k=g?\"are\":\"is\";if(a.Bo(b,c,e,g))throw Error(b+\" \"+k+\" no longer supported. \"+e);}})(c);(function(){if(document.documentElement.animate){var a=document.documentElement.animate([],0),b=!0;if(a&&(b=!1,\"play currentTime pause reverse playbackRate cancel finish startTime playState\".split(\" \").forEach(function(c){void 0===a[c]&&(b=!0)})),!b)return}!function(a,b){function c(a){for(var b={},c=0;c<a.length;c++)for(var e in a[c])if(\"offset\"!=e&&\"easing\"!=e&&\"composite\"!=e){var g=\n{offset:a[c].offset,easing:a[c].easing,value:a[c][e]};b[e]=b[e]||[];b[e].push(g)}for(var k in b)if(a=b[k],0!=a[0].offset||1!=a[a.length-1].offset)throw{type:DOMException.NOT_SUPPORTED_ERR,name:\"NotSupportedError\",message:\"Partial keyframes are not supported\"};return b}function e(c){var e=[],g;for(g in c)for(var k=c[g],n=0;n<k.length-1;n++){var m=k[n].offset,q=k[n+1].offset,v=k[n].value,B=k[n+1].value,C=k[n].easing;m==q&&(1==q?v=B:B=v);e.push({startTime:m,endTime:q,easing:a.rW(C?C:\"linear\"),property:g,\njN:b.aP(g,v,B)})}return e.sort(function(a,b){return a.startTime-b.startTime}),e}b.tK=function(g){g=a.TB(g);var k=c(g),n=e(k);return function(a,c){if(null!=c)n.filter(function(a){return 0>=c&&0==a.startTime||1<=c&&1==a.endTime||c>=a.startTime&&c<=a.endTime}).forEach(function(e){var g=c-e.startTime,k=e.endTime-e.startTime,g=0==k?0:e.easing(g/k);b.apply(a,e.property,e.jN(g))});else for(var e in k)\"offset\"!=e&&\"easing\"!=e&&\"composite\"!=e&&b.clear(a,e)}}}(c,e,null);(function(a,b){function c(a){return a.replace(/-(.)/g,\nfunction(a,b){return b.toUpperCase()})}function e(a,b,e){for(var g=0;g<e.length;g++){var n=e[g],m=a,q=b,n=c(n);k[n]=k[n]||[];k[n].push([m,q])}}function g(e,g,m){var q=e;/-/.test(e)&&!a.Bo(\"Hyphenated property names\",\"2016-03-22\",\"Use camelCase instead.\",!0)&&(q=c(e));\"initial\"!=g&&\"initial\"!=m||(\"initial\"==g&&(g=n[q]),\"initial\"==m&&(m=n[q]));e=g==m?[]:k[q];for(q=0;e&&q<e.length;q++){var v=e[q][0](g),B=e[q][0](m);if(void 0!==v&&void 0!==B&&(v=e[q][1](v,B))){var C=b.ku.apply(null,v);return function(a){return 0==\na?g:1==a?m:C(a)}}}return b.ku(!1,!0,function(a){return a?m:g})}var k={};b.cg=e;var n={backgroundColor:\"transparent\",backgroundPosition:\"0% 0%\",borderBottomColor:\"currentColor\",borderBottomLeftRadius:\"0px\",borderBottomRightRadius:\"0px\",borderBottomWidth:\"3px\",borderLeftColor:\"currentColor\",borderLeftWidth:\"3px\",borderRightColor:\"currentColor\",borderRightWidth:\"3px\",borderSpacing:\"2px\",borderTopColor:\"currentColor\",borderTopLeftRadius:\"0px\",borderTopRightRadius:\"0px\",borderTopWidth:\"3px\",bottom:\"auto\",\nclip:\"rect(0px, 0px, 0px, 0px)\",color:\"black\",fontSize:\"100%\",fontWeight:\"400\",height:\"auto\",left:\"auto\",letterSpacing:\"normal\",lineHeight:\"120%\",marginBottom:\"0px\",marginLeft:\"0px\",marginRight:\"0px\",marginTop:\"0px\",maxHeight:\"none\",maxWidth:\"none\",minHeight:\"0px\",minWidth:\"0px\",opacity:\"1.0\",outlineColor:\"invert\",n$:\"0px\",outlineWidth:\"3px\",paddingBottom:\"0px\",paddingLeft:\"0px\",paddingRight:\"0px\",paddingTop:\"0px\",right:\"auto\",textIndent:\"0px\",textShadow:\"0px 0px 0px transparent\",top:\"auto\",transform:\"\",\nverticalAlign:\"0px\",visibility:\"visible\",width:\"auto\",wordSpacing:\"normal\",zIndex:\"auto\"};b.aP=g})(c,e,null);(function(a,b){function c(b){var c=a.dk(b),e=function(e){return a.bo(c,e,b)};return e.Xg=b.delay+c+b.endDelay,e.sq=function(e){e=a.$J(c,e,b);return e===PhaseActive||e===PhaseBefore},e}b.KeyframeEffect=function(e,g,k,n){var m,q=c(a.pj(k)),v=b.tK(g);g=function(){v(e,m)};return g.bk=function(a){return m=q(a),null!==m},g.O_=function(){v(e,null)},g.XF=function(a){return e===a},g.sq=q.sq,g.Xg=q.Xg,\ng.Kc=n,g};b.YY=function(a){var b=function(){a&&(a(),a=null)};return b.bk=function(){return null},b.Xg=0,b.sq=function(){return!1},b.XF=function(){return!1},b}})(c,e,null);(function(a){a.apply=function(b,c,e){b.style[a.propertyName(c)]=e};a.clear=function(b,c){b.style[a.propertyName(c)]=\"\"}})(e,null);(function(a){window.Element.prototype.animate=function(b,c){var e=\"\";return c&&c.id&&(e=c.id),a.timeline.Vj(a.KeyframeEffect(this,b,c,e))}})(e);(function(a){function b(a,c,e){if(\"number\"==typeof a&&\"number\"==\ntypeof c)return a*(1-e)+c*e;if(\"boolean\"==typeof a&&\"boolean\"==typeof c)return.5>e?a:c;if(a.length==c.length){for(var g=[],k=0;k<a.length;k++)g.push(b(a[k],c[k],e));return g}throw\"Mismatched interpolation arguments \"+a+\":\"+c;}a.ku=function(a,c,e){return function(g){return e(b(a,c,g))}}})(e,null);(function(a,b){a.sC=0;var c=function(a,b){this.target=a;this.currentTime=b;this.type=\"finish\";this.cancelable=this.bubbles=!1;this.currentTarget=a;this.defaultPrevented=!1;this.eventPhase=Event.AT_TARGET;\nthis.timeStamp=Date.now()};b.Animation=function(b){this.id=\"\";b&&b.Kc&&(this.id=b.Kc);this.Xj=a.sC++;this.Ug=0;this.bg=null;this.ag=!1;this.Dg=1;this.Si=this.qq=!0;this.onfinish=null;this.yn=[];this.kc=b;this.Ui=this.kc.bk(0);this.Bg=!0;this.Oj=!1};b.Animation.prototype={Hv:function(){0>this.playbackRate&&0===this.currentTime?this.Ui=this.kc.bk(-1):this.Ui=this.kc.bk(this.currentTime);this.qq||!this.Ui&&this.Si||(this.qq=!0,b.timeline.sf.push(this))},Dq:function(a,b){a!=this.Ug&&(this.Ug=a,this.Sj&&\n!b&&(this.Ug=0<this.Dg?this.Xg:0),this.Hv())},get currentTime(){return this.Bg||this.Oj?null:this.Ug},set currentTime(a){a=+a;isNaN(a)||(b.restart(),this.ag||null==this.bg||(this.bg=this.$j.currentTime-a/this.Dg),this.Oj=!1,this.Ug!=a&&(this.Dq(a,!0),b.rk()))},get startTime(){return this.bg},set startTime(a){a=+a;isNaN(a)||this.ag||this.Bg||(this.bg=a,this.Dq((this.$j.currentTime-this.bg)*this.playbackRate),b.rk())},get playbackRate(){return this.Dg},set playbackRate(a){if(a!=this.Dg){var b=this.currentTime;\nthis.Dg=a;this.bg=null;\"paused\"!=this.playState&&\"idle\"!=this.playState&&this.play();null!=b&&(this.currentTime=b)}},get Sj(){return!this.Bg&&(0<this.Dg&&this.Ug>=this.Xg||0>this.Dg&&0>=this.Ug)},get Xg(){return this.kc.Xg},get playState(){return this.Bg?\"idle\":null==this.bg&&!this.ag&&0!=this.playbackRate||this.Oj?\"pending\":this.ag?\"paused\":this.Sj?\"finished\":\"running\"},play:function(){this.ag=!1;(this.Sj||this.Bg)&&(this.Ug=0<this.Dg?0:this.Xg,this.bg=null);this.Bg=this.Si=!1;this.Hv();b.rk()},\npause:function(){this.Sj||this.ag||this.Bg||(this.Oj=!0);this.bg=null;this.ag=!0},finish:function(){this.Bg||(this.currentTime=0<this.Dg?this.Xg:0,this.bg=this.Xg-this.currentTime,this.Oj=!1,b.rk())},cancel:function(){this.Ui&&(this.Ui=!1,this.Bg=!0,this.Si=!0,this.currentTime=0,this.bg=null,this.kc.bk(null),b.rk())},reverse:function(){this.playbackRate*=-1;this.play()},addEventListener:function(a,b){\"function\"==typeof b&&\"finish\"==a&&this.yn.push(b)},removeEventListener:function(a,b){\"finish\"==a&&\n(a=this.yn.indexOf(b),0<=a&&this.yn.splice(a,1))},IF:function(a){if(this.Sj){if(!this.Si){var b=new c(this,this.Ug,a),e=this.yn.concat(this.onfinish?[this.onfinish]:[]);setTimeout(function(){e.forEach(function(a){a.call(b.target,b)})},0);this.Si=!0}}else this.Si=!1},$G:function(a,b){this.Bg||this.ag||(null==this.bg?b&&(this.startTime=a-this.Ug/this.playbackRate):this.Sj||this.Dq((a-this.bg)*this.playbackRate));b&&(this.Oj=!1,this.IF(a))},get Uv(){return this.playState in{w$:1,Paa:1}||!this.Si}}})(c,\ne,null);(function(a,b){function c(a){var b=q;q=[];a<aa.currentTime&&(a=aa.currentTime);n(a,!0);b.forEach(function(b){b[1](a)});k()}function e(a,b){return a.Xj-b.Xj}function g(){this.sf=[];this.currentTime=window.performance&&performance.now?performance.now():0}function k(){U.forEach(function(a){a()});U.length=0}function n(a,c){ka=!1;var g=b.timeline;g.currentTime=a;g.sf.sort(e);Q=!1;var k=g.sf;g.sf=[];var n=[],m=[],k=k.filter(function(b){b.$G(a,c);b.Ui?m.push(b.kc):n.push(b.kc);b.Uv&&(Q=!0);var e=\nb.Ui||b.Uv;return b.qq=e,e});U.push.apply(U,n);U.push.apply(U,m);g.sf.push.apply(g.sf,k);Q&&requestAnimationFrame(function(){})}var m=window.requestAnimationFrame,q=[],O=0;window.requestAnimationFrame=function(a){var b=O++;return 0==q.length&&m(c),q.push([b,a]),b};window.cancelAnimationFrame=function(a){q.forEach(function(b){b[0]==a&&(b[1]=function(){})})};g.prototype={Vj:function(c){c.Kf=a.pj(c.timing);c=new b.Animation(c);return c.Bg=!1,c.$j=this,this.sf.push(c),b.restart(),b.rk(),c}};var Q=!1,\nka=!1;b.restart=function(){return Q||(Q=!0,requestAnimationFrame(function(){}),ka=!0),ka};b.rk=function(){n(b.timeline.currentTime,!1);k()};var U=[],aa=new g;b.timeline=aa})(c,e,null);(function(a){function b(a,b){var c=a.exec(b);return c?(c=a.ignoreCase?c[0].toLowerCase():c[0],[c,b.substr(c.length)]):void 0}function c(a,b){b=b.replace(/^\\s*/,\"\");return(a=a(b))?[a[0],a[1].replace(/^\\s*/,\"\")]:void 0}function e(a,e,g){a=c.bind(null,a);for(var k=[];;){var n=a(g);if(!n||(k.push(n[0]),g=n[1],n=b(e,g),!n||\n\"\"==n[1]))return[k,g];g=n[1]}}function g(a,b){for(var c=0,e=0;e<b.length&&(!/\\s|,/.test(b[e])||0!=c);e++)if(\"(\"==b[e])c++;else if(\")\"==b[e]&&(c--,0==c&&e++,0>=c))break;a=a(b.substr(0,e));return void 0==a?void 0:[a,b.substr(e)]}function k(a,b){for(var c=a,e=b;c&&e;)c>e?c%=e:e%=c;return a*b/(c+e)}function n(a){return function(b){b=a(b);return b&&(b[0]=void 0),b}}function m(a,b){return function(c){var e=a(c);return e?e:[b,c]}}function K(b,c){for(var e=[],g=0;g<b.length;g++){c=a.sK(b[g],c);if(!c||\"\"==\nc[0])return;void 0!==c[0]&&e.push(c[0]);c=c[1]}return\"\"==c?e:void 0}function O(a,b,c,e,g){for(var n=[],m=[],q=[],v=k(e.length,g.length),B=0;v>B;B++){var C=b(e[B%e.length],g[B%g.length]);if(!C)return;n.push(C[0]);m.push(C[1]);q.push(C[2])}return[n,m,function(b){b=b.map(function(a,b){return q[b](a)}).join(c);return a?a(b):b}]}function Q(a,b,c){for(var e=[],g=[],k=[],n=0,m=0;m<c.length;m++)if(\"function\"==typeof c[m]){var q=c[m](a[n],b[n++]);e.push(q[0]);g.push(q[1]);k.push(q[2])}else!function(a){e.push(!1);\ng.push(!1);k.push(function(){return c[a]})}(m);return[e,g,function(a){for(var b=\"\",c=0;c<a.length;c++)b+=k[c](a[c]);return b}]}a.Al=b;a.sK=c;a.zl=e;a.kr=g;a.as=n;a.optional=m;a.rK=K;a.ss=O.bind(null,null);a.oO=O;a.G8=Q})(e);(function(a){function b(b){function c(b){var c=a.Al(/^inset/i,b);return c?(e.lj=!0,c):(c=a.ix(b))?(e.fg.push(c[0]),c):(c=a.qK(b))?(e.color=c[0],c):void 0}var e={lj:!1,fg:[],color:null};return(b=a.zl(c,/^/,b))&&b[0].length?[e,b[1]]:void 0}function c(c){return(c=a.zl(b,/^,/,c))&&\n\"\"==c[1]?c[0]:void 0}function e(b,c){for(;b.fg.length<Math.max(b.fg.length,c.fg.length);)b.fg.push({px:0});for(;c.fg.length<Math.max(b.fg.length,c.fg.length);)c.fg.push({px:0});if(b.lj==c.lj&&!!b.color==!!c.color){for(var e,g=[],k=[[],0],n=[[],0],m=0;m<b.fg.length;m++){var q=a.Jo(b.fg[m],c.fg[m],2==m);k[0].push(q[0]);n[0].push(q[1]);g.push(q[2])}b.color&&c.color&&(c=a.mO(b.color,c.color),k[1]=c[0],n[1]=c[1],e=c[2]);return[k,n,function(a){for(var c=b.lj?\"inset \":\" \",k=0;k<g.length;k++)c+=g[k](a[0][k])+\n\" \";return e&&(c+=e(a[1])),c}]}}function g(b,c,e,g){function k(a){return{lj:a,color:[0,0,0,0],fg:[{px:0},{px:0},{px:0},{px:0}]}}for(var n=[],m=[],q=0;q<e.length||q<g.length;q++){var v=e[q]||k(g[q].lj),B=g[q]||k(e[q].lj);n.push(v);m.push(B)}return a.ss(b,c,n,m)}var k=g.bind(null,e,\", \");a.cg(c,k,[\"box-shadow\",\"text-shadow\"])})(e);(function(a){function b(a){return a.toFixed(3).replace(\".000\",\"\")}function c(a,b,c){return Math.min(b,Math.max(a,c))}function e(a){return/^\\s*[-+]?(\\d*\\.)?\\d+\\s*$/.test(a)?\nNumber(a):void 0}function g(a,c){return[a,c,b]}function k(a,b){return 0!=a?m(0,1/0)(a,b):void 0}function n(a,b){return[a,b,function(a){return Math.round(c(1,1/0,a))}]}function m(a,e){return function(g,k){return[g,k,function(g){return b(c(a,e,g))}]}}function K(a,b){return[a,b,Math.round]}a.clamp=c;a.cg(e,m(0,1/0),[\"border-image-width\",\"line-height\"]);a.cg(e,m(0,1),[\"opacity\",\"shape-image-threshold\"]);a.cg(e,k,[\"flex-grow\",\"flex-shrink\"]);a.cg(e,n,[\"orphans\",\"widows\"]);a.cg(e,K,[\"z-index\"]);a.RO=e;\na.nO=g;a.WB=b})(e,null);(function(a){function b(a,b){return\"visible\"==a||\"visible\"==b?[0,1,function(c){return 0>=c?a:1<=c?b:\"visible\"}]:void 0}a.cg(String,b,[\"visibility\"])})(e);(function(a){function b(a){a=a.trim();g.fillStyle=\"#000\";g.fillStyle=a;var b=g.fillStyle;if(g.fillStyle=\"#fff\",g.fillStyle=a,b==g.fillStyle)return g.fillRect(0,0,1,1),a=g.getImageData(0,0,1,1).data,g.clearRect(0,0,1,1),b=a[3]/255,[a[0]*b,a[1]*b,a[2]*b,b]}function c(b,c){return[b,c,function(b){if(b[3])for(var c=0;3>c;c++)b[c]=\nMath.round(Math.max(0,Math.min(255,b[c]/b[3])));return b[3]=a.WB(a.clamp(0,1,b[3])),\"rgba(\"+b.join(\",\")+\")\"}]}var e=document.createElementNS(\"http://www.w3.org/1999/xhtml\",\"canvas\");e.width=e.height=1;var g=e.getContext(\"2d\");a.cg(b,c,\"background-color border-bottom-color border-left-color border-right-color border-top-color color outline-color text-decoration-color\".split(\" \"));a.qK=a.kr.bind(null,b);a.mO=c})(e,null);(function(a){function b(a,b){if(b=b.trim().toLowerCase(),\"0\"==b&&0<=\"px\".search(a))return{px:0};\nif(/^[^(]*$|^calc/.test(b)){b=b.replace(/calc\\(/g,\"(\");var c={};b=b.replace(a,function(a){return c[a]=null,\"U\"+a});a=\"U(\"+a.source+\")\";for(var e=b.replace(/[-+]?(\\d*\\.)?\\d+/g,\"N\").replace(new RegExp(\"N\"+a,\"g\"),\"D\").replace(/\\s[+-]\\s/g,\"O\").replace(/\\s/g,\"\"),g=[/N\\*(D)/g,/(N|D)[*\\/]N/g,/(N|D)O\\1/g,/\\((N|D)\\)/g],k=0;k<g.length;)g[k].test(e)?(e=e.replace(g[k],\"$1\"),k=0):k++;if(\"D\"==e){for(var n in c){e=(0,eval)(b.replace(new RegExp(\"U\"+n,\"g\"),\"\").replace(new RegExp(a,\"g\"),\"*0\"));if(!isFinite(e))return;\nc[n]=e}return c}}}function c(a,b){return e(a,b,!0)}function e(b,c,e){var g,k=[];for(g in b)k.push(g);for(g in c)0>k.indexOf(g)&&k.push(g);return b=k.map(function(a){return b[a]||0}),c=k.map(function(a){return c[a]||0}),[b,c,function(b){var c=b.map(function(c,g){return 1==b.length&&e&&(c=Math.max(c,0)),a.WB(c)+k[g]}).join(\" + \");return 1<b.length?\"calc(\"+c+\")\":c}]}var g=b.bind(null,/px|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc/g),k=b.bind(null,/px|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|%/g),\nn=b.bind(null,/deg|rad|grad|turn/g);a.PO=g;a.QO=k;a.ix=a.kr.bind(null,k);a.OO=n;a.Jo=e;var g=a.kr.bind(null,g),g=a.zl.bind(void 0,g,/^/),m=a.zl.bind(void 0,g,/^,/);a.e4=m;var g=function(a){return(a=m(a))&&\"\"==a[1]?a[0]:void 0},n=a.ss.bind(void 0,c,\" \"),K=a.ss.bind(void 0,n,\",\");a.H8=n;a.cg(g,K,[\"background-size\"]);a.cg(k,c,\"border-bottom-width border-image-width border-left-width border-right-width border-top-width flex-basis font-size height line-height max-height max-width outline-width width\".split(\" \"));\na.cg(k,e,\"border-bottom-left-radius border-bottom-right-radius border-top-left-radius border-top-right-radius bottom left letter-spacing margin-bottom margin-left margin-right margin-top min-height min-width outline-offset padding-bottom padding-left padding-right padding-top perspective right shape-margin text-indent top vertical-align word-spacing\".split(\" \"))})(e,null);(function(a){function b(b){return a.ix(b)||a.Al(/^auto/,b)}function c(c){return(c=a.rK([a.as(a.Al.bind(null,/^rect/)),a.as(a.Al.bind(null,\n/^\\(/)),a.zl.bind(null,b,/^,/),a.as(a.Al.bind(null,/^\\)/))],c))&&4==c[0].length?c[0]:void 0}function e(b,c){return\"auto\"==b||\"auto\"==c?[!0,!1,function(e){e=e?b:c;if(\"auto\"==e)return\"auto\";e=a.Jo(e,e);return e[2](e[0])}]:a.Jo(b,c)}function g(a){return\"rect(\"+a+\")\"}var k=a.oO.bind(null,g,e,\", \");a.t$=c;a.F8=k;a.cg(c,k,[\"clip\"])})(e,null);(function(a){function b(a){return function(b){var c=0;return a.map(function(a){return a===K?b[c++]:a})}}function c(a){return a}function e(b){if(b=b.toLowerCase().trim(),\n\"none\"==b)return[];for(var c,e=/\\s*(\\w+)\\(([^)]*)\\)/g,g=[],k=0;(c=e.exec(b))&&c.index==k;){var k=c.index+c[0].length,n=c[1],m=ka[n];if(!m)break;c=c[2].split(\",\");m=m[0];if(m.length<c.length)break;for(var q=[],v=0;v<m.length;v++){var B,C=c[v],E=m[v];if(B=C?{gp:function(b){return\"0\"==b.trim()?Q:a.OO(b)},pe:a.RO,d_:a.QO,sb:a.PO}[E.toUpperCase()](C):{a:Q,n:q[0],t:O}[E],void 0===B)return;q.push(B)}if(g.push({t:n,d:q}),e.lastIndex==b.length)return g}}function g(a){return a.toFixed(6).replace(\".000000\",\n\"\")}function k(b,c){if(b.sr!==c){b.sr=c;var e=a.JB(b)}if(c.sr!==b){c.sr=b;var k=a.JB(c)}return null==e[0]||null==k[0]?[[!1],[!0],function(a){return a?c[0].d:b[0].d}]:(e[0].push(0),k[0].push(1),[e,k,function(b){var c=a.iaa(e[0][3],k[0][3],b[5]);b=a.K3(b[0],b[1],b[2],c,b[4]);return b=b.map(g).join(\",\")}])}function n(a){return a.replace(/(x|y|z|3d)?$/,\"3d\")}function m(b,c){var e=a.JB&&!0,g=!1;if(!b.length||!c.length){b.length||(g=!0,b=c,c=[]);for(var m=0;m<b.length;m++){var q=b[m].t,v=b[m].d,B=\"scale\"==\nq.substr(0,5)?1:0;c.push({t:q,d:v.map(function(a){if(\"number\"==typeof a)return B;var b={},c;for(c in a)b[c]=B;return b})})}}var v=[],C=[],E=[];if(b.length!=c.length){if(!e)return;var J=k(b,c),v=[J[0]],C=[J[1]],E=[[\"matrix\",[J[2]]]]}else for(m=0;m<b.length;m++){var q=b[m].t,K=c[m].t,O=b[m].d,Q=c[m].d,W=ka[q],U=ka[K];if(\"perspective\"==q&&\"perspective\"==K||!(\"matrix\"!=q&&\"matrix3d\"!=q||\"matrix\"!=K&&\"matrix3d\"!=K)){if(!e)return;J=k([b[m]],[c[m]]);v.push(J[0]);C.push(J[1]);E.push([\"matrix\",[J[2]]])}else{if(q!=\nK)if(W[2]&&U[2]&&q.replace(/[xy]/,\"\")==K.replace(/[xy]/,\"\"))q=q.replace(/[xy]/,\"\"),O=W[2](O),Q=U[2](Q);else{if(!W[1]||!U[1]||n(q)!=n(K)){if(!e)return;J=k(b,c);v=[J[0]];C=[J[1]];E=[[\"matrix\",[J[2]]]];break}q=n(q);O=W[1](O);Q=U[1](Q)}for(var W=[],U=[],K=[],aa=0;aa<O.length;aa++)J=\"number\"==typeof O[aa]?a.nO:a.Jo,J=J(O[aa],Q[aa]),W[aa]=J[0],U[aa]=J[1],K.push(J[2]);v.push(W);C.push(U);E.push([q,K])}}g&&(b=v,v=C,C=b);return[v,C,function(a){return a.map(function(a,b){a=a.map(function(a,c){return E[b][1][c](a)}).join(\",\");\nreturn\"matrix\"==E[b][0]&&16==a.split(\",\").length&&(E[b][0]=\"matrix3d\"),E[b][0]+\"(\"+a+\")\"}).join(\" \")}]}var K=null,O={px:0},Q={V4:0},ka={matrix:[\"NNNNNN\",[K,K,0,0,K,K,0,0,0,0,1,0,K,K,0,1],c],v8:[\"NNNNNNNNNNNNNNNN\",c],rotate:[\"A\"],Laa:[\"A\"],Maa:[\"A\"],Naa:[\"A\"],Kaa:[\"NNNA\"],perspective:[\"L\"],scale:[\"Nn\",b([K,K,1]),c],Vaa:[\"N\",b([K,1,1]),b([K,1])],Waa:[\"N\",b([1,K,1]),b([1,K])],Xaa:[\"N\",b([1,1,K])],Taa:[\"NNN\",c],wba:[\"Aa\",null,c],xba:[\"A\",null,b([K,Q])],yba:[\"A\",null,b([Q,K])],translate:[\"Tt\",b([K,K,O]),\nc],$ca:[\"T\",b([K,O,O]),b([K,O])],ada:[\"T\",b([O,K,O]),b([O,K])],bda:[\"L\",b([O,O,K])],translate3d:[\"TTL\",c]};a.cg(e,m,[\"transform\"])})(e,null);(function(a){function b(a,b){b.concat([a]).forEach(function(b){b in document.documentElement.style&&(c[a]=b)})}var c={};b(\"transform\",[\"webkitTransform\",\"msTransform\"]);b(\"transformOrigin\",[\"webkitTransformOrigin\"]);b(\"perspective\",[\"webkitPerspective\"]);b(\"perspectiveOrigin\",[\"webkitPerspectiveOrigin\"]);a.propertyName=function(a){return c[a]||a}})(e,null)})();\n!function(){if(void 0===document.createElement(\"div\").animate([]).oncancel){var a;a=window.performance&&performance.now?function(){return performance.now()}:function(){return Date.now()};var b=function(a,b){this.target=a;this.currentTime=b;this.type=\"cancel\";this.cancelable=this.bubbles=!1;this.currentTarget=a;this.defaultPrevented=!1;this.eventPhase=Event.AT_TARGET;this.timeStamp=Date.now()},c=window.Element.prototype.animate;window.Element.prototype.animate=function(e,g){e=c.call(this,e,g);e.un=\n[];e.oncancel=null;var k=e.cancel;e.cancel=function(){k.call(this);var c=new b(this,null,a()),e=this.un.concat(this.oncancel?[this.oncancel]:[]);setTimeout(function(){e.forEach(function(a){a.call(c.target,c)})},0)};var n=e.addEventListener;e.addEventListener=function(a,b){\"function\"==typeof b&&\"cancel\"==a?this.un.push(b):n.call(this,a,b)};var m=e.removeEventListener;return e.removeEventListener=function(a,b){\"cancel\"==a?(a=this.un.indexOf(b),0<=a&&this.un.splice(a,1)):m.call(this,a,b)},e}}}();(function(a){var b=\ndocument.documentElement,c=null,e=!1;try{var g=getComputedStyle(b).getPropertyValue(\"opacity\"),g=\"0\"==g?\"1\":\"0\",c=b.animate({opacity:[g,g]},{duration:1});c.currentTime=0;e=getComputedStyle(b).getPropertyValue(\"opacity\")==g}catch(C){}finally{c&&c.cancel()}if(!e){var k=window.Element.prototype.animate;window.Element.prototype.animate=function(b,c){return window.Symbol&&Symbol.iterator&&Array.prototype.from&&b[Symbol.iterator]&&(b=Array.from(b)),Array.isArray(b)||null===b||(b=a.uK(b)),k.call(this,b,\nc)}}})(c);!function(a,b){function c(a){var b=window.document.timeline;b.currentTime=a;b.Ev();0==b.sf.length?g=!1:requestAnimationFrame(c)}var e=window.requestAnimationFrame;window.requestAnimationFrame=function(a){return e(function(b){window.document.timeline.nl();a(b);window.document.timeline.nl()})};b.AnimationTimeline=function(){this.sf=[];this.currentTime=void 0};b.AnimationTimeline.prototype={getAnimations:function(){return this.Ev(),this.sf.slice()},nl:function(){b.Wn=b.Wn.filter(function(a){return a.Vc()})},\nEv:function(){this.nl();this.sf=this.sf.filter(function(a){return\"finished\"!=a.playState&&\"idle\"!=a.playState})},Vj:function(a){a=new b.Animation(a,this);return this.sf.push(a),b.TP(),a.Vc(),a.hb.play(),a.Vc(),a},play:function(a){return a&&a.remove(),this.Vj(a)}};var g=!1;b.TP=function(){g||(g=!0,requestAnimationFrame(c))};var k=new b.AnimationTimeline;b.timeline=k;try{Object.defineProperty(window.document,\"timeline\",{configurable:!0,get:function(){return k}})}catch(C){}try{window.document.timeline=\nk}catch(C){}}(c,g,null);(function(a,b){b.Wn=[];b.Animation=function(b,c){if(this.id=\"\",b&&b.Kc&&(this.id=b.Kc),this.effect=b,b&&(b.hb=this),!c)throw Error(\"Animation with null timeline is not supported\");this.$j=c;this.Xj=a.sC++;this.pq=0;this.Fn=this.ag=!1;this.hb=null;this.Pi=[];this.cl=null;this.Xv=\"idle\";this.hl();this.hb.cancel();this.Vc()};b.Animation.prototype={Vc:function(){var a=this.Xv,b=this.playState;return this.Wj&&b!==a&&(\"idle\"==b?(this.KG(),this.Wj=void 0):\"pending\"==a?this.lw():\"pending\"==\nb&&(this.Wj=void 0)),this.nq&&b!==a&&(\"idle\"==b?(this.h1(),this.nq=void 0):\"finished\"==b?this.l1():\"finished\"==a&&(this.nq=void 0)),this.Xv=this.playState,this.Wj||this.nq},hl:function(){this.Vc();var a,c,e,g,k=!!this.hb;k&&(a=this.playbackRate,c=this.ag,e=this.startTime,g=this.currentTime,this.hb.cancel(),this.hb.Vn=null,this.hb=null);(!this.effect||this.effect instanceof window.KeyframeEffect)&&(this.hb=b.CO(this.effect),b.WJ(this));(this.effect instanceof window.SequenceEffect||this.effect instanceof\nwindow.GroupEffect)&&(this.hb=b.BO(this.effect),b.VJ(this));this.effect&&this.effect.bw&&b.Uw(this);k&&(1!=a&&(this.playbackRate=a),null!==e?this.startTime=e:null!==g?this.currentTime=g:null!==this.pq&&(this.currentTime=this.pq),c&&this.pause());this.Vc()},jH:function(){if(this.effect&&\"idle\"!=this.playState){var a=this.effect.Kf.delay;this.Pi.forEach(function(c){this.sv(c,a);this.effect instanceof window.SequenceEffect&&(a+=b.aB(c.effect))}.bind(this))}},qw:function(a){if(this.effect&&this.Fn)for(var b=\n0;b<this.effect.children.length;b++)this.effect.children[b].hb=a,this.Pi[b].qw(a)},Bv:function(){if(this.effect&&this.Fn){var a=this.effect.Kf.delay;this.il();this.effect.children.forEach(function(c){var e=window.document.timeline.Vj(c);this.Pi.push(e);e.playbackRate=this.playbackRate;this.ag&&e.pause();c.hb=this.effect.hb;this.sv(e,a);this.effect instanceof window.SequenceEffect&&(a+=b.aB(c))}.bind(this))}},sv:function(a,b){null===this.startTime?a.currentTime=this.currentTime-b/this.playbackRate:\na.startTime!==this.startTime+b/this.playbackRate&&(a.startTime=this.startTime+b/this.playbackRate)},get timeline(){return this.$j},get playState(){return this.hb?this.hb.playState:\"idle\"},get ready(){return window.Promise?(this.Wj||(-1==b.Wn.indexOf(this)&&b.Wn.push(this),this.Wj=new Promise(function(a,b){this.lw=function(){a(this)};this.KG=function(){b({type:DOMException.ABORT_ERR,name:\"AbortError\"})}}.bind(this)),\"pending\"!==this.playState&&this.lw()),this.Wj):(console.warn(\"Animation Promises require JavaScript Promise constructor\"),\nnull)},get onfinish(){return this.hb.onfinish},set onfinish(a){\"function\"==typeof a?this.hb.onfinish=function(b){b.target=this;a.call(this,b)}.bind(this):this.hb.onfinish=a},get oncancel(){return this.hb.oncancel},set oncancel(a){\"function\"==typeof a?this.hb.oncancel=function(b){b.target=this;a.call(this,b)}.bind(this):this.hb.oncancel=a},get currentTime(){this.Vc();var a=this.hb.currentTime;return this.Vc(),a},set currentTime(a){this.Vc();this.hb.currentTime=isFinite(a)?a:Math.sign(a)*Number.MAX_VALUE;\nthis.Zh();this.Ti(function(b,c){b.currentTime=a-c});this.Vc()},get startTime(){return this.hb.startTime},set startTime(a){this.Vc();this.hb.startTime=isFinite(a)?a:Math.sign(a)*Number.MAX_VALUE;this.Zh();this.Ti(function(b,c){b.startTime=a+c});this.Vc()},get playbackRate(){return this.hb.playbackRate},set playbackRate(a){this.Vc();var b=this.currentTime;this.hb.playbackRate=a;this.Ti(function(b){b.playbackRate=a});\"paused\"!=this.playState&&\"idle\"!=this.playState&&this.play();null!==b&&(this.currentTime=\nb);this.Vc()},play:function(){this.Vc();this.ag=!1;this.hb.play();-1==this.$j.sf.indexOf(this)&&this.$j.sf.push(this);this.Zh();b.Qw(this);this.Ti(function(a){var b=a.currentTime;a.play();a.currentTime=b});this.Vc()},pause:function(){this.Vc();this.currentTime&&(this.pq=this.currentTime);this.hb.pause();this.Zh();this.Ti(function(a){a.pause()});this.ag=!0;this.Vc()},finish:function(){this.Vc();this.hb.finish();this.Zh();this.Vc()},cancel:function(){this.Vc();this.hb.cancel();this.Zh();this.il();this.Vc()},\nreverse:function(){this.Vc();var a=this.currentTime;this.hb.reverse();this.Ti(function(a){a.reverse()});null!==a&&(this.currentTime=a);this.Vc()},addEventListener:function(a,b){var c=b;\"function\"==typeof b&&(c=function(a){a.target=this;b.call(this,a)}.bind(this),b.Vn=c);this.hb.addEventListener(a,c)},removeEventListener:function(a,b){this.hb.removeEventListener(a,b&&b.Vn||b)},il:function(){for(;this.Pi.length;)this.Pi.pop().cancel()},Ti:function(b){var c=0;if(this.effect.children&&this.Pi.length<\nthis.effect.children.length&&this.Bv(),this.Pi.forEach(function(a){b.call(this,a,c);this.effect instanceof window.SequenceEffect&&(c+=a.effect.rl)}.bind(this)),\"pending\"!=this.playState){var e=this.effect.Kf,g=this.currentTime;null!==g&&(g=a.bo(a.dk(e),g,e));(null==g||isNaN(g))&&this.il()}}};window.Animation=b.Animation})(c,g,null);(function(a,b){function c(b){this.OF=a.TB(b)}function e(){for(var a=!1;E.length;)a=E.shift(),a.jH(),a=!0;return a}var g=function(a){if(a.hb=void 0,a instanceof window.SequenceEffect||\na instanceof window.GroupEffect)for(var b=0;b<a.children.length;b++)g(a.children[b])};b.Ds=function(a){for(var b=[],c=0;c<a.length;c++){var e=a[c];e.Ye?(-1==b.indexOf(e.Ye)&&b.push(e.Ye),e.Ye.children.splice(e.Ye.children.indexOf(e),1),e.Ye=null,g(e)):e.hb&&e.hb.effect==e&&(e.hb.cancel(),e.hb.effect=new KeyframeEffect(null,[]),e.hb.cl&&(e.hb.cl.hb=null),e.hb.hl(),g(e))}for(c=0;c<b.length;c++)b[c].fw()};b.KeyframeEffect=function(b,e,g,k){return this.target=b,this.Ye=null,g=a.ws(g),this.ak=a.io(g),\nthis.Kf=a.pj(g),this.timing=a.KB(g,!1,this),this.timing.kc=this,\"function\"==typeof e?(a.IK(\"Custom KeyframeEffect\",\"2015-06-22\",\"Use KeyframeEffect.onsample instead.\"),this.Xi=e):this.Xi=new c(e),this.tq=e,this.rl=a.dk(this.Kf),this.Kc=k,this};b.KeyframeEffect.prototype={getFrames:function(){return\"function\"==typeof this.Xi?this.Xi:this.Xi.OF},set onsample(a){if(\"function\"==typeof this.getFrames())throw Error(\"Setting onsample on custom effect KeyframeEffect is not supported.\");this.bw=a;this.hb&&\nthis.hb.hl()},get parent(){return this.Ye},clone:function(){if(\"function\"==typeof this.getFrames())throw Error(\"Cloning custom effects is not supported.\");var b=new KeyframeEffect(this.target,[],a.io(this.ak),this.Kc);return b.Xi=this.Xi,b.tq=this.tq,b},remove:function(){b.Ds([this])}};var k=Element.prototype.animate;Element.prototype.animate=function(a,c){var e=\"\";return c&&c.id&&(e=c.id),b.timeline.Vj(new b.KeyframeEffect(this,a,c,e))};var m=document.createElementNS(\"http://www.w3.org/1999/xhtml\",\n\"div\");b.CO=function(a){if(a){var b=a.target||m,c=a.tq;\"function\"==typeof c&&(c=[]);var e=a.ak;e.id=a.Kc}else b=m,c=[],e=0;return k.apply(b,[c,e])};b.WJ=function(a){a.effect&&\"function\"==typeof a.effect.Xi&&b.Uw(a)};var E=[];b.Qw=function(a){null===a.startTime&&a.Fn&&(0==E.length&&requestAnimationFrame(e),E.push(a))};var W=window.getComputedStyle;Object.defineProperty(window,\"getComputedStyle\",{configurable:!0,enumerable:!0,value:function(){window.document.timeline.nl();var a=W.apply(this,arguments);\nreturn e()&&(a=W.apply(this,arguments)),window.document.timeline.nl(),a}});window.KeyframeEffect=b.KeyframeEffect;window.Element.prototype.getAnimations=function(){return document.timeline.getAnimations().filter(function(a){return null!==a.effect&&a.effect.target==this}.bind(this))}})(c,g,null);(function(a,b){function c(a){a.Kn||(a.Kn=!0,k.push(a),m||(m=!0,requestAnimationFrame(e)))}function e(){var a=k;k=[];a.sort(function(a,b){return a.Xj-b.Xj});a=a.filter(function(a){a();var b=a.hb?a.hb.playState:\n\"idle\";return\"running\"!=b&&\"pending\"!=b&&(a.Kn=!1),a.Kn});k.push.apply(k,a);k.length?(m=!0,requestAnimationFrame(e)):m=!1}var g=(document.createElementNS(\"http://www.w3.org/1999/xhtml\",\"div\"),0);b.Uw=function(b){var e,k=b.effect.target,n=\"function\"==typeof b.effect.getFrames();e=n?b.effect.getFrames():b.effect.bw;var m=b.effect.timing,q=null,m=a.pj(m),v=function(){var c=v.hb?v.hb.currentTime:null;null!==c&&(c=a.bo(a.dk(m),c,m),isNaN(c)&&(c=null));c!==q&&(n?e(c,k,b.effect):e(c,b.effect,b.effect.hb));\nq=c};v.hb=b;v.Kn=!1;v.Xj=g++;b.cl=v;c(v)};var k=[],m=!1;b.Animation.prototype.Zh=function(){this.cl&&c(this.cl)}})(c,g,null);(function(a,b){function c(a){return a.Kf.delay+a.rl+a.Kf.endDelay}function e(b,c,e){this.Kc=e;this.Ye=null;this.children=b||[];this.iw(this.children);c=a.ws(c);this.ak=a.io(c);this.Kf=a.pj(c,!0);this.timing=a.KB(c,!0,this);this.timing.kc=this;\"auto\"===this.Kf.duration&&(this.Kf.duration=this.rl)}window.SequenceEffect=function(){e.apply(this,arguments)};window.GroupEffect=function(){e.apply(this,\narguments)};e.prototype={ZF:function(a){for(var b=this;null!==b;){if(b==a)return!0;b=b.Ye}return!1},fw:function(){for(var a=this;a;)\"auto\"===a.timing.duration&&(a.Kf.duration=a.rl),a=a.Ye;this.hb&&this.hb.hl()},iw:function(a){b.Ds(a);for(var c=0;c<a.length;c++)a[c].Ye=this},ew:function(a,b){for(var c=b?\"Cannot append an ancestor or self\":\"Cannot prepend an ancestor or self\",e=0;e<a.length;e++)if(this.ZF(a[e]))throw{type:DOMException.HIERARCHY_REQUEST_ERR,name:\"HierarchyRequestError\",message:c};for(e=\n0;e<a.length;e++)b?this.children.push(a[e]):this.children.unshift(a[e]);this.iw(a);this.fw()},append:function(){this.ew(arguments,!0)},prepend:function(){this.ew(arguments,!1)},get parent(){return this.Ye},get firstChild(){return this.children.length?this.children[0]:null},get lastChild(){return this.children.length?this.children[this.children.length-1]:null},clone:function(){for(var b=a.io(this.ak),c=[],e=0;e<this.children.length;e++)c.push(this.children[e].clone());return this instanceof GroupEffect?\nnew GroupEffect(c,b):new SequenceEffect(c,b)},remove:function(){b.Ds([this])}};window.SequenceEffect.prototype=Object.create(e.prototype);Object.defineProperty(window.SequenceEffect.prototype,\"activeDuration\",{get:function(){var a=0;return this.children.forEach(function(b){a+=c(b)}),Math.max(a,0)}});window.GroupEffect.prototype=Object.create(e.prototype);Object.defineProperty(window.GroupEffect.prototype,\"activeDuration\",{get:function(){var a=0;return this.children.forEach(function(b){a=Math.max(a,\nc(b))}),a}});b.BO=function(c){var e,g=null,k=function(b){var c=e.Vn;return c&&\"pending\"!=c.playState&&c.effect?null==b?void c.il():0==b&&0>c.playbackRate&&(g||(g=a.pj(c.effect.timing)),b=a.bo(a.dk(g),-1,g),isNaN(b)||null==b)?(c.Ti(function(a){a.currentTime=-1}),void c.il()):void 0:void 0};c=new KeyframeEffect(null,[],c.Kf,c.Kc);return c.onsample=k,e=b.timeline.Vj(c)};b.VJ=function(a){a.hb.Vn=a;a.Fn=!0;b.Qw(a);a.Bv();a.qw(a)};b.aB=c})(c,g,null);b[\"true\"]=a}({},function(){return this}())})();\nV.Gi.np={};V.Gi.np.bZ={};Polymer({is:\"opaque-animation\",behaviors:[Polymer.Rh],bj:function(a){var b=a.node;b.style.opacity=\"0\";return this.kc=new KeyframeEffect(b,[{opacity:\"1\"},{opacity:\"1\"}],this.zj(a))},complete:function(a){a.node.style.opacity=\"\"}});V.Gi.Fu={};\nPolymer.Fu={properties:{animationConfig:{type:Object},entryAnimation:{observer:\"f0\",type:String},exitAnimation:{observer:\"g0\",type:String}},f0:function(){this.animationConfig=this.animationConfig||{};this.animationConfig.entry=\"fade-in-animation\"!==this.entryAnimation?[{name:\"opaque-animation\",node:this},{name:this.entryAnimation,node:this}]:[{name:this.entryAnimation,node:this}]},g0:function(){this.animationConfig=this.animationConfig||{};this.animationConfig.exit=[{name:this.exitAnimation,node:this}]},\nCv:function(a,b){for(var c in b)a[c]=b[c]},nF:function(a){var b={pN:!0};this.Cv(b,a);return b},Lv:function(a,b,c){if(this.animationConfig)if(this.animationConfig.value&&\"function\"===typeof this.animationConfig.value)this._warn(this._logf(\"playAnimation\",\"Please put 'animationConfig' inside of your components 'properties' object instead of outside of it.\"));else{var e;e=a?this.animationConfig[a]:this.animationConfig;Array.isArray(e)||(e=[e]);if(e)for(var g,k=0;g=e[k];k++)if(g.HJ)g.HJ.Lv(g.type||a,\nb,c);else if(g.id){var m=b[g.id];m?(m.pN||(b[g.id]=this.nF(m),m=b[g.id]),this.Cv(m,g)):b[g.id]=g}else c.push(g)}},fL:function(a){var b={},c=[];this.Lv(a,b,c);for(var e in b)c.push(b[e]);return c}};V.Gi.Ep={};\nPolymer.aE={properties:{_player:{type:Object}},rF:function(a){var b=[];if(0<a.length)for(var c,e=0;c=a[e];e++){var g=document.createElement(c.name);if(g.zN){var k=g.bj(c);k&&b.push({IJ:g,gx:c,effect:k})}else Polymer.Base._warn(this.is+\":\",c.name,\"not found!\")}return b},OG:function(a){return document.timeline.play(new GroupEffect(a))},pF:function(a){for(var b,c=0;b=a[c];c++)b.IJ.complete(b.gx)},Oo:function(a,b){if(a=this.fL(a)){var c=this.rF(a);a=c.map(function(a){return a.effect});0<a.length?(this._player=\nthis.OG(a),this._player.onfinish=function(){this.pF(c);this._player&&(this._player.cancel(),this._player=null);this.fire(\"neon-animation-finish\",b,{bubbles:!1})}.bind(this)):this.fire(\"neon-animation-finish\",b,{bubbles:!1})}},eo:function(){this._player&&this._player.cancel()}};Polymer.Ep=[Polymer.Fu,Polymer.aE];V.Qh={};V.Qh.ou={};\n(function(){var a=Element.prototype,b=a.matches||a.matchesSelector||a.mozMatchesSelector||a.msMatchesSelector||a.oMatchesSelector||a.webkitMatchesSelector;Polymer.ou={CM:function(a){var b=[];return(a=this.yv(a,b))?this.Bq(b):b},rB:function(a){return b.call(a,\"input, select, textarea, button, object\")?b.call(a,\":not([disabled])\"):b.call(a,\"a[href], area[href], iframe, [tabindex], [contentEditable]\")},R7:function(a){return this.rB(a)&&b.call(a,':not([tabindex\\x3d\"-1\"])')&&this.Ov(a)},oG:function(a){return this.rB(a)?\n(a=a.getAttribute(\"tabindex\")||0,Number(a)):-1},yv:function(a,b){if(a.nodeType!==Node.ELEMENT_NODE||!this.Ov(a))return!1;var c=a,e=this.oG(c);a=0<e;0<=e&&b.push(c);c=\"content\"===c.localName?Polymer.dom(c).getDistributedNodes():Polymer.dom(c.root||c).children;for(e=0;e<c.length;e++){var m=this.yv(c[e],b);a=a||m}return a},Ov:function(a){var b=a.style;return\"hidden\"!==b.visibility&&\"none\"!==b.display?(b=window.getComputedStyle(a),\"hidden\"!==b.visibility&&\"none\"!==b.display):!1},Bq:function(a){var b=\na.length;if(2>b)return a;var c=Math.ceil(b/2),b=this.Bq(a.slice(0,c));a=this.Bq(a.slice(c));return this.kG(b,a)},kG:function(a,b){for(var c=[];0<a.length&&0<b.length;)this.WF(a[0],b[0])?c.push(b.shift()):c.push(a.shift());return c.concat(a,b)},WF:function(a,b){a=Math.max(a.tabIndex,0);b=Math.max(b.tabIndex,0);return 0===a||0===b?b>a:a>b}}})();V.Qh.nY={};\nPolymer({is:\"iron-overlay-backdrop\",properties:{opened:{reflectToAttribute:!0,type:Boolean,value:!1,observer:\"Yh\"}},listeners:{transitionend:\"$0\"},created:function(){this.$k=null},attached:function(){this.opened&&this.Yh(this.opened)},YO:function(){this.opened&&!this.parentNode&&Polymer.dom(document.body).appendChild(this)},open:function(){this.opened=!0},close:function(){this.opened=!1},complete:function(){this.opened||this.parentNode!==document.body||Polymer.dom(this.parentNode).removeChild(this)},\n$0:function(a){a&&a.target===this&&this.complete()},Yh:function(a){a?this.YO():(a=window.getComputedStyle(this),\"0s\"!==a.transitionDuration&&0!=a.opacity||this.complete());this.isAttached&&(this.$k&&(window.cancelAnimationFrame(this.$k),this.$k=null),this.scrollTop=this.scrollTop,this.$k=window.requestAnimationFrame(function(){this.$k=null;this.toggleClass(\"opened\",this.opened)}.bind(this)))}});V.Qh.vu={};\nPolymer.Ap=function(){this.Me=[];this.Hn=101;this.rn=null;Polymer.Gestures.add(document,\"tap\",this.vq.bind(this));document.addEventListener(\"focus\",this.wq.bind(this),!0);document.addEventListener(\"keydown\",this.tG.bind(this),!0)};\nPolymer.Ap.prototype={constructor:Polymer.Ap,get Xn(){this.rn||(this.rn=document.createElement(\"iron-overlay-backdrop\"));return this.rn},get sx(){for(var a=document.activeElement||document.body;a.root&&Polymer.dom(a.root).activeElement;)a=Polymer.dom(a.root).activeElement;return a},jF:function(a){var b=this.Me[a];if(b){var c=this.Me.length-1,e=this.Me[c];e&&this.rw(b,e)&&c--;if(!(a>=c)){e=Math.max(this.AK(),this.Hn);for(this.Pj(b)<=e&&this.$p(b,e);a<c;)this.Me[a]=this.Me[a+1],a++;this.Me[c]=b}}},\nRI:function(a){var b=this.Me.indexOf(a);if(0<=b)this.jF(b);else{var b=this.Me.length,c=this.Me[b-1],e=Math.max(this.Pj(c),this.Hn),g=this.Pj(a);c&&this.rw(a,c)&&(this.$p(c,e),b--,c=this.Me[b-1],e=Math.max(this.Pj(c),this.Hn));g<=e&&this.$p(a,e);this.Me.splice(b,0,a)}this.yt()},gC:function(a){a=this.Me.indexOf(a);-1!==a&&(this.Me.splice(a,1),this.yt())},Cl:function(){var a=this.Me.length-1;return this.Me[a]},AK:function(){return this.Pj(this.Cl())},yt:function(){var a=this.FG();if(a||this.rn)this.Xn.style.zIndex=\nthis.Pj(a)-1,this.Xn.opened=!!a},FG:function(){for(var a=0;a<this.Me.length;a++)if(this.Me[a].withBackdrop)return this.Me[a]},Pj:function(a){var b=this.Hn;a&&(a=Number(a.style.zIndex||window.getComputedStyle(a).zIndex),a===a&&(b=a));return b},UG:function(a,b){a.style.zIndex=b},$p:function(a,b){this.UG(a,b+2)},DG:function(a){a=a||[];for(var b=0;b<a.length;b++)if(a[b]._manager===this)return a[b]},vq:function(a){var b=this.Cl();b&&this.DG(Polymer.dom(a).path)!==b&&b.vq(a)},wq:function(a){var b=this.Cl();\nb&&b.wq(a)},tG:function(a){var b=this.Cl();b&&(Polymer.mg.Ho(a,\"esc\")?b.sG(a):Polymer.mg.Ho(a,\"tab\")&&b.vG(a))},rw:function(a,b){return!a.alwaysOnTop&&b.alwaysOnTop}};Polymer.vu=new Polymer.Ap;V.Xm={};V.Xm.Xm={};\nPolymer.Xm={properties:{sizingTarget:{type:Object,value:function(){return this}},fitInto:{type:Object,value:window},noOverlap:{type:Boolean},positionTarget:{type:Element},horizontalAlign:{type:String},verticalAlign:{type:String},dynamicAlign:{type:Boolean},horizontalOffset:{type:Number,value:0,notify:!0},verticalOffset:{type:Number,value:0,notify:!0},autoFitOnAttach:{type:Boolean,value:!1},_fitInfo:{type:Object}},get k0(){var a;return a=this.fitInto===window?this.fitInto.innerWidth:this.fitInto.getBoundingClientRect().width},\nget h0(){var a;return a=this.fitInto===window?this.fitInto.innerHeight:this.fitInto.getBoundingClientRect().height},get i0(){var a;return a=this.fitInto===window?0:this.fitInto.getBoundingClientRect().left},get j0(){var a;return a=this.fitInto===window?0:this.fitInto.getBoundingClientRect().top},get sF(){var a=Polymer.dom(this).parentNode;a&&a.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&(a=a.host);return a},get gG(){if(this.aG){if(\"right\"===this.horizontalAlign)return\"left\";if(\"left\"===this.horizontalAlign)return\"right\"}return this.horizontalAlign},\nattached:function(){this.aG=\"rtl\"==window.getComputedStyle(this).direction;this.positionTarget=this.positionTarget||this.sF;this.autoFitOnAttach&&(\"none\"===window.getComputedStyle(this).display?setTimeout(function(){this.fit()}.bind(this)):this.fit())},fit:function(){this.position();this.oK();this.center()},jq:function(){if(!this._fitInfo){var a=window.getComputedStyle(this),b=window.getComputedStyle(this.sizingTarget);this._fitInfo={pk:{top:this.style.top||\"\",left:this.style.left||\"\",position:this.style.position||\n\"\"},yC:{maxWidth:this.sizingTarget.style.maxWidth||\"\",maxHeight:this.sizingTarget.style.maxHeight||\"\",boxSizing:this.sizingTarget.style.boxSizing||\"\"},om:{Km:\"auto\"!==a.top?\"top\":\"auto\"!==a.bottom?\"bottom\":null,fm:\"auto\"!==a.left?\"left\":\"auto\"!==a.right?\"right\":null},Zo:{height:\"none\"!==b.maxHeight,width:\"none\"!==b.maxWidth,minWidth:parseInt(b.minWidth,10)||0,minHeight:parseInt(b.minHeight,10)||0},margin:{top:parseInt(a.marginTop,10)||0,right:parseInt(a.marginRight,10)||0,bottom:parseInt(a.marginBottom,\n10)||0,left:parseInt(a.marginLeft,10)||0}};this.verticalOffset&&(this._fitInfo.margin.top=this._fitInfo.margin.bottom=this.verticalOffset,this._fitInfo.pk.marginTop=this.style.marginTop||\"\",this._fitInfo.pk.marginBottom=this.style.marginBottom||\"\",this.style.marginTop=this.style.marginBottom=this.verticalOffset+\"px\");this.horizontalOffset&&(this._fitInfo.margin.left=this._fitInfo.margin.right=this.horizontalOffset,this._fitInfo.pk.marginLeft=this.style.marginLeft||\"\",this._fitInfo.pk.marginRight=\nthis.style.marginRight||\"\",this.style.marginLeft=this.style.marginRight=this.horizontalOffset+\"px\")}},OP:function(){var a=this._fitInfo||{},b;for(b in a.yC)this.sizingTarget.style[b]=a.yC[b];for(b in a.pk)this.style[b]=a.pk[b];this._fitInfo=null},As:function(){var a=this.sizingTarget.scrollLeft,b=this.sizingTarget.scrollTop;this.OP();this.fit();this.sizingTarget.scrollLeft=a;this.sizingTarget.scrollTop=b},position:function(){if(this.horizontalAlign||this.verticalAlign){this.jq();this.style.position=\n\"fixed\";this.sizingTarget.style.boxSizing=\"border-box\";this.style.left=\"0px\";this.style.top=\"0px\";var a=this.getBoundingClientRect(),b=this.qn(this.positionTarget),c=this.qn(this.fitInto),e=this._fitInfo.margin,g={width:a.width+e.left+e.right,height:a.height+e.top+e.bottom},g=this.eF(this.gG,this.verticalAlign,g,b,c),b=g.left+e.left,g=g.top+e.top,k=Math.min(c.right-e.right,b+a.width),c=Math.min(c.bottom-e.bottom,g+a.height),m=this._fitInfo.Zo.minWidth,n=this._fitInfo.Zo.minHeight;b<e.left&&(b=e.left,\nk-b<m&&(b=k-m));g<e.top&&(g=e.top,c-g<n&&(g=c-n));this.sizingTarget.style.maxWidth=k-b+\"px\";this.sizingTarget.style.maxHeight=c-g+\"px\";this.style.left=b-a.left+\"px\";this.style.top=g-a.top+\"px\"}},oK:function(){if(!this.horizontalAlign&&!this.verticalAlign){this.jq();var a=this._fitInfo;a.om.Km||(this.style.position=\"fixed\",this.style.top=\"0px\");a.om.fm||(this.style.position=\"fixed\",this.style.left=\"0px\");this.sizingTarget.style.boxSizing=\"border-box\";var b=this.getBoundingClientRect();a.Zo.height||\nthis.Yp(b,a.om.Km,\"top\",\"bottom\",\"Height\");a.Zo.width||this.Yp(b,a.om.fm,\"left\",\"right\",\"Width\")}},t1:function(a,b,c,e,g){this.Yp(a,b,c,e,g)},Yp:function(a,b,c,e,g){var k=this._fitInfo,m=this.qn(this.fitInto),m=\"Width\"===g?m.width:m.height;a=(b=b===e)?m-a[e]:a[c];c=k.margin[b?c:e];e=\"offset\"+g;e=this[e]-this.sizingTarget[e];this.sizingTarget.style[\"max\"+g]=m-c-a-e+\"px\"},center:function(){if(!this.horizontalAlign&&!this.verticalAlign){this.jq();var a=this._fitInfo.om;if(!a.Km||!a.fm){this.style.position=\n\"fixed\";a.Km||(this.style.top=\"0px\");a.fm||(this.style.left=\"0px\");var b=this.getBoundingClientRect(),c=this.qn(this.fitInto);if(!a.Km){var e=c.top-b.top+(c.height-b.height)/2;this.style.top=e+\"px\"}a.fm||(a=c.left-b.left+(c.width-b.width)/2,this.style.left=a+\"px\")}}},qn:function(a){return a===document.documentElement||a===window?{top:0,left:0,width:window.innerWidth,height:window.innerHeight,right:window.innerWidth,bottom:window.innerHeight}:a.getBoundingClientRect()},dF:function(a,b,c){var e=Math.min(0,\na.top)+Math.min(0,c.bottom-(a.top+b.height));a=Math.min(0,a.left)+Math.min(0,c.right-(a.left+b.width));return Math.abs(e)*b.width+Math.abs(a)*b.height},eF:function(a,b,c,e,g){var k=[{verticalAlign:\"top\",horizontalAlign:\"left\",top:e.top,left:e.left},{verticalAlign:\"top\",horizontalAlign:\"right\",top:e.top,left:e.right-c.width},{verticalAlign:\"bottom\",horizontalAlign:\"left\",top:e.bottom-c.height,left:e.left},{verticalAlign:\"bottom\",horizontalAlign:\"right\",top:e.bottom-c.height,left:e.right-c.width}];\nif(this.noOverlap){for(var m=0,n=k.length;m<n;m++){var q={},v;for(v in k[m])q[v]=k[m][v];k.push(q)}k[0].top=k[1].top+=e.height;k[2].top=k[3].top-=e.height;k[4].left=k[6].left+=e.width;k[5].left=k[7].left-=e.width}b=\"auto\"===b?null:b;a=\"auto\"===a?null:a;for(var B,m=0;m<k.length;m++){e=k[m];if(!this.dynamicAlign&&!this.noOverlap&&e.verticalAlign===b&&e.horizontalAlign===a){B=e;break}n=(!b||e.verticalAlign===b)&&(!a||e.horizontalAlign===a);if(this.dynamicAlign||n){B=B||e;e.or=this.dF(e,c,g);q=e.or-B.or;\nif(0>q||0===q&&n)B=e;if(0===B.or&&n)break}}return B}};V.Qh.Qh={};\nPolymer.Lk={properties:{opened:{observer:\"Yh\",type:Boolean,value:!1,notify:!0},canceled:{observer:\"L_\",readOnly:!0,type:Boolean,value:!1},withBackdrop:{observer:\"H1\",type:Boolean},noAutoFocus:{type:Boolean,value:!1},noCancelOnEscKey:{type:Boolean,value:!1},noCancelOnOutsideClick:{type:Boolean,value:!1},closingReason:{type:Object},restoreFocusOnClose:{type:Boolean,value:!1},alwaysOnTop:{type:Boolean},_manager:{type:Object,value:Polymer.vu},_focusedChild:{type:Object}},listeners:{\"iron-resize\":\"U0\"},\nget Xn(){return this._manager.Xn},get An(){return this._focusedChild||Polymer.dom(this).querySelector(\"[autofocus]\")||this},get LF(){return Polymer.ou.CM(this)},ready:function(){this.Xp=this.Yk=!1;this.al=this.Mi=this.Xk=this.Zk=null;this.CF()},attached:function(){this.opened&&this.Yh(this.opened);this.gl=Polymer.dom(this).observeNodes(this.zG)},detached:function(){Polymer.dom(this).unobserveNodes(this.gl);this.gl=null;this.Mi&&(window.cancelAnimationFrame(this.Mi),this.Mi=null);this._manager.gC(this)},\ntoggle:function(){this._setCanceled(!1);this.opened=!this.opened},open:function(){this._setCanceled(!1);this.opened=!0},close:function(){this._setCanceled(!1);this.opened=!1},cancel:function(a){a=this.fire(\"iron-overlay-canceled\",a,{cancelable:!0});a.defaultPrevented||(this._setCanceled(!0),this.opened=!1)},kN:function(){this.Xk=this.Zk=null},CF:function(){this.EG||(this.EG=!0,this.style.outline=\"none\",this.style.display=\"none\")},Yh:function(a){a?this.removeAttribute(\"aria-hidden\"):this.setAttribute(\"aria-hidden\",\n\"true\");this.isAttached&&(this.Yk=!0,this.jv(this.fF))},L_:function(){this.closingReason=this.closingReason||{};this.closingReason.canceled=this.canceled},H1:function(){this.withBackdrop&&!this.hasAttribute(\"tabindex\")?(this.setAttribute(\"tabindex\",\"-1\"),this.Xp=!0):this.Xp&&(this.removeAttribute(\"tabindex\"),this.Xp=!1);this.opened&&this.isAttached&&this._manager.yt()},HG:function(){this.al=this._manager.sx;this.GG();this.As();this.HF();this.noAutoFocus&&document.activeElement===this.An&&(this.An.blur(),\nthis.al.focus())},Mn:function(){this.mq()},Ln:function(){this.lq()},mq:function(){this.ri();this.Yk=!1;this.fire(\"iron-overlay-opened\")},lq:function(){this.style.display=\"none\";this.style.zIndex=\"\";this.ri();this.Yk=!1;this.fire(\"iron-overlay-closed\",this.closingReason)},GG:function(){this.style.transition=this.style.webkitTransition=\"none\";this.style.transform=this.style.webkitTransform=\"none\";this.style.display=\"\"},HF:function(){this.style.display=\"none\";this.scrollTop=this.scrollTop;this.style.transition=\nthis.style.webkitTransition=\"\";this.style.transform=this.style.webkitTransform=\"\";this.style.display=\"\";this.scrollTop=this.scrollTop},Oi:function(){if(this.opened)this.noAutoFocus||this.An.focus();else{this.An.blur();this._focusedChild=null;this.restoreFocusOnClose&&this.al&&this.al.focus();this.al=null;var a=this._manager.Cl();a&&this!==a&&a.Oi()}},vq:function(a){this.noCancelOnOutsideClick||this.cancel(a)},wq:function(a){if(this.withBackdrop){var b=Polymer.dom(a).path;-1===b.indexOf(this)?(a.stopPropagation(),\nthis.Oi()):this._focusedChild=b[0]}},sG:function(a){this.noCancelOnEscKey||this.cancel(a)},vG:function(a){if(this.withBackdrop){this.cF();var b=a.shiftKey,c=b?this.Xk:this.Zk,b=b?this.Zk:this.Xk;if(c===b)c=!0;else var e=this._manager.sx,c=e===c||e===this;c&&(a.preventDefault(),this._focusedChild=b,this.Oi())}},U0:function(){this.opened&&!this.Yk&&this.jv(this.As)},zG:function(){this.opened&&!this.Yk&&(this.kN(),this.ri())},cF:function(){if(!this.Xk||!this.Zk){var a=this.LF;this.Xk=a[0];this.Zk=a[a.length-\n1]}},fF:function(){this.opened?(this.HG(),this._manager.RI(this),this.Oi(),this.Mn()):(this._manager.gC(this),this.Oi(),this.Ln())},jv:function(a){this.Mi&&window.cancelAnimationFrame(this.Mi);var b=this;this.Mi=window.requestAnimationFrame(function(){b.Mi=null;a.call(b)})}};Polymer.Qh=[Polymer.Xm,Polymer.Jj,Polymer.Lk];V.Qk={};V.Qk.Qk={};\nPolymer.nE={hostAttributes:{role:\"dialog\",tabindex:\"-1\"},properties:{modal:{type:Boolean,value:!1}},observers:[\"F0(modal,_readied)\"],listeners:{tap:\"M0\"},ready:function(){this.lv=this.noCancelOnOutsideClick;this.kv=this.noCancelOnEscKey;this.mv=this.withBackdrop},F0:function(a,b){b&&(a?(this.lv=this.noCancelOnOutsideClick,this.kv=this.noCancelOnEscKey,this.mv=this.withBackdrop,this.withBackdrop=this.noCancelOnEscKey=this.noCancelOnOutsideClick=!0):(this.noCancelOnOutsideClick=this.noCancelOnOutsideClick&&\nthis.lv,this.noCancelOnEscKey=this.noCancelOnEscKey&&this.kv,this.withBackdrop=this.withBackdrop&&this.mv))},kH:function(a){this.closingReason=this.closingReason||{};this.closingReason.c4=a},M0:function(a){for(var b=Polymer.dom(a).path,c=0;c<b.indexOf(this);c++){var e=b[c];if(e.hasAttribute&&(e.hasAttribute(\"dialog-dismiss\")||e.hasAttribute(\"dialog-confirm\"))){this.kH(e.hasAttribute(\"dialog-confirm\"));this.close();a.stopPropagation();break}}}};Polymer.Qk=[Polymer.Qh,Polymer.nE];V.zD={};V.zD.FZ={};\nV.Vf.LE={};V.Qk.lZ={};V.Qu={};V.Qu.Qu={};Polymer({is:\"paper-dialog\",behaviors:[Polymer.Qk,Polymer.Ep],listeners:{\"neon-animation-finish\":\"yG\"},Mn:function(){this.eo();this.Oo(\"entry\")},Ln:function(){this.eo();this.Oo(\"exit\")},yG:function(){this.opened?this.mq():this.lq()}});V.Rk={};V.Rk.mZ={};V.Rk.oZ={};V.Qg={};V.Qg.Qg={};\nPolymer.Qg={properties:{name:{type:String},value:{notify:!0,type:String},required:{type:Boolean,value:!1},_parentForm:{type:Object}},attached:function(){this.fire(\"iron-form-element-register\")},detached:function(){this._parentForm&&this._parentForm.fire(\"iron-form-element-unregister\",{target:this})}};V.Rg={};V.Rg.Rg={};Polymer.Dp=null;\nPolymer.Rg={properties:{validator:{type:String},invalid:{notify:!0,reflectToAttribute:!0,type:Boolean,value:!1},_validatorMeta:{type:Object},validatorType:{type:String,value:\"validator\"},_validator:{type:Object,computed:\"A_(validator)\"}},observers:[\"YF(invalid)\"],registered:function(){Polymer.Dp=new Polymer.Ph({type:\"validator\"})},YF:function(){this.invalid?this.setAttribute(\"aria-invalid\",\"true\"):this.removeAttribute(\"aria-invalid\")},Zr:function(){return null!=this._validator},ah:function(a){this.invalid=\n!this.Cn(a);return!this.invalid},Cn:function(a){return this.Zr()?this._validator.ah(a):!0},A_:function(){return Polymer.Dp&&Polymer.Dp.er(this.validator)}};V.ph={};V.ph.Jp={};Polymer.hn={};Polymer.hn.cE=1;Polymer.hn.bE=1;\nPolymer.oE={properties:{label:{type:String},value:{notify:!0,type:String},disabled:{type:Boolean,value:!1},invalid:{type:Boolean,value:!1,notify:!0},preventInvalidInput:{type:Boolean},allowedPattern:{type:String},type:{type:String},list:{type:String},pattern:{type:String},required:{type:Boolean,value:!1},errorMessage:{type:String},charCounter:{type:Boolean,value:!1},noLabelFloat:{type:Boolean,value:!1},alwaysFloatLabel:{type:Boolean,value:!1},autoValidate:{type:Boolean,value:!1},validator:{type:String},\nautocomplete:{type:String,value:\"off\"},autofocus:{type:Boolean,observer:\"J_\"},inputmode:{type:String},minlength:{type:Number},maxlength:{type:Number},min:{type:String},max:{type:String},step:{type:String},name:{type:String},placeholder:{type:String,value:\"\"},readonly:{type:Boolean,value:!1},size:{type:Number},autocapitalize:{type:String,value:\"none\"},autocorrect:{type:String,value:\"off\"},autosave:{type:String},results:{type:Number},accept:{type:String},multiple:{type:Boolean},_ariaDescribedBy:{type:String,\nvalue:\"\"},_ariaLabelledBy:{type:String,value:\"\"}},listeners:{\"addon-attached\":\"qG\"},$g:{\"shift+tab:keydown\":\"AG\"},hostAttributes:{tabindex:0},get Ig(){return this.$.input},get Bn(){return this.Ig},registered:function(){this.eH=\"date datetime datetime-local month time week file\".split(\" \")},attached:function(){this.iH();this.Ig&&-1!==this.eH.indexOf(this.Ig.type)&&(this.alwaysFloatLabel=!0)},rv:function(a,b){return a=a?a+\" \"+b:b},qG:function(a){a=a.path?a.path[0]:a.target;if(a.id)this._ariaDescribedBy=\nthis.rv(this._ariaDescribedBy,a.id);else{var b=\"paper-input-add-on-\"+Polymer.hn.bE++;a.id=b;this._ariaDescribedBy=this.rv(this._ariaDescribedBy,b)}},ah:function(){return this.Ig.ah()},zn:function(a){Polymer.ng.zn.call(this,a);this.focused&&!this.Yj&&this.Bn.focus()},AG:function(){var a=this.getAttribute(\"tabindex\");this.Yj=!0;this.setAttribute(\"tabindex\",\"-1\");this.async(function(){this.setAttribute(\"tabindex\",a);this.Yj=!1},1)},o0:function(){this.autoValidate&&this.ah()},oda:function(a){try{var b=\nthis.Ig.selectionStart;this.value=a;this.Ig.selectionStart=b;this.Ig.selectionEnd=b}catch(c){this.value=a}},Q_:function(a,b){return b||a},iH:function(){var a=Polymer.dom(this.root).querySelector(\"label\");if(a){var b;a.id?b=a.id:(b=\"paper-input-label-\"+Polymer.hn.cE++,a.id=b);this._ariaLabelledBy=b}else this._ariaLabelledBy=\"\"},J0:function(a){this.shadowRoot&&this.fire(a.type,{sourceEvent:a},{node:this,bubbles:a.bubbles,cancelable:a.cancelable})},J_:function(){if(this.autofocus&&this.Bn){var a=document.activeElement,\nb=a instanceof HTMLElement;(a=b&&a!==document.body&&a!==document.documentElement)||this.Bn.focus()}}};Polymer.Jp=[Polymer.ng,Polymer.mg,Polymer.oE];V.ph.Ip={};Polymer.Ip={hostAttributes:{\"add-on\":\"\"},attached:function(){this.fire(\"addon-attached\")},update:function(){}};V.ph.rZ={};\nPolymer({is:\"paper-input-char-counter\",behaviors:[Polymer.Ip],properties:{_charCounterStr:{type:String,value:\"0\"}},update:function(a){if(a.Ig){a.value=a.value||\"\";var b=a.value.toString().length.toString();a.Ig.hasAttribute(\"maxlength\")&&(b+=\"/\"+a.Ig.getAttribute(\"maxlength\"));this._charCounterStr=b}}});V.ph.sZ={};\nPolymer({is:\"paper-input-container\",properties:{noLabelFloat:{type:Boolean,value:!1},alwaysFloatLabel:{type:Boolean,value:!1},attrForValue:{type:String,value:\"bind-value\"},autoValidate:{type:Boolean,value:!1},invalid:{observer:\"YF\",type:Boolean,value:!1},focused:{readOnly:!0,type:Boolean,value:!1,notify:!0},_addons:{type:Array},_inputHasContent:{type:Boolean,value:!1},_inputSelector:{type:String,value:\"input,textarea,.paper-input-input\"},_boundOnFocus:{type:Function,value:function(){return this.Yv.bind(this)}},\n_boundOnBlur:{type:Function,value:function(){return this.rG.bind(this)}},_boundOnInput:{type:Function,value:function(){return this.In.bind(this)}},_boundValueChanged:{type:Function,value:function(){return this.aw.bind(this)}}},listeners:{\"addon-attached\":\"qG\",\"iron-input-validate\":\"R0\"},get oH(){return this.attrForValue+\"-changed\"},get JG(){return Polymer.CaseMap.dashToCamelCase(this.attrForValue)},get Vh(){return Polymer.dom(this).querySelector(this._inputSelector)},get rq(){return this.Vh[this.JG]||\nthis.Vh.value},ready:function(){this._addons||(this._addons=[]);this.addEventListener(\"focus\",this._boundOnFocus,!0);this.addEventListener(\"blur\",this._boundOnBlur,!0)},attached:function(){this.attrForValue?this.Vh.addEventListener(this.oH,this._boundValueChanged):this.addEventListener(\"input\",this.In);\"\"!=this.rq?this.Dn(this.Vh):this.oq(this.Vh)},qG:function(a){this._addons||(this._addons=[]);a=a.target;-1===this._addons.indexOf(a)&&(this._addons.push(a),this.isAttached&&this.oq(this.Vh))},Yv:function(){this._setFocused(!0)},\nrG:function(){this._setFocused(!1);this.Dn(this.Vh)},In:function(a){this.Dn(a.target)},aw:function(a){this.Dn(a.target)},oq:function(a){var b=this.rq;b||0===b||\"number\"===a.type&&!a.checkValidity()?this._inputHasContent=!0:this._inputHasContent=!1;this.KC({Ig:a,value:b,invalid:this.invalid})},Dn:function(a){if(this.autoValidate){var b;b=a.ah?a.ah(this.rq):a.checkValidity();this.invalid=!b}this.oq(a)},R0:function(){this.invalid=this.Vh.invalid},YF:function(){this._addons&&this.KC({invalid:this.invalid})},\nKC:function(a){for(var b,c=0;b=this._addons[c];c++)b.update(a)},X_:function(a,b,c,e,g){var k=\"input-content\";a?g&&(k+=\" label-is-hidden\"):(a=this.querySelector(\"label\"),b||g?(k+=\" label-is-floating\",this.$.labelAndInputContainer.style.position=\"static\",e?k+=\" is-invalid\":c&&(k+=\" label-is-highlighted\")):a&&(this.$.labelAndInputContainer.style.position=\"relative\"));return k},b0:function(a,b){var c=\"underline\";b?c+=\" is-invalid\":a&&(c+=\" is-highlighted\");return c},P_:function(a,b){var c=\"add-on-content\";\nb?c+=\" is-invalid\":a&&(c+=\" is-highlighted\");return c}});V.ph.tZ={};Polymer({is:\"paper-input-error\",behaviors:[Polymer.Ip],properties:{invalid:{readOnly:!0,reflectToAttribute:!0,type:Boolean}},update:function(a){this._setInvalid(a.invalid)}});V.lg={};V.lg.lg={};Polymer.lg=function(){};\nPolymer.lg=Polymer({is:\"iron-a11y-announcer\",properties:{mode:{type:String,value:\"polite\"},_text:{type:String,value:\"\"}},created:function(){Polymer.lg.im||(Polymer.lg.im=this);document.body.addEventListener(\"iron-announce\",this.wG.bind(this))},JJ:function(a){this._text=\"\";this.async(function(){this._text=a},100)},wG:function(a){a.detail&&a.detail.text&&this.JJ(a.detail.text)}});Polymer.lg.im=null;\nPolymer.lg.LP=function(){Polymer.lg.im||(Polymer.lg.im=document.createElement(\"iron-a11y-announcer\"));document.body.appendChild(Polymer.lg.im)};V.su={};V.su.su={};\nPolymer({is:\"iron-input\",extends:\"input\",behaviors:[Polymer.Rg],properties:{bindValue:{observer:\"iF\",type:String},preventInvalidInput:{type:Boolean},allowedPattern:{type:String,observer:\"E_\"},_previousValidInput:{type:String,value:\"\"},_patternAlreadyChecked:{type:Boolean,value:!1}},listeners:{input:\"In\",keypress:\"W0\"},registered:function(){this.kF()||(this.CG=this.dispatchEvent,this.dispatchEvent=this.wF)},created:function(){Polymer.lg.LP()},kF:function(){var a=document.createElement(\"input\"),b=!1;\na.disabled=!0;a.addEventListener(\"feature-check-dispatch-event\",function(){b=!0});try{a.dispatchEvent(new Event(\"feature-check-dispatch-event\"))}catch(c){}return b},wF:function(){var a=this.disabled;this.disabled=!1;this.CG.apply(this,arguments);this.disabled=a},get cw(){var a;if(this.allowedPattern)a=new RegExp(this.allowedPattern);else switch(this.type){case \"number\":a=/[0-9.,e-]/}return a},ready:function(){this.bindValue=this.value},iF:function(){this.value!==this.bindValue&&(this.value=this.bindValue||\n0===this.bindValue||!1===this.bindValue?this.bindValue:\"\");this.fire(\"bind-value-changed\",{value:this.bindValue})},E_:function(){this.preventInvalidInput=this.allowedPattern?!0:!1},In:function(){if(this.preventInvalidInput&&!this._patternAlreadyChecked){var a=this.mF();a||(this.qv(\"Invalid string of characters not entered.\"),this.value=this._previousValidInput)}this._previousValidInput=this.bindValue=this.value;this._patternAlreadyChecked=!1},$F:function(a){var b=8==a.keyCode||9==a.keyCode||13==a.keyCode||\n27==a.keyCode,c=19==a.keyCode||20==a.keyCode||45==a.keyCode||46==a.keyCode||144==a.keyCode||145==a.keyCode||32<a.keyCode&&41>a.keyCode||111<a.keyCode&&124>a.keyCode;return!b&&!(0==a.charCode&&c)},W0:function(a){if(this.preventInvalidInput||\"number\"===this.type){var b=this.cw;if(b&&!(a.metaKey||a.ctrlKey||a.altKey)){this._patternAlreadyChecked=!0;var c=String.fromCharCode(a.charCode);this.$F(a)&&!b.test(c)&&(a.preventDefault(),this.qv(\"Invalid character \"+c+\" not entered.\"))}}},mF:function(){var a=\nthis.cw;if(!a)return!0;for(var b=0;b<this.value.length;b++)if(!a.test(this.value[b]))return!1;return!0},ah:function(){var a=this.checkValidity();a&&(this.required&&\"\"===this.value?a=!1:this.Zr()&&(a=Polymer.Rg.ah.call(this,this.value)));this.invalid=!a;this.fire(\"iron-input-validate\");return a},qv:function(a){this.fire(\"iron-announce\",{text:a})}});V.ph.ph={};Polymer({is:\"paper-input\",behaviors:[Polymer.Qg,Polymer.Jp]});V.jn={};V.jn.xZ={};\nPolymer({is:\"paper-menu-grow-height-animation\",behaviors:[Polymer.Rh],bj:function(a){var b=a.node,c=b.getBoundingClientRect(),c=c.height;return this.kc=new KeyframeEffect(b,[{height:c/2+\"px\"},{height:c+\"px\"}],this.zj(a))}});Polymer({is:\"paper-menu-grow-width-animation\",behaviors:[Polymer.Rh],bj:function(a){var b=a.node,c=b.getBoundingClientRect(),c=c.width;return this.kc=new KeyframeEffect(b,[{width:c/2+\"px\"},{width:c+\"px\"}],this.zj(a))}});\nPolymer({is:\"paper-menu-shrink-width-animation\",behaviors:[Polymer.Rh],bj:function(a){var b=a.node,c=b.getBoundingClientRect(),c=c.width;return this.kc=new KeyframeEffect(b,[{width:c+\"px\"},{width:c-c/20+\"px\"}],this.zj(a))}});\nPolymer({is:\"paper-menu-shrink-height-animation\",behaviors:[Polymer.Rh],bj:function(a){var b=a.node,c=b.getBoundingClientRect(),c=c.height;this.lU(b,\"transformOrigin\",\"0 0\");return this.kc=new KeyframeEffect(b,[{height:c+\"px\",transform:\"translateY(0)\"},{height:c/2+\"px\",transform:\"translateY(-20px)\"}],this.zj(a))}});V.zp={};V.zp.Wm={};\n(function(){var a={pageX:0,pageY:0},b=null,c=[];Polymer.Wm={get ox(){return this.Xh[this.Xh.length-1]},m5:function(a){var b=this.ox;if(void 0===b)return!1;if(this.UF(a))return!0;if(this.VF(a))return!1;(b=!!b&&b!==a&&!this.zv(b,a))?this.Gn.push(a):this.Rn.push(a);return b},cP:function(a){0<=this.Xh.indexOf(a)||(0===this.Xh.length&&this.hG(),this.Xh.push(a),this.Gn=[],this.Rn=[])},hC:function(a){a=this.Xh.indexOf(a);-1!==a&&(this.Xh.splice(a,1),this.Gn=[],this.Rn=[],0===this.Xh.length&&this.fH())},\nXh:[],Gn:null,Rn:null,UF:function(a){return-1<this.Gn.indexOf(a)},VF:function(a){return-1<this.Rn.indexOf(a)},zv:function(a,b){var c,e,g;if(a.contains(b))return!0;a=Polymer.dom(a).querySelectorAll(\"content\");for(e=0;e<a.length;++e)for(c=Polymer.dom(a[e]).getDistributedNodes(),g=0;g<c.length;++g)if(this.zv(c[g],b))return!0;return!1},QG:function(b){b.cancelable&&this.VG(b)&&b.preventDefault();b.targetTouches&&(b=b.targetTouches[0],a.pageX=b.pageX,a.pageY=b.pageY)},hG:function(){this.Ag=this.Ag||this.QG.bind(this);\ndocument.addEventListener(\"wheel\",this.Ag,!0);document.addEventListener(\"mousewheel\",this.Ag,!0);document.addEventListener(\"DOMMouseScroll\",this.Ag,!0);document.addEventListener(\"touchstart\",this.Ag,!0);document.addEventListener(\"touchmove\",this.Ag,!0)},fH:function(){document.removeEventListener(\"wheel\",this.Ag,!0);document.removeEventListener(\"mousewheel\",this.Ag,!0);document.removeEventListener(\"DOMMouseScroll\",this.Ag,!0);document.removeEventListener(\"touchstart\",this.Ag,!0);document.removeEventListener(\"touchmove\",\nthis.Ag,!0)},VG:function(a){var e=Polymer.dom(a).rootTarget;\"touchmove\"!==a.type&&b!==e&&(b=e,c=this.QF(Polymer.dom(a).path));if(!c.length)return!0;if(\"touchstart\"===a.type)return!1;a=this.PF(a);return!this.RF(c,a.deltaX,a.deltaY)},QF:function(a){for(var b=[],c=a.indexOf(this.ox),e=0;e<=c;e++)if(a[e].nodeType===Node.ELEMENT_NODE){var n=a[e],q=n.style;\"scroll\"!==q.overflow&&\"auto\"!==q.overflow&&(q=window.getComputedStyle(n));\"scroll\"!==q.overflow&&\"auto\"!==q.overflow||b.push(n)}return b},RF:function(a,\nb,c){if(b||c)for(var e=Math.abs(c)>=Math.abs(b),g=0;g<a.length;g++){var k=a[g],v;if(v=e?0>c?0<k.scrollTop:k.scrollTop<k.scrollHeight-k.clientHeight:0>b?0<k.scrollLeft:k.scrollLeft<k.scrollWidth-k.clientWidth)return k}},PF:function(b){var c={deltaX:b.deltaX,deltaY:b.deltaY};\"deltaX\"in b||(\"wheelDeltaX\"in b?(c.deltaX=-b.wheelDeltaX,c.deltaY=-b.wheelDeltaY):\"axis\"in b?(c.deltaX=1===b.axis?b.detail:0,c.deltaY=2===b.axis?b.detail:0):b.targetTouches&&(b=b.targetTouches[0],c.deltaX=a.pageX-b.pageX,c.deltaY=\na.pageY-b.pageY));return c}}})();V.zp.zp={};\nPolymer({is:\"iron-dropdown\",behaviors:[Polymer.ng,Polymer.mg,Polymer.Qh,Polymer.Ep],properties:{horizontalAlign:{type:String,value:\"left\",reflectToAttribute:!0},verticalAlign:{type:String,value:\"top\",reflectToAttribute:!0},openAnimationConfig:{type:Object},closeAnimationConfig:{type:Object},focusTarget:{type:Object},noAnimations:{type:Boolean,value:!1},allowOutsideScroll:{type:Boolean,value:!1},_boundOnCaptureScroll:{type:Function,value:function(){return this.uG.bind(this)}}},listeners:{\"neon-animation-finish\":\"yG\"},\nobservers:[\"D1(positionTarget,verticalAlign,horizontalAlign,verticalOffset,horizontalOffset)\"],get ko(){return Polymer.dom(this.$.content).getDistributedNodes()[0]},get l0(){return this.focusTarget||this.ko},ready:function(){this.jl=this.kl=0;this.yq=null},attached:function(){this.sizingTarget&&this.sizingTarget!==this||(this.sizingTarget=this.ko||this)},detached:function(){this.eo();document.removeEventListener(\"scroll\",this._boundOnCaptureScroll);Polymer.Wm.hC(this)},Yh:function(){this.opened&&\nthis.disabled?this.cancel():(this.eo(),this.hH(),this.PG(),this.opened?(document.addEventListener(\"scroll\",this._boundOnCaptureScroll),!this.allowOutsideScroll&&Polymer.Wm.cP(this)):(document.removeEventListener(\"scroll\",this._boundOnCaptureScroll),Polymer.Wm.hC(this)),Polymer.Lk.Yh.apply(this,arguments))},Mn:function(){!this.noAnimations&&this.animationConfig.open?(this.$.contentWrapper.classList.add(\"animating\"),this.Oo(\"open\")):Polymer.Lk.Mn.apply(this,arguments)},Ln:function(){!this.noAnimations&&\nthis.animationConfig.close?(this.$.contentWrapper.classList.add(\"animating\"),this.Oo(\"close\")):Polymer.Lk.Ln.apply(this,arguments)},yG:function(){this.$.contentWrapper.classList.remove(\"animating\");this.opened?this.mq():this.lq()},uG:function(){this.allowOutsideScroll?(this.yq&&window.cancelAnimationFrame(this.yq),this.yq=window.requestAnimationFrame(this.As.bind(this))):this.NG()},PG:function(){document.scrollingElement?(this.kl=document.scrollingElement.scrollTop,this.jl=document.scrollingElement.scrollLeft):\n(this.kl=Math.max(document.documentElement.scrollTop,document.body.scrollTop),this.jl=Math.max(document.documentElement.scrollLeft,document.body.scrollLeft))},NG:function(){document.scrollingElement?(document.scrollingElement.scrollTop=this.kl,document.scrollingElement.scrollLeft=this.jl):(document.documentElement.scrollTop=this.kl,document.documentElement.scrollLeft=this.jl,document.body.scrollTop=this.kl,document.body.scrollLeft=this.jl)},hH:function(){for(var a=this.ko,b=[].concat(this.openAnimationConfig||\n[]).concat(this.closeAnimationConfig||[]),c=0;c<b.length;c++)b[c].node=a;this.animationConfig={open:this.openAnimationConfig,close:this.closeAnimationConfig}},D1:function(){this.isAttached&&this.ri()},Oi:function(){var a=this.focusTarget||this.ko;a&&this.opened&&!this.noAutoFocus?a.focus():Polymer.Lk.Oi.apply(this,arguments)}});V.Gi.np.SX={};Polymer({is:\"fade-in-animation\",behaviors:[Polymer.Rh],bj:function(a){var b=a.node;return this.kc=new KeyframeEffect(b,[{opacity:\"0\"},{opacity:\"1\"}],this.zj(a))}});\nV.Gi.np.TX={};Polymer({is:\"fade-out-animation\",behaviors:[Polymer.Rh],bj:function(a){var b=a.node;return this.kc=new KeyframeEffect(b,[{opacity:\"1\"},{opacity:\"0\"}],this.zj(a))}});var Lw=function(){};d=Lw.prototype;d.registered=function(){};d.SI=function(){};d.vP=function(){};d.Ho=function(){};d.xv=function(){};d.Jn=function(){};d.Zp=function(){};d.Aq=function(){};d.uq=function(){};d.Gq=function(){};d.$v=function(){};d.ww=function(){};\nd.zn=function(a){if(a.target===this)this._setFocused(\"focus\"===a.type);else if(!this.shadowRoot){var b=Polymer.dom(a).localTarget;this.isLightDescendant(b)||this.fire(a.type,{sourceEvent:a},{node:this,bubbles:a.bubbles,cancelable:a.cancelable})}};d.lF=function(){this.vn&&this.vn()};d._setFocused=function(){};V.jn.jn={};\n(function(){var a={hp:\"cubic-bezier(.3,.95,.5,1)\",IY:400};Lw=Polymer({is:\"paper-menu-button\",behaviors:[Polymer.mg,Polymer.ng],properties:{opened:{type:Boolean,value:!1,notify:!0,observer:\"Yh\"},horizontalAlign:{type:String,value:\"left\",reflectToAttribute:!0},verticalAlign:{type:String,value:\"top\",reflectToAttribute:!0},dynamicAlign:{type:Boolean},horizontalOffset:{type:Number,value:0,notify:!0},verticalOffset:{type:Number,value:0,notify:!0},noOverlap:{type:Boolean},noAnimations:{type:Boolean,value:!1},\nignoreSelect:{type:Boolean,value:!1},closeOnActivate:{type:Boolean,value:!1},openAnimationConfig:{type:Object,value:function(){return[{name:\"fade-in-animation\",timing:{delay:100,duration:200}},{name:\"paper-menu-grow-width-animation\",timing:{delay:100,duration:150,easing:a.hp}},{name:\"paper-menu-grow-height-animation\",timing:{delay:100,duration:275,easing:a.hp}}]}},closeAnimationConfig:{type:Object,value:function(){return[{name:\"fade-out-animation\",timing:{duration:150}},{name:\"paper-menu-shrink-width-animation\",\ntiming:{delay:100,duration:50,easing:a.hp}},{name:\"paper-menu-shrink-height-animation\",timing:{duration:200,easing:\"ease-in\"}}]}},allowOutsideScroll:{type:Boolean,value:!1},restoreFocusOnClose:{type:Boolean,value:!0},_dropdownContent:{type:Object}},hostAttributes:{role:\"group\",\"aria-haspopup\":\"true\"},listeners:{\"iron-activate\":\"Q0\",\"iron-select\":\"Zv\"},get fj(){return Polymer.dom(this.$.content).getDistributedNodes()[0]},toggle:function(){this.opened?this.close():this.open()},open:function(){this.disabled||\nthis.$.dropdown.open()},close:function(){this.$.dropdown.close()},Zv:function(){this.ignoreSelect||this.close()},Q0:function(){this.closeOnActivate&&this.close()},Yh:function(a,c){a?(this._dropdownContent=this.fj,this.fire(\"paper-dropdown-open\")):null!=c&&this.fire(\"paper-dropdown-close\")},iq:function(a){Polymer.ng.iq.apply(this,arguments);a&&this.opened&&this.close()},B_:function(a){var b=a.detail;Polymer.dom(b);var e=this.$.trigger,b=Polymer.dom(b).path;-1<b.indexOf(e)&&a.preventDefault()}});Object.keys(a).forEach(function(b){Lw[b]=\na[b]});Polymer.jn=Lw})();V.Rk.Rk={};\nPolymer({is:\"paper-dropdown-menu\",behaviors:[Polymer.Hj,Polymer.ng,Polymer.Qg,Polymer.Rg],properties:{selectedItemLabel:{type:String,notify:!0,readOnly:!0},selectedItem:{type:Object,notify:!0,readOnly:!0},value:{type:String,notify:!0,readOnly:!0},label:{type:String},placeholder:{type:String},errorMessage:{type:String},opened:{type:Boolean,notify:!0,value:!1,observer:\"Yh\"},allowOutsideScroll:{type:Boolean,value:!1},noLabelFloat:{type:Boolean,value:!1,reflectToAttribute:!0},alwaysFloatLabel:{type:Boolean,\nvalue:!1},noAnimations:{type:Boolean,value:!1},horizontalAlign:{type:String,value:\"right\"},verticalAlign:{type:String,value:\"top\"},dynamicAlign:{type:Boolean},restoreFocusOnClose:{type:Boolean,value:!0}},listeners:{tap:\"BG\"},$g:{\"up down\":\"open\",esc:\"close\"},hostAttributes:{role:\"combobox\",\"aria-autocomplete\":\"none\",\"aria-haspopup\":\"true\"},observers:[\"SG(selectedItem)\"],attached:function(){var a=this.fj;a&&a.selectedItem&&this._setSelectedItem(a.selectedItem)},get fj(){return Polymer.dom(this.$.content).getDistributedNodes()[0]},\nopen:function(){this.$.menuButton.open()},close:function(){this.$.menuButton.close()},Zv:function(a){this._setSelectedItem(a.detail.item)},xG:function(){this._setSelectedItem(null)},BG:function(a){Polymer.Gestures.findOriginalTarget(a)===this&&this.open()},SG:function(a){a=a?a.label||a.getAttribute(\"label\")||a.textContent.trim():\"\";this._setValue(a);this._setSelectedItemLabel(a)},qF:function(a){return a?-4:8},Cn:function(){return this.disabled||!this.required||this.required&&!!this.value},Yh:function(){var a=\nthis.opened?\"true\":\"false\",b=this.fj;b&&b.setAttribute(\"aria-expanded\",a)}});V.Rk.nZ={};\nPolymer({is:\"paper-dropdown-menu-light\",behaviors:[Polymer.Hj,Polymer.ng,Polymer.qh,Polymer.Qg,Polymer.Rg],properties:{selectedItemLabel:{type:String,notify:!0,readOnly:!0},selectedItem:{type:Object,notify:!0,readOnly:!0},value:{type:String,notify:!0,readOnly:!0,observer:\"Iq\"},label:{type:String},placeholder:{type:String},opened:{type:Boolean,notify:!0,value:!1,observer:\"Yh\"},allowOutsideScroll:{type:Boolean,value:!1},noLabelFloat:{type:Boolean,value:!1,reflectToAttribute:!0},alwaysFloatLabel:{type:Boolean,\nvalue:!1},noAnimations:{type:Boolean,value:!1},horizontalAlign:{type:String,value:\"right\"},verticalAlign:{type:String,value:\"top\"},hasContent:{type:Boolean,readOnly:!0}},listeners:{tap:\"BG\"},$g:{\"up down\":\"open\",esc:\"close\"},hostAttributes:{tabindex:0,role:\"combobox\",\"aria-autocomplete\":\"none\",\"aria-haspopup\":\"true\"},observers:[\"SG(selectedItem)\"],attached:function(){var a=this.fj;a&&a.selectedItem&&this._setSelectedItem(a.selectedItem)},get fj(){return Polymer.dom(this.$.content).getDistributedNodes()[0]},\nopen:function(){this.$.menuButton.open()},close:function(){this.$.menuButton.close()},Zv:function(a){this._setSelectedItem(a.detail.item)},xG:function(){this._setSelectedItem(null)},BG:function(a){Polymer.Gestures.findOriginalTarget(a)===this&&this.open()},SG:function(a){a=a?a.label||a.getAttribute(\"label\")||a.textContent.trim():\"\";this._setValue(a);this._setSelectedItemLabel(a)},qF:function(a){return a?-4:8},Cn:function(){return this.disabled||!this.required||this.required&&!!this.value},Yh:function(){var a=\nthis.opened?\"true\":\"false\",b=this.fj;b&&b.setAttribute(\"aria-expanded\",a)},Z_:function(a,b,c){var e=\"\";if(!0===a)return c?\"label-is-hidden\":\"\";if(c||!0===b)e+=\" label-is-floating\";return e},Iq:function(){this.$.input&&this.$.input.textContent!==this.value&&(this.$.input.textContent=this.value);this._setHasContent(!!this.value)}});V.en.gn={};\nPolymer.Ru={observers:[\"MF(receivedFocusFromKeyboard)\"],MF:function(a){a&&this.hj();this.kj()&&(this.Ne.holdDown=a)},Ri:function(){var a=Polymer.qh.Ri();a.id=\"ink\";a.setAttribute(\"center\",\"\");a.classList.add(\"circle\");return a}};Polymer.gn=[Polymer.Hj,Polymer.ng,Polymer.qh,Polymer.Ru];V.Hp={};V.Hp.Hp={};\nPolymer({is:\"paper-icon-button\",hostAttributes:{role:\"button\",tabindex:\"0\"},behaviors:[Polymer.gn],properties:{src:{type:String},icon:{type:String},alt:{type:String,observer:\"F_\"}},F_:function(a,b){var c=this.getAttribute(\"aria-label\");c&&b!=c||this.setAttribute(\"aria-label\",a)}});V.Hp.pZ={};\nPolymer({is:\"paper-icon-button-light\",extends:\"button\",behaviors:[Polymer.qh],listeners:{down:\"m1\",up:\"n1\",focus:\"m1\",blur:\"n1\"},m1:function(){this.Pr().fk()},n1:function(){this.Pr().zk()},hj:function(a){var b=this.Ne;Polymer.qh.hj.apply(this,arguments);this.Ne&&this.Ne!==b&&(this.Ne.center=!0,this.Ne.classList.add(\"circle\"))}});V.lu={};V.lu.lu={};\nPolymer({is:\"iron-autogrow-textarea\",behaviors:[Polymer.Qg,Polymer.Rg,Polymer.ng],properties:{bindValue:{observer:\"iF\",type:String},rows:{type:Number,value:1,observer:\"B1\"},maxRows:{type:Number,value:0,observer:\"B1\"},autocomplete:{type:String,value:\"off\"},autofocus:{type:Boolean,value:!1},inputmode:{type:String},placeholder:{type:String},readonly:{type:String},required:{type:Boolean},maxlength:{type:Number}},listeners:{input:\"In\"},observers:[\"aw(value)\"],get Gm(){return this.$.textarea},get selectionStart(){return this.$.textarea.selectionStart},\nget selectionEnd(){return this.$.textarea.selectionEnd},set selectionStart(a){this.$.textarea.selectionStart=a},set selectionEnd(a){this.$.textarea.selectionEnd=a},ah:function(){if(!this.required&&\"\"==this.value)return this.invalid=!1,!0;var a;this.Zr()?a=Polymer.Rg.ah.call(this,this.value):(a=this.$.textarea.validity.valid,this.invalid=!a);this.fire(\"iron-input-validate\");return a},iF:function(){var a=this.Gm;a&&(a.value!==this.bindValue&&(a.value=this.bindValue||0===this.bindValue?this.bindValue:\n\"\"),this.value=this.bindValue,this.$.mirror.innerHTML=this.pH(),this.fire(\"bind-value-changed\",{value:this.bindValue}))},In:function(a){this.bindValue=a.path?a.path[0].value:a.target.value},Av:function(a){var b;a=a||[\"\"];for(b=0<this.maxRows&&a.length>this.maxRows?a.slice(0,this.maxRows):a.slice(0);0<this.rows&&b.length<this.rows;)b.push(\"\");return b.join(\"\\x3cbr/\\x3e\")+\"\\x26#160;\"},pH:function(){var a=this.Gm;if(a)return this.GC=a&&a.value?a.value.replace(/&/gm,\"\\x26amp;\").replace(/\"/gm,\"\\x26quot;\").replace(/'/gm,\n\"\\x26#39;\").replace(/</gm,\"\\x26lt;\").replace(/>/gm,\"\\x26gt;\").split(\"\\n\"):[\"\"],this.Av(this.GC)},B1:function(){this.$.mirror.innerHTML=this.Av(this.GC)},aw:function(){this.bindValue=this.value}});V.ph.zZ={};\nPolymer({is:\"paper-textarea\",behaviors:[Polymer.Jp,Polymer.Qg],properties:{_ariaLabelledBy:{observer:\"I_\",type:String},_ariaDescribedBy:{observer:\"H_\",type:String},rows:{type:Number,value:1},maxRows:{type:Number,value:0}},I_:function(a){this.$.input.Gm.setAttribute(\"aria-labelledby\",a)},H_:function(a){this.$.input.Gm.setAttribute(\"aria-describedby\",a)},get Bn(){return this.$.input.Gm}});V.ph.WC={};V.Hi={};V.Hi.Kp={};Polymer.pE={hostAttributes:{role:\"option\",tabindex:\"0\"}};\nPolymer.Kp=[Polymer.Hj,Polymer.ng,Polymer.pE];V.Hi.vZ={};V.Hi.qZ={};Polymer({is:\"paper-icon-item\",behaviors:[Polymer.Kp]});V.Hi.uZ={};Polymer({is:\"paper-item-body\"});V.Hi.Hi={};Polymer({is:\"paper-item\",behaviors:[Polymer.Kp]});V.Hi.WC={};V.Cp={};V.Cp.Bp={};Polymer.Bp=function(a){this.selection=[];this.pC=a};\nPolymer.Bp.prototype={get:function(){return this.multi?this.selection.slice():this.selection[0]},clear:function(a){this.selection.slice().forEach(function(b){(!a||0>a.indexOf(b))&&this.wm(b,!1)},this)},isSelected:function(a){return 0<=this.selection.indexOf(a)},wm:function(a,b){if(null!=a&&b!==this.isSelected(a)){if(b)this.selection.push(a);else{var c=this.selection.indexOf(a);0<=c&&this.selection.splice(c,1)}this.pC&&this.pC(a,b)}},select:function(a){this.multi?this.toggle(a):this.get()!==a&&(this.wm(this.get(),\n!1),this.wm(a,!0))},toggle:function(a){this.wm(a,!this.isSelected(a))}};V.Cp.pY={};\nPolymer.Nk={properties:{attrForSelected:{type:String,value:null},selected:{type:String,notify:!0},selectedItem:{type:Object,readOnly:!0,notify:!0},activateEvent:{type:String,value:\"tap\",observer:\"C_\"},selectable:String,selectedClass:{type:String,value:\"iron-selected\"},selectedAttribute:{type:String,value:null},fallbackSelection:{type:String,value:null},items:{type:Array,readOnly:!0,notify:!0,value:function(){return[]}},_excludedLocalNames:{type:Object,value:function(){return{template:1}}}},observers:[\"zw(attrForSelected)\",\n\"Sn(selected)\",\"N_(fallbackSelection)\"],created:function(){this.hF=this.GF.bind(this);this.Jf=new Polymer.Bp(this.aq.bind(this))},attached:function(){this.gl=this.pG(this);this.Hq();this.Zj||this.Sn();this.pv(this.activateEvent)},detached:function(){this.gl&&Polymer.dom(this).unobserveNodes(this.gl);this.hw(this.activateEvent)},indexOf:function(a){return this.items.indexOf(a)},select:function(a){this.selected=a},$aa:function(){var a=this.items.length,a=(Number(this.Jq(this.selected))-1+a)%a;this.selected=\nthis.Rj(a)},Zaa:function(){var a=(Number(this.Jq(this.selected))+1)%this.items.length;this.selected=this.Rj(a)},Yaa:function(a){this.select(this.Rj(a))},f6:function(){this.Hq()},get Zj(){return null!=this.selected},N_:function(){this.Zj&&this.Sn()},pv:function(a){this.listen(this,a,\"ov\")},hw:function(a){this.unlisten(this,a,\"ov\")},C_:function(a,b){this.hw(b);this.pv(a)},Hq:function(){var a=Polymer.dom(this).queryDistributedElements(this.selectable||\"*\"),a=Array.prototype.filter.call(a,this.hF);this._setItems(a)},\nzw:function(){this.Zj&&(this.selected=this.Rj(this.indexOf(this.selectedItem)))},Sn:function(){this.ow(this.selected)},ow:function(){this.Jf.select(this.Un(this.selected));this.fallbackSelection&&this.items.length&&void 0===this.Jf.get()&&(this.selected=this.fallbackSelection)},GF:function(a){return!this._excludedLocalNames[a.localName]},Un:function(a){return null==a?null:this.items[this.Jq(a)]},Jq:function(a){if(this.attrForSelected)for(var b=0,c;c=this.items[b];b++){if(this.Cw(c)==a)return b}else return Number(a)},\nRj:function(a){if(this.attrForSelected){if(a=this.items[a])return this.Cw(a)}else return a},Cw:function(a){var b=a[Polymer.CaseMap.dashToCamelCase(this.attrForSelected)];return void 0!=b?b:a.getAttribute(this.attrForSelected)},aq:function(a,b){this.selectedClass&&this.toggleClass(this.selectedClass,b,a);this.selectedAttribute&&this.toggleAttribute(this.selectedAttribute,b,a);this.pw();this.fire(\"iron-\"+(b?\"select\":\"deselect\"),{item:a})},pw:function(){this._setSelectedItem(this.Jf.get())},pG:function(a){return Polymer.dom(a).observeNodes(function(a){this.Hq();\nthis.Zj&&this.Sn();this.fire(\"iron-items-changed\",a,{bubbles:!1,cancelable:!1})})},ov:function(a){a=a.target;for(var b=this.items;a&&a!=this;){var c=b.indexOf(a);if(0<=c){b=this.Rj(c);this.bG(b,a);break}a=a.parentNode}},bG:function(a,b){this.fire(\"iron-activate\",{selected:a,item:b},{cancelable:!0}).defaultPrevented||this.select(a)}};V.Cp.mY={};\nPolymer.uu={properties:{multi:{type:Boolean,value:!1,observer:\"m9\"},selectedValues:{type:Array,notify:!0},selectedItems:{type:Array,readOnly:!0,notify:!0}},observers:[\"Sn(selectedValues.splices)\"],select:function(a){this.multi?this.selectedValues?this.aH(a):this.selectedValues=[a]:this.selected=a},m9:function(a){this.Jf.multi=a},get Zj(){return null!=this.selected||null!=this.selectedValues&&this.selectedValues.length},zw:function(){this.multi?this.Zj&&(this.selectedValues=this.selectedItems.map(function(a){return this.Rj(this.indexOf(a))},\nthis).filter(function(a){return null!=a},this)):Polymer.Nk.zw.apply(this)},Sn:function(){this.multi?this.RG(this.selectedValues):this.ow(this.selected)},RG:function(a){if(a){a=this.qH(a);this.Jf.clear(a);for(var b=0;b<a.length;b++)this.Jf.wm(a[b],!0);this.fallbackSelection&&this.items.length&&!this.Jf.get().length&&(a=this.Un(this.fallbackSelection))&&(this.selectedValues=[this.fallbackSelection])}else this.Jf.clear()},pw:function(){var a=this.Jf.get();this.multi?this._setSelectedItems(a):(this._setSelectedItems([a]),\nthis._setSelectedItem(a))},aH:function(a){var b=this.selectedValues.indexOf(a),c=0>b;c?this.push(\"selectedValues\",a):this.splice(\"selectedValues\",b,1)},qH:function(a){return null==a?null:a.map(function(a){return this.Un(a)},this)}};Polymer.QD=[Polymer.Nk,Polymer.uu];V.Ym={};V.Ym.Ym={};\nPolymer.Kk={properties:{focusedItem:{observer:\"m0\",readOnly:!0,type:Object},attrForItemTitle:{type:String}},hostAttributes:{role:\"menu\",tabindex:\"0\"},observers:[\"C1(multi)\"],listeners:{focus:\"Yv\",keydown:\"V0\",\"iron-items-changed\":\"S0\"},$g:{up:\"a1\",down:\"N0\",esc:\"P0\",\"shift+tab:keydown\":\"AG\"},attached:function(){this.kw()},select:function(a){this.hq&&(this.cancelAsync(this.hq),this.hq=null);var b=this.Un(a);b&&b.hasAttribute(\"disabled\")||(this._setFocusedItem(b),Polymer.uu.select.apply(this,arguments))},\nkw:function(){var a=this.multi?this.selectedItems&&this.selectedItems[0]:this.selectedItem;this.items.forEach(function(b){b.setAttribute(\"tabindex\",b===a?\"0\":\"-1\")},this)},C1:function(a){a?this.setAttribute(\"aria-multiselectable\",\"true\"):this.removeAttribute(\"aria-multiselectable\")},KF:function(a){for(var b=0,c;c=this.items[b];b++){var e=this.attrForItemTitle||\"textContent\",e=c[e]||c.getAttribute(e);if(!c.hasAttribute(\"disabled\")&&e&&e.trim().charAt(0).toLowerCase()===String.fromCharCode(a.keyCode).toLowerCase()){this._setFocusedItem(c);\nbreak}}},JF:function(){for(var a=this.items.length,b=Number(this.indexOf(this.focusedItem)),c=1;c<a+1;c++){var e=this.items[(b-c+a)%a];if(!e.hasAttribute(\"disabled\")){var g=Polymer.dom(e).getOwnerRoot()||document;this._setFocusedItem(e);if(Polymer.dom(g).activeElement==e)break}}},Kv:function(){for(var a=this.items.length,b=Number(this.indexOf(this.focusedItem)),c=1;c<a+1;c++){var e=this.items[(b+c)%a];if(!e.hasAttribute(\"disabled\")){var g=Polymer.dom(e).getOwnerRoot()||document;this._setFocusedItem(e);\nif(Polymer.dom(g).activeElement==e)break}}},aq:function(a,b){b?a.setAttribute(\"aria-selected\",\"true\"):a.removeAttribute(\"aria-selected\");Polymer.Nk.aq.apply(this,arguments)},m0:function(a,b){b&&b.setAttribute(\"tabindex\",\"-1\");a&&(a.setAttribute(\"tabindex\",\"0\"),a.focus())},S0:function(a){a.detail.addedNodes.length&&this.kw()},AG:function(){var a=this.getAttribute(\"tabindex\");Polymer.Kk.Yj=!0;this._setFocusedItem(null);this.setAttribute(\"tabindex\",\"-1\");this.async(function(){this.setAttribute(\"tabindex\",\na);Polymer.Kk.Yj=!1},1)},Yv:function(a){!Polymer.Kk.Yj&&(a=Polymer.dom(a).rootTarget,a===this||\"undefined\"===typeof a.tabIndex||this.isLightDescendant(a))&&(this.hq=this.async(function(){var a=this.multi?this.selectedItems&&this.selectedItems[0]:this.selectedItem;this._setFocusedItem(null);a?this._setFocusedItem(a):this.items[0]&&this.Kv()}))},a1:function(a){this.JF();a.detail.Go.preventDefault()},N0:function(a){this.Kv();a.detail.Go.preventDefault()},P0:function(){this.focusedItem.blur()},V0:function(a){this.Ho(a,\n\"up down esc\")||this.KF(a);a.stopPropagation()},ov:function(a){Polymer.Nk.ov.call(this,a);a.stopPropagation()}};Polymer.Kk.Yj=!1;Polymer.Ym=[Polymer.QD,Polymer.mg,Polymer.Kk];V.Su={};V.Su.Su={};Polymer({is:\"paper-listbox\",behaviors:[Polymer.Ym],hostAttributes:{role:\"listbox\"}});V.Mk={};V.Mk.Mk={};\nPolymer.Mk={properties:{value:{type:Number,value:0,notify:!0,reflectToAttribute:!0},min:{type:Number,value:0,notify:!0},max:{type:Number,value:100,notify:!0},step:{type:Number,value:1,notify:!0},ratio:{type:Number,value:0,readOnly:!0,notify:!0}},observers:[\"bk(value,min,max,step)\"],Nj:function(a){return(this.Qi(a)-this.min)/(this.max-this.min)},Qi:function(a){return Math.min(this.max,Math.max(this.min,this.fq(a)))},fq:function(a){a=parseFloat(a);return this.step?(Math.round((a+this.min)/this.step)-\nthis.min/this.step)/(1/this.step):a},nH:function(){var a=this.Qi(this.value);this.value=this.oldValue=isNaN(a)?this.oldValue:a;return this.value!==a},bk:function(){this.nH();this._setRatio(100*this.Nj(this.value))}};V.Tu={};V.Tu.Tu={};\nPolymer({is:\"paper-progress\",behaviors:[Polymer.Mk],properties:{secondaryProgress:{type:Number,value:0},secondaryRatio:{type:Number,value:0,readOnly:!0},indeterminate:{type:Boolean,value:!1,observer:\"w1\"},disabled:{type:Boolean,value:!1,reflectToAttribute:!0,observer:\"iq\"}},observers:[\"g1(secondaryProgress,value,min,max)\"],hostAttributes:{role:\"progressbar\"},w1:function(a){this.toggleClass(\"indeterminate\",a,this.$.primaryProgress)},Fq:function(a,b){b=\"scaleX(\"+b/100+\")\";a.style.transform=a.style.webkitTransform=\nb},D0:function(a){this.Fq(this.$.primaryProgress,a)},g1:function(a,b,c,e){a=this.Qi(a);b=this.Qi(b);var g=100*this.Nj(a),k=100*this.Nj(b);this._setSecondaryRatio(g);this.Fq(this.$.secondaryProgress,g);this.Fq(this.$.primaryProgress,k);this.secondaryProgress=a;this.setAttribute(\"aria-valuenow\",b);this.setAttribute(\"aria-valuemin\",c);this.setAttribute(\"aria-valuemax\",e)},iq:function(a){this.setAttribute(\"aria-disabled\",a?\"true\":\"false\")},s0:function(a){return 0===a}});V.Vu={};V.Vu.Vu={};\nPolymer({is:\"paper-slider\",behaviors:[Polymer.mg,Polymer.Qg,Polymer.gn,Polymer.Mk],properties:{snaps:{type:Boolean,value:!1,notify:!0},pin:{type:Boolean,value:!1,notify:!0},secondaryProgress:{type:Number,value:0,notify:!0,observer:\"p1\"},editable:{type:Boolean,value:!1},immediateValue:{type:Number,value:0,readOnly:!0,notify:!0},maxMarkers:{type:Number,value:0,notify:!0,observer:\"E0\"},expand:{type:Boolean,value:!1,readOnly:!0},dragging:{type:Boolean,value:!1,readOnly:!0},transiting:{type:Boolean,value:!1,\nreadOnly:!0},markers:{type:Array,readOnly:!0,value:[]}},observers:[\"lH(value,min,max,snaps,step)\",\"Iq(value)\",\"v0(immediateValue)\"],hostAttributes:{role:\"slider\",tabindex:0},$g:{\"left down pagedown home\":\"d0\",\"right up pageup end\":\"w0\"},ready:function(){this.async(function(){this.lH(this.value)},1)},eN:function(){this.value=this.Qi(this.value+this.step)},GK:function(){this.value=this.Qi(this.value-this.step)},lH:function(a,b,c){this.setAttribute(\"aria-valuemin\",b);this.setAttribute(\"aria-valuemax\",\nc);this.setAttribute(\"aria-valuenow\",a);this.dw(this.Nj(a))},Iq:function(){this.fire(\"value-change\")},v0:function(){this.dragging?this.fire(\"immediate-value-change\"):this.value=this.immediateValue},p1:function(){this.secondaryProgress=this.Qi(this.secondaryProgress)},Iv:function(){this._setExpand(!0)},LG:function(){this.cancelDebouncer(\"expandKnob\");this._setExpand(!1)},dw:function(a){this._setImmediateValue(this.fq(this.tv(a)));this._setRatio(this.Nj(this.immediateValue));this.$.sliderKnob.style.left=\n100*this.ratio+\"%\";this.dragging&&(this.Rv=this.ratio*this.$i,this.translate3d(0,0,0,this.$.sliderKnob))},tv:function(a){return(this.max-this.min)*a+this.min},Z0:function(a){a.stopPropagation();switch(a.detail.state){case \"start\":this.Qn(a);break;case \"track\":this.dH(a);break;case \"end\":this.Eq()}},Qn:function(){this.$i=this.$.sliderBar.offsetWidth;this.Rv=this.On=this.tc=this.ratio*this.$i;this.nG=-this.On;this.iG=this.$i-this.On;this.$.sliderKnob.classList.add(\"dragging\");this._setDragging(!0)},\ndH:function(a){this.dragging||this.Qn(a);a=Math.min(this.iG,Math.max(this.nG,a.detail.dx));this.tc=this.On+a;a=this.fq(this.tv(this.tc/this.$i));this._setImmediateValue(a);a=this.Nj(this.immediateValue)*this.$i-this.Rv;this.translate3d(a+\"px\",0,0,this.$.sliderKnob)},Eq:function(){var a=this.$.sliderKnob.style;this.$.sliderKnob.classList.remove(\"dragging\");this._setDragging(!1);this.LG();this.value=this.immediateValue;a.transform=a.webkitTransform=\"\";this.fire(\"change\")},C0:function(a){this.Iv();a.preventDefault();\nthis.focus()},K_:function(a){this.$i=this.$.sliderBar.offsetWidth;var b=this.$.sliderBar.getBoundingClientRect(),b=(a.detail.x-b.left)/this.$i,c=this.ratio;this._setTransiting(!0);this.dw(b);this.debounce(\"expandKnob\",this.Iv,60);c===this.ratio&&this._setTransiting(!1);this.async(function(){this.fire(\"change\")});a.preventDefault();this.focus()},B0:function(a){a.target===this.$.sliderKnob&&this._setTransiting(!1)},E0:function(a){this.snaps||this._setMarkers([]);var b=Math.round((this.max-this.min)/\nthis.step);b>a&&(b=a);this._setMarkers(Array(b))},jG:function(a){return Object.keys(a).filter(function(b){return a[b]}).join(\" \")},n0:function(){return this.jG({disabled:this.disabled,pin:this.pin,snaps:this.snaps,Iaa:this.immediateValue<=this.min,expand:this.expand,dragging:this.dragging,transiting:this.transiting,editable:this.editable})},w0:function(a){this.disabled||(\"end\"===a.detail.key?this.value=this.max:this.eN(),this.fire(\"change\"))},d0:function(a){this.disabled||(\"home\"===a.detail.key?this.value=\nthis.min:this.GK(),this.fire(\"change\"))},M_:function(a){this.value=a.target.value;this.fire(\"change\")},z0:function(a){a.stopPropagation()},Ri:function(){this._rippleContainer=this.$.sliderKnob;return Polymer.Ru.Ri.call(this)},MF:function(a){a&&this.hj();this.kj()&&(this.Ne.style.display=a?\"\":\"none\",this.Ne.holdDown=a)}});V.Vm={};V.Vm.Vm={};\nPolymer.nu={properties:{checked:{type:Boolean,value:!1,reflectToAttribute:!0,notify:!0,observer:\"vv\"},toggles:{type:Boolean,value:!0,reflectToAttribute:!0},value:{type:String,value:\"on\",observer:\"Iq\"}},observers:[\"j1(required)\"],created:function(){this.p0=!0},Cn:function(){return this.disabled||!this.required||this.required&&this.checked},j1:function(){this.required?this.setAttribute(\"aria-required\",\"true\"):this.removeAttribute(\"aria-required\")},vv:function(){this.active=this.checked;this.fire(\"iron-change\")},\nIq:function(){if(void 0===this.value||null===this.value)this.value=\"on\"}};Polymer.Vm=[Polymer.Qg,Polymer.Rg,Polymer.nu];V.en.Pu={};Polymer.mE={vv:function(){Polymer.nu.vv.call(this);this.kj()&&(this.checked?this.Ne.setAttribute(\"checked\",\"\"):this.Ne.removeAttribute(\"checked\"))},tn:function(){Polymer.qh.tn.call(this);!this.disabled&&this.isAttached&&(this.checked=this.active)}};Polymer.Pu=[Polymer.gn,Polymer.Vm,Polymer.mE];V.Wu={};V.Wu.Wu={};\nPolymer({is:\"paper-toggle-button\",behaviors:[Polymer.Pu],hostAttributes:{role:\"button\",\"aria-pressed\":\"false\",tabindex:0},properties:{},listeners:{track:\"b1\"},attached:function(){Polymer.RenderStatus.afterNextRender(this,function(){this.setScrollDirection(\"y\")})},b1:function(a){a=a.detail;\"start\"===a.state?this.Qn(a):\"track\"===a.state?this.cH(a):\"end\"===a.state&&this.Eq(a)},Qn:function(){this.Kq=this.$.toggleBar.offsetWidth/2;this.bH=this.checked;this.$.toggleButton.classList.add(\"dragging\")},cH:function(a){a=\na.dx;this.tc=Math.min(this.Kq,Math.max(0,this.bH?this.Kq+a:a));this.translate3d(this.tc+\"px\",0,0,this.$.toggleButton);this.Bw(this.tc>this.Kq/2)},Eq:function(){this.$.toggleButton.classList.remove(\"dragging\");this.transform(\"\",this.$.toggleButton)},Ri:function(){this._rippleContainer=this.$.toggleButton;var a=Polymer.qh.Ri();a.id=\"ink\";a.setAttribute(\"recenters\",\"\");a.classList.add(\"circle\",\"toggle-ink\");return a}});D.ob={};D.ob.cZ={};D.ob.yg={Wk:\"unweighted\",pn:\"weighted\",Ai:\"both\"};\nD.ob.hv={Wk:\"Number of slices in bucket\",pn:\"Number of (weighted) examples for slices in bucket\"};D.ob.xg={Zt:\"details\",EMPTY:\"empty\",Hu:\"overview\",uD:\"focus\",KY:\"metric-select\",j_:\"type-select\",VY:\"num-buckets\",zY:\"logarithm-scale\",hE:\"options\",aZ:\"options-toggle\"};D.ob.YD=680;D.ob.ED=200;D.ob.dn=30;D.ob.Iu=120;D.ob.iE=120;D.ob.kE=2;D.ob.jE=600;D.ob.Eu=[1,50];D.ob.iD=10;\nD.ob.Cy=function(a,b){a=a.slice(1);return a.reduce(function(a,e){return{min:Math.min(a.min,e[b]),max:Math.max(a.max,e[b])}},{min:Infinity,max:-Infinity})};\nPolymer({is:\"metrics-histogram\",properties:{data:{type:Object,value:function(){return new D.Jb([],[])}},focusRange:{type:Array,value:[0,1]},detailsData:{type:Object,computed:\"M3(data,metric,focusRange)\",notify:!0},numBuckets:{type:Number,value:D.ob.iD},type:{type:String,value:D.ob.yg.Wk},metric:{type:String,value:\"\"},selectableMetrics_:{type:Array,computed:\"V3(data,weightedExamplesColumn)\",observer:\"aba\"},weightedExamplesColumn:{type:String,value:\"\"},logarithmScale:{type:Boolean,value:!1},selectedFeatures:{type:Array,\nvalue:function(){return[]}},realTimeFocus:{type:Boolean,value:!1},chartPackages_:{type:Array,value:[\"corechart\"]}},listeners:{\"iron-resize\":\"j$\"},behaviors:[Polymer.Jj],observers:[\"saa(data,metric,type,focusRange,weightedExamplesColumn,logarithmScale,numBuckets,selectedFeatures)\"],jB:function(){this.Es()?this.Qo():this.async(this.jB,100)},ready:function(){this.$.loader.load();this.jB()},cp:function(a,b){this.focusRange=[a,b]},Qo:function(){this.Es()&&(this.BP(),this.EP())},Dr:function(){var a=this.getBoundingClientRect().width;\nreturn Math.max(a,D.ob.YD)},Jr:function(){var a=this.Dr();return a-D.ob.Iu-D.ob.iE},EP:function(){var a=D.ei.select(this.$[D.ob.xg.Hu]),b=this.Jr(),c=a.node();c.setAttribute(\"width\",b);c.setAttribute(\"height\",D.ob.dn*(this.type==D.ob.yg.Ai?2:1));c.style.marginLeft=D.ob.Iu+\"px\";var c=D.ob.dn,e=this.data.getColumnRange(this.metric),e=this.YB(this.data,D.ob.jE,e.min,e.max),e=e.pr,g=a.select(\".unweighted\"),k=a.select(\".weighted\");g.selectAll(\"*\").remove();k.selectAll(\"*\").remove();this.type!=D.ob.yg.pn&&\nthis.yx(g,e.map(function(a){return[a[0],a[1]]}),D.ob.Cy(e,1));this.type!=D.ob.yg.Wk&&this.yx(k,e.map(function(a){return[a[0],a[2]]}),D.ob.Cy(e,2));g.select(\"path\").attr(\"class\",\"blue\");k.select(\"path\").attr(\"class\",this.type==D.ob.yg.Ai?\"red\":\"blue\");this.type==D.ob.yg.Ai&&k.attr(\"transform\",\"translate(0,\"+c+\")\");this.xx(this.focusRange[0],this.focusRange[1]);var m=[],c=D.ei.drag(),n,q,e=function(){var c=D.ei.mouse(a.node())[0];void 0==m[0]?m[0]=c:(m[1]=c,n=Math.max(0,Math.min(m[0],m[1])/b),q=Math.min(1,\nMath.max(m[0],m[1])/b),this.xx(n,q),this.realTimeFocus&&this.cp(n,q))}.bind(this),g=function(){void 0!=m[0]&&void 0!=m[1]&&(this.cp(n,q),m=[],this.dispatchEvent(new CustomEvent(D.Event.fv,{detail:{aL:n,bL:q}})))}.bind(this);c.on(\"drag\",e).on(\"end\",g);a.call(c);a.on(D.Event.au,function(){this.PP();this.dispatchEvent(new CustomEvent(D.Event.fv,{detail:{aL:0,bL:1}}))}.bind(this))},BP:function(){var a=this.data.getColumnRange(this.metric),b=(a.max-a.min)*this.focusRange[0]+a.min,a=(a.max-a.min)*this.focusRange[1]+\na.min,b=this.YB(this.detailsData,this.numBuckets,b,a),a=[],c=[0],e=0;this.type!=D.ob.yg.pn&&(a.push({targetAxisIndex:e++}),c.push(1),c.push({calc:\"stringify\",sourceColumn:1,type:\"string\",role:\"annotation\"}));this.type!=D.ob.yg.Wk&&(a.push({targetAxisIndex:e++}),c.push(2),c.push({calc:\"stringify\",sourceColumn:2,type:\"string\",role:\"annotation\"}));var g=this.$[D.ob.xg.EMPTY],e=this.$[D.ob.xg.Zt];g.style.display=b.Zc?\"block\":\"none\";e.style.display=b.Zc?\"none\":\"block\";b.Zc||(g=google.visualization.arrayToDataTable(b.pr),\ng=new google.visualization.DataView(g),g.setColumns(c),c=new google.visualization.ColumnChart(e),c.draw(g,{enableInteractivity:!1,bar:{groupWidth:\"99%\"},hAxis:{ticks:b.dB},vAxis:{ticks:[{v:0,f:\"\"}]},legend:{position:\"top\"},tooltip:{trigger:\"none\"},series:a,width:this.Dr(),height:D.ob.ED}),this.$M(b.eB))},YB:function(a,b,c,e){if(0>=b)throw\"number of buckets must be larger than zero\";var g=a.tf,k=a.ki(this.metric);a=a.getColumnRange(this.metric);var m=[this.metric,D.ob.hv.Wk,D.ob.hv.pn],n=[m];if(c>\ne||a.min>e||a.max<c||!g.length)return{pr:[m],dB:[],eB:[],Zc:!0};0==e-c&&(e=c+Math.pow(.1,D.Nh)*b);var q=(e-c)/b;e=[];for(a=0;a<=b;a++)m=c+a*q,e.push({v:m,f:m.toFixed(D.Nh)});for(a=0;a<b;a++)n.push([c+q*(a+.5),0,0]);var v=this.data.ki(this.weightedExamplesColumn),B={};g.forEach(function(a){var e=a.Bh(),g=e[v],e=e[k],e=Math.floor((e-c)/q),e=Math.min(e,b-1)+1;n[e][1]+=1;n[e][2]+=g;a=a.Ah();-1!=this.selectedFeatures.indexOf(a)&&(B[e-1]=!0,this.type==D.ob.yg.Ai&&(B[e+b-1]=!0))}.bind(this));if(this.logarithmScale)for(a=\n1;a<n.length;a++)n[a][1]=Math.log(n[a][1]+1),n[a][2]=Math.log(n[a][2]+1);return{pr:n,dB:e,Zc:!1,eB:Object.keys(B)}},xx:function(a,b){var c=D.ei.select(this.$[D.ob.xg.Hu]),e=c.select(\"rect#focus\");e.empty()&&(e=c.append(\"rect\").attr(\"id\",D.ob.xg.uD));c=this.Jr();e.attr(\"x\",c*a).attr(\"width\",c*(b-a)).attr(\"height\",D.ob.dn*(this.type==D.ob.yg.Ai?2:1))},yx:function(a,b,c){var e=b.slice(1);if(e.length){b=this.Jr();var g=D.ob.dn,k=[e[0][0],e[e.length-1][0]],m=D.ei.scaleLinear().domain(k).range([0,b]),n=\nD.ei.scaleLinear().domain([c.min,c.max]).range([0,g-D.ob.kE]);c=D.ei.line();var q=0,e=e.map(function(a){q=m(a[0]);return[q,g-n(a[1])]});e.push([q,g]);e.push([m(k[0]),g]);a.append(\"path\").attr(\"d\",c(e));a.append(\"rect\").attr(\"class\",\"overview\").attr(\"height\",g).attr(\"width\",b)}},$M:function(a){for(var b=this.$[D.ob.xg.Zt].getElementsByTagName(\"g\"),c,e=0;e<b.length;e++)if(null!=b[e].getAttribute(\"clip-path\")){c=b[e];break}for(var g=c.children[1],k=c.nextSibling.nextSibling.nextSibling,e=0;e<g.children.length;e++)g.children[e].classList.remove(\"highlighted\"),\nk.children[e].classList.remove(\"highlighted\");a.forEach(function(a){g.children[a].classList.add(\"highlighted\");k.children[a].classList.add(\"highlighted\")})},PP:function(){this.cp(0,1)},Es:function(){return\"undefined\"!=typeof google&&\"undefined\"!=typeof google.visualization&&\"undefined\"!=typeof google.visualization.ColumnChart&&\"\"!==this.metric&&this.numBuckets>=D.ob.Eu[0]&&this.numBuckets<=D.ob.Eu[1]},l$:function(){this.$[D.ob.xg.hE].open()},M3:function(a,b,c){var e=a.ki(b);b=a.getColumnRange(b);\nvar g=b.max-b.min;0==g&&(g=Math.pow(.1,D.Nh));var k=Math.max(b.min,b.min+g*c[0]),m=Math.min(b.max,b.min+g*c[1]);a=a.filter(function(a){a=a.Bh();return a[e]>=k&&a[e]<=m});return this.detailsData&&this.detailsData.ii(a)?this.detailsData:a},V3:function(a,b){a=a.lk();if(!a.length||\"\"===b)return[];a=a.slice();b=a.indexOf(b);if(-1==b)throw\"no data table column found for weighted examples\";a.splice(b,1);return a},aba:function(){this.selectableMetrics_.length&&(this.metric=this.selectableMetrics_[0])},saa:function(){this.Es()&&\nthis.Qo()},ZB:0,j$:function(){var a=this.Dr();a!=this.ZB&&(this.ZB=a,this.Qo())}});\nPolymer({is:\"gviz-table\",properties:{options:{type:Object},data:{type:Object},selection:{type:Array,notify:!0,observer:\"WP\"},chartReady:{type:Boolean,notify:!0},updatingSelection_:{type:Boolean,value:!1},table_:{type:Object},staticState_:{type:Object,value:{r:!1}}},observers:[\"Qo(table_,data,options)\"],ready:function(){var a=this;this.async(function(){a.chartReady=a.staticState_.r},1);this.$.loader.load(function(){return a.hN()})},hN:function(){var a=this,b=new google.visualization.Table(this.$.table);\nthis.table_=b;google.visualization.events.addListener(b,\"select\",function(){return a.zW()});this.chartReady=!0;this.staticState_.r=!0;this.selection&&b.setSelection(this.selection)},zW:function(){this.updatingSelection_=!0;this.selection=this.table_.getSelection();this.updatingSelection_=!1},WP:function(a){this.updatingSelection_||this.table_&&this.table_.setSelection(a)},Qo:function(a,b,c){this.$.loader.Dl(b).then(function(b){a.draw(b,c)})}});\nPolymer({is:\"bounded-value\",properties:{upperBound:{type:Number},lowerBound:{type:Number},value_:{type:String,computed:\"W3(lowerBound,upperBound)\"},range_:{type:String,computed:\"U3(lowerBound,upperBound)\"},data:{type:String,value:\"\",observer:\"F4\"}},F4:function(){if(this.data){var a=JSON.parse(this.data);this.upperBound=a.upperBound;this.lowerBound=a.lowerBound}},U3:function(a,b){return((b-a)/2).toFixed(D.Nh)},W3:function(a,b){return((b+a)/2).toFixed(D.Nh)}});\nPolymer({is:\"precision-at-k\",properties:{data:{type:String},formattedData_:{type:Object,computed:\"g6(data)\"}},g6:function(a){var b;try{b=JSON.parse(a)}catch(c){}if(b&&Array.isArray(b))return b.map(function(a){return{k:a.k||\"\",value:(a.value||0).toFixed(D.Nh),total:a.totalPositives||0}})}});window.Promise||(window.Promise=Mw(Polymer.Base.async));\nPromise.all=Promise.all||function(){var a=Array.prototype.slice.call(1===arguments.length&&Array.isArray(arguments[0])?arguments[0]:arguments);return new Promise(function(b,c){function e(k,n){try{if(n&&(\"object\"===typeof n||\"function\"===typeof n)){var m=n.then;if(\"function\"===typeof m){m.call(n,function(a){e(k,a)},c);return}}a[k]=n;0===--g&&b(a)}catch(v){c(v)}}if(0===a.length)return b([]);for(var g=a.length,k=0;k<a.length;k++)e(k,a[k])})};\nPromise.race=Promise.race||function(a){var b=a;return new Promise(function(a,e){for(var c=0,k=b.length;c<k;c++)b[c].then(a,e)})};\nfunction Mw(a){function b(b){var c=this;null===this.ll?this.xn.push(b):a(function(){var a=c.ll?b.KO:b.LO;if(\"function\"!==typeof a)(c.ll?b.resolve:b.reject)(c.uh);else{var e;try{e=a(c.uh)}catch(C){b.reject(C);return}b.resolve(e)}})}function c(a){try{if(a===this)throw new TypeError;if(a&&(\"object\"===typeof a||\"function\"===typeof a)){var b=a.then;if(\"function\"===typeof b){k(b.bind(a),c.bind(this),e.bind(this));return}}this.ll=!0;this.uh=a;g.call(this)}catch(v){e.call(this,v)}}function e(a){this.ll=!1;\nthis.uh=a;g.call(this)}function g(){for(var a=0,c=this.xn.length;a<c;a++)b.call(this,this.xn[a]);this.xn=null}function k(a,b,c){var e=!1;try{a(function(a){e||(e=!0,b(a))},function(a){e||(e=!0,c(a))})}catch(C){e||(e=!0,c(C))}}var m=function(a){if(\"object\"!==typeof this||\"function\"!==typeof a)throw new TypeError;this.uh=this.ll=null;this.xn=[];k(a,c.bind(this),e.bind(this))};m.prototype[\"catch\"]=function(a){return this.then(null,a)};m.prototype.then=function(a,c){var e=this;return new m(function(g,\nk){b.call(e,{KO:a,LO:c,resolve:g,reject:k})})};m.resolve=function(a){return a&&\"object\"===typeof a&&a.constructor===Promise?a:new m(function(b){b(a)})};m.reject=function(a){return new m(function(b,c){c(a)})};return m}V.yp={};V.yp.oY={};\nPolymer({is:\"iron-request\",hostAttributes:{hidden:!0},properties:{xhr:{type:Object,notify:!0,readOnly:!0,value:function(){return new XMLHttpRequest}},response:{type:Object,notify:!0,readOnly:!0,value:function(){return null}},status:{type:Number,notify:!0,readOnly:!0,value:0},statusText:{type:String,notify:!0,readOnly:!0,value:\"\"},completes:{type:Object,readOnly:!0,notify:!0,value:function(){return new Promise(function(a,b){this.QP=a;this.sm=b}.bind(this))}},progress:{type:Object,notify:!0,readOnly:!0,\nvalue:function(){return{}}},aborted:{type:Boolean,notify:!0,readOnly:!0,value:!1},errored:{type:Boolean,notify:!0,readOnly:!0,value:!1},timedOut:{type:Boolean,notify:!0,readOnly:!0,value:!1}},get lW(){if(this.errored||this.aborted||this.timedOut)return!1;var a=this.xhr.status||0;return 0===a||200<=a&&300>a},send:function(a){var b=this.xhr;if(0<b.readyState)return null;b.addEventListener(\"progress\",function(a){this._setProgress({lengthComputable:a.lengthComputable,loaded:a.loaded,total:a.total})}.bind(this));\nb.addEventListener(\"error\",function(a){this._setErrored(!0);this.Tn();this.sm(a)}.bind(this));b.addEventListener(\"timeout\",function(a){this._setTimedOut(!0);this.Tn();this.sm(a)}.bind(this));b.addEventListener(\"abort\",function(){this.Tn();this.sm(Error(\"Request aborted.\"))}.bind(this));b.addEventListener(\"loadend\",function(){this.Tn();this.lW?(this._setResponse(this.TO()),this.QP(this)):this.sm(Error(\"The request failed with status code: \"+this.xhr.status))}.bind(this));this.url=a.url;b.open(a.method||\n\"GET\",a.url,!1!==a.async);var c={json:\"application/json\",text:\"text/plain\",html:\"text/html\",xml:\"application/xml\",arraybuffer:\"application/octet-stream\"}[a.handleAs],e=a.headers||Object.create(null),g=Object.create(null),k;for(k in e)g[k.toLowerCase()]=e[k];e=g;c&&!e.accept&&(e.accept=c);Object.keys(e).forEach(function(a){/[A-Z]/.test(a)&&console.error(\"Headers must be lower case, got\",a);b.setRequestHeader(a,e[a])},this);if(!1!==a.async){c=a.handleAs;if(a.jsonPrefix||!c)c=\"text\";b.responseType=b.MG=\nc;a.jsonPrefix&&(b.Pv=a.jsonPrefix)}b.withCredentials=!!a.withCredentials;b.timeout=a.timeout;a=this.AF(a.body,e[\"content-type\"]);b.send(a);return this.completes},TO:function(){var a=this.xhr,b=a.responseType||a.MG,c=!this.xhr.responseType,e=a.Pv&&a.Pv.length||0;try{switch(b){case \"json\":if(c||void 0===a.response)try{return JSON.parse(a.responseText)}catch(g){return null}return a.response;case \"xml\":return a.responseXML;case \"blob\":case \"document\":case \"arraybuffer\":return a.response;default:if(e)try{return JSON.parse(a.responseText.substring(e))}catch(g){return null}return a.responseText}}catch(g){this.sm(Error(\"Could not parse response. \"+\ng.message))}},abort:function(){this._setAborted(!0);this.xhr.abort()},AF:function(a,b){if(\"string\"==typeof a)return a;var c=a;switch(b){case \"application/json\":return JSON.stringify(c);case \"application/x-www-form-urlencoded\":return this.rH(c)}return a},rH:function(a){if(!a)return\"\";var b=[];Object.keys(a).forEach(function(c){b.push(this.Dw(c)+\"\\x3d\"+this.Dw(a[c]))},this);return b.join(\"\\x26\")},Dw:function(a){return encodeURIComponent(a.toString().replace(/\\r?\\n/g,\"\\r\\n\")).replace(/%20/g,\"+\")},Tn:function(){this._setStatus(this.xhr.status);\nthis._setStatusText(void 0===this.xhr.statusText?\"\":this.xhr.statusText)}});V.yp.yp={};\nPolymer({is:\"iron-ajax\",hostAttributes:{hidden:!0},properties:{url:{type:String},params:{type:Object,value:function(){return{}}},method:{type:String,value:\"GET\"},headers:{type:Object,value:function(){return{}}},contentType:{type:String,value:null},body:{type:Object,value:null},sync:{type:Boolean,value:!1},handleAs:{type:String,value:\"json\"},withCredentials:{type:Boolean,value:!1},timeout:{type:Number,value:0},auto:{type:Boolean,value:!1},verbose:{type:Boolean,value:!1},lastRequest:{type:Object,notify:!0,\nreadOnly:!0},loading:{type:Boolean,notify:!0,readOnly:!0},lastResponse:{type:Object,notify:!0,readOnly:!0},lastError:{type:Object,notify:!0,readOnly:!0},activeRequests:{type:Array,notify:!0,readOnly:!0,value:function(){return[]}},debounceDuration:{type:Number,value:0,notify:!0},jsonPrefix:{type:String,value:\"\"},bubbles:{type:Boolean,value:!1},_boundHandleResponse:{type:Function,value:function(){return this.TF.bind(this)}}},observers:[\"i1(url,method,params.*,headers,contentType,body,sync,handleAs,jsonPrefix,withCredentials,timeout,auto)\"],\nget dP(){var a=[],b,c;for(b in this.params)if(c=this.params[b],b=window.encodeURIComponent(b),Array.isArray(c))for(var e=0;e<c.length;e++)a.push(b+\"\\x3d\"+window.encodeURIComponent(c[e]));else null!==c?a.push(b+\"\\x3d\"+window.encodeURIComponent(c)):a.push(b);return a.join(\"\\x26\")},get NP(){var a=this.dP;if(a){var b=0<=this.url.indexOf(\"?\")?\"\\x26\":\"?\";return this.url+b+a}return this.url},get MP(){var a={},b=this.contentType;null==b&&\"string\"===typeof this.body&&(b=\"application/x-www-form-urlencoded\");\nb&&(a[\"content-type\"]=b);var c;if(this.headers instanceof Object)for(c in this.headers)a[c]=this.headers[c].toString();return a},qW:function(){return{url:this.NP||\"\",method:this.method,headers:this.MP,body:this.body,async:!this.sync,handleAs:this.handleAs,jsonPrefix:this.jsonPrefix,withCredentials:this.withCredentials,timeout:this.timeout}},generateRequest:function(){var a=document.createElement(\"iron-request\"),b=this.qW();this.activeRequests.push(a);a.completes.then(this._boundHandleResponse).catch(this.SF.bind(this,\na)).then(this.vF.bind(this,a));a.send(b);this._setLastRequest(a);this._setLoading(!0);this.fire(\"request\",{request:a,options:b},{bubbles:this.bubbles});return a},TF:function(a){a===this.lastRequest&&(this._setLastResponse(a.response),this._setLastError(null),this._setLoading(!1));this.fire(\"response\",a,{bubbles:this.bubbles})},SF:function(a,b){this.verbose&&console.error(b);a===this.lastRequest&&(this._setLastError({request:a,error:b}),this._setLastResponse(null),this._setLoading(!1));this.fire(\"error\",\n{request:a,error:b},{bubbles:this.bubbles})},vF:function(a){a=this.activeRequests.indexOf(a);-1<a&&this.activeRequests.splice(a,1)},i1:function(){this.debounce(\"generate-request\",function(){null!=this.url&&this.auto&&this.generateRequest()},this.debounceDuration)}});\nPolymer({is:\"google-chart\",properties:{type:{type:String,value:\"column\",observer:\"xw\"},events:{type:Array,value:function(){return[]}},options:{type:Object},cols:{type:Array,observer:\"o1\"},rows:{type:Array,observer:\"o1\"},data:{type:Object,observer:\"c0\"},view:{type:Object,observer:\"F1\"},selection:{type:Array,notify:!0,observer:\"TG\"},drawn:{type:Boolean,readOnly:!0,value:!1}},observers:[\"xF(Th,el)\",\"u1(options.*)\"],listeners:{\"google-chart-select\":\"E1\",\"google-chart-ready\":\"K0\"},Th:null,el:null,Jf:null,\nxw:function(){this.$.loader.create(this.type,this.$.chartdiv).then(function(a){var b=this.$.loader;Object.keys(this.events.concat([\"select\",\"ready\"]).reduce(function(a,b){a[b]=!0;return a},{})).forEach(function(c){b.YK(a,c)});this._setDrawn(!1);this.Th=a}.bind(this))},u1:function(a){this.options=a.base;this.debounce(\"optionChangeRedraw\",function(){this.redraw()},5)},TG:function(){this.drawn&&this.selection&&this.selection!==this.Jf&&(this.Th.setSelection&&this.Th.setSelection(this.selection),this.Jf=\nthis.selection)},E1:function(){this.selection=this.Jf=this.Th.getSelection()},K0:function(){this._setDrawn(!0);this.Jf=null;this.TG()},redraw:function(){this.Th&&this.el&&this.xF(this.Th,this.el)},xF:function(a,b){try{this._setDrawn(!1),a.draw(b,this.options||{})}catch(c){this.$.chartdiv.innerHTML=c}},get p7(){return this.Th?this.Th.getImageURI():null},F1:function(a){a&&(this.el=a)},o1:function(){var a=this.rows,b=this.cols;a&&b&&this.$.loader.Dl().then(function(c){b.forEach(function(a){c.addColumn(a)});\nc.addRows(a);return c}.bind(this)).then(this.$.loader.no.bind(this.$.loader)).then(function(a){this.el=a}.bind(this)).catch(function(a){this.$.chartdiv.innerHTML=a}.bind(this))},c0:function(a){if(a){if(\"string\"==typeof a||a instanceof String){var b=document.createElement(\"iron-request\");a=b.send({url:a,handleAs:\"json\"}).then(function(a){return a.response})}else a=Promise.resolve(a);a.then(this.$.loader.Dl.bind(this.$.loader)).then(this.$.loader.no.bind(this.$.loader)).then(function(a){this.el=a}.bind(this))}}});\n(function(){var a={area:{ctor:\"AreaChart\"},bar:{ctor:\"BarChart\"},\"md-bar\":{ctor:\"Bar\",Eh:\"bar\"},bubble:{ctor:\"BubbleChart\"},candlestick:{ctor:\"CandlestickChart\"},column:{ctor:\"ColumnChart\"},combo:{ctor:\"ComboChart\"},geo:{ctor:\"GeoChart\"},histogram:{ctor:\"Histogram\"},line:{ctor:\"LineChart\"},\"md-line\":{ctor:\"Line\",Eh:\"line\"},org:{ctor:\"OrgChart\",Eh:\"orgchart\"},pie:{ctor:\"PieChart\"},scatter:{ctor:\"ScatterChart\"},\"md-scatter\":{ctor:\"Scatter\",Eh:\"scatter\"},\"stepped-area\":{ctor:\"SteppedAreaChart\"},table:{ctor:\"Table\",\nEh:\"table\"},timeline:{ctor:\"Timeline\",Eh:\"timeline\"},gauge:{ctor:\"Gauge\",Eh:\"gauge\"},treemap:{ctor:\"TreeMap\",Eh:\"treemap\"},calendar:{ctor:\"Calendar\",Eh:\"calendar\"}},b={},c={},e={};Polymer({is:\"google-chart-loader\",properties:{packages:{type:Array,value:function(){return[]},observer:\"Tv\"},type:{type:String,observer:\"eG\"}},get wn(){return c.corechart?c.corechart:this.Tv([\"corechart\"]).then(function(a){return a[0]})},fG:function(){this.debounce(\"loadPackages\",function(){var a=Object.keys(b);a.length&&\n(b={},google.charts.load(\"current\",{packages:a,language:document.documentElement.lang||\"en\"}),google.charts.setOnLoadCallback(function(){a.forEach(function(a){this.fire(\"loaded\",a);e[a](google.visualization)}.bind(this))}.bind(this)))},100)},Tv:function(a){var g=[];a.forEach(function(a){c[a]||(b[a]=!0,c[a]=new Promise(function(b){e[a]=b}),this.fG());g.push(c[a])}.bind(this));return Promise.all(g)},eG:function(b){var c=a[b];return this.Tv([c.Eh||\"corechart\"]).then(function(){return google[0===b.indexOf(\"md-\")?\n\"charts\":\"visualization\"][c.ctor]})},create:function(a,b){return this.eG(a).then(function(a){return new a(b)})},YK:function(a,b,c){return this.wn.then(function(e){e=c?e.events.addOneTimeListener:e.events.addListener;e(a,b,function(c){this.fire(\"google-chart-\"+b,{r3:a,data:c})}.bind(this))}.bind(this))},Dl:function(a){return this.wn.then(function(b){return null==a?new b.DataTable:a.getNumberOfRows?a:a.cols?new b.DataTable(a):0<a.length?b.arrayToDataTable(a):0===a.length?Promise.reject(\"Data was empty.\"):\nPromise.reject(\"Data format was not recognized.\")})},no:function(a){return this.wn.then(function(b){return new b.DataView(a)})},query:function(a,b){return this.wn.then(function(c){return new c.Query(a,b)})}})})();V.Vf.Ci={};V.Vf.Ci.FE={};V.Vf.Ci.LE={};V.Ij.Ci={};V.Ij.Ci.qY={};console.warn(\"This file is deprecated. Please use `iron-flex-layout/iron-flex-layout-classes.html`, and one of the specific dom-modules instead\");V.Ij.Ci.Ij={};console.warn(\"This file is deprecated. Please use `iron-flex-layout/iron-flex-layout-classes.html`, and one of the specific dom-modules instead\");\nV.Vf.yZ={};V.Vf.Ci.XX={};V.Vf.Ci.VZ={};V.Vf.uX={};V.Vf.Vf={};D.Fi={};D.Fi.IX={TW:\"arrow-asc\",UW:\"arrow-desc\",m_:\"visible-column\"};D.Fi.JY=20;D.Fi.ln=\"gviz-table\";\nPolymer({is:\"metrics-table\",properties:{metrics:{type:Array,value:function(){return[]}},metricFormats:{type:Object,value:function(){return{}}},data:Object,options:{type:Object,value:function(){return{allowHtml:!0,width:\"100%\",page:\"enable\",pageSize:20,pageButtons:\"auto\"}}},selection:{type:Array,observer:\"WP\",notify:!0},selected:{type:String,value:\"\"},tableReady_:{type:Boolean,value:!1},plotData_:{type:Array,computed:\"T3(data,selected,metrics,metricFormats,tableReady_)\"}},ready:function(){var a=this.querySelector(D.Fi.ln);\nthis.tm=!0;var b=function(){a.removeEventListener(\"google-chart-ready\",b);this.tableReady_=!0}.bind(this);a.addEventListener(\"google-chart-ready\",b)},select:function(a){this.qC(a,!0)},clearSelection:function(){this.ax(!0)},X6:function(a){this.qC(a,!1)},x3:function(){this.ax(!1)},qC:function(a,b){for(var c=this.querySelector(D.Fi.ln),e=-1,g=this.plotData_,k=1;k<g.length;k++)if(g[k][0].f==a){e=k-1;break}h.R.assert(-1!=e);this.tm=b;c.selection=[{row:e}];this.tm=!0},ax:function(a){var b=this.querySelector(D.Fi.ln);\nthis.tm=a;b.selection=[];this.tm=!0},WP:function(){if(this.tm){var a=this.querySelector(D.Fi.ln),b=a.selection;b.length?(a=this.plotData_[a.selection[0].row+1][0].f,this.dispatchEvent(new CustomEvent(D.Event.Op,{detail:a}))):this.dispatchEvent(new Event(D.Event.Vt))}},T3:function(a,b,c,e,g){if(!g||!a.zs(b))return[[]];var k=a.Gr(c);b=a.getDataTable(b);var m=a.Fr(e);e=b.map(function(b){return k.map(function(c,e){return D.data.Ua.JP(b[e],a,m[c])})});return[k].concat(e)}});D.Ji={};D.Ji.Xt=\"Slice\";\nD.Ji.XD=680;D.Ji.$C=200;\nPolymer({is:\"slice-overview\",properties:{slices:{type:Object},chart_:{type:Object},metrics_:{type:Array,computed:\"S3(slices)\"},metricsForSorting_:{type:Array,computed:\"Q3(metrics_)\"},metricToShow:{type:String},metricToSort_:{type:String,value:D.Ji.Xt},chartPackages_:{type:Array,value:[\"corechart\"]},displayed:{type:Boolean},dataView_:{type:Object}},observers:[\"A$(displayed,slices,metricToShow,metricToSort_,chart_)\"],S3:function(a){if(!a)return[];var b=a.lk(),c={};a.jk().forEach(function(e){e=a.Hl(e);\ne.forEach(function(a,e){!h.ni(a)&&h.Ch(a)&&(c[b[e]]=!0)})});return b.map(function(a){return{name:a,disabled:!!c[a]}})},Q3:function(a){return[{name:D.Ji.Xt,disabled:!1}].concat(a)},A$:function(a,b,c,e,g){var k=this;if(a&&b&&g&&c&&e){var m=b.ki(c);if(-1!=m){var n=b.ki(e),q=[[\"feature\"].concat(b.lk())],v=-1!=n&&e!=c;b.jk().forEach(function(a){var c=b.Hl(a),g=a;v&&(g={v:a,f:a+\", \"+e+\":\"+c[n].toFixed(D.Nh)});q.push([g].concat(c.map(function(a){return h.ni(a)?a:NaN})))});this.$.loader.Dl(q).then(function(a){-1!=\nn&&a.sort([{column:n+1}]);k.$.loader.no(a).then(function(a){a.setColumns([0,m+1]);k.dataView_=a;k.chart_.draw(a,{bar:{groupWidth:\"75%\"},hAxis:{ticks:[]},legend:{position:\"top\"},width:Math.max(k.getBoundingClientRect().width,D.Ji.XD),height:D.Ji.$C})})})}}},ready:function(){var a=this;this.$.loader.create(\"column\",this.$.chart).then(function(b){return a.chart_=b});this.displayed=0<this.getBoundingClientRect().width}});V.wu={};V.wu.wu={};\nPolymer({is:\"iron-pages\",behaviors:[Polymer.Jj,Polymer.Nk],properties:{activateEvent:{type:String,value:null}},observers:[\"q1(selected)\"],q1:function(){this.async(this.ri)}});D.Ff={};D.Ff.xg={GE:\"table\",FD:\"histogram\",cX:\"chart-type\",ZE:\"weighted-examples-threshold\"};D.Ff.Hk={Pp:0,Bu:1};D.Ff.CE=50;D.Ff.YE=10;\nPolymer({is:\"lantern-browser\",properties:{data:{type:Array,value:function(){return[]}},metrics:{type:Array,value:function(){return[]}},sourceType:{type:String},weightedExamplesColumn:{type:String,value:\"\"},weightedExamplesThreshold:{type:Number,value:0},chartType:{type:String,value:D.Ff.Hk.Bu,observer:\"s3\"},selectedFeatures:{type:Array,value:function(){return[]}},selectedColumn:{type:String,value:\"\"},calibrationPlotUriFn:{type:Object,value:null},lanternData_:{type:Object,computed:\"O3(metrics,data,sourceType)\",\nobserver:\"c8\"},filteredData_:{type:Object,computed:\"N3(lanternData_,weightedExamplesColumn,weightedExamplesThreshold)\",observer:\"Z5\"},focusedData_:{type:Object,value:new D.Jb([],[])},weightedExamplesInfo_:{type:Object,computed:\"X3(lanternData_,weightedExamplesColumn,calibrationPlotUriFn)\"},metricFormats_:{type:Object,computed:\"P3(focusedData_,weightedExamplesColumn,calibrationPlotUriFn)\"},metricsTableData_:{type:Object,computed:\"R3(chartType,filteredData_,focusedData_)\"}},observers:[\"nda(lanternData_)\"],\nready:function(){this.fN();this.gN()},fN:function(){var a=this.$[D.Ff.xg.GE];a.addEventListener(D.Event.Op,function(a){a=a.detail;this.selectedFeatures=[a]}.bind(this))},gN:function(){var a=this.$[D.Ff.xg.ZE],b=a.getElementsByTagName(\"input\")[0],c=a.getElementsByTagName(\"paper-slider\")[0],a=function(a){a=+a.target.value;c.setAttribute(\"value\",a);this.weightedExamplesThreshold=a}.bind(this);b.addEventListener(D.Event.xu,a);c.addEventListener(D.Event.KD,function(a){a=+a.target.getElementsByTagName(\"paper-progress\")[0].getAttribute(\"value\");\nb.value=a});c.addEventListener(D.Event.Ut,function(a){this.weightedExamplesThreshold=a=+a.target.getElementsByTagName(\"paper-progress\")[0].getAttribute(\"value\")}.bind(this))},nda:function(a){a=a.vB()?\"none\":\"\";for(var b=this.getElementsByClassName(\"vis\"),c=0;c<b.length;c++)b[c].style.display=a},O3:function(a,b,c){return D.Jb.Vw(a,b,c)},N3:function(a,b,c){var e=a.ki(b);return a.filter(function(a){a=a.Bh();return a[e]>=c})},X3:function(a,b){b=a.getColumnRange(b);a=Math.min(D.Ff.YE,Math.ceil(b.max/100));\nb=Math.ceil((b.max+1)/a)*a;return{max:b,step:a}},P3:function(a,b,c){var e={};e[b]={type:D.Pk.INT};a.Xr()&&(a=function(a){var b=\"\";a.to()&&c&&(a=a.Ah(),a==D.Pf.Kj&&(a=\"\"),b='\\x3ca href\\x3d\"'+c(a)+'\" target\\x3d\"_blank\" class\\x3d\"links\"\\x3eCalib. Plot\\x3c/a\\x3e');return b}.bind(this),e[D.Pf.yu]={type:D.Pk.GD,transform:{withDataSeries:a}});return e},Z5:function(){this.$[D.Ff.xg.FD].cp(0,1)},s3:function(a){this.querySelector(\"slice-overview\").displayed=a==D.Ff.Hk.Pp},c8:function(a){this.chartType=a&&a.jk().length>\nD.Ff.CE?D.Ff.Hk.Bu:D.Ff.Hk.Pp},R3:function(a,b,c){return a==D.Ff.Hk.Pp?b:c}});\n</script></body></html>\n"
  },
  {
    "path": "google/datalab/notebook/static/extern/parcoords-LICENSE.txt",
    "content": "Copyright (c) 2012, Kai Chang\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n* Redistributions of source code must retain the above copyright notice, this\n  list of conditions and the following disclaimer.\n\n* Redistributions in binary form must reproduce the above copyright notice,\n  this list of conditions and the following disclaimer in the documentation\n  and/or other materials provided with the distribution.\n\n* The name Kai Chang may not be used to endorse or promote products\n  derived from this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL MICHAEL BOSTOCK BE LIABLE FOR ANY DIRECT,\nINDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\nBUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY\nOF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\nNEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\nEVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "google/datalab/notebook/static/extern/sylvester-LICENSE.txt",
    "content": "(The MIT License)\n\nCopyright (c) 2007-2015 James Coglan\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "google/datalab/notebook/static/extern/sylvester.js",
    "content": "// === Sylvester ===\n// Vector and Matrix mathematics modules for JavaScript\n// Copyright (c) 2007 James Coglan\n// \n// Permission is hereby granted, free of charge, to any person obtaining\n// a copy of this software and associated documentation files (the \"Software\"),\n// to deal in the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nvar Sylvester = {\n  version: '0.1.3',\n  precision: 1e-6\n};\n\nfunction Vector() {}\nVector.prototype = {\n\n  // Returns element i of the vector\n  e: function(i) {\n    return (i < 1 || i > this.elements.length) ? null : this.elements[i-1];\n  },\n\n  // Returns the number of elements the vector has\n  dimensions: function() {\n    return this.elements.length;\n  },\n\n  // Returns the modulus ('length') of the vector\n  modulus: function() {\n    return Math.sqrt(this.dot(this));\n  },\n\n  // Returns true iff the vector is equal to the argument\n  eql: function(vector) {\n    var n = this.elements.length;\n    var V = vector.elements || vector;\n    if (n != V.length) { return false; }\n    do {\n      if (Math.abs(this.elements[n-1] - V[n-1]) > Sylvester.precision) { return false; }\n    } while (--n);\n    return true;\n  },\n\n  // Returns a copy of the vector\n  dup: function() {\n    return Vector.create(this.elements);\n  },\n\n  // Maps the vector to another vector according to the given function\n  map: function(fn) {\n    var elements = [];\n    this.each(function(x, i) {\n      elements.push(fn(x, i));\n    });\n    return Vector.create(elements);\n  },\n  \n  // Calls the iterator for each element of the vector in turn\n  each: function(fn) {\n    var n = this.elements.length, k = n, i;\n    do { i = k - n;\n      fn(this.elements[i], i+1);\n    } while (--n);\n  },\n\n  // Returns a new vector created by normalizing the receiver\n  toUnitVector: function() {\n    var r = this.modulus();\n    if (r === 0) { return this.dup(); }\n    return this.map(function(x) { return x/r; });\n  },\n\n  // Returns the angle between the vector and the argument (also a vector)\n  angleFrom: function(vector) {\n    var V = vector.elements || vector;\n    var n = this.elements.length, k = n, i;\n    if (n != V.length) { return null; }\n    var dot = 0, mod1 = 0, mod2 = 0;\n    // Work things out in parallel to save time\n    this.each(function(x, i) {\n      dot += x * V[i-1];\n      mod1 += x * x;\n      mod2 += V[i-1] * V[i-1];\n    });\n    mod1 = Math.sqrt(mod1); mod2 = Math.sqrt(mod2);\n    if (mod1*mod2 === 0) { return null; }\n    var theta = dot / (mod1*mod2);\n    if (theta < -1) { theta = -1; }\n    if (theta > 1) { theta = 1; }\n    return Math.acos(theta);\n  },\n\n  // Returns true iff the vector is parallel to the argument\n  isParallelTo: function(vector) {\n    var angle = this.angleFrom(vector);\n    return (angle === null) ? null : (angle <= Sylvester.precision);\n  },\n\n  // Returns true iff the vector is antiparallel to the argument\n  isAntiparallelTo: function(vector) {\n    var angle = this.angleFrom(vector);\n    return (angle === null) ? null : (Math.abs(angle - Math.PI) <= Sylvester.precision);\n  },\n\n  // Returns true iff the vector is perpendicular to the argument\n  isPerpendicularTo: function(vector) {\n    var dot = this.dot(vector);\n    return (dot === null) ? null : (Math.abs(dot) <= Sylvester.precision);\n  },\n\n  // Returns the result of adding the argument to the vector\n  add: function(vector) {\n    var V = vector.elements || vector;\n    if (this.elements.length != V.length) { return null; }\n    return this.map(function(x, i) { return x + V[i-1]; });\n  },\n\n  // Returns the result of subtracting the argument from the vector\n  subtract: function(vector) {\n    var V = vector.elements || vector;\n    if (this.elements.length != V.length) { return null; }\n    return this.map(function(x, i) { return x - V[i-1]; });\n  },\n\n  // Returns the result of multiplying the elements of the vector by the argument\n  multiply: function(k) {\n    return this.map(function(x) { return x*k; });\n  },\n\n  x: function(k) { return this.multiply(k); },\n\n  // Returns the scalar product of the vector with the argument\n  // Both vectors must have equal dimensionality\n  dot: function(vector) {\n    var V = vector.elements || vector;\n    var i, product = 0, n = this.elements.length;\n    if (n != V.length) { return null; }\n    do { product += this.elements[n-1] * V[n-1]; } while (--n);\n    return product;\n  },\n\n  // Returns the vector product of the vector with the argument\n  // Both vectors must have dimensionality 3\n  cross: function(vector) {\n    var B = vector.elements || vector;\n    if (this.elements.length != 3 || B.length != 3) { return null; }\n    var A = this.elements;\n    return Vector.create([\n      (A[1] * B[2]) - (A[2] * B[1]),\n      (A[2] * B[0]) - (A[0] * B[2]),\n      (A[0] * B[1]) - (A[1] * B[0])\n    ]);\n  },\n\n  // Returns the (absolute) largest element of the vector\n  max: function() {\n    var m = 0, n = this.elements.length, k = n, i;\n    do { i = k - n;\n      if (Math.abs(this.elements[i]) > Math.abs(m)) { m = this.elements[i]; }\n    } while (--n);\n    return m;\n  },\n\n  // Returns the index of the first match found\n  indexOf: function(x) {\n    var index = null, n = this.elements.length, k = n, i;\n    do { i = k - n;\n      if (index === null && this.elements[i] == x) {\n        index = i + 1;\n      }\n    } while (--n);\n    return index;\n  },\n\n  // Returns a diagonal matrix with the vector's elements as its diagonal elements\n  toDiagonalMatrix: function() {\n    return Matrix.Diagonal(this.elements);\n  },\n\n  // Returns the result of rounding the elements of the vector\n  round: function() {\n    return this.map(function(x) { return Math.round(x); });\n  },\n\n  // Returns a copy of the vector with elements set to the given value if they\n  // differ from it by less than Sylvester.precision\n  snapTo: function(x) {\n    return this.map(function(y) {\n      return (Math.abs(y - x) <= Sylvester.precision) ? x : y;\n    });\n  },\n\n  // Returns the vector's distance from the argument, when considered as a point in space\n  distanceFrom: function(obj) {\n    if (obj.anchor) { return obj.distanceFrom(this); }\n    var V = obj.elements || obj;\n    if (V.length != this.elements.length) { return null; }\n    var sum = 0, part;\n    this.each(function(x, i) {\n      part = x - V[i-1];\n      sum += part * part;\n    });\n    return Math.sqrt(sum);\n  },\n\n  // Returns true if the vector is point on the given line\n  liesOn: function(line) {\n    return line.contains(this);\n  },\n\n  // Return true iff the vector is a point in the given plane\n  liesIn: function(plane) {\n    return plane.contains(this);\n  },\n\n  // Rotates the vector about the given object. The object should be a \n  // point if the vector is 2D, and a line if it is 3D. Be careful with line directions!\n  rotate: function(t, obj) {\n    var V, R, x, y, z;\n    switch (this.elements.length) {\n      case 2:\n        V = obj.elements || obj;\n        if (V.length != 2) { return null; }\n        R = Matrix.Rotation(t).elements;\n        x = this.elements[0] - V[0];\n        y = this.elements[1] - V[1];\n        return Vector.create([\n          V[0] + R[0][0] * x + R[0][1] * y,\n          V[1] + R[1][0] * x + R[1][1] * y\n        ]);\n        break;\n      case 3:\n        if (!obj.direction) { return null; }\n        var C = obj.pointClosestTo(this).elements;\n        R = Matrix.Rotation(t, obj.direction).elements;\n        x = this.elements[0] - C[0];\n        y = this.elements[1] - C[1];\n        z = this.elements[2] - C[2];\n        return Vector.create([\n          C[0] + R[0][0] * x + R[0][1] * y + R[0][2] * z,\n          C[1] + R[1][0] * x + R[1][1] * y + R[1][2] * z,\n          C[2] + R[2][0] * x + R[2][1] * y + R[2][2] * z\n        ]);\n        break;\n      default:\n        return null;\n    }\n  },\n\n  // Returns the result of reflecting the point in the given point, line or plane\n  reflectionIn: function(obj) {\n    if (obj.anchor) {\n      // obj is a plane or line\n      var P = this.elements.slice();\n      var C = obj.pointClosestTo(P).elements;\n      return Vector.create([C[0] + (C[0] - P[0]), C[1] + (C[1] - P[1]), C[2] + (C[2] - (P[2] || 0))]);\n    } else {\n      // obj is a point\n      var Q = obj.elements || obj;\n      if (this.elements.length != Q.length) { return null; }\n      return this.map(function(x, i) { return Q[i-1] + (Q[i-1] - x); });\n    }\n  },\n\n  // Utility to make sure vectors are 3D. If they are 2D, a zero z-component is added\n  to3D: function() {\n    var V = this.dup();\n    switch (V.elements.length) {\n      case 3: break;\n      case 2: V.elements.push(0); break;\n      default: return null;\n    }\n    return V;\n  },\n\n  // Returns a string representation of the vector\n  inspect: function() {\n    return '[' + this.elements.join(', ') + ']';\n  },\n\n  // Set vector's elements from an array\n  setElements: function(els) {\n    this.elements = (els.elements || els).slice();\n    return this;\n  }\n};\n  \n// Constructor function\nVector.create = function(elements) {\n  var V = new Vector();\n  return V.setElements(elements);\n};\n\n// i, j, k unit vectors\nVector.i = Vector.create([1,0,0]);\nVector.j = Vector.create([0,1,0]);\nVector.k = Vector.create([0,0,1]);\n\n// Random vector of size n\nVector.Random = function(n) {\n  var elements = [];\n  do { elements.push(Math.random());\n  } while (--n);\n  return Vector.create(elements);\n};\n\n// Vector filled with zeros\nVector.Zero = function(n) {\n  var elements = [];\n  do { elements.push(0);\n  } while (--n);\n  return Vector.create(elements);\n};\n\n\n\nfunction Matrix() {}\nMatrix.prototype = {\n\n  // Returns element (i,j) of the matrix\n  e: function(i,j) {\n    if (i < 1 || i > this.elements.length || j < 1 || j > this.elements[0].length) { return null; }\n    return this.elements[i-1][j-1];\n  },\n\n  // Returns row k of the matrix as a vector\n  row: function(i) {\n    if (i > this.elements.length) { return null; }\n    return Vector.create(this.elements[i-1]);\n  },\n\n  // Returns column k of the matrix as a vector\n  col: function(j) {\n    if (j > this.elements[0].length) { return null; }\n    var col = [], n = this.elements.length, k = n, i;\n    do { i = k - n;\n      col.push(this.elements[i][j-1]);\n    } while (--n);\n    return Vector.create(col);\n  },\n\n  // Returns the number of rows/columns the matrix has\n  dimensions: function() {\n    return {rows: this.elements.length, cols: this.elements[0].length};\n  },\n\n  // Returns the number of rows in the matrix\n  rows: function() {\n    return this.elements.length;\n  },\n\n  // Returns the number of columns in the matrix\n  cols: function() {\n    return this.elements[0].length;\n  },\n\n  // Returns true iff the matrix is equal to the argument. You can supply\n  // a vector as the argument, in which case the receiver must be a\n  // one-column matrix equal to the vector.\n  eql: function(matrix) {\n    var M = matrix.elements || matrix;\n    if (typeof(M[0][0]) == 'undefined') { M = Matrix.create(M).elements; }\n    if (this.elements.length != M.length ||\n        this.elements[0].length != M[0].length) { return false; }\n    var ni = this.elements.length, ki = ni, i, nj, kj = this.elements[0].length, j;\n    do { i = ki - ni;\n      nj = kj;\n      do { j = kj - nj;\n        if (Math.abs(this.elements[i][j] - M[i][j]) > Sylvester.precision) { return false; }\n      } while (--nj);\n    } while (--ni);\n    return true;\n  },\n\n  // Returns a copy of the matrix\n  dup: function() {\n    return Matrix.create(this.elements);\n  },\n\n  // Maps the matrix to another matrix (of the same dimensions) according to the given function\n  map: function(fn) {\n    var els = [], ni = this.elements.length, ki = ni, i, nj, kj = this.elements[0].length, j;\n    do { i = ki - ni;\n      nj = kj;\n      els[i] = [];\n      do { j = kj - nj;\n        els[i][j] = fn(this.elements[i][j], i + 1, j + 1);\n      } while (--nj);\n    } while (--ni);\n    return Matrix.create(els);\n  },\n\n  // Returns true iff the argument has the same dimensions as the matrix\n  isSameSizeAs: function(matrix) {\n    var M = matrix.elements || matrix;\n    if (typeof(M[0][0]) == 'undefined') { M = Matrix.create(M).elements; }\n    return (this.elements.length == M.length &&\n        this.elements[0].length == M[0].length);\n  },\n\n  // Returns the result of adding the argument to the matrix\n  add: function(matrix) {\n    var M = matrix.elements || matrix;\n    if (typeof(M[0][0]) == 'undefined') { M = Matrix.create(M).elements; }\n    if (!this.isSameSizeAs(M)) { return null; }\n    return this.map(function(x, i, j) { return x + M[i-1][j-1]; });\n  },\n\n  // Returns the result of subtracting the argument from the matrix\n  subtract: function(matrix) {\n    var M = matrix.elements || matrix;\n    if (typeof(M[0][0]) == 'undefined') { M = Matrix.create(M).elements; }\n    if (!this.isSameSizeAs(M)) { return null; }\n    return this.map(function(x, i, j) { return x - M[i-1][j-1]; });\n  },\n\n  // Returns true iff the matrix can multiply the argument from the left\n  canMultiplyFromLeft: function(matrix) {\n    var M = matrix.elements || matrix;\n    if (typeof(M[0][0]) == 'undefined') { M = Matrix.create(M).elements; }\n    // this.columns should equal matrix.rows\n    return (this.elements[0].length == M.length);\n  },\n\n  // Returns the result of multiplying the matrix from the right by the argument.\n  // If the argument is a scalar then just multiply all the elements. If the argument is\n  // a vector, a vector is returned, which saves you having to remember calling\n  // col(1) on the result.\n  multiply: function(matrix) {\n    if (!matrix.elements) {\n      return this.map(function(x) { return x * matrix; });\n    }\n    var returnVector = matrix.modulus ? true : false;\n    var M = matrix.elements || matrix;\n    if (typeof(M[0][0]) == 'undefined') { M = Matrix.create(M).elements; }\n    if (!this.canMultiplyFromLeft(M)) { return null; }\n    var ni = this.elements.length, ki = ni, i, nj, kj = M[0].length, j;\n    var cols = this.elements[0].length, elements = [], sum, nc, c;\n    do { i = ki - ni;\n      elements[i] = [];\n      nj = kj;\n      do { j = kj - nj;\n        sum = 0;\n        nc = cols;\n        do { c = cols - nc;\n          sum += this.elements[i][c] * M[c][j];\n        } while (--nc);\n        elements[i][j] = sum;\n      } while (--nj);\n    } while (--ni);\n    var M = Matrix.create(elements);\n    return returnVector ? M.col(1) : M;\n  },\n\n  x: function(matrix) { return this.multiply(matrix); },\n\n  // Returns a submatrix taken from the matrix\n  // Argument order is: start row, start col, nrows, ncols\n  // Element selection wraps if the required index is outside the matrix's bounds, so you could\n  // use this to perform row/column cycling or copy-augmenting.\n  minor: function(a, b, c, d) {\n    var elements = [], ni = c, i, nj, j;\n    var rows = this.elements.length, cols = this.elements[0].length;\n    do { i = c - ni;\n      elements[i] = [];\n      nj = d;\n      do { j = d - nj;\n        elements[i][j] = this.elements[(a+i-1)%rows][(b+j-1)%cols];\n      } while (--nj);\n    } while (--ni);\n    return Matrix.create(elements);\n  },\n\n  // Returns the transpose of the matrix\n  transpose: function() {\n    var rows = this.elements.length, cols = this.elements[0].length;\n    var elements = [], ni = cols, i, nj, j;\n    do { i = cols - ni;\n      elements[i] = [];\n      nj = rows;\n      do { j = rows - nj;\n        elements[i][j] = this.elements[j][i];\n      } while (--nj);\n    } while (--ni);\n    return Matrix.create(elements);\n  },\n\n  // Returns true iff the matrix is square\n  isSquare: function() {\n    return (this.elements.length == this.elements[0].length);\n  },\n\n  // Returns the (absolute) largest element of the matrix\n  max: function() {\n    var m = 0, ni = this.elements.length, ki = ni, i, nj, kj = this.elements[0].length, j;\n    do { i = ki - ni;\n      nj = kj;\n      do { j = kj - nj;\n        if (Math.abs(this.elements[i][j]) > Math.abs(m)) { m = this.elements[i][j]; }\n      } while (--nj);\n    } while (--ni);\n    return m;\n  },\n\n  // Returns the indeces of the first match found by reading row-by-row from left to right\n  indexOf: function(x) {\n    var index = null, ni = this.elements.length, ki = ni, i, nj, kj = this.elements[0].length, j;\n    do { i = ki - ni;\n      nj = kj;\n      do { j = kj - nj;\n        if (this.elements[i][j] == x) { return {i: i+1, j: j+1}; }\n      } while (--nj);\n    } while (--ni);\n    return null;\n  },\n\n  // If the matrix is square, returns the diagonal elements as a vector.\n  // Otherwise, returns null.\n  diagonal: function() {\n    if (!this.isSquare) { return null; }\n    var els = [], n = this.elements.length, k = n, i;\n    do { i = k - n;\n      els.push(this.elements[i][i]);\n    } while (--n);\n    return Vector.create(els);\n  },\n\n  // Make the matrix upper (right) triangular by Gaussian elimination.\n  // This method only adds multiples of rows to other rows. No rows are\n  // scaled up or switched, and the determinant is preserved.\n  toRightTriangular: function() {\n    var M = this.dup(), els;\n    var n = this.elements.length, k = n, i, np, kp = this.elements[0].length, p;\n    do { i = k - n;\n      if (M.elements[i][i] == 0) {\n        for (j = i + 1; j < k; j++) {\n          if (M.elements[j][i] != 0) {\n            els = []; np = kp;\n            do { p = kp - np;\n              els.push(M.elements[i][p] + M.elements[j][p]);\n            } while (--np);\n            M.elements[i] = els;\n            break;\n          }\n        }\n      }\n      if (M.elements[i][i] != 0) {\n        for (j = i + 1; j < k; j++) {\n          var multiplier = M.elements[j][i] / M.elements[i][i];\n          els = []; np = kp;\n          do { p = kp - np;\n            // Elements with column numbers up to an including the number\n            // of the row that we're subtracting can safely be set straight to\n            // zero, since that's the point of this routine and it avoids having\n            // to loop over and correct rounding errors later\n            els.push(p <= i ? 0 : M.elements[j][p] - M.elements[i][p] * multiplier);\n          } while (--np);\n          M.elements[j] = els;\n        }\n      }\n    } while (--n);\n    return M;\n  },\n\n  toUpperTriangular: function() { return this.toRightTriangular(); },\n\n  // Returns the determinant for square matrices\n  determinant: function() {\n    if (!this.isSquare()) { return null; }\n    var M = this.toRightTriangular();\n    var det = M.elements[0][0], n = M.elements.length - 1, k = n, i;\n    do { i = k - n + 1;\n      det = det * M.elements[i][i];\n    } while (--n);\n    return det;\n  },\n\n  det: function() { return this.determinant(); },\n\n  // Returns true iff the matrix is singular\n  isSingular: function() {\n    return (this.isSquare() && this.determinant() === 0);\n  },\n\n  // Returns the trace for square matrices\n  trace: function() {\n    if (!this.isSquare()) { return null; }\n    var tr = this.elements[0][0], n = this.elements.length - 1, k = n, i;\n    do { i = k - n + 1;\n      tr += this.elements[i][i];\n    } while (--n);\n    return tr;\n  },\n\n  tr: function() { return this.trace(); },\n\n  // Returns the rank of the matrix\n  rank: function() {\n    var M = this.toRightTriangular(), rank = 0;\n    var ni = this.elements.length, ki = ni, i, nj, kj = this.elements[0].length, j;\n    do { i = ki - ni;\n      nj = kj;\n      do { j = kj - nj;\n        if (Math.abs(M.elements[i][j]) > Sylvester.precision) { rank++; break; }\n      } while (--nj);\n    } while (--ni);\n    return rank;\n  },\n  \n  rk: function() { return this.rank(); },\n\n  // Returns the result of attaching the given argument to the right-hand side of the matrix\n  augment: function(matrix) {\n    var M = matrix.elements || matrix;\n    if (typeof(M[0][0]) == 'undefined') { M = Matrix.create(M).elements; }\n    var T = this.dup(), cols = T.elements[0].length;\n    var ni = T.elements.length, ki = ni, i, nj, kj = M[0].length, j;\n    if (ni != M.length) { return null; }\n    do { i = ki - ni;\n      nj = kj;\n      do { j = kj - nj;\n        T.elements[i][cols + j] = M[i][j];\n      } while (--nj);\n    } while (--ni);\n    return T;\n  },\n\n  // Returns the inverse (if one exists) using Gauss-Jordan\n  inverse: function() {\n    if (!this.isSquare() || this.isSingular()) { return null; }\n    var ni = this.elements.length, ki = ni, i, j;\n    var M = this.augment(Matrix.I(ni)).toRightTriangular();\n    var np, kp = M.elements[0].length, p, els, divisor;\n    var inverse_elements = [], new_element;\n    // Matrix is non-singular so there will be no zeros on the diagonal\n    // Cycle through rows from last to first\n    do { i = ni - 1;\n      // First, normalise diagonal elements to 1\n      els = []; np = kp;\n      inverse_elements[i] = [];\n      divisor = M.elements[i][i];\n      do { p = kp - np;\n        new_element = M.elements[i][p] / divisor;\n        els.push(new_element);\n        // Shuffle of the current row of the right hand side into the results\n        // array as it will not be modified by later runs through this loop\n        if (p >= ki) { inverse_elements[i].push(new_element); }\n      } while (--np);\n      M.elements[i] = els;\n      // Then, subtract this row from those above it to\n      // give the identity matrix on the left hand side\n      for (j = 0; j < i; j++) {\n        els = []; np = kp;\n        do { p = kp - np;\n          els.push(M.elements[j][p] - M.elements[i][p] * M.elements[j][i]);\n        } while (--np);\n        M.elements[j] = els;\n      }\n    } while (--ni);\n    return Matrix.create(inverse_elements);\n  },\n\n  inv: function() { return this.inverse(); },\n\n  // Returns the result of rounding all the elements\n  round: function() {\n    return this.map(function(x) { return Math.round(x); });\n  },\n\n  // Returns a copy of the matrix with elements set to the given value if they\n  // differ from it by less than Sylvester.precision\n  snapTo: function(x) {\n    return this.map(function(p) {\n      return (Math.abs(p - x) <= Sylvester.precision) ? x : p;\n    });\n  },\n\n  // Returns a string representation of the matrix\n  inspect: function() {\n    var matrix_rows = [];\n    var n = this.elements.length, k = n, i;\n    do { i = k - n;\n      matrix_rows.push(Vector.create(this.elements[i]).inspect());\n    } while (--n);\n    return matrix_rows.join('\\n');\n  },\n\n  // Set the matrix's elements from an array. If the argument passed\n  // is a vector, the resulting matrix will be a single column.\n  setElements: function(els) {\n    var i, elements = els.elements || els;\n    if (typeof(elements[0][0]) != 'undefined') {\n      var ni = elements.length, ki = ni, nj, kj, j;\n      this.elements = [];\n      do { i = ki - ni;\n        nj = elements[i].length; kj = nj;\n        this.elements[i] = [];\n        do { j = kj - nj;\n          this.elements[i][j] = elements[i][j];\n        } while (--nj);\n      } while(--ni);\n      return this;\n    }\n    var n = elements.length, k = n;\n    this.elements = [];\n    do { i = k - n;\n      this.elements.push([elements[i]]);\n    } while (--n);\n    return this;\n  }\n};\n\n// Constructor function\nMatrix.create = function(elements) {\n  var M = new Matrix();\n  return M.setElements(elements);\n};\n\n// Identity matrix of size n\nMatrix.I = function(n) {\n  var els = [], k = n, i, nj, j;\n  do { i = k - n;\n    els[i] = []; nj = k;\n    do { j = k - nj;\n      els[i][j] = (i == j) ? 1 : 0;\n    } while (--nj);\n  } while (--n);\n  return Matrix.create(els);\n};\n\n// Diagonal matrix - all off-diagonal elements are zero\nMatrix.Diagonal = function(elements) {\n  var n = elements.length, k = n, i;\n  var M = Matrix.I(n);\n  do { i = k - n;\n    M.elements[i][i] = elements[i];\n  } while (--n);\n  return M;\n};\n\n// Rotation matrix about some axis. If no axis is\n// supplied, assume we're after a 2D transform\nMatrix.Rotation = function(theta, a) {\n  if (!a) {\n    return Matrix.create([\n      [Math.cos(theta),  -Math.sin(theta)],\n      [Math.sin(theta),   Math.cos(theta)]\n    ]);\n  }\n  var axis = a.dup();\n  if (axis.elements.length != 3) { return null; }\n  var mod = axis.modulus();\n  var x = axis.elements[0]/mod, y = axis.elements[1]/mod, z = axis.elements[2]/mod;\n  var s = Math.sin(theta), c = Math.cos(theta), t = 1 - c;\n  // Formula derived here: http://www.gamedev.net/reference/articles/article1199.asp\n  // That proof rotates the co-ordinate system so theta\n  // becomes -theta and sin becomes -sin here.\n  return Matrix.create([\n    [ t*x*x + c, t*x*y - s*z, t*x*z + s*y ],\n    [ t*x*y + s*z, t*y*y + c, t*y*z - s*x ],\n    [ t*x*z - s*y, t*y*z + s*x, t*z*z + c ]\n  ]);\n};\n\n// Special case rotations\nMatrix.RotationX = function(t) {\n  var c = Math.cos(t), s = Math.sin(t);\n  return Matrix.create([\n    [  1,  0,  0 ],\n    [  0,  c, -s ],\n    [  0,  s,  c ]\n  ]);\n};\nMatrix.RotationY = function(t) {\n  var c = Math.cos(t), s = Math.sin(t);\n  return Matrix.create([\n    [  c,  0,  s ],\n    [  0,  1,  0 ],\n    [ -s,  0,  c ]\n  ]);\n};\nMatrix.RotationZ = function(t) {\n  var c = Math.cos(t), s = Math.sin(t);\n  return Matrix.create([\n    [  c, -s,  0 ],\n    [  s,  c,  0 ],\n    [  0,  0,  1 ]\n  ]);\n};\n\n// Random matrix of n rows, m columns\nMatrix.Random = function(n, m) {\n  return Matrix.Zero(n, m).map(\n    function() { return Math.random(); }\n  );\n};\n\n// Matrix filled with zeros\nMatrix.Zero = function(n, m) {\n  var els = [], ni = n, i, nj, j;\n  do { i = n - ni;\n    els[i] = [];\n    nj = m;\n    do { j = m - nj;\n      els[i][j] = 0;\n    } while (--nj);\n  } while (--ni);\n  return Matrix.create(els);\n};\n\n\n\nfunction Line() {}\nLine.prototype = {\n\n  // Returns true if the argument occupies the same space as the line\n  eql: function(line) {\n    return (this.isParallelTo(line) && this.contains(line.anchor));\n  },\n\n  // Returns a copy of the line\n  dup: function() {\n    return Line.create(this.anchor, this.direction);\n  },\n\n  // Returns the result of translating the line by the given vector/array\n  translate: function(vector) {\n    var V = vector.elements || vector;\n    return Line.create([\n      this.anchor.elements[0] + V[0],\n      this.anchor.elements[1] + V[1],\n      this.anchor.elements[2] + (V[2] || 0)\n    ], this.direction);\n  },\n\n  // Returns true if the line is parallel to the argument. Here, 'parallel to'\n  // means that the argument's direction is either parallel or antiparallel to\n  // the line's own direction. A line is parallel to a plane if the two do not\n  // have a unique intersection.\n  isParallelTo: function(obj) {\n    if (obj.normal) { return obj.isParallelTo(this); }\n    var theta = this.direction.angleFrom(obj.direction);\n    return (Math.abs(theta) <= Sylvester.precision || Math.abs(theta - Math.PI) <= Sylvester.precision);\n  },\n\n  // Returns the line's perpendicular distance from the argument,\n  // which can be a point, a line or a plane\n  distanceFrom: function(obj) {\n    if (obj.normal) { return obj.distanceFrom(this); }\n    if (obj.direction) {\n      // obj is a line\n      if (this.isParallelTo(obj)) { return this.distanceFrom(obj.anchor); }\n      var N = this.direction.cross(obj.direction).toUnitVector().elements;\n      var A = this.anchor.elements, B = obj.anchor.elements;\n      return Math.abs((A[0] - B[0]) * N[0] + (A[1] - B[1]) * N[1] + (A[2] - B[2]) * N[2]);\n    } else {\n      // obj is a point\n      var P = obj.elements || obj;\n      var A = this.anchor.elements, D = this.direction.elements;\n      var PA1 = P[0] - A[0], PA2 = P[1] - A[1], PA3 = (P[2] || 0) - A[2];\n      var modPA = Math.sqrt(PA1*PA1 + PA2*PA2 + PA3*PA3);\n      if (modPA === 0) return 0;\n      // Assumes direction vector is normalized\n      var cosTheta = (PA1 * D[0] + PA2 * D[1] + PA3 * D[2]) / modPA;\n      var sin2 = 1 - cosTheta*cosTheta;\n      return Math.abs(modPA * Math.sqrt(sin2 < 0 ? 0 : sin2));\n    }\n  },\n\n  // Returns true iff the argument is a point on the line\n  contains: function(point) {\n    var dist = this.distanceFrom(point);\n    return (dist !== null && dist <= Sylvester.precision);\n  },\n\n  // Returns true iff the line lies in the given plane\n  liesIn: function(plane) {\n    return plane.contains(this);\n  },\n\n  // Returns true iff the line has a unique point of intersection with the argument\n  intersects: function(obj) {\n    if (obj.normal) { return obj.intersects(this); }\n    return (!this.isParallelTo(obj) && this.distanceFrom(obj) <= Sylvester.precision);\n  },\n\n  // Returns the unique intersection point with the argument, if one exists\n  intersectionWith: function(obj) {\n    if (obj.normal) { return obj.intersectionWith(this); }\n    if (!this.intersects(obj)) { return null; }\n    var P = this.anchor.elements, X = this.direction.elements,\n        Q = obj.anchor.elements, Y = obj.direction.elements;\n    var X1 = X[0], X2 = X[1], X3 = X[2], Y1 = Y[0], Y2 = Y[1], Y3 = Y[2];\n    var PsubQ1 = P[0] - Q[0], PsubQ2 = P[1] - Q[1], PsubQ3 = P[2] - Q[2];\n    var XdotQsubP = - X1*PsubQ1 - X2*PsubQ2 - X3*PsubQ3;\n    var YdotPsubQ = Y1*PsubQ1 + Y2*PsubQ2 + Y3*PsubQ3;\n    var XdotX = X1*X1 + X2*X2 + X3*X3;\n    var YdotY = Y1*Y1 + Y2*Y2 + Y3*Y3;\n    var XdotY = X1*Y1 + X2*Y2 + X3*Y3;\n    var k = (XdotQsubP * YdotY / XdotX + XdotY * YdotPsubQ) / (YdotY - XdotY * XdotY);\n    return Vector.create([P[0] + k*X1, P[1] + k*X2, P[2] + k*X3]);\n  },\n\n  // Returns the point on the line that is closest to the given point or line\n  pointClosestTo: function(obj) {\n    if (obj.direction) {\n      // obj is a line\n      if (this.intersects(obj)) { return this.intersectionWith(obj); }\n      if (this.isParallelTo(obj)) { return null; }\n      var D = this.direction.elements, E = obj.direction.elements;\n      var D1 = D[0], D2 = D[1], D3 = D[2], E1 = E[0], E2 = E[1], E3 = E[2];\n      // Create plane containing obj and the shared normal and intersect this with it\n      // Thank you: http://www.cgafaq.info/wiki/Line-line_distance\n      var x = (D3 * E1 - D1 * E3), y = (D1 * E2 - D2 * E1), z = (D2 * E3 - D3 * E2);\n      var N = Vector.create([x * E3 - y * E2, y * E1 - z * E3, z * E2 - x * E1]);\n      var P = Plane.create(obj.anchor, N);\n      return P.intersectionWith(this);\n    } else {\n      // obj is a point\n      var P = obj.elements || obj;\n      if (this.contains(P)) { return Vector.create(P); }\n      var A = this.anchor.elements, D = this.direction.elements;\n      var D1 = D[0], D2 = D[1], D3 = D[2], A1 = A[0], A2 = A[1], A3 = A[2];\n      var x = D1 * (P[1]-A2) - D2 * (P[0]-A1), y = D2 * ((P[2] || 0) - A3) - D3 * (P[1]-A2),\n          z = D3 * (P[0]-A1) - D1 * ((P[2] || 0) - A3);\n      var V = Vector.create([D2 * x - D3 * z, D3 * y - D1 * x, D1 * z - D2 * y]);\n      var k = this.distanceFrom(P) / V.modulus();\n      return Vector.create([\n        P[0] + V.elements[0] * k,\n        P[1] + V.elements[1] * k,\n        (P[2] || 0) + V.elements[2] * k\n      ]);\n    }\n  },\n\n  // Returns a copy of the line rotated by t radians about the given line. Works by\n  // finding the argument's closest point to this line's anchor point (call this C) and\n  // rotating the anchor about C. Also rotates the line's direction about the argument's.\n  // Be careful with this - the rotation axis' direction affects the outcome!\n  rotate: function(t, line) {\n    // If we're working in 2D\n    if (typeof(line.direction) == 'undefined') { line = Line.create(line.to3D(), Vector.k); }\n    var R = Matrix.Rotation(t, line.direction).elements;\n    var C = line.pointClosestTo(this.anchor).elements;\n    var A = this.anchor.elements, D = this.direction.elements;\n    var C1 = C[0], C2 = C[1], C3 = C[2], A1 = A[0], A2 = A[1], A3 = A[2];\n    var x = A1 - C1, y = A2 - C2, z = A3 - C3;\n    return Line.create([\n      C1 + R[0][0] * x + R[0][1] * y + R[0][2] * z,\n      C2 + R[1][0] * x + R[1][1] * y + R[1][2] * z,\n      C3 + R[2][0] * x + R[2][1] * y + R[2][2] * z\n    ], [\n      R[0][0] * D[0] + R[0][1] * D[1] + R[0][2] * D[2],\n      R[1][0] * D[0] + R[1][1] * D[1] + R[1][2] * D[2],\n      R[2][0] * D[0] + R[2][1] * D[1] + R[2][2] * D[2]\n    ]);\n  },\n\n  // Returns the line's reflection in the given point or line\n  reflectionIn: function(obj) {\n    if (obj.normal) {\n      // obj is a plane\n      var A = this.anchor.elements, D = this.direction.elements;\n      var A1 = A[0], A2 = A[1], A3 = A[2], D1 = D[0], D2 = D[1], D3 = D[2];\n      var newA = this.anchor.reflectionIn(obj).elements;\n      // Add the line's direction vector to its anchor, then mirror that in the plane\n      var AD1 = A1 + D1, AD2 = A2 + D2, AD3 = A3 + D3;\n      var Q = obj.pointClosestTo([AD1, AD2, AD3]).elements;\n      var newD = [Q[0] + (Q[0] - AD1) - newA[0], Q[1] + (Q[1] - AD2) - newA[1], Q[2] + (Q[2] - AD3) - newA[2]];\n      return Line.create(newA, newD);\n    } else if (obj.direction) {\n      // obj is a line - reflection obtained by rotating PI radians about obj\n      return this.rotate(Math.PI, obj);\n    } else {\n      // obj is a point - just reflect the line's anchor in it\n      var P = obj.elements || obj;\n      return Line.create(this.anchor.reflectionIn([P[0], P[1], (P[2] || 0)]), this.direction);\n    }\n  },\n\n  // Set the line's anchor point and direction.\n  setVectors: function(anchor, direction) {\n    // Need to do this so that line's properties are not\n    // references to the arguments passed in\n    anchor = Vector.create(anchor);\n    direction = Vector.create(direction);\n    if (anchor.elements.length == 2) {anchor.elements.push(0); }\n    if (direction.elements.length == 2) { direction.elements.push(0); }\n    if (anchor.elements.length > 3 || direction.elements.length > 3) { return null; }\n    var mod = direction.modulus();\n    if (mod === 0) { return null; }\n    this.anchor = anchor;\n    this.direction = Vector.create([\n      direction.elements[0] / mod,\n      direction.elements[1] / mod,\n      direction.elements[2] / mod\n    ]);\n    return this;\n  }\n};\n\n  \n// Constructor function\nLine.create = function(anchor, direction) {\n  var L = new Line();\n  return L.setVectors(anchor, direction);\n};\n\n// Axes\nLine.X = Line.create(Vector.Zero(3), Vector.i);\nLine.Y = Line.create(Vector.Zero(3), Vector.j);\nLine.Z = Line.create(Vector.Zero(3), Vector.k);\n\n\n\nfunction Plane() {}\nPlane.prototype = {\n\n  // Returns true iff the plane occupies the same space as the argument\n  eql: function(plane) {\n    return (this.contains(plane.anchor) && this.isParallelTo(plane));\n  },\n\n  // Returns a copy of the plane\n  dup: function() {\n    return Plane.create(this.anchor, this.normal);\n  },\n\n  // Returns the result of translating the plane by the given vector\n  translate: function(vector) {\n    var V = vector.elements || vector;\n    return Plane.create([\n      this.anchor.elements[0] + V[0],\n      this.anchor.elements[1] + V[1],\n      this.anchor.elements[2] + (V[2] || 0)\n    ], this.normal);\n  },\n\n  // Returns true iff the plane is parallel to the argument. Will return true\n  // if the planes are equal, or if you give a line and it lies in the plane.\n  isParallelTo: function(obj) {\n    var theta;\n    if (obj.normal) {\n      // obj is a plane\n      theta = this.normal.angleFrom(obj.normal);\n      return (Math.abs(theta) <= Sylvester.precision || Math.abs(Math.PI - theta) <= Sylvester.precision);\n    } else if (obj.direction) {\n      // obj is a line\n      return this.normal.isPerpendicularTo(obj.direction);\n    }\n    return null;\n  },\n  \n  // Returns true iff the receiver is perpendicular to the argument\n  isPerpendicularTo: function(plane) {\n    var theta = this.normal.angleFrom(plane.normal);\n    return (Math.abs(Math.PI/2 - theta) <= Sylvester.precision);\n  },\n\n  // Returns the plane's distance from the given object (point, line or plane)\n  distanceFrom: function(obj) {\n    if (this.intersects(obj) || this.contains(obj)) { return 0; }\n    if (obj.anchor) {\n      // obj is a plane or line\n      var A = this.anchor.elements, B = obj.anchor.elements, N = this.normal.elements;\n      return Math.abs((A[0] - B[0]) * N[0] + (A[1] - B[1]) * N[1] + (A[2] - B[2]) * N[2]);\n    } else {\n      // obj is a point\n      var P = obj.elements || obj;\n      var A = this.anchor.elements, N = this.normal.elements;\n      return Math.abs((A[0] - P[0]) * N[0] + (A[1] - P[1]) * N[1] + (A[2] - (P[2] || 0)) * N[2]);\n    }\n  },\n\n  // Returns true iff the plane contains the given point or line\n  contains: function(obj) {\n    if (obj.normal) { return null; }\n    if (obj.direction) {\n      return (this.contains(obj.anchor) && this.contains(obj.anchor.add(obj.direction)));\n    } else {\n      var P = obj.elements || obj;\n      var A = this.anchor.elements, N = this.normal.elements;\n      var diff = Math.abs(N[0]*(A[0] - P[0]) + N[1]*(A[1] - P[1]) + N[2]*(A[2] - (P[2] || 0)));\n      return (diff <= Sylvester.precision);\n    }\n  },\n\n  // Returns true iff the plane has a unique point/line of intersection with the argument\n  intersects: function(obj) {\n    if (typeof(obj.direction) == 'undefined' && typeof(obj.normal) == 'undefined') { return null; }\n    return !this.isParallelTo(obj);\n  },\n\n  // Returns the unique intersection with the argument, if one exists. The result\n  // will be a vector if a line is supplied, and a line if a plane is supplied.\n  intersectionWith: function(obj) {\n    if (!this.intersects(obj)) { return null; }\n    if (obj.direction) {\n      // obj is a line\n      var A = obj.anchor.elements, D = obj.direction.elements,\n          P = this.anchor.elements, N = this.normal.elements;\n      var multiplier = (N[0]*(P[0]-A[0]) + N[1]*(P[1]-A[1]) + N[2]*(P[2]-A[2])) / (N[0]*D[0] + N[1]*D[1] + N[2]*D[2]);\n      return Vector.create([A[0] + D[0]*multiplier, A[1] + D[1]*multiplier, A[2] + D[2]*multiplier]);\n    } else if (obj.normal) {\n      // obj is a plane\n      var direction = this.normal.cross(obj.normal).toUnitVector();\n      // To find an anchor point, we find one co-ordinate that has a value\n      // of zero somewhere on the intersection, and remember which one we picked\n      var N = this.normal.elements, A = this.anchor.elements,\n          O = obj.normal.elements, B = obj.anchor.elements;\n      var solver = Matrix.Zero(2,2), i = 0;\n      while (solver.isSingular()) {\n        i++;\n        solver = Matrix.create([\n          [ N[i%3], N[(i+1)%3] ],\n          [ O[i%3], O[(i+1)%3]  ]\n        ]);\n      }\n      // Then we solve the simultaneous equations in the remaining dimensions\n      var inverse = solver.inverse().elements;\n      var x = N[0]*A[0] + N[1]*A[1] + N[2]*A[2];\n      var y = O[0]*B[0] + O[1]*B[1] + O[2]*B[2];\n      var intersection = [\n        inverse[0][0] * x + inverse[0][1] * y,\n        inverse[1][0] * x + inverse[1][1] * y\n      ];\n      var anchor = [];\n      for (var j = 1; j <= 3; j++) {\n        // This formula picks the right element from intersection by\n        // cycling depending on which element we set to zero above\n        anchor.push((i == j) ? 0 : intersection[(j + (5 - i)%3)%3]);\n      }\n      return Line.create(anchor, direction);\n    }\n  },\n\n  // Returns the point in the plane closest to the given point\n  pointClosestTo: function(point) {\n    var P = point.elements || point;\n    var A = this.anchor.elements, N = this.normal.elements;\n    var dot = (A[0] - P[0]) * N[0] + (A[1] - P[1]) * N[1] + (A[2] - (P[2] || 0)) * N[2];\n    return Vector.create([P[0] + N[0] * dot, P[1] + N[1] * dot, (P[2] || 0) + N[2] * dot]);\n  },\n\n  // Returns a copy of the plane, rotated by t radians about the given line\n  // See notes on Line#rotate.\n  rotate: function(t, line) {\n    var R = Matrix.Rotation(t, line.direction).elements;\n    var C = line.pointClosestTo(this.anchor).elements;\n    var A = this.anchor.elements, N = this.normal.elements;\n    var C1 = C[0], C2 = C[1], C3 = C[2], A1 = A[0], A2 = A[1], A3 = A[2];\n    var x = A1 - C1, y = A2 - C2, z = A3 - C3;\n    return Plane.create([\n      C1 + R[0][0] * x + R[0][1] * y + R[0][2] * z,\n      C2 + R[1][0] * x + R[1][1] * y + R[1][2] * z,\n      C3 + R[2][0] * x + R[2][1] * y + R[2][2] * z\n    ], [\n      R[0][0] * N[0] + R[0][1] * N[1] + R[0][2] * N[2],\n      R[1][0] * N[0] + R[1][1] * N[1] + R[1][2] * N[2],\n      R[2][0] * N[0] + R[2][1] * N[1] + R[2][2] * N[2]\n    ]);\n  },\n\n  // Returns the reflection of the plane in the given point, line or plane.\n  reflectionIn: function(obj) {\n    if (obj.normal) {\n      // obj is a plane\n      var A = this.anchor.elements, N = this.normal.elements;\n      var A1 = A[0], A2 = A[1], A3 = A[2], N1 = N[0], N2 = N[1], N3 = N[2];\n      var newA = this.anchor.reflectionIn(obj).elements;\n      // Add the plane's normal to its anchor, then mirror that in the other plane\n      var AN1 = A1 + N1, AN2 = A2 + N2, AN3 = A3 + N3;\n      var Q = obj.pointClosestTo([AN1, AN2, AN3]).elements;\n      var newN = [Q[0] + (Q[0] - AN1) - newA[0], Q[1] + (Q[1] - AN2) - newA[1], Q[2] + (Q[2] - AN3) - newA[2]];\n      return Plane.create(newA, newN);\n    } else if (obj.direction) {\n      // obj is a line\n      return this.rotate(Math.PI, obj);\n    } else {\n      // obj is a point\n      var P = obj.elements || obj;\n      return Plane.create(this.anchor.reflectionIn([P[0], P[1], (P[2] || 0)]), this.normal);\n    }\n  },\n\n  // Sets the anchor point and normal to the plane. If three arguments are specified,\n  // the normal is calculated by assuming the three points should lie in the same plane.\n  // If only two are sepcified, the second is taken to be the normal. Normal vector is\n  // normalised before storage.\n  setVectors: function(anchor, v1, v2) {\n    anchor = Vector.create(anchor);\n    anchor = anchor.to3D(); if (anchor === null) { return null; }\n    v1 = Vector.create(v1);\n    v1 = v1.to3D(); if (v1 === null) { return null; }\n    if (typeof(v2) == 'undefined') {\n      v2 = null;\n    } else {\n      v2 = Vector.create(v2);\n      v2 = v2.to3D(); if (v2 === null) { return null; }\n    }\n    var A1 = anchor.elements[0], A2 = anchor.elements[1], A3 = anchor.elements[2];\n    var v11 = v1.elements[0], v12 = v1.elements[1], v13 = v1.elements[2];\n    var normal, mod;\n    if (v2 !== null) {\n      var v21 = v2.elements[0], v22 = v2.elements[1], v23 = v2.elements[2];\n      normal = Vector.create([\n        (v12 - A2) * (v23 - A3) - (v13 - A3) * (v22 - A2),\n        (v13 - A3) * (v21 - A1) - (v11 - A1) * (v23 - A3),\n        (v11 - A1) * (v22 - A2) - (v12 - A2) * (v21 - A1)\n      ]);\n      mod = normal.modulus();\n      if (mod === 0) { return null; }\n      normal = Vector.create([normal.elements[0] / mod, normal.elements[1] / mod, normal.elements[2] / mod]);\n    } else {\n      mod = Math.sqrt(v11*v11 + v12*v12 + v13*v13);\n      if (mod === 0) { return null; }\n      normal = Vector.create([v1.elements[0] / mod, v1.elements[1] / mod, v1.elements[2] / mod]);\n    }\n    this.anchor = anchor;\n    this.normal = normal;\n    return this;\n  }\n};\n\n// Constructor function\nPlane.create = function(anchor, v1, v2) {\n  var P = new Plane();\n  return P.setVectors(anchor, v1, v2);\n};\n\n// X-Y-Z planes\nPlane.XY = Plane.create(Vector.Zero(3), Vector.k);\nPlane.YZ = Plane.create(Vector.Zero(3), Vector.i);\nPlane.ZX = Plane.create(Vector.Zero(3), Vector.j);\nPlane.YX = Plane.XY; Plane.ZY = Plane.YZ; Plane.XZ = Plane.ZX;\n\n// Utility functions\nvar $V = Vector.create;\nvar $M = Matrix.create;\nvar $L = Line.create;\nvar $P = Plane.create;\n"
  },
  {
    "path": "google/datalab/notebook/static/job.css",
    "content": "/*\n * Copyright 2015 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License. You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under the License\n * is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n * or implied. See the License for the specific language governing permissions and limitations under\n * the License.\n */\n\np.jobfail {\n  color: red;\n}\np.jobsucceed {\n  color: green;\n}\np.jobfooter {\n  font-size: smaller;\n}\n"
  },
  {
    "path": "google/datalab/notebook/static/job.ts",
    "content": "/*\n * Copyright 2015 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License. You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under the License\n * is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n * or implied. See the License for the specific language governing permissions and limitations under\n * the License.\n */\n\n/// <reference path=\"../../../../externs/ts/require/require.d.ts\" />\n\ndeclare var datalab: any;\ndeclare var IPython: any;\n\nmodule Job {\n\n  function refresh(dom: any, job_name: any, job_type: any, interval: any,\n      html_on_running: string, html_on_success: string): any {\n    var code = '%_get_job_status ' + job_name + ' ' + job_type;\n    datalab.session.execute(code, function (error: any, newData: any) {\n      error = error || newData.error;\n      if (error) {\n        dom.innerHTML = '<p class=\"jobfail\">Job failed with error: ' + error\n            + '</p>';\n        return;\n      }\n      if (!newData.exists) {\n        dom.innerHTML = '<p>The job does not exist.</p>';\n      } else if (newData.done) {\n        dom.innerHTML = '<p class=\"jobsucceed\">Job completed successfully.</p><br>' +\n                        html_on_success;\n      } else {\n        dom.innerHTML = 'Running... <p class=\"jobfooter\">Updated at '\n          + new Date().toLocaleTimeString() + '</p>' + html_on_running;\n        setTimeout(function() {\n              refresh(dom, job_name, job_type, interval, html_on_running, html_on_success);\n            }, interval * 1000);\n      }\n    });\n  }\n\n  // Render the job view. This is called from Python generated code.\n  export function render(dom: any, events: any, job_name: string, job_type: string,\n      interval: any, html_on_running: string, html_on_success: string) {\n    if (IPython.notebook.kernel.is_connected()) {\n      refresh(dom, job_name, job_type, interval, html_on_running, html_on_success);\n      return;\n    }\n    // If the kernel is not connected, wait for the event.\n    events.on('kernel_ready.Kernel', function(e: any) {\n      refresh(dom, job_name, job_type, interval, html_on_running, html_on_success);\n    });\n  }\n}\n\n\nexport = Job;\n\n"
  },
  {
    "path": "google/datalab/notebook/static/parcoords.ts",
    "content": "/*\n * Copyright 2016 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License. You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under the License\n * is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n * or implied. See the License for the specific language governing permissions and limitations under\n * the License.\n */\n\n/// <reference path=\"../../../../externs/ts/require/require.d.ts\" />\n\nmodule ParCoords {\n\n  function getCentroids(data: any, graph: any): any {\n      var margins = graph.margin();\n      var graphCentPts: any[] = [];\n\n      data.forEach(function(d: any){\n        var initCenPts = graph.compute_centroids(d).filter(function(d: any, i: number) {return i%2==0;});\n        var cenPts = initCenPts.map(function(d: any){\n        return [d[0] + margins[\"left\"], d[1]+ margins[\"top\"]]; \n      });\n      graphCentPts.push(cenPts);\n    });\n\n    return graphCentPts;\n  }\n\n  function getActiveData(graph: any): any{\n    if (graph.brushed()!=false) return graph.brushed();\n      return graph.data();\n  }\n\n  function findAxes(testPt: any, cenPts: any): number {\n    var x: number = testPt[0];\n    var y: number = testPt[1];\n    if (cenPts[0][0] > x) return 0;\n    if (cenPts[cenPts.length-1][0] < x) return 0;\n    for (var i=0; i<cenPts.length; i++) {\n        if (cenPts[i][0] > x) return i;\n    }\n    return 0;\n  }\n\n  function isOnLine(startPt: any, endPt: any, testPt: any, tol: number){\n    var x0 = testPt[0];\n    var\ty0 = testPt[1];\n    var x1 = startPt[0];\n    var\ty1 = startPt[1];\n    var x2 = endPt[0];\n    var y2 = endPt[1];\n    var Dx = x2 - x1;\n    var Dy = y2 - y1;\n    var delta = Math.abs(Dy*x0 - Dx*y0 - x1*y2+x2*y1)/Math.sqrt(Math.pow(Dx, 2) + Math.pow(Dy, 2)); \n    if (delta <= tol) return true;\n    return false;\n  }\n\n  function getClickedLines(mouseClick: any, graph: any): any {\n    var clicked: any[] = [];\n    var clickedCenPts: any[] = [];\n    // find which data is activated right now\n    var activeData: any = getActiveData(graph);\n\n    // find centriod points\n    var graphCentPts: any = getCentroids(activeData, graph);\n\n    if (graphCentPts.length==0) return false;\n    // find between which axes the point is\n    var axeNum: number = findAxes(mouseClick, graphCentPts[0]);\n    if (!axeNum) return false;\n    graphCentPts.forEach(function(d: any, i: number){\n      if (isOnLine(d[axeNum-1], d[axeNum], mouseClick, 2)) {\n        clicked.push(activeData[i]);\n        clickedCenPts.push(graphCentPts[i]); // for tooltip\n      }\n    });\n    return [clicked, clickedCenPts]\n  }\n\n  function highlightLineOnClick(mouseClick: any, graph: any) {\n    var clicked: any[] = [];\n    var clickedCenPts: any[] = [];\n    var clickedData: any = getClickedLines(mouseClick, graph);\n    if (clickedData && clickedData[0].length!=0){\n      clicked = clickedData[0];\n      clickedCenPts = clickedData[1];\n      // highlight clicked line\n      graph.highlight(clicked);\n    }\n  };\n\n  export function plot(d3: any, color_domain: number[], maximize: boolean, data: any,\n           graph_html_id: string, grid_html_id: string) {\n    var range = [\"green\", \"gray\"];\n    if (maximize) {\n      range = [\"gray\", \"green\"];\n    }\n    var blue_to_brown = d3.scale.linear().domain(color_domain)\n                                         .range(range)\n                                         .interpolate(d3.interpolateLab);\n    var color = function(d: any) { return blue_to_brown(d['Objective']); };\n    var columns_hide: string[] = [\"Trial\", \"Training Step\"];\n    for (var attr in data) {\n      if (attr.lastIndexOf(\"(log)\") > 0) {\n        columns_hide.push(attr.slice(0, -5));\n      }\n    }\n    var data_display: any[] = [];\n    for (var i: number =0; i<data.Trial.length; i++) {\n      var instance: any = {};\n      for (var attr in data) {\n        instance[attr] = data[attr][i];\n      }\n      data_display.push(instance);\n    }\n    var parcoords = d3.parcoords()(\"#\" + graph_html_id).color(color).alpha(0.4);\n    parcoords.data(data_display).hideAxis(columns_hide)\n                                .composite(\"darken\")\n                                .render()\n                                .brushMode(\"1D-axes\");\n\n    var grid = d3.divgrid();\n    d3.select(\"#\" + grid_html_id).datum(data_display)\n        .call(grid)\n        .selectAll(\".row\")\n        .on({\n          \"mouseover\": function(d: any) { parcoords.highlight([d]) },\n          \"mouseout\": parcoords.unhighlight\n        });     \n    // update data table on brush event\n    parcoords.on(\"brush\", function(d: any) {\n        d3.select(\"#\" + grid_html_id).datum(d)\n        .call(grid)\n        .selectAll(\".row\")\n        .on({\n            \"mouseover\": function(d: any) { parcoords.highlight([d]) },\n            \"mouseout\": parcoords.unhighlight\n        });\n    });\n    //add hover event\n    d3.select(\"#\" + graph_html_id + \" svg\").on(\"mousemove\", function() {\n          var mousePosition: any = d3.mouse(this);\t\t\t    \n          highlightLineOnClick(mousePosition, parcoords);\n        })\n        .on(\"mouseout\", function(){\n          parcoords.unhighlight();\n\t});\n  }\n}\n\n\nexport = ParCoords;\n\n"
  },
  {
    "path": "google/datalab/notebook/static/style.ts",
    "content": "/*\n * Copyright 2015 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License. You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under the License\n * is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n * or implied. See the License for the specific language governing permissions and limitations under\n * the License.\n */\n\n// RequireJS plugin to load stylesheets.\n\n/// <reference path=\"../../../../externs/ts/require/require.d.ts\" />\n\nmodule Style {\n\n  'use strict';\n\n  // An object containing the set of loaded stylesheets, so as to avoid reloading.\n  var loadedStyleSheets: any = {};\n\n  // An object containing stylesheets to load, once the DOM is ready.\n  var pendingStyleSheets: Array<string> = null;\n\n  function addStyleSheet(url: string): void {\n    loadedStyleSheets[url] = true;\n\n    var stylesheet = document.createElement('link');\n    stylesheet.type = 'text/css';\n    stylesheet.rel = 'stylesheet';\n    stylesheet.href = url;\n\n    document.getElementsByTagName('head')[0].appendChild(stylesheet);\n  }\n\n  function domReadyCallback(): void {\n    if (pendingStyleSheets) {\n      // Clear out pendingStyleSheets, so any future adds are immediately processed.\n      var styleSheets: Array<string> = pendingStyleSheets;\n      pendingStyleSheets = null;\n\n      styleSheets.forEach(addStyleSheet);\n    }\n  }\n\n  export function load(url: string, req: any, loadCallback: any, config: any): void {\n    if (config.isBuild) {\n      loadCallback(null);\n    }\n    else {\n      // Go ahead and immediately/optimistically resolve this, since the resolved value of a\n      // stylesheet is never interesting.\n      setTimeout(loadCallback, 0);\n\n      // Only load a specified stylesheet once for the lifetime of this page.\n      if (loadedStyleSheets[url]) {\n        return;\n      }\n      loadedStyleSheets[url] = true;\n\n      if (document.readyState == 'loading') {\n        if (!pendingStyleSheets) {\n          pendingStyleSheets = [];\n          document.addEventListener('DOMContentLoaded', domReadyCallback, false);\n        }\n\n        pendingStyleSheets.push(url);\n      }\n      else {\n        addStyleSheet(url);\n      }\n    }\n  }\n}\n\nexport = Style;\n"
  },
  {
    "path": "google/datalab/notebook/static/visualization.ts",
    "content": "/*\n * Copyright 2015 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License. You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under the License\n * is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n * or implied. See the License for the specific language governing permissions and limitations under\n * the License.\n */\n\n// require.js plugin to allow Google Chart API to be loaded.\n\n/// <reference path=\"../../../../externs/ts/require/require.d.ts\" />\n\ndeclare var google: any;\ndeclare var window: any;\n\nmodule Visualization {\n\n  'use strict';\n\n  // Queued packages to load until the google api loader itself has not been loaded.\n  var queue: any = {\n    packages: [],\n    callbacks: []\n  };\n\n  function loadGoogleApiLoader(callback: any): void {\n    // Visualization packages are loaded using the Google loader.\n    // The loader URL itself must contain a callback (by name) that it invokes when its loaded.\n    var callbackName: string = '__googleApiLoaderCallback';\n    window[callbackName] = callback;\n\n    var script = document.createElement('script');\n    script.type = 'text/javascript';\n    script.async = true;\n    script.src = 'https://www.google.com/jsapi?callback=' + callbackName;\n    document.getElementsByTagName('head')[0].appendChild(script);\n  }\n\n  function invokeVisualizationCallback(cb: any) {\n    cb(google.visualization);\n  }\n\n  function loadVisualizationPackages(names: any, callbacks: any): void {\n    if (names.length) {\n      var visualizationOptions = {\n        packages: names,\n        callback: function() { callbacks.forEach(invokeVisualizationCallback); }\n      };\n\n      google.load('visualization', '1', visualizationOptions);\n    }\n  }\n\n  loadGoogleApiLoader(function() {\n    if (queue) {\n      loadVisualizationPackages(queue.packages, queue.callbacks);\n      queue = null;\n    }\n  });\n\n  export function load(name: any, req: any, callback: any, config: any) {\n    if (config.isBuild) {\n      callback(null);\n    }\n    else {\n      if (queue) {\n        // Queue the package and associated callback to load, once the loader has been loaded.\n        queue.packages.push(name);\n        queue.callbacks.push(callback);\n      }\n      else {\n        // Loader has already been loaded, so go ahead and load the specified package.\n        loadVisualizationPackages([ name ], [ callback ]);\n      }\n    }\n  }\n}\n\nexport = Visualization;\n"
  },
  {
    "path": "google/datalab/stackdriver/__init__.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License.  You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied.  See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Google Cloud Platform library - Stackdriver Functionality.\"\"\"\n"
  },
  {
    "path": "google/datalab/stackdriver/commands/__init__.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\nfrom __future__ import absolute_import\n\nfrom . import _monitoring\n\n__all__ = ['_monitoring']\n"
  },
  {
    "path": "google/datalab/stackdriver/commands/_monitoring.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"IPython Functionality for the Google Monitoring API.\"\"\"\nfrom __future__ import absolute_import\n\ntry:\n  import IPython.core.display\n  import IPython.core.magic\nexcept ImportError:\n  raise Exception('This module can only be loaded in ipython.')\n\nimport google.datalab\nimport google.datalab.stackdriver.monitoring as gcm\nimport google.datalab.utils.commands\n\n\n@IPython.core.magic.register_line_cell_magic\ndef sd(line, cell=None):\n  \"\"\"Implements the stackdriver cell magic for ipython notebooks.\n\n  Args:\n    line: the contents of the storage line.\n  Returns:\n    The results of executing the cell.\n  \"\"\"\n  parser = google.datalab.utils.commands.CommandParser(prog='%sd', description=(\n      'Execute various Stackdriver related operations. Use \"%sd '\n      '<stackdriver_product> -h\" for help on a specific Stackdriver product.'))\n\n  # %%sd monitoring\n  _create_monitoring_subparser(parser)\n  return google.datalab.utils.commands.handle_magic_line(line, cell, parser)\n\n\ndef _create_monitoring_subparser(parser):\n  monitoring_parser = parser.subcommand(\n      'monitoring', 'Execute Stackdriver monitoring related operations. Use '\n      '\"sd monitoring <command> -h\" for help on a specific command')\n\n  metric_parser = monitoring_parser.subcommand(\n      'metrics', 'Operations on Stackdriver Monitoring metrics')\n  metric_list_parser = metric_parser.subcommand('list', 'List metrics')\n  metric_list_parser.add_argument(\n      '-p', '--project',\n      help='The project whose metrics should be listed.')\n  metric_list_parser.add_argument(\n      '-t', '--type',\n      help='The type of metric(s) to list; can include wildchars.')\n  metric_list_parser.set_defaults(func=_monitoring_metrics_list)\n\n  resource_parser = monitoring_parser.subcommand(\n      'resource_types', 'Operations on Stackdriver Monitoring resource types')\n  resource_list_parser = resource_parser.subcommand('list', 'List resource types')\n  resource_list_parser.add_argument(\n      '-p', '--project',\n      help='The project whose resource types should be listed.')\n  resource_list_parser.add_argument(\n      '-t', '--type',\n      help='The resource type(s) to list; can include wildchars.')\n  resource_list_parser.set_defaults(func=_monitoring_resource_types_list)\n\n  group_parser = monitoring_parser.subcommand(\n      'groups', 'Operations on Stackdriver groups')\n  group_list_parser = group_parser.subcommand('list', 'List groups')\n  group_list_parser.add_argument(\n      '-p', '--project',\n      help='The project whose groups should be listed.')\n  group_list_parser.add_argument(\n      '-n', '--name',\n      help='The name of the group(s) to list; can include wildchars.')\n  group_list_parser.set_defaults(func=_monitoring_groups_list)\n\n\ndef _monitoring_metrics_list(args, _):\n  \"\"\"Lists the metric descriptors in the project.\"\"\"\n  project_id = args['project']\n  pattern = args['type'] or '*'\n  descriptors = gcm.MetricDescriptors(context=_make_context(project_id))\n  dataframe = descriptors.as_dataframe(pattern=pattern)\n  return _render_dataframe(dataframe)\n\n\ndef _monitoring_resource_types_list(args, _):\n  \"\"\"Lists the resource descriptors in the project.\"\"\"\n  project_id = args['project']\n  pattern = args['type'] or '*'\n  descriptors = gcm.ResourceDescriptors(context=_make_context(project_id))\n  dataframe = descriptors.as_dataframe(pattern=pattern)\n  return _render_dataframe(dataframe)\n\n\ndef _monitoring_groups_list(args, _):\n  \"\"\"Lists the groups in the project.\"\"\"\n  project_id = args['project']\n  pattern = args['name'] or '*'\n  groups = gcm.Groups(context=_make_context(project_id))\n  dataframe = groups.as_dataframe(pattern=pattern)\n  return _render_dataframe(dataframe)\n\n\ndef _render_dataframe(dataframe):\n  \"\"\"Helper to render a dataframe as an HTML table.\"\"\"\n  data = dataframe.to_dict(orient='records')\n  fields = dataframe.columns.tolist()\n  return IPython.core.display.HTML(\n      google.datalab.utils.commands.HtmlBuilder.render_table(data, fields))\n\n\ndef _make_context(project_id):\n  default_context = google.datalab.Context.default()\n  if project_id:\n    return google.datalab.Context(project_id, default_context.credentials)\n  else:\n    return default_context\n"
  },
  {
    "path": "google/datalab/stackdriver/monitoring/__init__.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License.  You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied.  See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Google Cloud Platform library - Monitoring Functionality.\"\"\"\n\nfrom __future__ import absolute_import\n\nfrom google.cloud.monitoring import enums\nfrom ._group import Groups\nfrom ._metric import MetricDescriptors\nfrom ._query import Query\nfrom ._query_metadata import QueryMetadata\nfrom ._resource import ResourceDescriptors\n\nAligner = enums.Aggregation.Aligner\nReducer = enums.Aggregation.Reducer\n\n__all__ = ['Aligner', 'Reducer', 'Groups', 'MetricDescriptors', 'Query', 'QueryMetadata',\n           'ResourceDescriptors']\n"
  },
  {
    "path": "google/datalab/stackdriver/monitoring/_group.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License.  You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied.  See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Groups for the Google Monitoring API.\"\"\"\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom builtins import object\n\nimport collections\nimport fnmatch\n\nimport pandas\n\nimport google.datalab\n\nfrom . import _utils\n\n\nclass Groups(object):\n  \"\"\"Represents a list of Stackdriver groups for a project.\"\"\"\n\n  _DISPLAY_HEADERS = ('Group ID', 'Group name', 'Parent ID', 'Parent name',\n                      'Is cluster', 'Filter')\n\n  def __init__(self, context=None):\n    \"\"\"Initializes the Groups for a Stackdriver project.\n\n    Args:\n      context: An optional Context object to use instead of the global default.\n    \"\"\"\n    self._context = context or google.datalab.Context.default()\n    self._client = _utils.make_client(self._context)\n    self._group_dict = None\n\n  def list(self, pattern='*'):\n    \"\"\"Returns a list of groups that match the filters.\n\n    Args:\n      pattern: An optional pattern to filter the groups based on their display\n          name. This can include Unix shell-style wildcards. E.g.\n          ``\"Production*\"``.\n\n    Returns:\n      A list of Group objects that match the filters.\n    \"\"\"\n    if self._group_dict is None:\n      self._group_dict = collections.OrderedDict(\n          (group.name, group) for group in self._client.list_groups())\n\n    return [group for group in self._group_dict.values()\n            if fnmatch.fnmatch(group.display_name, pattern)]\n\n  def as_dataframe(self, pattern='*', max_rows=None):\n    \"\"\"Creates a pandas dataframe from the groups that match the filters.\n\n    Args:\n      pattern: An optional pattern to further filter the groups. This can\n          include Unix shell-style wildcards. E.g. ``\"Production *\"``,\n          ``\"*-backend\"``.\n      max_rows: The maximum number of groups to return. If None, return all.\n\n    Returns:\n      A pandas dataframe containing matching groups.\n    \"\"\"\n    data = []\n    for i, group in enumerate(self.list(pattern)):\n      if max_rows is not None and i >= max_rows:\n        break\n      parent = self._group_dict.get(group.parent_name)\n      parent_display_name = '' if parent is None else parent.display_name\n      data.append([\n          group.name, group.display_name, group.parent_name,\n          parent_display_name, group.is_cluster, group.filter])\n\n    return pandas.DataFrame(data, columns=self._DISPLAY_HEADERS)\n"
  },
  {
    "path": "google/datalab/stackdriver/monitoring/_metric.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License.  You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied.  See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Provides the MetricDescriptors in the monitoring API.\"\"\"\n\nfrom __future__ import absolute_import\nfrom builtins import object\n\nfrom google.cloud.monitoring_v3 import enums\n\nimport fnmatch\nimport pandas\n\nfrom . import _utils\n\n\nclass MetricDescriptors(object):\n  \"\"\"MetricDescriptors object for retrieving the metric descriptors.\"\"\"\n\n  _DISPLAY_HEADERS = ('Metric type', 'Display name', 'Kind', 'Value', 'Unit',\n                      'Labels')\n\n  def __init__(self, filter_string=None, type_prefix=None, context=None):\n    \"\"\"Initializes the MetricDescriptors based on the specified filters.\n\n    Args:\n      filter_string: An optional filter expression describing the resource\n          descriptors to be returned.\n      type_prefix: An optional prefix constraining the selected metric types.\n          This adds ``metric.type = starts_with(\"<prefix>\")`` to the filter.\n      context: An optional Context object to use instead of the global default.\n    \"\"\"\n    self._client = _utils.make_client(context)\n    self._filter_string = filter_string\n    self._type_prefix = type_prefix\n    self._descriptors = None\n\n  def list(self, pattern='*'):\n    \"\"\"Returns a list of metric descriptors that match the filters.\n\n    Args:\n      pattern: An optional pattern to further filter the descriptors. This can\n          include Unix shell-style wildcards. E.g. ``\"compute*\"``,\n          ``\"*cpu/load_??m\"``.\n\n    Returns:\n      A list of MetricDescriptor objects that match the filters.\n    \"\"\"\n    if self._descriptors is None:\n      self._descriptors = self._client.list_metric_descriptors(\n          filter_string=self._filter_string, type_prefix=self._type_prefix)\n    return [metric for metric in self._descriptors\n            if fnmatch.fnmatch(metric.type, pattern)]\n\n  def as_dataframe(self, pattern='*', max_rows=None):\n    \"\"\"Creates a pandas dataframe from the descriptors that match the filters.\n\n    Args:\n      pattern: An optional pattern to further filter the descriptors. This can\n          include Unix shell-style wildcards. E.g. ``\"compute*\"``,\n          ``\"*/cpu/load_??m\"``.\n      max_rows: The maximum number of descriptors to return. If None, return\n          all.\n\n    Returns:\n      A pandas dataframe containing matching metric descriptors.\n    \"\"\"\n    data = []\n    for i, metric in enumerate(self.list(pattern)):\n      if max_rows is not None and i >= max_rows:\n        break\n      labels = ', '. join([l.key for l in metric.labels])\n      data.append([\n          metric.type, metric.display_name,\n          enums.MetricDescriptor.MetricKind(metric.metric_kind).name,\n          enums.MetricDescriptor.ValueType(metric.value_type).name,\n          metric.unit, labels])\n\n    return pandas.DataFrame(data, columns=self._DISPLAY_HEADERS)\n"
  },
  {
    "path": "google/datalab/stackdriver/monitoring/_query.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License.  You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied.  See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Provides access to metric data as pandas dataframes.\"\"\"\n\nfrom __future__ import absolute_import\n\nimport google.cloud.monitoring_v3.query\n\nfrom . import _query_metadata\nfrom . import _utils\n\n\nclass Query(google.cloud.monitoring_v3.query.Query):\n  \"\"\"Query object for retrieving metric data.\"\"\"\n\n  def __init__(self,\n               metric_type=google.cloud.monitoring_v3.query.Query.DEFAULT_METRIC_TYPE,\n               end_time=None, days=0, hours=0, minutes=0, context=None):\n    \"\"\"Initializes the core query parameters.\n\n    The start time (exclusive) is determined by combining the\n    values of ``days``, ``hours``, and ``minutes``, and subtracting\n    the resulting duration from the end time.\n\n    It is also allowed to omit the end time and duration here,\n    in which case :meth:`~google.cloud.monitoring_v3.query.Query.select_interval`\n    must be called before the query is executed.\n\n    Args:\n      metric_type: The metric type name. The default value is\n          :data:`Query.DEFAULT_METRIC_TYPE\n          <google.cloud.monitoring_v3.query.Query.DEFAULT_METRIC_TYPE>`, but\n          please note that this default value is provided only for\n          demonstration purposes and is subject to change.\n      end_time: The end time (inclusive) of the time interval for which\n          results should be returned, as a datetime object. The default\n          is the start of the current minute.\n      days: The number of days in the time interval.\n      hours: The number of hours in the time interval.\n      minutes: The number of minutes in the time interval.\n      context: An optional Context object to use instead of the global default.\n\n    Raises:\n        ValueError: ``end_time`` was specified but ``days``, ``hours``, and\n            ``minutes`` are all zero. If you really want to specify a point in\n            time, use\n            :meth:`~google.cloud.monitoring_v3.query.Query.select_interval`.\n    \"\"\"\n    client = _utils.make_client(context)\n    super(Query, self).__init__(client.metrics_client,\n                                project=client.project,\n                                metric_type=metric_type,\n                                end_time=end_time,\n                                days=days, hours=hours, minutes=minutes)\n\n  def metadata(self):\n    \"\"\"Retrieves the metadata for the query.\"\"\"\n    return _query_metadata.QueryMetadata(self)\n"
  },
  {
    "path": "google/datalab/stackdriver/monitoring/_query_metadata.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License.  You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied.  See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"QueryMetadata object that shows the metadata in a query's results.\"\"\"\n\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom builtins import object\n\nfrom google.cloud.monitoring_v3 import _dataframe\nfrom google.protobuf.json_format import MessageToDict\nimport pandas\n\n\nclass QueryMetadata(object):\n  \"\"\"QueryMetadata object contains the metadata of a timeseries query.\"\"\"\n\n  def __init__(self, query):\n    \"\"\"Initializes the QueryMetadata given the query object.\n\n    Args:\n      query: A Query object.\n    \"\"\"\n    self._timeseries_list = list(query.iter(headers_only=True))\n\n    # Note: If self._timeseries_list has even one entry, the metric type\n    # can be extracted from there as well.\n    self._metric_type = query.metric_type\n\n  def __iter__(self):\n    for timeseries in self._timeseries_list:\n      yield timeseries\n\n  @property\n  def metric_type(self):\n    \"\"\"Returns the metric type in the underlying query.\"\"\"\n    return self._metric_type\n\n  @property\n  def resource_types(self):\n    \"\"\"Returns a set containing resource types in the query result.\"\"\"\n    return set([ts.resource.type for ts in self._timeseries_list])\n\n  def as_dataframe(self, max_rows=None):\n      \"\"\"Creates a pandas dataframe from the query metadata.\n\n      Args:\n        max_rows: The maximum number of timeseries metadata to return. If None,\n            return all.\n\n      Returns:\n        A pandas dataframe containing the resource type, resource labels and\n        metric labels. Each row in this dataframe corresponds to the metadata\n        from one time series.\n      \"\"\"\n      max_rows = len(self._timeseries_list) if max_rows is None else max_rows\n      headers = [{\n          'resource': MessageToDict(ts.resource),\n          'metric': MessageToDict(ts.metric)\n      } for ts in self._timeseries_list[:max_rows]]\n\n      if not headers:\n        return pandas.DataFrame()\n\n      dataframe = pandas.io.json.json_normalize(headers)\n\n      # Add a 2 level column header.\n      dataframe.columns = pandas.MultiIndex.from_tuples(\n          [(col, '') if col == 'resource.type' else col.rsplit('.', 1)\n           for col in dataframe.columns])\n\n      # Re-order the columns.\n      resource_keys = _dataframe._sorted_resource_labels(\n          dataframe['resource.labels'].columns)\n      sorted_columns = [('resource.type', '')]\n      sorted_columns += [('resource.labels', key) for key in resource_keys]\n      sorted_columns += sorted(col for col in dataframe.columns\n                               if col[0] == 'metric.labels')\n      dataframe = dataframe[sorted_columns]\n\n      # Sort the data, and clean up index values, and NaNs.\n      dataframe = dataframe.sort_values(sorted_columns)\n      dataframe = dataframe.reset_index(drop=True).fillna('')\n      return dataframe\n"
  },
  {
    "path": "google/datalab/stackdriver/monitoring/_resource.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License.  You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied.  See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Provides the ResourceDescriptors in the monitoring API.\"\"\"\n\nfrom __future__ import absolute_import\nfrom builtins import object\n\nimport fnmatch\nimport pandas\n\nfrom . import _utils\n\n\nclass ResourceDescriptors(object):\n  \"\"\"ResourceDescriptors object for retrieving the resource descriptors.\"\"\"\n\n  _DISPLAY_HEADERS = ('Resource type', 'Display name', 'Labels')\n\n  def __init__(self, filter_string=None, context=None):\n    \"\"\"Initializes the ResourceDescriptors based on the specified filters.\n\n    Args:\n      filter_string: An optional filter expression describing the resource\n          descriptors to be returned.\n      context: An optional Context object to use instead of the global default.\n    \"\"\"\n    self._client = _utils.make_client(context)\n    self._filter_string = filter_string\n    self._descriptors = None\n\n  def list(self, pattern='*'):\n    \"\"\"Returns a list of resource descriptors that match the filters.\n\n    Args:\n      pattern: An optional pattern to further filter the descriptors. This can\n          include Unix shell-style wildcards. E.g. ``\"aws*\"``, ``\"*cluster*\"``.\n\n    Returns:\n      A list of ResourceDescriptor objects that match the filters.\n    \"\"\"\n    if self._descriptors is None:\n      self._descriptors = self._client.list_resource_descriptors(\n          filter_string=self._filter_string)\n    return [resource for resource in self._descriptors\n            if fnmatch.fnmatch(resource.type, pattern)]\n\n  def as_dataframe(self, pattern='*', max_rows=None):\n    \"\"\"Creates a pandas dataframe from the descriptors that match the filters.\n\n    Args:\n      pattern: An optional pattern to further filter the descriptors. This can\n          include Unix shell-style wildcards. E.g. ``\"aws*\"``, ``\"*cluster*\"``.\n      max_rows: The maximum number of descriptors to return. If None, return\n          all.\n\n    Returns:\n      A pandas dataframe containing matching resource descriptors.\n    \"\"\"\n    data = []\n    for i, resource in enumerate(self.list(pattern)):\n      if max_rows is not None and i >= max_rows:\n        break\n      labels = ', '. join([l.key for l in resource.labels])\n      data.append([resource.type, resource.display_name, labels])\n\n    return pandas.DataFrame(data, columns=self._DISPLAY_HEADERS)\n"
  },
  {
    "path": "google/datalab/stackdriver/monitoring/_utils.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License.  You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied.  See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Provides utility methods for the Monitoring API.\"\"\"\n\nfrom __future__ import absolute_import\n\nfrom google.api_core.gapic_v1.client_info import ClientInfo\nfrom google.cloud.monitoring_v3 import MetricServiceClient\nfrom google.cloud.monitoring_v3 import GroupServiceClient\n\nimport google.datalab\n\n\n# _MonitoringClient holds instances of individual google.cloud.monitoring\n# clients and translates each call from the old signature, since the prior\n# client has been updated and has split into multiple client classes.\nclass _MonitoringClient(object):\n  def __init__(self, context):\n    self.project = context.project_id\n    client_info = ClientInfo(user_agent='pydatalab/v0')\n    self.metrics_client = MetricServiceClient(\n      credentials=context.credentials,\n      client_info=client_info\n    )\n    self.group_client = GroupServiceClient(\n      credentials=context.credentials,\n      client_info=client_info\n    )\n\n  def list_metric_descriptors(self, filter_string=None, type_prefix=None):\n    filters = []\n    if filter_string is not None:\n      filters.append(filter_string)\n\n    if type_prefix is not None:\n      filters.append('metric.type = starts_with(\"{prefix}\")'.format(\n          prefix=type_prefix))\n\n    metric_filter = ' AND '.join(filters)\n    metrics = self.metrics_client.list_metric_descriptors(\n        self.project, filter_=metric_filter)\n    return metrics\n\n  def list_resource_descriptors(self, filter_string=None):\n    resources = self.metrics_client.list_monitored_resource_descriptors(\n        self.project, filter_=filter_string)\n    return resources\n\n  def list_groups(self):\n    groups = self.group_client.list_groups(self.project)\n    return groups\n\n\ndef make_client(context=None):\n  context = context or google.datalab.Context.default()\n  client = _MonitoringClient(context)\n  return client\n"
  },
  {
    "path": "google/datalab/storage/__init__.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Google Cloud Platform library - Cloud Storage Functionality.\"\"\"\nfrom __future__ import absolute_import\n\nfrom ._bucket import Bucket, Buckets\nfrom ._object import Object, Objects\n\n__all__ = ['Bucket', 'Buckets', 'Object', 'Objects']\n"
  },
  {
    "path": "google/datalab/storage/_api.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Implements Storage HTTP API wrapper.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom future import standard_library\nstandard_library.install_aliases()  # noqa\nfrom builtins import object\n\nimport google.datalab\nimport urllib.request\nimport urllib.parse\nimport urllib.error\nimport google.datalab.utils\n\n\nclass Api(object):\n  \"\"\"A helper class to issue Storage HTTP requests.\"\"\"\n\n  # TODO(nikhilko): Use named placeholders in these string templates.\n  _ENDPOINT = 'https://www.googleapis.com/storage/v1'\n  _DOWNLOAD_ENDPOINT = 'https://www.googleapis.com/download/storage/v1'\n  _UPLOAD_ENDPOINT = 'https://www.googleapis.com/upload/storage/v1'\n  _BUCKET_PATH = '/b/%s'\n  _OBJECT_PATH = '/b/%s/o/%s'\n  _OBJECT_COPY_PATH = '/b/%s/o/%s/copyTo/b/%s/o/%s'\n\n  _MAX_RESULTS = 100\n\n  def __init__(self, context):\n    \"\"\"Initializes the Storage helper with context information.\n\n    Args:\n      context: a Context object providing project_id and credentials.\n    \"\"\"\n    self._credentials = context.credentials\n    self._project_id = context.project_id\n\n  @property\n  def project_id(self):\n    \"\"\"The project_id associated with this API client.\"\"\"\n    return self._project_id\n\n  def buckets_insert(self, bucket, project_id=None):\n    \"\"\"Issues a request to create a new bucket.\n\n    Args:\n      bucket: the name of the bucket.\n      project_id: the project to use when inserting the bucket.\n    Returns:\n      A parsed bucket information dictionary.\n    Raises:\n      Exception if there is an error performing the operation.\n    \"\"\"\n    args = {'project': project_id if project_id else self._project_id}\n    data = {'name': bucket}\n\n    url = Api._ENDPOINT + (Api._BUCKET_PATH % '')\n    return google.datalab.utils.Http.request(url, args=args, data=data,\n                                             credentials=self._credentials)\n\n  def buckets_delete(self, bucket):\n    \"\"\"Issues a request to delete a bucket.\n\n    Args:\n      bucket: the name of the bucket.\n    Raises:\n      Exception if there is an error performing the operation.\n    \"\"\"\n    url = Api._ENDPOINT + (Api._BUCKET_PATH % bucket)\n    google.datalab.utils.Http.request(url, method='DELETE', credentials=self._credentials,\n                                      raw_response=True)\n\n  def buckets_get(self, bucket, projection='noAcl'):\n    \"\"\"Issues a request to retrieve information about a bucket.\n\n    Args:\n      bucket: the name of the bucket.\n      projection: the projection of the bucket information to retrieve.\n    Returns:\n      A parsed bucket information dictionary.\n    Raises:\n      Exception if there is an error performing the operation.\n    \"\"\"\n    args = {'projection': projection}\n    url = Api._ENDPOINT + (Api._BUCKET_PATH % bucket)\n    return google.datalab.utils.Http.request(url, credentials=self._credentials, args=args)\n\n  def buckets_list(self, projection='noAcl', max_results=0, page_token=None, project_id=None):\n    \"\"\"Issues a request to retrieve the list of buckets.\n\n    Args:\n      projection: the projection of the bucket information to retrieve.\n      max_results: an optional maximum number of objects to retrieve.\n      page_token: an optional token to continue the retrieval.\n      project_id: the project whose buckets should be listed.\n    Returns:\n      A parsed list of bucket information dictionaries.\n    Raises:\n      Exception if there is an error performing the operation.\n    \"\"\"\n    if max_results == 0:\n      max_results = Api._MAX_RESULTS\n\n    args = {'project': project_id if project_id else self._project_id, 'maxResults': max_results}\n    if projection is not None:\n      args['projection'] = projection\n    if page_token is not None:\n      args['pageToken'] = page_token\n\n    url = Api._ENDPOINT + (Api._BUCKET_PATH % '')\n    return google.datalab.utils.Http.request(url, args=args, credentials=self._credentials)\n\n  def object_download(self, bucket, key, start_offset=0, byte_count=None):\n    \"\"\"Reads the contents of an object as text.\n\n    Args:\n      bucket: the name of the bucket containing the object.\n      key: the key of the object to be read.\n      start_offset: the start offset of bytes to read.\n      byte_count: the number of bytes to read. If None, it reads to the end.\n    Returns:\n      The text content within the object.\n    Raises:\n      Exception if the object could not be read from.\n    \"\"\"\n    args = {'alt': 'media'}\n    headers = {}\n    if start_offset > 0 or byte_count is not None:\n      header = 'bytes=%d-' % start_offset\n      if byte_count is not None:\n        header += '%d' % byte_count\n      headers['Range'] = header\n    url = Api._DOWNLOAD_ENDPOINT + (Api._OBJECT_PATH % (bucket, Api._escape_key(key)))\n    return google.datalab.utils.Http.request(url, args=args, headers=headers,\n                                             credentials=self._credentials, raw_response=True)\n\n  def object_upload(self, bucket, key, content, content_type):\n    \"\"\"Writes text content to the object.\n\n    Args:\n      bucket: the name of the bucket containing the object.\n      key: the key of the object to be written.\n      content: the text content to be written.\n      content_type: the type of text content.\n    Raises:\n      Exception if the object could not be written to.\n    \"\"\"\n    args = {'uploadType': 'media', 'name': key}\n    headers = {'Content-Type': content_type}\n\n    url = Api._UPLOAD_ENDPOINT + (Api._OBJECT_PATH % (bucket, ''))\n    return google.datalab.utils.Http.request(url, args=args, data=content, headers=headers,\n                                             credentials=self._credentials, raw_response=True)\n\n  def objects_copy(self, source_bucket, source_key, target_bucket, target_key):\n    \"\"\"Updates the metadata associated with an object.\n\n    Args:\n      source_bucket: the name of the bucket containing the source object.\n      source_key: the key of the source object being copied.\n      target_bucket: the name of the bucket that will contain the copied object.\n      target_key: the key of the copied object.\n    Returns:\n      A parsed object information dictionary.\n    Raises:\n      Exception if there is an error performing the operation.\n    \"\"\"\n    url = Api._ENDPOINT + (Api._OBJECT_COPY_PATH % (source_bucket, Api._escape_key(source_key),\n                                                    target_bucket, Api._escape_key(target_key)))\n    return google.datalab.utils.Http.request(url, method='POST', credentials=self._credentials)\n\n  def objects_delete(self, bucket, key):\n    \"\"\"Deletes the specified object.\n\n    Args:\n      bucket: the name of the bucket.\n      key: the key of the object within the bucket.\n    Raises:\n      Exception if there is an error performing the operation.\n    \"\"\"\n    url = Api._ENDPOINT + (Api._OBJECT_PATH % (bucket, Api._escape_key(key)))\n    google.datalab.utils.Http.request(url, method='DELETE', credentials=self._credentials,\n                                      raw_response=True)\n\n  def objects_get(self, bucket, key, projection='noAcl'):\n    \"\"\"Issues a request to retrieve information about an object.\n\n    Args:\n      bucket: the name of the bucket.\n      key: the key of the object within the bucket.\n      projection: the projection of the object to retrieve.\n    Returns:\n      A parsed object information dictionary.\n    Raises:\n      Exception if there is an error performing the operation.\n    \"\"\"\n    args = {}\n    if projection is not None:\n      args['projection'] = projection\n\n    url = Api._ENDPOINT + (Api._OBJECT_PATH % (bucket, Api._escape_key(key)))\n    return google.datalab.utils.Http.request(url, args=args, credentials=self._credentials)\n\n  def objects_list(self, bucket, prefix=None, delimiter=None, projection='noAcl', versions=False,\n                   max_results=0, page_token=None):\n    \"\"\"Issues a request to retrieve information about an object.\n\n    Args:\n      bucket: the name of the bucket.\n      prefix: an optional key prefix.\n      delimiter: an optional key delimiter.\n      projection: the projection of the objects to retrieve.\n      versions: whether to list each version of a file as a distinct object.\n      max_results: an optional maximum number of objects to retrieve.\n      page_token: an optional token to continue the retrieval.\n    Returns:\n      A parsed list of object information dictionaries.\n    Raises:\n      Exception if there is an error performing the operation.\n    \"\"\"\n    if max_results == 0:\n      max_results = Api._MAX_RESULTS\n\n    args = {'maxResults': max_results}\n    if prefix is not None:\n      args['prefix'] = prefix\n    if delimiter is not None:\n      args['delimiter'] = delimiter\n    if projection is not None:\n      args['projection'] = projection\n    if versions:\n      args['versions'] = 'true'\n    if page_token is not None:\n      args['pageToken'] = page_token\n\n    url = Api._ENDPOINT + (Api._OBJECT_PATH % (bucket, ''))\n    return google.datalab.utils.Http.request(url, args=args, credentials=self._credentials)\n\n  def objects_patch(self, bucket, key, info):\n    \"\"\"Updates the metadata associated with an object.\n\n    Args:\n      bucket: the name of the bucket containing the object.\n      key: the key of the object being updated.\n      info: the metadata to update.\n    Returns:\n      A parsed object information dictionary.\n    Raises:\n      Exception if there is an error performing the operation.\n    \"\"\"\n    url = Api._ENDPOINT + (Api._OBJECT_PATH % (bucket, Api._escape_key(key)))\n    return google.datalab.utils.Http.request(url, method='PATCH', data=info,\n                                             credentials=self._credentials)\n\n  @staticmethod\n  def _escape_key(key):\n    # Disable the behavior to leave '/' alone by explicitly specifying the safe parameter.\n    return urllib.parse.quote(key, safe='')\n\n  @staticmethod\n  def verify_permitted_to_read(gs_path):\n    \"\"\"Check if the user has permissions to read from the given path.\n\n    Args:\n      gs_path: the GCS path to check if user is permitted to read.\n    Raises:\n      Exception if user has no permissions to read.\n    \"\"\"\n    # TODO(qimingj): Storage APIs need to be modified to allow absence of project\n    #                or credential on Objects. When that happens we can move the function\n    #                to Objects class.\n    from . import _bucket\n    bucket, prefix = _bucket.parse_name(gs_path)\n    credentials = None\n    if google.datalab.Context._is_signed_in():\n      credentials = google.datalab.Context.default().credentials\n    args = {\n        'maxResults': Api._MAX_RESULTS,\n        'projection': 'noAcl'\n    }\n    if prefix is not None:\n      args['prefix'] = prefix\n    url = Api._ENDPOINT + (Api._OBJECT_PATH % (bucket, ''))\n    try:\n      google.datalab.utils.Http.request(url, args=args, credentials=credentials)\n    except google.datalab.utils.RequestException as e:\n      if e.status == 401:\n        raise Exception('Not permitted to read from specified path. '\n                        'Please sign in and make sure you have read access.')\n      raise e\n"
  },
  {
    "path": "google/datalab/storage/_bucket.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Implements Bucket-related Cloud Storage APIs.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom builtins import object\n\nimport dateutil.parser\nimport re\n\nimport google.datalab\nimport google.datalab.utils\n\nfrom . import _api\nfrom . import _object\n\n\n# REs to match bucket names and optionally object names\n_BUCKET_NAME = '[a-z\\d][a-z\\d_\\.\\-]+[a-z\\d]'\n_OBJECT_NAME = '[^\\n\\r]+'\n_STORAGE_NAME = 'gs://(' + _BUCKET_NAME + ')(/' + _OBJECT_NAME + ')?'\n\n\ndef parse_name(name):\n  \"\"\" Parse a gs:// URL into the bucket and object names.\n\n  Args:\n    name: a GCS URL of the form gs://bucket or gs://bucket/object\n  Returns:\n    The bucket name (with no gs:// prefix), and the object name if present. If the name\n    could not be parsed returns None for both.\n  \"\"\"\n  bucket = None\n  obj = None\n  m = re.match(_STORAGE_NAME, name)\n  if m:\n    # We want to return the last two groups as first group is the optional 'gs://'\n    bucket = m.group(1)\n    obj = m.group(2)\n    if obj is not None:\n      obj = obj[1:]  # Strip '/'\n  else:\n    m = re.match('(' + _OBJECT_NAME + ')', name)\n    if m:\n      obj = m.group(1)\n  return bucket, obj\n\n\nclass BucketMetadata(object):\n  \"\"\"Represents metadata about a Cloud Storage bucket.\"\"\"\n\n  def __init__(self, info):\n    \"\"\"Initializes an instance of a BucketMetadata object.\n\n    Args:\n      info: a dictionary containing information about an Bucket.\n    \"\"\"\n    self._info = info\n\n  @property\n  def created_on(self):\n    \"\"\"The created timestamp of the bucket as a datetime.datetime.\"\"\"\n    s = self._info.get('timeCreated', None)\n    return dateutil.parser.parse(s) if s else None\n\n  @property\n  def etag(self):\n    \"\"\"The ETag of the bucket, if any.\"\"\"\n    return self._info.get('etag', None)\n\n  @property\n  def name(self):\n    \"\"\"The name of the bucket.\"\"\"\n    return self._info['name']\n\n\nclass Bucket(object):\n  \"\"\"Represents a Cloud Storage bucket.\"\"\"\n\n  def __init__(self, name, info=None, context=None):\n    \"\"\"Initializes an instance of a Bucket object.\n\n    Args:\n      name: the name of the bucket.\n      info: the information about the bucket if available.\n      context: an optional Context object providing project_id and credentials. If a specific\n          project id or credentials are unspecified, the default ones configured at the global\n          level are used.\n    \"\"\"\n    if context is None:\n      context = google.datalab.Context.default()\n    self._context = context\n    self._api = _api.Api(context)\n    self._name = name\n    self._info = info\n\n  @property\n  def name(self):\n    \"\"\"The name of the bucket.\"\"\"\n    return self._name\n\n  def __repr__(self):\n    \"\"\"Returns a representation for the table for showing in the notebook.\n    \"\"\"\n    return 'Google Cloud Storage Bucket gs://%s' % self._name\n\n  @property\n  def metadata(self):\n    \"\"\"Retrieves metadata about the bucket.\n\n    Returns:\n      A BucketMetadata instance with information about this bucket.\n    Raises:\n      Exception if there was an error requesting the bucket's metadata.\n    \"\"\"\n    if self._info is None:\n      try:\n        self._info = self._api.buckets_get(self._name)\n      except Exception as e:\n        raise e\n\n    return BucketMetadata(self._info) if self._info else None\n\n  def object(self, key):\n    \"\"\"Retrieves a Storage Object for the specified key in this bucket.\n\n    The object need not exist.\n\n    Args:\n      key: the key of the object within the bucket.\n    Returns:\n      An Object instance representing the specified key.\n    \"\"\"\n    return _object.Object(self._name, key, context=self._context)\n\n  def objects(self, prefix=None, delimiter=None):\n    \"\"\"Get an iterator for the objects within this bucket.\n\n    Args:\n      prefix: an optional prefix to match objects.\n      delimiter: an optional string to simulate directory-like semantics. The returned objects\n           will be those whose names do not contain the delimiter after the prefix. For\n           the remaining objects, the names will be returned truncated after the delimiter\n           with duplicates removed (i.e. as pseudo-directories).\n    Returns:\n      An iterable list of objects within this bucket.\n    \"\"\"\n    return _object.Objects(self._name, prefix, delimiter, context=self._context)\n\n  def exists(self):\n    \"\"\" Checks if the bucket exists. \"\"\"\n    try:\n      return self.metadata is not None\n    except Exception:\n      return False\n\n  def create(self, context=None):\n    \"\"\"Creates the bucket.\n\n    Args:\n      context: the context object to use when creating the bucket.\n    Returns:\n      The bucket.\n    Raises:\n      Exception if there was an error creating the bucket.\n    \"\"\"\n    if not self.exists():\n      project_id = context.project_id if context else self._api.project_id\n      try:\n        self._info = self._api.buckets_insert(self._name, project_id=project_id)\n      except Exception as e:\n        raise e\n    return self\n\n  def delete(self):\n    \"\"\"Deletes the bucket.\n\n    Raises:\n      Exception if there was an error deleting the bucket.\n    \"\"\"\n    if self.exists():\n      try:\n        self._api.buckets_delete(self._name)\n      except Exception as e:\n        raise e\n\n\nclass Buckets(object):\n  \"\"\"Represents a list of Cloud Storage buckets for a project.\"\"\"\n\n  def __init__(self, context=None):\n    \"\"\"Initializes an instance of a BucketList.\n\n    Args:\n      context: an optional Context object providing project_id and credentials. If a specific\n          project id or credentials are unspecified, the default ones configured at the global\n          level are used.\n    \"\"\"\n    if context is None:\n      context = google.datalab.Context.default()\n    self._context = context\n    self._api = _api.Api(context)\n    self._project_id = context.project_id if context else self._api.project_id\n\n  def contains(self, name):\n    \"\"\"Checks if the specified bucket exists.\n\n    Args:\n      name: the name of the bucket to lookup.\n    Returns:\n      True if the bucket exists; False otherwise.\n    Raises:\n      Exception if there was an error requesting information about the bucket.\n    \"\"\"\n    try:\n      self._api.buckets_get(name)\n    except google.datalab.utils.RequestException as e:\n      if e.status == 404:\n        return False\n      raise e\n    except Exception as e:\n      raise e\n    return True\n\n  def _retrieve_buckets(self, page_token, _):\n    try:\n      list_info = self._api.buckets_list(page_token=page_token, project_id=self._project_id)\n    except Exception as e:\n      raise e\n\n    buckets = list_info.get('items', [])\n    if len(buckets):\n      try:\n        buckets = [Bucket(info['name'], info, context=self._context) for info in buckets]\n      except KeyError:\n        raise Exception('Unexpected response from server')\n\n    page_token = list_info.get('nextPageToken', None)\n    return buckets, page_token\n\n  def __iter__(self):\n    return iter(google.datalab.utils.Iterator(self._retrieve_buckets))\n"
  },
  {
    "path": "google/datalab/storage/_object.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Implements Object-related Cloud Storage APIs.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom builtins import object\n\nimport dateutil.parser\nimport logging\nimport time\n\nimport google.datalab\nimport google.datalab.utils\n\nfrom . import _api\n\n# TODO(nikhilko): Read/write operations don't account for larger files, or non-textual content.\n#                 Use streaming reads into a buffer or StringIO or into a file handle.\n\n# In some polling operations, we sleep between API calls to avoid hammering the\n# server. This argument controls how long we sleep between API calls.\n_POLLING_SLEEP = 1\n# This argument controls how many times we'll poll before giving up.\n_MAX_POLL_ATTEMPTS = 30\n\n\nclass ObjectMetadata(object):\n  \"\"\"Represents metadata about a Cloud Storage object.\"\"\"\n\n  def __init__(self, info):\n    \"\"\"Initializes an instance of a ObjectMetadata object.\n\n    Args:\n      info: a dictionary containing information about an Object.\n    \"\"\"\n    self._info = info\n\n  @property\n  def content_type(self):\n    \"\"\"The Content-Type associated with the object, if any.\"\"\"\n    return self._info.get('contentType', None)\n\n  @property\n  def etag(self):\n    \"\"\"The ETag of the object, if any.\"\"\"\n    return self._info.get('etag', None)\n\n  @property\n  def name(self):\n    \"\"\"The name of the object.\"\"\"\n    return self._info['name']\n\n  @property\n  def size(self):\n    \"\"\"The size (in bytes) of the object. 0 for objects that don't exist.\"\"\"\n    return int(self._info.get('size', 0))\n\n  @property\n  def updated_on(self):\n    \"\"\"The updated timestamp of the object as a datetime.datetime.\"\"\"\n    s = self._info.get('updated', None)\n    return dateutil.parser.parse(s) if s else None\n\n\nclass Object(object):\n  \"\"\"Represents a Cloud Storage object within a bucket.\"\"\"\n\n  def __init__(self, bucket, key, info=None, context=None):\n    \"\"\"Initializes an instance of an Object.\n\n    Args:\n      bucket: the name of the bucket containing the object.\n      key: the key of the object.\n      info: the information about the object if available.\n      context: an optional Context object providing project_id and credentials. If a specific\n          project id or credentials are unspecified, the default ones configured at the global\n          level are used.\n    \"\"\"\n    if context is None:\n      context = google.datalab.Context.default()\n    self._context = context\n    self._api = _api.Api(context)\n    self._bucket = bucket\n    self._key = key\n    self._info = info\n\n  @staticmethod\n  def from_url(url):\n    from . import _bucket\n    bucket, object = _bucket.parse_name(url)\n    return Object(bucket, object)\n\n  @property\n  def key(self):\n    \"\"\"Returns the key of the object.\"\"\"\n    return self._key\n\n  @property\n  def uri(self):\n    \"\"\"Returns the gs:// URI for the object.\n    \"\"\"\n    return 'gs://%s/%s' % (self._bucket, self._key)\n\n  def __repr__(self):\n    \"\"\"Returns a representation for the table for showing in the notebook.\n    \"\"\"\n    return 'Google Cloud Storage Object %s' % self.uri\n\n  def copy_to(self, new_key, bucket=None):\n    \"\"\"Copies this object to the specified new key.\n\n    Args:\n      new_key: the new key to copy this object to.\n      bucket: the bucket of the new object; if None (the default) use the same bucket.\n    Returns:\n      An Object corresponding to new key.\n    Raises:\n      Exception if there was an error copying the object.\n    \"\"\"\n    if bucket is None:\n      bucket = self._bucket\n    try:\n      new_info = self._api.objects_copy(self._bucket, self._key, bucket, new_key)\n    except Exception as e:\n      raise e\n    return Object(bucket, new_key, new_info, context=self._context)\n\n  def exists(self):\n    \"\"\" Checks if the object exists. \"\"\"\n    try:\n      return self.metadata is not None\n    except google.datalab.utils.RequestException:\n      return False\n    except Exception as e:\n      raise e\n\n  def delete(self, wait_for_deletion=True):\n    \"\"\"Deletes this object from its bucket.\n\n    Args:\n      wait_for_deletion: If True, we poll until this object no longer appears in\n          objects.list operations for this bucket before returning.\n\n    Raises:\n      Exception if there was an error deleting the object.\n    \"\"\"\n    if self.exists():\n      try:\n        self._api.objects_delete(self._bucket, self._key)\n      except Exception as e:\n        raise e\n      if wait_for_deletion:\n        for _ in range(_MAX_POLL_ATTEMPTS):\n          objects = Objects(self._bucket, prefix=self.key, delimiter='/',\n                            context=self._context)\n          if any(o.key == self.key for o in objects):\n            time.sleep(_POLLING_SLEEP)\n            continue\n          break\n        else:\n          logging.error('Failed to see object deletion after %d attempts.',\n                        _MAX_POLL_ATTEMPTS)\n\n  @property\n  def metadata(self):\n    \"\"\"Retrieves metadata about the object.\n\n    Returns:\n      An ObjectMetadata instance with information about this object.\n    Raises:\n      Exception if there was an error requesting the object's metadata.\n    \"\"\"\n    if self._info is None:\n      try:\n        self._info = self._api.objects_get(self._bucket, self._key)\n      except Exception as e:\n        raise e\n    return ObjectMetadata(self._info) if self._info else None\n\n  def read_stream(self, start_offset=0, byte_count=None):\n    \"\"\"Reads the content of this object as text.\n\n    Args:\n      start_offset: the start offset of bytes to read.\n      byte_count: the number of bytes to read. If None, it reads to the end.\n    Returns:\n      The text content within the object.\n    Raises:\n      Exception if there was an error requesting the object's content.\n    \"\"\"\n    try:\n      return self._api.object_download(self._bucket, self._key,\n                                       start_offset=start_offset, byte_count=byte_count)\n    except Exception as e:\n      raise e\n\n  def download(self):\n    \"\"\"Reads the content of this object.\n\n    Returns:\n      The content within the object.\n    Raises:\n      Exception if there was an error requesting the object's content.\n    \"\"\"\n    return self.read_stream()\n\n  def read_lines(self, max_lines=None):\n    \"\"\"Reads the content of this object as text, and return a list of lines up to some max.\n\n    Args:\n      max_lines: max number of lines to return. If None, return all lines.\n    Returns:\n      The text content of the object as a list of lines.\n    Raises:\n      Exception if there was an error requesting the object's content.\n    \"\"\"\n    if max_lines is None:\n      return self.read_stream().split('\\n')\n\n    max_to_read = self.metadata.size\n    bytes_to_read = min(100 * max_lines, self.metadata.size)\n    while True:\n      content = self.read_stream(byte_count=bytes_to_read)\n\n      lines = content.split('\\n')\n      if len(lines) > max_lines or bytes_to_read >= max_to_read:\n        break\n      # try 10 times more bytes or max\n      bytes_to_read = min(bytes_to_read * 10, max_to_read)\n\n    # remove the partial line at last\n    del lines[-1]\n    return lines[0:max_lines]\n\n  def write_stream(self, content, content_type):\n    \"\"\"Writes text content to this object.\n\n    Args:\n      content: the text content to be written.\n      content_type: the type of text content.\n    Raises:\n      Exception if there was an error requesting the object's content.\n    \"\"\"\n    try:\n      self._api.object_upload(self._bucket, self._key, content, content_type)\n    except Exception as e:\n      raise e\n\n  def upload(self, content):\n    \"\"\"Uploads content to this object.\n\n    Args:\n      content: the text content to be written.\n    Raises:\n      Exception if there was an error requesting the object's content.\n    \"\"\"\n    self.write_stream(content, content_type=None)\n\n\nclass Objects(object):\n  \"\"\"Represents a list of Cloud Storage objects within a bucket.\"\"\"\n\n  def __init__(self, bucket, prefix, delimiter, context=None):\n    \"\"\"Initializes an instance of an ObjectList.\n\n    Args:\n      bucket: the name of the bucket containing the objects.\n      prefix: an optional prefix to match objects.\n      delimiter: an optional string to simulate directory-like semantics. The returned objects\n           will be those whose names do not contain the delimiter after the prefix. For\n           the remaining objects, the names will be returned truncated after the delimiter\n           with duplicates removed (i.e. as pseudo-directories).\n      context: an optional Context object providing project_id and credentials. If a specific\n          project id or credentials are unspecified, the default ones configured at the global\n          level are used.\n    \"\"\"\n    if context is None:\n      context = google.datalab.Context.default()\n    self._context = context\n    self._api = _api.Api(context)\n    self._bucket = bucket\n    self._prefix = prefix\n    self._delimiter = delimiter\n\n  def contains(self, key):\n    \"\"\"Checks if the specified object exists.\n\n    Args:\n      key: the key of the object to lookup.\n    Returns:\n      True if the object exists; False otherwise.\n    Raises:\n      Exception if there was an error requesting information about the object.\n    \"\"\"\n    try:\n      self._api.objects_get(self._bucket, key)\n    except google.datalab.utils.RequestException as e:\n      if e.status == 404:\n        return False\n      raise e\n    except Exception as e:\n      raise e\n    return True\n\n  def _retrieve_objects(self, page_token, _):\n    try:\n      list_info = self._api.objects_list(self._bucket,\n                                         prefix=self._prefix, delimiter=self._delimiter,\n                                         page_token=page_token)\n    except Exception as e:\n      raise e\n\n    objects = list_info.get('items', [])\n    if len(objects):\n      try:\n        objects = [Object(self._bucket, info['name'], info, context=self._context)\n                   for info in objects]\n      except KeyError:\n        raise Exception('Unexpected response from server')\n\n    page_token = list_info.get('nextPageToken', None)\n    return objects, page_token\n\n  def __iter__(self):\n    return iter(google.datalab.utils.Iterator(self._retrieve_objects))\n"
  },
  {
    "path": "google/datalab/storage/commands/__init__.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\nfrom __future__ import absolute_import\n\nfrom . import _storage\n\n__all__ = ['_storage']\n"
  },
  {
    "path": "google/datalab/storage/commands/_storage.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Google Cloud Platform library - BigQuery IPython Functionality.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom builtins import str\nfrom past.builtins import basestring\n\ntry:\n  import IPython\n  import IPython.core.display\n  import IPython.core.magic\nexcept ImportError:\n  raise Exception('This module can only be loaded in ipython.')\n\nimport fnmatch\nimport json\nimport re\n\nimport google.datalab.storage\nimport google.datalab.utils.commands\n\n\ndef _extract_gcs_api_response_error(message):\n  \"\"\" A helper function to extract user-friendly error messages from service exceptions.\n\n  Args:\n    message: An error message from an exception. If this is from our HTTP client code, it\n        will actually be a tuple.\n\n  Returns:\n    A modified version of the message that is less cryptic.\n  \"\"\"\n  try:\n    if len(message) == 3:\n      # Try treat the last part as JSON\n      data = json.loads(message[2])\n      return data['error']['errors'][0]['message']\n  except Exception:\n    pass\n  return message\n\n\n@IPython.core.magic.register_line_cell_magic\ndef gcs(line, cell=None):\n  \"\"\"Implements the gcs cell magic for ipython notebooks.\n\n  Args:\n    line: the contents of the gcs line.\n  Returns:\n    The results of executing the cell.\n  \"\"\"\n  parser = google.datalab.utils.commands.CommandParser(prog='%gcs', description=\"\"\"\nExecute various Google Cloud Storage related operations. Use \"%gcs <command> -h\"\nfor help on a specific command.\n\"\"\")\n\n  # TODO(gram): consider adding a move command too. I did try this already using the\n  # objects.patch API to change the object name but that fails with an error:\n  #\n  # Value 'newname' in content does not agree with value 'oldname'. This can happen when a value\n  # set through a parameter is inconsistent with a value set in the request.\n  #\n  # This is despite 'name' being identified as writable in the storage API docs.\n  # The alternative would be to use a copy/delete.\n  copy_parser = parser.subcommand('copy', 'Copy one or more Google Cloud Storage objects to a '\n                                          'different location.')\n  copy_parser.add_argument('-s', '--source', help='The name of the object(s) to copy', nargs='+')\n  copy_parser.add_argument('-d', '--destination', required=True,\n                           help='The copy destination. For multiple source objects this must be a '\n                                'bucket.')\n  copy_parser.set_defaults(func=_gcs_copy)\n\n  create_parser = parser.subcommand('create', 'Create one or more Google Cloud Storage buckets.')\n  create_parser.add_argument('-p', '--project', help='The project associated with the objects')\n  create_parser.add_argument('-b', '--bucket', help='The name of the bucket(s) to create',\n                             nargs='+')\n  create_parser.set_defaults(func=_gcs_create)\n\n  delete_parser = parser.subcommand('delete', 'Delete one or more Google Cloud Storage buckets or '\n                                              'objects.')\n  delete_parser.add_argument('-b', '--bucket', nargs='*',\n                             help='The name of the bucket(s) to remove')\n  delete_parser.add_argument('-o', '--object', nargs='*',\n                             help='The name of the object(s) to remove')\n  delete_parser.set_defaults(func=_gcs_delete)\n\n  list_parser = parser.subcommand('list', 'List buckets in a project, or contents of a bucket.')\n  list_parser.add_argument('-p', '--project', help='The project associated with the objects')\n  list_parser.add_argument('-o', '--objects',\n                           help='List objects under the given Google Cloud Storage path',\n                           nargs='?')\n  list_parser.set_defaults(func=_gcs_list)\n\n  read_parser = parser.subcommand('read', 'Read the contents of a Google Cloud Storage object into '\n                                          'a Python variable.')\n  read_parser.add_argument('-o', '--object', help='The name of the object to read',\n                           required=True)\n  read_parser.add_argument('-v', '--variable', required=True,\n                           help='The name of the Python variable to set')\n  read_parser.set_defaults(func=_gcs_read)\n\n  view_parser = parser.subcommand('view', 'View the contents of a Google Cloud Storage object.')\n  view_parser.add_argument('-n', '--head', type=int, default=20,\n                           help='The number of initial lines to view')\n  view_parser.add_argument('-t', '--tail', type=int, default=20,\n                           help='The number of lines from end to view')\n  view_parser.add_argument('-o', '--object', help='The name of the object to view',\n                           required=True)\n  view_parser.set_defaults(func=_gcs_view)\n\n  write_parser = parser.subcommand('write', 'Write the value of a Python variable to a Google '\n                                            'Cloud Storage object.')\n  write_parser.add_argument('-v', '--variable', help='The name of the source Python variable',\n                            required=True)\n  write_parser.add_argument('-o', '--object', required=True,\n                            help='The name of the destination Google Cloud Storage object to write')\n  write_parser.add_argument('-c', '--content_type', help='MIME type', default='text/plain')\n  write_parser.set_defaults(func=_gcs_write)\n\n  return google.datalab.utils.commands.handle_magic_line(line, cell, parser)\n\n\ndef _parser_exit(status=0, message=None):\n  \"\"\" Replacement exit method for argument parser. We want to stop processing args but not\n      call sys.exit(), so we raise an exception here and catch it in the call to parse_args.\n  \"\"\"\n  raise Exception()\n\n\ndef _expand_list(names):\n  \"\"\" Do a wildchar name expansion of object names in a list and return expanded list.\n\n    The objects are expected to exist as this is used for copy sources or delete targets.\n    Currently we support wildchars in the key name only.\n  \"\"\"\n\n  if names is None:\n    names = []\n  elif isinstance(names, basestring):\n    names = [names]\n\n  results = []  # The expanded list.\n  objects = {}  # Cached contents of buckets; used for matching.\n  for name in names:\n    bucket, key = google.datalab.storage._bucket.parse_name(name)\n    results_len = len(results)  # If we fail to add any we add name and let caller deal with it.\n    if bucket:\n      if not key:\n        # Just a bucket; add it.\n        results.append('gs://%s' % bucket)\n      elif google.datalab.storage.Object(bucket, key).exists():\n        results.append('gs://%s/%s' % (bucket, key))\n      else:\n        # Expand possible key values.\n        if bucket not in objects and key[:1] == '*':\n          # We need the full list; cache a copy for efficiency.\n          objects[bucket] = [obj.metadata.name\n                             for obj in list(google.datalab.storage.Bucket(bucket).objects())]\n        # If we have a cached copy use it\n        if bucket in objects:\n          candidates = objects[bucket]\n        # else we have no cached copy but can use prefix matching which is more efficient than\n        # getting the full contents.\n        else:\n          # Get the non-wildchar prefix.\n          match = re.search('\\?|\\*|\\[', key)\n          prefix = key\n          if match:\n            prefix = key[0:match.start()]\n\n          candidates = [obj.metadata.name\n                        for obj in google.datalab.storage.Bucket(bucket).objects(prefix=prefix)]\n\n        for obj in candidates:\n          if fnmatch.fnmatch(obj, key):\n            results.append('gs://%s/%s' % (bucket, obj))\n\n    # If we added no matches, add the original name and let caller deal with it.\n    if len(results) == results_len:\n      results.append(name)\n\n  return results\n\n\ndef _gcs_copy(args, _):\n  target = args['destination']\n  target_bucket, target_key = google.datalab.storage._bucket.parse_name(target)\n  if target_bucket is None and target_key is None:\n    raise Exception('Invalid copy target name %s' % target)\n\n  sources = _expand_list(args['source'])\n\n  if len(sources) > 1:\n    # Multiple sources; target must be a bucket\n    if target_bucket is None or target_key is not None:\n      raise Exception('More than one source but target %s is not a bucket' % target)\n\n  errs = []\n  for source in sources:\n    source_bucket, source_key = google.datalab.storage._bucket.parse_name(source)\n    if source_bucket is None or source_key is None:\n      raise Exception('Invalid source object name %s' % source)\n    destination_bucket = target_bucket if target_bucket else source_bucket\n    destination_key = target_key if target_key else source_key\n    try:\n      google.datalab.storage.Object(source_bucket, source_key).copy_to(destination_key,\n                                                                       bucket=destination_bucket)\n    except Exception as e:\n      errs.append(\"Couldn't copy %s to %s: %s\" %\n                  (source, target, _extract_gcs_api_response_error(str(e))))\n  if errs:\n    raise Exception('\\n'.join(errs))\n\n\ndef _gcs_create(args, _):\n  \"\"\" Create one or more buckets. \"\"\"\n  errs = []\n  for name in args['bucket']:\n    try:\n      bucket, key = google.datalab.storage._bucket.parse_name(name)\n      if bucket and not key:\n        google.datalab.storage.Bucket(bucket).create(_make_context(args['project']))\n      else:\n        raise Exception(\"Invalid bucket name %s\" % name)\n    except Exception as e:\n      errs.append(\"Couldn't create %s: %s\" %\n                  (name, _extract_gcs_api_response_error(str(e))))\n  if errs:\n    raise Exception('\\n'.join(errs))\n\n\ndef _gcs_delete(args, _):\n  \"\"\" Delete one or more buckets or objects. \"\"\"\n  objects = _expand_list(args['bucket'])\n  objects.extend(_expand_list(args['object']))\n  errs = []\n  for obj in objects:\n    try:\n      bucket, key = google.datalab.storage._bucket.parse_name(obj)\n      if bucket and key:\n        gcs_object = google.datalab.storage.Object(bucket, key)\n        if gcs_object.exists():\n          google.datalab.storage.Object(bucket, key).delete()\n        else:\n          errs.append(\"%s does not exist\" % obj)\n      elif bucket:\n        gcs_bucket = google.datalab.storage.Bucket(bucket)\n        if gcs_bucket.exists():\n          gcs_bucket.delete()\n        else:\n          errs.append(\"%s does not exist\" % obj)\n      else:\n        raise Exception(\"Can't delete object with invalid name %s\" % obj)\n    except Exception as e:\n      errs.append(\"Couldn't delete %s: %s\" %\n                  (obj, _extract_gcs_api_response_error(str(e))))\n  if errs:\n    raise Exception('\\n'.join(errs))\n\n\ndef _make_context(project_id=None):\n  default_context = google.datalab.Context.default()\n  project_id = project_id or default_context.project_id\n  return google.datalab.Context(project_id, default_context.credentials)\n\n\ndef _gcs_list_buckets(project, pattern):\n  \"\"\" List all Google Cloud Storage buckets that match a pattern. \"\"\"\n  data = [{'Bucket': 'gs://' + bucket.name, 'Created': bucket.metadata.created_on}\n          for bucket in google.datalab.storage.Buckets(_make_context(project))\n          if fnmatch.fnmatch(bucket.name, pattern)]\n  return google.datalab.utils.commands.render_dictionary(data, ['Bucket', 'Created'])\n\n\ndef _gcs_get_keys(bucket, pattern):\n  \"\"\" Get names of all Google Cloud Storage keys in a specified bucket that match a pattern. \"\"\"\n  return [obj for obj in list(bucket.objects()) if fnmatch.fnmatch(obj.metadata.name, pattern)]\n\n\ndef _gcs_get_key_names(bucket, pattern):\n  \"\"\" Get names of all Google Cloud Storage keys in a specified bucket that match a pattern. \"\"\"\n  return [obj.metadata.name for obj in _gcs_get_keys(bucket, pattern)]\n\n\ndef _gcs_list_keys(bucket, pattern):\n  \"\"\" List all Google Cloud Storage keys in a specified bucket that match a pattern. \"\"\"\n  data = [{'Name': obj.metadata.name,\n           'Type': obj.metadata.content_type,\n           'Size': obj.metadata.size,\n           'Updated': obj.metadata.updated_on}\n          for obj in _gcs_get_keys(bucket, pattern)]\n  return google.datalab.utils.commands.render_dictionary(data, ['Name', 'Type', 'Size', 'Updated'])\n\n\ndef _gcs_list(args, _):\n  \"\"\" List the buckets or the contents of a bucket.\n\n  This command is a bit different in that we allow wildchars in the bucket name and will list\n  the buckets that match.\n  \"\"\"\n  target = args['objects']\n  project = args['project']\n  if target is None:\n    return _gcs_list_buckets(project, '*')  # List all buckets.\n\n  bucket_name, key = google.datalab.storage._bucket.parse_name(target)\n  if bucket_name is None:\n    raise Exception('Cannot list %s; not a valid bucket name' % target)\n\n  # If a target was specified, list keys inside it\n  if target:\n    if not re.search('\\?|\\*|\\[', target):\n      # If no wild characters are present in the key string, append a '/*' suffix to show all keys\n      key = key.strip('/') + '/*' if key else '*'\n\n    if project:\n      # Only list if the bucket is in the project\n      for bucket in google.datalab.storage.Buckets(_make_context(project)):\n        if bucket.name == bucket_name:\n          break\n      else:\n        raise Exception('%s does not exist in project %s' % (target, project))\n    else:\n      bucket = google.datalab.storage.Bucket(bucket_name)\n\n    if bucket.exists():\n      return _gcs_list_keys(bucket, key)\n    else:\n      raise Exception('Bucket %s does not exist' % target)\n\n  else:\n    # Treat the bucket name as a pattern and show matches. We don't use bucket_name as that\n    # can strip off wildchars and so we need to strip off gs:// here.\n    return _gcs_list_buckets(project, target.strip('/')[5:])\n\n\ndef _get_object_contents(source_name):\n  source_bucket, source_key = google.datalab.storage._bucket.parse_name(source_name)\n  if source_bucket is None:\n    raise Exception('Invalid source object name %s; no bucket specified.' % source_name)\n  if source_key is None:\n    raise Exception('Invalid source object name %si; source cannot be a bucket.' % source_name)\n  source = google.datalab.storage.Object(source_bucket, source_key)\n  if not source.exists():\n    raise Exception('Source object %s does not exist' % source_name)\n  return source.download()\n\n\ndef _gcs_read(args, _):\n  contents = _get_object_contents(args['object'])\n  ipy = IPython.get_ipython()\n  ipy.push({args['variable']: contents})\n\n\ndef _gcs_view(args, _):\n  contents = _get_object_contents(args['object'])\n  if not isinstance(contents, basestring):\n    contents = str(contents)\n  elif isinstance(contents, bytes):\n    contents = str(contents, encoding='UTF-8')\n  lines = contents.splitlines()\n  head_count = args['head']\n  tail_count = args['tail']\n  if len(lines) > head_count + tail_count:\n    head = '\\n'.join(lines[:head_count])\n    tail = '\\n'.join(lines[-tail_count:])\n    return head + '\\n...\\n' + tail\n  else:\n    return contents\n\n\ndef _gcs_write(args, _):\n  target_name = args['object']\n  target_bucket, target_key = google.datalab.storage._bucket.parse_name(target_name)\n  if target_bucket is None or target_key is None:\n    raise Exception('Invalid target object name %s' % target_name)\n  target = google.datalab.storage.Object(target_bucket, target_key)\n  ipy = IPython.get_ipython()\n  contents = ipy.user_ns[args['variable']]\n  # TODO(gram): would we want to to do any special handling here; e.g. for DataFrames?\n  target.write_stream(str(contents), args['content_type'])\n"
  },
  {
    "path": "google/datalab/utils/__init__.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Google Cloud Platform library - Internal Helpers.\"\"\"\n\nfrom ._async import async_, async_function, async_method\nfrom ._http import Http, RequestException\nfrom ._iterator import Iterator\nfrom ._json_encoder import JSONEncoder\nfrom ._lru_cache import LRUCache\nfrom ._lambda_job import LambdaJob\nfrom ._dataflow_job import DataflowJob\nfrom ._utils import print_exception_with_last_stack, get_item, compare_datetimes, \\\n    pick_unused_port, is_http_running_on, gcs_copy_file, python_portable_string\n\n\n__all__ = ['async_', 'async_function', 'async_method', 'Http', 'RequestException', 'Iterator',\n           'JSONEncoder', 'LRUCache', 'LambdaJob', 'DataflowJob',\n           'print_exception_with_last_stack', 'get_item', 'compare_datetimes', 'pick_unused_port',\n           'is_http_running_on', 'gcs_copy_file', 'python_portable_string']\n"
  },
  {
    "path": "google/datalab/utils/_async.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Decorators for async methods and functions to dispatch on threads and support chained calls.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom builtins import object\n\nimport abc\nimport concurrent.futures\nimport functools\n\nfrom google.datalab._job import Job\nfrom future.utils import with_metaclass\n\n\nclass async_(with_metaclass(abc.ABCMeta, object)):\n  \"\"\" Base class for async_function/async_method. Creates a wrapped function/method that will\n      run the original function/method on a thread pool worker thread and return a Job instance\n      for monitoring the status of the thread.\n  \"\"\"\n  executor = concurrent.futures.ThreadPoolExecutor(max_workers=50)  # Pool for doing the work.\n\n  def __init__(self, function):\n    self._function = function\n    # Make the wrapper get attributes like docstring from wrapped method.\n    functools.update_wrapper(self, function)\n\n  @staticmethod\n  def _preprocess_args(*args):\n    # Pre-process arguments - if any are themselves Futures block until they can be resolved.\n    return [arg.result() if isinstance(arg, concurrent.futures.Future) else arg for arg in args]\n\n  @staticmethod\n  def _preprocess_kwargs(**kwargs):\n    # Pre-process keyword arguments - if any are Futures block until they can be resolved.\n    return {kw: (arg.result() if isinstance(arg, concurrent.futures.Future) else arg)\n            for kw, arg in list(kwargs.items())}\n\n  @abc.abstractmethod\n  def _call(self, *args, **kwargs):\n    return\n\n  def __call__(self, *args, **kwargs):\n    # Queue the call up in the thread pool.\n    return Job(future=self.executor.submit(self._call, *args, **kwargs))\n\n\nclass async_function(async_):\n  \"\"\" This decorator can be applied to any static function that makes blocking calls to create\n      a modified version that creates a Job and returns immediately; the original\n      method will be called on a thread pool worker thread.\n  \"\"\"\n\n  def _call(self, *args, **kwargs):\n    # Call the wrapped method.\n    return self._function(*async_._preprocess_args(*args), **async_._preprocess_kwargs(**kwargs))\n\n\nclass async_method(async_):\n  \"\"\" This decorator can be applied to any class instance method that makes blocking calls to create\n      a modified version that creates a Job and returns immediately; the original method will be\n      called on a thread pool worker thread.\n  \"\"\"\n\n  def _call(self, *args, **kwargs):\n    # Call the wrapped method.\n    return self._function(self.obj, *async_._preprocess_args(*args),\n                          **async_._preprocess_kwargs(**kwargs))\n\n  def __get__(self, instance, owner):\n    # This is important for attribute inheritance and setting self.obj so it can be\n    # passed as first argument to wrapped method.\n    self.cls = owner\n    self.obj = instance\n    return self\n"
  },
  {
    "path": "google/datalab/utils/_dataflow_job.py",
    "content": "# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Implements DataFlow Job functionality.\"\"\"\n\n\nfrom google.datalab import _job\n\n\nclass DataflowJob(_job.Job):\n  \"\"\"Represents a DataFlow Job.\n  \"\"\"\n\n  def __init__(self, runner_results):\n    \"\"\"Initializes an instance of a DataFlow Job.\n\n    Args:\n      runner_results: a DataflowPipelineResult returned from Pipeline.run().\n    \"\"\"\n    super(DataflowJob, self).__init__(runner_results._job.name)\n    self._runner_results = runner_results\n\n  def _refresh_state(self):\n    \"\"\" Refresh the job info. \"\"\"\n\n    # DataFlow's DataflowPipelineResult does not refresh state, so we have to do it ourselves\n    # as a workaround.\n    # TODO(Change this to use runner_results.state once it refreshes itself)\n    dataflow_internal_job = (\n        self._runner_results._runner.dataflow_client.get_job(self._runner_results.job_id()))\n    self._is_complete = str(dataflow_internal_job.currentState) in ['JOB_STATE_STOPPED',\n                                                                    'JOB_STATE_DONE',\n                                                                    'JOB_STATE_FAILED',\n                                                                    'JOB_STATE_CANCELLED']\n    self._fatal_error = getattr(self._runner_results._runner, 'last_error_msg', None)\n    # Sometimes Dataflow does not populate runner.last_error_msg even if the job fails.\n    if self._fatal_error is None and self._runner_results.state == 'FAILED':\n      self._fatal_error = 'FAILED'\n"
  },
  {
    "path": "google/datalab/utils/_gcp_job.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Implements GCP Job functionality.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\n\nimport google.datalab\nfrom google.datalab import _job\n\n\nclass GCPJob(_job.Job):\n  \"\"\"Represents a BigQuery Job.\n  \"\"\"\n\n  def __init__(self, job_id, context):\n    \"\"\"Initializes an instance of a Job.\n\n    Args:\n      job_id: the BigQuery job ID corresponding to this job.\n      context: a Context object providing project_id and credentials.\n    \"\"\"\n    super(GCPJob, self).__init__(job_id)\n    if context is None:\n      context = google.datalab.Context.default()\n    self._context = context\n    self._api = self._create_api(context)\n\n  def _create_api(self, context):\n    raise Exception('_create_api must be defined in a derived class')\n\n  def __repr__(self):\n    \"\"\"Returns a representation for the job for showing in the notebook.\n    \"\"\"\n    return 'Job %s/%s %s' % (self._context.project_id, self._job_id, self.state)\n"
  },
  {
    "path": "google/datalab/utils/_http.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Implements HTTP client helper functionality.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom future import standard_library\nstandard_library.install_aliases()  # noqa\nfrom builtins import str\nfrom past.builtins import basestring\nfrom builtins import object\n\nimport copy\nimport datetime\nimport json\nimport urllib.request\nimport urllib.parse\nimport urllib.error\nimport httplib2\nimport google_auth_httplib2\nimport logging\n\n\nlog = logging.getLogger(__name__)\n\n\n# TODO(nikhilko): Start using the requests library instead.\n\n\nclass RequestException(Exception):\n\n  def __init__(self, status, content):\n    self.status = status\n    self.content = content\n    self.message = 'HTTP request failed'\n    # Try extract a message from the body; swallow possible resulting ValueErrors and KeyErrors.\n    try:\n      if isinstance(content, str):\n        error = json.loads(content)['error']\n      else:\n        error = json.loads(str(content, encoding='UTF-8'))['error']\n      if 'errors' in error:\n        error = error['errors'][0]\n      self.message += ': {}'.format(error['message'])\n    except Exception:\n      lines = content.splitlines() if isinstance(content, basestring) else []\n      if lines:\n        self.message += ': {}'.format(lines[0])\n\n  def __str__(self):\n    return self.message\n\n\nclass Http(object):\n  \"\"\"A helper class for making HTTP requests.\n  \"\"\"\n\n  # Reuse one Http object across requests to take advantage of Keep-Alive, e.g.\n  # for BigQuery queries that requires at least ~5 sequential http requests.\n  #\n  # TODO(nikhilko):\n  # SSL cert validation seemingly fails, and workarounds are not amenable\n  # to implementing in library code. So configure the Http object to skip\n  # doing so, in the interim.\n  http = httplib2.Http()\n  http.disable_ssl_certificate_validation = True\n\n  def __init__(self):\n    pass\n\n  @staticmethod\n  def request(url, args=None, data=None, headers=None, method=None,\n              credentials=None, raw_response=False, stats=None):\n    \"\"\"Issues HTTP requests.\n\n    Args:\n      url: the URL to request.\n      args: optional query string arguments.\n      data: optional data to be sent within the request.\n      headers: optional headers to include in the request.\n      method: optional HTTP method to use. If unspecified this is inferred\n          (GET or POST) based on the existence of request data.\n      credentials: optional set of credentials to authorize the request.\n      raw_response: whether the raw response content should be returned as-is.\n      stats: an optional dictionary that, if provided, will be populated with some\n          useful info about the request, like 'duration' in seconds and 'data_size' in\n          bytes. These may be useful optimizing the access to rate-limited APIs.\n    Returns:\n      The parsed response object.\n    Raises:\n      Exception when the HTTP request fails or the response cannot be processed.\n    \"\"\"\n    if headers is None:\n      headers = {}\n\n    headers['user-agent'] = 'GoogleCloudDataLab/1.0'\n    # Add querystring to the URL if there are any arguments.\n    if args is not None:\n      qs = urllib.parse.urlencode(args)\n      url = url + '?' + qs\n\n    # Setup method to POST if unspecified, and appropriate request headers\n    # if there is data to be sent within the request.\n    if data is not None:\n      if method is None:\n        method = 'POST'\n\n      if data != '':\n        # If there is a content type specified, use it (and the data) as-is.\n        # Otherwise, assume JSON, and serialize the data object.\n        if 'Content-Type' not in headers:\n          data = json.dumps(data)\n          headers['Content-Type'] = 'application/json'\n      headers['Content-Length'] = str(len(data))\n    else:\n      if method == 'POST':\n        headers['Content-Length'] = '0'\n\n    # If the method is still unset, i.e. it was unspecified, and there\n    # was no data to be POSTed, then default to GET request.\n    if method is None:\n      method = 'GET'\n\n    http = Http.http\n\n    # Authorize with credentials if given\n    if credentials is not None:\n      # Make a copy of the shared http instance before we modify it.\n      http = copy.copy(http)\n      http = google_auth_httplib2.AuthorizedHttp(credentials)\n    if stats is not None:\n      stats['duration'] = datetime.datetime.utcnow()\n\n    response = None\n    try:\n      log.debug('request: method[%(method)s], url[%(url)s], body[%(data)s]' % locals())\n      response, content = http.request(url,\n                                       method=method,\n                                       body=data,\n                                       headers=headers)\n      if 200 <= response.status < 300:\n        if raw_response:\n          return content\n        if type(content) == str:\n          return json.loads(content)\n        else:\n          return json.loads(str(content, encoding='UTF-8'))\n      else:\n        raise RequestException(response.status, content)\n    except ValueError:\n      raise Exception('Failed to process HTTP response.')\n    except httplib2.HttpLib2Error:\n      raise Exception('Failed to send HTTP request.')\n    finally:\n      if stats is not None:\n        stats['data_size'] = len(data)\n        stats['status'] = response.status\n        stats['duration'] = (datetime.datetime.utcnow() - stats['duration']).total_seconds()\n"
  },
  {
    "path": "google/datalab/utils/_iterator.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Iterator class for iterable cloud lists.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom builtins import object\n\n\nclass Iterator(object):\n  \"\"\"An iterator implementation that handles paging over a cloud list.\"\"\"\n\n  def __init__(self, retriever):\n    \"\"\"Initializes an instance of an Iterator.\n\n    Args:\n      retriever: a function that can retrieve the next page of items.\n    \"\"\"\n    self._page_token = None\n    self._first_page = True\n    self._retriever = retriever\n    self._count = 0\n\n  def __iter__(self):\n    \"\"\"Provides iterator functionality.\"\"\"\n    while self._first_page or (self._page_token is not None):\n      items, next_page_token = self._retriever(self._page_token, self._count)\n\n      self._page_token = next_page_token\n      self._first_page = False\n      self._count += len(items)\n\n      for item in items:\n        yield item\n\n  def reset(self):\n    \"\"\"Resets the current iteration.\"\"\"\n    self._page_token = None\n    self._first_page = True\n    self._count = 0\n"
  },
  {
    "path": "google/datalab/utils/_json_encoder.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\" JSON encoder that can handle Python datetime objects. \"\"\"\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nimport datetime\nimport json\n\n\nclass JSONEncoder(json.JSONEncoder):\n  \"\"\" A JSON encoder that can handle Python datetime objects. \"\"\"\n\n  def default(self, obj):\n    if isinstance(obj, datetime.date) or isinstance(obj, datetime.datetime):\n      return obj.isoformat()\n    elif isinstance(obj, datetime.timedelta):\n      return (datetime.datetime.min + obj).time().isoformat()\n    else:\n      return super(JSONEncoder, self).default(obj)\n"
  },
  {
    "path": "google/datalab/utils/_lambda_job.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Implements OS shell Job functionality.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\n\nfrom . import _async\nfrom google.datalab import _job\n\n\nclass LambdaJob(_job.Job):\n  \"\"\"Represents an lambda function as a Job.\n  \"\"\"\n\n  def __init__(self, fn, job_id, *args, **kwargs):\n    \"\"\"Initializes an instance of a Job.\n\n    Args:\n      fn: the lambda function to execute asyncronously\n      job_id: an optional ID for the job. If None, a UUID will be generated.\n    \"\"\"\n    super(LambdaJob, self).__init__(job_id)\n    self._future = _async.async_.executor.submit(fn, *args, **kwargs)\n\n  def __repr__(self):\n    \"\"\"Returns a representation for the job for showing in the notebook.\n    \"\"\"\n    return 'Job %s %s' % (self._job_id, self.state)\n\n    # TODO: ShellJob, once we need it, should inherit on LambdaJob:\n    #      import subprocess\n    #      LambdaJob(subprocess.check_output, id, command_line, shell=True)\n"
  },
  {
    "path": "google/datalab/utils/_lru_cache.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"A simple LRU cache.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom builtins import str\nfrom past.builtins import basestring\nfrom builtins import object\n\nimport datetime\n\n\nclass LRUCache(object):\n  \"\"\"A simple LRU cache.\"\"\"\n\n  def __init__(self, cache_size):\n    \"\"\" Initialize the cache with the given size.\n\n    Args:\n      cache_size: the maximum number of items the cache can hold. Attempts to add more\n          items than this will result in the least recently used items being displaced to\n          make room.\n    \"\"\"\n    self._cache = {}\n    self._cache_size = cache_size\n\n  def __getitem__(self, key):\n    \"\"\" Get an item from the cache.\n\n    Args:\n      key: a string used as the lookup key.\n    Returns:\n      The cached item, if any.\n    Raises:\n      Exception if the key is not a string.\n      KeyError if the key is not found.\n    \"\"\"\n    if not isinstance(key, basestring):\n      raise Exception(\"LRU cache can only be indexed by strings (%s has type %s)\" %\n                      (str(key), str(type(key))))\n\n    if key in self._cache:\n      entry = self._cache[key]\n      entry['last_used'] = datetime.datetime.now()\n      return entry['value']\n    else:\n      raise KeyError(key)\n\n  def __delitem__(self, key):\n    \"\"\" Remove an item from the cache.\n\n    Args:\n      key: a string key for retrieving the item.\n    \"\"\"\n    if not isinstance(key, basestring):\n      raise Exception(\"LRU cache can only be indexed by strings\")\n    del self._cache[key]\n\n  def __setitem__(self, key, value):\n    \"\"\" Put an item in the cache.\n\n    Args:\n      key: a string key for retrieving the item.\n      value: the item to cache.\n    Raises:\n      Exception if the key is not a string.\n    \"\"\"\n    if not isinstance(key, basestring):\n      raise Exception(\"LRU cache can only be indexed by strings\")\n\n    if key in self._cache:\n      entry = self._cache[key]\n    elif len(self._cache) < self._cache_size:\n      # Cache is not full; append an new entry\n      self._cache[key] = entry = {}\n    else:\n      # Cache is full; displace an entry\n      entry = min(list(self._cache.values()), key=lambda x: x['last_used'])\n      self._cache.pop(entry['key'])\n      self._cache[key] = entry\n\n    entry['value'] = value\n    entry['key'] = key\n    entry['last_used'] = datetime.datetime.now()\n\n  def __contains__(self, key):\n    return key in self._cache\n\n  def get(self, key, value):\n    if key in self._cache:\n      return self._cache[key]['value']\n    return value\n"
  },
  {
    "path": "google/datalab/utils/_utils.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Miscellaneous simple utility functions.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import print_function\nfrom __future__ import unicode_literals\nfrom builtins import str\n\ntry:\n    import http.client as httplib\nexcept ImportError:\n    import httplib\n\nimport json\nimport logging\nimport os\nimport pytz\nimport six\nimport subprocess\nimport socket\nimport traceback\nimport types\n\nimport oauth2client.client\nimport google.auth\nimport google.auth.exceptions\nimport google.auth.credentials\nimport google.auth._oauth2client\n\n\ndef print_exception_with_last_stack(e):\n  \"\"\" Print the call stack of the last exception plu sprint the passed exception.\n\n  Args:\n    e: the exception to print.\n  \"\"\"\n  traceback.print_exc()\n  print(str(e))\n\n\ndef get_item(env, name, default=None):\n  \"\"\" Get an item from a dictionary, handling nested lookups with dotted notation.\n\n  Args:\n    env: the environment (dictionary) to use to look up the name.\n    name: the name to look up, in dotted notation.\n    default: the value to return if the name if not found.\n\n  Returns:\n    The result of looking up the name, if found; else the default.\n  \"\"\"\n  # TODO: handle attributes\n  if not name:\n    return default\n  for key in name.split('.'):\n    if isinstance(env, dict) and key in env:\n      env = env[key]\n    elif isinstance(env, types.ModuleType) and key in env.__dict__:\n      env = env.__dict__[key]\n    else:\n      return default\n  return env\n\n\ndef compare_datetimes(d1, d2):\n  \"\"\" Compares two datetimes safely, whether they are timezone-naive or timezone-aware.\n\n  If either datetime is naive it is converted to an aware datetime assuming UTC.\n\n  Args:\n    d1: first datetime.\n    d2: second datetime.\n\n  Returns:\n    -1 if d1 < d2, 0 if they are the same, or +1 is d1 > d2.\n  \"\"\"\n  if d1.tzinfo is None or d1.tzinfo.utcoffset(d1) is None:\n    d1 = d1.replace(tzinfo=pytz.UTC)\n  if d2.tzinfo is None or d2.tzinfo.utcoffset(d2) is None:\n    d2 = d2.replace(tzinfo=pytz.UTC)\n  if d1 < d2:\n    return -1\n  elif d1 > d2:\n    return 1\n  return 0\n\n\ndef pick_unused_port():\n  \"\"\" get an unused port on the VM.\n\n  Returns:\n    An unused port.\n  \"\"\"\n  s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n  s.bind(('localhost', 0))\n  addr, port = s.getsockname()\n  s.close()\n  return port\n\n\ndef is_http_running_on(port):\n  \"\"\" Check if an http server runs on a given port.\n\n  Args:\n    The port to check.\n  Returns:\n    True if it is used by an http server. False otherwise.\n  \"\"\"\n  try:\n    conn = httplib.HTTPConnection('127.0.0.1:' + str(port))\n    conn.connect()\n    conn.close()\n    return True\n  except Exception:\n    return False\n\n\ndef gcs_copy_file(source, dest):\n  \"\"\" Copy file from source to destination. The paths can be GCS or local.\n\n  Args:\n    source: the source file path.\n    dest: the destination file path.\n  \"\"\"\n  subprocess.check_call(['gsutil', '-q', 'cp', source, dest])\n\n\n\"\"\" Support for getting gcloud credentials. \"\"\"\n\n# TODO(ojarjur): This limits the APIs against which Datalab can be called\n# (when using a service account with a credentials file) to only being those\n# that are part of the Google Cloud Platform. We should either extend this\n# to all of the API scopes that Google supports, or make it extensible so\n# that the user can define for themselves which scopes they want to use.\nCREDENTIAL_SCOPES = [\n  'https://www.googleapis.com/auth/cloud-platform',\n]\n\n\ndef _in_datalab_docker():\n  return os.path.exists('/datalab') and os.getenv('DATALAB_ENV')\n\n\ndef get_config_dir():\n  config_dir = os.getenv('CLOUDSDK_CONFIG')\n  if config_dir is None:\n    if os.name == 'nt':\n      try:\n        config_dir = os.path.join(os.environ['APPDATA'], 'gcloud')\n      except KeyError:\n        # This should never happen unless someone is really messing with things.\n        drive = os.environ.get('SystemDrive', 'C:')\n        config_dir = os.path.join(drive, '\\\\gcloud')\n    else:\n      config_dir = os.path.join(os.path.expanduser('~'), '.config/gcloud')\n  return config_dir\n\n\ndef _convert_oauth2client_creds(credentials):\n  new_credentials = google.oauth2.credentials.Credentials(\n    token=credentials.access_token,\n    refresh_token=credentials.refresh_token,\n    token_uri=credentials.token_uri,\n    client_id=credentials.client_id,\n    client_secret=credentials.client_secret,\n    scopes=credentials.scopes)\n\n  new_credentials._expires = credentials.token_expiry\n  return new_credentials\n\n\ndef get_credentials():\n  \"\"\" Get the credentials to use. We try application credentials first, followed by\n      user credentials. The path to the application credentials can be overridden\n      by pointing the GOOGLE_APPLICATION_CREDENTIALS environment variable to some file;\n      the path to the user credentials can be overridden by pointing the CLOUDSDK_CONFIG\n      environment variable to some directory (after which we will look for the file\n      $CLOUDSDK_CONFIG/gcloud/credentials). Unless you have specific reasons for\n      overriding these the defaults should suffice.\n  \"\"\"\n  try:\n    # We temporarily disable warning logs from the \"_default\" module to avoid\n    # a spurious warning about the project not being set.\n    authDefaultLogger = logging.getLogger(\"google.auth._default\")\n    previousLevel = authDefaultLogger.getEffectiveLevel()\n    authDefaultLogger.setLevel(logging.ERROR)\n    credentials, _ = google.auth.default()\n    credentials = google.auth.credentials.with_scopes_if_required(credentials, CREDENTIAL_SCOPES)\n    authDefaultLogger.setLevel(previousLevel)\n    return credentials\n  except Exception as e:\n\n    # Try load user creds from file\n    cred_file = get_config_dir() + '/credentials'\n    if os.path.exists(cred_file):\n      with open(cred_file) as f:\n        creds = json.loads(f.read())\n      # Use the first gcloud one we find\n      for entry in creds['data']:\n        if entry['key']['type'] == 'google-cloud-sdk':\n          creds = oauth2client.client.OAuth2Credentials.from_json(json.dumps(entry['credential']))\n          return _convert_oauth2client_creds(creds)\n\n    if type(e) == google.auth.exceptions.DefaultCredentialsError:\n      # If we are in Datalab container, change the message to be about signing in.\n      if _in_datalab_docker():\n        raise Exception('No application credentials found. Perhaps you should sign in.')\n\n    raise e\n\n\ndef save_project_id(project_id):\n  \"\"\" Save project id to config file.\n\n  Args:\n    project_id: the project_id to save.\n  \"\"\"\n  # Try gcloud first. If gcloud fails (probably because it does not exist), then\n  # write to a config file.\n  try:\n    subprocess.call(['gcloud', 'config', 'set', 'project', project_id])\n  except:\n    config_file = os.path.join(get_config_dir(), 'config.json')\n    config = {}\n    if os.path.exists(config_file):\n      with open(config_file) as f:\n        config = json.loads(f.read())\n    config['project_id'] = project_id\n    with open(config_file, 'w') as f:\n      f.write(json.dumps(config))\n\n\ndef get_default_project_id():\n  \"\"\" Get default project id from config or environment var.\n\n  Returns: the project id if available, or None.\n  \"\"\"\n  # Try getting default project id from gcloud. If it fails try config.json.\n  try:\n    proc = subprocess.Popen(['gcloud', 'config', 'list', '--format', 'value(core.project)'],\n                            stdout=subprocess.PIPE)\n    stdout, _ = proc.communicate()\n    value = stdout.strip()\n    if proc.poll() == 0 and value:\n      if isinstance(value, six.string_types):\n        return value\n      else:\n        # Hope it's a utf-8 string encoded in bytes. Otherwise an exception will\n        # be thrown and config.json will be checked.\n        return value.decode()\n  except:\n    pass\n\n  config_file = os.path.join(get_config_dir(), 'config.json')\n  if os.path.exists(config_file):\n    with open(config_file) as f:\n      config = json.loads(f.read())\n      if 'project_id' in config and config['project_id']:\n        return str(config['project_id'])\n\n  if os.getenv('PROJECT_ID') is not None:\n    return os.getenv('PROJECT_ID')\n  return None\n\n\ndef _construct_context_for_args(args):\n  \"\"\"Construct a new Context for the parsed arguments.\n\n  Args:\n    args: the dictionary of magic arguments.\n  Returns:\n    A new Context based on the current default context, but with any explicitly\n      specified arguments overriding the default's config.\n  \"\"\"\n  global_default_context = google.datalab.Context.default()\n  config = {}\n  for key in global_default_context.config:\n    config[key] = global_default_context.config[key]\n\n  billing_tier_arg = args.get('billing', None)\n  if billing_tier_arg:\n    config['bigquery_billing_tier'] = billing_tier_arg\n\n  return google.datalab.Context(\n    project_id=global_default_context.project_id,\n    credentials=global_default_context.credentials,\n    config=config)\n\n\ndef python_portable_string(string, encoding='utf-8'):\n  \"\"\"Converts bytes into a string type.\n\n  Valid string types are retuned without modification. So in Python 2, type str\n  and unicode are not converted.\n\n  In Python 3, type bytes is converted to type str (unicode)\n  \"\"\"\n  if isinstance(string, six.string_types):\n    return string\n\n  if six.PY3:\n    return string.decode(encoding)\n\n  raise ValueError('Unsupported type %s' % str(type(string)))\n"
  },
  {
    "path": "google/datalab/utils/commands/__init__.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n# flake8: noqa\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\n\n# Support functions for magics and display help.\nfrom ._commands import CommandParser\nfrom ._html import Html, HtmlBuilder\nfrom ._utils import *\n\n# Magics\nfrom . import _chart\nfrom . import _chart_data\nfrom . import _csv\nfrom . import _job\n"
  },
  {
    "path": "google/datalab/utils/commands/_chart.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Google Cloud Platform library - Chart cell magic.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\n\ntry:\n  import IPython\n  import IPython.core.display\n  import IPython.core.magic\nexcept ImportError:\n  raise Exception('This module can only be loaded in ipython.')\n\nfrom . import _commands\nfrom . import _utils\n\n\n@IPython.core.magic.register_line_cell_magic\ndef chart(line, cell=None):\n  \"\"\" Generate charts with Google Charts. Use %chart --help for more details. \"\"\"\n  parser = _commands.CommandParser(prog='%chart', description=\"\"\"\nGenerate an inline chart using Google Charts using the data in a Table, Query, dataframe, or list.\nNumerous types of charts are supported. Options for the charts can be specified in the cell body\nusing YAML or JSON.\n\"\"\")\n  for chart_type in ['annotation', 'area', 'bars', 'bubbles', 'calendar', 'candlestick', 'columns',\n                     'combo', 'gauge', 'geo', 'heatmap', 'histogram', 'line', 'map', 'org',\n                     'paged_table', 'pie', 'sankey', 'scatter', 'stepped_area', 'table',\n                     'timeline', 'treemap']:\n    subparser = parser.subcommand(chart_type, 'Generate a %s chart.' % chart_type)\n    subparser.add_argument('-f', '--fields',\n                           help='The field(s) to include in the chart')\n    subparser.add_argument('-d', '--data',\n                           help='The name of the variable referencing the Table or Query to chart',\n                           required=True)\n    subparser.set_defaults(chart=chart_type)\n\n  parser.set_defaults(func=_chart_cell)\n  return _utils.handle_magic_line(line, cell, parser)\n\n\ndef _chart_cell(args, cell):\n  source = args['data']\n  ipy = IPython.get_ipython()\n  chart_options = _utils.parse_config(cell, ipy.user_ns)\n  if chart_options is None:\n    chart_options = {}\n  elif not isinstance(chart_options, dict):\n    raise Exception(\"Could not parse chart options\")\n  chart_type = args['chart']\n  fields = args['fields'] if args['fields'] else '*'\n  return IPython.core.display.HTML(_utils.chart_html('gcharts', chart_type, source=source,\n                                                     chart_options=chart_options, fields=fields))\n"
  },
  {
    "path": "google/datalab/utils/commands/_chart_data.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Google Cloud Platform library - chart_data cell magic.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import print_function\nfrom __future__ import unicode_literals\n\ntry:\n  import IPython\n  import IPython.core.display\n  import IPython.core.magic\nexcept ImportError:\n  raise Exception('This module can only be loaded in ipython.')\n\nimport json\n\nimport datalab.utils.commands\nimport google.datalab.data\nimport google.datalab.utils\n\nfrom . import _utils\n\n\n@IPython.core.magic.register_cell_magic\ndef _get_chart_data(line, cell_body=''):\n\n  refresh = 0\n  options = {}\n  try:\n    metadata = json.loads(cell_body) if cell_body else {}\n    source_index = metadata.get('source_index', None)\n    fields = metadata.get('fields', '*')\n    first_row = int(metadata.get('first', 0))\n    count = int(metadata.get('count', -1))\n    legacy = metadata.get('legacy', None)\n\n    # Both legacy and non-legacy table viewer calls this magic for new pages of data.\n    # Need to find their own data source --- one under datalab.utils.commands._utils\n    # and the other under google.datalab.utils.commands._utils.\n    if legacy is not None:\n      data_source = datalab.utils.commands._utils._data_sources\n    else:\n      data_source = _utils._data_sources\n\n    source_index = int(source_index)\n    if source_index >= len(data_source):  # Can happen after e.g. kernel restart\n      # TODO(gram): get kernel restart events in charting.js and disable any refresh timers.\n      print('No source %d' % source_index)\n      return IPython.core.display.JSON({'data': {}})\n    source = data_source[source_index]\n    schema = None\n\n    controls = metadata['controls'] if 'controls' in metadata else {}\n    if legacy is not None:\n      data, _ = datalab.utils.commands.get_data(\n          source, fields, controls, first_row, count, schema)\n    else:\n      data, _ = _utils.get_data(source, fields, controls, first_row, count, schema)\n  except Exception as e:\n    google.datalab.utils.print_exception_with_last_stack(e)\n    print('Failed with exception %s' % e)\n    data = {}\n\n  # TODO(gram): The old way - commented out below - has the advantage that it worked\n  # for datetimes, but it is strictly wrong. The correct way below may have issues if the\n  # chart has datetimes though so test this.\n  return IPython.core.display.JSON({'data': data, 'refresh_interval': refresh, 'options': options})\n  # return IPython.core.display.JSON(json.dumps({'data': data},\n  #                                             cls=google.datalab.utils.JSONEncoder))\n"
  },
  {
    "path": "google/datalab/utils/commands/_commands.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Implementation of command parsing and handling within magics.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import print_function\nfrom __future__ import unicode_literals\n\ntry:\n  import IPython\nexcept ImportError:\n  raise Exception('This module can only be loaded in ipython.')\n\nimport argparse\nimport shlex\nimport six\n\nimport google.datalab.utils\n\n\nclass CommandParser(argparse.ArgumentParser):\n  \"\"\"An argument parser to parse commands in line/cell magic declarations. \"\"\"\n\n  def __init__(self, *args, **kwargs):\n    \"\"\"Initializes an instance of a CommandParser. \"\"\"\n\n    super(CommandParser, self).__init__(*args, **kwargs)\n    # Set _parser_class, so that subparsers added will also be of this type.\n    self._parser_class = CommandParser\n    self._subcommands = None\n    # A dict such as {'argname': {'required': True, 'help': 'arg help string'}}\n    self._cell_args = {}\n\n  @staticmethod\n  def create(name):\n    \"\"\"Creates a CommandParser for a specific magic. \"\"\"\n    return CommandParser(prog=name)\n\n  def exit(self, status=0, message=None):\n    \"\"\"Overridden exit method to stop parsing without calling sys.exit(). \"\"\"\n    if status == 0 and message is None:\n      # This happens when parsing '--help'\n      raise Exception('exit_0')\n    else:\n      raise Exception(message)\n\n  def format_help(self):\n    \"\"\"Override help doc to add cell args. \"\"\"\n\n    if not self._cell_args:\n      return super(CommandParser, self).format_help()\n    else:\n      # Print the standard argparse info, the cell arg block, and then the epilog\n      # If we don't remove epilog before calling the super, then epilog will\n      # be printed before the 'Cell args' block.\n      epilog = self.epilog\n      self.epilog = None\n      orig_help = super(CommandParser, self).format_help()\n\n      cell_args_help = '\\nCell args:\\n\\n'\n      for cell_arg, v in six.iteritems(self._cell_args):\n        required = 'Required' if v['required'] else 'Optional'\n        cell_args_help += '%s: %s. %s.\\n\\n' % (cell_arg, required, v['help'])\n\n      orig_help += cell_args_help\n      if epilog:\n        orig_help += epilog + '\\n\\n'\n      return orig_help\n\n  def format_usage(self):\n    \"\"\"Overridden usage generator to use the full help message. \"\"\"\n    return self.format_help()\n\n  @staticmethod\n  def create_args(line, namespace):\n    \"\"\" Expand any meta-variable references in the argument list. \"\"\"\n    args = []\n    # Using shlex.split handles quotes args and escape characters.\n    for arg in shlex.split(line):\n      if not arg:\n         continue\n      if arg[0] == '$':\n        var_name = arg[1:]\n        if var_name in namespace:\n          args.append((namespace[var_name]))\n        else:\n          raise Exception('Undefined variable referenced in command line: %s' % arg)\n      else:\n        args.append(arg)\n    return args\n\n  def _get_subparsers(self):\n    \"\"\"Recursively get subparsers.\"\"\"\n\n    subparsers = []\n    for action in self._actions:\n      if isinstance(action, argparse._SubParsersAction):\n        for _, subparser in action.choices.items():\n          subparsers.append(subparser)\n\n    ret = subparsers\n    for sp in subparsers:\n      ret += sp._get_subparsers()\n    return ret\n\n  def _get_subparser_line_args(self, subparser_prog):\n    \"\"\" Get line args of a specified subparser by its prog.\"\"\"\n\n    subparsers = self._get_subparsers()\n    for subparser in subparsers:\n      if subparser_prog == subparser.prog:\n        # Found the subparser.\n        args_to_parse = []\n        for action in subparser._actions:\n          if action.option_strings:\n            for argname in action.option_strings:\n              if argname.startswith('--'):\n                args_to_parse.append(argname[2:])\n        return args_to_parse\n\n    return None\n\n  def _get_subparser_cell_args(self, subparser_prog):\n    \"\"\" Get cell args of a specified subparser by its prog.\"\"\"\n\n    subparsers = self._get_subparsers()\n    for subparser in subparsers:\n      if subparser_prog == subparser.prog:\n        return subparser._cell_args\n\n    return None\n\n  def add_cell_argument(self, name, help, required=False):\n    \"\"\" Add a cell only argument.\n\n    Args:\n      name: name of the argument. No need to start with \"-\" or \"--\".\n      help: the help string of the argument.\n      required: Whether it is required in cell content.\n    \"\"\"\n\n    for action in self._actions:\n      if action.dest == name:\n        raise ValueError('Arg \"%s\" was added by add_argument already.' % name)\n\n    self._cell_args[name] = {'required': required, 'help': help}\n\n  def parse(self, line, cell, namespace=None):\n    \"\"\"Parses a line and cell into a dictionary of arguments, expanding variables from a namespace.\n\n    For each line parameters beginning with --, it also checks the cell content and see if it exists\n    there. For example, if \"--config1\" is a line parameter, it checks to see if cell dict contains\n    \"config1\" item, and if so, use the cell value. The \"config1\" item will also be removed from\n    cell content.\n\n    Args:\n      line: line content.\n      cell: cell content.\n      namespace: user namespace. If None, IPython's user namespace is used.\n\n    Returns:\n      A tuple of: 1. parsed config dict. 2. remaining cell after line parameters are extracted.\n    \"\"\"\n\n    if namespace is None:\n      ipy = IPython.get_ipython()\n      namespace = ipy.user_ns\n\n    # Find which subcommand in the line by comparing line with subcommand progs.\n    # For example, assuming there are 3 subcommands with their progs\n    #   %bq tables\n    #   %bq tables list\n    #   %bq datasets\n    # and the line is \"tables list --dataset proj.myds\"\n    # it will find the second one --- \"tables list\" because it matches the prog and\n    # it is the longest.\n    args = CommandParser.create_args(line, namespace)\n\n    # \"prog\" is a ArgumentParser's path splitted by namspace, such as '%bq tables list'.\n    sub_parsers_progs = [x.prog for x in self._get_subparsers()]\n    matched_progs = []\n    for prog in sub_parsers_progs:\n      # Remove the leading magic such as \"%bq\".\n      match = prog.split()[1:]\n      for i in range(len(args)):\n        if args[i:i + len(match)] == match:\n          matched_progs.append(prog)\n          break\n\n    matched_prog = None\n    if matched_progs:\n      # Get the longest match.\n      matched_prog = max(matched_progs, key=lambda x: len(x.split()))\n\n    # Line args can be provided in cell too. If they are in cell, move them to line\n    # so we can parse them all together.\n    line_args = self._get_subparser_line_args(matched_prog)\n    if line_args:\n      cell_config = None\n      try:\n        cell_config, cell = google.datalab.utils.commands.parse_config_for_selected_keys(\n            cell, line_args)\n      except:\n        # It is okay --- probably because cell is not in yaml or json format.\n        pass\n\n      if cell_config:\n        google.datalab.utils.commands.replace_vars(cell_config, namespace)\n        for arg_name in cell_config:\n          arg_value = cell_config[arg_name]\n          if arg_value is None:\n            continue\n\n          if '--' + arg_name in args:\n            raise ValueError('config item \"%s\" is specified in both cell and line.' % arg_name)\n          if isinstance(arg_value, bool):\n            if arg_value:\n              line += ' --%s' % arg_name\n          else:\n            line += ' --%s %s' % (arg_name, str(cell_config[arg_name]))\n\n    # Parse args again with the new line.\n    args = CommandParser.create_args(line, namespace)\n    args = vars(self.parse_args(args))\n\n    # Parse cell args.\n    cell_config = None\n    cell_args = self._get_subparser_cell_args(matched_prog)\n    if cell_args:\n      try:\n        cell_config, _ = google.datalab.utils.commands.parse_config_for_selected_keys(\n            cell, cell_args)\n      except:\n        # It is okay --- probably because cell is not in yaml or json format.\n        pass\n\n      if cell_config:\n        google.datalab.utils.commands.replace_vars(cell_config, namespace)\n\n      for arg in cell_args:\n        if (cell_args[arg]['required'] and\n           (cell_config is None or cell_config.get(arg, None) is None)):\n          raise ValueError('Cell config \"%s\" is required.' % arg)\n\n    if cell_config:\n      args.update(cell_config)\n\n    return args, cell\n\n  def subcommand(self, name, help, **kwargs):\n    \"\"\"Creates a parser for a sub-command. \"\"\"\n    if self._subcommands is None:\n      self._subcommands = self.add_subparsers(help='commands')\n    return self._subcommands.add_parser(name, description=help, help=help, **kwargs)\n"
  },
  {
    "path": "google/datalab/utils/commands/_csv.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Implements CSV file exploration\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\n\n\ntry:\n  import IPython\n  import IPython.core.magic\n  import IPython.core.display\nexcept ImportError:\n  raise Exception('This module can only be loaded in ipython.')\n\nimport pandas as pd\n\nimport google.datalab.data\n\nfrom . import _commands\nfrom . import _utils\n\n\n@IPython.core.magic.register_line_cell_magic\ndef csv(line, cell=None):\n  parser = _commands.CommandParser.create('csv')\n\n  view_parser = parser.subcommand('view',\n                                  'Browse CSV files without providing a schema. ' +\n                                  'Each value is considered string type.')\n  view_parser.add_argument('-i', '--input',\n                           help='Path of the input CSV data', required=True)\n  view_parser.add_argument('-n', '--count',\n                           help='The number of lines to browse from head, default to 5.')\n  view_parser.add_argument('-P', '--profile', action='store_true',\n                           default=False, help='Generate an interactive profile of the data')\n  view_parser.set_defaults(func=_view)\n\n  return _utils.handle_magic_line(line, cell, parser)\n\n\ndef _view(args, cell):\n  csv = google.datalab.data.CsvFile(args['input'])\n  num_lines = int(args['count'] or 5)\n  headers = None\n  if cell:\n    ipy = IPython.get_ipython()\n    config = _utils.parse_config(cell, ipy.user_ns)\n    if 'columns' in config:\n      headers = [e.strip() for e in config['columns'].split(',')]\n  df = pd.DataFrame(csv.browse(num_lines, headers))\n  if args['profile']:\n    # TODO(gram): We need to generate a schema and type-convert the columns before this\n    # will be useful for CSV\n    return _utils.profile_df(df)\n  else:\n    return IPython.core.display.HTML(df.to_html(index=False))\n"
  },
  {
    "path": "google/datalab/utils/commands/_html.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Google Cloud Platform library - IPython HTML display Functionality.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom builtins import str\nfrom builtins import range\nfrom past.builtins import basestring\nfrom builtins import object\n\nimport time\n\n\nclass Html(object):\n  \"\"\"A helper to enable generating an HTML representation as display data in a notebook.\n\n  This object supports the combination of HTML markup and/or associated JavaScript.\n  \"\"\"\n\n  _div_id_counter = 0\n\n  @staticmethod\n  def next_id():\n    \"\"\" Return an ID containing a reproducible part (counter) and unique part (timestamp). \"\"\"\n    Html._div_id_counter += 1\n    return '%d_%d' % (Html._div_id_counter, int(round(time.time() * 100)))\n\n  def __init__(self, markup=None):\n    \"\"\"Initializes an instance of Html.\n    \"\"\"\n    self._id = Html.next_id()\n    Html._div_id_counter += 1\n    self._class_name = ''\n    self._markup = markup\n    self._dependencies = [('element!hh_%d' % self._id, 'dom')]\n    self._script = ''\n    self._class = None\n\n  def add_class(self, class_name):\n    \"\"\"Adds a CSS class to be generated on the output HTML.\n    \"\"\"\n    self._class = class_name\n\n  def add_dependency(self, path, name):\n    \"\"\"Adds a script dependency to be loaded before any script is executed.\n    \"\"\"\n    self._dependencies.append((path, name))\n\n  def add_script(self, script):\n    \"\"\"Adds JavaScript that should be included along-side the HTML.\n    \"\"\"\n    self._script = script\n\n  def _repr_html_(self):\n    \"\"\"Generates the HTML representation.\n    \"\"\"\n    parts = []\n    if self._class:\n      parts.append('<div id=\"hh_%s\" class=\"%s\">%s</div>' % (self._id, self._class, self._markup))\n    else:\n      parts.append('<div id=\"hh_%s\">%s</div>' % (self._id, self._markup))\n\n    if len(self._script) != 0:\n      parts.append('<script>')\n      parts.append('require([')\n      parts.append(','.join(['\"%s\"' % d[0] for d in self._dependencies]))\n      parts.append('], function(')\n      parts.append(','.join([d[1] for d in self._dependencies]))\n      parts.append(') {')\n      parts.append(self._script)\n      parts.append('});')\n      parts.append('</script>')\n\n    return ''.join(parts)\n\n\nclass HtmlBuilder(object):\n  \"\"\"A set of helpers to build HTML representations of objects.\n  \"\"\"\n\n  def __init__(self):\n    \"\"\"Initializes an instance of an HtmlBuilder.\n    \"\"\"\n    self._segments = []\n\n  def _render_objects(self, items, attributes=None, datatype='object'):\n    \"\"\"Renders an HTML table with the specified list of objects.\n\n    Args:\n      items: the iterable collection of objects to render.\n      attributes: the optional list of properties or keys to render.\n      datatype: the type of data; one of 'object' for Python objects, 'dict' for a list\n          of dictionaries, or 'chartdata' for Google chart data.\n    \"\"\"\n    if not items:\n      return\n\n    if datatype == 'chartdata':\n      if not attributes:\n        attributes = [items['cols'][i]['label'] for i in range(0, len(items['cols']))]\n      items = items['rows']\n      indices = {attributes[i]: i for i in range(0, len(attributes))}\n\n    num_segments = len(self._segments)\n    self._segments.append('<table>')\n\n    first = True\n    for o in items:\n      if first:\n        first = False\n        if datatype == 'dict' and not attributes:\n          attributes = list(o.keys())\n\n        if attributes is not None:\n          self._segments.append('<tr>')\n          for attr in attributes:\n            self._segments.append('<th>%s</th>' % attr)\n          self._segments.append('</tr>')\n\n      self._segments.append('<tr>')\n      if attributes is None:\n        self._segments.append('<td>%s</td>' % HtmlBuilder._format(o))\n      else:\n        for attr in attributes:\n          if datatype == 'dict':\n            self._segments.append('<td>%s</td>' % HtmlBuilder._format(o.get(attr, None), nbsp=True))\n          elif datatype == 'chartdata':\n            self._segments.append('<td>%s</td>' % HtmlBuilder._format(o['c'][indices[attr]]['v'],\n                                                                      nbsp=True))\n          else:\n            self._segments.append('<td>%s</td>' % HtmlBuilder._format(o.__getattribute__(attr),\n                                                                      nbsp=True))\n\n      self._segments.append('</tr>')\n\n    self._segments.append('</table>')\n    if first:\n      # The table was empty; drop it from the segments.\n      self._segments = self._segments[:num_segments]\n\n  def _render_text(self, text, preformatted=False):\n    \"\"\"Renders an HTML formatted text block with the specified text.\n\n    Args:\n      text: the text to render\n      preformatted: whether the text should be rendered as preformatted\n    \"\"\"\n    tag = 'pre' if preformatted else 'div'\n    self._segments.append('<%s>%s</%s>' % (tag, HtmlBuilder._format(text), tag))\n\n  def _render_list(self, items, empty='<pre>&lt;empty&gt;</pre>'):\n    \"\"\"Renders an HTML list with the specified list of strings.\n\n    Args:\n      items: the iterable collection of objects to render.\n      empty: what to render if the list is None or empty.\n    \"\"\"\n    if not items or len(items) == 0:\n      self._segments.append(empty)\n      return\n    self._segments.append('<ul>')\n    for o in items:\n      self._segments.append('<li>')\n      self._segments.append(str(o))\n      self._segments.append('</li>')\n    self._segments.append('</ul>')\n\n  def _to_html(self):\n    \"\"\"Returns the HTML that has been rendered.\n\n    Returns:\n      The HTML string that has been built.\n    \"\"\"\n    return ''.join(self._segments)\n\n  @staticmethod\n  def _format(value, nbsp=False):\n    if value is None:\n      return '&nbsp;' if nbsp else ''\n    elif isinstance(value, basestring):\n      return value.replace('&', '&amp;').replace('<', '&lt;').replace('>', '&gt;')\n    else:\n      return str(value)\n\n  @staticmethod\n  def render_text(text, preformatted=False):\n    \"\"\"Renders an HTML formatted text block with the specified text.\n\n    Args:\n      text: the text to render\n      preformatted: whether the text should be rendered as preformatted\n    Returns:\n      The formatted HTML.\n    \"\"\"\n    builder = HtmlBuilder()\n    builder._render_text(text, preformatted=preformatted)\n    return builder._to_html()\n\n  @staticmethod\n  def render_table(data, headers=None):\n    \"\"\" Return a dictionary list formatted as a HTML table.\n\n    Args:\n      data: a list of dictionaries, one per row.\n      headers: the keys in the dictionary to use as table columns, in order.\n    \"\"\"\n    builder = HtmlBuilder()\n    builder._render_objects(data, headers, datatype='dict')\n    return builder._to_html()\n\n  @staticmethod\n  def render_chart_data(data):\n    \"\"\" Return a dictionary list formatted as a HTML table.\n\n    Args:\n      data: data in the form consumed by Google Charts.\n    \"\"\"\n    builder = HtmlBuilder()\n    builder._render_objects(data, datatype='chartdata')\n    return builder._to_html()\n\n  @staticmethod\n  def render_list(data):\n    \"\"\" Return a list formatted as a HTML list.\n\n    Args:\n      data: a list of strings.\n    \"\"\"\n    builder = HtmlBuilder()\n    builder._render_list(data)\n    return builder._to_html()\n"
  },
  {
    "path": "google/datalab/utils/commands/_job.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Implements job view\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom builtins import str\n\n\ntry:\n  import IPython\n  import IPython.core.magic\n  import IPython.core.display\nexcept ImportError:\n  raise Exception('This module can only be loaded in ipython.')\n\nimport google.datalab.utils\n\nfrom . import _html\n\n\n_local_jobs = {}\n\n\ndef html_job_status(job_name, job_type, refresh_interval, html_on_running, html_on_success):\n  \"\"\"create html representation of status of a job (long running operation).\n\n  Args:\n    job_name: the full name of the job.\n    job_type: type of job. Can be 'local' or 'cloud'.\n    refresh_interval: how often should the client refresh status.\n    html_on_running: additional html that the job view needs to include on job running.\n    html_on_success: additional html that the job view needs to include on job success.\n  \"\"\"\n  _HTML_TEMPLATE = \"\"\"\n    <div class=\"jobstatus\" id=\"%s\">\n    </div>\n    <script>\n      require(['datalab/job', 'datalab/element!%s', 'base/js/events',\n          'datalab/style!/nbextensions/datalab/job.css'],\n        function(job, dom, events) {\n          job.render(dom, events, '%s', '%s', %s, '%s', '%s');\n        }\n      );\n    </script>\"\"\"\n  div_id = _html.Html.next_id()\n  return IPython.core.display.HTML(_HTML_TEMPLATE % (div_id, div_id, job_name, job_type,\n                                   refresh_interval, html_on_running, html_on_success))\n\n\n@IPython.core.magic.register_line_magic\ndef _get_job_status(line):\n  \"\"\"magic used as an endpoint for client to get job status.\n\n       %_get_job_status <name>\n\n  Returns:\n    A JSON object of the job status.\n  \"\"\"\n  try:\n    args = line.strip().split()\n    job_name = args[0]\n\n    job = None\n    if job_name in _local_jobs:\n      job = _local_jobs[job_name]\n    else:\n      raise Exception('invalid job %s' % job_name)\n\n    if job is not None:\n      error = '' if job.fatal_error is None else str(job.fatal_error)\n      data = {'exists': True, 'done': job.is_complete, 'error': error}\n    else:\n      data = {'exists': False}\n\n  except Exception as e:\n    google.datalab.utils.print_exception_with_last_stack(e)\n    data = {'done': True, 'error': str(e)}\n\n  return IPython.core.display.JSON(data)\n"
  },
  {
    "path": "google/datalab/utils/commands/_utils.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Utility functions.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import unicode_literals\nfrom builtins import str\nfrom past.builtins import basestring\n\ntry:\n  import IPython\n  import IPython.core.display\nexcept ImportError:\n  raise Exception('This module can only be loaded in ipython.')\n\nimport json\nimport pandas\ntry:\n  # Pandas profiling is not needed for build/test but will be in the container.\n  import pandas_profiling\nexcept ImportError:\n  pass\nimport sys\nimport yaml\n\nimport google.datalab.data\nimport google.datalab.bigquery\nimport google.datalab.storage\nimport google.datalab.utils\n\nfrom . import _html\n\n\ndef notebook_environment():\n  \"\"\" Get the IPython user namespace. \"\"\"\n  ipy = IPython.get_ipython()\n  return ipy.user_ns\n\n\ndef get_notebook_item(name):\n  \"\"\" Get an item from the IPython environment. \"\"\"\n  env = notebook_environment()\n  return google.datalab.utils.get_item(env, name)\n\n\ndef render_list(data):\n  return IPython.core.display.HTML(_html.HtmlBuilder.render_list(data))\n\n\ndef render_dictionary(data, headers=None):\n  \"\"\" Return a dictionary list formatted as a HTML table.\n\n  Args:\n    data: the dictionary list\n    headers: the keys in the dictionary to use as table columns, in order.\n  \"\"\"\n  return IPython.core.display.HTML(_html.HtmlBuilder.render_table(data, headers))\n\n\ndef render_text(text, preformatted=False):\n  \"\"\" Return text formatted as a HTML\n\n  Args:\n    text: the text to render\n    preformatted: whether the text should be rendered as preformatted\n  \"\"\"\n  return IPython.core.display.HTML(_html.HtmlBuilder.render_text(text, preformatted))\n\n\ndef get_field_list(fields, schema):\n  \"\"\" Convert a field list spec into a real list of field names.\n\n      For tables, we return only the top-level non-RECORD fields as Google charts\n      can't handle nested data.\n  \"\"\"\n  # If the fields weren't supplied get them from the schema.\n  if schema:\n    all_fields = [f['name'] for f in schema._bq_schema if f['type'] != 'RECORD']\n\n  if isinstance(fields, list):\n    if schema:\n      # validate fields exist\n      for f in fields:\n        if f not in all_fields:\n          raise Exception('Cannot find field %s in given schema' % f)\n    return fields\n  if isinstance(fields, basestring) and fields != '*':\n    if schema:\n      # validate fields exist\n      for f in fields.split(','):\n        if f not in all_fields:\n          raise Exception('Cannot find field %s in given schema' % f)\n      return fields.split(',')\n  if not schema:\n    return []\n  return all_fields\n\n\ndef _get_cols(fields, schema):\n  \"\"\" Get column metadata for Google Charts based on field list and schema. \"\"\"\n  typemap = {\n    'STRING': 'string',\n    'INT64': 'number',\n    'INTEGER': 'number',\n    'FLOAT': 'number',\n    'FLOAT64': 'number',\n    'BOOL': 'boolean',\n    'BOOLEAN': 'boolean',\n    'DATE': 'date',\n    'TIME': 'timeofday',\n    'DATETIME': 'datetime',\n    'TIMESTAMP': 'timestamp'\n  }\n  cols = []\n  for col in fields:\n    if schema:\n      f = schema[col]\n      t = 'string' if f.mode == 'REPEATED' else typemap.get(f.type, 'string')\n      cols.append({'id': f.name, 'label': f.name, 'type': t})\n    else:\n      # This will only happen if we had no rows to infer a schema from, so the type\n      # is not really important, except that GCharts will choke if we pass such a schema\n      # to a chart if it is string x string so we default to number.\n      cols.append({'id': col, 'label': col, 'type': 'number'})\n  return cols\n\n\ndef _get_data_from_empty_list(source, fields='*', first_row=0, count=-1, schema=None):\n  \"\"\" Helper function for _get_data that handles empty lists. \"\"\"\n  fields = get_field_list(fields, schema)\n  return {'cols': _get_cols(fields, schema), 'rows': []}, 0\n\n\ndef _get_data_from_list_of_dicts(source, fields='*', first_row=0, count=-1, schema=None):\n  \"\"\" Helper function for _get_data that handles lists of dicts. \"\"\"\n  if schema is None:\n    schema = google.datalab.bigquery.Schema.from_data(source)\n  fields = get_field_list(fields, schema)\n  gen = source[first_row:first_row + count] if count >= 0 else source\n  rows = [{'c': [{'v': row[c]} if c in row else {} for c in fields]} for row in gen]\n  return {'cols': _get_cols(fields, schema), 'rows': rows}, len(source)\n\n\ndef _get_data_from_list_of_lists(source, fields='*', first_row=0, count=-1, schema=None):\n  \"\"\" Helper function for _get_data that handles lists of lists. \"\"\"\n  if schema is None:\n    schema = google.datalab.bigquery.Schema.from_data(source)\n  fields = get_field_list(fields, schema)\n  gen = source[first_row:first_row + count] if count >= 0 else source\n  cols = [schema.find(name) for name in fields]\n  rows = [{'c': [{'v': row[i]} for i in cols]} for row in gen]\n  return {'cols': _get_cols(fields, schema), 'rows': rows}, len(source)\n\n\ndef _get_data_from_dataframe(source, fields='*', first_row=0, count=-1, schema=None):\n  \"\"\" Helper function for _get_data that handles Pandas DataFrames. \"\"\"\n  if schema is None:\n    schema = google.datalab.bigquery.Schema.from_data(source)\n  fields = get_field_list(fields, schema)\n  rows = []\n  if count < 0:\n    count = len(source.index)\n  df_slice = source.reset_index(drop=True)[first_row:first_row + count]\n  for index, data_frame_row in df_slice.iterrows():\n    row = data_frame_row.to_dict()\n    for key in list(row.keys()):\n      val = row[key]\n      if isinstance(val, pandas.Timestamp):\n        row[key] = val.to_pydatetime()\n\n    rows.append({'c': [{'v': row[c]} if c in row else {} for c in fields]})\n  cols = _get_cols(fields, schema)\n  return {'cols': cols, 'rows': rows}, len(source)\n\n\ndef _get_data_from_table(source, fields='*', first_row=0, count=-1, schema=None):\n  \"\"\" Helper function for _get_data that handles BQ Tables. \"\"\"\n  if not source.exists():\n    return _get_data_from_empty_list(source, fields, first_row, count)\n  if schema is None:\n    schema = source.schema\n  fields = get_field_list(fields, schema)\n  gen = source.range(first_row, count) if count >= 0 else source\n  rows = [{'c': [{'v': row[c]} if c in row else {} for c in fields]} for row in gen]\n  return {'cols': _get_cols(fields, schema), 'rows': rows}, source.length\n\n\ndef get_data(source, fields='*', env=None, first_row=0, count=-1, schema=None):\n  \"\"\" A utility function to get a subset of data from a Table, Query, Pandas dataframe or List.\n\n  Args:\n    source: the source of the data. Can be a Table, Pandas DataFrame, List of dictionaries or\n        lists, or a string, in which case it is expected to be the name of a table in BQ.\n    fields: a list of fields that we want to return as a list of strings, comma-separated string,\n        or '*' for all.\n    env: if the data source is a Query module, this is the set of variable overrides for\n        parameterizing the Query.\n    first_row: the index of the first row to return; default 0. Onl;y used if count is non-negative.\n    count: the number or rows to return. If negative (the default), return all rows.\n    schema: the schema of the data. Optional; if supplied this can be used to help do type-coercion.\n\n  Returns:\n    A tuple consisting of a dictionary and a count; the dictionary has two entries: 'cols'\n    which is a list of column metadata entries for Google Charts, and 'rows' which is a list of\n    lists of values. The count is the total number of rows in the source (independent of the\n    first_row/count parameters).\n\n  Raises:\n    Exception if the request could not be fulfilled.\n  \"\"\"\n\n  ipy = IPython.get_ipython()\n  if env is None:\n    env = {}\n  env.update(ipy.user_ns)\n  if isinstance(source, basestring):\n    source = google.datalab.utils.get_item(ipy.user_ns, source, source)\n    if isinstance(source, basestring):\n      source = google.datalab.bigquery.Table(source)\n\n  if isinstance(source, list):\n    if len(source) == 0:\n      return _get_data_from_empty_list(source, fields, first_row, count, schema)\n    elif isinstance(source[0], dict):\n      return _get_data_from_list_of_dicts(source, fields, first_row, count, schema)\n    elif isinstance(source[0], list):\n      return _get_data_from_list_of_lists(source, fields, first_row, count, schema)\n    else:\n      raise Exception(\"To get tabular data from a list it must contain dictionaries or lists.\")\n  elif isinstance(source, pandas.DataFrame):\n    return _get_data_from_dataframe(source, fields, first_row, count, schema)\n  elif isinstance(source, google.datalab.bigquery.Query):\n    return _get_data_from_table(source.execute().result(), fields, first_row, count, schema)\n  elif isinstance(source, google.datalab.bigquery.Table):\n    return _get_data_from_table(source, fields, first_row, count, schema)\n  else:\n    raise Exception(\"Cannot chart %s; unsupported object type\" % source)\n\n\ndef handle_magic_line(line, cell, parser, namespace=None):\n  \"\"\" Helper function for handling magic command lines given a parser with handlers set. \"\"\"\n  try:\n    args, cell = parser.parse(line, cell, namespace)\n    if args:\n      return args['func'](args, cell)\n  except Exception as e:\n    # e.args[0] is 'exit_0' if --help is provided in line.\n    # In this case don't write anything to stderr.\n    if e.args and e.args[0] == 'exit_0':\n      return\n    sys.stderr.write('\\n' + str(e))\n    sys.stderr.flush()\n\n\ndef expand_var(v, env):\n  \"\"\" If v is a variable reference (for example: '$myvar'), replace it using the supplied\n      env dictionary.\n\n  Args:\n    v: the variable to replace if needed.\n    env: user supplied dictionary.\n\n  Raises:\n    Exception if v is a variable reference but it is not found in env.\n  \"\"\"\n  if len(v) == 0:\n    return v\n  # Using len() and v[0] instead of startswith makes this Unicode-safe.\n  if v[0] == '$':\n    v = v[1:]\n    if len(v) and v[0] != '$':\n      if v in env:\n        v = env[v]\n      else:\n        raise Exception('Cannot expand variable $%s' % v)\n  return v\n\n\ndef replace_vars(config, env):\n  \"\"\" Replace variable references in config using the supplied env dictionary.\n\n  Args:\n    config: the config to parse. Can be a tuple, list or dict.\n    env: user supplied dictionary.\n\n  Raises:\n    Exception if any variable references are not found in env.\n  \"\"\"\n  if isinstance(config, dict):\n    for k, v in list(config.items()):\n      if isinstance(v, dict) or isinstance(v, list) or isinstance(v, tuple):\n        replace_vars(v, env)\n      elif isinstance(v, basestring):\n        config[k] = expand_var(v, env)\n  elif isinstance(config, list):\n    for i, v in enumerate(config):\n      if isinstance(v, dict) or isinstance(v, list) or isinstance(v, tuple):\n        replace_vars(v, env)\n      elif isinstance(v, basestring):\n        config[i] = expand_var(v, env)\n  elif isinstance(config, tuple):\n    # TODO(gram): figure out how to handle these if the tuple elements are scalar\n    for v in config:\n      if isinstance(v, dict) or isinstance(v, list) or isinstance(v, tuple):\n        replace_vars(v, env)\n\n\ndef parse_config(config, env, as_dict=True):\n  \"\"\" Parse a config from a magic cell body. This could be JSON or YAML. We turn it into\n      a Python dictionary then recursively replace any variable references using the supplied\n      env dictionary.\n  \"\"\"\n\n  if config is None:\n    return None\n  stripped = config.strip()\n  if len(stripped) == 0:\n    config = {}\n  elif stripped[0] == '{':\n    config = json.loads(config)\n  else:\n    config = yaml.load(config)\n  if as_dict:\n    config = dict(config)\n\n  # Now we need to walk the config dictionary recursively replacing any '$name' vars.\n  replace_vars(config, env)\n  return config\n\n\ndef parse_config_for_selected_keys(content, keys):\n  \"\"\" Parse a config from a magic cell body for selected config keys.\n\n  For example, if 'content' is:\n    config_item1: value1\n    config_item2: value2\n    config_item3: value3\n  and 'keys' are: [config_item1, config_item3]\n\n  The results will be a tuple of\n  1. The parsed config items (dict): {config_item1: value1, config_item3: value3}\n  2. The remaining content (string): config_item2: value2\n\n  Args:\n    content: the input content. A string. It has to be a yaml or JSON string.\n    keys: a list of keys to retrieve from content. Note that it only checks top level keys\n        in the dict.\n\n  Returns:\n    A tuple. First is the parsed config including only selected keys. Second is\n      the remaining content.\n\n  Raises:\n    Exception if the content is not a valid yaml or JSON string.\n  \"\"\"\n\n  config_items = {key: None for key in keys}\n  if not content:\n    return config_items, content\n\n  stripped = content.strip()\n  if len(stripped) == 0:\n    return {}, None\n  elif stripped[0] == '{':\n    config = json.loads(content)\n  else:\n    config = yaml.load(content)\n\n  if not isinstance(config, dict):\n    raise ValueError('Invalid config.')\n\n  for key in keys:\n    config_items[key] = config.pop(key, None)\n\n  if not config:\n    return config_items, None\n\n  if stripped[0] == '{':\n    content_out = json.dumps(config, indent=4)\n  else:\n    content_out = yaml.dump(config, default_flow_style=False)\n\n  return config_items, content_out\n\n\ndef validate_config(config, required_keys, optional_keys=None):\n  \"\"\" Validate a config dictionary to make sure it includes all required keys\n      and does not include any unexpected keys.\n\n  Args:\n    config: the config to validate.\n    required_keys: the names of the keys that the config must have.\n    optional_keys: the names of the keys that the config can have.\n\n  Raises:\n    Exception if the config is not a dict or invalid.\n  \"\"\"\n  if optional_keys is None:\n    optional_keys = []\n  if not isinstance(config, dict):\n    raise Exception('config is not dict type')\n  invalid_keys = set(config) - set(required_keys + optional_keys)\n  if len(invalid_keys) > 0:\n    raise Exception('Invalid config with unexpected keys '\n                    '\"%s\"' % ', '.join(e for e in invalid_keys))\n  missing_keys = set(required_keys) - set(config)\n  if len(missing_keys) > 0:\n    raise Exception('Invalid config with missing keys \"%s\"' % ', '.join(missing_keys))\n\n\ndef validate_config_must_have(config, required_keys):\n  \"\"\" Validate a config dictionary to make sure it has all of the specified keys\n\n  Args:\n    config: the config to validate.\n    required_keys: the list of possible keys that config must include.\n\n  Raises:\n    Exception if the config does not have any of them.\n  \"\"\"\n  missing_keys = set(required_keys) - set(config)\n  if len(missing_keys) > 0:\n    raise Exception('Invalid config with missing keys \"%s\"' % ', '.join(missing_keys))\n\n\ndef validate_config_has_one_of(config, one_of_keys):\n  \"\"\" Validate a config dictionary to make sure it has one and only one\n      key in one_of_keys.\n\n  Args:\n    config: the config to validate.\n    one_of_keys: the list of possible keys that config can have one and only one.\n\n  Raises:\n    Exception if the config does not have any of them, or multiple of them.\n  \"\"\"\n  intersection = set(config).intersection(one_of_keys)\n  if len(intersection) > 1:\n    raise Exception('Only one of the values in \"%s\" is needed' % ', '.join(intersection))\n  if len(intersection) == 0:\n    raise Exception('One of the values in \"%s\" is needed' % ', '.join(one_of_keys))\n\n\ndef validate_config_value(value, possible_values):\n  \"\"\" Validate a config value to make sure it is one of the possible values.\n\n  Args:\n    value: the config value to validate.\n    possible_values: the possible values the value can be\n\n  Raises:\n    Exception if the value is not one of possible values.\n  \"\"\"\n  if value not in possible_values:\n    raise Exception('Invalid config value \"%s\". Possible values are '\n                    '%s' % (value, ', '.join(e for e in possible_values)))\n\n\n# For chart and table HTML viewers, we use a list of table names and reference\n# instead the indices in the HTML, so as not to include things like projectID, etc,\n# in the HTML.\n\n_data_sources = []\n\n\ndef get_data_source_index(name):\n  if name not in _data_sources:\n    _data_sources.append(name)\n  return _data_sources.index(name)\n\n\ndef validate_gcs_path(path, require_object):\n  \"\"\" Check whether a given path is a valid GCS path.\n\n  Args:\n    path: the config to check.\n    require_object: if True, the path has to be an object path but not bucket path.\n\n  Raises:\n    Exception if the path is invalid\n  \"\"\"\n  bucket, key = google.datalab.storage._bucket.parse_name(path)\n  if bucket is None:\n    raise Exception('Invalid GCS path \"%s\"' % path)\n  if require_object and key is None:\n    raise Exception('It appears the GCS path \"%s\" is a bucket path but not an object path' % path)\n\n\ndef parse_control_options(controls, variable_defaults=None):\n  \"\"\" Parse a set of control options.\n\n  Args:\n    controls: The dictionary of control options.\n    variable_defaults: If the controls are for a Query with variables, then this is the\n        default variable values defined in the Query module. The options in the controls\n        parameter can override these but if a variable has no 'value' property then we\n        fall back to these.\n\n  Returns:\n    - the HTML for the controls.\n    - the default values for the controls as a dict.\n    - the list of DIV IDs of the controls.\n\n  \"\"\"\n  controls_html = ''\n  control_defaults = {}\n  control_ids = []\n  div_id = _html.Html.next_id()\n  if variable_defaults is None:\n    variable_defaults = {}\n  for varname, control in list(controls.items()):\n    label = control.get('label', varname)\n    control_id = div_id + '__' + varname\n    control_ids.append(control_id)\n    value = control.get('value', variable_defaults.get(varname, None))\n    # The user should usually specify the type but we will default to 'textbox' for strings\n    # and 'set' for lists.\n    if isinstance(value, basestring):\n      type = 'textbox'\n    elif isinstance(value, list):\n      type = 'set'\n    else:\n      type = None\n    type = control.get('type', type)\n\n    if type == 'picker':\n      choices = control.get('choices', value)\n      if not isinstance(choices, list) or len(choices) == 0:\n        raise Exception('picker control must specify a nonempty set of choices')\n      if value is None:\n        value = choices[0]\n      choices_html = ''\n      for i, choice in enumerate(choices):\n        choices_html += \"<option value=\\\"%s\\\" %s>%s</option>\" % \\\n                        (choice, (\"selected=\\\"selected\\\"\" if choice == value else ''), choice)\n      control_html = \"{label}<select disabled id=\\\"{id}\\\">{choices}</select>\" \\\n          .format(label=label, id=control_id, choices=choices_html)\n    elif type == 'set':  # Multi-picker; implemented as checkboxes.\n      # TODO(gram): consider using \"name\" property of the control to group checkboxes. That\n      # way we can save the code of constructing and parsing control Ids with sequential\n      #  numbers in it. Multiple checkboxes can share the same name.\n      choices = control.get('choices', value)\n      if not isinstance(choices, list) or len(choices) == 0:\n        raise Exception('set control must specify a nonempty set of choices')\n      if value is None:\n        value = choices\n      choices_html = ''\n      control_ids[-1] = '%s:%d' % (control_id, len(choices))  # replace ID to include count.\n      for i, choice in enumerate(choices):\n        checked = choice in value\n        choice_id = '%s:%d' % (control_id, i)\n        # TODO(gram): we may want a 'Submit/Refresh button as we may not want to rerun\n        # query on each checkbox change.\n        choices_html += \"\"\"\n          <div>\n            <label>\n              <input type=\"checkbox\" id=\"{id}\" value=\"{choice}\" {checked} disabled>\n              {choice}\n            </label>\n          </div>\n        \"\"\".format(id=choice_id, choice=choice, checked=\"checked\" if checked else '')\n      control_html = \"{label}<div>{choices}</div>\".format(label=label, choices=choices_html)\n    elif type == 'checkbox':\n      control_html = \"\"\"\n            <label>\n              <input type=\"checkbox\" id=\"{id}\" {checked} disabled>\n              {label}\n            </label>\n        \"\"\".format(label=label, id=control_id, checked=\"checked\" if value else '')\n    elif type == 'slider':\n      min_ = control.get('min', None)\n      max_ = control.get('max', None)\n      if min_ is None or max_ is None:\n        raise Exception('slider control must specify a min and max value')\n      if max_ <= min_:\n        raise Exception('slider control must specify a min value less than max value')\n      step = control.get('step', 1 if isinstance(min_, int) and isinstance(max_, int)\n                         else (float(max_ - min_) / 10.0))\n      if value is None:\n        value = min_\n      control_html = \"\"\"\n        {label}\n        <input type=\"text\" class=\"gchart-slider_value\" id=\"{id}_value\" value=\"{value}\" disabled/>\n        <input type=\"range\" class=\"gchart-slider\" id=\"{id}\" min=\"{min}\" max=\"{max}\" step=\"{step}\"\n            value=\"{value}\" disabled/>\n      \"\"\".format(label=label, id=control_id, value=value, min=min_, max=max_, step=step)\n    elif type == 'textbox':\n      if value is None:\n        value = ''\n      control_html = \"{label}<input type=\\\"text\\\" value=\\\"{value}\\\" id=\\\"{id}\\\" disabled/>\" \\\n          .format(label=label, value=value, id=control_id)\n    else:\n      raise Exception(\n          'Unknown control type %s (expected picker, slider, checkbox, textbox or set)' % type)\n\n    control_defaults[varname] = value\n    controls_html += \"<div class=\\\"gchart-control\\\">{control}</div>\\n\" \\\n        .format(control=control_html)\n\n  controls_html = \"<div class=\\\"gchart-controls\\\">{controls}</div>\".format(controls=controls_html)\n  return controls_html, control_defaults, control_ids\n\n\ndef chart_html(driver_name, chart_type, source, chart_options=None, fields='*', refresh_interval=0,\n               refresh_data=None, control_defaults=None, control_ids=None, schema=None):\n  \"\"\" Return HTML for a chart.\n\n  Args:\n    driver_name: the name of the chart driver. Currently we support 'plotly' or 'gcharts'.\n    chart_type: string specifying type of chart.\n    source: the data source for the chart. Can be actual data (e.g. list) or the name of\n        a data source (e.g. the name of a query module).\n    chart_options: a dictionary of options for the chart. Can contain a 'controls' entry\n        specifying controls. Other entries are passed as JSON to Google Charts.\n    fields: the fields to chart. Can be '*' for all fields (only sensible if the columns are\n        ordered; e.g. a Query or list of lists, but not a list of dictionaries); otherwise a\n        string containing a comma-separated list of field names.\n    refresh_interval: a time in seconds after which the chart data will be refreshed. 0 if the\n        chart should not be refreshed (i.e. the data is static).\n    refresh_data: if the source is a list or other raw data, this is a YAML string containing\n        metadata needed to support calls to refresh (get_chart_data).\n    control_defaults: the default variable values for controls that are shared across charts\n        including this one.\n    control_ids: the DIV IDs for controls that are shared across charts including this one.\n    schema: an optional schema for the data; if not supplied one will be inferred.\n\n  Returns:\n    A string containing the HTML for the chart.\n\n  \"\"\"\n  div_id = _html.Html.next_id()\n  controls_html = ''\n  if control_defaults is None:\n    control_defaults = {}\n  if control_ids is None:\n    control_ids = []\n  if chart_options is not None and 'variables' in chart_options:\n    controls = chart_options['variables']\n    del chart_options['variables']  # Just to make sure GCharts doesn't see them.\n    controls_html, defaults, ids = parse_control_options(controls)\n    # We augment what we are passed so that in principle we can have controls that are\n    # shared by charts as well as controls that are specific to a chart.\n    control_defaults.update(defaults)\n    control_ids.extend(ids),\n\n  _HTML_TEMPLATE = \"\"\"\n    <div class=\"bqgc-container\">\n      {controls}\n      <div class=\"bqgc {extra_class}\" id=\"{id}\">\n      </div>\n    </div>\n    <script src=\"/static/components/requirejs/require.js\"></script>\n    <script>\n      require.config({{\n        paths: {{\n          base: '/static/base',\n          d3: '//cdnjs.cloudflare.com/ajax/libs/d3/3.4.13/d3',\n          plotly: 'https://cdn.plot.ly/plotly-1.5.1.min.js?noext',\n          jquery: '//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min'\n        }},\n        map: {{\n          '*': {{\n            datalab: 'nbextensions/gcpdatalab'\n          }}\n        }},\n        shim: {{\n          plotly: {{\n            deps: ['d3', 'jquery'],\n            exports: 'plotly'\n          }}\n        }}\n      }});\n\n      require(['datalab/charting',\n               'datalab/element!{id}',\n               'base/js/events',\n               'datalab/style!/nbextensions/gcpdatalab/charting.css'\n              ],\n        function(charts, dom, events) {{\n          charts.render(\n              '{driver}',\n              dom,\n              events,\n              '{chart_type}',\n              {control_ids},\n              {data},\n              {options},\n              {refresh_data},\n              {refresh_interval},\n              {total_rows});\n          }}\n        );\n    </script>\n  \"\"\"\n  count = 25 if chart_type == 'paged_table' else -1\n  data, total_count = get_data(source, fields, control_defaults, 0, count, schema)\n  if refresh_data is None:\n    if isinstance(source, basestring):\n      source_index = get_data_source_index(source)\n      refresh_data = {'source_index': source_index, 'name': source_index}\n    else:\n      refresh_data = {'name': 'raw data'}\n  refresh_data['fields'] = fields\n\n  # TODO(gram): check if we need to augment env with user_ns\n  return _HTML_TEMPLATE \\\n      .format(driver=driver_name,\n              controls=controls_html,\n              id=div_id,\n              chart_type=chart_type,\n              extra_class=\" bqgc-controlled\" if len(controls_html) else '',\n              data=json.dumps(data, cls=google.datalab.utils.JSONEncoder),\n              options=json.dumps(chart_options, cls=google.datalab.utils.JSONEncoder),\n              refresh_data=json.dumps(refresh_data, cls=google.datalab.utils.JSONEncoder),\n              refresh_interval=refresh_interval,\n              control_ids=str(control_ids),\n              total_rows=total_count)\n\n\ndef profile_df(df):\n  \"\"\" Generate a profile of data in a dataframe.\n\n  Args:\n    df: the Pandas dataframe.\n  \"\"\"\n  # The bootstrap CSS messes up the Datalab display so we tweak it to not have an effect.\n  # TODO(gram): strip it out rather than this kludge.\n  return IPython.core.display.HTML(\n      pandas_profiling.ProfileReport(df).html.replace('bootstrap', 'nonexistent'))\n"
  },
  {
    "path": "google/datalab/utils/facets/__init__.py",
    "content": "# Copyright 2017 Google Inc. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n# ==============================================================================\n\n# The files in this directory are copied from\n# https://github.com/PAIR-code/facets/tree/master/facets_overview/python\n"
  },
  {
    "path": "google/datalab/utils/facets/base_feature_statistics_generator.py",
    "content": "# Copyright 2017 Google Inc. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n# ==============================================================================\n\"\"\"Base class for generating the feature_statistics proto from TensorFlow data.\n\nThe proto is used as input for the Overview visualization.\n\"\"\"\n\n# flake8: noqa\n\nfrom functools import partial\nfrom .base_generic_feature_statistics_generator import BaseGenericFeatureStatisticsGenerator\nimport tensorflow as tf\n\n\n# The feature name used to track sequence length when analyzing\n# tf.SequenceExamples.\nSEQUENCE_LENGTH_FEATURE_NAME = 'sequence length (derived feature)'\n\n\nclass BaseFeatureStatisticsGenerator(BaseGenericFeatureStatisticsGenerator):\n  \"\"\"Base class for generator of stats proto from TF data.\"\"\"\n\n  def __init__(self, fs_proto, datasets_proto, histogram_proto):\n    BaseGenericFeatureStatisticsGenerator.__init__(\n        self, fs_proto, datasets_proto, histogram_proto)\n\n  def ProtoFromTfRecordFiles(self,\n                             files,\n                             max_entries=10000,\n                             features=None,\n                             is_sequence=False,\n                             iterator_options=None):\n    \"\"\"Creates a feature statistics proto from a set of TFRecord files.\n\n    Args:\n      files: A list of dicts describing files for each dataset for the proto.\n        Each\n          entry contains a 'path' field with the path to the TFRecord file on\n            disk\n          and a 'name' field to identify the dataset in the proto.\n      max_entries: The maximum number of examples to load from each dataset\n          in order to create the proto. Defaults to 10000.\n      features: A list of strings that is an allowlist of feature names to create\n          feature statistics for. If set to None then all features in the\n            dataset\n          are analyzed. Defaults to None.\n      is_sequence: True if the input data from 'tables' are tf.SequenceExamples,\n          False if tf.Examples. Defaults to false.\n      iterator_options: Options to pass to the iterator that reads the examples.\n          Defaults to None.\n\n    Returns:\n      The feature statistics proto for the provided files.\n    \"\"\"\n    datasets = []\n    for entry in files:\n      entries, size = self._GetTfRecordEntries(entry['path'], max_entries,\n                                               is_sequence, iterator_options)\n      datasets.append({'entries': entries, 'size': size, 'name': entry['name']})\n    return self.GetDatasetsProto(datasets, features)\n\n  def _ParseExample(self, example_features, example_feature_lists, entries,\n                    index):\n    \"\"\"Parses data from an example, populating a dictionary of feature values.\n\n    Args:\n      example_features: A map of strings to tf.Features from the example.\n      example_feature_lists: A map of strings to tf.FeatureLists from the\n        example.\n      entries: A dictionary of all features parsed thus far and arrays of their\n          values. This is mutated by the function.\n      index: The index of the example to parse from a list of examples.\n    Raises:\n      TypeError: Raises an exception when a feature has inconsistent types\n      across\n          examples.\n    \"\"\"\n    features_seen = set()\n\n    for feature_list, is_feature in zip(\n        [example_features, example_feature_lists], [True, False]):\n      sequence_length = None\n      for feature_name in feature_list:\n        # If this feature has not been seen in previous examples, then\n        # initialize its entry into the entries dictionary.\n        if feature_name not in entries:\n          entries[feature_name] = {\n              'vals': [],\n              'counts': [],\n              'feat_lens': [],\n              'missing': index\n          }\n\n        feature_entry = entries[feature_name]\n        feature = feature_list[feature_name]\n\n        value_type = None\n        value_list = []\n        if is_feature:\n          # If parsing a tf.Feature, extract the type and values simply.\n          if feature.HasField('float_list'):\n            value_list = feature.float_list.value\n            value_type = self.fs_proto.FLOAT\n          elif feature.HasField('bytes_list'):\n            value_list = feature.bytes_list.value\n            value_type = self.fs_proto.STRING\n          elif feature.HasField('int64_list'):\n            value_list = feature.int64_list.value\n            value_type = self.fs_proto.INT\n        else:\n          # If parsing a tf.FeatureList, get the type and values by iterating\n          # over all Features in the FeatureList.\n          sequence_length = len(feature.feature)\n          if sequence_length != 0 and feature.feature[0].HasField('float_list'):\n            for feat in feature.feature:\n              for value in feat.float_list.value:\n                value_list.append(value)\n            value_type = self.fs_proto.FLOAT\n          elif sequence_length != 0 and feature.feature[0].HasField(\n              'bytes_list'):\n            for feat in feature.feature:\n              for value in feat.bytes_list.value:\n                value_list.append(value)\n            value_type = self.fs_proto.STRING\n          elif sequence_length != 0 and feature.feature[0].HasField(\n              'int64_list'):\n            for feat in feature.feature:\n              for value in feat.int64_list.value:\n                value_list.append(value)\n            value_type = self.fs_proto.INT\n        if value_type is not None:\n          if 'type' not in feature_entry:\n            feature_entry['type'] = value_type\n          elif feature_entry['type'] != value_type:\n            raise TypeError('type mismatch for feature ' + feature_name)\n        feature_entry['counts'].append(len(value_list))\n        feature_entry['vals'].extend(value_list)\n        if sequence_length is not None:\n          feature_entry['feat_lens'].append(sequence_length)\n        if value_list:\n          features_seen.add(feature_name)\n\n    # For all previously-seen features not found in this example, update the\n    # feature's missing value.\n    for f in entries:\n      fv = entries[f]\n      if f not in features_seen:\n        fv['missing'] += 1\n\n  def _GetEntries(self,\n                  paths,\n                  max_entries,\n                  iterator_from_file,\n                  is_sequence=False):\n    \"\"\"Extracts examples into a dictionary of feature values.\n\n    Args:\n      paths: A list of the paths to the files to parse.\n      max_entries: The maximum number of examples to load.\n      iterator_from_file: A method that takes a file path string and returns an\n          iterator to the examples in that file.\n      is_sequence: True if the input data from 'iterator_from_file' are\n           tf.SequenceExamples, False if tf.Examples. Defaults to false.\n\n    Returns:\n      A tuple with two elements:\n          - A dictionary of all features parsed thus far and arrays of their\n            values.\n          - The number of examples parsed.\n    \"\"\"\n    entries = {}\n    index = 0\n    for filepath in paths:\n      reader = iterator_from_file(filepath)\n      for record in reader:\n        if is_sequence:\n          sequence_example = tf.train.SequenceExample.FromString(record)\n          self._ParseExample(sequence_example.context.feature,\n                             sequence_example.feature_lists.feature_list,\n                             entries, index)\n        else:\n          self._ParseExample(\n              tf.train.Example.FromString(record).features.feature, [], entries,\n              index)\n        index += 1\n        if index == max_entries:\n          return entries, index\n    return entries, index\n\n  def _GetTfRecordEntries(self, path, max_entries, is_sequence,\n                          iterator_options):\n    \"\"\"Extracts TFRecord examples into a dictionary of feature values.\n\n    Args:\n      path: The path to the TFRecord file(s).\n      max_entries: The maximum number of examples to load.\n      is_sequence: True if the input data from 'path' are tf.SequenceExamples,\n           False if tf.Examples. Defaults to false.\n      iterator_options: Options to pass to the iterator that reads the examples.\n          Defaults to None.\n\n    Returns:\n      A tuple with two elements:\n          - A dictionary of all features parsed thus far and arrays of their\n            values.\n          - The number of examples parsed.\n    \"\"\"\n    return self._GetEntries([path], max_entries,\n                            partial(\n                                tf.python_io.tf_record_iterator,\n                                options=iterator_options), is_sequence)\n"
  },
  {
    "path": "google/datalab/utils/facets/base_generic_feature_statistics_generator.py",
    "content": "# Copyright 2017 Google Inc. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n# ==============================================================================\n\n# flake8: noqa\n\n\"\"\"Base class for generating the feature_statistics proto from generic data.\n\nThe proto is used as input for the Overview visualization.\n\"\"\"\n\nimport numpy as np\nimport pandas as pd\n\n\nclass BaseGenericFeatureStatisticsGenerator(object):\n  \"\"\"Base class for generator of stats proto from generic data.\"\"\"\n\n  def __init__(self, fs_proto, datasets_proto, histogram_proto):\n    self.fs_proto = fs_proto\n    self.datasets_proto = datasets_proto\n    self.histogram_proto = histogram_proto\n\n  def ProtoFromDataFrames(self, dataframes):\n    \"\"\"Creates a feature statistics proto from a set of pandas dataframes.\n    Args:\n      dataframes: A list of dicts describing tables for each dataset for the\n          proto. Each entry contains a 'table' field of the dataframe of the\n            data\n          and a 'name' field to identify the dataset in the proto.\n    Returns:\n      The feature statistics proto for the provided tables.\n    \"\"\"\n    datasets = []\n    for dataframe in dataframes:\n      table = dataframe['table']\n      table_entries = {}\n      for col in table:\n        table_entries[col] = self.NdarrayToEntry(table[col])\n      datasets.append({\n          'entries': table_entries,\n          'size': len(table),\n          'name': dataframe['name']\n      })\n    return self.GetDatasetsProto(datasets)\n\n  def DtypeToType(self, dtype):\n    \"\"\"Converts a Numpy dtype to the FeatureNameStatistics.Type proto enum.\"\"\"\n    if dtype.char in np.typecodes['AllFloat']:\n      return self.fs_proto.FLOAT\n    elif (dtype.char in np.typecodes['AllInteger'] or dtype == np.bool or\n          np.issubdtype(dtype, np.datetime64) or\n          np.issubdtype(dtype, np.timedelta64)):\n      return self.fs_proto.INT\n    else:\n      return self.fs_proto.STRING\n\n  def DtypeToNumberConverter(self, dtype):\n    \"\"\"Converts a Numpy dtype to a converter method if applicable.\n      The converter method takes in a numpy array of objects of the provided\n      dtype\n      and returns a numpy array of the numbers backing that object for\n      statistical\n      analysis. Returns None if no converter is necessary.\n    Args:\n      dtype: The numpy dtype to make a converter for.\n    Returns:\n      The converter method or None.\n    \"\"\"\n    if np.issubdtype(dtype, np.datetime64):\n\n      def DatetimesToNumbers(dt_list):\n        return np.array([pd.Timestamp(dt).value for dt in dt_list])\n\n      return DatetimesToNumbers\n    elif np.issubdtype(dtype, np.timedelta64):\n\n      def TimedetlasToNumbers(td_list):\n        return np.array([pd.Timedelta(td).value for td in td_list])\n\n      return TimedetlasToNumbers\n    else:\n      return None\n\n  def NdarrayToEntry(self, x):\n    \"\"\"Converts an ndarray to the Entry format.\"\"\"\n    row_counts = []\n    for row in x:\n      try:\n        rc = np.count_nonzero(~np.isnan(row))\n        if rc != 0:\n          row_counts.append(rc)\n      except TypeError:\n        try:\n          row_counts.append(row.size)\n        except AttributeError:\n          row_counts.append(1)\n\n    data_type = self.DtypeToType(x.dtype)\n    converter = self.DtypeToNumberConverter(x.dtype)\n    flattened = x.ravel()\n    orig_size = len(flattened)\n\n    # Remove all None and nan values and count how many were removed.\n    flattened = flattened[flattened != np.array(None)]\n    if converter:\n      flattened = converter(flattened)\n    if data_type == self.fs_proto.STRING:\n      flattened_temp = []\n      for x in flattened:\n        try:\n          if str(x) != 'nan':\n            flattened_temp.append(x)\n        except UnicodeEncodeError:\n          if x.encode('utf-8') != 'nan':\n            flattened_temp.append(x)\n      flattened = flattened_temp\n    else:\n      flattened = flattened[~np.isnan(flattened)].tolist()\n    missing = orig_size - len(flattened)\n    return {\n        'vals': flattened,\n        'counts': row_counts,\n        'missing': missing,\n        'type': data_type\n    }\n\n  def GetDatasetsProto(self, datasets, features=None):\n    \"\"\"Generates the feature stats proto from dictionaries of feature values.\n    Args:\n      datasets: An array of dictionaries, one per dataset, each one containing:\n          - 'entries': The dictionary of features in the dataset from the parsed\n            examples.\n          - 'size': The number of examples parsed for the dataset.\n          - 'name': The name of the dataset.\n      features: A list of strings that is an allowlist of feature names to create\n          feature statistics for. If set to None then all features in the\n            dataset\n          are analyzed. Defaults to None.\n    Returns:\n      The feature statistics proto for the provided datasets.\n    \"\"\"\n    features_seen = set()\n    allowlist_features = set(features) if features else None\n    all_datasets = self.datasets_proto()\n\n    # TODO(jwexler): Add ability to generate weighted feature stats\n    # if there is a specified weight feature in the dataset.\n\n    # Initialize each dataset\n    for dataset in datasets:\n      all_datasets.datasets.add(\n          name=dataset['name'], num_examples=dataset['size'])\n    # This outer loop ensures that for each feature seen in any of the provided\n    # datasets, we check the feature once against all datasets.\n    for outer_dataset in datasets:\n      for key, value in outer_dataset['entries'].items():\n        # If we have a feature allowlist and this feature is not in the\n        # allowlist then do not process it.\n        # If we have processed this feature already, no need to do it again.\n        if ((allowlist_features and key not in allowlist_features) or\n            key in features_seen):\n          continue\n        features_seen.add(key)\n        # Default to type int if no type is found, so that the fact that all\n        # values are missing from this feature can be displayed.\n        feature_type = value['type'] if 'type' in value else self.fs_proto.INT\n        # Process the found feature for each dataset.\n        for j, dataset in enumerate(datasets):\n          feat = all_datasets.datasets[j].features.add(\n              type=feature_type, name=str(key))\n          value = dataset['entries'].get(key)\n          has_data = value is not None and (value['vals'].size != 0\n                                            if isinstance(\n                                                value['vals'], np.ndarray) else\n                                            value['vals'])\n          commonstats = None\n          # For numeric features, calculate numeric statistics.\n          if feat.type in (self.fs_proto.INT, self.fs_proto.FLOAT):\n            featstats = feat.num_stats\n            commonstats = featstats.common_stats\n            if has_data:\n              nums = value['vals']\n              featstats.std_dev = np.asscalar(np.std(nums))\n              featstats.mean = np.asscalar(np.mean(nums))\n              featstats.min = np.asscalar(np.min(nums))\n              featstats.max = np.asscalar(np.max(nums))\n              featstats.median = np.asscalar(np.median(nums))\n              featstats.num_zeros = len(nums) - np.count_nonzero(nums)\n\n              nums = np.array(nums)\n              num_nan = len(nums[np.isnan(nums)])\n              num_posinf = len(nums[np.isposinf(nums)])\n              num_neginf = len(nums[np.isneginf(nums)])\n\n              # Remove all non-finite (including NaN) values from the numeric\n              # values in order to calculate histogram buckets/counts. The\n              # inf values will be added back to the first and last buckets.\n              nums = nums[np.isfinite(nums)]\n              counts, buckets = np.histogram(nums)\n              hist = featstats.histograms.add()\n              hist.type = self.histogram_proto.STANDARD\n              hist.num_nan = num_nan\n              for bucket_count in range(len(counts)):\n                bucket = hist.buckets.add(\n                    low_value=buckets[bucket_count],\n                    high_value=buckets[bucket_count + 1],\n                    sample_count=np.asscalar(counts[bucket_count]))\n                # Add any negative or positive infinities to the first and last\n                # buckets in the histogram.\n                if bucket_count == 0 and num_neginf > 0:\n                  bucket.low_value = float('-inf')\n                  bucket.sample_count += num_neginf\n                elif bucket_count == len(counts) - 1 and num_posinf > 0:\n                  bucket.high_value = float('inf')\n                  bucket.sample_count += num_posinf\n              if not hist.buckets:\n                if num_neginf:\n                  hist.buckets.add(\n                      low_value=float('-inf'),\n                      high_value=float('-inf'),\n                      sample_count=num_neginf)\n                if num_posinf:\n                  hist.buckets.add(\n                      low_value=float('inf'),\n                      high_value=float('inf'),\n                      sample_count=num_posinf)\n              self._PopulateQuantilesHistogram(featstats.histograms.add(),\n                                               nums.tolist())\n          elif feat.type == self.fs_proto.STRING:\n            featstats = feat.string_stats\n            commonstats = featstats.common_stats\n            if has_data:\n              strs = []\n              for item in value['vals']:\n                strs.append(item if hasattr(item, '__len__') else str(item))\n\n              featstats.avg_length = np.mean(np.vectorize(len)(strs))\n              vals, counts = np.unique(strs, return_counts=True)\n              featstats.unique = len(vals)\n              sorted_vals = sorted(zip(counts, vals), reverse=True)\n              for val_index, val in enumerate(sorted_vals):\n                if val[1].dtype.type is np.str_:\n                  printable_val = val[1]\n                else:\n                  try:\n                    printable_val = val[1].decode('UTF-8', 'strict')\n                  except (UnicodeDecodeError, UnicodeEncodeError):\n                    printable_val = '__BYTES_VALUE__'\n                bucket = featstats.rank_histogram.buckets.add(\n                    low_rank=val_index,\n                    high_rank=val_index,\n                    sample_count=np.asscalar(val[0]),\n                    label=printable_val)\n                if val_index < 2:\n                  featstats.top_values.add(\n                      value=bucket.label, frequency=bucket.sample_count)\n          # Add the common stats regardless of the feature type.\n          if has_data:\n            commonstats.num_missing = value['missing']\n            commonstats.num_non_missing = (all_datasets.datasets[j].num_examples\n                                           - featstats.common_stats.num_missing)\n            commonstats.min_num_values = int(np.min(value['counts']).astype(int))\n            commonstats.max_num_values = int(np.max(value['counts']).astype(int))\n            commonstats.avg_num_values = np.mean(value['counts'])\n            if 'feat_lens' in value and value['feat_lens']:\n              self._PopulateQuantilesHistogram(\n                  commonstats.feature_list_length_histogram, value['feat_lens'])\n            self._PopulateQuantilesHistogram(commonstats.num_values_histogram,\n                                             value['counts'])\n          else:\n            commonstats.num_non_missing = 0\n            commonstats.num_missing = all_datasets.datasets[j].num_examples\n\n    return all_datasets\n\n  def _PopulateQuantilesHistogram(self, hist, nums):\n    \"\"\"Fills in the histogram with quantile information from the provided array.\n    Args:\n      hist: A Histogram proto message to fill in.\n      nums: A list of numbers to create a quantiles histogram from.\n    \"\"\"\n    if not nums:\n      return\n    num_quantile_buckets = 10\n    quantiles_to_get = [\n        x * 100 / num_quantile_buckets for x in range(num_quantile_buckets + 1)\n    ]\n    quantiles = np.percentile(nums, quantiles_to_get)\n    hist.type = self.histogram_proto.QUANTILES\n    quantiles_sample_count = float(len(nums)) / num_quantile_buckets\n    for low, high in zip(quantiles, quantiles[1:]):\n      hist.buckets.add(\n          low_value=low, high_value=high, sample_count=quantiles_sample_count)\n"
  },
  {
    "path": "google/datalab/utils/facets/feature_statistics_generator.py",
    "content": "# Copyright 2017 Google Inc. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n# ==============================================================================\n\"\"\"Class for generating the feature_statistics proto.\n\nThe proto is used as input for the Overview visualization.\n\"\"\"\n\nimport warnings\nfrom .base_feature_statistics_generator import BaseFeatureStatisticsGenerator\nfrom . import feature_statistics_pb2 as fs\n\n\nclass FeatureStatisticsGenerator(BaseFeatureStatisticsGenerator):\n  \"\"\"Generator of stats proto from TF data.\"\"\"\n\n  def __init__(self):\n    BaseFeatureStatisticsGenerator.__init__(self, fs.FeatureNameStatistics,\n                                            fs.DatasetFeatureStatisticsList,\n                                            fs.Histogram)\n\n\ndef ProtoFromTfRecordFiles(files,\n                           max_entries=10000,\n                           features=None,\n                           is_sequence=False,\n                           iterator_options=None):\n  \"\"\"Creates a feature statistics proto from a set of TFRecord files.\n\n  Args:\n    files: A list of dicts describing files for each dataset for the proto.\n      Each\n        entry contains a 'path' field with the path to the TFRecord file on\n          disk\n        and a 'name' field to identify the dataset in the proto.\n    max_entries: The maximum number of examples to load from each dataset\n        in order to create the proto. Defaults to 10000.\n    features: A list of strings that is a allowlist of feature names to create\n        feature statistics for. If set to None then all features in the\n          dataset\n        are analyzed. Defaults to None.\n    is_sequence: True if the input data from 'tables' are tf.SequenceExamples,\n        False if tf.Examples. Defaults to false.\n    iterator_options: Options to pass to the iterator that reads the examples.\n        Defaults to None.\n\n  Returns:\n    The feature statistics proto for the provided files.\n  \"\"\"\n  warnings.warn(\n      'Use GenericFeatureStatisticsGenerator class method instead.',\n      DeprecationWarning)\n  return FeatureStatisticsGenerator().ProtoFromTfRecordFiles(\n      files, max_entries, features, is_sequence, iterator_options)\n"
  },
  {
    "path": "google/datalab/utils/facets/feature_statistics_pb2.py",
    "content": "# Copyright 2017 Google Inc. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n# ==============================================================================\n# Generated by the protocol buffer compiler.  DO NOT EDIT!\n# source: feature_statistics.proto\n\n# flake8: noqa\n\nimport sys\n_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))\nfrom google.protobuf import descriptor as _descriptor\nfrom google.protobuf import message as _message\nfrom google.protobuf import reflection as _reflection\nfrom google.protobuf import symbol_database as _symbol_database\nfrom google.protobuf import descriptor_pb2\n# @@protoc_insertion_point(imports)\n\n_sym_db = _symbol_database.Default()\n\n\n\n\nDESCRIPTOR = _descriptor.FileDescriptor(\n  name='feature_statistics.proto',\n  package='featureStatistics',\n  syntax='proto3',\n  serialized_pb=_b('\\n\\x18\\x66\\x65\\x61ture_statistics.proto\\x12\\x11\\x66\\x65\\x61tureStatistics\\\"]\\n\\x1c\\x44\\x61tasetFeatureStatisticsList\\x12=\\n\\x08\\x64\\x61tasets\\x18\\x01 \\x03(\\x0b\\x32+.featureStatistics.DatasetFeatureStatistics\\\"\\x99\\x01\\n\\x18\\x44\\x61tasetFeatureStatistics\\x12\\x0c\\n\\x04name\\x18\\x01 \\x01(\\t\\x12\\x14\\n\\x0cnum_examples\\x18\\x02 \\x01(\\x04\\x12\\x1d\\n\\x15weighted_num_examples\\x18\\x04 \\x01(\\x01\\x12:\\n\\x08\\x66\\x65\\x61tures\\x18\\x03 \\x03(\\x0b\\x32(.featureStatistics.FeatureNameStatistics\\\"\\x8b\\x03\\n\\x15\\x46\\x65\\x61tureNameStatistics\\x12\\x0c\\n\\x04name\\x18\\x01 \\x01(\\t\\x12;\\n\\x04type\\x18\\x02 \\x01(\\x0e\\x32-.featureStatistics.FeatureNameStatistics.Type\\x12\\x39\\n\\tnum_stats\\x18\\x03 \\x01(\\x0b\\x32$.featureStatistics.NumericStatisticsH\\x00\\x12;\\n\\x0cstring_stats\\x18\\x04 \\x01(\\x0b\\x32#.featureStatistics.StringStatisticsH\\x00\\x12\\x39\\n\\x0b\\x62ytes_stats\\x18\\x05 \\x01(\\x0b\\x32\\\".featureStatistics.BytesStatisticsH\\x00\\x12\\x38\\n\\x0c\\x63ustom_stats\\x18\\x06 \\x03(\\x0b\\x32\\\".featureStatistics.CustomStatistic\\\"1\\n\\x04Type\\x12\\x07\\n\\x03INT\\x10\\x00\\x12\\t\\n\\x05\\x46LOAT\\x10\\x01\\x12\\n\\n\\x06STRING\\x10\\x02\\x12\\t\\n\\x05\\x42YTES\\x10\\x03\\x42\\x07\\n\\x05stats\\\"x\\n\\x18WeightedCommonStatistics\\x12\\x17\\n\\x0fnum_non_missing\\x18\\x01 \\x01(\\x01\\x12\\x13\\n\\x0bnum_missing\\x18\\x02 \\x01(\\x01\\x12\\x16\\n\\x0e\\x61vg_num_values\\x18\\x03 \\x01(\\x01\\x12\\x16\\n\\x0etot_num_values\\x18\\x04 \\x01(\\x01\\\"w\\n\\x0f\\x43ustomStatistic\\x12\\x0c\\n\\x04name\\x18\\x01 \\x01(\\t\\x12\\r\\n\\x03num\\x18\\x02 \\x01(\\x01H\\x00\\x12\\r\\n\\x03str\\x18\\x03 \\x01(\\tH\\x00\\x12\\x31\\n\\thistogram\\x18\\x04 \\x01(\\x0b\\x32\\x1c.featureStatistics.HistogramH\\x00\\x42\\x05\\n\\x03val\\\"\\xaa\\x02\\n\\x11NumericStatistics\\x12\\x39\\n\\x0c\\x63ommon_stats\\x18\\x01 \\x01(\\x0b\\x32#.featureStatistics.CommonStatistics\\x12\\x0c\\n\\x04mean\\x18\\x02 \\x01(\\x01\\x12\\x0f\\n\\x07std_dev\\x18\\x03 \\x01(\\x01\\x12\\x11\\n\\tnum_zeros\\x18\\x04 \\x01(\\x04\\x12\\x0b\\n\\x03min\\x18\\x05 \\x01(\\x01\\x12\\x0e\\n\\x06median\\x18\\x06 \\x01(\\x01\\x12\\x0b\\n\\x03max\\x18\\x07 \\x01(\\x01\\x12\\x30\\n\\nhistograms\\x18\\x08 \\x03(\\x0b\\x32\\x1c.featureStatistics.Histogram\\x12L\\n\\x16weighted_numeric_stats\\x18\\t \\x01(\\x0b\\x32,.featureStatistics.WeightedNumericStatistics\\\"\\x8c\\x03\\n\\x10StringStatistics\\x12\\x39\\n\\x0c\\x63ommon_stats\\x18\\x01 \\x01(\\x0b\\x32#.featureStatistics.CommonStatistics\\x12\\x0e\\n\\x06unique\\x18\\x02 \\x01(\\x04\\x12\\x44\\n\\ntop_values\\x18\\x03 \\x03(\\x0b\\x32\\x30.featureStatistics.StringStatistics.FreqAndValue\\x12\\x12\\n\\navg_length\\x18\\x04 \\x01(\\x02\\x12\\x38\\n\\x0erank_histogram\\x18\\x05 \\x01(\\x0b\\x32 .featureStatistics.RankHistogram\\x12J\\n\\x15weighted_string_stats\\x18\\x06 \\x01(\\x0b\\x32+.featureStatistics.WeightedStringStatistics\\x1aM\\n\\x0c\\x46reqAndValue\\x12\\x1b\\n\\x0f\\x64\\x65precated_freq\\x18\\x01 \\x01(\\x04\\x42\\x02\\x18\\x01\\x12\\r\\n\\x05value\\x18\\x02 \\x01(\\t\\x12\\x11\\n\\tfrequency\\x18\\x03 \\x01(\\x01\\\"|\\n\\x19WeightedNumericStatistics\\x12\\x0c\\n\\x04mean\\x18\\x01 \\x01(\\x01\\x12\\x0f\\n\\x07std_dev\\x18\\x02 \\x01(\\x01\\x12\\x0e\\n\\x06median\\x18\\x03 \\x01(\\x01\\x12\\x30\\n\\nhistograms\\x18\\x04 \\x03(\\x0b\\x32\\x1c.featureStatistics.Histogram\\\"\\x9a\\x01\\n\\x18WeightedStringStatistics\\x12\\x44\\n\\ntop_values\\x18\\x01 \\x03(\\x0b\\x32\\x30.featureStatistics.StringStatistics.FreqAndValue\\x12\\x38\\n\\x0erank_histogram\\x18\\x02 \\x01(\\x0b\\x32 .featureStatistics.RankHistogram\\\"\\xa1\\x01\\n\\x0f\\x42ytesStatistics\\x12\\x39\\n\\x0c\\x63ommon_stats\\x18\\x01 \\x01(\\x0b\\x32#.featureStatistics.CommonStatistics\\x12\\x0e\\n\\x06unique\\x18\\x02 \\x01(\\x04\\x12\\x15\\n\\ravg_num_bytes\\x18\\x03 \\x01(\\x02\\x12\\x15\\n\\rmin_num_bytes\\x18\\x04 \\x01(\\x02\\x12\\x15\\n\\rmax_num_bytes\\x18\\x05 \\x01(\\x02\\\"\\xed\\x02\\n\\x10\\x43ommonStatistics\\x12\\x17\\n\\x0fnum_non_missing\\x18\\x01 \\x01(\\x04\\x12\\x13\\n\\x0bnum_missing\\x18\\x02 \\x01(\\x04\\x12\\x16\\n\\x0emin_num_values\\x18\\x03 \\x01(\\x04\\x12\\x16\\n\\x0emax_num_values\\x18\\x04 \\x01(\\x04\\x12\\x16\\n\\x0e\\x61vg_num_values\\x18\\x05 \\x01(\\x02\\x12\\x16\\n\\x0etot_num_values\\x18\\x08 \\x01(\\x04\\x12:\\n\\x14num_values_histogram\\x18\\x06 \\x01(\\x0b\\x32\\x1c.featureStatistics.Histogram\\x12J\\n\\x15weighted_common_stats\\x18\\x07 \\x01(\\x0b\\x32+.featureStatistics.WeightedCommonStatistics\\x12\\x43\\n\\x1d\\x66\\x65\\x61ture_list_length_histogram\\x18\\t \\x01(\\x0b\\x32\\x1c.featureStatistics.Histogram\\\"\\xc4\\x02\\n\\tHistogram\\x12\\x0f\\n\\x07num_nan\\x18\\x01 \\x01(\\x04\\x12\\x15\\n\\rnum_undefined\\x18\\x02 \\x01(\\x04\\x12\\x34\\n\\x07\\x62uckets\\x18\\x03 \\x03(\\x0b\\x32#.featureStatistics.Histogram.Bucket\\x12\\x38\\n\\x04type\\x18\\x04 \\x01(\\x0e\\x32*.featureStatistics.Histogram.HistogramType\\x12\\x0c\\n\\x04name\\x18\\x05 \\x01(\\t\\x1a\\x63\\n\\x06\\x42ucket\\x12\\x11\\n\\tlow_value\\x18\\x01 \\x01(\\x01\\x12\\x12\\n\\nhigh_value\\x18\\x02 \\x01(\\x01\\x12\\x1c\\n\\x10\\x64\\x65precated_count\\x18\\x03 \\x01(\\x04\\x42\\x02\\x18\\x01\\x12\\x14\\n\\x0csample_count\\x18\\x04 \\x01(\\x01\\\",\\n\\rHistogramType\\x12\\x0c\\n\\x08STANDARD\\x10\\x00\\x12\\r\\n\\tQUANTILES\\x10\\x01\\\"\\xc9\\x01\\n\\rRankHistogram\\x12\\x38\\n\\x07\\x62uckets\\x18\\x01 \\x03(\\x0b\\x32\\'.featureStatistics.RankHistogram.Bucket\\x12\\x0c\\n\\x04name\\x18\\x02 \\x01(\\t\\x1ap\\n\\x06\\x42ucket\\x12\\x10\\n\\x08low_rank\\x18\\x01 \\x01(\\x04\\x12\\x11\\n\\thigh_rank\\x18\\x02 \\x01(\\x04\\x12\\x1c\\n\\x10\\x64\\x65precated_count\\x18\\x03 \\x01(\\x04\\x42\\x02\\x18\\x01\\x12\\r\\n\\x05label\\x18\\x04 \\x01(\\t\\x12\\x14\\n\\x0csample_count\\x18\\x05 \\x01(\\x01\\x62\\x06proto3')\n)\n\n\n\n_FEATURENAMESTATISTICS_TYPE = _descriptor.EnumDescriptor(\n  name='Type',\n  full_name='featureStatistics.FeatureNameStatistics.Type',\n  filename=None,\n  file=DESCRIPTOR,\n  values=[\n    _descriptor.EnumValueDescriptor(\n      name='INT', index=0, number=0,\n      options=None,\n      type=None),\n    _descriptor.EnumValueDescriptor(\n      name='FLOAT', index=1, number=1,\n      options=None,\n      type=None),\n    _descriptor.EnumValueDescriptor(\n      name='STRING', index=2, number=2,\n      options=None,\n      type=None),\n    _descriptor.EnumValueDescriptor(\n      name='BYTES', index=3, number=3,\n      options=None,\n      type=None),\n  ],\n  containing_type=None,\n  options=None,\n  serialized_start=636,\n  serialized_end=685,\n)\n_sym_db.RegisterEnumDescriptor(_FEATURENAMESTATISTICS_TYPE)\n\n_HISTOGRAM_HISTOGRAMTYPE = _descriptor.EnumDescriptor(\n  name='HistogramType',\n  full_name='featureStatistics.Histogram.HistogramType',\n  filename=None,\n  file=DESCRIPTOR,\n  values=[\n    _descriptor.EnumValueDescriptor(\n      name='STANDARD', index=0, number=0,\n      options=None,\n      type=None),\n    _descriptor.EnumValueDescriptor(\n      name='QUANTILES', index=1, number=1,\n      options=None,\n      type=None),\n  ],\n  containing_type=None,\n  options=None,\n  serialized_start=2735,\n  serialized_end=2779,\n)\n_sym_db.RegisterEnumDescriptor(_HISTOGRAM_HISTOGRAMTYPE)\n\n\n_DATASETFEATURESTATISTICSLIST = _descriptor.Descriptor(\n  name='DatasetFeatureStatisticsList',\n  full_name='featureStatistics.DatasetFeatureStatisticsList',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='datasets', full_name='featureStatistics.DatasetFeatureStatisticsList.datasets', index=0,\n      number=1, type=11, cpp_type=10, label=3,\n      has_default_value=False, default_value=[],\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=47,\n  serialized_end=140,\n)\n\n\n_DATASETFEATURESTATISTICS = _descriptor.Descriptor(\n  name='DatasetFeatureStatistics',\n  full_name='featureStatistics.DatasetFeatureStatistics',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='name', full_name='featureStatistics.DatasetFeatureStatistics.name', index=0,\n      number=1, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n    _descriptor.FieldDescriptor(\n      name='num_examples', full_name='featureStatistics.DatasetFeatureStatistics.num_examples', index=1,\n      number=2, type=4, cpp_type=4, label=1,\n      has_default_value=False, default_value=0,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n    _descriptor.FieldDescriptor(\n      name='weighted_num_examples', full_name='featureStatistics.DatasetFeatureStatistics.weighted_num_examples', index=2,\n      number=4, type=1, cpp_type=5, label=1,\n      has_default_value=False, default_value=float(0),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n    _descriptor.FieldDescriptor(\n      name='features', full_name='featureStatistics.DatasetFeatureStatistics.features', index=3,\n      number=3, type=11, cpp_type=10, label=3,\n      has_default_value=False, default_value=[],\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=143,\n  serialized_end=296,\n)\n\n\n_FEATURENAMESTATISTICS = _descriptor.Descriptor(\n  name='FeatureNameStatistics',\n  full_name='featureStatistics.FeatureNameStatistics',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='name', full_name='featureStatistics.FeatureNameStatistics.name', index=0,\n      number=1, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n    _descriptor.FieldDescriptor(\n      name='type', full_name='featureStatistics.FeatureNameStatistics.type', index=1,\n      number=2, type=14, cpp_type=8, label=1,\n      has_default_value=False, default_value=0,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n    _descriptor.FieldDescriptor(\n      name='num_stats', full_name='featureStatistics.FeatureNameStatistics.num_stats', index=2,\n      number=3, type=11, cpp_type=10, label=1,\n      has_default_value=False, default_value=None,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n    _descriptor.FieldDescriptor(\n      name='string_stats', full_name='featureStatistics.FeatureNameStatistics.string_stats', index=3,\n      number=4, type=11, cpp_type=10, label=1,\n      has_default_value=False, default_value=None,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n    _descriptor.FieldDescriptor(\n      name='bytes_stats', full_name='featureStatistics.FeatureNameStatistics.bytes_stats', index=4,\n      number=5, type=11, cpp_type=10, label=1,\n      has_default_value=False, default_value=None,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n    _descriptor.FieldDescriptor(\n      name='custom_stats', full_name='featureStatistics.FeatureNameStatistics.custom_stats', index=5,\n      number=6, type=11, cpp_type=10, label=3,\n      has_default_value=False, default_value=[],\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n    _FEATURENAMESTATISTICS_TYPE,\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n    _descriptor.OneofDescriptor(\n      name='stats', full_name='featureStatistics.FeatureNameStatistics.stats',\n      index=0, containing_type=None, fields=[]),\n  ],\n  serialized_start=299,\n  serialized_end=694,\n)\n\n\n_WEIGHTEDCOMMONSTATISTICS = _descriptor.Descriptor(\n  name='WeightedCommonStatistics',\n  full_name='featureStatistics.WeightedCommonStatistics',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='num_non_missing', full_name='featureStatistics.WeightedCommonStatistics.num_non_missing', index=0,\n      number=1, type=1, cpp_type=5, label=1,\n      has_default_value=False, default_value=float(0),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n    _descriptor.FieldDescriptor(\n      name='num_missing', full_name='featureStatistics.WeightedCommonStatistics.num_missing', index=1,\n      number=2, type=1, cpp_type=5, label=1,\n      has_default_value=False, default_value=float(0),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n    _descriptor.FieldDescriptor(\n      name='avg_num_values', full_name='featureStatistics.WeightedCommonStatistics.avg_num_values', index=2,\n      number=3, type=1, cpp_type=5, label=1,\n      has_default_value=False, default_value=float(0),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n    _descriptor.FieldDescriptor(\n      name='tot_num_values', full_name='featureStatistics.WeightedCommonStatistics.tot_num_values', index=3,\n      number=4, type=1, cpp_type=5, label=1,\n      has_default_value=False, default_value=float(0),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=696,\n  serialized_end=816,\n)\n\n\n_CUSTOMSTATISTIC = _descriptor.Descriptor(\n  name='CustomStatistic',\n  full_name='featureStatistics.CustomStatistic',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='name', full_name='featureStatistics.CustomStatistic.name', index=0,\n      number=1, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n    _descriptor.FieldDescriptor(\n      name='num', full_name='featureStatistics.CustomStatistic.num', index=1,\n      number=2, type=1, cpp_type=5, label=1,\n      has_default_value=False, default_value=float(0),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n    _descriptor.FieldDescriptor(\n      name='str', full_name='featureStatistics.CustomStatistic.str', index=2,\n      number=3, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n    _descriptor.FieldDescriptor(\n      name='histogram', full_name='featureStatistics.CustomStatistic.histogram', index=3,\n      number=4, type=11, cpp_type=10, label=1,\n      has_default_value=False, default_value=None,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n    _descriptor.OneofDescriptor(\n      name='val', full_name='featureStatistics.CustomStatistic.val',\n      index=0, containing_type=None, fields=[]),\n  ],\n  serialized_start=818,\n  serialized_end=937,\n)\n\n\n_NUMERICSTATISTICS = _descriptor.Descriptor(\n  name='NumericStatistics',\n  full_name='featureStatistics.NumericStatistics',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='common_stats', full_name='featureStatistics.NumericStatistics.common_stats', index=0,\n      number=1, type=11, cpp_type=10, label=1,\n      has_default_value=False, default_value=None,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n    _descriptor.FieldDescriptor(\n      name='mean', full_name='featureStatistics.NumericStatistics.mean', index=1,\n      number=2, type=1, cpp_type=5, label=1,\n      has_default_value=False, default_value=float(0),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n    _descriptor.FieldDescriptor(\n      name='std_dev', full_name='featureStatistics.NumericStatistics.std_dev', index=2,\n      number=3, type=1, cpp_type=5, label=1,\n      has_default_value=False, default_value=float(0),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n    _descriptor.FieldDescriptor(\n      name='num_zeros', full_name='featureStatistics.NumericStatistics.num_zeros', index=3,\n      number=4, type=4, cpp_type=4, label=1,\n      has_default_value=False, default_value=0,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n    _descriptor.FieldDescriptor(\n      name='min', full_name='featureStatistics.NumericStatistics.min', index=4,\n      number=5, type=1, cpp_type=5, label=1,\n      has_default_value=False, default_value=float(0),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n    _descriptor.FieldDescriptor(\n      name='median', full_name='featureStatistics.NumericStatistics.median', index=5,\n      number=6, type=1, cpp_type=5, label=1,\n      has_default_value=False, default_value=float(0),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n    _descriptor.FieldDescriptor(\n      name='max', full_name='featureStatistics.NumericStatistics.max', index=6,\n      number=7, type=1, cpp_type=5, label=1,\n      has_default_value=False, default_value=float(0),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n    _descriptor.FieldDescriptor(\n      name='histograms', full_name='featureStatistics.NumericStatistics.histograms', index=7,\n      number=8, type=11, cpp_type=10, label=3,\n      has_default_value=False, default_value=[],\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n    _descriptor.FieldDescriptor(\n      name='weighted_numeric_stats', full_name='featureStatistics.NumericStatistics.weighted_numeric_stats', index=8,\n      number=9, type=11, cpp_type=10, label=1,\n      has_default_value=False, default_value=None,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=940,\n  serialized_end=1238,\n)\n\n\n_STRINGSTATISTICS_FREQANDVALUE = _descriptor.Descriptor(\n  name='FreqAndValue',\n  full_name='featureStatistics.StringStatistics.FreqAndValue',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='deprecated_freq', full_name='featureStatistics.StringStatistics.FreqAndValue.deprecated_freq', index=0,\n      number=1, type=4, cpp_type=4, label=1,\n      has_default_value=False, default_value=0,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\\030\\001'))),\n    _descriptor.FieldDescriptor(\n      name='value', full_name='featureStatistics.StringStatistics.FreqAndValue.value', index=1,\n      number=2, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n    _descriptor.FieldDescriptor(\n      name='frequency', full_name='featureStatistics.StringStatistics.FreqAndValue.frequency', index=2,\n      number=3, type=1, cpp_type=5, label=1,\n      has_default_value=False, default_value=float(0),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=1560,\n  serialized_end=1637,\n)\n\n_STRINGSTATISTICS = _descriptor.Descriptor(\n  name='StringStatistics',\n  full_name='featureStatistics.StringStatistics',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='common_stats', full_name='featureStatistics.StringStatistics.common_stats', index=0,\n      number=1, type=11, cpp_type=10, label=1,\n      has_default_value=False, default_value=None,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n    _descriptor.FieldDescriptor(\n      name='unique', full_name='featureStatistics.StringStatistics.unique', index=1,\n      number=2, type=4, cpp_type=4, label=1,\n      has_default_value=False, default_value=0,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n    _descriptor.FieldDescriptor(\n      name='top_values', full_name='featureStatistics.StringStatistics.top_values', index=2,\n      number=3, type=11, cpp_type=10, label=3,\n      has_default_value=False, default_value=[],\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n    _descriptor.FieldDescriptor(\n      name='avg_length', full_name='featureStatistics.StringStatistics.avg_length', index=3,\n      number=4, type=2, cpp_type=6, label=1,\n      has_default_value=False, default_value=float(0),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n    _descriptor.FieldDescriptor(\n      name='rank_histogram', full_name='featureStatistics.StringStatistics.rank_histogram', index=4,\n      number=5, type=11, cpp_type=10, label=1,\n      has_default_value=False, default_value=None,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n    _descriptor.FieldDescriptor(\n      name='weighted_string_stats', full_name='featureStatistics.StringStatistics.weighted_string_stats', index=5,\n      number=6, type=11, cpp_type=10, label=1,\n      has_default_value=False, default_value=None,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n  ],\n  extensions=[\n  ],\n  nested_types=[_STRINGSTATISTICS_FREQANDVALUE, ],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=1241,\n  serialized_end=1637,\n)\n\n\n_WEIGHTEDNUMERICSTATISTICS = _descriptor.Descriptor(\n  name='WeightedNumericStatistics',\n  full_name='featureStatistics.WeightedNumericStatistics',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='mean', full_name='featureStatistics.WeightedNumericStatistics.mean', index=0,\n      number=1, type=1, cpp_type=5, label=1,\n      has_default_value=False, default_value=float(0),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n    _descriptor.FieldDescriptor(\n      name='std_dev', full_name='featureStatistics.WeightedNumericStatistics.std_dev', index=1,\n      number=2, type=1, cpp_type=5, label=1,\n      has_default_value=False, default_value=float(0),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n    _descriptor.FieldDescriptor(\n      name='median', full_name='featureStatistics.WeightedNumericStatistics.median', index=2,\n      number=3, type=1, cpp_type=5, label=1,\n      has_default_value=False, default_value=float(0),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n    _descriptor.FieldDescriptor(\n      name='histograms', full_name='featureStatistics.WeightedNumericStatistics.histograms', index=3,\n      number=4, type=11, cpp_type=10, label=3,\n      has_default_value=False, default_value=[],\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=1639,\n  serialized_end=1763,\n)\n\n\n_WEIGHTEDSTRINGSTATISTICS = _descriptor.Descriptor(\n  name='WeightedStringStatistics',\n  full_name='featureStatistics.WeightedStringStatistics',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='top_values', full_name='featureStatistics.WeightedStringStatistics.top_values', index=0,\n      number=1, type=11, cpp_type=10, label=3,\n      has_default_value=False, default_value=[],\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n    _descriptor.FieldDescriptor(\n      name='rank_histogram', full_name='featureStatistics.WeightedStringStatistics.rank_histogram', index=1,\n      number=2, type=11, cpp_type=10, label=1,\n      has_default_value=False, default_value=None,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=1766,\n  serialized_end=1920,\n)\n\n\n_BYTESSTATISTICS = _descriptor.Descriptor(\n  name='BytesStatistics',\n  full_name='featureStatistics.BytesStatistics',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='common_stats', full_name='featureStatistics.BytesStatistics.common_stats', index=0,\n      number=1, type=11, cpp_type=10, label=1,\n      has_default_value=False, default_value=None,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n    _descriptor.FieldDescriptor(\n      name='unique', full_name='featureStatistics.BytesStatistics.unique', index=1,\n      number=2, type=4, cpp_type=4, label=1,\n      has_default_value=False, default_value=0,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n    _descriptor.FieldDescriptor(\n      name='avg_num_bytes', full_name='featureStatistics.BytesStatistics.avg_num_bytes', index=2,\n      number=3, type=2, cpp_type=6, label=1,\n      has_default_value=False, default_value=float(0),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n    _descriptor.FieldDescriptor(\n      name='min_num_bytes', full_name='featureStatistics.BytesStatistics.min_num_bytes', index=3,\n      number=4, type=2, cpp_type=6, label=1,\n      has_default_value=False, default_value=float(0),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n    _descriptor.FieldDescriptor(\n      name='max_num_bytes', full_name='featureStatistics.BytesStatistics.max_num_bytes', index=4,\n      number=5, type=2, cpp_type=6, label=1,\n      has_default_value=False, default_value=float(0),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=1923,\n  serialized_end=2084,\n)\n\n\n_COMMONSTATISTICS = _descriptor.Descriptor(\n  name='CommonStatistics',\n  full_name='featureStatistics.CommonStatistics',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='num_non_missing', full_name='featureStatistics.CommonStatistics.num_non_missing', index=0,\n      number=1, type=4, cpp_type=4, label=1,\n      has_default_value=False, default_value=0,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n    _descriptor.FieldDescriptor(\n      name='num_missing', full_name='featureStatistics.CommonStatistics.num_missing', index=1,\n      number=2, type=4, cpp_type=4, label=1,\n      has_default_value=False, default_value=0,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n    _descriptor.FieldDescriptor(\n      name='min_num_values', full_name='featureStatistics.CommonStatistics.min_num_values', index=2,\n      number=3, type=4, cpp_type=4, label=1,\n      has_default_value=False, default_value=0,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n    _descriptor.FieldDescriptor(\n      name='max_num_values', full_name='featureStatistics.CommonStatistics.max_num_values', index=3,\n      number=4, type=4, cpp_type=4, label=1,\n      has_default_value=False, default_value=0,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n    _descriptor.FieldDescriptor(\n      name='avg_num_values', full_name='featureStatistics.CommonStatistics.avg_num_values', index=4,\n      number=5, type=2, cpp_type=6, label=1,\n      has_default_value=False, default_value=float(0),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n    _descriptor.FieldDescriptor(\n      name='tot_num_values', full_name='featureStatistics.CommonStatistics.tot_num_values', index=5,\n      number=8, type=4, cpp_type=4, label=1,\n      has_default_value=False, default_value=0,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n    _descriptor.FieldDescriptor(\n      name='num_values_histogram', full_name='featureStatistics.CommonStatistics.num_values_histogram', index=6,\n      number=6, type=11, cpp_type=10, label=1,\n      has_default_value=False, default_value=None,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n    _descriptor.FieldDescriptor(\n      name='weighted_common_stats', full_name='featureStatistics.CommonStatistics.weighted_common_stats', index=7,\n      number=7, type=11, cpp_type=10, label=1,\n      has_default_value=False, default_value=None,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n    _descriptor.FieldDescriptor(\n      name='feature_list_length_histogram', full_name='featureStatistics.CommonStatistics.feature_list_length_histogram', index=8,\n      number=9, type=11, cpp_type=10, label=1,\n      has_default_value=False, default_value=None,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=2087,\n  serialized_end=2452,\n)\n\n\n_HISTOGRAM_BUCKET = _descriptor.Descriptor(\n  name='Bucket',\n  full_name='featureStatistics.Histogram.Bucket',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='low_value', full_name='featureStatistics.Histogram.Bucket.low_value', index=0,\n      number=1, type=1, cpp_type=5, label=1,\n      has_default_value=False, default_value=float(0),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n    _descriptor.FieldDescriptor(\n      name='high_value', full_name='featureStatistics.Histogram.Bucket.high_value', index=1,\n      number=2, type=1, cpp_type=5, label=1,\n      has_default_value=False, default_value=float(0),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n    _descriptor.FieldDescriptor(\n      name='deprecated_count', full_name='featureStatistics.Histogram.Bucket.deprecated_count', index=2,\n      number=3, type=4, cpp_type=4, label=1,\n      has_default_value=False, default_value=0,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\\030\\001'))),\n    _descriptor.FieldDescriptor(\n      name='sample_count', full_name='featureStatistics.Histogram.Bucket.sample_count', index=3,\n      number=4, type=1, cpp_type=5, label=1,\n      has_default_value=False, default_value=float(0),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=2634,\n  serialized_end=2733,\n)\n\n_HISTOGRAM = _descriptor.Descriptor(\n  name='Histogram',\n  full_name='featureStatistics.Histogram',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='num_nan', full_name='featureStatistics.Histogram.num_nan', index=0,\n      number=1, type=4, cpp_type=4, label=1,\n      has_default_value=False, default_value=0,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n    _descriptor.FieldDescriptor(\n      name='num_undefined', full_name='featureStatistics.Histogram.num_undefined', index=1,\n      number=2, type=4, cpp_type=4, label=1,\n      has_default_value=False, default_value=0,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n    _descriptor.FieldDescriptor(\n      name='buckets', full_name='featureStatistics.Histogram.buckets', index=2,\n      number=3, type=11, cpp_type=10, label=3,\n      has_default_value=False, default_value=[],\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n    _descriptor.FieldDescriptor(\n      name='type', full_name='featureStatistics.Histogram.type', index=3,\n      number=4, type=14, cpp_type=8, label=1,\n      has_default_value=False, default_value=0,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n    _descriptor.FieldDescriptor(\n      name='name', full_name='featureStatistics.Histogram.name', index=4,\n      number=5, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n  ],\n  extensions=[\n  ],\n  nested_types=[_HISTOGRAM_BUCKET, ],\n  enum_types=[\n    _HISTOGRAM_HISTOGRAMTYPE,\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=2455,\n  serialized_end=2779,\n)\n\n\n_RANKHISTOGRAM_BUCKET = _descriptor.Descriptor(\n  name='Bucket',\n  full_name='featureStatistics.RankHistogram.Bucket',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='low_rank', full_name='featureStatistics.RankHistogram.Bucket.low_rank', index=0,\n      number=1, type=4, cpp_type=4, label=1,\n      has_default_value=False, default_value=0,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n    _descriptor.FieldDescriptor(\n      name='high_rank', full_name='featureStatistics.RankHistogram.Bucket.high_rank', index=1,\n      number=2, type=4, cpp_type=4, label=1,\n      has_default_value=False, default_value=0,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n    _descriptor.FieldDescriptor(\n      name='deprecated_count', full_name='featureStatistics.RankHistogram.Bucket.deprecated_count', index=2,\n      number=3, type=4, cpp_type=4, label=1,\n      has_default_value=False, default_value=0,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\\030\\001'))),\n    _descriptor.FieldDescriptor(\n      name='label', full_name='featureStatistics.RankHistogram.Bucket.label', index=3,\n      number=4, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n    _descriptor.FieldDescriptor(\n      name='sample_count', full_name='featureStatistics.RankHistogram.Bucket.sample_count', index=4,\n      number=5, type=1, cpp_type=5, label=1,\n      has_default_value=False, default_value=float(0),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=2871,\n  serialized_end=2983,\n)\n\n_RANKHISTOGRAM = _descriptor.Descriptor(\n  name='RankHistogram',\n  full_name='featureStatistics.RankHistogram',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='buckets', full_name='featureStatistics.RankHistogram.buckets', index=0,\n      number=1, type=11, cpp_type=10, label=3,\n      has_default_value=False, default_value=[],\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n    _descriptor.FieldDescriptor(\n      name='name', full_name='featureStatistics.RankHistogram.name', index=1,\n      number=2, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None),\n  ],\n  extensions=[\n  ],\n  nested_types=[_RANKHISTOGRAM_BUCKET, ],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=2782,\n  serialized_end=2983,\n)\n\n_DATASETFEATURESTATISTICSLIST.fields_by_name['datasets'].message_type = _DATASETFEATURESTATISTICS\n_DATASETFEATURESTATISTICS.fields_by_name['features'].message_type = _FEATURENAMESTATISTICS\n_FEATURENAMESTATISTICS.fields_by_name['type'].enum_type = _FEATURENAMESTATISTICS_TYPE\n_FEATURENAMESTATISTICS.fields_by_name['num_stats'].message_type = _NUMERICSTATISTICS\n_FEATURENAMESTATISTICS.fields_by_name['string_stats'].message_type = _STRINGSTATISTICS\n_FEATURENAMESTATISTICS.fields_by_name['bytes_stats'].message_type = _BYTESSTATISTICS\n_FEATURENAMESTATISTICS.fields_by_name['custom_stats'].message_type = _CUSTOMSTATISTIC\n_FEATURENAMESTATISTICS_TYPE.containing_type = _FEATURENAMESTATISTICS\n_FEATURENAMESTATISTICS.oneofs_by_name['stats'].fields.append(\n  _FEATURENAMESTATISTICS.fields_by_name['num_stats'])\n_FEATURENAMESTATISTICS.fields_by_name['num_stats'].containing_oneof = _FEATURENAMESTATISTICS.oneofs_by_name['stats']\n_FEATURENAMESTATISTICS.oneofs_by_name['stats'].fields.append(\n  _FEATURENAMESTATISTICS.fields_by_name['string_stats'])\n_FEATURENAMESTATISTICS.fields_by_name['string_stats'].containing_oneof = _FEATURENAMESTATISTICS.oneofs_by_name['stats']\n_FEATURENAMESTATISTICS.oneofs_by_name['stats'].fields.append(\n  _FEATURENAMESTATISTICS.fields_by_name['bytes_stats'])\n_FEATURENAMESTATISTICS.fields_by_name['bytes_stats'].containing_oneof = _FEATURENAMESTATISTICS.oneofs_by_name['stats']\n_CUSTOMSTATISTIC.fields_by_name['histogram'].message_type = _HISTOGRAM\n_CUSTOMSTATISTIC.oneofs_by_name['val'].fields.append(\n  _CUSTOMSTATISTIC.fields_by_name['num'])\n_CUSTOMSTATISTIC.fields_by_name['num'].containing_oneof = _CUSTOMSTATISTIC.oneofs_by_name['val']\n_CUSTOMSTATISTIC.oneofs_by_name['val'].fields.append(\n  _CUSTOMSTATISTIC.fields_by_name['str'])\n_CUSTOMSTATISTIC.fields_by_name['str'].containing_oneof = _CUSTOMSTATISTIC.oneofs_by_name['val']\n_CUSTOMSTATISTIC.oneofs_by_name['val'].fields.append(\n  _CUSTOMSTATISTIC.fields_by_name['histogram'])\n_CUSTOMSTATISTIC.fields_by_name['histogram'].containing_oneof = _CUSTOMSTATISTIC.oneofs_by_name['val']\n_NUMERICSTATISTICS.fields_by_name['common_stats'].message_type = _COMMONSTATISTICS\n_NUMERICSTATISTICS.fields_by_name['histograms'].message_type = _HISTOGRAM\n_NUMERICSTATISTICS.fields_by_name['weighted_numeric_stats'].message_type = _WEIGHTEDNUMERICSTATISTICS\n_STRINGSTATISTICS_FREQANDVALUE.containing_type = _STRINGSTATISTICS\n_STRINGSTATISTICS.fields_by_name['common_stats'].message_type = _COMMONSTATISTICS\n_STRINGSTATISTICS.fields_by_name['top_values'].message_type = _STRINGSTATISTICS_FREQANDVALUE\n_STRINGSTATISTICS.fields_by_name['rank_histogram'].message_type = _RANKHISTOGRAM\n_STRINGSTATISTICS.fields_by_name['weighted_string_stats'].message_type = _WEIGHTEDSTRINGSTATISTICS\n_WEIGHTEDNUMERICSTATISTICS.fields_by_name['histograms'].message_type = _HISTOGRAM\n_WEIGHTEDSTRINGSTATISTICS.fields_by_name['top_values'].message_type = _STRINGSTATISTICS_FREQANDVALUE\n_WEIGHTEDSTRINGSTATISTICS.fields_by_name['rank_histogram'].message_type = _RANKHISTOGRAM\n_BYTESSTATISTICS.fields_by_name['common_stats'].message_type = _COMMONSTATISTICS\n_COMMONSTATISTICS.fields_by_name['num_values_histogram'].message_type = _HISTOGRAM\n_COMMONSTATISTICS.fields_by_name['weighted_common_stats'].message_type = _WEIGHTEDCOMMONSTATISTICS\n_COMMONSTATISTICS.fields_by_name['feature_list_length_histogram'].message_type = _HISTOGRAM\n_HISTOGRAM_BUCKET.containing_type = _HISTOGRAM\n_HISTOGRAM.fields_by_name['buckets'].message_type = _HISTOGRAM_BUCKET\n_HISTOGRAM.fields_by_name['type'].enum_type = _HISTOGRAM_HISTOGRAMTYPE\n_HISTOGRAM_HISTOGRAMTYPE.containing_type = _HISTOGRAM\n_RANKHISTOGRAM_BUCKET.containing_type = _RANKHISTOGRAM\n_RANKHISTOGRAM.fields_by_name['buckets'].message_type = _RANKHISTOGRAM_BUCKET\nDESCRIPTOR.message_types_by_name['DatasetFeatureStatisticsList'] = _DATASETFEATURESTATISTICSLIST\nDESCRIPTOR.message_types_by_name['DatasetFeatureStatistics'] = _DATASETFEATURESTATISTICS\nDESCRIPTOR.message_types_by_name['FeatureNameStatistics'] = _FEATURENAMESTATISTICS\nDESCRIPTOR.message_types_by_name['WeightedCommonStatistics'] = _WEIGHTEDCOMMONSTATISTICS\nDESCRIPTOR.message_types_by_name['CustomStatistic'] = _CUSTOMSTATISTIC\nDESCRIPTOR.message_types_by_name['NumericStatistics'] = _NUMERICSTATISTICS\nDESCRIPTOR.message_types_by_name['StringStatistics'] = _STRINGSTATISTICS\nDESCRIPTOR.message_types_by_name['WeightedNumericStatistics'] = _WEIGHTEDNUMERICSTATISTICS\nDESCRIPTOR.message_types_by_name['WeightedStringStatistics'] = _WEIGHTEDSTRINGSTATISTICS\nDESCRIPTOR.message_types_by_name['BytesStatistics'] = _BYTESSTATISTICS\nDESCRIPTOR.message_types_by_name['CommonStatistics'] = _COMMONSTATISTICS\nDESCRIPTOR.message_types_by_name['Histogram'] = _HISTOGRAM\nDESCRIPTOR.message_types_by_name['RankHistogram'] = _RANKHISTOGRAM\n_sym_db.RegisterFileDescriptor(DESCRIPTOR)\n\nDatasetFeatureStatisticsList = _reflection.GeneratedProtocolMessageType('DatasetFeatureStatisticsList', (_message.Message,), dict(\n  DESCRIPTOR = _DATASETFEATURESTATISTICSLIST,\n  __module__ = 'feature_statistics_pb2'\n  # @@protoc_insertion_point(class_scope:featureStatistics.DatasetFeatureStatisticsList)\n  ))\n_sym_db.RegisterMessage(DatasetFeatureStatisticsList)\n\nDatasetFeatureStatistics = _reflection.GeneratedProtocolMessageType('DatasetFeatureStatistics', (_message.Message,), dict(\n  DESCRIPTOR = _DATASETFEATURESTATISTICS,\n  __module__ = 'feature_statistics_pb2'\n  # @@protoc_insertion_point(class_scope:featureStatistics.DatasetFeatureStatistics)\n  ))\n_sym_db.RegisterMessage(DatasetFeatureStatistics)\n\nFeatureNameStatistics = _reflection.GeneratedProtocolMessageType('FeatureNameStatistics', (_message.Message,), dict(\n  DESCRIPTOR = _FEATURENAMESTATISTICS,\n  __module__ = 'feature_statistics_pb2'\n  # @@protoc_insertion_point(class_scope:featureStatistics.FeatureNameStatistics)\n  ))\n_sym_db.RegisterMessage(FeatureNameStatistics)\n\nWeightedCommonStatistics = _reflection.GeneratedProtocolMessageType('WeightedCommonStatistics', (_message.Message,), dict(\n  DESCRIPTOR = _WEIGHTEDCOMMONSTATISTICS,\n  __module__ = 'feature_statistics_pb2'\n  # @@protoc_insertion_point(class_scope:featureStatistics.WeightedCommonStatistics)\n  ))\n_sym_db.RegisterMessage(WeightedCommonStatistics)\n\nCustomStatistic = _reflection.GeneratedProtocolMessageType('CustomStatistic', (_message.Message,), dict(\n  DESCRIPTOR = _CUSTOMSTATISTIC,\n  __module__ = 'feature_statistics_pb2'\n  # @@protoc_insertion_point(class_scope:featureStatistics.CustomStatistic)\n  ))\n_sym_db.RegisterMessage(CustomStatistic)\n\nNumericStatistics = _reflection.GeneratedProtocolMessageType('NumericStatistics', (_message.Message,), dict(\n  DESCRIPTOR = _NUMERICSTATISTICS,\n  __module__ = 'feature_statistics_pb2'\n  # @@protoc_insertion_point(class_scope:featureStatistics.NumericStatistics)\n  ))\n_sym_db.RegisterMessage(NumericStatistics)\n\nStringStatistics = _reflection.GeneratedProtocolMessageType('StringStatistics', (_message.Message,), dict(\n\n  FreqAndValue = _reflection.GeneratedProtocolMessageType('FreqAndValue', (_message.Message,), dict(\n    DESCRIPTOR = _STRINGSTATISTICS_FREQANDVALUE,\n    __module__ = 'feature_statistics_pb2'\n    # @@protoc_insertion_point(class_scope:featureStatistics.StringStatistics.FreqAndValue)\n    ))\n  ,\n  DESCRIPTOR = _STRINGSTATISTICS,\n  __module__ = 'feature_statistics_pb2'\n  # @@protoc_insertion_point(class_scope:featureStatistics.StringStatistics)\n  ))\n_sym_db.RegisterMessage(StringStatistics)\n_sym_db.RegisterMessage(StringStatistics.FreqAndValue)\n\nWeightedNumericStatistics = _reflection.GeneratedProtocolMessageType('WeightedNumericStatistics', (_message.Message,), dict(\n  DESCRIPTOR = _WEIGHTEDNUMERICSTATISTICS,\n  __module__ = 'feature_statistics_pb2'\n  # @@protoc_insertion_point(class_scope:featureStatistics.WeightedNumericStatistics)\n  ))\n_sym_db.RegisterMessage(WeightedNumericStatistics)\n\nWeightedStringStatistics = _reflection.GeneratedProtocolMessageType('WeightedStringStatistics', (_message.Message,), dict(\n  DESCRIPTOR = _WEIGHTEDSTRINGSTATISTICS,\n  __module__ = 'feature_statistics_pb2'\n  # @@protoc_insertion_point(class_scope:featureStatistics.WeightedStringStatistics)\n  ))\n_sym_db.RegisterMessage(WeightedStringStatistics)\n\nBytesStatistics = _reflection.GeneratedProtocolMessageType('BytesStatistics', (_message.Message,), dict(\n  DESCRIPTOR = _BYTESSTATISTICS,\n  __module__ = 'feature_statistics_pb2'\n  # @@protoc_insertion_point(class_scope:featureStatistics.BytesStatistics)\n  ))\n_sym_db.RegisterMessage(BytesStatistics)\n\nCommonStatistics = _reflection.GeneratedProtocolMessageType('CommonStatistics', (_message.Message,), dict(\n  DESCRIPTOR = _COMMONSTATISTICS,\n  __module__ = 'feature_statistics_pb2'\n  # @@protoc_insertion_point(class_scope:featureStatistics.CommonStatistics)\n  ))\n_sym_db.RegisterMessage(CommonStatistics)\n\nHistogram = _reflection.GeneratedProtocolMessageType('Histogram', (_message.Message,), dict(\n\n  Bucket = _reflection.GeneratedProtocolMessageType('Bucket', (_message.Message,), dict(\n    DESCRIPTOR = _HISTOGRAM_BUCKET,\n    __module__ = 'feature_statistics_pb2'\n    # @@protoc_insertion_point(class_scope:featureStatistics.Histogram.Bucket)\n    ))\n  ,\n  DESCRIPTOR = _HISTOGRAM,\n  __module__ = 'feature_statistics_pb2'\n  # @@protoc_insertion_point(class_scope:featureStatistics.Histogram)\n  ))\n_sym_db.RegisterMessage(Histogram)\n_sym_db.RegisterMessage(Histogram.Bucket)\n\nRankHistogram = _reflection.GeneratedProtocolMessageType('RankHistogram', (_message.Message,), dict(\n\n  Bucket = _reflection.GeneratedProtocolMessageType('Bucket', (_message.Message,), dict(\n    DESCRIPTOR = _RANKHISTOGRAM_BUCKET,\n    __module__ = 'feature_statistics_pb2'\n    # @@protoc_insertion_point(class_scope:featureStatistics.RankHistogram.Bucket)\n    ))\n  ,\n  DESCRIPTOR = _RANKHISTOGRAM,\n  __module__ = 'feature_statistics_pb2'\n  # @@protoc_insertion_point(class_scope:featureStatistics.RankHistogram)\n  ))\n_sym_db.RegisterMessage(RankHistogram)\n_sym_db.RegisterMessage(RankHistogram.Bucket)\n\n\n_STRINGSTATISTICS_FREQANDVALUE.fields_by_name['deprecated_freq'].has_options = True\n_STRINGSTATISTICS_FREQANDVALUE.fields_by_name['deprecated_freq']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\\030\\001'))\n_HISTOGRAM_BUCKET.fields_by_name['deprecated_count'].has_options = True\n_HISTOGRAM_BUCKET.fields_by_name['deprecated_count']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\\030\\001'))\n_RANKHISTOGRAM_BUCKET.fields_by_name['deprecated_count'].has_options = True\n_RANKHISTOGRAM_BUCKET.fields_by_name['deprecated_count']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\\030\\001'))\n# @@protoc_insertion_point(module_scope)\n"
  },
  {
    "path": "google/datalab/utils/facets/generic_feature_statistics_generator.py",
    "content": "# Copyright 2017 Google Inc. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n# ==============================================================================\n\"\"\"Code for generating the feature_statistics proto from generic data.\n\nThe proto is used as input for the Overview visualization.\n\"\"\"\n\nimport warnings\nfrom .base_generic_feature_statistics_generator import BaseGenericFeatureStatisticsGenerator\nfrom . import feature_statistics_pb2 as fs\n\n\nclass GenericFeatureStatisticsGenerator(BaseGenericFeatureStatisticsGenerator):\n  \"\"\"Generator of stats proto from generic data.\"\"\"\n\n  def __init__(self):\n    BaseGenericFeatureStatisticsGenerator.__init__(\n        self, fs.FeatureNameStatistics, fs.DatasetFeatureStatisticsList,\n        fs.Histogram)\n\n\ndef ProtoFromDataFrames(dataframes):\n  \"\"\"Creates a feature statistics proto from a set of pandas dataframes.\n\n  Args:\n    dataframes: A list of dicts describing tables for each dataset for the\n        proto. Each entry contains a 'table' field of the dataframe of the\n          data\n        and a 'name' field to identify the dataset in the proto.\n\n  Returns:\n    The feature statistics proto for the provided tables.\n  \"\"\"\n  warnings.warn(\n      'Use GenericFeatureStatisticsGenerator class method instead.',\n      DeprecationWarning)\n  return GenericFeatureStatisticsGenerator().ProtoFromDataFrames(dataframes)\n"
  },
  {
    "path": "install-no-virtualenv.sh",
    "content": "#!/bin/sh -e\n\n# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n# Build a distribution package\ntsc --module amd --noImplicitAny --outdir datalab/notebook/static datalab/notebook/static/*.ts\npip install .\njupyter nbextension install --py datalab.notebook\nrm datalab/notebook/static/*.js\n\n\n"
  },
  {
    "path": "install-virtualenv.sh",
    "content": "#!/bin/sh -e\n\n# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n# Build a distribution package\ntsc --module amd --noImplicitAny --outdir datalab/notebook/static datalab/notebook/static/*.ts\npip install .\njupyter nbextension install --py datalab.notebook --sys-prefix\nrm datalab/notebook/static/*.js\n"
  },
  {
    "path": "legacy_tests/_util/__init__.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n"
  },
  {
    "path": "legacy_tests/_util/http_tests.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nimport mock\nimport unittest\n\n# The httplib2 import is implicitly used when mocking its functionality.\n# pylint: disable=unused-import\nfrom datalab.utils._http import Http\n\n\nclass TestCases(unittest.TestCase):\n\n  @mock.patch('httplib2.Response')\n  @mock.patch('datalab.utils._http.Http.http.request')\n  def test_get_request_is_invoked(self, mock_request, mock_response):\n    TestCases._setup_mocks(mock_request, mock_response, '{}')\n\n    Http.request('http://www.example.org')\n    self.assertEqual(mock_request.call_count, 1)\n    self.assertEqual(mock_request.call_args[1]['method'], 'GET')\n\n  @mock.patch('httplib2.Response')\n  @mock.patch('datalab.utils._http.Http.http.request')\n  def test_post_request_is_invoked(self, mock_request, mock_response):\n    TestCases._setup_mocks(mock_request, mock_response, '{}')\n\n    Http.request('http://www.example.org', data={})\n    self.assertEqual(mock_request.call_args[1]['method'], 'POST')\n\n  @mock.patch('httplib2.Response')\n  @mock.patch('datalab.utils._http.Http.http.request')\n  def test_explicit_post_request_is_invoked(self, mock_request, mock_response):\n    TestCases._setup_mocks(mock_request, mock_response, '{}')\n\n    Http.request('http://www.example.org', method='POST')\n    self.assertEqual(mock_request.call_args[1]['method'], 'POST')\n\n  @mock.patch('httplib2.Response')\n  @mock.patch('datalab.utils._http.Http.http.request')\n  def test_query_string_format(self, mock_request, mock_response):\n    TestCases._setup_mocks(mock_request, mock_response, '{}')\n\n    Http.request('http://www.example.org', args={'a': 1, 'b': 'a b c'})\n    parts = mock_request.call_args[0][0].replace('?', '&').split('&')\n    self.assertEqual(parts[0], 'http://www.example.org')\n    self.assertTrue('a=1' in parts[1:])\n    self.assertTrue('b=a+b+c' in parts[1:])\n\n  @mock.patch('httplib2.Response')\n  @mock.patch('datalab.utils._http.Http.http.request')\n  def test_formats_json_request(self, mock_request, mock_response):\n    TestCases._setup_mocks(mock_request, mock_response, '{}')\n\n    data = {'abc': 123}\n    Http.request('http://www.example.org', data=data)\n\n    self.assertEqual(mock_request.call_args[1]['body'], '{\"abc\": 123}')\n    self.assertEqual(mock_request.call_args[1]['headers']['Content-Type'],\n                     'application/json')\n\n  @mock.patch('httplib2.Response')\n  @mock.patch('datalab.utils._http.Http.http.request')\n  def test_supports_custom_content(self, mock_request, mock_response):\n    TestCases._setup_mocks(mock_request, mock_response, '{}')\n\n    headers = {'Content-Type': 'text/plain'}\n    data = 'custom text'\n    Http.request('http://www.example.org', data=data, headers=headers)\n\n    self.assertEqual(mock_request.call_args[1]['body'], 'custom text')\n    self.assertEqual(mock_request.call_args[1]['headers']['Content-Type'], 'text/plain')\n\n  @mock.patch('httplib2.Response')\n  @mock.patch('datalab.utils._http.Http.http.request')\n  def test_parses_json_response(self, mock_request, mock_response):\n    TestCases._setup_mocks(mock_request, mock_response, '{\"abc\":123}')\n\n    data = Http.request('http://www.example.org')\n    self.assertEqual(data['abc'], 123)\n\n  @mock.patch('httplib2.Response')\n  @mock.patch('datalab.utils._http.Http.http.request')\n  def test_raises_http_error(self, mock_request, mock_response):\n    TestCases._setup_mocks(mock_request, mock_response, 'Not Found', 404)\n\n    with self.assertRaises(Exception) as error:\n      Http.request('http://www.example.org')\n\n    e = error.exception\n    self.assertEqual(e.status, 404)\n    self.assertEqual(e.content, 'Not Found')\n\n  @staticmethod\n  def _setup_mocks(mock_request, mock_response, content, status=200):\n    response = mock_response()\n    response.status = status\n    mock_request.return_value = (response, content)\n"
  },
  {
    "path": "legacy_tests/_util/lru_cache_tests.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nimport unittest\n\nfrom datalab.utils._lru_cache import LRUCache\n\n\nclass TestCases(unittest.TestCase):\n\n  def test_cache_no_entry(self):\n    cache = LRUCache(3)\n    with self.assertRaises(KeyError):\n      cache['a']\n\n  def test_cache_lookup(self):\n    cache = LRUCache(4)\n    for x in ['a', 'b', 'c', 'd']:\n      cache[x] = x\n\n    for x in ['a', 'b', 'c', 'd']:\n      self.assertEqual(x, cache[x])\n\n  def test_cache_overflow(self):\n    cache = LRUCache(3)\n    for x in ['a', 'b', 'c', 'd']:\n      cache[x] = x\n\n    for x in ['b', 'c', 'd']:\n      self.assertEqual(x, cache[x])\n\n    with self.assertRaises(KeyError):\n      cache['a']\n\n    cache['b']\n    cache['d']\n    # 'c' should be LRU now\n    cache['e'] = 'e'\n\n    with self.assertRaises(KeyError):\n      cache['c']\n\n    for x in ['b', 'd', 'e']:\n      self.assertEqual(x, cache[x])\n"
  },
  {
    "path": "legacy_tests/_util/util_tests.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nimport imp\nimport unittest\n\nfrom datalab.utils._utils import get_item\n\n\nclass TestCases(unittest.TestCase):\n\n  @staticmethod\n  def _get_data():\n    m = imp.new_module('baz')\n    exec('x = 99', m.__dict__)\n    data = {\n      'foo': {\n        'bar': {\n          'xyz': 0\n        },\n        'm': m\n      }\n    }\n    return data\n\n  def test_no_entry(self):\n    data = TestCases._get_data()\n    self.assertIsNone(get_item(data, 'x'))\n    self.assertIsNone(get_item(data, 'bar.x'))\n    self.assertIsNone(get_item(data, 'foo.bar.x'))\n    self.assertIsNone(get_item(globals(), 'datetime.bar.x'))\n\n  def test_entry(self):\n    data = TestCases._get_data()\n    self.assertEquals(data['foo']['bar']['xyz'], get_item(data, 'foo.bar.xyz'))\n    self.assertEquals(data['foo']['bar'], get_item(data, 'foo.bar'))\n    self.assertEquals(data['foo'], get_item(data, 'foo'))\n    self.assertEquals(data['foo']['m'], get_item(data, 'foo.m'))\n    self.assertEquals(99, get_item(data, 'foo.m.x'))\n"
  },
  {
    "path": "legacy_tests/bigquery/__init__.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n"
  },
  {
    "path": "legacy_tests/bigquery/api_tests.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nimport unittest\nimport mock\n\nimport google.auth\nimport datalab.bigquery\nimport datalab.context\nimport datalab.utils\nfrom datalab.bigquery._api import Api\n\n\nclass TestCases(unittest.TestCase):\n\n  def validate(self, mock_http_request, expected_url, expected_args=None, expected_data=None,\n               expected_headers=None, expected_method=None):\n    url = mock_http_request.call_args[0][0]\n    kwargs = mock_http_request.call_args[1]\n    self.assertEquals(expected_url, url)\n    if expected_args is not None:\n      self.assertEquals(expected_args, kwargs['args'])\n    else:\n      self.assertNotIn('args', kwargs)\n    if expected_data is not None:\n      self.assertEquals(expected_data, kwargs['data'])\n    else:\n      self.assertNotIn('data', kwargs)\n    if expected_headers is not None:\n      self.assertEquals(expected_headers, kwargs['headers'])\n    else:\n      self.assertNotIn('headers', kwargs)\n    if expected_method is not None:\n      self.assertEquals(expected_method, kwargs['method'])\n    else:\n      self.assertNotIn('method', kwargs)\n\n  @mock.patch('datalab.utils.Http.request')\n  def test_jobs_insert_load(self, mock_http_request):\n    api = TestCases._create_api()\n    api.jobs_insert_load('SOURCE', datalab.bigquery._utils.TableName('p', 'd', 't', ''))\n    self.maxDiff = None\n    expected_data = {\n      'kind': 'bigquery#job',\n      'configuration': {\n        'load': {\n          'sourceUris': ['SOURCE'],\n          'destinationTable': {\n            'projectId': 'p',\n            'datasetId': 'd',\n            'tableId': 't'\n          },\n          'createDisposition': 'CREATE_NEVER',\n          'writeDisposition': 'WRITE_EMPTY',\n          'sourceFormat': 'CSV',\n          'fieldDelimiter': ',',\n          'allowJaggedRows': False,\n          'allowQuotedNewlines': False,\n          'encoding': 'UTF-8',\n          'ignoreUnknownValues': False,\n          'maxBadRecords': 0,\n          'quote': '\"',\n          'skipLeadingRows': 0\n        }\n      }\n    }\n    self.validate(mock_http_request, 'https://www.googleapis.com/bigquery/v2/projects/p/jobs/',\n                  expected_data=expected_data)\n\n    api.jobs_insert_load('SOURCE2', datalab.bigquery._utils.TableName('p2', 'd2', 't2', ''),\n                         append=True, create=True, allow_jagged_rows=True,\n                         allow_quoted_newlines=True, ignore_unknown_values=True,\n                         source_format='JSON', max_bad_records=1)\n    expected_data = {\n      'kind': 'bigquery#job',\n      'configuration': {\n        'load': {\n          'sourceUris': ['SOURCE2'],\n          'destinationTable': {\n            'projectId': 'p2',\n            'datasetId': 'd2',\n            'tableId': 't2'\n          },\n          'createDisposition': 'CREATE_IF_NEEDED',\n          'writeDisposition': 'WRITE_APPEND',\n          'sourceFormat': 'JSON',\n          'ignoreUnknownValues': True,\n          'maxBadRecords': 1\n        }\n      }\n    }\n    self.validate(mock_http_request, 'https://www.googleapis.com/bigquery/v2/projects/p2/jobs/',\n                  expected_data=expected_data)\n\n  @mock.patch('datalab.utils.Http.request')\n  def test_jobs_insert_query(self, mock_http_request):\n    api = TestCases._create_api()\n    api.jobs_insert_query('SQL')\n    expected_data = {\n      'kind': 'bigquery#job',\n      'configuration': {\n        'query': {\n          'query': 'SQL',\n          'useQueryCache': True,\n          'userDefinedFunctionResources': [],\n          'allowLargeResults': False,\n          'useLegacySql': True,\n        },\n        'dryRun': False,\n        'priority': 'BATCH',\n      },\n    }\n    self.validate(mock_http_request, 'https://www.googleapis.com/bigquery/v2/projects/test/jobs/',\n                  expected_data=expected_data)\n    api.jobs_insert_query('SQL2', ['CODE'],\n                          table_name=datalab.bigquery._utils.TableName('p', 'd', 't', ''),\n                          append=True, dry_run=True, use_cache=False, batch=False,\n                          allow_large_results=True, dialect='standard', billing_tier=1)\n    expected_data = {\n      'kind': 'bigquery#job',\n      'configuration': {\n        'query': {\n          'query': 'SQL2',\n          'useQueryCache': False,\n          'allowLargeResults': True,\n          'useLegacySql': False,\n          'maximumBillingTier': 1,\n          'destinationTable': {\n            'projectId': 'p',\n            'datasetId': 'd',\n            'tableId': 't'\n          },\n          'writeDisposition': 'WRITE_APPEND',\n          'userDefinedFunctionResources': [\n            {\n              'inlineCode': 'CODE'\n            }\n          ]\n        },\n        'dryRun': True,\n        'priority': 'INTERACTIVE',\n      },\n    }\n    self.maxDiff = None\n    self.validate(mock_http_request, 'https://www.googleapis.com/bigquery/v2/projects/test/jobs/',\n                  expected_data=expected_data)\n\n  @mock.patch('datalab.utils.Http.request')\n  def test_jobs_query_results(self, mock_http_request):\n    api = TestCases._create_api()\n    api.jobs_query_results('JOB', 'PROJECT', 10, 20, 30)\n    self.validate(mock_http_request,\n                  'https://www.googleapis.com/bigquery/v2/projects/PROJECT/queries/JOB',\n                  expected_args={'maxResults': 10, 'timeoutMs': 20, 'startIndex': 30})\n\n  @mock.patch('datalab.utils.Http.request')\n  def test_jobs_get(self, mock_http_request):\n    api = TestCases._create_api()\n    api.jobs_get('JOB', 'PROJECT')\n    self.validate(mock_http_request,\n                  'https://www.googleapis.com/bigquery/v2/projects/PROJECT/jobs/JOB')\n\n  @mock.patch('datalab.utils.Http.request')\n  def test_datasets_insert(self, mock_http_request):\n    api = TestCases._create_api()\n    api.datasets_insert(datalab.bigquery._utils.DatasetName('p', 'd'))\n    expected_data = {\n      'kind': 'bigquery#dataset',\n      'datasetReference': {\n        'projectId': 'p',\n        'datasetId': 'd',\n      }\n    }\n    self.validate(mock_http_request, 'https://www.googleapis.com/bigquery/v2/projects/p/datasets/',\n                  expected_data=expected_data)\n    api.datasets_insert(datalab.bigquery._utils.DatasetName('p', 'd'), 'FRIENDLY', 'DESCRIPTION')\n    expected_data = {\n      'kind': 'bigquery#dataset',\n      'datasetReference': {\n        'projectId': 'p',\n        'datasetId': 'd'\n      },\n      'friendlyName': 'FRIENDLY',\n      'description': 'DESCRIPTION'\n    }\n    self.validate(mock_http_request, 'https://www.googleapis.com/bigquery/v2/projects/p/datasets/',\n                  expected_data=expected_data)\n\n  @mock.patch('datalab.utils.Http.request')\n  def test_datasets_delete(self, mock_http_request):\n    api = TestCases._create_api()\n    api.datasets_delete(datalab.bigquery._utils.DatasetName('p', 'd'), False)\n    self.validate(mock_http_request, 'https://www.googleapis.com/bigquery/v2/projects/p/datasets/d',\n                  expected_args={},\n                  expected_method='DELETE')\n    api.datasets_delete(datalab.bigquery._utils.DatasetName('p', 'd'), True)\n    self.validate(mock_http_request, 'https://www.googleapis.com/bigquery/v2/projects/p/datasets/d',\n                  expected_args={'deleteContents': True},\n                  expected_method='DELETE')\n\n  @mock.patch('datalab.utils.Http.request')\n  def test_datasets_update(self, mock_http_request):\n    api = TestCases._create_api()\n    api.datasets_update(datalab.bigquery._utils.DatasetName('p', 'd'), 'INFO')\n    self.validate(mock_http_request, 'https://www.googleapis.com/bigquery/v2/projects/p/datasets/d',\n                  expected_method='PUT', expected_data='INFO')\n\n  @mock.patch('datalab.utils.Http.request')\n  def test_datasets_get(self, mock_http_request):\n    api = TestCases._create_api()\n    api.datasets_get(datalab.bigquery._utils.DatasetName('p', 'd'))\n    self.validate(mock_http_request, 'https://www.googleapis.com/bigquery/v2/projects/p/datasets/d')\n\n  @mock.patch('datalab.utils.Http.request')\n  def test_datasets_list(self, mock_http_request):\n    api = TestCases._create_api()\n    api.datasets_list()\n    self.validate(mock_http_request,\n                  'https://www.googleapis.com/bigquery/v2/projects/test/datasets/',\n                  expected_args={})\n\n    api.datasets_list('PROJECT', 10, 'TOKEN')\n    self.validate(mock_http_request,\n                  'https://www.googleapis.com/bigquery/v2/projects/PROJECT/datasets/',\n                  expected_args={'maxResults': 10, 'pageToken': 'TOKEN'})\n\n  @mock.patch('datalab.utils.Http.request')\n  def test_tables_get(self, mock_http_request):\n    api = TestCases._create_api()\n    api.tables_get(datalab.bigquery._utils.TableName('p', 'd', 't', ''))\n    self.validate(mock_http_request,\n                  'https://www.googleapis.com/bigquery/v2/projects/p/datasets/d/tables/t')\n\n  @mock.patch('datalab.utils.Http.request')\n  def test_tables_list(self, mock_http_request):\n    api = TestCases._create_api()\n    api.tables_list(datalab.bigquery._utils.DatasetName('p', 'd'))\n    self.validate(mock_http_request,\n                  'https://www.googleapis.com/bigquery/v2/projects/p/datasets/d/tables/',\n                  expected_args={})\n\n    api.tables_list(datalab.bigquery._utils.DatasetName('p', 'd'), 10, 'TOKEN')\n    self.validate(mock_http_request,\n                  'https://www.googleapis.com/bigquery/v2/projects/p/datasets/d/tables/',\n                  expected_args={'maxResults': 10, 'pageToken': 'TOKEN'})\n\n  @mock.patch('datalab.utils.Http.request')\n  def test_tables_insert(self, mock_http_request):\n    api = TestCases._create_api()\n    api.tables_insert(datalab.bigquery._utils.TableName('p', 'd', 't', ''))\n    expected_data = {\n      'kind': 'bigquery#table',\n      'tableReference': {\n        'projectId': 'p',\n        'datasetId': 'd',\n        'tableId': 't'\n      }\n    }\n    self.validate(mock_http_request,\n                  'https://www.googleapis.com/bigquery/v2/projects/p/datasets/d/tables/',\n                  expected_data=expected_data)\n\n    api.tables_insert(datalab.bigquery._utils.TableName('p', 'd', 't', ''),\n                      'SCHEMA', 'QUERY', 'FRIENDLY', 'DESCRIPTION')\n    expected_data = {\n      'kind': 'bigquery#table',\n      'tableReference': {\n        'projectId': 'p',\n        'datasetId': 'd',\n        'tableId': 't'\n      },\n      'schema': {\n        'fields': 'SCHEMA'\n      },\n      'view': {'query': 'QUERY'},\n      'friendlyName': 'FRIENDLY',\n      'description': 'DESCRIPTION'\n    }\n    self.validate(mock_http_request,\n                  'https://www.googleapis.com/bigquery/v2/projects/p/datasets/d/tables/',\n                  expected_data=expected_data)\n\n  @mock.patch('datalab.utils.Http.request')\n  def test_tabledata_insertAll(self, mock_http_request):\n    api = TestCases._create_api()\n    api.tabledata_insert_all(datalab.bigquery._utils.TableName('p', 'd', 't', ''), 'ROWS')\n    expected_data = {\n      'kind': 'bigquery#tableDataInsertAllRequest',\n      'rows': 'ROWS'\n    }\n    self.validate(mock_http_request,\n                  'https://www.googleapis.com/bigquery/v2/projects/p/datasets/d/tables/t/insertAll',\n                  expected_data=expected_data)\n\n  @mock.patch('datalab.utils.Http.request')\n  def test_tabledata_list(self, mock_http_request):\n    api = TestCases._create_api()\n    api.tabledata_list(datalab.bigquery._utils.TableName('p', 'd', 't', ''))\n    self.validate(mock_http_request,\n                  'https://www.googleapis.com/bigquery/v2/projects/p/datasets/d/tables/t/data',\n                  expected_args={})\n\n    api.tabledata_list(datalab.bigquery._utils.TableName('p', 'd', 't', ''), 10, 20, 'TOKEN')\n    self.validate(mock_http_request,\n                  'https://www.googleapis.com/bigquery/v2/projects/p/datasets/d/tables/t/data',\n                  expected_args={\n                    'startIndex': 10,\n                    'maxResults': 20,\n                    'pageToken': 'TOKEN'\n                  })\n\n  @mock.patch('datalab.utils.Http.request')\n  def test_table_delete(self, mock_http_request):\n    api = TestCases._create_api()\n    api.table_delete(datalab.bigquery._utils.TableName('p', 'd', 't', ''))\n    self.validate(mock_http_request,\n                  'https://www.googleapis.com/bigquery/v2/projects/p/datasets/d/tables/t',\n                  expected_method='DELETE')\n\n  @mock.patch('datalab.utils.Http.request')\n  def test_table_extract(self, mock_http_request):\n    api = TestCases._create_api()\n    api.table_extract(datalab.bigquery._utils.TableName('p', 'd', 't', ''), 'DEST')\n    expected_data = {\n      'kind': 'bigquery#job',\n      'configuration': {\n        'extract': {\n          'sourceTable': {\n            'projectId': 'p',\n            'datasetId': 'd',\n            'tableId': 't'\n          },\n          'compression': 'GZIP',\n          'fieldDelimiter': ',',\n          'printHeader': True,\n          'destinationUris': ['DEST'],\n          'destinationFormat': 'CSV',\n        }\n      }\n    }\n    self.validate(mock_http_request,\n                  'https://www.googleapis.com/bigquery/v2/projects/p/jobs/',\n                  expected_data=expected_data)\n\n    api.table_extract(datalab.bigquery._utils.TableName('p', 'd', 't', ''),\n                      ['DEST'], format='JSON', compress=False, field_delimiter=':',\n                      print_header=False)\n    expected_data = {\n      'kind': 'bigquery#job',\n      'configuration': {\n        'extract': {\n          'sourceTable': {\n            'projectId': 'p',\n            'datasetId': 'd',\n            'tableId': 't'\n          },\n          'compression': 'NONE',\n          'fieldDelimiter': ':',\n          'printHeader': False,\n          'destinationUris': ['DEST'],\n          'destinationFormat': 'JSON',\n        }\n      }\n    }\n    self.validate(mock_http_request, 'https://www.googleapis.com/bigquery/v2/projects/p/jobs/',\n                  expected_data=expected_data)\n\n  @mock.patch('datalab.utils.Http.request')\n  def test_table_update(self, mock_http_request):\n    api = TestCases._create_api()\n    api.table_update(datalab.bigquery._utils.TableName('p', 'd', 't', ''), 'INFO')\n    self.validate(mock_http_request,\n                  'https://www.googleapis.com/bigquery/v2/projects/p/datasets/d/tables/t',\n                  expected_method='PUT', expected_data='INFO')\n\n  @staticmethod\n  def _create_api():\n    context = TestCases._create_context()\n    return Api(context)\n\n  @staticmethod\n  def _create_context():\n    project_id = 'test'\n    creds = mock.Mock(spec=google.auth.credentials.Credentials)\n    return datalab.context.Context(project_id, creds)\n"
  },
  {
    "path": "legacy_tests/bigquery/dataset_tests.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom builtins import str\nimport mock\nimport unittest\n\nimport google.auth\nimport datalab.bigquery\nimport datalab.context\nimport datalab.utils\n\n\nclass TestCases(unittest.TestCase):\n\n  def _check_name_parts(self, dataset):\n    parsed_name = dataset._name_parts\n    self.assertEqual('test', parsed_name[0])\n    self.assertEqual('requestlogs', parsed_name[1])\n    self.assertEqual('test:requestlogs', dataset._full_name)\n    self.assertEqual('test:requestlogs', str(dataset))\n\n  def test_parse_full_name(self):\n    dataset = TestCases._create_dataset('test:requestlogs')\n    self._check_name_parts(dataset)\n\n  def test_parse_local_name(self):\n    dataset = TestCases._create_dataset('requestlogs')\n    self._check_name_parts(dataset)\n\n  def test_parse_dict_full_name(self):\n    dataset = TestCases._create_dataset({'project_id': 'test', 'dataset_id': 'requestlogs'})\n    self._check_name_parts(dataset)\n\n  def test_parse_dict_local_name(self):\n    dataset = TestCases._create_dataset({'dataset_id': 'requestlogs'})\n    self._check_name_parts(dataset)\n\n  def test_parse_named_tuple_name(self):\n    dataset = TestCases._create_dataset(datalab.bigquery._utils.DatasetName('test', 'requestlogs'))\n    self._check_name_parts(dataset)\n\n  def test_parse_tuple_full_name(self):\n    dataset = TestCases._create_dataset(('test', 'requestlogs'))\n    self._check_name_parts(dataset)\n\n  def test_parse_tuple_local(self):\n    dataset = TestCases._create_dataset(('requestlogs'))\n    self._check_name_parts(dataset)\n\n  def test_parse_array_full_name(self):\n    dataset = TestCases._create_dataset(['test', 'requestlogs'])\n    self._check_name_parts(dataset)\n\n  def test_parse_array_local(self):\n    dataset = TestCases._create_dataset(['requestlogs'])\n    self._check_name_parts(dataset)\n\n  def test_parse_invalid_name(self):\n    with self.assertRaises(Exception):\n      TestCases._create_dataset('today@')\n\n  @mock.patch('datalab.bigquery._api.Api.datasets_get')\n  def test_dataset_exists(self, mock_api_datasets_get):\n    mock_api_datasets_get.return_value = ''\n    dataset = TestCases._create_dataset('test:requestlogs')\n    self.assertTrue(dataset.exists())\n    mock_api_datasets_get.side_effect = datalab.utils.RequestException(404, None)\n    dataset._info = None\n    self.assertFalse(dataset.exists())\n\n  @mock.patch('datalab.bigquery._api.Api.datasets_insert')\n  @mock.patch('datalab.bigquery._api.Api.datasets_get')\n  def test_datasets_create_fails(self, mock_api_datasets_get, mock_api_datasets_insert):\n    mock_api_datasets_get.side_effect = datalab.utils.RequestException(None, 404)\n    mock_api_datasets_insert.return_value = {}\n\n    ds = TestCases._create_dataset('requestlogs')\n    with self.assertRaises(Exception):\n      ds.create()\n\n  @mock.patch('datalab.bigquery._api.Api.datasets_insert')\n  @mock.patch('datalab.bigquery._api.Api.datasets_get')\n  def test_datasets_create_succeeds(self, mock_api_datasets_get, mock_api_datasets_insert):\n    mock_api_datasets_get.side_effect = datalab.utils.RequestException(404, None)\n    mock_api_datasets_insert.return_value = {'selfLink': None}\n    ds = TestCases._create_dataset('requestlogs')\n    self.assertEqual(ds, ds.create())\n\n  @mock.patch('datalab.bigquery._api.Api.datasets_insert')\n  @mock.patch('datalab.bigquery._api.Api.datasets_get')\n  def test_datasets_create_redundant(self, mock_api_datasets_get, mock_api_datasets_insert):\n    ds = TestCases._create_dataset('requestlogs', {})\n    mock_api_datasets_get.return_value = None\n    mock_api_datasets_insert.return_value = {}\n    self.assertEqual(ds, ds.create())\n\n  @mock.patch('datalab.bigquery._api.Api.datasets_get')\n  @mock.patch('datalab.bigquery._api.Api.datasets_delete')\n  def test_datasets_delete_succeeds(self, mock_api_datasets_delete, mock_api_datasets_get):\n    mock_api_datasets_get.return_value = ''\n    mock_api_datasets_delete.return_value = None\n    ds = TestCases._create_dataset('requestlogs')\n    self.assertIsNone(ds.delete())\n\n  @mock.patch('datalab.bigquery._api.Api.datasets_get')\n  @mock.patch('datalab.bigquery._api.Api.datasets_delete')\n  def test_datasets_delete_fails(self, mock_api_datasets_delete, mock_api_datasets_get):\n    mock_api_datasets_delete.return_value = None\n    mock_api_datasets_get.side_effect = datalab.utils.RequestException(404, None)\n    ds = TestCases._create_dataset('requestlogs')\n    with self.assertRaises(Exception):\n      ds.delete()\n\n  @mock.patch('datalab.bigquery._api.Api.tables_list')\n  def test_tables_list(self, mock_api_tables_list):\n    mock_api_tables_list.return_value = {\n      'tables': [\n          {\n            'type': 'TABLE',\n            'tableReference': {'projectId': 'p', 'datasetId': 'd', 'tableId': 't1'}\n          },\n          {\n            'type': 'TABLE',\n            'tableReference': {'projectId': 'p', 'datasetId': 'd', 'tableId': 't2'}\n          },\n      ]\n    }\n    ds = TestCases._create_dataset('requestlogs')\n    tables = [table for table in ds]\n    self.assertEqual(2, len(tables))\n    self.assertEqual('p:d.t1', str(tables[0]))\n    self.assertEqual('p:d.t2', str(tables[1]))\n\n  @mock.patch('datalab.bigquery.Dataset._get_info')\n  @mock.patch('datalab.bigquery._api.Api.datasets_list')\n  def test_datasets_list(self, mock_api_datasets_list, mock_dataset_get_info):\n    mock_api_datasets_list.return_value = {\n      'datasets': [\n        {'datasetReference': {'projectId': 'p', 'datasetId': 'd1'}},\n        {'datasetReference': {'projectId': 'p', 'datasetId': 'd2'}},\n      ]\n    }\n    mock_dataset_get_info.return_value = {}\n    datasets = [dataset for dataset in datalab.bigquery.Datasets('test',\n                                                                 TestCases._create_context())]\n    self.assertEqual(2, len(datasets))\n    self.assertEqual('p:d1', str(datasets[0]))\n    self.assertEqual('p:d2', str(datasets[1]))\n\n  @mock.patch('datalab.bigquery._api.Api.tables_list')\n  @mock.patch('datalab.bigquery._api.Api.datasets_get')\n  @mock.patch('datalab.bigquery._api.Api.datasets_update')\n  def test_datasets_update(self, mock_api_datasets_update, mock_api_datasets_get,\n                           mock_api_tables_list):\n    mock_api_tables_list.return_value = {\n      'tables': [\n        {'type': 'TABLE', 'tableReference': {'projectId': 'p', 'datasetId': 'd', 'tableId': 't1'}},\n        {'type': 'TABLE', 'tableReference': {'projectId': 'p', 'datasetId': 'd', 'tableId': 't2'}},\n      ]\n    }\n    info = {'friendlyName': 'casper', 'description': 'ghostly logs'}\n    mock_api_datasets_get.return_value = info\n    ds = TestCases._create_dataset('requestlogs')\n\n    new_friendly_name = 'aziraphale'\n    new_description = 'demon duties'\n    ds.update(new_friendly_name, new_description)\n\n    name, info = mock_api_datasets_update.call_args[0]\n    self.assertEqual(ds.name, name)\n\n    self.assertEqual(new_friendly_name, ds.friendly_name)\n    self.assertEqual(new_description, ds.description)\n\n  @staticmethod\n  def _create_context():\n    project_id = 'test'\n    creds = mock.Mock(spec=google.auth.credentials.Credentials)\n    return datalab.context.Context(project_id, creds)\n\n  @staticmethod\n  def _create_dataset(name, metadata=None):\n    # Patch get_info so we don't have to mock it everywhere else.\n    orig = datalab.bigquery.Dataset._get_info\n    datalab.bigquery.Dataset._get_info = mock.Mock(return_value=metadata)\n    ds = datalab.bigquery.Dataset(name, context=TestCases._create_context())\n    datalab.bigquery.Dataset._get_info = orig\n    return ds\n"
  },
  {
    "path": "legacy_tests/bigquery/federated_table_tests.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nimport collections\nimport mock\nimport unittest\n\nimport google.auth\nimport datalab.bigquery\nimport datalab.context\nimport datalab.utils\n\n\nclass TestCases(unittest.TestCase):\n\n  # The main thing we need to test is a query that references an external table and how\n  # that translates into a REST call.\n\n  @staticmethod\n  def _request_result():\n    return {\n      'jobReference': {\n        'jobId': 'job1234'\n      },\n      'configuration': {\n        'query': {\n          'destinationTable': {\n            'projectId': 'test',\n            'datasetId': 'dataset',\n            'tableId': 'table'\n          }\n        }\n      },\n      'jobComplete': True\n    }\n\n  @staticmethod\n  def _get_data():\n    data = []\n    day = 1\n    for weight in [220, 221, 220, 219, 218]:\n      d = collections.OrderedDict()\n      data.append(d)\n      d['day'] = day\n      day += 1\n      d['weight'] = weight\n    return data\n\n  @staticmethod\n  def _get_table_definition(uris, skip_rows=0):\n    if not isinstance(uris, list):\n      uris = [uris]\n    return {\n      'compression': 'NONE',\n      'csvOptions': {\n        'allowJaggedRows': False,\n        'quote': '\"',\n        'encoding': 'UTF-8',\n        'skipLeadingRows': skip_rows,\n        'fieldDelimiter': ',',\n        'allowQuotedNewlines': False\n      },\n      'sourceFormat': 'CSV',\n      'maxBadRecords': 0,\n      'ignoreUnknownValues': False,\n      'sourceUris': uris,\n      'schema': {\n        'fields': [\n          {'type': 'INTEGER', 'name': 'day'},\n          {'type': 'INTEGER', 'name': 'weight'}\n        ]\n      }\n    }\n\n  @staticmethod\n  def _get_expected_request_data(sql, table_definitions):\n    return {\n      'kind': 'bigquery#job',\n      'configuration': {\n        'priority': 'INTERACTIVE',\n        'query': {\n          'query': sql,\n          'useLegacySql': True,\n          'allowLargeResults': False,\n          'tableDefinitions': table_definitions,\n          'useQueryCache': True,\n          'userDefinedFunctionResources': []\n        },\n        'dryRun': False\n      }\n    }\n\n  @mock.patch('datalab.utils.Http.request')\n  def test_external_table_query(self, mock_http_request):\n    mock_http_request.return_value = self._request_result()\n\n    data = self._get_data()\n    schema = datalab.bigquery.Schema.from_data(data)\n\n    table_uri = 'gs://datalab/weight.csv'\n    options = datalab.bigquery.CSVOptions(skip_leading_rows=1)\n    sql = 'SELECT * FROM weight'\n\n    weight = datalab.bigquery.FederatedTable.from_storage(table_uri, schema=schema,\n                                                          csv_options=options)\n    q = datalab.bigquery.Query(sql, data_sources={'weight': weight}, context=self._create_context())\n    q.execute_async()\n\n    table_definition = self._get_table_definition(table_uri, skip_rows=1)\n    expected_data = self._get_expected_request_data(sql, {'weight': table_definition})\n    request_url = 'https://www.googleapis.com/bigquery/v2/projects/test/jobs/'\n\n    mock_http_request.assert_called_with(request_url, credentials=mock.ANY, data=expected_data)\n\n  # Test with multiple URLs and no non-default options\n  @mock.patch('datalab.utils.Http.request')\n  def test_external_table_query2(self, mock_http_request):\n    mock_http_request.return_value = self._request_result()\n\n    data = self._get_data()\n    schema = datalab.bigquery.Schema.from_data(data)\n\n    table_uris = ['gs://datalab/weight1.csv', 'gs://datalab/weight2.csv']\n    sql = 'SELECT * FROM weight'\n\n    weight = datalab.bigquery.FederatedTable.from_storage(table_uris, schema=schema)\n    q = datalab.bigquery.Query(sql, data_sources={'weight': weight}, context=self._create_context())\n    q.execute_async()\n\n    table_definition = self._get_table_definition(table_uris)\n    expected_data = self._get_expected_request_data(sql, {'weight': table_definition})\n    request_url = 'https://www.googleapis.com/bigquery/v2/projects/test/jobs/'\n\n    mock_http_request.assert_called_with(request_url, credentials=mock.ANY, data=expected_data)\n\n  # Test with multiple tables and using keyword args\n  @mock.patch('datalab.utils.Http.request')\n  def test_external_tables_query(self, mock_http_request):\n    mock_http_request.return_value = self._request_result()\n\n    data = self._get_data()\n    schema = datalab.bigquery.Schema.from_data(data)\n\n    table_uri1 = 'gs://datalab/weight1.csv'\n    table_uri2 = 'gs://datalab/weight2.csv'\n    sql = 'SELECT * FROM weight1 JOIN weight2 ON day'\n\n    options = datalab.bigquery.CSVOptions(skip_leading_rows=1)\n    weight1 = datalab.bigquery.FederatedTable.from_storage(table_uri1, schema=schema,\n                                                           csv_options=options)\n    weight2 = datalab.bigquery.FederatedTable.from_storage(table_uri2, schema=schema)\n    q = datalab.bigquery.Query(sql, weight1=weight1, weight2=weight2,\n                               context=self._create_context())\n    q.execute_async()\n\n    table_definition1 = self._get_table_definition(table_uri1, skip_rows=1)\n    table_definition2 = self._get_table_definition(table_uri2)\n    table_definitions = {'weight1': table_definition1, 'weight2': table_definition2}\n    expected_data = self._get_expected_request_data(sql, table_definitions)\n    request_url = 'https://www.googleapis.com/bigquery/v2/projects/test/jobs/'\n\n    mock_http_request.assert_called_with(request_url, credentials=mock.ANY, data=expected_data)\n\n  @staticmethod\n  def _create_context():\n    project_id = 'test'\n    creds = mock.Mock(spec=google.auth.credentials.Credentials)\n    return datalab.context.Context(project_id, creds)\n"
  },
  {
    "path": "legacy_tests/bigquery/jobs_tests.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nimport mock\nimport unittest\n\nimport google.auth\nimport datalab.bigquery\nimport datalab.context\n\n\nclass TestCases(unittest.TestCase):\n\n  @staticmethod\n  def _make_job(id):\n    return datalab.bigquery.Job(id, TestCases._create_context())\n\n  @mock.patch('datalab.bigquery._api.Api.jobs_get')\n  def test_job_complete(self, mock_api_jobs_get):\n    mock_api_jobs_get.return_value = {}\n    j = TestCases._make_job('foo')\n    self.assertFalse(j.is_complete)\n    self.assertFalse(j.failed)\n    mock_api_jobs_get.return_value = {'status': {'state': 'DONE'}}\n    self.assertTrue(j.is_complete)\n    self.assertFalse(j.failed)\n\n  @mock.patch('datalab.bigquery._api.Api.jobs_get')\n  def test_job_fatal_error(self, mock_api_jobs_get):\n    mock_api_jobs_get.return_value = {\n      'status': {\n        'state': 'DONE',\n        'errorResult': {\n          'location': 'A',\n          'message': 'B',\n          'reason': 'C'\n        }\n      }\n    }\n    j = TestCases._make_job('foo')\n    self.assertTrue(j.is_complete)\n    self.assertTrue(j.failed)\n    e = j.fatal_error\n    self.assertIsNotNone(e)\n    self.assertEqual('A', e.location)\n    self.assertEqual('B', e.message)\n    self.assertEqual('C', e.reason)\n\n  @mock.patch('datalab.bigquery._api.Api.jobs_get')\n  def test_job_errors(self, mock_api_jobs_get):\n    mock_api_jobs_get.return_value = {\n      'status': {\n        'state': 'DONE',\n        'errors': [\n          {\n            'location': 'A',\n            'message': 'B',\n            'reason': 'C'\n          },\n          {\n            'location': 'D',\n            'message': 'E',\n            'reason': 'F'\n          }\n        ]\n      }\n    }\n    j = TestCases._make_job('foo')\n    self.assertTrue(j.is_complete)\n    self.assertFalse(j.failed)\n    self.assertEqual(2, len(j.errors))\n    self.assertEqual('A', j.errors[0].location)\n    self.assertEqual('B', j.errors[0].message)\n    self.assertEqual('C', j.errors[0].reason)\n    self.assertEqual('D', j.errors[1].location)\n    self.assertEqual('E', j.errors[1].message)\n    self.assertEqual('F', j.errors[1].reason)\n\n  @staticmethod\n  def _create_context():\n    project_id = 'test'\n    creds = mock.Mock(spec=google.auth.credentials.Credentials)\n    return datalab.context.Context(project_id, creds)\n\n  @staticmethod\n  def _create_api():\n    return datalab.bigquery._api.Api(TestCases._create_context())\n"
  },
  {
    "path": "legacy_tests/bigquery/parser_tests.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nimport unittest\nimport datalab.bigquery as bq\n\n\nclass TestCases(unittest.TestCase):\n\n  def test_repeating_data(self):\n    schema = [{'name': 'counts', 'type': 'INTEGER', 'mode': 'REPEATED'}]\n    data = {'f': [{'v': [{'v': 0}, {'v': 1}, {'v': 2}]}]}\n    parsed = {'counts': [0, 1, 2]}\n    result = bq._parser.Parser.parse_row(schema, data)\n    self.assertEqual(parsed, result)\n\n  def test_non_nested_data(self):\n\n    data = {u'f': [{u'v': u'1969'},\n                   {u'v': u'1969'},\n                   {u'v': u'1'},\n                   {u'v': u'20'},\n                   {u'v': None},\n                   {u'v': u'AL'},\n                   {u'v': u'true'},\n                   {u'v': u'1'},\n                   {u'v': u'7.81318256528'},\n                   {u'v': None},\n                   {u'v': None},\n                   {u'v': None},\n                   {u'v': u'AL'},\n                   {u'v': u'1'},\n                   {u'v': u'20'},\n                   {u'v': None},\n                   {u'v': u'88881998'},\n                   {u'v': u'true'},\n                   {u'v': u''},\n                   {u'v': None},\n                   {u'v': None},\n                   {u'v': None},\n                   {u'v': None},\n                   {u'v': None},\n                   {u'v': u'1'},\n                   {u'v': u'0'},\n                   {u'v': u'0'},\n                   {u'v': u'2'},\n                   {u'v': u'1'},\n                   {u'v': u'19'},\n                   {u'v': u'2'}]}\n\n    natality_schema = [{u'description': u'Four-digit year of the birth. Example: 1975.',\n                        u'mode': u'REQUIRED',\n                        u'name': u'source_year',\n                        u'type': u'INTEGER'},\n                       {u'description': u'Four-digit year of the birth. Example: 1975.',\n                        u'mode': u'NULLABLE',\n                        u'name': u'year',\n                        u'type': u'INTEGER'},\n                       {u'description': u'Month index of the date of birth, where 1=January.',\n                        u'mode': u'NULLABLE',\n                        u'name': u'month',\n                        u'type': u'INTEGER'},\n                       {u'description': u'Day of birth, starting from 1.',\n                        u'mode': u'NULLABLE',\n                        u'name': u'day',\n                        u'type': u'INTEGER'},\n                       {u'description': u'Day of the week, where 1 is Sunday and 7 is Saturday.',\n                        u'mode': u'NULLABLE',\n                        u'name': u'wday',\n                        u'type': u'INTEGER'},\n                       {u'description': u'The two character postal code for the state. '\n                                        u'Entries after 2004 do not include this value.',\n                        u'mode': u'NULLABLE',\n                        u'name': u'state',\n                        u'type': u'STRING'},\n                       {u'description': u'TRUE if the child is male, FALSE if female.',\n                        u'mode': u'REQUIRED',\n                        u'name': u'is_male',\n                        u'type': u'BOOLEAN'},\n                       {u'description': u'The race of the child. One of the following numbers:\\n\\n'\n                                        u'1 - White\\n2 - Black\\n3 - American Indian\\n4 - Chinese\\n'\n                                        u'5 - Japanese\\n6 - Hawaiian\\n7 - Filipino\\n'\n                                        u'9 - Unknown/Other\\n18 - Asian Indian\\n28 - Korean\\n'\n                                        u'39 - Samoan\\n48 - Vietnamese',\n                        u'mode': u'NULLABLE',\n                        u'name': u'child_race',\n                        u'type': u'INTEGER'},\n                       {u'description': u'Weight of the child, in pounds.',\n                        u'mode': u'NULLABLE',\n                        u'name': u'weight_pounds',\n                        u'type': u'FLOAT'},\n                       {u'description': u'How many children were born as a result of this '\n                                        u'pregnancy. twins=2, triplets=3, and so on.',\n                        u'mode': u'NULLABLE',\n                        u'name': u'plurality',\n                        u'type': u'INTEGER'},\n                       {u'description': u'Apgar scores measure the health of a newborn child on a '\n                                        u'scale from 0-10. Value after 1 minute. Available from '\n                                        u'1978-2002.',\n                        u'mode': u'NULLABLE',\n                        u'name': u'apgar_1min',\n                        u'type': u'INTEGER'},\n                       {u'description': u'Apgar scores measure the health of a newborn child on a '\n                                        u'scale from 0-10. Value after 5 minutes. Available from '\n                                        u'1978-2002.',\n                        u'mode': u'NULLABLE',\n                        u'name': u'apgar_5min',\n                        u'type': u'INTEGER'},\n                       {u'description': u\"The two-letter postal code of the mother's state of \"\n                                        u\"residence when the child was born.\",\n                        u'mode': u'NULLABLE',\n                        u'name': u'mother_residence_state',\n                        u'type': u'STRING'},\n                       {u'description': u'Race of the mother. Same values as child_race.',\n                        u'mode': u'NULLABLE',\n                        u'name': u'mother_race',\n                        u'type': u'INTEGER'},\n                       {u'description': u'Reported age of the mother when giving birth.',\n                        u'mode': u'NULLABLE',\n                        u'name': u'mother_age',\n                        u'type': u'INTEGER'},\n                       {u'description': u'The number of weeks of the pregnancy.',\n                        u'mode': u'NULLABLE',\n                        u'name': u'gestation_weeks',\n                        u'type': u'INTEGER'},\n                       {u'description': u'Date of the last menstrual period in the format '\n                                        u'MMDDYYYY. Unknown values are recorded as \"99\" or \"9999\".',\n                        u'mode': u'NULLABLE',\n                        u'name': u'lmp',\n                        u'type': u'STRING'},\n                       {u'description': u'True if the mother was married when she gave birth.',\n                        u'mode': u'NULLABLE',\n                        u'name': u'mother_married',\n                        u'type': u'BOOLEAN'},\n                       {u'description': u\"The two-letter postal code of the mother's birth state.\",\n                        u'mode': u'NULLABLE',\n                        u'name': u'mother_birth_state',\n                        u'type': u'STRING'},\n                       {u'description': u'True if the mother smoked cigarettes. Available starting '\n                                        u'2003.',\n                        u'mode': u'NULLABLE',\n                        u'name': u'cigarette_use',\n                        u'type': u'BOOLEAN'},\n                       {u'description': u'Number of cigarettes smoked by the mother per day. '\n                                        u'Available starting 2003.',\n                        u'mode': u'NULLABLE',\n                        u'name': u'cigarettes_per_day',\n                        u'type': u'INTEGER'},\n                       {u'description': u'True if the mother used alcohol. Available starting '\n                                        u'1989.',\n                        u'mode': u'NULLABLE',\n                        u'name': u'alcohol_use',\n                        u'type': u'BOOLEAN'},\n                       {u'description': u'Number of drinks per week consumed by the mother. '\n                                        u'Available starting 1989.',\n                        u'mode': u'NULLABLE',\n                        u'name': u'drinks_per_week',\n                        u'type': u'INTEGER'},\n                       {u'description': u'Number of pounds gained by the mother during pregnancy.',\n                        u'mode': u'NULLABLE',\n                        u'name': u'weight_gain_pounds',\n                        u'type': u'INTEGER'},\n                       {u'description': u'Number of children previously born to the mother who are '\n                                        u'now living.',\n                        u'mode': u'NULLABLE',\n                        u'name': u'born_alive_alive',\n                        u'type': u'INTEGER'},\n                       {u'description': u'Number of children previously born to the mother who are '\n                                        u'now dead.',\n                        u'mode': u'NULLABLE',\n                        u'name': u'born_alive_dead',\n                        u'type': u'INTEGER'},\n                       {u'description': u'Number of children who were born dead '\n                                        u'(i.e. miscarriages)',\n                        u'mode': u'NULLABLE',\n                        u'name': u'born_dead',\n                        u'type': u'INTEGER'},\n                       {u'description': u'Total number of children to whom the woman has ever '\n                                        u'given birth (includes the current birth).',\n                        u'mode': u'NULLABLE',\n                        u'name': u'ever_born',\n                        u'type': u'INTEGER'},\n                       {u'description': u'Race of the father. Same values as child_race.',\n                        u'mode': u'NULLABLE',\n                        u'name': u'father_race',\n                        u'type': u'INTEGER'},\n                       {u'description': u'Age of the father when the child was born.',\n                        u'mode': u'NULLABLE',\n                        u'name': u'father_age',\n                        u'type': u'INTEGER'},\n                       {u'description': u'1 or 2, where 1 is a row from a full-reporting area, and '\n                                        u'2 is a row from a 50% sample area.',\n                        u'mode': u'NULLABLE',\n                        u'name': u'record_weight',\n                        u'type': u'INTEGER'}]\n\n    parsed = {u'alcohol_use': None,\n              u'apgar_1min': None,\n              u'apgar_5min': None,\n              u'born_alive_alive': 1,\n              u'born_alive_dead': 0,\n              u'born_dead': 0,\n              u'child_race': 1,\n              u'cigarette_use': None,\n              u'cigarettes_per_day': None,\n              u'day': 20,\n              u'drinks_per_week': None,\n              u'ever_born': 2,\n              u'father_age': 19,\n              u'father_race': 1,\n              u'gestation_weeks': None,\n              u'is_male': True,\n              u'lmp': u'88881998',\n              u'month': 1,\n              u'mother_age': 20,\n              u'mother_birth_state': u'',\n              u'mother_married': True,\n              u'mother_race': 1,\n              u'mother_residence_state': u'AL',\n              u'plurality': None,\n              u'record_weight': 2,\n              u'source_year': 1969,\n              u'state': u'AL',\n              u'wday': None,\n              u'weight_gain_pounds': None,\n              u'weight_pounds': 7.81318256528,\n              u'year': 1969}\n\n    self.assertEqual(parsed, bq._parser.Parser.parse_row(natality_schema, data))\n\n  def test_parse_nested_data(self):\n\n    self.maxDiff = None  # Show full diff on failure\n    data = {u'f': [{u'v': {u'f': [{u'v': u'https://github.com/foo'},\n                                  {u'v': u'true'},\n                                  {u'v': u'2011/04/12 20:04:19 -0700'},\n                                  {u'v': u'true'},\n                                  {u'v': u'A website.'},\n                                  {u'v': u'17'},\n                                  {u'v': u'false'},\n                                  {u'v': u'true'},\n                                  {u'v': u'http://foo.com/'},\n                                  {u'v': None},\n                                  {u'v': None},\n                                  {u'v': u'424'},\n                                  {u'v': u'false'},\n                                  {u'v': u'foo'},\n                                  {u'v': None},\n                                  {u'v': u'foo'},\n                                  {u'v': u'0'},\n                                  {u'v': u'95'},\n                                  {u'v': u'2012/03/15 00:00:00 -0700'},\n                                  {u'v': u'Ruby'}]}},\n                   {u'v': {u'f': [{u'v': u'http://foo.com/'},\n                                  {u'v': u'Flickr'},\n                                  {u'v': u'd+github@foo.com'},\n                                  {u'v': u'94c21234567890abcdef25e704b88407'},\n                                  {u'v': u'San Francisco, California'},\n                                  {u'v': u'foo'},\n                                  {u'v': u'Foo Bar'},\n                                  {u'v': u'User'}]}},\n                   {u'v': u'2012/03/15 00:00:01 -0700'},\n                   {u'v': u'true'},\n                   {u'v': u'foo'},\n                   {u'v': {u'f': [{u'v': None},\n                                  {u'v': None},\n                                  {u'v': None},\n                                  {u'v': None},\n                                  {u'v': None},\n                                  {u'v': None},\n                                  {u'v': None},\n                                  {u'v': None},\n                                  {u'v': u'2de950123456789abcdef01234451feaf8ce6ae'},\n                                  {u'v': None},\n                                  {u'v': None},\n                                  {u'v': None},\n                                  {u'v': None},\n                                  {u'v': None},\n                                  {u'v': None},\n                                  {u'v': None},\n                                  {u'v': None},\n                                  {u'v': []},\n                                  {u'v': None},\n                                  {u'v': u'refs/heads/master'},\n                                  {u'v': None},\n                                  {u'v': u'1'},\n                                  {u'v': [\n                                      {u'v':\n                                          {u'f': [\n                                              {u'v': u'2de958ab480eabe2501b343425b451feaf8ce6ae'},\n                                              {u'v': u'd+github@foo.com'},\n                                              {u'v': u'Foo tastes good.'},\n                                              {u'v': u'Foo Bar'}]}}]},\n                                  {u'v': None},\n                                  {u'v': None}]}},\n                   {u'v': u'https://github.com/compare/d3e91cb736...2de958ab48'},\n                   {u'v': u'PushEvent'}]}\n\n    github_nested_schema = [{u'fields': [{u'name': u'url', u'type': u'STRING'},\n                                         {u'name': u'has_downloads', u'type': u'BOOLEAN'},\n                                         {u'name': u'created_at', u'type': u'STRING'},\n                                         {u'name': u'has_issues', u'type': u'BOOLEAN'},\n                                         {u'name': u'description', u'type': u'STRING'},\n                                         {u'name': u'forks', u'type': u'INTEGER'},\n                                         {u'name': u'fork', u'type': u'BOOLEAN'},\n                                         {u'name': u'has_wiki', u'type': u'BOOLEAN'},\n                                         {u'name': u'homepage', u'type': u'STRING'},\n                                         {u'name': u'integrate_branch', u'type': u'STRING'},\n                                         {u'name': u'master_branch', u'type': u'STRING'},\n                                         {u'name': u'size', u'type': u'INTEGER'},\n                                         {u'name': u'private', u'type': u'BOOLEAN'},\n                                         {u'name': u'name', u'type': u'STRING'},\n                                         {u'name': u'organization', u'type': u'STRING'},\n                                         {u'name': u'owner', u'type': u'STRING'},\n                                         {u'name': u'open_issues', u'type': u'INTEGER'},\n                                         {u'name': u'watchers', u'type': u'INTEGER'},\n                                         {u'name': u'pushed_at', u'type': u'STRING'},\n                                         {u'name': u'language', u'type': u'STRING'}],\n                             u'name': u'repository',\n                             u'type': u'RECORD'},\n                            {u'fields': [{u'name': u'blog', u'type': u'STRING'},\n                                         {u'name': u'company', u'type': u'STRING'},\n                                         {u'name': u'email', u'type': u'STRING'},\n                                         {u'name': u'gravatar_id', u'type': u'STRING'},\n                                         {u'name': u'location', u'type': u'STRING'},\n                                         {u'name': u'login', u'type': u'STRING'},\n                                         {u'name': u'name', u'type': u'STRING'},\n                                         {u'name': u'type', u'type': u'STRING'}],\n                             u'name': u'actor_attributes',\n                             u'type': u'RECORD'},\n                            {u'name': u'created_at', u'type': u'STRING'},\n                            {u'name': u'public', u'type': u'BOOLEAN'},\n                            {u'name': u'actor', u'type': u'STRING'},\n                            {u'fields': [\n                                {u'name': u'action', u'type': u'STRING'},\n                                {u'name': u'after', u'type': u'STRING'},\n                                {u'name': u'before', u'type': u'STRING'},\n                                {u'name': u'commit', u'type': u'STRING'},\n                                {u'fields': [\n                                    {u'name': u'commit_id', u'type': u'STRING'},\n                                    {u'name': u'body', u'type': u'STRING'},\n                                    {u'name': u'created_at', u'type': u'STRING'},\n                                    {u'name': u'id', u'type': u'INTEGER'},\n                                    {u'name': u'original_commit_id', u'type': u'STRING'},\n                                    {u'name': u'original_position', u'type': u'INTEGER'},\n                                    {u'name': u'path', u'type': u'STRING'},\n                                    {u'name': u'position', u'type': u'INTEGER'},\n                                    {u'name': u'updated_at', u'type': u'STRING'},\n                                    {u'fields': [{u'name': u'id', u'type': u'INTEGER'},\n                                                 {u'name': u'gravatar_id', u'type': u'STRING'},\n                                                 {u'name': u'avatar_url', u'type': u'STRING'},\n                                                 {u'name': u'login', u'type': u'STRING'},\n                                                 {u'name': u'url', u'type': u'STRING'}],\n                                     u'name': u'user', u'type': u'RECORD'},\n                                    {u'name': u'url', u'type': u'STRING'}],\n                                    u'name': u'comment', u'type': u'RECORD'},\n                                {u'name': u'comment_id', u'type': u'INTEGER'},\n                                {u'name': u'desc', u'type': u'STRING'},\n                                {u'name': u'description', u'type': u'STRING'},\n                                {u'name': u'head', u'type': u'STRING'},\n                                {u'name': u'id', u'type': u'INTEGER'},\n                                {u'name': u'issue', u'type': u'INTEGER'},\n                                {u'name': u'issue_id', u'type': u'INTEGER'},\n                                {u'name': u'master_branch', u'type': u'STRING'},\n                                {u'name': u'master', u'type': u'STRING'},\n                                {u'fields': [{u'name': u'id', u'type': u'INTEGER'},\n                                             {u'name': u'gravatar_id', u'type': u'STRING'},\n                                             {u'name': u'avatar_url', u'type': u'STRING'},\n                                             {u'name': u'login', u'type': u'STRING'},\n                                             {u'name': u'url', u'type': u'STRING'}],\n                                 u'name': u'member', u'type': u'RECORD'},\n                                {u'name': u'name', u'type': u'STRING'},\n                                {u'name': u'number', u'type': u'INTEGER'},\n                                {u'fields': [{u'name': u'action', u'type': u'STRING'},\n                                             {u'name': u'html_url', u'type': u'STRING'},\n                                             {u'name': u'page_name', u'type': u'STRING'},\n                                             {u'name': u'sha', u'type': u'STRING'},\n                                             {u'name': u'summary', u'type': u'STRING'},\n                                             {u'name': u'title', u'type': u'STRING'}],\n                                 u'mode': u'REPEATED', u'name': u'pages', u'type': u'RECORD'},\n                                {u'fields': [\n                                    {u'name': u'additions', u'type': u'INTEGER'},\n                                    {u'fields': [\n                                        {u'fields': [\n                                            {u'name': u'clone_url', u'type': u'STRING'},\n                                            {u'name': u'created_at', u'type': u'STRING'},\n                                            {u'name': u'description', u'type': u'STRING'},\n                                            {u'name': u'fork', u'type': u'BOOLEAN'},\n                                            {u'name': u'forks', u'type': u'INTEGER'},\n                                            {u'name': u'git_url', u'type': u'STRING'},\n                                            {u'name': u'has_downloads', u'type': u'BOOLEAN'},\n                                            {u'name': u'has_issues', u'type': u'BOOLEAN'},\n                                            {u'name': u'has_wiki', u'type': u'BOOLEAN'},\n                                            {u'name': u'homepage', u'type': u'STRING'},\n                                            {u'name': u'html_url', u'type': u'STRING'},\n                                            {u'name': u'id', u'type': u'INTEGER'},\n                                            {u'name': u'language', u'type': u'STRING'},\n                                            {u'name': u'master_branch', u'type': u'STRING'},\n                                            {u'name': u'name', u'type': u'STRING'},\n                                            {u'name': u'open_issues', u'type': u'INTEGER'},\n                                            {u'fields': [\n                                                {u'name': u'id', u'type': u'INTEGER'},\n                                                {u'name': u'gravatar_id', u'type': u'STRING'},\n                                                {u'name': u'avatar_url', u'type': u'STRING'},\n                                                {u'name': u'login', u'type': u'STRING'},\n                                                {u'name': u'url', u'type': u'STRING'}],\n                                                u'name': u'owner', u'type': u'RECORD'},\n                                            {u'name': u'private', u'type': u'BOOLEAN'},\n                                            {u'name': u'pushed_at', u'type': u'STRING'},\n                                            {u'name': u'size', u'type': u'INTEGER'},\n                                            {u'name': u'ssh_url', u'type': u'STRING'},\n                                            {u'name': u'svn_url', u'type': u'STRING'},\n                                            {u'name': u'updated_at', u'type': u'STRING'},\n                                            {u'name': u'watchers', u'type': u'INTEGER'},\n                                            {u'name': u'url', u'type': u'STRING'}],\n                                            u'name': u'repo', u'type': u'RECORD'},\n                                        {u'name': u'sha', u'type': u'STRING'},\n                                        {u'name': u'ref', u'type': u'STRING'},\n                                        {u'fields': [{u'name': u'id', u'type': u'INTEGER'},\n                                                     {u'name': u'gravatar_id', u'type': u'STRING'},\n                                                     {u'name': u'avatar_url', u'type': u'STRING'},\n                                                     {u'name': u'login', u'type': u'STRING'},\n                                                     {u'name': u'url', u'type': u'STRING'}],\n                                         u'name': u'user', u'type': u'RECORD'},\n                                        {u'name': u'label', u'type': u'STRING'}],\n                                        u'name': u'base', u'type': u'RECORD'},\n                                    {u'name': u'body', u'type': u'STRING'},\n                                    {u'name': u'changed_files', u'type': u'INTEGER'},\n                                    {u'name': u'closed_at', u'type': u'STRING'},\n                                    {u'name': u'comments', u'type': u'INTEGER'},\n                                    {u'name': u'commits', u'type': u'INTEGER'},\n                                    {u'name': u'created_at', u'type': u'STRING'},\n                                    {u'name': u'deletions', u'type': u'INTEGER'},\n                                    {u'name': u'diff_url', u'type': u'STRING'},\n                                    {u'fields': [\n                                        {u'fields': [\n                                            {u'name': u'clone_url', u'type': u'STRING'},\n                                            {u'name': u'created_at', u'type': u'STRING'},\n                                            {u'name': u'description', u'type': u'STRING'},\n                                            {u'name': u'fork', u'type': u'BOOLEAN'},\n                                            {u'name': u'forks', u'type': u'INTEGER'},\n                                            {u'name': u'git_url', u'type': u'STRING'},\n                                            {u'name': u'has_downloads', u'type': u'BOOLEAN'},\n                                            {u'name': u'has_issues', u'type': u'BOOLEAN'},\n                                            {u'name': u'has_wiki', u'type': u'BOOLEAN'},\n                                            {u'name': u'homepage', u'type': u'STRING'},\n                                            {u'name': u'html_url', u'type': u'STRING'},\n                                            {u'name': u'id', u'type': u'INTEGER'},\n                                            {u'name': u'language', u'type': u'STRING'},\n                                            {u'name': u'master_branch', u'type': u'STRING'},\n                                            {u'name': u'name', u'type': u'STRING'},\n                                            {u'name': u'open_issues', u'type': u'INTEGER'},\n                                            {u'fields': [\n                                                {u'name': u'id', u'type': u'INTEGER'},\n                                                {u'name': u'gravatar_id', u'type': u'STRING'},\n                                                {u'name': u'avatar_url', u'type': u'STRING'},\n                                                {u'name': u'login', u'type': u'STRING'},\n                                                {u'name': u'url', u'type': u'STRING'}],\n                                                u'name': u'owner', u'type': u'RECORD'},\n                                            {u'name': u'private', u'type': u'BOOLEAN'},\n                                            {u'name': u'pushed_at', u'type': u'STRING'},\n                                            {u'name': u'size', u'type': u'INTEGER'},\n                                            {u'name': u'ssh_url', u'type': u'STRING'},\n                                            {u'name': u'svn_url', u'type': u'STRING'},\n                                            {u'name': u'updated_at', u'type': u'STRING'},\n                                            {u'name': u'watchers', u'type': u'INTEGER'},\n                                            {u'name': u'url', u'type': u'STRING'}],\n                                            u'name': u'repo', u'type': u'RECORD'},\n                                        {u'name': u'sha', u'type': u'STRING'},\n                                        {u'name': u'ref', u'type': u'STRING'},\n                                        {u'fields': [{u'name': u'id', u'type': u'INTEGER'},\n                                                     {u'name': u'gravatar_id', u'type': u'STRING'},\n                                                     {u'name': u'avatar_url', u'type': u'STRING'},\n                                                     {u'name': u'login', u'type': u'STRING'},\n                                                     {u'name': u'url', u'type': u'STRING'}],\n                                         u'name': u'user', u'type': u'RECORD'},\n                                        {u'name': u'label', u'type': u'STRING'}],\n                                        u'name': u'head',\n                                        u'type': u'RECORD'},\n                                    {u'name': u'html_url', u'type': u'STRING'},\n                                    {u'name': u'issue_url', u'type': u'STRING'},\n                                    {u'name': u'id', u'type': u'INTEGER'},\n                                    {u'fields': [\n                                        {u'fields': [\n                                            {u'name': u'href', u'type': u'STRING'}],\n                                            u'name': u'self', u'type': u'RECORD'},\n                                        {u'fields': [{u'name': u'href', u'type': u'STRING'}],\n                                         u'name': u'html', u'type': u'RECORD'},\n                                        {u'fields': [{u'name': u'href', u'type': u'STRING'}],\n                                         u'name': u'review_comments', u'type': u'RECORD'},\n                                        {u'fields': [{u'name': u'href', u'type': u'STRING'}],\n                                         u'name': u'comments', u'type': u'RECORD'}],\n                                        u'name': u'_links', u'type': u'RECORD'},\n                                    {u'name': u'mergeable', u'type': u'BOOLEAN'},\n                                    {u'name': u'merged', u'type': u'BOOLEAN'},\n                                    {u'name': u'merged_at', u'type': u'STRING'},\n                                    {u'fields': [{u'name': u'id', u'type': u'INTEGER'},\n                                                 {u'name': u'gravatar_id', u'type': u'STRING'},\n                                                 {u'name': u'avatar_url', u'type': u'STRING'},\n                                                 {u'name': u'login', u'type': u'STRING'},\n                                                 {u'name': u'url', u'type': u'STRING'}],\n                                     u'name': u'merged_by', u'type': u'RECORD'},\n                                    {u'name': u'number', u'type': u'INTEGER'},\n                                    {u'name': u'patch_url', u'type': u'STRING'},\n                                    {u'name': u'review_comments', u'type': u'INTEGER'},\n                                    {u'name': u'state', u'type': u'STRING'},\n                                    {u'name': u'title', u'type': u'STRING'},\n                                    {u'name': u'updated_at', u'type': u'STRING'},\n                                    {u'name': u'url', u'type': u'STRING'},\n                                    {u'fields': [{u'name': u'id', u'type': u'INTEGER'},\n                                                 {u'name': u'gravatar_id', u'type': u'STRING'},\n                                                 {u'name': u'avatar_url', u'type': u'STRING'},\n                                                 {u'name': u'login', u'type': u'STRING'},\n                                                 {u'name': u'url', u'type': u'STRING'}],\n                                     u'name': u'user', u'type': u'RECORD'}],\n                                    u'name': u'pull_request', u'type': u'RECORD'},\n                                {u'name': u'ref', u'type': u'STRING'},\n                                {u'name': u'ref_type', u'type': u'STRING'},\n                                {u'name': u'size', u'type': u'INTEGER'},\n                                {u'fields': [\n                                    {u'name': u'encoded', u'type': u'STRING'},\n                                    {u'name': u'actor_email', u'type': u'STRING'},\n                                    {u'name': u'message', u'type': u'STRING'},\n                                    {u'name': u'actor_login', u'type': u'STRING'}],\n                                    u'mode': u'REPEATED', u'name': u'shas', u'type': u'RECORD'},\n                                {u'fields': [{u'name': u'login', u'type': u'STRING'},\n                                             {u'name': u'repos', u'type': u'INTEGER'},\n                                             {u'name': u'followers', u'type': u'INTEGER'},\n                                             {u'name': u'id', u'type': u'INTEGER'},\n                                             {u'name': u'gravatar_id', u'type': u'STRING'}],\n                                 u'name': u'target', u'type': u'RECORD'},\n                                {u'name': u'url', u'type': u'STRING'}],\n                                u'name': u'payload', u'type': u'RECORD'},\n                            {u'name': u'url', u'type': u'STRING'},\n                            {u'name': u'type', u'type': u'STRING'}]\n\n    parsed = {u'actor': u'foo',\n              u'actor_attributes': {u'blog': u'http://foo.com/',\n                                    u'company': u'Flickr',\n                                    u'email': u'd+github@foo.com',\n                                    u'gravatar_id': u'94c21234567890abcdef25e704b88407',\n                                    u'location': u'San Francisco, California',\n                                    u'login': u'foo',\n                                    u'name': u'Foo Bar',\n                                    u'type': u'User'},\n              u'created_at': u'2012/03/15 00:00:01 -0700',\n              u'payload': {u'action': None,\n                           u'after': None,\n                           u'before': None,\n                           u'comment': {},\n                           u'comment_id': None,\n                           u'commit': None,\n                           u'desc': None,\n                           u'description': None,\n                           u'head': u'2de950123456789abcdef01234451feaf8ce6ae',\n                           u'id': None,\n                           u'issue': None,\n                           u'issue_id': None,\n                           u'master': None,\n                           u'master_branch': None,\n                           u'member': {},\n                           u'name': None,\n                           u'number': None,\n                           u'pages': [],\n                           u'pull_request': {},\n                           u'ref': u'refs/heads/master',\n                           u'ref_type': None,\n                           u'shas': [{u'actor_email': u'd+github@foo.com',\n                                      u'actor_login': u'Foo Bar',\n                                      u'encoded': u'2de958ab480eabe2501b343425b451feaf8ce6ae',\n                                      u'message': u'Foo tastes good.'}],\n                           u'size': 1,\n                           u'target': {},\n                           u'url': None},\n              u'public': True,\n              u'repository': {u'created_at': u'2011/04/12 20:04:19 -0700',\n                              u'description': u'A website.',\n                              u'fork': False,\n                              u'forks': 17,\n                              u'has_downloads': True,\n                              u'has_issues': True,\n                              u'has_wiki': True,\n                              u'homepage': u'http://foo.com/',\n                              u'integrate_branch': None,\n                              u'language': u'Ruby',\n                              u'master_branch': None,\n                              u'name': u'foo',\n                              u'open_issues': 0,\n                              u'organization': None,\n                              u'owner': u'foo',\n                              u'private': False,\n                              u'pushed_at': u'2012/03/15 00:00:00 -0700',\n                              u'size': 424,\n                              u'url': u'https://github.com/foo',\n                              u'watchers': 95},\n              u'type': u'PushEvent',\n              u'url': u'https://github.com/compare/d3e91cb736...2de958ab48'}\n\n    self.assertEqual(parsed, bq._parser.Parser.parse_row(github_nested_schema, data))\n"
  },
  {
    "path": "legacy_tests/bigquery/query_tests.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom builtins import str\nimport mock\nimport unittest\n\nimport google.auth\nimport datalab.bigquery\nimport datalab.context\n\n\nclass TestCases(unittest.TestCase):\n\n  @mock.patch('datalab.bigquery._api.Api.tabledata_list')\n  @mock.patch('datalab.bigquery._api.Api.jobs_insert_query')\n  @mock.patch('datalab.bigquery._api.Api.jobs_query_results')\n  @mock.patch('datalab.bigquery._api.Api.jobs_get')\n  @mock.patch('datalab.bigquery._api.Api.tables_get')\n  def test_single_result_query(self, mock_api_tables_get, mock_api_jobs_get,\n                               mock_api_jobs_query_results, mock_api_insert_query,\n                               mock_api_tabledata_list):\n    mock_api_tables_get.return_value = TestCases._create_tables_get_result()\n    mock_api_jobs_get.return_value = {'status': {'state': 'DONE'}}\n    mock_api_jobs_query_results.return_value = {'jobComplete': True}\n    mock_api_insert_query.return_value = TestCases._create_insert_done_result()\n    mock_api_tabledata_list.return_value = TestCases._create_single_row_result()\n\n    sql = 'SELECT field1 FROM [table] LIMIT 1'\n    q = TestCases._create_query(sql)\n    results = q.results()\n\n    self.assertEqual(sql, results.sql)\n    self.assertEqual('(%s)' % sql, q._repr_sql_())\n    self.assertEqual(sql, str(q))\n    self.assertEqual(1, results.length)\n    first_result = results[0]\n    self.assertEqual('value1', first_result['field1'])\n\n  @mock.patch('datalab.bigquery._api.Api.jobs_insert_query')\n  @mock.patch('datalab.bigquery._api.Api.jobs_query_results')\n  @mock.patch('datalab.bigquery._api.Api.jobs_get')\n  @mock.patch('datalab.bigquery._api.Api.tables_get')\n  def test_empty_result_query(self, mock_api_tables_get, mock_api_jobs_get,\n                              mock_api_jobs_query_results, mock_api_insert_query):\n    mock_api_tables_get.return_value = TestCases._create_tables_get_result(0)\n    mock_api_jobs_get.return_value = {'status': {'state': 'DONE'}}\n    mock_api_jobs_query_results.return_value = {'jobComplete': True}\n    mock_api_insert_query.return_value = TestCases._create_insert_done_result()\n\n    q = TestCases._create_query()\n    results = q.results()\n\n    self.assertEqual(0, results.length)\n\n  @mock.patch('datalab.bigquery._api.Api.jobs_insert_query')\n  @mock.patch('datalab.bigquery._api.Api.jobs_query_results')\n  @mock.patch('datalab.bigquery._api.Api.jobs_get')\n  @mock.patch('datalab.bigquery._api.Api.tables_get')\n  def test_incomplete_result_query(self,\n                                   mock_api_tables_get,\n                                   mock_api_jobs_get,\n                                   mock_api_jobs_query_results,\n                                   mock_api_insert_query):\n    mock_api_tables_get.return_value = TestCases._create_tables_get_result()\n    mock_api_jobs_get.return_value = {'status': {'state': 'DONE'}}\n    mock_api_jobs_query_results.return_value = {'jobComplete': True}\n    mock_api_insert_query.return_value = TestCases._create_incomplete_result()\n\n    q = TestCases._create_query()\n    results = q.results()\n\n    self.assertEqual(1, results.length)\n    self.assertEqual('test_job', results.job_id)\n\n  @mock.patch('datalab.bigquery._api.Api.jobs_insert_query')\n  def test_malformed_response_raises_exception(self, mock_api_insert_query):\n    mock_api_insert_query.return_value = {}\n\n    q = TestCases._create_query()\n\n    with self.assertRaises(Exception) as error:\n      q.results()\n    self.assertEqual('Unexpected response from server', str(error.exception))\n\n  def test_udf_expansion(self):\n    sql = 'SELECT * FROM udf(source)'\n    udf = datalab.bigquery.UDF('inputs', [('foo', 'string'), ('bar', 'integer')], 'udf', 'code')\n    context = TestCases._create_context()\n    query = datalab.bigquery.Query(sql, udf=udf, context=context)\n    self.assertEquals('SELECT * FROM (SELECT foo, bar FROM udf(source))', query.sql)\n\n    # Alternate form\n    query = datalab.bigquery.Query(sql, udfs=[udf], context=context)\n    self.assertEquals('SELECT * FROM (SELECT foo, bar FROM udf(source))', query.sql)\n\n  @staticmethod\n  def _create_query(sql=None):\n    if sql is None:\n      sql = 'SELECT * ...'\n    return datalab.bigquery.Query(sql, context=TestCases._create_context())\n\n  @staticmethod\n  def _create_context():\n    project_id = 'test'\n    creds = mock.Mock(spec=google.auth.credentials.Credentials)\n    return datalab.context.Context(project_id, creds)\n\n  @staticmethod\n  def _create_insert_done_result():\n    # pylint: disable=g-continuation-in-parens-misaligned\n    return {\n      'jobReference': {\n        'jobId': 'test_job'\n      },\n      'configuration': {\n        'query': {\n          'destinationTable': {\n            'projectId': 'project',\n            'datasetId': 'dataset',\n            'tableId': 'table'\n          }\n        }\n      },\n      'jobComplete': True,\n    }\n\n  @staticmethod\n  def _create_single_row_result():\n    # pylint: disable=g-continuation-in-parens-misaligned\n    return {\n      'totalRows': 1,\n      'rows': [\n        {'f': [{'v': 'value1'}]}\n      ]\n    }\n\n  @staticmethod\n  def _create_empty_result():\n    # pylint: disable=g-continuation-in-parens-misaligned\n    return {\n      'totalRows': 0\n    }\n\n  @staticmethod\n  def _create_incomplete_result():\n    # pylint: disable=g-continuation-in-parens-misaligned\n    return {\n      'jobReference': {\n        'jobId': 'test_job'\n      },\n      'configuration': {\n        'query': {\n          'destinationTable': {\n            'projectId': 'project',\n            'datasetId': 'dataset',\n            'tableId': 'table'\n          }\n        }\n      },\n      'jobComplete': False\n    }\n\n  @staticmethod\n  def _create_page_result(page_token=None):\n    # pylint: disable=g-continuation-in-parens-misaligned\n    return {\n      'totalRows': 2,\n      'rows': [\n        {'f': [{'v': 'value1'}]}\n      ],\n      'pageToken': page_token\n    }\n\n  @staticmethod\n  def _create_tables_get_result(num_rows=1, schema=None):\n    if schema is None:\n      schema = [{'name': 'field1', 'type': 'string'}]\n    return {\n      'numRows': num_rows,\n      'schema': {\n        'fields': schema\n      },\n    }\n"
  },
  {
    "path": "legacy_tests/bigquery/sampling_tests.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nimport unittest\nfrom datalab.bigquery import Sampling\n\n\nclass TestCases(unittest.TestCase):\n\n  BASE_SQL = '[<q>]'\n\n  def test_default(self):\n    expected_sql = 'SELECT * FROM (%s) LIMIT 5' % TestCases.BASE_SQL\n    self._apply_sampling(Sampling.default(), expected_sql)\n\n  def test_default_custom_count(self):\n    expected_sql = 'SELECT * FROM (%s) LIMIT 20' % TestCases.BASE_SQL\n    self._apply_sampling(Sampling.default(count=20), expected_sql)\n\n  def test_default_custom_fields(self):\n    expected_sql = 'SELECT f1,f2 FROM (%s) LIMIT 5' % TestCases.BASE_SQL\n    self._apply_sampling(Sampling.default(fields=['f1', 'f2']), expected_sql)\n\n  def test_default_all_fields(self):\n    expected_sql = 'SELECT * FROM (%s) LIMIT 5' % TestCases.BASE_SQL\n    self._apply_sampling(Sampling.default(fields=[]), expected_sql)\n\n  def test_hashed(self):\n    expected_sql = 'SELECT * FROM (%s) WHERE ABS(HASH(f1)) %% 100 < 5' % TestCases.BASE_SQL\n    self._apply_sampling(Sampling.hashed('f1', 5), expected_sql)\n\n  def test_hashed_and_limited(self):\n    expected_sql = 'SELECT * FROM (%s) WHERE ABS(HASH(f1)) %% 100 < 5 LIMIT 100' \\\n                   % TestCases.BASE_SQL\n    self._apply_sampling(Sampling.hashed('f1', 5, count=100), expected_sql)\n\n  def test_hashed_with_fields(self):\n    expected_sql = 'SELECT f1 FROM (%s) WHERE ABS(HASH(f1)) %% 100 < 5' % TestCases.BASE_SQL\n    self._apply_sampling(Sampling.hashed('f1', 5, fields=['f1']), expected_sql)\n\n  def test_sorted_ascending(self):\n    expected_sql = 'SELECT * FROM (%s) ORDER BY f1 LIMIT 5' % TestCases.BASE_SQL\n    self._apply_sampling(Sampling.sorted('f1'), expected_sql)\n\n  def test_sorted_descending(self):\n    expected_sql = 'SELECT * FROM (%s) ORDER BY f1 DESC LIMIT 5' % TestCases.BASE_SQL\n    self._apply_sampling(Sampling.sorted('f1', ascending=False), expected_sql)\n\n  def test_sorted_with_fields(self):\n    expected_sql = 'SELECT f1,f2 FROM (%s) ORDER BY f1 LIMIT 5' % TestCases.BASE_SQL\n    self._apply_sampling(Sampling.sorted('f1', fields=['f1', 'f2']), expected_sql)\n\n  def _apply_sampling(self, sampling, expected_query):\n    sampled_query = sampling(TestCases.BASE_SQL)\n    self.assertEqual(sampled_query, expected_query)\n"
  },
  {
    "path": "legacy_tests/bigquery/schema_tests.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nimport collections\nimport pandas\nimport sys\nimport unittest\n\nimport datalab.bigquery\nimport datalab.utils\n\n\nclass TestCases(unittest.TestCase):\n\n  def test_schema_from_dataframe(self):\n    df = TestCases._create_data_frame()\n    result = datalab.bigquery.Schema.from_data(df)\n    self.assertEqual(datalab.bigquery.Schema.from_data(TestCases._create_inferred_schema()), result)\n\n  def test_schema_from_data(self):\n    variant1 = [\n      3,\n      2.0,\n      True,\n      ['cow', 'horse', [0, []]]\n    ]\n    variant2 = collections.OrderedDict()\n    variant2['Column1'] = 3\n    variant2['Column2'] = 2.0\n    variant2['Column3'] = True\n    variant2['Column4'] = collections.OrderedDict()\n    variant2['Column4']['Column1'] = 'cow'\n    variant2['Column4']['Column2'] = 'horse'\n    variant2['Column4']['Column3'] = collections.OrderedDict()\n    variant2['Column4']['Column3']['Column1'] = 0\n    variant2['Column4']['Column3']['Column2'] = collections.OrderedDict()\n\n    master = [\n      {'name': 'Column1', 'type': 'INTEGER'},\n      {'name': 'Column2', 'type': 'FLOAT'},\n      {'name': 'Column3', 'type': 'BOOLEAN'},\n      {'name': 'Column4', 'type': 'RECORD', 'fields': [\n          {'name': 'Column1', 'type': 'STRING'},\n          {'name': 'Column2', 'type': 'STRING'},\n          {'name': 'Column3', 'type': 'RECORD', 'fields': [\n              {'name': 'Column1', 'type': 'INTEGER'},\n              {'name': 'Column2', 'type': 'RECORD', 'fields': []}\n          ]}\n      ]}\n    ]\n\n    schema_master = datalab.bigquery.Schema(master)\n\n    with self.assertRaises(Exception) as error1:\n      datalab.bigquery.Schema.from_data(variant1)\n    if sys.version_info[0] == 3:\n      self.assertEquals('Cannot create a schema from heterogeneous list [3, 2.0, True, ' +\n                        '[\\'cow\\', \\'horse\\', [0, []]]]; perhaps you meant to use ' +\n                        'Schema.from_record?', str(error1.exception))\n    else:\n      self.assertEquals('Cannot create a schema from heterogeneous list [3, 2.0, True, ' +\n                        '[u\\'cow\\', u\\'horse\\', [0, []]]]; perhaps you meant to use ' +\n                        'Schema.from_record?', str(error1.exception))\n    with self.assertRaises(Exception) as error2:\n      datalab.bigquery.Schema.from_data(variant2)\n    if sys.version_info[0] == 3:\n      self.assertEquals('Cannot create a schema from dict OrderedDict([(\\'Column1\\', 3), ' +\n                        '(\\'Column2\\', 2.0), (\\'Column3\\', True), (\\'Column4\\', ' +\n                        'OrderedDict([(\\'Column1\\', \\'cow\\'), (\\'Column2\\', \\'horse\\'), ' +\n                        '(\\'Column3\\', OrderedDict([(\\'Column1\\', 0), (\\'Column2\\', ' +\n                        'OrderedDict())]))]))]); perhaps you meant to use Schema.from_record?',\n                        str(error2.exception))\n    else:\n      self.assertEquals('Cannot create a schema from dict OrderedDict([(u\\'Column1\\', 3), ' +\n                        '(u\\'Column2\\', 2.0), (u\\'Column3\\', True), (u\\'Column4\\', ' +\n                        'OrderedDict([(u\\'Column1\\', u\\'cow\\'), (u\\'Column2\\', u\\'horse\\'), ' +\n                        '(u\\'Column3\\', OrderedDict([(u\\'Column1\\', 0), (u\\'Column2\\', ' +\n                        'OrderedDict())]))]))]); perhaps you meant to use Schema.from_record?',\n                        str(error2.exception))\n    schema3 = datalab.bigquery.Schema.from_data([variant1])\n    schema4 = datalab.bigquery.Schema.from_data([variant2])\n    schema5 = datalab.bigquery.Schema.from_data(master)\n    schema6 = datalab.bigquery.Schema.from_record(variant1)\n    schema7 = datalab.bigquery.Schema.from_record(variant2)\n\n    self.assertEquals(schema_master, schema3, 'schema inferred from list of lists with from_data')\n    self.assertEquals(schema_master, schema4, 'schema inferred from list of dicts with from_data')\n    self.assertEquals(schema_master, schema5, 'schema inferred from BQ schema list with from_data')\n    self.assertEquals(schema_master, schema6, 'schema inferred from list with from_record')\n    self.assertEquals(schema_master, schema7, 'schema inferred from dict with from_record')\n\n  @staticmethod\n  def _create_data_frame():\n    data = {\n      'some': [\n        0, 1, 2, 3\n      ],\n      'column': [\n        'r0', 'r1', 'r2', 'r3'\n      ],\n      'headers': [\n        10.0, 10.0, 10.0, 10.0\n      ]\n    }\n    return pandas.DataFrame(data)\n\n  @staticmethod\n  def _create_inferred_schema(extra_field=None):\n    schema = [\n      {'name': 'some', 'type': 'INTEGER'},\n      {'name': 'column', 'type': 'STRING'},\n      {'name': 'headers', 'type': 'FLOAT'},\n    ]\n    if extra_field:\n      schema.append({'name': extra_field, 'type': 'INTEGER'})\n    return schema\n"
  },
  {
    "path": "legacy_tests/bigquery/table_tests.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom builtins import str\nfrom builtins import object\nimport calendar\nimport datetime as dt\nimport mock\nimport pandas\nimport unittest\n\nimport google.auth\nimport datalab.bigquery\nimport datalab.context\nimport datalab.utils\n\n\nclass TestCases(unittest.TestCase):\n\n  def _check_name_parts(self, table):\n    parsed_name = table._name_parts\n    self.assertEqual('test', parsed_name[0])\n    self.assertEqual('requestlogs', parsed_name[1])\n    self.assertEqual('today', parsed_name[2])\n    self.assertEqual('', parsed_name[3])\n    self.assertEqual('[test:requestlogs.today]', table._repr_sql_())\n    self.assertEqual('test:requestlogs.today', str(table))\n\n  def test_api_paths(self):\n    name = datalab.bigquery._utils.TableName('a', 'b', 'c', 'd')\n    self.assertEqual('/projects/a/datasets/b/tables/cd',\n                     datalab.bigquery._api.Api._TABLES_PATH % name)\n    self.assertEqual('/projects/a/datasets/b/tables/cd/data',\n                     datalab.bigquery._api.Api._TABLEDATA_PATH % name)\n    name = datalab.bigquery._utils.DatasetName('a', 'b')\n    self.assertEqual('/projects/a/datasets/b', datalab.bigquery._api.Api._DATASETS_PATH % name)\n\n  def test_parse_full_name(self):\n    table = TestCases._create_table('test:requestlogs.today')\n    self._check_name_parts(table)\n\n  def test_parse_local_name(self):\n    table = TestCases._create_table('requestlogs.today')\n    self._check_name_parts(table)\n\n  def test_parse_dict_full_name(self):\n    table = TestCases._create_table({'project_id': 'test', 'dataset_id': 'requestlogs',\n                                     'table_id': 'today'})\n    self._check_name_parts(table)\n\n  def test_parse_dict_local_name(self):\n    table = TestCases._create_table({'dataset_id': 'requestlogs', 'table_id': 'today'})\n    self._check_name_parts(table)\n\n  def test_parse_named_tuple_name(self):\n    table = TestCases._create_table(datalab.bigquery._utils.TableName('test',\n                                                                      'requestlogs', 'today', ''))\n    self._check_name_parts(table)\n\n  def test_parse_tuple_full_name(self):\n    table = TestCases._create_table(('test', 'requestlogs', 'today'))\n    self._check_name_parts(table)\n\n  def test_parse_tuple_local(self):\n    table = TestCases._create_table(('requestlogs', 'today'))\n    self._check_name_parts(table)\n\n  def test_parse_array_full_name(self):\n    table = TestCases._create_table(['test', 'requestlogs', 'today'])\n    self._check_name_parts(table)\n\n  def test_parse_array_local(self):\n    table = TestCases._create_table(['requestlogs', 'today'])\n    self._check_name_parts(table)\n\n  def test_parse_invalid_name(self):\n    with self.assertRaises(Exception):\n      TestCases._create_table('today@')\n\n  @mock.patch('datalab.bigquery._api.Api.tables_get')\n  def test_table_metadata(self, mock_api_tables_get):\n    name = 'test:requestlogs.today'\n    ts = dt.datetime.utcnow()\n\n    mock_api_tables_get.return_value = TestCases._create_table_info_result(ts=ts)\n    t = TestCases._create_table(name)\n\n    metadata = t.metadata\n\n    self.assertEqual('Logs', metadata.friendly_name)\n    self.assertEqual(2, metadata.rows)\n    self.assertEqual(2, metadata.rows)\n    self.assertTrue(abs((metadata.created_on - ts).total_seconds()) <= 1)\n    self.assertEqual(None, metadata.expires_on)\n\n  @mock.patch('datalab.bigquery._api.Api.tables_get')\n  def test_table_schema(self, mock_api_tables):\n    mock_api_tables.return_value = TestCases._create_table_info_result()\n\n    t = TestCases._create_table('test:requestlogs.today')\n    schema = t.schema\n\n    self.assertEqual(2, len(schema))\n    self.assertEqual('name', schema[0].name)\n\n  @mock.patch('datalab.bigquery._api.Api.tables_get')\n  def test_table_schema_nested(self, mock_api_tables):\n    mock_api_tables.return_value = TestCases._create_table_info_nested_schema_result()\n\n    t = TestCases._create_table('test:requestlogs.today')\n    schema = t.schema\n\n    self.assertEqual(4, len(schema))\n    self.assertEqual('name', schema[0].name)\n    self.assertEqual('val', schema[1].name)\n    self.assertEqual('more', schema[2].name)\n    self.assertEqual('more.xyz', schema[3].name)\n\n    self.assertIsNone(schema['value'])\n    self.assertIsNotNone(schema['val'])\n\n  @mock.patch('datalab.bigquery._api.Api.tables_get')\n  def test_malformed_response_raises_exception(self, mock_api_tables_get):\n    mock_api_tables_get.return_value = {}\n\n    t = TestCases._create_table('test:requestlogs.today')\n\n    with self.assertRaises(Exception) as error:\n      t.schema\n    self.assertEqual('Unexpected table response: missing schema', str(error.exception))\n\n  @mock.patch('datalab.bigquery._api.Api.tables_list')\n  @mock.patch('datalab.bigquery._api.Api.datasets_get')\n  def test_dataset_list(self, mock_api_datasets_get, mock_api_tables_list):\n    mock_api_datasets_get.return_value = None\n    mock_api_tables_list.return_value = TestCases._create_table_list_result()\n\n    ds = datalab.bigquery.Dataset('testds', context=TestCases._create_context())\n\n    tables = []\n    for table in ds:\n      tables.append(table)\n    self.assertEqual(2, len(tables))\n    self.assertEqual('test:testds.testTable1', str(tables[0]))\n    self.assertEqual('test:testds.testTable2', str(tables[1]))\n\n  @mock.patch('datalab.bigquery._api.Api.tables_list')\n  @mock.patch('datalab.bigquery._api.Api.datasets_get')\n  def test_table_list(self, mock_api_datasets_get, mock_api_tables_list):\n    mock_api_datasets_get.return_value = None\n    mock_api_tables_list.return_value = TestCases._create_table_list_result()\n\n    ds = datalab.bigquery.Dataset('testds', context=TestCases._create_context())\n\n    tables = []\n    for table in ds.tables():\n      tables.append(table)\n    self.assertEqual(2, len(tables))\n    self.assertEqual('test:testds.testTable1', str(tables[0]))\n    self.assertEqual('test:testds.testTable2', str(tables[1]))\n\n  @mock.patch('datalab.bigquery._api.Api.tables_list')\n  @mock.patch('datalab.bigquery._api.Api.datasets_get')\n  def test_view_list(self, mock_api_datasets_get, mock_api_tables_list):\n    mock_api_datasets_get.return_value = None\n    mock_api_tables_list.return_value = TestCases._create_table_list_result()\n\n    ds = datalab.bigquery.Dataset('testds', context=TestCases._create_context())\n\n    views = []\n    for view in ds.views():\n      views.append(view)\n    self.assertEqual(1, len(views))\n    self.assertEqual('test:testds.testView1', str(views[0]))\n\n  @mock.patch('datalab.bigquery._api.Api.tables_list')\n  @mock.patch('datalab.bigquery._api.Api.datasets_get')\n  def test_table_list_empty(self, mock_api_datasets_get, mock_api_tables_list):\n    mock_api_datasets_get.return_value = None\n    mock_api_tables_list.return_value = TestCases._create_table_list_empty_result()\n\n    ds = datalab.bigquery.Dataset('testds', context=TestCases._create_context())\n\n    tables = []\n    for table in ds:\n      tables.append(table)\n\n    self.assertEqual(0, len(tables))\n\n  @mock.patch('datalab.bigquery._api.Api.tables_get')\n  def test_table_exists(self, mock_api_tables_get):\n    mock_api_tables_get.return_value = None\n    tbl = datalab.bigquery.Table('testds.testTable0', context=TestCases._create_context())\n    self.assertTrue(tbl.exists())\n\n    mock_api_tables_get.side_effect = datalab.utils.RequestException(404, 'failed')\n    self.assertFalse(tbl.exists())\n\n  @mock.patch('datalab.bigquery._api.Api.tables_insert')\n  @mock.patch('datalab.bigquery._api.Api.tables_list')\n  @mock.patch('datalab.bigquery._api.Api.datasets_get')\n  def test_tables_create(self,\n                         mock_api_datasets_get,\n                         mock_api_tables_list,\n                         mock_api_tables_insert):\n    mock_api_datasets_get.return_value = None\n    mock_api_tables_list.return_value = []\n    schema = TestCases._create_inferred_schema()\n\n    mock_api_tables_insert.return_value = {}\n    with self.assertRaises(Exception) as error:\n      TestCases._create_table_with_schema(schema)\n    self.assertEqual('Table test:testds.testTable0 could not be created as it already exists',\n                     str(error.exception))\n\n    mock_api_tables_insert.return_value = {'selfLink': 'http://foo'}\n    self.assertIsNotNone(TestCases._create_table_with_schema(schema), 'Expected a table')\n\n  @mock.patch('uuid.uuid4')\n  @mock.patch('time.sleep')\n  @mock.patch('datalab.bigquery._api.Api.tables_list')\n  @mock.patch('datalab.bigquery._api.Api.tables_insert')\n  @mock.patch('datalab.bigquery._api.Api.tables_get')\n  @mock.patch('datalab.bigquery._api.Api.tabledata_insert_all')\n  @mock.patch('datalab.bigquery._api.Api.datasets_get')\n  def test_insert_data_no_table(self,\n                                mock_api_datasets_get,\n                                mock_api_tabledata_insert_all,\n                                mock_api_tables_get,\n                                mock_api_tables_insert,\n                                mock_api_tables_list,\n                                mock_time_sleep,\n                                mock_uuid):\n    mock_uuid.return_value = TestCases._create_uuid()\n    mock_time_sleep.return_value = None\n    mock_api_tables_list.return_value = []\n    mock_api_tables_insert.return_value = {'selfLink': 'http://foo'}\n    mock_api_tables_get.side_effect = datalab.utils.RequestException(404, 'failed')\n    mock_api_tabledata_insert_all.return_value = {}\n    mock_api_datasets_get.return_value = None\n\n    table = TestCases._create_table_with_schema(TestCases._create_inferred_schema())\n    df = TestCases._create_data_frame()\n\n    with self.assertRaises(Exception) as error:\n      table.insert_data(df)\n    self.assertEqual('Table %s does not exist.' % str(table), str(error.exception))\n\n  @mock.patch('uuid.uuid4')\n  @mock.patch('time.sleep')\n  @mock.patch('datalab.bigquery._api.Api.datasets_get')\n  @mock.patch('datalab.bigquery._api.Api.tables_list')\n  @mock.patch('datalab.bigquery._api.Api.tables_insert')\n  @mock.patch('datalab.bigquery._api.Api.tables_get')\n  @mock.patch('datalab.bigquery._api.Api.tabledata_insert_all')\n  def test_insert_data_missing_field(self,\n                                     mock_api_tabledata_insert_all,\n                                     mock_api_tables_get,\n                                     mock_api_tables_insert,\n                                     mock_api_tables_list,\n                                     mock_api_datasets_get,\n                                     mock_time_sleep,\n                                     mock_uuid,):\n    # Truncate the schema used when creating the table so we have an unmatched column in insert.\n    schema = TestCases._create_inferred_schema()[:2]\n\n    mock_uuid.return_value = TestCases._create_uuid()\n    mock_time_sleep.return_value = None\n    mock_api_datasets_get.return_value = None\n    mock_api_tables_insert.return_value = {'selfLink': 'http://foo'}\n    mock_api_tables_list.return_value = []\n    mock_api_tables_get.return_value = {'schema': {'fields': schema}}\n    mock_api_tabledata_insert_all.return_value = {}\n\n    table = TestCases._create_table_with_schema(schema)\n    df = TestCases._create_data_frame()\n\n    with self.assertRaises(Exception) as error:\n      table.insert_data(df)\n    self.assertEqual('Table does not contain field headers', str(error.exception))\n\n  @mock.patch('uuid.uuid4')\n  @mock.patch('time.sleep')\n  @mock.patch('datalab.bigquery._api.Api.tables_list')\n  @mock.patch('datalab.bigquery._api.Api.tables_insert')\n  @mock.patch('datalab.bigquery._api.Api.tables_get')\n  @mock.patch('datalab.bigquery._api.Api.tabledata_insert_all')\n  @mock.patch('datalab.bigquery._api.Api.datasets_get')\n  def test_insert_data_mismatched_schema(self,\n                                         mock_api_datasets_get,\n                                         mock_api_tabledata_insert_all,\n                                         mock_api_tables_get,\n                                         mock_api_tables_insert,\n                                         mock_api_tables_list,\n                                         mock_time_sleep,\n                                         mock_uuid):\n    # Change the schema used when creating the table so we get a mismatch when inserting.\n    schema = TestCases._create_inferred_schema()\n    schema[2]['type'] = 'STRING'\n\n    mock_uuid.return_value = TestCases._create_uuid()\n    mock_time_sleep.return_value = None\n    mock_api_tables_list.return_value = []\n    mock_api_tables_insert.return_value = {'selfLink': 'http://foo'}\n    mock_api_tables_get.return_value = {'schema': {'fields': schema}}\n    mock_api_tabledata_insert_all.return_value = {}\n    mock_api_datasets_get.return_value = None\n\n    table = TestCases._create_table_with_schema(schema)\n    df = TestCases._create_data_frame()\n\n    with self.assertRaises(Exception) as error:\n      table.insert_data(df)\n    self.assertEqual('Field headers in data has type FLOAT but in table has type STRING',\n                     str(error.exception))\n\n  @mock.patch('uuid.uuid4')\n  @mock.patch('time.sleep')\n  @mock.patch('datalab.bigquery._api.Api.datasets_get')\n  @mock.patch('datalab.bigquery._api.Api.tables_list')\n  @mock.patch('datalab.bigquery._api.Api.tables_insert')\n  @mock.patch('datalab.bigquery._api.Api.tables_get')\n  @mock.patch('datalab.bigquery._api.Api.tabledata_insert_all')\n  def test_insert_data_dataframe(self,\n                                 mock_api_tabledata_insert_all,\n                                 mock_api_tables_get,\n                                 mock_api_tables_insert,\n                                 mock_api_tables_list,\n                                 mock_api_datasets_get,\n                                 mock_time_sleep, mock_uuid):\n    schema = TestCases._create_inferred_schema()\n\n    mock_uuid.return_value = TestCases._create_uuid()\n    mock_time_sleep.return_value = None\n    mock_api_datasets_get.return_value = True\n    mock_api_tables_list.return_value = []\n    mock_api_tables_insert.return_value = {'selfLink': 'http://foo'}\n    mock_api_tables_get.return_value = {'schema': {'fields': schema}}\n    mock_api_tabledata_insert_all.return_value = {}\n\n    table = TestCases._create_table_with_schema(schema)\n    df = TestCases._create_data_frame()\n\n    result = table.insert_data(df)\n    self.assertIsNotNone(result, \"insert_all should return the table object\")\n    mock_api_tabledata_insert_all.assert_called_with(('test', 'testds', 'testTable0', ''), [\n      {'insertId': '#0', 'json': {u'column': 'r0', u'headers': 10.0, u'some': 0}},\n      {'insertId': '#1', 'json': {u'column': 'r1', u'headers': 10.0, u'some': 1}},\n      {'insertId': '#2', 'json': {u'column': 'r2', u'headers': 10.0, u'some': 2}},\n      {'insertId': '#3', 'json': {u'column': 'r3', u'headers': 10.0, u'some': 3}}\n    ])\n\n  @mock.patch('uuid.uuid4')\n  @mock.patch('time.sleep')\n  @mock.patch('datalab.bigquery._api.Api.datasets_get')\n  @mock.patch('datalab.bigquery._api.Api.tables_list')\n  @mock.patch('datalab.bigquery._api.Api.tables_insert')\n  @mock.patch('datalab.bigquery._api.Api.tables_get')\n  @mock.patch('datalab.bigquery._api.Api.tabledata_insert_all')\n  def test_insert_data_dictlist(self,\n                                mock_api_tabledata_insert_all,\n                                mock_api_tables_get,\n                                mock_api_tables_insert,\n                                mock_api_tables_list,\n                                mock_api_datasets_get,\n                                mock_time_sleep, mock_uuid):\n    schema = TestCases._create_inferred_schema()\n\n    mock_uuid.return_value = TestCases._create_uuid()\n    mock_time_sleep.return_value = None\n    mock_api_datasets_get.return_value = True\n    mock_api_tables_list.return_value = []\n    mock_api_tables_insert.return_value = {'selfLink': 'http://foo'}\n    mock_api_tables_get.return_value = {'schema': {'fields': schema}}\n    mock_api_tabledata_insert_all.return_value = {}\n\n    table = TestCases._create_table_with_schema(schema)\n\n    result = table.insert_data([\n      {u'column': 'r0', u'headers': 10.0, u'some': 0},\n      {u'column': 'r1', u'headers': 10.0, u'some': 1},\n      {u'column': 'r2', u'headers': 10.0, u'some': 2},\n      {u'column': 'r3', u'headers': 10.0, u'some': 3}\n    ])\n    self.assertIsNotNone(result, \"insert_all should return the table object\")\n    mock_api_tabledata_insert_all.assert_called_with(('test', 'testds', 'testTable0', ''), [\n      {'insertId': '#0', 'json': {u'column': 'r0', u'headers': 10.0, u'some': 0}},\n      {'insertId': '#1', 'json': {u'column': 'r1', u'headers': 10.0, u'some': 1}},\n      {'insertId': '#2', 'json': {u'column': 'r2', u'headers': 10.0, u'some': 2}},\n      {'insertId': '#3', 'json': {u'column': 'r3', u'headers': 10.0, u'some': 3}}\n    ])\n\n  @mock.patch('uuid.uuid4')\n  @mock.patch('time.sleep')\n  @mock.patch('datalab.bigquery._api.Api.datasets_get')\n  @mock.patch('datalab.bigquery._api.Api.tables_list')\n  @mock.patch('datalab.bigquery._api.Api.tables_insert')\n  @mock.patch('datalab.bigquery._api.Api.tables_get')\n  @mock.patch('datalab.bigquery._api.Api.tabledata_insert_all')\n  def test_insert_data_dictlist_index(self,\n                                      mock_api_tabledata_insert_all,\n                                      mock_api_tables_get,\n                                      mock_api_tables_insert,\n                                      mock_api_tables_list,\n                                      mock_api_datasets_get,\n                                      mock_time_sleep, mock_uuid):\n    schema = TestCases._create_inferred_schema('Index')\n\n    mock_uuid.return_value = TestCases._create_uuid()\n    mock_time_sleep.return_value = None\n    mock_api_datasets_get.return_value = True\n    mock_api_tables_list.return_value = []\n    mock_api_tables_insert.return_value = {'selfLink': 'http://foo'}\n    mock_api_tables_get.return_value = {'schema': {'fields': schema}}\n    mock_api_tabledata_insert_all.return_value = {}\n\n    table = TestCases._create_table_with_schema(schema)\n\n    result = table.insert_data([\n      {u'column': 'r0', u'headers': 10.0, u'some': 0},\n      {u'column': 'r1', u'headers': 10.0, u'some': 1},\n      {u'column': 'r2', u'headers': 10.0, u'some': 2},\n      {u'column': 'r3', u'headers': 10.0, u'some': 3}\n    ], include_index=True)\n    self.assertIsNotNone(result, \"insert_all should return the table object\")\n    mock_api_tabledata_insert_all.assert_called_with(('test', 'testds', 'testTable0', ''), [\n      {'insertId': '#0', 'json': {u'column': 'r0', u'headers': 10.0, u'some': 0, 'Index': 0}},\n      {'insertId': '#1', 'json': {u'column': 'r1', u'headers': 10.0, u'some': 1, 'Index': 1}},\n      {'insertId': '#2', 'json': {u'column': 'r2', u'headers': 10.0, u'some': 2, 'Index': 2}},\n      {'insertId': '#3', 'json': {u'column': 'r3', u'headers': 10.0, u'some': 3, 'Index': 3}}\n    ])\n\n  @mock.patch('uuid.uuid4')\n  @mock.patch('time.sleep')\n  @mock.patch('datalab.bigquery._api.Api.datasets_get')\n  @mock.patch('datalab.bigquery._api.Api.tables_list')\n  @mock.patch('datalab.bigquery._api.Api.tables_insert')\n  @mock.patch('datalab.bigquery._api.Api.tables_get')\n  @mock.patch('datalab.bigquery._api.Api.tabledata_insert_all')\n  def test_insert_data_dictlist_named_index(self,\n                                            mock_api_tabledata_insert_all,\n                                            mock_api_tables_get,\n                                            mock_api_tables_insert,\n                                            mock_api_tables_list,\n                                            mock_api_datasets_get,\n                                            mock_time_sleep, mock_uuid):\n    schema = TestCases._create_inferred_schema('Row')\n\n    mock_uuid.return_value = TestCases._create_uuid()\n    mock_time_sleep.return_value = None\n    mock_api_datasets_get.return_value = True\n    mock_api_tables_list.return_value = []\n    mock_api_tables_insert.return_value = {'selfLink': 'http://foo'}\n    mock_api_tables_get.return_value = {'schema': {'fields': schema}}\n    mock_api_tabledata_insert_all.return_value = {}\n\n    table = TestCases._create_table_with_schema(schema)\n\n    result = table.insert_data([\n        {u'column': 'r0', u'headers': 10.0, u'some': 0},\n        {u'column': 'r1', u'headers': 10.0, u'some': 1},\n        {u'column': 'r2', u'headers': 10.0, u'some': 2},\n        {u'column': 'r3', u'headers': 10.0, u'some': 3}\n    ], include_index=True, index_name='Row')\n    self.assertIsNotNone(result, \"insert_all should return the table object\")\n    mock_api_tabledata_insert_all.assert_called_with(('test', 'testds', 'testTable0', ''), [\n      {'insertId': '#0', 'json': {u'column': 'r0', u'headers': 10.0, u'some': 0, 'Row': 0}},\n      {'insertId': '#1', 'json': {u'column': 'r1', u'headers': 10.0, u'some': 1, 'Row': 1}},\n      {'insertId': '#2', 'json': {u'column': 'r2', u'headers': 10.0, u'some': 2, 'Row': 2}},\n      {'insertId': '#3', 'json': {u'column': 'r3', u'headers': 10.0, u'some': 3, 'Row': 3}}\n    ])\n\n  @mock.patch('datalab.bigquery._api.Api.tables_get')\n  @mock.patch('datalab.bigquery._api.Api.jobs_insert_load')\n  @mock.patch('datalab.bigquery._api.Api.jobs_get')\n  def test_table_load(self, mock_api_jobs_get, mock_api_jobs_insert_load, mock_api_tables_get):\n    schema = TestCases._create_inferred_schema('Row')\n    mock_api_jobs_get.return_value = {'status': {'state': 'DONE'}}\n    mock_api_jobs_insert_load.return_value = None\n    mock_api_tables_get.return_value = {'schema': {'fields': schema}}\n    tbl = datalab.bigquery.Table('testds.testTable0', context=TestCases._create_context())\n    job = tbl.load('gs://foo')\n    self.assertIsNone(job)\n    mock_api_jobs_insert_load.return_value = {'jobReference': {'jobId': 'bar'}}\n    job = tbl.load('gs://foo')\n    self.assertEquals('bar', job.id)\n\n  @mock.patch('datalab.bigquery._api.Api.table_extract')\n  @mock.patch('datalab.bigquery._api.Api.jobs_get')\n  @mock.patch('datalab.bigquery._api.Api.tables_get')\n  def test_table_extract(self, mock_api_tables_get, mock_api_jobs_get, mock_api_table_extract):\n    mock_api_tables_get.return_value = {}\n    mock_api_jobs_get.return_value = {'status': {'state': 'DONE'}}\n    mock_api_table_extract.return_value = None\n    tbl = datalab.bigquery.Table('testds.testTable0', context=self._create_context())\n    job = tbl.extract('gs://foo')\n    self.assertIsNone(job)\n    mock_api_table_extract.return_value = {'jobReference': {'jobId': 'bar'}}\n    job = tbl.extract('gs://foo')\n    self.assertEquals('bar', job.id)\n\n  @mock.patch('datalab.bigquery._api.Api.tabledata_list')\n  @mock.patch('datalab.bigquery._api.Api.tables_get')\n  def test_table_to_dataframe(self, mock_api_tables_get, mock_api_tabledata_list):\n    schema = self._create_inferred_schema()\n    mock_api_tables_get.return_value = {'schema': {'fields': schema}}\n    mock_api_tabledata_list.return_value = {\n      'rows': [\n          {'f': [{'v': 1}, {'v': 'foo'}, {'v': 3.1415}]},\n          {'f': [{'v': 2}, {'v': 'bar'}, {'v': 0.5}]},\n      ]\n    }\n    tbl = datalab.bigquery.Table('testds.testTable0', context=TestCases._create_context())\n    df = tbl.to_dataframe()\n    self.assertEquals(2, len(df))\n    self.assertEquals(1, df['some'][0])\n    self.assertEquals(2, df['some'][1])\n    self.assertEquals('foo', df['column'][0])\n    self.assertEquals('bar', df['column'][1])\n    self.assertEquals(3.1415, df['headers'][0])\n    self.assertEquals(0.5, df['headers'][1])\n\n  def test_encode_dict_as_row(self):\n    when = dt.datetime(2001, 2, 3, 4, 5, 6, 7)\n    row = datalab.bigquery.Table._encode_dict_as_row({'fo@o': 'b@r', 'b+ar': when}, {})\n    self.assertEqual({'foo': 'b@r', 'bar': '2001-02-03T04:05:06.000007'}, row)\n\n  def test_decorators(self):\n    tbl = datalab.bigquery.Table('testds.testTable0', context=TestCases._create_context())\n    tbl2 = tbl.snapshot(dt.timedelta(hours=-1))\n    self.assertEquals('test:testds.testTable0@-3600000', str(tbl2))\n\n    with self.assertRaises(Exception) as error:\n      tbl2 = tbl2.snapshot(dt.timedelta(hours=-2))\n    self.assertEqual('Cannot use snapshot() on an already decorated table',\n                     str(error.exception))\n\n    with self.assertRaises(Exception) as error:\n      tbl2.window(dt.timedelta(hours=-2), 0)\n    self.assertEqual('Cannot use window() on an already decorated table',\n                     str(error.exception))\n\n    with self.assertRaises(Exception) as error:\n      tbl.snapshot(dt.timedelta(days=-8))\n    self.assertEqual(\n        'Invalid snapshot relative when argument: must be within 7 days: -8 days, 0:00:00',\n        str(error.exception))\n\n    with self.assertRaises(Exception) as error:\n      tbl.snapshot(dt.timedelta(days=-8))\n    self.assertEqual(\n        'Invalid snapshot relative when argument: must be within 7 days: -8 days, 0:00:00',\n        str(error.exception))\n\n    tbl2 = tbl.snapshot(dt.timedelta(days=-1))\n    self.assertEquals('test:testds.testTable0@-86400000', str(tbl2))\n\n    with self.assertRaises(Exception) as error:\n      tbl.snapshot(dt.timedelta(days=1))\n    self.assertEqual('Invalid snapshot relative when argument: 1 day, 0:00:00',\n                     str(error.exception))\n\n    with self.assertRaises(Exception) as error:\n      tbl2 = tbl.snapshot(1000)\n    self.assertEqual('Invalid snapshot when argument type: 1000',\n                     str(error.exception))\n\n    self.assertEquals('test:testds.testTable0@-86400000', str(tbl2))\n\n    when = dt.datetime.utcnow() + dt.timedelta(1)\n    with self.assertRaises(Exception) as error:\n      tbl.snapshot(when)\n    self.assertEqual('Invalid snapshot absolute when argument: %s' % when,\n                     str(error.exception))\n\n    when = dt.datetime.utcnow() - dt.timedelta(8)\n    with self.assertRaises(Exception) as error:\n      tbl.snapshot(when)\n    self.assertEqual('Invalid snapshot absolute when argument: %s' % when,\n                     str(error.exception))\n\n  def test_window_decorators(self):\n    # The at test above already tests many of the conversion cases. The extra things we\n    # have to test are that we can use two values, we get a meaningful default for the second\n    # if we pass None, and that the first time comes before the second.\n    tbl = datalab.bigquery.Table('testds.testTable0', context=TestCases._create_context())\n\n    tbl2 = tbl.window(dt.timedelta(hours=-1))\n    self.assertEquals('test:testds.testTable0@-3600000-0', str(tbl2))\n\n    with self.assertRaises(Exception) as error:\n      tbl2 = tbl2.window(-400000, 0)\n    self.assertEqual('Cannot use window() on an already decorated table',\n                     str(error.exception))\n\n    with self.assertRaises(Exception) as error:\n      tbl2.snapshot(-400000)\n    self.assertEqual('Cannot use snapshot() on an already decorated table',\n                     str(error.exception))\n\n    with self.assertRaises(Exception) as error:\n      tbl.window(dt.timedelta(0), dt.timedelta(hours=-1))\n    self.assertEqual(\n        'window: Between arguments: begin must be before end: 0:00:00, -1 day, 23:00:00',\n        str(error.exception))\n\n  @mock.patch('datalab.bigquery._api.Api.tables_get')\n  @mock.patch('datalab.bigquery._api.Api.table_update')\n  def test_table_update(self, mock_api_table_update, mock_api_tables_get):\n    schema = self._create_inferred_schema()\n    info = {'schema': {'fields': schema}, 'friendlyName': 'casper',\n            'description': 'ghostly logs',\n            'expirationTime': calendar.timegm(dt.datetime(2020, 1, 1).utctimetuple()) * 1000}\n    mock_api_tables_get.return_value = info\n    tbl = datalab.bigquery.Table('testds.testTable0', context=TestCases._create_context())\n    new_name = 'aziraphale'\n    new_description = 'demon duties'\n    new_schema = [{'name': 'injected', 'type': 'FLOAT'}]\n    new_schema.extend(schema)\n    new_expiry = dt.datetime(2030, 1, 1)\n    tbl.update(new_name, new_description, new_expiry, new_schema)\n    name, info = mock_api_table_update.call_args[0]\n    self.assertEqual(tbl.name, name)\n    self.assertEqual(new_name, tbl.metadata.friendly_name)\n    self.assertEqual(new_description, tbl.metadata.description)\n    self.assertEqual(new_expiry, tbl.metadata.expires_on)\n    self.assertEqual(len(new_schema), len(tbl.schema))\n\n  def test_table_to_query(self):\n    tbl = datalab.bigquery.Table('testds.testTable0', context=TestCases._create_context())\n    q = tbl.to_query()\n    self.assertEqual('SELECT * FROM [test:testds.testTable0]', q.sql)\n    q = tbl.to_query('foo, bar')\n    self.assertEqual('SELECT foo, bar FROM [test:testds.testTable0]', q.sql)\n    q = tbl.to_query(['bar', 'foo'])\n    self.assertEqual('SELECT bar,foo FROM [test:testds.testTable0]', q.sql)\n\n  @staticmethod\n  def _create_context():\n    project_id = 'test'\n    creds = mock.Mock(spec=google.auth.credentials.Credentials)\n    return datalab.context.Context(project_id, creds)\n\n  @staticmethod\n  def _create_table(name):\n    return datalab.bigquery.Table(name, TestCases._create_context())\n\n  @staticmethod\n  def _create_table_info_result(ts=None):\n    if ts is None:\n      ts = dt.datetime.utcnow()\n    epoch = dt.datetime.utcfromtimestamp(0)\n    timestamp = (ts - epoch).total_seconds() * 1000\n\n    return {\n      'description': 'Daily Logs Table',\n      'friendlyName': 'Logs',\n      'numBytes': 1000,\n      'numRows': 2,\n      'creationTime': timestamp,\n      'lastModifiedTime': timestamp,\n      'schema': {\n        'fields': [\n          {'name': 'name', 'type': 'STRING', 'mode': 'NULLABLE'},\n          {'name': 'val', 'type': 'INTEGER', 'mode': 'NULLABLE'}\n        ]\n       }\n    }\n\n  @staticmethod\n  def _create_table_info_nested_schema_result(ts=None):\n    if ts is None:\n      ts = dt.datetime.utcnow()\n    epoch = dt.datetime.utcfromtimestamp(0)\n    timestamp = (ts - epoch).total_seconds() * 1000\n\n    return {\n      'description': 'Daily Logs Table',\n      'friendlyName': 'Logs',\n      'numBytes': 1000,\n      'numRows': 2,\n      'creationTime': timestamp,\n      'lastModifiedTime': timestamp,\n      'schema': {\n        'fields': [\n          {'name': 'name', 'type': 'STRING', 'mode': 'NULLABLE'},\n          {'name': 'val', 'type': 'INTEGER', 'mode': 'NULLABLE'},\n          {'name': 'more', 'type': 'RECORD', 'mode': 'REPEATED',\n           'fields': [\n              {'name': 'xyz', 'type': 'INTEGER', 'mode': 'NULLABLE'}\n            ]\n           }\n        ]\n      }\n    }\n\n  @staticmethod\n  def _create_dataset(dataset_id):\n    return datalab.bigquery.Dataset(dataset_id, context=TestCases._create_context())\n\n  @staticmethod\n  def _create_table_list_result():\n    return {\n      'tables': [\n        {\n          'type': 'TABLE',\n          'tableReference': {'projectId': 'test', 'datasetId': 'testds', 'tableId': 'testTable1'}\n        },\n        {\n          'type': 'VIEW',\n          'tableReference': {'projectId': 'test', 'datasetId': 'testds', 'tableId': 'testView1'}\n        },\n        {\n          'type': 'TABLE',\n          'tableReference': {'projectId': 'test', 'datasetId': 'testds', 'tableId': 'testTable2'}\n        }\n       ]\n    }\n\n  @staticmethod\n  def _create_table_list_empty_result():\n    return {\n      'tables': []\n    }\n\n  @staticmethod\n  def _create_data_frame():\n    data = {\n      'some': [\n        0, 1, 2, 3\n      ],\n      'column': [\n        'r0', 'r1', 'r2', 'r3'\n      ],\n      'headers': [\n        10.0, 10.0, 10.0, 10.0\n      ]\n    }\n    return pandas.DataFrame(data)\n\n  @staticmethod\n  def _create_inferred_schema(extra_field=None):\n    schema = [\n      {'name': 'some', 'type': 'INTEGER'},\n      {'name': 'column', 'type': 'STRING'},\n      {'name': 'headers', 'type': 'FLOAT'},\n    ]\n    if extra_field:\n      schema.append({'name': extra_field, 'type': 'INTEGER'})\n    return schema\n\n  @staticmethod\n  def _create_table_with_schema(schema, name='test:testds.testTable0'):\n    return datalab.bigquery.Table(name, TestCases._create_context()).create(schema)\n\n  class _uuid(object):\n    @property\n    def hex(self):\n      return '#'\n\n  @staticmethod\n  def _create_uuid():\n    return TestCases._uuid()\n"
  },
  {
    "path": "legacy_tests/bigquery/udf_tests.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nimport mock\nimport unittest\n\nimport google.auth\nimport datalab.bigquery\nimport datalab.context\n\n\nclass TestCases(unittest.TestCase):\n\n  def test_sql_building(self):\n    context = self._create_context()\n    table = datalab.bigquery.Table('test:requestlogs.today', context=context)\n\n    udf = self._create_udf()\n    query = datalab.bigquery.Query('SELECT * FROM foo($t)', t=table, udfs=[udf], context=context)\n\n    expected_js = '\\nfoo=function(r,emit) { emit({output1: r.field2, output2: r.field1 }); };\\n' +\\\n                  'bigquery.defineFunction(\\'foo\\', [\"field1\", \"field2\"], ' +\\\n                  '[{\"name\": \"output1\", \"type\": \"integer\"}, ' +\\\n                  '{\"name\": \"output2\", \"type\": \"string\"}], foo);'\n    self.assertEqual(query.sql, 'SELECT * FROM '\n                                '(SELECT output1, output2 FROM foo([test:requestlogs.today]))')\n    self.assertEqual(udf._code, expected_js)\n\n  @staticmethod\n  def _create_udf():\n    inputs = [('field1', 'string'), ('field2', 'integer')]\n    outputs = [('output1', 'integer'), ('output2', 'string')]\n    impl = 'function(r,emit) { emit({output1: r.field2, output2: r.field1 }); }'\n    udf = datalab.bigquery.UDF(inputs, outputs, 'foo', impl)\n    return udf\n\n  @staticmethod\n  def _create_context():\n    project_id = 'test'\n    creds = mock.Mock(spec=google.auth.credentials.Credentials)\n    return datalab.context.Context(project_id, creds)\n"
  },
  {
    "path": "legacy_tests/bigquery/view_tests.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom builtins import str\nimport mock\nimport unittest\n\nimport google.auth\nimport datalab.bigquery\nimport datalab.context\n\n\nclass TestCases(unittest.TestCase):\n\n  def test_view_repr_sql(self):\n    name = 'test:testds.testView0'\n    view = datalab.bigquery.View(name, TestCases._create_context())\n    self.assertEqual('[%s]' % name, view._repr_sql_())\n\n  @mock.patch('datalab.bigquery._api.Api.tables_insert')\n  @mock.patch('datalab.bigquery._api.Api.tables_get')\n  @mock.patch('datalab.bigquery._api.Api.tables_list')\n  @mock.patch('datalab.bigquery._api.Api.datasets_get')\n  def test_view_create(self,\n                       mock_api_datasets_get,\n                       mock_api_tables_list,\n                       mock_api_tables_get,\n                       mock_api_tables_insert):\n    mock_api_datasets_get.return_value = None\n    mock_api_tables_list.return_value = []\n    mock_api_tables_get.return_value = None\n    mock_api_tables_insert.return_value = TestCases._create_tables_insert_success_result()\n\n    name = 'test:testds.testView0'\n    sql = 'select * from test:testds.testTable0'\n    view = datalab.bigquery.View(name, TestCases._create_context())\n    result = view.create(sql)\n    self.assertTrue(view.exists())\n    self.assertEqual(name, str(view))\n    self.assertEqual('[%s]' % name, view._repr_sql_())\n    self.assertIsNotNone(result, 'Expected a view')\n\n  @mock.patch('datalab.bigquery._api.Api.tables_insert')\n  @mock.patch('datalab.bigquery._api.Api.tabledata_list')\n  @mock.patch('datalab.bigquery._api.Api.jobs_insert_query')\n  @mock.patch('datalab.bigquery._api.Api.jobs_query_results')\n  @mock.patch('datalab.bigquery._api.Api.jobs_get')\n  @mock.patch('datalab.bigquery._api.Api.tables_get')\n  def test_view_result(self, mock_api_tables_get, mock_api_jobs_get, mock_api_jobs_query_results,\n                       mock_api_insert_query, mock_api_tabledata_list, mock_api_tables_insert):\n\n    mock_api_insert_query.return_value = TestCases._create_insert_done_result()\n    mock_api_tables_insert.return_value = TestCases._create_tables_insert_success_result()\n    mock_api_jobs_query_results.return_value = {'jobComplete': True}\n    mock_api_tables_get.return_value = TestCases._create_tables_get_result()\n    mock_api_jobs_get.return_value = {'status': {'state': 'DONE'}}\n    mock_api_tabledata_list.return_value = TestCases._create_single_row_result()\n\n    name = 'test:testds.testView0'\n    sql = 'select * from test:testds.testTable0'\n    view = datalab.bigquery.View(name, TestCases._create_context())\n    view.create(sql)\n    results = view.results()\n\n    self.assertEqual(1, results.length)\n    first_result = results[0]\n    self.assertEqual('value1', first_result['field1'])\n\n  @mock.patch('datalab.bigquery._api.Api.tables_insert')\n  @mock.patch('datalab.bigquery._api.Api.tables_get')\n  @mock.patch('datalab.bigquery._api.Api.table_update')\n  @mock.patch('datalab.context.Context.default')\n  def test_view_update(self, mock_context_default, mock_api_table_update,\n                       mock_api_tables_get, mock_api_tables_insert):\n    mock_api_tables_insert.return_value = TestCases._create_tables_insert_success_result()\n    mock_context_default.return_value = TestCases._create_context()\n    mock_api_table_update.return_value = None\n    friendly_name = 'casper'\n    description = 'ghostly logs'\n    sql = 'select * from [test:testds.testTable0]'\n    info = {'friendlyName': friendly_name,\n            'description': description,\n            'view': {'query': sql}}\n    mock_api_tables_get.return_value = info\n    name = 'test:testds.testView0'\n    view = datalab.bigquery.View(name, TestCases._create_context())\n    view.create(sql)\n    self.assertEqual(friendly_name, view.friendly_name)\n    self.assertEqual(description, view.description)\n    self.assertEqual(sql, view.query.sql)\n\n    new_friendly_name = 'aziraphale'\n    new_description = 'demon duties'\n    new_query = 'SELECT 3 AS x'\n    view.update(new_friendly_name, new_description, new_query)\n\n    self.assertEqual(new_friendly_name, view.friendly_name)\n    self.assertEqual(new_description, view.description)\n    self.assertEqual(new_query, view.query.sql)\n\n  @staticmethod\n  def _create_tables_insert_success_result():\n    return {'selfLink': 'http://foo'}\n\n  @staticmethod\n  def _create_insert_done_result():\n    # pylint: disable=g-continuation-in-parens-misaligned\n    return {\n      'jobReference': {\n        'jobId': 'test_job'\n      },\n      'configuration': {\n        'query': {\n          'destinationTable': {\n            'projectId': 'project',\n            'datasetId': 'dataset',\n            'tableId': 'table'\n          }\n        }\n      },\n      'jobComplete': True,\n    }\n\n  @staticmethod\n  def _create_tables_get_result(num_rows=1, schema=None):\n    if not schema:\n      schema = [{'name': 'field1', 'type': 'string'}]\n    return {\n      'numRows': num_rows,\n      'schema': {\n        'fields': schema\n      },\n    }\n\n  @staticmethod\n  def _create_single_row_result():\n    # pylint: disable=g-continuation-in-parens-misaligned\n    return {\n      'totalRows': 1,\n      'rows': [\n        {'f': [{'v': 'value1'}]}\n      ]\n    }\n\n  @staticmethod\n  def _create_context():\n    project_id = 'test'\n    creds = mock.Mock(spec=google.auth.credentials.Credentials)\n    return datalab.context.Context(project_id, creds)\n"
  },
  {
    "path": "legacy_tests/data/__init__.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n"
  },
  {
    "path": "legacy_tests/data/sql_tests.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nimport imp\nimport unittest\n\nimport datalab.data\n\n\nclass TestCases(unittest.TestCase):\n\n  def test_sql_tokenizer(self):\n    query = \"SELECT * FROM function(SELECT * FROM [table])  -- a comment\\n\" \\\n            \"WHERE x>0 AND y == 'cat'/*\\nmulti-line comment */LIMIT 10\"\n    tokens = datalab.data.tokenize(query)\n    # Make sure we get all the content\n    self.assertEquals(''.join(tokens), query)\n\n    # Then check the tokens\n    expected = [\n      'SELECT',\n      ' ',\n      '*',\n      ' ',\n      'FROM',\n      ' ',\n      'function',\n      '(',\n      'SELECT',\n      ' ',\n      '*',\n      ' ',\n      'FROM',\n      ' ',\n      '[',\n      'table',\n      ']',\n      ')',\n      '  ',\n      '-- a comment\\n',\n      'WHERE',\n      ' ',\n      'x',\n      '>',\n      '0',\n      ' ',\n      'AND',\n      ' ',\n      'y',\n      ' ',\n      '=',\n      '=',\n      ' ',\n      '\\'cat\\'',\n      '/*\\nmulti-line comment */',\n      'LIMIT',\n      ' ',\n      '10'\n    ]\n    self.assertEquals(expected, tokens)\n\n  def test_zero_placeholders(self):\n    queries = ['SELECT * FROM [logs.today]',\n               ' SELECT time FROM [logs.today] ']\n\n    for query in queries:\n      formatted_query = datalab.data.SqlStatement.format(query, None)\n      self.assertEqual(query, formatted_query)\n\n  def test_single_placeholder(self):\n    query = 'SELECT time FROM [logs.today] WHERE status == $param'\n    args = {'param': 200}\n\n    formatted_query = datalab.data.SqlStatement.format(query, args)\n    self.assertEqual(formatted_query,\n                     'SELECT time FROM [logs.today] WHERE status == 200')\n\n  def test_multiple_placeholders(self):\n    query = ('SELECT time FROM [logs.today] '\n             'WHERE status == $status AND path == $path')\n    args = {'status': 200, 'path': '/home'}\n\n    formatted_query = datalab.data.SqlStatement.format(query, args)\n    self.assertEqual(formatted_query,\n                     ('SELECT time FROM [logs.today] '\n                      'WHERE status == 200 AND path == \"/home\"'))\n\n  def test_escaped_placeholder(self):\n    query = 'SELECT time FROM [logs.today] WHERE path == \"/foo$$bar\"'\n    args = {'status': 200}\n\n    formatted_query = datalab.data.SqlStatement.format(query, args)\n    self.assertEqual(formatted_query,\n                     'SELECT time FROM [logs.today] WHERE path == \"/foo$bar\"')\n\n  def test_string_escaping(self):\n    query = 'SELECT time FROM [logs.today] WHERE path == $path'\n    args = {'path': 'xyz\"xyz'}\n\n    formatted_query = datalab.data.SqlStatement.format(query, args)\n    self.assertEqual(formatted_query,\n                     'SELECT time FROM [logs.today] WHERE path == \"xyz\\\\\"xyz\"')\n\n  def test_all_combinations(self):\n    query = ('SELECT time FROM '\n             '  (SELECT * FROM [logs.today] '\n             '   WHERE path contains \"$$\" AND path contains $segment '\n             '     AND status == $status) '\n             'WHERE success == $success AND server == \"$$master\" '\n             'LIMIT $pageSize')\n    args = {'status': 200, 'pageSize': 10, 'success': False, 'segment': 'home'}\n\n    expected_query = ('SELECT time FROM '\n                      '  (SELECT * FROM [logs.today] '\n                      '   WHERE path contains \"$\" AND path contains \"home\" '\n                      '     AND status == 200) '\n                      'WHERE success == False AND server == \"$master\" '\n                      'LIMIT 10')\n\n    formatted_query = datalab.data.SqlStatement.format(query, args)\n\n    self.assertEqual(formatted_query, expected_query)\n\n  def test_missing_args(self):\n    query = 'SELECT time FROM [logs.today] WHERE status == $status'\n    args = {'s': 200}\n\n    with self.assertRaises(Exception) as error:\n      datalab.data.SqlStatement.format(query, args)\n\n    e = error.exception\n    self.assertEqual('Unsatisfied dependency $status', str(e))\n\n  def test_invalid_args(self):\n    query = 'SELECT time FROM [logs.today] WHERE status == $0'\n\n    with self.assertRaises(Exception) as error:\n      datalab.data.SqlStatement.format(query, {})\n\n    e = error.exception\n    self.assertEqual(\n        'Invalid sql; $ with no following $ or identifier: ' + query + '.', str(e))\n\n  def test_nested_queries(self):\n    query1 = datalab.data.SqlStatement('SELECT 3 as x')\n    query2 = datalab.data.SqlStatement('SELECT x FROM $query1')\n    query3 = 'SELECT * FROM $query2 WHERE x == $count'\n\n    self.assertEquals('SELECT 3 as x', query1.sql)\n\n    with self.assertRaises(Exception) as e:\n      datalab.data.SqlStatement.format(query3)[0]\n    self.assertEquals('Unsatisfied dependency $query2', str(e.exception))\n\n    with self.assertRaises(Exception) as e:\n      datalab.data.SqlStatement.format(query3, {'query1': query1})\n    self.assertEquals('Unsatisfied dependency $query2', str(e.exception))\n\n    with self.assertRaises(Exception) as e:\n      datalab.data.SqlStatement.format(query3, {'query2': query2})\n    self.assertEquals('Unsatisfied dependency $query1', str(e.exception))\n\n    with self.assertRaises(Exception) as e:\n      datalab.data.SqlStatement.format(query3, {'query1': query1, 'query2': query2})\n    self.assertEquals('Unsatisfied dependency $count', str(e.exception))\n\n    formatted_query =\\\n        datalab.data.SqlStatement.format(query3, {'query1': query1, 'query2': query2, 'count': 5})\n    self.assertEqual('SELECT * FROM (SELECT x FROM (SELECT 3 as x)) WHERE x == 5', formatted_query)\n\n  def test_shared_nested_queries(self):\n    query1 = datalab.data.SqlStatement('SELECT 3 as x')\n    query2 = datalab.data.SqlStatement('SELECT x FROM $query1')\n    query3 = 'SELECT x AS y FROM $query1, x FROM $query2'\n    formatted_query = datalab.data.SqlStatement.format(query3, {'query1': query1, 'query2': query2})\n    self.assertEqual('SELECT x AS y FROM (SELECT 3 as x), x FROM (SELECT x FROM (SELECT 3 as x))',\n                     formatted_query)\n\n  def test_circular_references(self):\n    query1 = datalab.data.SqlStatement('SELECT * FROM $query3')\n    query2 = datalab.data.SqlStatement('SELECT x FROM $query1')\n    query3 = datalab.data.SqlStatement('SELECT * FROM $query2 WHERE x == $count')\n    args = {'query1': query1, 'query2': query2, 'query3': query3}\n\n    with self.assertRaises(Exception) as e:\n      datalab.data.SqlStatement.format('SELECT * FROM $query1', args)\n    self.assertEquals('Circular dependency in $query1', str(e.exception))\n\n    with self.assertRaises(Exception) as e:\n      datalab.data.SqlStatement.format('SELECT * FROM $query2', args)\n    self.assertEquals('Circular dependency in $query2', str(e.exception))\n\n    with self.assertRaises(Exception) as e:\n      datalab.data.SqlStatement.format('SELECT * FROM $query3', args)\n    self.assertEquals('Circular dependency in $query3', str(e.exception))\n\n  def test_module_reference(self):\n    m = imp.new_module('m')\n    m.__dict__['q1'] = datalab.data.SqlStatement('SELECT 3 AS x')\n    m.__dict__[datalab.data._utils._SQL_MODULE_LAST] =\\\n        datalab.data.SqlStatement('SELECT * FROM $q1 LIMIT 10')\n    with self.assertRaises(Exception) as e:\n      datalab.data.SqlStatement.format('SELECT * FROM $s', {'s': m})\n    self.assertEquals('Unsatisfied dependency $q1', str(e.exception))\n\n    formatted_query = datalab.data.SqlStatement.format('SELECT * FROM $s', {'s': m, 'q1': m.q1})\n    self.assertEqual('SELECT * FROM (SELECT * FROM (SELECT 3 AS x) LIMIT 10)', formatted_query)\n\n    formatted_query = datalab.data.SqlStatement.format('SELECT * FROM $s', {'s': m.q1})\n    self.assertEqual('SELECT * FROM (SELECT 3 AS x)', formatted_query)\n\n  def test_get_sql_statement_with_environment(self):\n    # TODO(gram).\n    pass\n\n  def test_get_query_from_module(self):\n    # TODO(gram).\n    pass\n\n  def test_get_sql_args(self):\n    # TODO(gram).\n    pass\n"
  },
  {
    "path": "legacy_tests/kernel/__init__.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n"
  },
  {
    "path": "legacy_tests/kernel/bigquery_tests.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nimport mock\nimport unittest\nimport google.auth\n\n# import Python so we can mock the parts we need to here.\nimport IPython\nimport IPython.core.magic\n\n\ndef noop_decorator(func):\n  return func\n\n\nIPython.core.magic.register_line_cell_magic = noop_decorator\nIPython.core.magic.register_line_magic = noop_decorator\nIPython.core.magic.register_cell_magic = noop_decorator\nIPython.get_ipython = mock.Mock()\n\n\nimport datalab.bigquery  # noqa: E402\nimport datalab.bigquery.commands  # noqa: E402\nimport datalab.context  # noqa: E402\nimport datalab.utils.commands  # noqa: E402\n\n\nclass TestCases(unittest.TestCase):\n\n  @mock.patch('datalab.utils.commands.notebook_environment')\n  @mock.patch('datalab.context._context.Context.default')\n  def test_udf_cell(self, mock_default_context, mock_notebook_environment):\n    env = {}\n    cell_body = \"\"\"\n    /**\n    * @param {{word: string, corpus: string, word_count: integer}} r\n    * @param function({{word: string, corpus: string, count: integer}}) emitFn\n    */\n    function(r, emitFn) {\n      if (r.word.match(/[shakespeare]/) !== null) {\n        var result = { word: r.word, corpus: r.corpus, count: r.word_count };\n        emitFn(result);\n      }\n    }\n    \"\"\"\n    mock_default_context.return_value = TestCases._create_context()\n    mock_notebook_environment.return_value = env\n    datalab.bigquery.commands._bigquery._udf_cell({'module': 'word_filter'}, cell_body)\n    udf = env['word_filter']\n    self.assertIsNotNone(udf)\n    self.assertEquals('word_filter', udf._name)\n    self.assertEquals([('word', 'string'), ('corpus', 'string'), ('count', 'integer')],\n                      udf._outputs)\n    self.assertEquals(cell_body, udf._implementation)\n\n  @staticmethod\n  def _create_context():\n    project_id = 'test'\n    creds = mock.Mock(spec=google.auth.credentials.Credentials)\n    return datalab.context.Context(project_id, creds)\n\n  def test_sample_cell(self):\n    # TODO(gram): complete this test\n    pass\n\n  def test_get_schema(self):\n    # TODO(gram): complete this test\n    pass\n\n  def test_get_table(self):\n    # TODO(gram): complete this test\n    pass\n\n  def test_table_viewer(self):\n    # TODO(gram): complete this test\n    pass\n"
  },
  {
    "path": "legacy_tests/kernel/chart_data_tests.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nimport json\nimport mock\nimport unittest\n\n# import Python so we can mock the parts we need to here.\nimport IPython.core.display\nimport IPython.core.magic\n\nimport datalab.utils.commands\n\n\ndef noop_decorator(func):\n  return func\n\n\nIPython.core.magic.register_line_cell_magic = noop_decorator\nIPython.core.magic.register_line_magic = noop_decorator\nIPython.core.magic.register_cell_magic = noop_decorator\nIPython.core.display.HTML = lambda x: x\nIPython.core.display.JSON = lambda x: x\n\n\nclass TestCases(unittest.TestCase):\n\n  @mock.patch('datalab.utils.get_item')\n  def test_get_chart_data(self, mock_get_item):\n    IPython.get_ipython().user_ns = {}\n    t = [\n        {'country': 'US', 'quantity': 100},\n        {'country': 'ZA', 'quantity': 50},\n        {'country': 'UK', 'quantity': 75},\n        {'country': 'AU', 'quantity': 25}\n    ]\n    mock_get_item.return_value = t\n    ds = datalab.utils.commands.get_data_source_index('t')\n    data = datalab.utils.commands._chart_data._get_chart_data('', json.dumps({\n      'source_index': ds,\n      'fields': 'country',\n      'first': 1,\n      'count': 1\n    }))\n    self.assertEquals({\"data\": {\"rows\": [{\"c\": [{\"v\": \"ZA\"}]}],\n                                \"cols\": [{\"type\": \"string\", \"id\": \"country\", \"label\": \"country\"}]},\n                       \"refresh_interval\": 0, \"options\": {}}, data)\n\n    data = datalab.utils.commands._chart_data._get_chart_data('', json.dumps({\n      'source_index': ds,\n      'fields': 'country',\n      'first': 6,\n      'count': 1\n    }))\n    self.assertEquals({\"data\": {\"rows\": [],\n                                \"cols\": [{\"type\": \"string\", \"id\": \"country\", \"label\": \"country\"}]},\n                       \"refresh_interval\": 0, \"options\": {}}, data)\n\n    data = datalab.utils.commands._chart_data._get_chart_data('', json.dumps({\n      'source_index': ds,\n      'fields': 'country',\n      'first': 2,\n      'count': 0\n    }))\n    self.assertEquals({\"data\": {\"rows\": [],\n                                \"cols\": [{\"type\": \"string\", \"id\": \"country\", \"label\": \"country\"}]},\n                      \"refresh_interval\": 0, \"options\": {}}, data)\n"
  },
  {
    "path": "legacy_tests/kernel/chart_tests.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nimport unittest\n\n# import Python so we can mock the parts we need to here.\nimport IPython.core.display\nimport IPython.core.magic\n\nimport datalab.utils.commands\n\n\ndef noop_decorator(func):\n  return func\n\n\nIPython.core.magic.register_line_cell_magic = noop_decorator\nIPython.core.magic.register_line_magic = noop_decorator\nIPython.core.magic.register_cell_magic = noop_decorator\nIPython.core.display.HTML = lambda x: x\nIPython.core.display.JSON = lambda x: x\n\n\nclass TestCases(unittest.TestCase):\n\n  def test_chart_cell(self):\n    t = [{'country': 'US', 'quantity': 100}, {'country': 'ZA', 'quantity': 50}]\n    IPython.get_ipython().user_ns = {}\n    chart = datalab.utils.commands._chart._chart_cell({'chart': 'geo', 'data': t, 'fields': None},\n                                                      '')\n    self.assertTrue(chart.find('charts.render(') > 0)\n    self.assertTrue(chart.find('\\'geo\\'') > 0)\n    self.assertTrue(chart.find('\"fields\": \"*\"') > 0)\n    self.assertTrue(chart.find('{\"c\": [{\"v\": \"US\"}, {\"v\": 100}]}') > 0 or\n                    chart.find('{\"c\": [{\"v\": 100}, {\"v\": \"US\"}]}') > 0)\n    self.assertTrue(chart.find('{\"c\": [{\"v\": \"ZA\"}, {\"v\": 50}]}') > 0 or\n                    chart.find('{\"c\": [{\"v\": 50}, {\"v\": \"ZA\"}]}') > 0)\n\n  def test_chart_magic(self):\n    # TODO(gram): complete this test\n    pass\n"
  },
  {
    "path": "legacy_tests/kernel/commands_tests.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nimport mock\nimport unittest\n\n# import Python so we can mock the parts we need to here.\nimport IPython\nimport IPython.core.magic\n\n\ndef noop_decorator(func):\n  return func\n\n\nIPython.core.magic.register_line_cell_magic = noop_decorator\nIPython.core.magic.register_line_magic = noop_decorator\nIPython.core.magic.register_cell_magic = noop_decorator\nIPython.get_ipython = mock.Mock()\n\n\nclass TestCases(unittest.TestCase):\n\n  def test_create_args(self):\n    # TODO(gram): complete this test\n    pass\n"
  },
  {
    "path": "legacy_tests/kernel/html_tests.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nimport mock\nimport unittest\n\n# import Python so we can mock the parts we need to here.\nimport IPython\nimport IPython.core.magic\n\n\ndef noop_decorator(func):\n  return func\n\n\nIPython.core.magic.register_line_cell_magic = noop_decorator\nIPython.core.magic.register_line_magic = noop_decorator\nIPython.core.magic.register_cell_magic = noop_decorator\nIPython.get_ipython = mock.Mock()\n\n\nclass TestCases(unittest.TestCase):\n\n  def test_render_table(self):\n    # TODO(gram): complete this test\n    pass\n\n  def test_render_text(self):\n    # TODO(gram): complete this test\n    pass\n"
  },
  {
    "path": "legacy_tests/kernel/module_tests.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nimport mock\nimport sys\nimport unittest\n\n# import Python so we can mock the parts we need to here.\nimport IPython\nimport IPython.core.magic\n\nimport datalab.utils.commands\n\n\ndef noop_decorator(func):\n  return func\n\n\nIPython.core.magic.register_line_cell_magic = noop_decorator\nIPython.core.magic.register_line_magic = noop_decorator\nIPython.core.magic.register_cell_magic = noop_decorator\nIPython.get_ipython = mock.Mock()\n\n\nclass TestCases(unittest.TestCase):\n\n  def test_create_python_module(self):\n    datalab.utils.commands._modules._create_python_module('bar', 'y=1')\n    self.assertIsNotNone(sys.modules['bar'])\n    self.assertEqual(1, sys.modules['bar'].y)\n\n  def test_pymodule(self):\n    datalab.utils.commands._modules.pymodule('--name foo', 'x=1')\n    self.assertIsNotNone(sys.modules['foo'])\n    self.assertEqual(1, sys.modules['foo'].x)\n\n  @mock.patch('datalab.utils.commands._modules._pymodule_cell', autospec=True)\n  def test_pymodule_magic(self, mock_pymodule_cell):\n    datalab.utils.commands._modules.pymodule('-n foo')\n    mock_pymodule_cell.assert_called_with({\n      'name': 'foo',\n      'func': datalab.utils.commands._modules._pymodule_cell\n    }, None)\n"
  },
  {
    "path": "legacy_tests/kernel/sql_tests.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nimport imp\nimport mock\nimport unittest\n\n# import Python so we can mock the parts we need to here.\nimport IPython\nimport IPython.core.magic\n\nimport google.auth\nimport datalab.bigquery\nimport datalab.context\nimport datalab.data\nimport datalab.data.commands\nimport datalab.utils.commands\n\n\ndef noop_decorator(func):\n  return func\n\n\nIPython.core.magic.register_line_cell_magic = noop_decorator\nIPython.core.magic.register_line_magic = noop_decorator\nIPython.core.magic.register_cell_magic = noop_decorator\nIPython.get_ipython = mock.Mock()\n\n\nclass TestCases(unittest.TestCase):\n\n  _SQL_MODULE_MAIN = datalab.data._utils._SQL_MODULE_MAIN\n  _SQL_MODULE_LAST = datalab.data._utils._SQL_MODULE_LAST\n\n  def test_split_cell(self):\n    # TODO(gram): add tests for argument parser.\n    m = imp.new_module('m')\n    query = datalab.data.commands._sql._split_cell('', m)\n    self.assertIsNone(query)\n    self.assertNotIn(TestCases._SQL_MODULE_LAST, m.__dict__)\n    self.assertNotIn(TestCases._SQL_MODULE_MAIN, m.__dict__)\n\n    m = imp.new_module('m')\n    query = datalab.data.commands._sql._split_cell('\\n\\n', m)\n    self.assertIsNone(query)\n    self.assertNotIn(TestCases._SQL_MODULE_LAST, m.__dict__)\n    self.assertNotIn(TestCases._SQL_MODULE_MAIN, m.__dict__)\n\n    m = imp.new_module('m')\n    query = datalab.data.commands._sql._split_cell('# This is a comment\\n\\nSELECT 3 AS x', m)\n    self.assertEquals(query, m.__dict__[TestCases._SQL_MODULE_MAIN])\n    self.assertEquals(query, m.__dict__[TestCases._SQL_MODULE_LAST])\n    self.assertEquals('SELECT 3 AS x', m.__dict__[TestCases._SQL_MODULE_MAIN].sql)\n    self.assertEquals('SELECT 3 AS x', m.__dict__[TestCases._SQL_MODULE_LAST].sql)\n\n    m = imp.new_module('m')\n    query = datalab.data.commands._sql._split_cell(\n        '# This is a comment\\n\\nfoo=\"bar\"\\nSELECT 3 AS x', m)\n    self.assertEquals(query, m.__dict__[TestCases._SQL_MODULE_MAIN])\n    self.assertEquals(query, m.__dict__[TestCases._SQL_MODULE_LAST])\n    self.assertEquals('SELECT 3 AS x', m.__dict__[TestCases._SQL_MODULE_MAIN].sql)\n    self.assertEquals('SELECT 3 AS x', m.__dict__[TestCases._SQL_MODULE_LAST].sql)\n\n    sql_string_list = ['SELECT 3 AS x',\n                       'WITH q1 as (SELECT \"1\")\\nSELECT * FROM q1',\n                       'INSERT DataSet.Table (Id, Description)\\nVALUES(100,\"TestDesc\")',\n                       'INSERT DataSet.Table (Id, Description)\\n'\n                       'SELECT * FROM UNNEST([(200,\"TestDesc2\"),(300,\"TestDesc3\")])'\n                       'INSERT DataSet.Table (Id, Description)\\n' +\n                       'WITH w as (SELECT ARRAY<STRUCT<Id int64, Description string>>\\n' +\n                       '[(400, \"TestDesc4\"),(500, \"TestDesc5\")] col)\\n' +\n                       'SELECT Id, Description FROM w, UNNEST(w.col)'\n                       'INSERT DataSet.Table (Id, Description)\\n' +\n                       'VALUES (600,\\n' +\n                       '(SELECT Description FROM DataSet.Table WHERE Id = 400))',\n                       'DELETE FROM DataSet.Table WHERE DESCRIPTION IS NULL'\n                       'DELETE FROM DataSet.Table\\n' +\n                       'WHERE Id NOT IN (100, 200, 300)'\n                       ]\n    for i in range(0, len(sql_string_list)):\n        m = imp.new_module('m')\n        query = datalab.data.commands._sql._split_cell(sql_string_list[i], m)\n        self.assertEquals(query, m.__dict__[TestCases._SQL_MODULE_MAIN])\n        self.assertEquals(query, m.__dict__[TestCases._SQL_MODULE_LAST])\n        self.assertEquals(sql_string_list[i], m.__dict__[TestCases._SQL_MODULE_MAIN].sql)\n        self.assertEquals(sql_string_list[i], m.__dict__[TestCases._SQL_MODULE_LAST].sql)\n\n    m = imp.new_module('m')\n    query = datalab.data.commands._sql._split_cell('DEFINE QUERY q1\\nSELECT 3 AS x', m)\n    self.assertEquals(query, m.__dict__[TestCases._SQL_MODULE_LAST])\n    self.assertEquals(query, m.__dict__[TestCases._SQL_MODULE_LAST])\n    self.assertEquals('SELECT 3 AS x', m.q1.sql)\n    self.assertNotIn(TestCases._SQL_MODULE_MAIN, m.__dict__)\n    self.assertEquals('SELECT 3 AS x', m.__dict__[TestCases._SQL_MODULE_LAST].sql)\n\n    m = imp.new_module('m')\n    query = datalab.data.commands._sql._split_cell(\n        'DEFINE QUERY q1\\nSELECT 3 AS x\\nSELECT * FROM $q1', m)\n    self.assertEquals(query, m.__dict__[TestCases._SQL_MODULE_MAIN])\n    self.assertEquals(query, m.__dict__[TestCases._SQL_MODULE_LAST])\n    self.assertEquals('SELECT 3 AS x', m.q1.sql)\n    self.assertEquals('SELECT * FROM $q1', m.__dict__[TestCases._SQL_MODULE_MAIN].sql)\n    self.assertEquals('SELECT * FROM $q1', m.__dict__[TestCases._SQL_MODULE_LAST].sql)\n\n  @mock.patch('datalab.context._context.Context.default')\n  def test_arguments(self, mock_default_context):\n    mock_default_context.return_value = TestCases._create_context()\n    m = imp.new_module('m')\n    query = datalab.data.commands._sql._split_cell(\"\"\"\nwords = ('thus', 'forsooth')\nlimit = 10\n\nSELECT * FROM [publicdata:samples.shakespeare]\nWHERE word IN $words\nLIMIT $limit\n\"\"\", m)\n    sql = datalab.bigquery.Query(query, values={}).sql\n    self.assertEquals('SELECT * FROM [publicdata:samples.shakespeare]\\n' +\n                      'WHERE word IN (\"thus\", \"forsooth\")\\nLIMIT 10', sql)\n    # As above but with overrides, using list\n    sql = datalab.bigquery.Query(query, words=['eyeball'], limit=5).sql\n    self.assertEquals('SELECT * FROM [publicdata:samples.shakespeare]\\n' +\n                      'WHERE word IN (\"eyeball\")\\nLIMIT 5', sql)\n    # As above but with overrides, using tuple and values dict\n    sql = datalab.bigquery.Query(query, values={'limit': 3, 'words': ('thus',)}).sql\n    self.assertEquals('SELECT * FROM [publicdata:samples.shakespeare]\\n' +\n                      'WHERE word IN (\"thus\")\\nLIMIT 3', sql)\n    # As above but with list argument\n    m = imp.new_module('m')\n    query = datalab.data.commands._sql._split_cell(\"\"\"\nwords = ['thus', 'forsooth']\nlimit = 10\n\nSELECT * FROM [publicdata:samples.shakespeare]\nWHERE word IN $words\nLIMIT $limit\n\"\"\", m)\n    sql = datalab.bigquery.Query(query, values={}).sql\n    self.assertEquals('SELECT * FROM [publicdata:samples.shakespeare]\\n' +\n                      'WHERE word IN (\"thus\", \"forsooth\")\\nLIMIT 10', sql)\n    # As above but with overrides, using list\n    sql = datalab.bigquery.Query(query, values={'limit': 2, 'words': ['forsooth']}).sql\n    self.assertEquals('SELECT * FROM [publicdata:samples.shakespeare]\\n' +\n                      'WHERE word IN (\"forsooth\")\\nLIMIT 2', sql)\n    # As above but with overrides, using tuple\n    sql = datalab.bigquery.Query(query, words=('eyeball',)).sql\n    self.assertEquals('SELECT * FROM [publicdata:samples.shakespeare]\\n' +\n                      'WHERE word IN (\"eyeball\")\\nLIMIT 10', sql)\n    # TODO(gram): add some tests for source and datestring variables\n\n  def test_date(self):\n    # TODO(gram): complete this test\n    pass\n\n  def test_sql_cell(self):\n    # TODO(gram): complete this test\n    pass\n\n  @staticmethod\n  def _create_context():\n    project_id = 'test'\n    creds = mock.Mock(spec=google.auth.credentials.Credentials)\n    return datalab.context.Context(project_id, creds)\n"
  },
  {
    "path": "legacy_tests/kernel/storage_tests.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nimport mock\nimport unittest\n\n# import Python so we can mock the parts we need to here.\nimport IPython\nimport IPython.core.magic\n\nimport google.auth\nimport datalab.context\nimport datalab.storage\nimport datalab.storage.commands\n\n\ndef noop_decorator(func):\n  return func\n\n\nIPython.core.magic.register_line_cell_magic = noop_decorator\nIPython.core.magic.register_line_magic = noop_decorator\nIPython.core.magic.register_cell_magic = noop_decorator\nIPython.get_ipython = mock.Mock()\n\n\nclass TestCases(unittest.TestCase):\n\n  @mock.patch('datalab.storage._item.Item.exists', autospec=True)\n  @mock.patch('datalab.storage._bucket.Bucket.items', autospec=True)\n  @mock.patch('datalab.storage._api.Api.objects_get', autospec=True)\n  @mock.patch('datalab.context._context.Context.default')\n  def test_expand_list(self, mock_context_default, mock_api_objects_get, mock_bucket_items,\n                       mock_item_exists):\n    context = TestCases._create_context()\n    mock_context_default.return_value = context\n\n    # Mock API for testing for item existence. Fail if called with name that includes wild char.\n    def item_exists_side_effect(*args, **kwargs):\n      return args[0].key.find('*') < 0\n\n    mock_item_exists.side_effect = item_exists_side_effect\n\n    # Mock API for getting items in a bucket.\n    mock_bucket_items.side_effect = TestCases._mock_bucket_items_return(context)\n\n    # Mock API for getting item metadata.\n    mock_api_objects_get.side_effect = TestCases._mock_api_objects_get()\n\n    items = datalab.storage.commands._storage._expand_list(None)\n    self.assertEqual([], items)\n\n    items = datalab.storage.commands._storage._expand_list([])\n    self.assertEqual([], items)\n\n    items = datalab.storage.commands._storage._expand_list('gs://bar/o*')\n    self.assertEqual(['gs://bar/object1', 'gs://bar/object3'], items)\n\n    items = datalab.storage.commands._storage._expand_list(['gs://foo', 'gs://bar'])\n    self.assertEqual(['gs://foo', 'gs://bar'], items)\n\n    items = datalab.storage.commands._storage._expand_list(['gs://foo/*', 'gs://bar'])\n    self.assertEqual(['gs://foo/item1', 'gs://foo/item2', 'gs://foo/item3', 'gs://bar'], items)\n\n    items = datalab.storage.commands._storage._expand_list(['gs://bar/o*'])\n    self.assertEqual(['gs://bar/object1', 'gs://bar/object3'], items)\n\n    items = datalab.storage.commands._storage._expand_list(['gs://bar/i*'])\n    # Note - if no match we return the pattern.\n    self.assertEqual(['gs://bar/i*'], items)\n\n    items = datalab.storage.commands._storage._expand_list(['gs://baz'])\n    self.assertEqual(['gs://baz'], items)\n\n    items = datalab.storage.commands._storage._expand_list(['gs://baz/*'])\n    self.assertEqual(['gs://baz/*'], items)\n\n    items = datalab.storage.commands._storage._expand_list(['gs://foo/i*3'])\n    self.assertEqual(['gs://foo/item3'], items)\n\n  @mock.patch('datalab.storage._item.Item.copy_to', autospec=True)\n  @mock.patch('datalab.storage._bucket.Bucket.items', autospec=True)\n  @mock.patch('datalab.storage._api.Api.objects_get', autospec=True)\n  @mock.patch('datalab.context._context.Context.default')\n  def test_storage_copy(self, mock_context_default, mock_api_objects_get, mock_bucket_items,\n                        mock_storage_item_copy_to):\n    context = TestCases._create_context()\n    mock_context_default.return_value = context\n    # Mock API for getting items in a bucket.\n    mock_bucket_items.side_effect = TestCases._mock_bucket_items_return(context)\n    # Mock API for getting item metadata.\n    mock_api_objects_get.side_effect = TestCases._mock_api_objects_get()\n\n    datalab.storage.commands._storage._storage_copy({\n      'source': ['gs://foo/item1'],\n      'destination': 'gs://foo/bar1'\n    }, None)\n\n    mock_storage_item_copy_to.assert_called_with(mock.ANY, 'bar1', bucket='foo')\n    self.assertEquals('item1', mock_storage_item_copy_to.call_args[0][0].key)\n    self.assertEquals('foo', mock_storage_item_copy_to.call_args[0][0]._bucket)\n\n    with self.assertRaises(Exception) as error:\n      datalab.storage.commands._storage._storage_copy({\n        'source': ['gs://foo/item*'],\n        'destination': 'gs://foo/bar1'\n      }, None)\n    self.assertEqual('More than one source but target gs://foo/bar1 is not a bucket',\n                     str(error.exception))\n\n  @mock.patch('datalab.storage.commands._storage._storage_copy', autospec=True)\n  def test_storage_copy_magic(self, mock_storage_copy):\n    datalab.storage.commands._storage.storage('copy --source gs://foo/item1 '\n                                              '--destination gs://foo/bar1')\n    mock_storage_copy.assert_called_with({\n        'source': ['gs://foo/item1'],\n        'destination': 'gs://foo/bar1',\n        'func': datalab.storage.commands._storage._storage_copy\n      }, None)\n\n  @mock.patch('datalab.storage._api.Api.buckets_insert', autospec=True)\n  @mock.patch('datalab.context._context.Context.default')\n  def test_storage_create(self, mock_context_default, mock_api_buckets_insert):\n    context = TestCases._create_context()\n    mock_context_default.return_value = context\n\n    errs = datalab.storage.commands._storage._storage_create({\n      'project': 'test',\n      'bucket': [\n        'gs://baz'\n      ]\n    }, None)\n    self.assertEqual(None, errs)\n    mock_api_buckets_insert.assert_called_with(mock.ANY, 'baz', project_id='test')\n\n    with self.assertRaises(Exception) as error:\n      datalab.storage.commands._storage._storage_create({\n        'project': 'test',\n        'bucket': [\n          'gs://foo/bar'\n        ]\n      }, None)\n    self.assertEqual(\"Couldn't create gs://foo/bar: Invalid bucket name gs://foo/bar\",\n                     str(error.exception))\n\n  @mock.patch('datalab.storage._api.Api.buckets_get', autospec=True)\n  @mock.patch('datalab.storage._api.Api.objects_get', autospec=True)\n  @mock.patch('datalab.storage._bucket.Bucket.items', autospec=True)\n  @mock.patch('datalab.storage._api.Api.objects_delete', autospec=True)\n  @mock.patch('datalab.storage._api.Api.buckets_delete', autospec=True)\n  @mock.patch('datalab.context._context.Context.default')\n  def test_storage_delete(self, mock_context_default, mock_api_bucket_delete,\n                          mock_api_objects_delete, mock_bucket_items, mock_api_objects_get,\n                          mock_api_buckets_get):\n    context = TestCases._create_context()\n    mock_context_default.return_value = context\n    # Mock API for getting items in a bucket.\n    mock_bucket_items.side_effect = TestCases._mock_bucket_items_return(context)\n    # Mock API for getting item metadata.\n    mock_api_objects_get.side_effect = TestCases._mock_api_objects_get()\n    mock_api_buckets_get.side_effect = TestCases._mock_api_buckets_get()\n\n    with self.assertRaises(Exception) as error:\n      datalab.storage.commands._storage._storage_delete({\n        'bucket': [\n          'gs://bar',\n          'gs://baz'\n        ],\n        'object': [\n          'gs://foo/item1',\n          'gs://baz/item1',\n        ]\n      }, None)\n    self.assertEqual('gs://baz does not exist\\ngs://baz/item1 does not exist',\n                     str(error.exception))\n    mock_api_bucket_delete.assert_called_with(mock.ANY, 'bar')\n    mock_api_objects_delete.assert_called_with(mock.ANY, 'foo', 'item1')\n\n  @mock.patch('datalab.context._context.Context.default')\n  def test_storage_view(self, mock_context_default):\n    context = TestCases._create_context()\n    mock_context_default.return_value = context\n    # TODO(gram): complete this test\n\n  @mock.patch('datalab.context._context.Context.default')\n  def test_storage_write(self, mock_context_default):\n    context = TestCases._create_context()\n    mock_context_default.return_value = context\n    # TODO(gram): complete this test\n\n  @staticmethod\n  def _create_context():\n    project_id = 'test'\n    creds = mock.Mock(spec=google.auth.credentials.Credentials)\n    return datalab.context.Context(project_id, creds)\n\n  @staticmethod\n  def _mock_bucket_items_return(context):\n    # Mock API for getting items in a bucket.\n    def bucket_items_side_effect(*args, **kwargs):\n      bucket = args[0].name  # self\n      if bucket == 'foo':\n        return [\n          datalab.storage._item.Item(bucket, 'item1', context=context),\n          datalab.storage._item.Item(bucket, 'item2', context=context),\n          datalab.storage._item.Item(bucket, 'item3', context=context),\n        ]\n      elif bucket == 'bar':\n        return [\n          datalab.storage._item.Item(bucket, 'object1', context=context),\n          datalab.storage._item.Item(bucket, 'object3', context=context),\n        ]\n      else:\n        return []\n    return bucket_items_side_effect\n\n  @staticmethod\n  def _mock_api_objects_get():\n    # Mock API for getting item metadata.\n    def api_objects_get_side_effect(*args, **kwargs):\n      if args[1].find('baz') >= 0:\n        return None\n      key = args[2]\n      if key.find('*') >= 0:\n        return None\n      return {'name': key}\n    return api_objects_get_side_effect\n\n  @staticmethod\n  def _mock_api_buckets_get():\n    # Mock API for getting bucket metadata.\n    def api_buckets_get_side_effect(*args, **kwargs):\n      key = args[1]\n      if key.find('*') >= 0 or key.find('baz') >= 0:\n        return None\n      return {'name': key}\n    return api_buckets_get_side_effect\n"
  },
  {
    "path": "legacy_tests/kernel/utils_tests.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom builtins import range\nimport datetime as dt\nimport collections\nimport mock\nimport pandas\nimport unittest\nimport google.auth\n\n# import Python so we can mock the parts we need to here.\nimport IPython\nimport IPython.core.magic\n\n\nIPython.core.magic.register_line_cell_magic = mock.Mock()\nIPython.core.magic.register_line_magic = mock.Mock()\nIPython.core.magic.register_cell_magic = mock.Mock()\nIPython.get_ipython = mock.Mock()\n\n\nimport datalab.bigquery  # noqa: E402\nimport datalab.context  # noqa: E402\nimport datalab.utils.commands  # noqa: E402\n\n\nclass TestCases(unittest.TestCase):\n\n  @staticmethod\n  def _get_expected_cols():\n    cols = [\n      {'type': 'number', 'id': 'Column1', 'label': 'Column1'},\n      {'type': 'number', 'id': 'Column2', 'label': 'Column2'},\n      {'type': 'string', 'id': 'Column3', 'label': 'Column3'},\n      {'type': 'boolean', 'id': 'Column4', 'label': 'Column4'},\n      {'type': 'number', 'id': 'Column5', 'label': 'Column5'},\n      {'type': 'datetime', 'id': 'Column6', 'label': 'Column6'}\n    ]\n    return cols\n\n  @staticmethod\n  def _timestamp(d):\n    return (d - dt.datetime(1970, 1, 1)).total_seconds()\n\n  @staticmethod\n  def _get_raw_rows():\n    rows = [\n      {'f': [\n        {'v': 1}, {'v': 2}, {'v': '3'}, {'v': 'true'}, {'v': 0.0},\n        {'v': TestCases._timestamp(dt.datetime(2000, 1, 1))}\n      ]},\n      {'f': [\n        {'v': 11}, {'v': 12}, {'v': '13'}, {'v': 'false'}, {'v': 0.2},\n        {'v': TestCases._timestamp(dt.datetime(2000, 1, 2))}\n      ]},\n      {'f': [\n        {'v': 21}, {'v': 22}, {'v': '23'}, {'v': 'true'}, {'v': 0.3},\n        {'v': TestCases._timestamp(dt.datetime(2000, 1, 3))}\n      ]},\n      {'f': [\n        {'v': 31}, {'v': 32}, {'v': '33'}, {'v': 'false'}, {'v': 0.4},\n        {'v': TestCases._timestamp(dt.datetime(2000, 1, 4))}\n      ]},\n      {'f': [\n        {'v': 41}, {'v': 42}, {'v': '43'}, {'v': 'true'}, {'v': 0.5},\n        {'v': TestCases._timestamp(dt.datetime(2000, 1, 5))}\n      ]},\n      {'f': [\n        {'v': 51}, {'v': 52}, {'v': '53'}, {'v': 'true'}, {'v': 0.6},\n        {'v': TestCases._timestamp(dt.datetime(2000, 1, 6))}\n      ]}\n    ]\n    return rows\n\n  @staticmethod\n  def _get_expected_rows():\n    rows = [\n      {'c': [\n        {'v': 1}, {'v': 2}, {'v': '3'}, {'v': True}, {'v': 0.0}, {'v': dt.datetime(2000, 1, 1)}\n      ]},\n      {'c': [\n        {'v': 11}, {'v': 12}, {'v': '13'}, {'v': False}, {'v': 0.2}, {'v': dt.datetime(2000, 1, 2)}\n      ]},\n      {'c': [\n        {'v': 21}, {'v': 22}, {'v': '23'}, {'v': True}, {'v': 0.3}, {'v': dt.datetime(2000, 1, 3)}\n      ]},\n      {'c': [\n        {'v': 31}, {'v': 32}, {'v': '33'}, {'v': False}, {'v': 0.4}, {'v': dt.datetime(2000, 1, 4)}\n      ]},\n      {'c': [\n        {'v': 41}, {'v': 42}, {'v': '43'}, {'v': True}, {'v': 0.5}, {'v': dt.datetime(2000, 1, 5)}\n      ]},\n      {'c': [\n        {'v': 51}, {'v': 52}, {'v': '53'}, {'v': True}, {'v': 0.6}, {'v': dt.datetime(2000, 1, 6)}\n      ]}\n    ]\n    return rows\n\n  @staticmethod\n  def _get_test_data_as_list_of_dicts():\n    test_data = [\n      {'Column1': 1, 'Column2': 2, 'Column3': '3',\n       'Column4': True, 'Column5': 0.0, 'Column6': dt.datetime(2000, 1, 1)},\n      {'Column1': 11, 'Column2': 12, 'Column3': '13',\n       'Column4': False, 'Column5': 0.2, 'Column6': dt.datetime(2000, 1, 2)},\n      {'Column1': 21, 'Column2': 22, 'Column3': '23',\n       'Column4': True, 'Column5': 0.3, 'Column6': dt.datetime(2000, 1, 3)},\n      {'Column1': 31, 'Column2': 32, 'Column3': '33',\n       'Column4': False, 'Column5': 0.4, 'Column6': dt.datetime(2000, 1, 4)},\n      {'Column1': 41, 'Column2': 42, 'Column3': '43',\n       'Column4': True, 'Column5': 0.5, 'Column6': dt.datetime(2000, 1, 5)},\n      {'Column1': 51, 'Column2': 52, 'Column3': '53',\n       'Column4': True, 'Column5': 0.6, 'Column6': dt.datetime(2000, 1, 6)}\n    ]\n    # Use OrderedDicts to make testing the result easier.\n    for i in range(0, len(test_data)):\n      test_data[i] = collections.OrderedDict(sorted(list(test_data[i].items()), key=lambda t: t[0]))\n\n    return test_data\n\n  def test_get_data_from_list_of_dicts(self):\n    self._test_get_data(TestCases._get_test_data_as_list_of_dicts(), TestCases._get_expected_cols(),\n                        TestCases._get_expected_rows(), 6,\n                        datalab.utils.commands._utils._get_data_from_list_of_dicts)\n    self._test_get_data(TestCases._get_test_data_as_list_of_dicts(), TestCases._get_expected_cols(),\n                        TestCases._get_expected_rows(), 6, datalab.utils.commands._utils.get_data)\n\n  def test_get_data_from_list_of_lists(self):\n    test_data = [\n      [1, 2, '3', True, 0.0, dt.datetime(2000, 1, 1)],\n      [11, 12, '13', False, 0.2, dt.datetime(2000, 1, 2)],\n      [21, 22, '23', True, 0.3, dt.datetime(2000, 1, 3)],\n      [31, 32, '33', False, 0.4, dt.datetime(2000, 1, 4)],\n      [41, 42, '43', True, 0.5, dt.datetime(2000, 1, 5)],\n      [51, 52, '53', True, 0.6, dt.datetime(2000, 1, 6)],\n    ]\n\n    self._test_get_data(test_data, TestCases._get_expected_cols(), TestCases._get_expected_rows(),\n                        6, datalab.utils.commands._utils._get_data_from_list_of_lists)\n    self._test_get_data(test_data, TestCases._get_expected_cols(), TestCases._get_expected_rows(),\n                        6, datalab.utils.commands._utils.get_data)\n\n  def test_get_data_from_dataframe(self):\n    df = pandas.DataFrame(self._get_test_data_as_list_of_dicts())\n    self._test_get_data(df, TestCases._get_expected_cols(), TestCases._get_expected_rows(), 6,\n                        datalab.utils.commands._utils._get_data_from_dataframe)\n    self._test_get_data(df, TestCases._get_expected_cols(), TestCases._get_expected_rows(), 6,\n                        datalab.utils.commands._utils.get_data)\n\n  @mock.patch('datalab.bigquery._api.Api.tabledata_list')\n  @mock.patch('datalab.bigquery._table.Table.exists')\n  @mock.patch('datalab.bigquery._api.Api.tables_get')\n  @mock.patch('datalab.context._context.Context.default')\n  def test_get_data_from_table(self, mock_context_default, mock_api_tables_get,\n                               mock_table_exists, mock_api_tabledata_list):\n    data = TestCases._get_expected_rows()\n    mock_context_default.return_value = TestCases._create_context()\n    mock_api_tables_get.return_value = {\n      'numRows': len(data),\n      'schema': {\n        'fields': [\n          {'name': 'Column1', 'type': 'INTEGER'},\n          {'name': 'Column2', 'type': 'INTEGER'},\n          {'name': 'Column3', 'type': 'STRING'},\n          {'name': 'Column4', 'type': 'BOOLEAN'},\n          {'name': 'Column5', 'type': 'FLOAT'},\n          {'name': 'Column6', 'type': 'TIMESTAMP'}\n        ]\n      }\n    }\n    mock_table_exists.return_value = True\n    raw_data = self._get_raw_rows()\n\n    def tabledata_list(*args, **kwargs):\n      start_index = kwargs['start_index']\n      max_results = kwargs['max_results']\n      if max_results < 0:\n        max_results = len(data)\n      return {'rows': raw_data[start_index:start_index + max_results]}\n\n    mock_api_tabledata_list.side_effect = tabledata_list\n    t = datalab.bigquery.Table('foo.bar')\n    self._test_get_data(t, TestCases._get_expected_cols(), TestCases._get_expected_rows(), 6,\n                        datalab.utils.commands._utils._get_data_from_table)\n    self._test_get_data(t, TestCases._get_expected_cols(), TestCases._get_expected_rows(), 6,\n                        datalab.utils.commands._utils.get_data)\n\n  def test_get_data_from_empty_list(self):\n    self._test_get_data([], [], [], 0, datalab.utils.commands._utils.get_data)\n\n  def test_get_data_from_malformed_list(self):\n    with self.assertRaises(Exception) as error:\n      self._test_get_data(['foo', 'bar'], [], [], 0, datalab.utils.commands._utils.get_data)\n    self.assertEquals('To get tabular data from a list it must contain dictionaries or lists.',\n                      str(error.exception))\n\n  def _test_get_data(self, test_data, cols, rows, expected_count, fn):\n    self.maxDiff = None\n    data, count = fn(test_data)\n    self.assertEquals(expected_count, count)\n    self.assertEquals({'cols': cols, 'rows': rows}, data)\n\n    # Test first_row. Note that count must be set in this case so we use a value greater than the\n    # data set size.\n    for first in range(0, 6):\n      data, count = fn(test_data, first_row=first, count=10)\n      self.assertEquals(expected_count, count)\n      self.assertEquals({'cols': cols, 'rows': rows[first:]}, data)\n\n    # Test first_row + count\n    for first in range(0, 6):\n      data, count = fn(test_data, first_row=first, count=2)\n      self.assertEquals(expected_count, count)\n      self.assertEquals({'cols': cols, 'rows': rows[first:first + 2]}, data)\n\n    # Test subsets of columns\n\n    # No columns\n    data, count = fn(test_data, fields=[])\n    self.assertEquals({'cols': [], 'rows': [{'c': []}] * expected_count}, data)\n\n    # Single column\n    data, count = fn(test_data, fields=['Column3'])\n\n    if expected_count == 0:\n      return\n\n    self.assertEquals({'cols': [cols[2]],\n                       'rows': [{'c': [row['c'][2]]} for row in rows]}, data)\n\n    # Multi-columns\n    data, count = fn(test_data, fields=['Column1', 'Column3', 'Column6'])\n    self.assertEquals({'cols': [cols[0], cols[2], cols[5]],\n                       'rows': [{'c': [row['c'][0], row['c'][2], row['c'][5]]} for row in rows]},\n                      data)\n\n    # Switch order\n    data, count = fn(test_data, fields=['Column3', 'Column1'])\n    self.assertEquals({'cols': [cols[2], cols[0]],\n                       'rows': [{'c': [row['c'][2], row['c'][0]]} for row in rows]}, data)\n\n    # Select all\n    data, count = fn(test_data,\n                     fields=['Column1', 'Column2', 'Column3', 'Column4', 'Column5', 'Column6'])\n    self.assertEquals({'cols': cols, 'rows': rows}, data)\n\n  @staticmethod\n  def _create_api():\n    context = TestCases._create_context()\n    return datalab.bigquery._api.Api(context.credentials, context.project_id)\n\n  @staticmethod\n  def _create_context():\n    project_id = 'test'\n    creds = mock.Mock(spec=google.auth.credentials.Credentials)\n    return datalab.context.Context(project_id, creds)\n"
  },
  {
    "path": "legacy_tests/main.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nimport os\nimport sys\nimport unittest\n\n# Set up the path so that we can import our datalab.* packages.\nsys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../datalab')))  # noqa\n\nimport bigquery.api_tests\nimport bigquery.dataset_tests\nimport bigquery.federated_table_tests\nimport bigquery.jobs_tests\nimport bigquery.parser_tests\nimport bigquery.query_tests\nimport bigquery.sampling_tests\nimport bigquery.schema_tests\nimport bigquery.table_tests\nimport bigquery.udf_tests\nimport bigquery.view_tests\nimport data.sql_tests\nimport kernel.bigquery_tests\nimport kernel.chart_data_tests\nimport kernel.chart_tests\nimport kernel.commands_tests\nimport kernel.html_tests\nimport kernel.module_tests\nimport kernel.sql_tests\nimport kernel.storage_tests\nimport kernel.utils_tests\nimport stackdriver.commands.monitoring_tests\nimport stackdriver.monitoring.group_tests\nimport stackdriver.monitoring.metric_tests\nimport stackdriver.monitoring.resource_tests\nimport stackdriver.monitoring.query_metadata_tests\nimport stackdriver.monitoring.query_tests\nimport stackdriver.monitoring.utils_tests\nimport storage.api_tests\nimport storage.bucket_tests\nimport storage.item_tests\nimport _util.http_tests\nimport _util.lru_cache_tests\nimport _util.util_tests\n\n\n_TEST_MODULES = [\n    bigquery.api_tests,\n    bigquery.dataset_tests,\n    bigquery.federated_table_tests,\n    bigquery.jobs_tests,\n    bigquery.parser_tests,\n    bigquery.query_tests,\n    bigquery.sampling_tests,\n    bigquery.schema_tests,\n    bigquery.table_tests,\n    bigquery.udf_tests,\n    bigquery.view_tests,\n    bigquery.sampling_tests,\n    data.sql_tests,\n    kernel.bigquery_tests,\n    kernel.chart_data_tests,\n    kernel.chart_tests,\n    kernel.commands_tests,\n    kernel.html_tests,\n    kernel.module_tests,\n    kernel.sql_tests,\n    kernel.storage_tests,\n    kernel.utils_tests,\n    stackdriver.commands.monitoring_tests,\n    stackdriver.monitoring.group_tests,\n    stackdriver.monitoring.metric_tests,\n    stackdriver.monitoring.resource_tests,\n    stackdriver.monitoring.query_metadata_tests,\n    stackdriver.monitoring.query_tests,\n    stackdriver.monitoring.utils_tests,\n    storage.api_tests,\n    storage.bucket_tests,\n    storage.item_tests,\n    _util.http_tests,\n    _util.lru_cache_tests,\n    _util.util_tests\n]\n\nif __name__ == '__main__':\n  suite = unittest.TestSuite()\n  for m in _TEST_MODULES:\n    suite.addTests(unittest.defaultTestLoader.loadTestsFromModule(m))\n\n  runner = unittest.TextTestRunner()\n  result = runner.run(suite)\n\n  sys.exit(len(result.errors) + len(result.failures))\n"
  },
  {
    "path": "legacy_tests/stackdriver/__init__.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n"
  },
  {
    "path": "legacy_tests/stackdriver/commands/__init__.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n"
  },
  {
    "path": "legacy_tests/stackdriver/commands/monitoring_tests.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nimport mock\nimport unittest\n\nimport pandas\n\nimport datalab.stackdriver.commands._monitoring as monitoring_commands\n\nPROJECT = 'my-project'\n\n\nclass TestCases(unittest.TestCase):\n\n  @mock.patch('datalab.stackdriver.commands._monitoring._render_dataframe')\n  @mock.patch('datalab.stackdriver.monitoring.MetricDescriptors')\n  def test_list_metric_descriptors(self, mock_metric_descriptors, mock_render_dataframe):\n    METRIC_TYPES = ['compute.googleapis.com/instances/cpu/utilization',\n                    'compute.googleapis.com/instances/cpu/usage_time']\n    DATAFRAME = pandas.DataFrame(METRIC_TYPES, columns=['Metric type'])\n    PATTERN = 'compute*cpu*'\n\n    mock_metric_class = mock_metric_descriptors.return_value\n    mock_metric_class.as_dataframe.return_value = DATAFRAME\n\n    monitoring_commands._list_metric_descriptors(\n        {'project': PROJECT, 'type': PATTERN}, None)\n\n    mock_metric_descriptors.assert_called_once_with(project_id=PROJECT)\n    mock_metric_class.as_dataframe.assert_called_once_with(pattern=PATTERN)\n    mock_render_dataframe.assert_called_once_with(DATAFRAME)\n\n  @mock.patch('datalab.stackdriver.commands._monitoring._render_dataframe')\n  @mock.patch('datalab.stackdriver.monitoring.ResourceDescriptors')\n  def test_list_resource_descriptors(self, mock_resource_descriptors, mock_render_dataframe):\n    RESOURCE_TYPES = ['gce_instance', 'aws_ec2_instance']\n    DATAFRAME = pandas.DataFrame(RESOURCE_TYPES, columns=['Resource type'])\n    PATTERN = '*instance*'\n\n    mock_resource_class = mock_resource_descriptors.return_value\n    mock_resource_class.as_dataframe.return_value = DATAFRAME\n\n    monitoring_commands._list_resource_descriptors(\n        {'project': PROJECT, 'type': PATTERN}, None)\n\n    mock_resource_descriptors.assert_called_once_with(project_id=PROJECT)\n    mock_resource_class.as_dataframe.assert_called_once_with(pattern=PATTERN)\n    mock_render_dataframe.assert_called_once_with(DATAFRAME)\n\n  @mock.patch('datalab.stackdriver.commands._monitoring._render_dataframe')\n  @mock.patch('datalab.stackdriver.monitoring.Groups')\n  def test_list_groups(self, mock_groups, mock_render_dataframe):\n    GROUP_IDS = ['GROUP-205', 'GROUP-101']\n    DATAFRAME = pandas.DataFrame(GROUP_IDS, columns=['Group ID'])\n    PATTERN = 'GROUP-*'\n\n    mock_group_class = mock_groups.return_value\n    mock_group_class.as_dataframe.return_value = DATAFRAME\n\n    monitoring_commands._list_groups(\n        {'project': PROJECT, 'name': PATTERN}, None)\n\n    mock_groups.assert_called_once_with(project_id=PROJECT)\n    mock_group_class.as_dataframe.assert_called_once_with(pattern=PATTERN)\n    mock_render_dataframe.assert_called_once_with(DATAFRAME)\n"
  },
  {
    "path": "legacy_tests/stackdriver/monitoring/__init__.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n"
  },
  {
    "path": "legacy_tests/stackdriver/monitoring/group_tests.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\n\nimport mock\nimport unittest\n\nimport google.cloud.monitoring_v3\n\nimport google.auth\nimport google.datalab\nimport google.datalab.stackdriver.monitoring as gcm\n\nDEFAULT_PROJECT = 'test'\nPROJECT = 'my-project'\nGROUP_IDS = ['GROUP-205', 'GROUP-101']\nPARENT_IDS = ['', GROUP_IDS[0]]\nDISPLAY_NAMES = ['All Instances', 'GCE Instances']\nPARENT_DISPLAY_NAMES = ['', DISPLAY_NAMES[0]]\nFILTER_STRINGS = ['resource.type = ends_with(\"instance\")',\n                  'resource.type = \"gce_instance\"']\nIS_CLUSTERS = [False, True]\n\n\nclass TestCases(unittest.TestCase):\n\n  def setUp(self):\n    self.context = self._create_context(DEFAULT_PROJECT)\n    self.groups = gcm.Groups(context=self.context)\n\n  @mock.patch('google.datalab.Context.default')\n  def test_constructor_minimal(self, mock_context_default):\n    mock_context_default.return_value = self.context\n\n    groups = gcm.Groups()\n\n    self.assertIs(groups._context, self.context)\n    self.assertIsNone(groups._group_dict)\n\n    self.assertEqual(groups._client.project, DEFAULT_PROJECT)\n\n  def test_constructor_maximal(self):\n    context = self._create_context(PROJECT)\n    groups = gcm.Groups(context)\n    self.assertIs(groups._context, context)\n    self.assertIsNone(groups._group_dict)\n    self.assertEqual(groups._client.project, PROJECT)\n\n  @mock.patch('google.cloud.monitoring_v3.GroupServiceClient.list_groups')\n  def test_list(self, mock_api_list_groups):\n    mock_api_list_groups.return_value = self._list_groups_get_result(\n        context=self.context)\n\n    group_list = self.groups.list()\n\n    mock_api_list_groups.assert_called_once_with(DEFAULT_PROJECT)\n    self.assertEqual(len(group_list), 2)\n    self.assertEqual(group_list[0].name, GROUP_IDS[0])\n    self.assertEqual(group_list[1].name, GROUP_IDS[1])\n\n  @mock.patch('google.cloud.monitoring_v3.GroupServiceClient.list_groups')\n  def test_list_w_pattern_match(self, mock_api_list_groups):\n    mock_api_list_groups.return_value = self._list_groups_get_result(\n        context=self.context)\n\n    group_list = self.groups.list(pattern='GCE*')\n\n    mock_api_list_groups.assert_called_once_with(DEFAULT_PROJECT)\n    self.assertEqual(len(group_list), 1)\n    self.assertEqual(group_list[0].name, GROUP_IDS[1])\n\n  @mock.patch('google.cloud.monitoring_v3.GroupServiceClient.list_groups')\n  def test_list_caching(self, mock_gcloud_list_groups):\n    mock_gcloud_list_groups.return_value = self._list_groups_get_result(\n        context=self.context)\n\n    actual_list1 = self.groups.list()\n    actual_list2 = self.groups.list()\n\n    mock_gcloud_list_groups.assert_called_once_with(DEFAULT_PROJECT)\n    self.assertEqual(actual_list1, actual_list2)\n\n  @mock.patch('google.cloud.monitoring_v3.GroupServiceClient.list_groups')\n  def test_as_dataframe(self, mock_gcloud_list_groups):\n    mock_gcloud_list_groups.return_value = self._list_groups_get_result(\n        context=self.context)\n    dataframe = self.groups.as_dataframe()\n    mock_gcloud_list_groups.assert_called_once_with(DEFAULT_PROJECT)\n\n    expected_headers = list(gcm.Groups._DISPLAY_HEADERS)\n    self.assertEqual(dataframe.columns.tolist(), expected_headers)\n    self.assertEqual(dataframe.columns.names, [None])\n\n    self.assertEqual(dataframe.index.tolist(), list(range(len(GROUP_IDS))))\n    self.assertEqual(dataframe.index.names, [None])\n\n    expected_values = [list(row) for row in\n                       zip(GROUP_IDS, DISPLAY_NAMES, PARENT_IDS,\n                           PARENT_DISPLAY_NAMES, IS_CLUSTERS, FILTER_STRINGS)]\n    self.assertEqual(dataframe.values.tolist(), expected_values)\n\n  @mock.patch('google.cloud.monitoring_v3.GroupServiceClient.list_groups')\n  def test_as_dataframe_w_all_args(self, mock_gcloud_list_groups):\n    mock_gcloud_list_groups.return_value = self._list_groups_get_result(\n        context=self.context)\n    dataframe = self.groups.as_dataframe(pattern='*Instance*', max_rows=1)\n    mock_gcloud_list_groups.assert_called_once_with(DEFAULT_PROJECT)\n\n    expected_headers = list(gcm.Groups._DISPLAY_HEADERS)\n    self.assertEqual(dataframe.columns.tolist(), expected_headers)\n    self.assertEqual(dataframe.index.tolist(), [0])\n    self.assertEqual(dataframe.iloc[0, 0], GROUP_IDS[0])\n\n  @staticmethod\n  def _create_context(project_id):\n    creds = mock.Mock(spec=google.auth.credentials.Credentials)\n    return google.datalab.Context(project_id, creds)\n\n  @staticmethod\n  def _list_groups_get_result(context):\n    groups = []\n    for group_id, parent_id, display_name, filter_string, is_cluster in \\\n            zip(GROUP_IDS, PARENT_IDS, DISPLAY_NAMES, FILTER_STRINGS, IS_CLUSTERS):\n      group = google.cloud.monitoring_v3.types.Group(\n          name=group_id, display_name=display_name,\n          parent_name=parent_id, filter=filter_string,\n          is_cluster=is_cluster)\n      groups.append(group)\n\n    return groups\n"
  },
  {
    "path": "legacy_tests/stackdriver/monitoring/metric_tests.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\n\nimport mock\nimport unittest\n\nimport google.cloud.monitoring_v3\n\nimport google.auth\nimport google.datalab\nimport google.datalab.stackdriver.monitoring as gcm\n\nDEFAULT_PROJECT = 'test'\nPROJECT = 'my-project'\nMETRIC_TYPES = ['compute.googleapis.com/instances/cpu/utilization',\n                'compute.googleapis.com/instances/cpu/usage_time']\nDISPLAY_NAMES = ['CPU Utilization', 'CPU Usage']\nMETRIC_KIND = 'GAUGE'\nVALUE_TYPE = 'DOUBLE'\nUNIT = '1'\nLABELS = [dict(key='instance_name', value_type='STRING',\n               description='VM instance'),\n          dict(key='device_name', value_type='STRING',\n               description='Device name')]\nFILTER_STRING = 'metric.type:\"cpu\"'\nTYPE_PREFIX = 'compute'\n\n\nclass TestCases(unittest.TestCase):\n\n  def setUp(self):\n    self.context = self._create_context(DEFAULT_PROJECT)\n    self.descriptors = gcm.MetricDescriptors(context=self.context)\n\n  @mock.patch('google.datalab.Context.default')\n  def test_constructor_minimal(self, mock_context_default):\n    mock_context_default.return_value = self.context\n\n    descriptors = gcm.MetricDescriptors()\n\n    self.assertEqual(descriptors._client.project, DEFAULT_PROJECT)\n\n    self.assertIsNone(descriptors._filter_string)\n    self.assertIsNone(descriptors._type_prefix)\n    self.assertIsNone(descriptors._descriptors)\n\n  def test_constructor_maximal(self):\n    context = self._create_context(PROJECT)\n    descriptors = gcm.MetricDescriptors(\n        filter_string=FILTER_STRING, type_prefix=TYPE_PREFIX,\n        context=context)\n\n    self.assertEqual(descriptors._client.project, PROJECT)\n\n    self.assertEqual(descriptors._filter_string, FILTER_STRING)\n    self.assertEqual(descriptors._type_prefix, TYPE_PREFIX)\n    self.assertIsNone(descriptors._descriptors)\n\n  @mock.patch('google.cloud.monitoring_v3.MetricServiceClient.list_metric_descriptors')\n  def test_list(self, mock_gcloud_list_descriptors):\n    mock_gcloud_list_descriptors.return_value = self._list_metrics_get_result(\n        context=self.context)\n\n    metric_descriptor_list = self.descriptors.list()\n\n    mock_gcloud_list_descriptors.assert_called_once_with(\n        DEFAULT_PROJECT, filter_='')\n    self.assertEqual(len(metric_descriptor_list), 2)\n    self.assertEqual(metric_descriptor_list[0].type, METRIC_TYPES[0])\n    self.assertEqual(metric_descriptor_list[1].type, METRIC_TYPES[1])\n\n  @mock.patch('google.cloud.monitoring_v3.MetricServiceClient.list_metric_descriptors')\n  def test_list_w_api_filter(self, mock_gcloud_list_descriptors):\n    mock_gcloud_list_descriptors.return_value = self._list_metrics_get_result(\n        context=self.context)\n\n    descriptors = gcm.MetricDescriptors(\n        filter_string=FILTER_STRING, type_prefix=TYPE_PREFIX,\n        context=self.context)\n    metric_descriptor_list = descriptors.list()\n\n    expected_filter = '{} AND metric.type = starts_with(\"{}\")'.format(\n        FILTER_STRING, TYPE_PREFIX)\n\n    mock_gcloud_list_descriptors.assert_called_once_with(\n        DEFAULT_PROJECT, filter_=expected_filter)\n    self.assertEqual(len(metric_descriptor_list), 2)\n    self.assertEqual(metric_descriptor_list[0].type, METRIC_TYPES[0])\n    self.assertEqual(metric_descriptor_list[1].type, METRIC_TYPES[1])\n\n  @mock.patch('google.cloud.monitoring_v3.MetricServiceClient.list_metric_descriptors')\n  def test_list_w_pattern_match(self, mock_gcloud_list_descriptors):\n    mock_gcloud_list_descriptors.return_value = self._list_metrics_get_result(\n        context=self.context)\n\n    metric_descriptor_list = self.descriptors.list(pattern='*usage_time')\n\n    mock_gcloud_list_descriptors.assert_called_once_with(\n        DEFAULT_PROJECT, filter_='')\n    self.assertEqual(len(metric_descriptor_list), 1)\n    self.assertEqual(metric_descriptor_list[0].type, METRIC_TYPES[1])\n\n  @mock.patch('google.cloud.monitoring_v3.MetricServiceClient.list_metric_descriptors')\n  def test_list_caching(self, mock_gcloud_list_descriptors):\n    mock_gcloud_list_descriptors.return_value = self._list_metrics_get_result(\n        context=self.context)\n\n    actual_list1 = self.descriptors.list()\n    actual_list2 = self.descriptors.list()\n\n    mock_gcloud_list_descriptors.assert_called_once_with(\n        DEFAULT_PROJECT, filter_='')\n    self.assertEqual(actual_list1, actual_list2)\n\n  @mock.patch('google.datalab.stackdriver.monitoring.MetricDescriptors.list')\n  def test_as_dataframe(self, mock_datalab_list_descriptors):\n    mock_datalab_list_descriptors.return_value = self._list_metrics_get_result(\n        context=self.context)\n    dataframe = self.descriptors.as_dataframe()\n    mock_datalab_list_descriptors.assert_called_once_with('*')\n\n    expected_headers = list(gcm.MetricDescriptors._DISPLAY_HEADERS)\n    self.assertEqual(dataframe.columns.tolist(), expected_headers)\n    self.assertEqual(dataframe.columns.names, [None])\n\n    self.assertEqual(dataframe.index.tolist(), list(range(len(METRIC_TYPES))))\n    self.assertEqual(dataframe.index.names, [None])\n\n    expected_labels = 'instance_name, device_name'\n    expected_values = [\n        [metric_type, display_name, METRIC_KIND, VALUE_TYPE, UNIT,\n         expected_labels]\n        for metric_type, display_name in zip(METRIC_TYPES, DISPLAY_NAMES)]\n    self.assertEqual(dataframe.values.tolist(), expected_values)\n\n  @mock.patch('google.datalab.stackdriver.monitoring.MetricDescriptors.list')\n  def test_as_dataframe_w_all_args(self, mock_datalab_list_descriptors):\n    mock_datalab_list_descriptors.return_value = self._list_metrics_get_result(\n        context=self.context)\n    dataframe = self.descriptors.as_dataframe(pattern='*cpu*', max_rows=1)\n    mock_datalab_list_descriptors.assert_called_once_with('*cpu*')\n\n    expected_headers = list(gcm.MetricDescriptors._DISPLAY_HEADERS)\n    self.assertEqual(dataframe.columns.tolist(), expected_headers)\n    self.assertEqual(dataframe.index.tolist(), [0])\n    self.assertEqual(dataframe.iloc[0, 0], METRIC_TYPES[0])\n\n  @staticmethod\n  def _create_context(project_id):\n    creds = mock.Mock(spec=google.auth.credentials.Credentials)\n    return google.datalab.Context(project_id, creds)\n\n  @staticmethod\n  def _list_metrics_get_result(context):\n    all_labels = [google.cloud.monitoring_v3.types.LabelDescriptor(**labels)\n                  for labels in LABELS]\n    descriptors = [\n        google.cloud.monitoring_v3.types.MetricDescriptor(\n            type=metric_type, metric_kind=METRIC_KIND, value_type=VALUE_TYPE,\n            unit=UNIT, display_name=display_name, labels=all_labels,\n        )\n        for metric_type, display_name in zip(METRIC_TYPES, DISPLAY_NAMES)]\n    return descriptors\n"
  },
  {
    "path": "legacy_tests/stackdriver/monitoring/query_metadata_tests.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nimport mock\nimport unittest\n\nfrom google.cloud.monitoring_v3.types import Metric\nfrom google.cloud.monitoring_v3.types import MonitoredResource\nfrom google.cloud.monitoring_v3.types import TimeSeries\n\nimport google.auth\nimport google.datalab\nimport google.datalab.stackdriver.monitoring as gcm\n\n\nPROJECT = 'my-project'\n\nMETRIC_TYPE = 'compute.googleapis.com/instance/cpu/utilization'\nRESOURCE_TYPE = 'gce_instance'\nINSTANCE_NAMES = ['instance-1', 'instance-2']\nINSTANCE_ZONES = ['us-east1-a', 'us-east1-b']\nINSTANCE_IDS = ['1234567890123456789', '9876543210987654321']\n\n\nclass TestCases(unittest.TestCase):\n\n  def setUp(self):\n    creds = mock.Mock(spec=google.auth.credentials.Credentials)\n    context = google.datalab.Context(PROJECT, creds)\n    self.query = gcm.Query(METRIC_TYPE, context=context)\n\n  @mock.patch('google.datalab.stackdriver.monitoring.Query.iter')\n  def test_constructor(self, mock_query_iter):\n    time_series_iterable = list(self._query_iter_get_result())\n    mock_query_iter.return_value = self._query_iter_get_result()\n\n    query_metadata = gcm.QueryMetadata(self.query)\n\n    mock_query_iter.assert_called_once_with(headers_only=True)\n    self.assertEqual(query_metadata.metric_type, METRIC_TYPE)\n    self.assertEqual(query_metadata.resource_types, set([RESOURCE_TYPE]))\n    self.assertEqual(query_metadata._timeseries_list, time_series_iterable)\n\n  @mock.patch('google.datalab.stackdriver.monitoring.Query.iter')\n  def test_iteration(self, mock_query_iter):\n    time_series_iterable = list(self._query_iter_get_result())\n    mock_query_iter.return_value = self._query_iter_get_result()\n\n    query_metadata = gcm.QueryMetadata(self.query)\n    response = list(query_metadata)\n\n    self.assertEqual(len(response), len(time_series_iterable))\n    self.assertEqual(response, time_series_iterable)\n\n  @mock.patch('google.datalab.stackdriver.monitoring.Query.iter')\n  def test_as_dataframe(self, mock_query_iter):\n    mock_query_iter.return_value = self._query_iter_get_result()\n\n    query_metadata = gcm.QueryMetadata(self.query)\n    dataframe = query_metadata.as_dataframe()\n\n    NUM_INSTANCES = len(INSTANCE_IDS)\n\n    self.assertEqual(dataframe.shape, (NUM_INSTANCES, 5))\n\n    expected_values = [\n        [RESOURCE_TYPE, PROJECT, zone, instance_id, instance_name]\n        for zone, instance_id, instance_name\n        in zip(INSTANCE_ZONES, INSTANCE_IDS, INSTANCE_NAMES)]\n    self.assertEqual(dataframe.values.tolist(), expected_values)\n\n    expected_headers = [\n        ('resource.type', ''),\n        ('resource.labels', 'project_id'),\n        ('resource.labels', 'zone'),\n        ('resource.labels', 'instance_id'),\n        ('metric.labels', 'instance_name')\n    ]\n    self.assertEqual(dataframe.columns.tolist(), expected_headers)\n    self.assertEqual(dataframe.columns.names, [None, None])\n\n    self.assertEqual(dataframe.index.tolist(), list(range(NUM_INSTANCES)))\n    self.assertEqual(dataframe.index.names, [None])\n\n  @mock.patch('google.datalab.stackdriver.monitoring.Query.iter')\n  def test_as_dataframe_w_max_rows(self, mock_query_iter):\n    mock_query_iter.return_value = self._query_iter_get_result()\n\n    MAX_ROWS = 1\n    query_metadata = gcm.QueryMetadata(self.query)\n    dataframe = query_metadata.as_dataframe(max_rows=MAX_ROWS)\n\n    self.assertEqual(dataframe.shape, (MAX_ROWS, 5))\n\n    expected_values = [\n        [RESOURCE_TYPE, PROJECT, INSTANCE_ZONES[0], INSTANCE_IDS[0],\n         INSTANCE_NAMES[0]],\n    ]\n    self.assertEqual(dataframe.values.tolist(), expected_values)\n\n    expected_headers = [\n        ('resource.type', ''),\n        ('resource.labels', 'project_id'),\n        ('resource.labels', 'zone'),\n        ('resource.labels', 'instance_id'),\n        ('metric.labels', 'instance_name')\n    ]\n    self.assertEqual(dataframe.columns.tolist(), expected_headers)\n    self.assertEqual(dataframe.columns.names, [None, None])\n\n    self.assertEqual(dataframe.index.tolist(), list(range(MAX_ROWS)))\n    self.assertEqual(dataframe.index.names, [None])\n\n  @mock.patch('google.datalab.stackdriver.monitoring.Query.iter')\n  def test_as_dataframe_w_no_data(self, mock_query_iter):\n    query_metadata = gcm.QueryMetadata(self.query)\n    dataframe = query_metadata.as_dataframe()\n\n    self.assertEqual(dataframe.shape, (0, 0))\n    self.assertIsNone(dataframe.columns.name)\n    self.assertIsNone(dataframe.index.name)\n\n  @staticmethod\n  def _query_iter_get_result():\n    METRIC_LABELS = list({'instance_name': name} for name in INSTANCE_NAMES)\n    RESOURCE_LABELS = list({\n        'project_id': PROJECT,\n        'zone': zone,\n        'instance_id': instance_id,\n    } for zone, instance_id in zip(INSTANCE_ZONES, INSTANCE_IDS))\n\n    for metric_labels, resource_labels in zip(METRIC_LABELS, RESOURCE_LABELS):\n      yield TimeSeries(\n        metric=Metric(type=METRIC_TYPE, labels=metric_labels),\n        resource=MonitoredResource(type=RESOURCE_TYPE, labels=resource_labels),\n        metric_kind='GAUGE',\n        value_type='DOUBLE',\n        points=[],\n      )\n"
  },
  {
    "path": "legacy_tests/stackdriver/monitoring/query_tests.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nimport datetime\nimport mock\nimport unittest\n\nfrom google.cloud.monitoring_v3.query import Query as BaseQuery\n\nimport google.auth\nimport google.datalab\nimport google.datalab.stackdriver.monitoring as gcm\n\n\nPROJECT = 'my-project'\nMETRIC_TYPE = 'compute.googleapis.com/instance/cpu/utilization'\nRESOURCE_TYPE = 'gce_instance'\nINSTANCE_NAMES = ['instance-1', 'instance-2']\nINSTANCE_ZONES = ['us-east1-a', 'us-east1-b']\nINSTANCE_IDS = ['1234567890123456789', '9876543210987654321']\n\n\nclass TestCases(unittest.TestCase):\n\n  def setUp(self):\n    creds = mock.Mock(spec=google.auth.credentials.Credentials)\n    self.context = google.datalab.Context(PROJECT, creds)\n\n  @mock.patch('google.datalab.Context.default')\n  def test_constructor_minimal(self, mock_context_default):\n    mock_context_default.return_value = self.context\n\n    query = gcm.Query()\n\n    self.assertEqual(query._filter.metric_type, BaseQuery.DEFAULT_METRIC_TYPE)\n\n    self.assertIsNone(query._start_time)\n    self.assertIsNone(query._end_time)\n\n    self.assertEqual(query._per_series_aligner, 0)\n    self.assertEqual(query._alignment_period_seconds, 0)\n    self.assertEqual(query._cross_series_reducer, 0)\n    self.assertEqual(query._group_by_fields, ())\n\n  def test_constructor_maximal(self):\n    UPTIME_METRIC = 'compute.googleapis.com/instance/uptime'\n    T1 = datetime.datetime(2016, 4, 7, 2, 30, 30)\n    DAYS, HOURS, MINUTES = 1, 2, 3\n    T0 = T1 - datetime.timedelta(days=DAYS, hours=HOURS, minutes=MINUTES)\n\n    query = gcm.Query(UPTIME_METRIC,\n                      end_time=T1, days=DAYS, hours=HOURS, minutes=MINUTES,\n                      context=self.context)\n\n    self.assertEqual(query._filter.metric_type, UPTIME_METRIC)\n\n    self.assertEqual(query._start_time, T0)\n    self.assertEqual(query._end_time, T1)\n\n    self.assertEqual(query._per_series_aligner, 0)\n    self.assertEqual(query._alignment_period_seconds, 0)\n    self.assertEqual(query._cross_series_reducer, 0)\n    self.assertEqual(query._group_by_fields, ())\n\n  @mock.patch('google.datalab.stackdriver.monitoring.Query.iter')\n  def test_metadata(self, mock_query_iter):\n    query = gcm.Query(METRIC_TYPE, hours=1, context=self.context)\n    query_metadata = query.metadata()\n\n    mock_query_iter.assert_called_once_with(headers_only=True)\n    self.assertIsInstance(query_metadata, gcm.QueryMetadata)\n    self.assertEqual(query_metadata.metric_type, METRIC_TYPE)\n"
  },
  {
    "path": "legacy_tests/stackdriver/monitoring/resource_tests.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nimport mock\nimport unittest\n\nimport google.cloud.monitoring_v3\n\nimport google.auth\nimport google.datalab\nimport google.datalab.stackdriver.monitoring as gcm\n\nDEFAULT_PROJECT = 'test'\nPROJECT = 'my-project'\nRESOURCE_TYPES = ['gce_instance', 'aws_ec2_instance']\nDISPLAY_NAMES = ['GCE VM Instance', 'Amazon EC2 Instance']\n\nLABELS = [dict(key='instance_id', value_type='STRING',\n               description='VM instance ID'),\n          dict(key='project_id', value_type='STRING',\n               description='Project ID')]\nFILTER_STRING = 'resource.type = ends_with(\"instance\")'\n\n\nclass TestCases(unittest.TestCase):\n\n  def setUp(self):\n    self.context = self._create_context(DEFAULT_PROJECT)\n    self.descriptors = gcm.ResourceDescriptors(context=self.context)\n\n  @mock.patch('google.datalab.Context.default')\n  def test_constructor_minimal(self, mock_context_default):\n    mock_context_default.return_value = self.context\n    descriptors = gcm.ResourceDescriptors()\n    self.assertEqual(descriptors._client.project, DEFAULT_PROJECT)\n    self.assertIsNone(descriptors._filter_string)\n    self.assertIsNone(descriptors._descriptors)\n\n  def test_constructor_maximal(self):\n    context = self._create_context(PROJECT)\n    descriptors = gcm.ResourceDescriptors(\n        filter_string=FILTER_STRING, context=context)\n    self.assertEqual(descriptors._client.project, PROJECT)\n\n    self.assertEqual(descriptors._filter_string, FILTER_STRING)\n    self.assertIsNone(descriptors._descriptors)\n\n  @mock.patch('google.cloud.monitoring_v3.MetricServiceClient.list_monitored_resource_descriptors')\n  def test_list(self, mock_api_list_descriptors):\n    mock_api_list_descriptors.return_value = self._list_resources_get_result()\n\n    resource_descriptor_list = self.descriptors.list()\n\n    mock_api_list_descriptors.assert_called_once_with(\n        DEFAULT_PROJECT, filter_=None)\n    self.assertEqual(len(resource_descriptor_list), 2)\n    self.assertEqual(resource_descriptor_list[0].type, RESOURCE_TYPES[0])\n    self.assertEqual(resource_descriptor_list[1].type, RESOURCE_TYPES[1])\n\n  @mock.patch('google.cloud.monitoring_v3.MetricServiceClient.list_monitored_resource_descriptors')\n  def test_list_w_api_filter(self, mock_api_list_descriptors):\n    mock_api_list_descriptors.return_value = self._list_resources_get_result()\n\n    descriptors = gcm.ResourceDescriptors(\n        filter_string=FILTER_STRING, context=self.context)\n    resource_descriptor_list = descriptors.list()\n\n    mock_api_list_descriptors.assert_called_once_with(\n        DEFAULT_PROJECT, filter_=FILTER_STRING)\n    self.assertEqual(len(resource_descriptor_list), 2)\n    self.assertEqual(resource_descriptor_list[0].type, RESOURCE_TYPES[0])\n    self.assertEqual(resource_descriptor_list[1].type, RESOURCE_TYPES[1])\n\n  @mock.patch('google.cloud.monitoring_v3.MetricServiceClient.list_monitored_resource_descriptors')\n  def test_list_w_pattern_match(self, mock_api_list_descriptors):\n    mock_api_list_descriptors.return_value = self._list_resources_get_result()\n\n    resource_descriptor_list = self.descriptors.list(pattern='*ec2*')\n\n    mock_api_list_descriptors.assert_called_once_with(\n        DEFAULT_PROJECT, filter_=None)\n    self.assertEqual(len(resource_descriptor_list), 1)\n    self.assertEqual(resource_descriptor_list[0].type, RESOURCE_TYPES[1])\n\n  @mock.patch('google.cloud.monitoring_v3.MetricServiceClient.list_monitored_resource_descriptors')\n  def test_list_caching(self, mock_gcloud_list_descriptors):\n    mock_gcloud_list_descriptors.return_value = (\n        self._list_resources_get_result())\n\n    actual_list1 = self.descriptors.list()\n    actual_list2 = self.descriptors.list()\n\n    mock_gcloud_list_descriptors.assert_called_once_with(\n        DEFAULT_PROJECT, filter_=None)\n    self.assertEqual(actual_list1, actual_list2)\n\n  @mock.patch('google.cloud.monitoring_v3.MetricServiceClient.list_monitored_resource_descriptors')\n  def test_as_dataframe(self, mock_datalab_list_descriptors):\n    mock_datalab_list_descriptors.return_value = (\n        self._list_resources_get_result())\n    dataframe = self.descriptors.as_dataframe()\n    mock_datalab_list_descriptors.assert_called_once_with(\n        DEFAULT_PROJECT, filter_=None)\n\n    expected_headers = list(gcm.ResourceDescriptors._DISPLAY_HEADERS)\n    self.assertEqual(dataframe.columns.tolist(), expected_headers)\n    self.assertEqual(dataframe.columns.names, [None])\n\n    self.assertEqual(dataframe.index.tolist(), list(range(len(RESOURCE_TYPES))))\n    self.assertEqual(dataframe.index.names, [None])\n\n    expected_labels = 'instance_id, project_id'\n    expected_values = [\n        [resource_type, display_name, expected_labels]\n        for resource_type, display_name in zip(RESOURCE_TYPES, DISPLAY_NAMES)]\n    self.assertEqual(dataframe.values.tolist(), expected_values)\n\n  @mock.patch('google.cloud.monitoring_v3.MetricServiceClient.list_monitored_resource_descriptors')\n  def test_as_dataframe_w_all_args(self, mock_datalab_list_descriptors):\n    mock_datalab_list_descriptors.return_value = (\n        self._list_resources_get_result())\n    dataframe = self.descriptors.as_dataframe(pattern='*instance*', max_rows=1)\n    mock_datalab_list_descriptors.assert_called_once_with(\n        DEFAULT_PROJECT, filter_=None)\n\n    expected_headers = list(gcm.ResourceDescriptors._DISPLAY_HEADERS)\n    self.assertEqual(dataframe.columns.tolist(), expected_headers)\n    self.assertEqual(dataframe.index.tolist(), [0])\n    self.assertEqual(dataframe.iloc[0, 0], RESOURCE_TYPES[0])\n\n  @staticmethod\n  def _create_context(project_id):\n    creds = mock.Mock(spec=google.auth.credentials.Credentials)\n    return google.datalab.Context(project_id, creds)\n\n  @staticmethod\n  def _list_resources_get_result():\n    all_labels = [google.cloud.monitoring_v3.types.LabelDescriptor(**labels)\n                  for labels in LABELS]\n    descriptors = [\n        google.cloud.monitoring_v3.types.MonitoredResourceDescriptor(\n            name=None, type=resource_type, display_name=display_name,\n            description=None, labels=all_labels,\n        )\n        for resource_type, display_name in zip(RESOURCE_TYPES, DISPLAY_NAMES)]\n    return descriptors\n"
  },
  {
    "path": "legacy_tests/stackdriver/monitoring/utils_tests.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nimport mock\nimport unittest\n\nimport google.auth\nimport google.datalab\nimport google.datalab.stackdriver.monitoring as gcm\n\n\nclass TestCases(unittest.TestCase):\n\n  def test_make_client(self):\n    context = self._create_context()\n    client = gcm._utils.make_client(context)\n\n    self.assertEqual(client.project, context.project_id)\n\n  @mock.patch('google.datalab.Context.default')\n  def test_make_client_w_defaults(self, mock_context_default):\n    default_context = self._create_context()\n    mock_context_default.return_value = default_context\n    client = gcm._utils.make_client()\n\n    self.assertEqual(client.project, default_context.project_id)\n\n  @staticmethod\n  def _create_context():\n    creds = mock.Mock(spec=google.auth.credentials.Credentials)\n    return google.datalab.Context('test_project', creds)\n"
  },
  {
    "path": "legacy_tests/storage/__init__.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n"
  },
  {
    "path": "legacy_tests/storage/api_tests.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nimport unittest\nimport mock\n\nimport google.auth\nimport datalab.context\nfrom datalab.storage._api import Api\n\n\nclass TestCases(unittest.TestCase):\n\n  def validate(self, mock_http_request, expected_url, expected_args=None, expected_data=None,\n               expected_headers=None, expected_method=None):\n    url = mock_http_request.call_args[0][0]\n    kwargs = mock_http_request.call_args[1]\n    self.assertEquals(expected_url, url)\n    if expected_args is not None:\n      self.assertEquals(expected_args, kwargs['args'])\n    if expected_data is not None:\n      self.assertEquals(expected_data, kwargs['data'])\n    if expected_headers is not None:\n      self.assertEquals(expected_headers, kwargs['headers'])\n    if expected_method is not None:\n      self.assertEquals(expected_method, kwargs['method'])\n\n  @mock.patch('datalab.utils.Http.request')\n  def test_buckets_insert(self, mock_http_request):\n    api = TestCases._create_api()\n\n    api.buckets_insert('foo')\n    self.validate(mock_http_request, 'https://www.googleapis.com/storage/v1/b/',\n                  expected_args={'project': 'test'}, expected_data={'name': 'foo'})\n\n    api.buckets_insert('foo', 'bar')\n    self.validate(mock_http_request, 'https://www.googleapis.com/storage/v1/b/',\n                  expected_args={'project': 'bar'}, expected_data={'name': 'foo'})\n\n  @mock.patch('datalab.utils.Http.request')\n  def test_buckets_delete(self, mock_http_request):\n    api = TestCases._create_api()\n    api.buckets_delete('foo')\n    self.validate(mock_http_request, 'https://www.googleapis.com/storage/v1/b/foo',\n                  expected_method='DELETE')\n\n  @mock.patch('datalab.utils.Http.request')\n  def test_buckets_get(self, mock_http_request):\n    api = TestCases._create_api()\n    api.buckets_get('foo')\n    self.validate(mock_http_request, 'https://www.googleapis.com/storage/v1/b/foo',\n                  expected_args={'projection': 'noAcl'})\n    api.buckets_get('foo', 'bar')\n    self.validate(mock_http_request, 'https://www.googleapis.com/storage/v1/b/foo',\n                  expected_args={'projection': 'bar'})\n\n  @mock.patch('datalab.utils.Http.request')\n  def test_buckets_list(self, mock_http_request):\n    api = TestCases._create_api()\n    api.buckets_list()\n    self.validate(mock_http_request, 'https://www.googleapis.com/storage/v1/b/',\n                  expected_args={'project': 'test', 'projection': 'noAcl', 'maxResults': 100})\n\n    api.buckets_list(projection='foo', max_results=99, page_token='xyz', project_id='bar')\n    self.validate(mock_http_request, 'https://www.googleapis.com/storage/v1/b/',\n                  expected_args={'project': 'bar', 'maxResults': 99,\n                                 'projection': 'foo', 'pageToken': 'xyz'})\n\n  @mock.patch('datalab.utils.Http.request')\n  def test_object_download(self, mock_http_request):\n    api = TestCases._create_api()\n    api.object_download('foo', 'bar')\n    self.validate(mock_http_request, 'https://www.googleapis.com/download/storage/v1/b/foo/o/bar',\n                  expected_args={'alt': 'media'})\n\n  @mock.patch('datalab.utils.Http.request')\n  def test_object_upload(self, mock_http_request):\n    api = TestCases._create_api()\n    api.object_upload('b', 'k', 'c', 't')\n    self.validate(mock_http_request, 'https://www.googleapis.com/upload/storage/v1/b/b/o/',\n                  expected_args={'uploadType': 'media', 'name': 'k'},\n                  expected_data='c', expected_headers={'Content-Type': 't'})\n\n  @mock.patch('datalab.utils.Http.request')\n  def test_objects_copy(self, mock_http_request):\n    api = TestCases._create_api()\n    api.objects_copy('sb', 'sk', 'tb', 'tk')\n    self.validate(mock_http_request,\n                  'https://www.googleapis.com/storage/v1/b/sb/o/sk/copyTo/b/tb/o/tk',\n                  expected_method='POST')\n\n  @mock.patch('datalab.utils.Http.request')\n  def test_objects_delete(self, mock_http_request):\n    api = TestCases._create_api()\n    api.objects_delete('b', 'k')\n    self.validate(mock_http_request, 'https://www.googleapis.com/storage/v1/b/b/o/k',\n                  expected_method='DELETE')\n\n  @mock.patch('datalab.utils.Http.request')\n  def test_objects_get(self, mock_http_request):\n    api = TestCases._create_api()\n    api.objects_get('b', 'k')\n    self.validate(mock_http_request, 'https://www.googleapis.com/storage/v1/b/b/o/k',\n                  expected_args={'projection': 'noAcl'})\n\n    api.objects_get('b', 'k', 'p')\n    self.validate(mock_http_request, 'https://www.googleapis.com/storage/v1/b/b/o/k',\n                  expected_args={'projection': 'p'})\n\n  @mock.patch('datalab.utils.Http.request')\n  def test_objects_list(self, mock_http_request):\n    api = TestCases._create_api()\n    api.objects_list('b')\n    self.validate(mock_http_request, 'https://www.googleapis.com/storage/v1/b/b/o/',\n                  expected_args={'projection': 'noAcl', 'maxResults': 100})\n\n    api.objects_list('b', 'p', 'd', 'pr', True, 99, 'foo')\n    self.validate(mock_http_request, 'https://www.googleapis.com/storage/v1/b/b/o/',\n                  expected_args={'projection': 'pr', 'maxResults': 99,\n                                 'prefix': 'p', 'delimiter': 'd', 'versions': 'true',\n                                 'pageToken': 'foo'})\n\n  @mock.patch('datalab.utils.Http.request')\n  def test_objects_patch(self, mock_http_request):\n    api = TestCases._create_api()\n    api.objects_patch('b', 'k', 'i')\n    self.validate(mock_http_request, 'https://www.googleapis.com/storage/v1/b/b/o/k',\n                  expected_method='PATCH', expected_data='i')\n\n  @staticmethod\n  def _create_api():\n    context = TestCases._create_context()\n    return Api(context)\n\n  @staticmethod\n  def _create_context():\n    project_id = 'test'\n    creds = mock.Mock(spec=google.auth.credentials.Credentials)\n    return datalab.context.Context(project_id, creds)\n"
  },
  {
    "path": "legacy_tests/storage/bucket_tests.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nimport mock\nimport unittest\n\nimport google.auth\nimport datalab.context\nimport datalab.storage\nimport datalab.utils\n\n\nclass TestCases(unittest.TestCase):\n\n  @mock.patch('datalab.storage._api.Api.buckets_get')\n  def test_bucket_existence(self, mock_api_buckets):\n    mock_api_buckets.return_value = TestCases._create_buckets_get_result()\n\n    buckets = datalab.storage.Buckets(context=TestCases._create_context())\n    self.assertTrue(buckets.contains('test_bucket'))\n\n    mock_api_buckets.side_effect = datalab.utils.RequestException(404, 'failed')\n    self.assertFalse(buckets.contains('test_bucket_2'))\n\n  @mock.patch('datalab.storage._api.Api.buckets_get')\n  def test_bucket_metadata(self, mock_api_buckets):\n    mock_api_buckets.return_value = TestCases._create_buckets_get_result()\n\n    b = TestCases._create_bucket()\n    m = b.metadata\n\n    self.assertEqual(m.name, 'test_bucket')\n\n  @staticmethod\n  def _create_bucket(name='test_bucket'):\n    return datalab.storage.Bucket(name, context=TestCases._create_context())\n\n  @staticmethod\n  def _create_context():\n    project_id = 'test'\n    creds = mock.Mock(spec=google.auth.credentials.Credentials)\n    return datalab.context.Context(project_id, creds)\n\n  @staticmethod\n  def _create_buckets_get_result():\n    return {'name': 'test_bucket'}\n"
  },
  {
    "path": "legacy_tests/storage/item_tests.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nimport mock\nimport unittest\n\nimport google.auth\nimport datalab.context\nimport datalab.storage\nimport datalab.utils\n\n\nclass TestCases(unittest.TestCase):\n\n  @mock.patch('datalab.storage._api.Api.objects_list')\n  @mock.patch('datalab.storage._api.Api.objects_get')\n  def test_item_existence(self, mock_api_objects_get, mock_api_objects_list):\n    mock_api_objects_list.return_value = TestCases._create_enumeration_single_result()\n    mock_api_objects_get.return_value = TestCases._create_objects_get_result()\n\n    b = TestCases._create_bucket()\n    self.assertTrue(b.items().contains('test_item1'))\n\n    mock_api_objects_get.side_effect = datalab.utils.RequestException(404, 'failed')\n    self.assertFalse('test_item2' in list(b.items()))\n\n  @mock.patch('datalab.storage._api.Api.objects_get')\n  def test_item_metadata(self, mock_api_objects):\n    mock_api_objects.return_value = TestCases._create_objects_get_result()\n\n    b = TestCases._create_bucket()\n    i = b.item('test_item1')\n    m = i.metadata\n\n    self.assertEqual(m.name, 'test_item1')\n    self.assertEqual(m.content_type, 'text/plain')\n\n  @mock.patch('datalab.storage._api.Api.objects_list')\n  def test_enumerate_items_empty(self, mock_api_objects):\n    mock_api_objects.return_value = TestCases._create_enumeration_empty_result()\n\n    b = self._create_bucket()\n    items = list(b.items())\n\n    self.assertEqual(len(items), 0)\n\n  @mock.patch('datalab.storage._api.Api.objects_list')\n  def test_enumerate_items_single(self, mock_api_objects):\n    mock_api_objects.return_value = TestCases._create_enumeration_single_result()\n\n    b = TestCases._create_bucket()\n    items = list(b.items())\n\n    self.assertEqual(len(items), 1)\n    self.assertEqual(items[0].key, 'test_item1')\n\n  @mock.patch('datalab.storage._api.Api.objects_list')\n  def test_enumerate_items_multi_page(self, mock_api_objects):\n    mock_api_objects.side_effect = [\n      TestCases._create_enumeration_multipage_result1(),\n      TestCases._create_enumeration_multipage_result2()\n    ]\n\n    b = TestCases._create_bucket()\n    items = list(b.items())\n\n    self.assertEqual(len(items), 2)\n    self.assertEqual(items[0].key, 'test_item1')\n    self.assertEqual(items[1].key, 'test_item2')\n\n  @staticmethod\n  def _create_bucket(name='test_bucket'):\n    return datalab.storage.Bucket(name, context=TestCases._create_context())\n\n  @staticmethod\n  def _create_context():\n    project_id = 'test'\n    creds = mock.Mock(spec=google.auth.credentials.Credentials)\n    return datalab.context.Context(project_id, creds)\n\n  @staticmethod\n  def _create_objects_get_result():\n    return {'name': 'test_item1', 'contentType': 'text/plain'}\n\n  @staticmethod\n  def _create_enumeration_empty_result():\n    return {}\n\n  @staticmethod\n  def _create_enumeration_single_result():\n    return {\n      'items': [\n        {'name': 'test_item1'}\n      ]\n    }\n\n  @staticmethod\n  def _create_enumeration_multipage_result1():\n    return {\n      'items': [\n        {'name': 'test_item1'}\n      ],\n      'nextPageToken': 'test_token'\n    }\n\n  @staticmethod\n  def _create_enumeration_multipage_result2():\n    return {\n      'items': [\n        {'name': 'test_item2'}\n      ]\n    }\n"
  },
  {
    "path": "release.sh",
    "content": "#!/bin/bash -e\n# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#  http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n# Compiles the typescript sources to javascript and submits the files\n# to the pypi server specified as first parameter, defaults to testpypi\n# In order to run this script locally, make sure you have the following:\n# - A Python 3 environment (due to urllib issues)\n# - Typescript installed\n# - A configured ~/.pypirc containing your pypi/testpypi credentials with\n#   the server names matching the name you're passing in. Do not include\n#   the repository URLs in the config file, this has been deprecated.\n# - Make sure the package version string in the setup.py file is updated.\n#   It will get rejected by the server if it already exists\n# - If this is a new release, make sure the release notes are updated\n#   and create a new release tag\n\ntsc --module amd --noImplicitAny datalab/notebook/static/*.ts\ntsc --module amd --noImplicitAny google/datalab/notebook/static/*.ts\n\n# This is the test url, you should change this to\n# https://upload.pypi.org/legacy/ for prod binaries\nserver=\"${1:-https://test.pypi.python.org/pypi}\"\necho \"Submitting package to ${server}\"\n\n# Build and upload a distribution package\nrm -rf dist/*\npython setup.py sdist\ntwine upload --repository-url \"${server}\" dist/*\n\n# Clean up\nrm -f datalab/notebook/static/*.js\nrm -f google/datalab/notebook/static/*.js\n"
  },
  {
    "path": "setup.cfg",
    "content": "[metadata]\ndescription-file = README.md\n\n[flake8]\nmax-line-length = 100\nexclude =\n    docs\nignore =\n    # Indentation is not a multiple of four\n    E111,\n    # Indentation is not a multiple of four (comment)\n    E114,\n    # Continuation line under-indented for hanging indent\n    E121\n"
  },
  {
    "path": "setup.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n# To publish to PyPi use: python setup.py bdist_wheel upload -r pypi\n\nfrom setuptools import setup\n\nversion = '1.2.1'\n\nsetup(\n  name='datalab',\n  version=version,\n  namespace_packages=['google', 'datalab'],\n  packages=[\n    'google.datalab',\n    'google.datalab.bigquery',\n    'google.datalab.bigquery.commands',\n    'google.datalab.commands',\n    'google.datalab.contrib',\n    'google.datalab.contrib.bigquery',\n    'google.datalab.contrib.bigquery.commands',\n    'google.datalab.contrib.bigquery.operators',\n    'google.datalab.contrib.mlworkbench',\n    'google.datalab.contrib.mlworkbench.commands',\n    'google.datalab.contrib.pipeline',\n    'google.datalab.contrib.pipeline.airflow',\n    'google.datalab.contrib.pipeline.composer',\n    'google.datalab.contrib.pipeline.commands',\n    'google.datalab.data',\n    'google.datalab.kernel',\n    'google.datalab.ml',\n    'google.datalab.notebook',\n    'google.datalab.stackdriver',\n    'google.datalab.stackdriver.commands',\n    'google.datalab.stackdriver.monitoring',\n    'google.datalab.storage',\n    'google.datalab.storage.commands',\n    'google.datalab.utils',\n    'google.datalab.utils.commands',\n    'google.datalab.utils.facets',\n    'datalab.bigquery',\n    'datalab.bigquery.commands',\n    'datalab.context',\n    'datalab.context.commands',\n    'datalab.data',\n    'datalab.data.commands',\n    'datalab.kernel',\n    'datalab.notebook',\n    'datalab.stackdriver',\n    'datalab.stackdriver.commands',\n    'datalab.stackdriver.monitoring',\n    'datalab.storage',\n    'datalab.storage.commands',\n    'datalab.utils',\n    'datalab.utils.commands'\n  ],\n  description='Google Cloud Datalab',\n  author='Google',\n  author_email='google-cloud-datalab-feedback@googlegroups.com',\n  url='https://github.com/googledatalab/pydatalab',\n  download_url='https://github.com/googledatalab/pydatalab/archive/v1.1.0.zip',\n  keywords=[\n    'Google',\n    'GCP',\n    'GCS',\n    'bigquery'\n  ],\n  license=\"Apache Software License\",\n  classifiers=[\n      \"Programming Language :: Python\",\n      \"Programming Language :: Python :: 2\",\n      \"Programming Language :: Python :: 3\",\n      \"Development Status :: 7 - Inactive\",\n      \"Environment :: Other Environment\",\n      \"Intended Audience :: Developers\",\n      \"License :: OSI Approved :: Apache Software License\",\n      \"Operating System :: OS Independent\",\n      \"Topic :: Software Development :: Libraries :: Python Modules\"\n  ],\n  long_description_content_type='text/markdown',\n  long_description=\"\"\"\\\nDatalab is deprecated. [Vertex AI Workbench](https://cloud.google.com/vertex-ai/docs/workbench)\nprovides a notebook-based environment that offers capabilities beyond Datalab.\nWe recommend that you use Vertex AI Workbench for new projects and\n[migrate your Datalab notebooks to Vertex AI Workbench](https://cloud.google.com/datalab/docs/resources/troubleshooting#migrate).\nFor more information, see\n[Deprecation information](https://cloud.google.com/datalab/docs/resources/deprecation).\nTo get help migrating Datalab projects to Vertex AI Workbench see\n[Get help](https://cloud.google.com/datalab/docs/resources/support#get-help).\n  \"\"\",\n  install_requires=[\n    'configparser>=3.5.0',\n    'mock>=2.0.0',\n    'future>=0.16.0',\n    'google-cloud-monitoring==0.31.1',\n    'google-api-core>=1.10.0',\n    'google-api-python-client>=1.6.2',\n    'seaborn>=0.7.0',\n    'plotly>=1.12.5',\n    'httplib2>=0.10.3',\n    'oauth2client>=2.2.0',\n    'pandas>=0.22.0',\n    'google_auth_httplib2>=0.0.2',\n    'pandas-profiling==1.4.0',\n    'python-dateutil>=2.5.0',\n    'pytz>=2015.4',\n    'pyyaml>=3.11',\n    'requests>=2.9.1',\n    'scikit-image>=0.13.0',\n    'scikit-learn>=0.18.2',\n    'ipykernel>=4.5.2',\n    'psutil>=4.3.0',\n    'jsonschema>=2.6.0',\n    'six>=1.10.0',\n    'urllib3>=1.22',\n  ],\n  extras_require={\n    ':python_version == \"2.7\"': [\n      'futures>=3.0.5',\n    ]\n  },\n  package_data={\n    'google.datalab.notebook': [\n        'static/bigquery.css',\n        'static/bigquery.js',\n        'static/charting.css',\n        'static/charting.js',\n        'static/job.css',\n        'static/job.js',\n        'static/element.js',\n        'static/style.js',\n        'static/visualization.js',\n        'static/codemirror/mode/bigquery.js',\n        'static/parcoords.js',\n        'static/extern/d3.parcoords.js',\n        'static/extern/d3.parcoords.css',\n        'static/extern/sylvester.js',\n        'static/extern/lantern-browser.html',\n        'static/extern/facets-jupyter.html',\n      ],\n    'datalab.notebook': [\n        'static/bigquery.css',\n        'static/bigquery.js',\n        'static/charting.css',\n        'static/charting.js',\n        'static/job.css',\n        'static/job.js',\n        'static/element.js',\n        'static/style.js',\n        'static/visualization.js',\n        'static/codemirror/mode/sql.js',\n        'static/parcoords.js',\n        'static/extern/d3.parcoords.js',\n        'static/extern/d3.parcoords.css',\n        'static/extern/sylvester.js',\n        'static/extern/lantern-browser.html',\n        'static/extern/facets-jupyter.html',\n      ]\n  }\n)\n"
  },
  {
    "path": "solutionbox/image_classification/mltoolbox/__init__.py",
    "content": "# Copyright 2017 Google Inc. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n# ==============================================================================\n\n__import__('pkg_resources').declare_namespace(__name__)\n"
  },
  {
    "path": "solutionbox/image_classification/mltoolbox/image/__init__.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n"
  },
  {
    "path": "solutionbox/image_classification/mltoolbox/image/classification/__init__.py",
    "content": "# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"\nSingle label image classification solution. Typical usage is:\n\nRun preprocess() or preprocess_async() to preprocess data for training.\nRun train() or train_async() to train models.\nRun predict(), batch_predict(), batch_predict_async() to perform predictions.\n\nThe trained model can also be deployed online with google.datalab.ml.ModelVersions.deploy() call.\n\"\"\"\n\nfrom ._api import preprocess, preprocess_async, train, train_async, predict, batch_predict, \\\n    batch_predict_async\n\n__all__ = ['preprocess', 'preprocess_async', 'train', 'train_async', 'predict', 'batch_predict',\n           'batch_predict_async']\n"
  },
  {
    "path": "solutionbox/image_classification/mltoolbox/image/classification/_api.py",
    "content": "# Copyright 2017 Google Inc. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\n\"\"\"Face functions for image classification.\n\"\"\"\n\nimport warnings\n\nfrom . import _local\nfrom . import _cloud\n\n\ndef preprocess_async(train_dataset, output_dir, eval_dataset=None, checkpoint=None, cloud=None):\n  \"\"\"Preprocess data. Produce output that can be used by training efficiently.\n\n  Args:\n    train_dataset: training data source to preprocess. Can be CsvDataset or BigQueryDataSet.\n        If eval_dataset is None, the pipeline will randomly split train_dataset into\n        train/eval set with 7:3 ratio.\n    output_dir: The output directory to use. Preprocessing will create a sub directory under\n        it for each run, and also update \"latest\" file which points to the latest preprocessed\n        directory. Users are responsible for cleanup. Can be local or GCS path.\n    eval_dataset: evaluation data source to preprocess. Can be CsvDataset or BigQueryDataSet.\n        If specified, it will be used for evaluation during training, and train_dataset will be\n        completely used for training.\n    checkpoint: the Inception checkpoint to use. If None, a default checkpoint is used.\n    cloud: a DataFlow pipeline option dictionary such as {'num_workers': 3}. If anything but\n        not None, it will run in cloud. Otherwise, it runs locally.\n\n  Returns:\n    A google.datalab.utils.Job object that can be used to query state from or wait.\n  \"\"\"\n  with warnings.catch_warnings():\n    warnings.simplefilter(\"ignore\")\n    if cloud is None:\n      return _local.Local.preprocess(train_dataset, output_dir, eval_dataset, checkpoint)\n\n    if not isinstance(cloud, dict):\n      cloud = {}\n    return _cloud.Cloud.preprocess(train_dataset, output_dir, eval_dataset, checkpoint, cloud)\n\n\ndef preprocess(train_dataset, output_dir, eval_dataset=None, checkpoint=None, cloud=None):\n  \"\"\"Blocking version of preprocess_async(). The only difference is that it blocks the caller\n     until the job finishes, and it does not have a return value.\n  \"\"\"\n  with warnings.catch_warnings():\n    warnings.simplefilter(\"ignore\")\n    job = preprocess_async(train_dataset, output_dir, eval_dataset, checkpoint, cloud)\n    job.wait()\n    print(job.state)\n\n\ndef train_async(input_dir, batch_size, max_steps, output_dir, checkpoint=None, cloud=None):\n  \"\"\"Train model. The output can be used for batch prediction or online deployment.\n\n  Args:\n    input_dir: A directory path containing preprocessed results. Can be local or GCS path.\n    batch_size: size of batch used for training.\n    max_steps: number of steps to train.\n    output_dir: The output directory to use. Can be local or GCS path.\n    checkpoint: the Inception checkpoint to use. If None, a default checkpoint is used.\n    cloud: a google.datalab.ml.CloudTrainingConfig object to let it run in cloud.\n        If None, it runs locally.\n\n  Returns:\n    A google.datalab.utils.Job object that can be used to query state from or wait.\n  \"\"\"\n  with warnings.catch_warnings():\n    warnings.simplefilter(\"ignore\")\n    if cloud is None:\n      return _local.Local.train(input_dir, batch_size, max_steps, output_dir, checkpoint)\n\n    return _cloud.Cloud.train(input_dir, batch_size, max_steps, output_dir, checkpoint, cloud)\n\n\ndef train(input_dir, batch_size, max_steps, output_dir, checkpoint=None, cloud=None):\n  \"\"\"Blocking version of train_async(). The only difference is that it blocks the caller\n     until the job finishes, and it does not have a return value.\n  \"\"\"\n  with warnings.catch_warnings():\n    warnings.simplefilter(\"ignore\")\n    job = train_async(input_dir, batch_size, max_steps, output_dir, checkpoint, cloud)\n    job.wait()\n    print(job.state)\n\n\ndef predict(model, image_files, resize=False, show_image=True, cloud=None):\n  \"\"\"Predict using an model in a local or GCS directory (offline), or a deployed model (online).\n\n  Args:\n    model: if cloud is None, a local or GCS directory of a trained model. Otherwise, it specifies\n        a deployed model identified by model.version, such as \"imagemodel.v1\".\n    image_files: The paths to the image files to predict labels. Can be local or GCS paths.\n    resize: Whether to resize the image to a reasonable size (300x300) before prediction.\n    show_image: Whether to show images in the results.\n    cloud: if None, predicts with offline model locally. Otherwise, predict with a deployed online\n        model.\n\n  Returns:\n    A pandas DataFrame including the prediction results.\n  \"\"\"\n\n  print('Predicting...')\n  with warnings.catch_warnings():\n    warnings.simplefilter(\"ignore\")\n    if cloud is None:\n      results = _local.Local.predict(model, image_files, resize, show_image)\n    else:\n      results = _cloud.Cloud.predict(model, image_files, resize, show_image)\n    return results\n\n\ndef batch_predict_async(dataset, model_dir, output_csv=None, output_bq_table=None, cloud=None):\n  \"\"\"Batch prediction with an offline model.\n\n  Args:\n    dataset: CsvDataSet or BigQueryDataSet for batch prediction input. Can contain either\n        one column 'image_url', or two columns with another being 'label'.\n    model_dir: The directory of a trained inception model. Can be local or GCS paths.\n    output_csv: The output csv file for prediction results. If specified,\n        it will also output a csv schema file with the name output_csv + '.schema.json'.\n    output_bq_table: if specified, the output BigQuery table for prediction results.\n        output_csv and output_bq_table can both be set.\n    cloud: a DataFlow pipeline option dictionary such as {'num_workers': 3}. If anything but\n        not None, it will run in cloud. Otherwise, it runs locally.\n        If specified, it must include 'temp_location' with value being a GCS path, because cloud\n        run requires a staging GCS directory.\n\n  Raises:\n    ValueError if both output_csv and output_bq_table are None, or if cloud is not None\n        but it does not include 'temp_location'.\n\n  Returns:\n    A google.datalab.utils.Job object that can be used to query state from or wait.\n  \"\"\"\n  with warnings.catch_warnings():\n    warnings.simplefilter(\"ignore\")\n    if cloud is None:\n      return _local.Local.batch_predict(dataset, model_dir, output_csv, output_bq_table)\n\n    if not isinstance(cloud, dict):\n      cloud = {}\n    return _cloud.Cloud.batch_predict(dataset, model_dir, output_csv, output_bq_table, cloud)\n\n\ndef batch_predict(dataset, model_dir, output_csv=None, output_bq_table=None, cloud=None):\n  \"\"\"Blocking version of batch_predict_async(). The only difference is that it blocks the caller\n     until the job finishes, and it does not have a return value.\n  \"\"\"\n  with warnings.catch_warnings():\n    warnings.simplefilter(\"ignore\")\n    job = batch_predict_async(dataset, model_dir, output_csv, output_bq_table, cloud)\n    job.wait()\n    print(job.state)\n"
  },
  {
    "path": "solutionbox/image_classification/mltoolbox/image/classification/_cloud.py",
    "content": "# Copyright 2017 Google Inc. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\n\"\"\"Cloud implementation for preprocessing, training and prediction for inception model.\n\"\"\"\n\n\nimport base64\nimport datetime\nimport logging\nimport os\nimport shutil\nimport tempfile\nfrom tensorflow.python.lib.io import file_io\nimport urllib\n\nfrom . import _util\n\n\n_TF_GS_URL = 'gs://cloud-datalab/deploy/tf/tensorflow-1.2.0-cp27-none-linux_x86_64.whl'\n_PROTOBUF_GS_URL = 'gs://cloud-datalab/deploy/tf/protobuf-3.1.0-py2.py3-none-any.whl'\n\n\nclass Cloud(object):\n  \"\"\"Class for cloud training, preprocessing and prediction.\"\"\"\n\n  @staticmethod\n  def preprocess(train_dataset, output_dir, eval_dataset, checkpoint, pipeline_option):\n    \"\"\"Preprocess data in Cloud with DataFlow.\"\"\"\n\n    import apache_beam as beam\n    import google.datalab.utils\n    from . import _preprocess\n\n    if checkpoint is None:\n      checkpoint = _util._DEFAULT_CHECKPOINT_GSURL\n\n    job_name = ('preprocess-image-classification-' +\n                datetime.datetime.now().strftime('%y%m%d-%H%M%S'))\n\n    staging_package_url = _util.repackage_to_staging(output_dir)\n    tmpdir = tempfile.mkdtemp()\n    # suppress DataFlow warnings about wheel package as extra package.\n    original_level = logging.getLogger().getEffectiveLevel()\n    logging.getLogger().setLevel(logging.ERROR)\n    try:\n      # Workaround for DataFlow 2.0, which doesn't work well with extra packages in GCS.\n      # Remove when the issue is fixed and new version of DataFlow is included in Datalab.\n      extra_packages = [staging_package_url, _TF_GS_URL, _PROTOBUF_GS_URL]\n      local_packages = [os.path.join(tmpdir, os.path.basename(p))\n                        for p in extra_packages]\n      for source, dest in zip(extra_packages, local_packages):\n        file_io.copy(source, dest, overwrite=True)\n\n      options = {\n          'staging_location': os.path.join(output_dir, 'tmp', 'staging'),\n          'temp_location': os.path.join(output_dir, 'tmp'),\n          'job_name': job_name,\n          'project': _util.default_project(),\n          'extra_packages': local_packages,\n          'teardown_policy': 'TEARDOWN_ALWAYS',\n          'no_save_main_session': True\n      }\n      if pipeline_option is not None:\n        options.update(pipeline_option)\n\n      opts = beam.pipeline.PipelineOptions(flags=[], **options)\n      p = beam.Pipeline('DataflowRunner', options=opts)\n      _preprocess.configure_pipeline(p, train_dataset, eval_dataset,\n                                     checkpoint, output_dir, job_name)\n      job_results = p.run()\n    finally:\n      shutil.rmtree(tmpdir)\n      logging.getLogger().setLevel(original_level)\n\n    if (_util.is_in_IPython()):\n      import IPython\n      dataflow_url = 'https://console.developers.google.com/dataflow?project=%s' % \\\n                     _util.default_project()\n      html = 'Job \"%s\" submitted.' % job_name\n      html += '<p>Click <a href=\"%s\" target=\"_blank\">here</a> to track preprocessing job. <br/>' \\\n          % dataflow_url\n      IPython.display.display_html(html, raw=True)\n    return google.datalab.utils.DataflowJob(job_results)\n\n  @staticmethod\n  def train(input_dir, batch_size, max_steps, output_dir, checkpoint, cloud_train_config):\n    \"\"\"Train model in the cloud with CloudML trainer service.\"\"\"\n\n    import google.datalab.ml as ml\n    if checkpoint is None:\n      checkpoint = _util._DEFAULT_CHECKPOINT_GSURL\n    staging_package_url = _util.repackage_to_staging(output_dir)\n    job_args = {\n      'input_dir': input_dir,\n      'max_steps': max_steps,\n      'batch_size': batch_size,\n      'checkpoint': checkpoint\n    }\n    job_request = {\n      'package_uris': [staging_package_url, _TF_GS_URL, _PROTOBUF_GS_URL],\n      'python_module': 'mltoolbox.image.classification.task',\n      'job_dir': output_dir,\n      'args': job_args\n    }\n    job_request.update(dict(cloud_train_config._asdict()))\n    job_id = 'image_classification_train_' + datetime.datetime.now().strftime('%y%m%d_%H%M%S')\n    job = ml.Job.submit_training(job_request, job_id)\n    if (_util.is_in_IPython()):\n      import IPython\n      log_url_query_strings = {\n        'project': _util.default_project(),\n        'resource': 'ml.googleapis.com/job_id/' + job.info['jobId']\n      }\n      log_url = 'https://console.developers.google.com/logs/viewer?' + \\\n          urllib.urlencode(log_url_query_strings)\n      html = 'Job \"%s\" submitted.' % job.info['jobId']\n      html += '<p>Click <a href=\"%s\" target=\"_blank\">here</a> to view cloud log. <br/>' % log_url\n      IPython.display.display_html(html, raw=True)\n    return job\n\n  @staticmethod\n  def predict(model_id, image_files, resize, show_image):\n    \"\"\"Predict using a deployed (online) model.\"\"\"\n\n    import google.datalab.ml as ml\n\n    images = _util.load_images(image_files, resize=resize)\n\n    parts = model_id.split('.')\n    if len(parts) != 2:\n      raise ValueError('Invalid model name for cloud prediction. Use \"model.version\".')\n    if len(images) == 0:\n      raise ValueError('images is empty.')\n\n    data = []\n    for ii, image in enumerate(images):\n      image_encoded = base64.b64encode(image)\n      data.append({\n        'key': str(ii),\n        'image_bytes': {'b64': image_encoded}\n      })\n\n    predictions = ml.ModelVersions(parts[0]).predict(parts[1], data)\n    if len(predictions) == 0:\n      raise Exception('Prediction results are empty.')\n    # Although prediction results contains a labels list in each instance, they are all the same\n    # so taking the first one.\n    labels = predictions[0]['labels']\n    labels_and_scores = [(x['prediction'], x['scores'][labels.index(x['prediction'])])\n                         for x in predictions]\n    results = zip(image_files, images, labels_and_scores)\n    ret = _util.process_prediction_results(results, show_image)\n    return ret\n\n  @staticmethod\n  def batch_predict(dataset, model_dir, output_csv, output_bq_table, pipeline_option):\n    \"\"\"Batch predict running in cloud.\"\"\"\n\n    import apache_beam as beam\n    import google.datalab.utils\n    from . import _predictor\n\n    if output_csv is None and output_bq_table is None:\n      raise ValueError('output_csv and output_bq_table cannot both be None.')\n    if 'temp_location' not in pipeline_option:\n      raise ValueError('\"temp_location\" is not set in cloud.')\n\n    job_name = ('batch-predict-image-classification-' +\n                datetime.datetime.now().strftime('%y%m%d-%H%M%S'))\n    staging_package_url = _util.repackage_to_staging(pipeline_option['temp_location'])\n    tmpdir = tempfile.mkdtemp()\n    # suppress DataFlow warnings about wheel package as extra package.\n    original_level = logging.getLogger().getEffectiveLevel()\n    logging.getLogger().setLevel(logging.ERROR)\n    try:\n      # Workaround for DataFlow 2.0, which doesn't work well with extra packages in GCS.\n      # Remove when the issue is fixed and new version of DataFlow is included in Datalab.\n      extra_packages = [staging_package_url, _TF_GS_URL, _PROTOBUF_GS_URL]\n      local_packages = [os.path.join(tmpdir, os.path.basename(p))\n                        for p in extra_packages]\n      for source, dest in zip(extra_packages, local_packages):\n        file_io.copy(source, dest, overwrite=True)\n\n      options = {\n          'staging_location': os.path.join(pipeline_option['temp_location'], 'staging'),\n          'job_name': job_name,\n          'project': _util.default_project(),\n          'extra_packages': local_packages,\n          'teardown_policy': 'TEARDOWN_ALWAYS',\n          'no_save_main_session': True\n      }\n      options.update(pipeline_option)\n\n      opts = beam.pipeline.PipelineOptions(flags=[], **options)\n      p = beam.Pipeline('DataflowRunner', options=opts)\n      _predictor.configure_pipeline(p, dataset, model_dir, output_csv, output_bq_table)\n      job_results = p.run()\n    finally:\n      shutil.rmtree(tmpdir)\n      logging.getLogger().setLevel(original_level)\n\n    if (_util.is_in_IPython()):\n      import IPython\n      dataflow_url = ('https://console.developers.google.com/dataflow?project=%s' %\n                      _util.default_project())\n      html = 'Job \"%s\" submitted.' % job_name\n      html += ('<p>Click <a href=\"%s\" target=\"_blank\">here</a> to track batch prediction job. <br/>'\n               % dataflow_url)\n      IPython.display.display_html(html, raw=True)\n    return google.datalab.utils.DataflowJob(job_results)\n"
  },
  {
    "path": "solutionbox/image_classification/mltoolbox/image/classification/_inceptionlib.py",
    "content": "# Copyright 2017 Google Inc. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\n\"\"\"Inception model building libraries.\n\"\"\"\n\nfrom __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport tensorflow as tf\n\nslim = tf.contrib.slim\n\n\ndef trunc_normal(stddev):\n    return tf.truncated_normal_initializer(0.0, stddev)\n\n\ndef inception_v3_base(inputs,\n                      final_endpoint='Mixed_7c',\n                      min_depth=16,\n                      depth_multiplier=1.0,\n                      scope=None):\n  \"\"\"Inception model from http://arxiv.org/abs/1512.00567.\n\n  Constructs an Inception v3 network from inputs to the given final endpoint.\n  This method can construct the network up to the final inception block\n  Mixed_7c.\n\n  Note that the names of the layers in the paper do not correspond to the names\n  of the endpoints registered by this function although they build the same\n  network.\n\n  Here is a mapping from the old_names to the new names:\n  Old name          | New name\n  =======================================\n  conv0             | Conv2d_1a_3x3\n  conv1             | Conv2d_2a_3x3\n  conv2             | Conv2d_2b_3x3\n  pool1             | MaxPool_3a_3x3\n  conv3             | Conv2d_3b_1x1\n  conv4             | Conv2d_4a_3x3\n  pool2             | MaxPool_5a_3x3\n  mixed_35x35x256a  | Mixed_5b\n  mixed_35x35x288a  | Mixed_5c\n  mixed_35x35x288b  | Mixed_5d\n  mixed_17x17x768a  | Mixed_6a\n  mixed_17x17x768b  | Mixed_6b\n  mixed_17x17x768c  | Mixed_6c\n  mixed_17x17x768d  | Mixed_6d\n  mixed_17x17x768e  | Mixed_6e\n  mixed_8x8x1280a   | Mixed_7a\n  mixed_8x8x2048a   | Mixed_7b\n  mixed_8x8x2048b   | Mixed_7c\n\n  Args:\n    inputs: a tensor of size [batch_size, height, width, channels].\n    final_endpoint: specifies the endpoint to construct the network up to. It\n      can be one of ['Conv2d_1a_3x3', 'Conv2d_2a_3x3', 'Conv2d_2b_3x3',\n      'MaxPool_3a_3x3', 'Conv2d_3b_1x1', 'Conv2d_4a_3x3', 'MaxPool_5a_3x3',\n      'Mixed_5b', 'Mixed_5c', 'Mixed_5d', 'Mixed_6a', 'Mixed_6b', 'Mixed_6c',\n      'Mixed_6d', 'Mixed_6e', 'Mixed_7a', 'Mixed_7b', 'Mixed_7c'].\n    min_depth: Minimum depth value (number of channels) for all convolution ops.\n      Enforced when depth_multiplier < 1, and not an active constraint when\n      depth_multiplier >= 1.\n    depth_multiplier: Float multiplier for the depth (number of channels)\n      for all convolution ops. The value must be greater than zero. Typical\n      usage will be to set this value in (0, 1) to reduce the number of\n      parameters or computation cost of the model.\n    scope: Optional variable_scope.\n\n  Returns:\n    tensor_out: output tensor corresponding to the final_endpoint.\n    end_points: a set of activations for external use, for example summaries or\n                losses.\n\n  Raises:\n    ValueError: if final_endpoint is not set to one of the predefined values,\n                or depth_multiplier <= 0\n  \"\"\"\n  # end_points will collect relevant activations for external use, for example\n  # summaries or losses.\n  end_points = {}\n\n  if depth_multiplier <= 0:\n    raise ValueError('depth_multiplier is not greater than zero.')\n\n  def depth(d):\n      return max(int(d * depth_multiplier), min_depth)\n\n  with tf.variable_scope(scope, 'InceptionV3', [inputs]):\n    with slim.arg_scope([slim.conv2d, slim.max_pool2d, slim.avg_pool2d],\n                        stride=1, padding='VALID'):\n      # 299 x 299 x 3\n      end_point = 'Conv2d_1a_3x3'\n      net = slim.conv2d(inputs, depth(32), [3, 3], stride=2, scope=end_point)\n      end_points[end_point] = net\n      if end_point == final_endpoint:\n          return net, end_points\n      # 149 x 149 x 32\n      end_point = 'Conv2d_2a_3x3'\n      net = slim.conv2d(net, depth(32), [3, 3], scope=end_point)\n      end_points[end_point] = net\n      if end_point == final_endpoint:\n          return net, end_points\n      # 147 x 147 x 32\n      end_point = 'Conv2d_2b_3x3'\n      net = slim.conv2d(net, depth(64), [3, 3], padding='SAME', scope=end_point)\n      end_points[end_point] = net\n      if end_point == final_endpoint:\n          return net, end_points\n      # 147 x 147 x 64\n      end_point = 'MaxPool_3a_3x3'\n      net = slim.max_pool2d(net, [3, 3], stride=2, scope=end_point)\n      end_points[end_point] = net\n      if end_point == final_endpoint:\n          return net, end_points\n      # 73 x 73 x 64\n      end_point = 'Conv2d_3b_1x1'\n      net = slim.conv2d(net, depth(80), [1, 1], scope=end_point)\n      end_points[end_point] = net\n      if end_point == final_endpoint:\n          return net, end_points\n      # 73 x 73 x 80.\n      end_point = 'Conv2d_4a_3x3'\n      net = slim.conv2d(net, depth(192), [3, 3], scope=end_point)\n      end_points[end_point] = net\n      if end_point == final_endpoint:\n          return net, end_points\n      # 71 x 71 x 192.\n      end_point = 'MaxPool_5a_3x3'\n      net = slim.max_pool2d(net, [3, 3], stride=2, scope=end_point)\n      end_points[end_point] = net\n      if end_point == final_endpoint:\n          return net, end_points\n      # 35 x 35 x 192.\n\n    # Inception blocks\n    with slim.arg_scope([slim.conv2d, slim.max_pool2d, slim.avg_pool2d],\n                        stride=1, padding='SAME'):\n      # mixed: 35 x 35 x 256.\n      end_point = 'Mixed_5b'\n      with tf.variable_scope(end_point):\n        with tf.variable_scope('Branch_0'):\n          branch_0 = slim.conv2d(net, depth(64), [1, 1], scope='Conv2d_0a_1x1')\n        with tf.variable_scope('Branch_1'):\n          branch_1 = slim.conv2d(net, depth(48), [1, 1], scope='Conv2d_0a_1x1')\n          branch_1 = slim.conv2d(branch_1, depth(64), [5, 5],\n                                 scope='Conv2d_0b_5x5')\n        with tf.variable_scope('Branch_2'):\n          branch_2 = slim.conv2d(net, depth(64), [1, 1], scope='Conv2d_0a_1x1')\n          branch_2 = slim.conv2d(branch_2, depth(96), [3, 3],\n                                 scope='Conv2d_0b_3x3')\n          branch_2 = slim.conv2d(branch_2, depth(96), [3, 3],\n                                 scope='Conv2d_0c_3x3')\n        with tf.variable_scope('Branch_3'):\n          branch_3 = slim.avg_pool2d(net, [3, 3], scope='AvgPool_0a_3x3')\n          branch_3 = slim.conv2d(branch_3, depth(32), [1, 1],\n                                 scope='Conv2d_0b_1x1')\n        net = tf.concat([branch_0, branch_1, branch_2, branch_3], 3)\n      end_points[end_point] = net\n      if end_point == final_endpoint:\n          return net, end_points\n\n      # mixed_1: 35 x 35 x 288.\n      end_point = 'Mixed_5c'\n      with tf.variable_scope(end_point):\n        with tf.variable_scope('Branch_0'):\n          branch_0 = slim.conv2d(net, depth(64), [1, 1], scope='Conv2d_0a_1x1')\n        with tf.variable_scope('Branch_1'):\n          branch_1 = slim.conv2d(net, depth(48), [1, 1], scope='Conv2d_0b_1x1')\n          branch_1 = slim.conv2d(branch_1, depth(64), [5, 5],\n                                 scope='Conv_1_0c_5x5')\n        with tf.variable_scope('Branch_2'):\n          branch_2 = slim.conv2d(net, depth(64), [1, 1],\n                                 scope='Conv2d_0a_1x1')\n          branch_2 = slim.conv2d(branch_2, depth(96), [3, 3],\n                                 scope='Conv2d_0b_3x3')\n          branch_2 = slim.conv2d(branch_2, depth(96), [3, 3],\n                                 scope='Conv2d_0c_3x3')\n        with tf.variable_scope('Branch_3'):\n          branch_3 = slim.avg_pool2d(net, [3, 3], scope='AvgPool_0a_3x3')\n          branch_3 = slim.conv2d(branch_3, depth(64), [1, 1],\n                                 scope='Conv2d_0b_1x1')\n        net = tf.concat([branch_0, branch_1, branch_2, branch_3], 3)\n      end_points[end_point] = net\n      if end_point == final_endpoint:\n          return net, end_points\n\n      # mixed_2: 35 x 35 x 288.\n      end_point = 'Mixed_5d'\n      with tf.variable_scope(end_point):\n        with tf.variable_scope('Branch_0'):\n          branch_0 = slim.conv2d(net, depth(64), [1, 1], scope='Conv2d_0a_1x1')\n        with tf.variable_scope('Branch_1'):\n          branch_1 = slim.conv2d(net, depth(48), [1, 1], scope='Conv2d_0a_1x1')\n          branch_1 = slim.conv2d(branch_1, depth(64), [5, 5],\n                                 scope='Conv2d_0b_5x5')\n        with tf.variable_scope('Branch_2'):\n          branch_2 = slim.conv2d(net, depth(64), [1, 1], scope='Conv2d_0a_1x1')\n          branch_2 = slim.conv2d(branch_2, depth(96), [3, 3],\n                                 scope='Conv2d_0b_3x3')\n          branch_2 = slim.conv2d(branch_2, depth(96), [3, 3],\n                                 scope='Conv2d_0c_3x3')\n        with tf.variable_scope('Branch_3'):\n          branch_3 = slim.avg_pool2d(net, [3, 3], scope='AvgPool_0a_3x3')\n          branch_3 = slim.conv2d(branch_3, depth(64), [1, 1],\n                                 scope='Conv2d_0b_1x1')\n        net = tf.concat([branch_0, branch_1, branch_2, branch_3], 3)\n      end_points[end_point] = net\n      if end_point == final_endpoint:\n          return net, end_points\n\n      # mixed_3: 17 x 17 x 768.\n      end_point = 'Mixed_6a'\n      with tf.variable_scope(end_point):\n        with tf.variable_scope('Branch_0'):\n          branch_0 = slim.conv2d(net, depth(384), [3, 3], stride=2,\n                                 padding='VALID', scope='Conv2d_1a_1x1')\n        with tf.variable_scope('Branch_1'):\n          branch_1 = slim.conv2d(net, depth(64), [1, 1], scope='Conv2d_0a_1x1')\n          branch_1 = slim.conv2d(branch_1, depth(96), [3, 3],\n                                 scope='Conv2d_0b_3x3')\n          branch_1 = slim.conv2d(branch_1, depth(96), [3, 3], stride=2,\n                                 padding='VALID', scope='Conv2d_1a_1x1')\n        with tf.variable_scope('Branch_2'):\n          branch_2 = slim.max_pool2d(net, [3, 3], stride=2, padding='VALID',\n                                     scope='MaxPool_1a_3x3')\n        net = tf.concat([branch_0, branch_1, branch_2], 3)\n      end_points[end_point] = net\n      if end_point == final_endpoint:\n          return net, end_points\n\n      # mixed4: 17 x 17 x 768.\n      end_point = 'Mixed_6b'\n      with tf.variable_scope(end_point):\n        with tf.variable_scope('Branch_0'):\n          branch_0 = slim.conv2d(net, depth(192), [1, 1], scope='Conv2d_0a_1x1')\n        with tf.variable_scope('Branch_1'):\n          branch_1 = slim.conv2d(net, depth(128), [1, 1], scope='Conv2d_0a_1x1')\n          branch_1 = slim.conv2d(branch_1, depth(128), [1, 7],\n                                 scope='Conv2d_0b_1x7')\n          branch_1 = slim.conv2d(branch_1, depth(192), [7, 1],\n                                 scope='Conv2d_0c_7x1')\n        with tf.variable_scope('Branch_2'):\n          branch_2 = slim.conv2d(net, depth(128), [1, 1], scope='Conv2d_0a_1x1')\n          branch_2 = slim.conv2d(branch_2, depth(128), [7, 1],\n                                 scope='Conv2d_0b_7x1')\n          branch_2 = slim.conv2d(branch_2, depth(128), [1, 7],\n                                 scope='Conv2d_0c_1x7')\n          branch_2 = slim.conv2d(branch_2, depth(128), [7, 1],\n                                 scope='Conv2d_0d_7x1')\n          branch_2 = slim.conv2d(branch_2, depth(192), [1, 7],\n                                 scope='Conv2d_0e_1x7')\n        with tf.variable_scope('Branch_3'):\n          branch_3 = slim.avg_pool2d(net, [3, 3], scope='AvgPool_0a_3x3')\n          branch_3 = slim.conv2d(branch_3, depth(192), [1, 1],\n                                 scope='Conv2d_0b_1x1')\n        net = tf.concat([branch_0, branch_1, branch_2, branch_3], 3)\n      end_points[end_point] = net\n      if end_point == final_endpoint:\n          return net, end_points\n\n      # mixed_5: 17 x 17 x 768.\n      end_point = 'Mixed_6c'\n      with tf.variable_scope(end_point):\n        with tf.variable_scope('Branch_0'):\n          branch_0 = slim.conv2d(net, depth(192), [1, 1], scope='Conv2d_0a_1x1')\n        with tf.variable_scope('Branch_1'):\n          branch_1 = slim.conv2d(net, depth(160), [1, 1], scope='Conv2d_0a_1x1')\n          branch_1 = slim.conv2d(branch_1, depth(160), [1, 7],\n                                 scope='Conv2d_0b_1x7')\n          branch_1 = slim.conv2d(branch_1, depth(192), [7, 1],\n                                 scope='Conv2d_0c_7x1')\n        with tf.variable_scope('Branch_2'):\n          branch_2 = slim.conv2d(net, depth(160), [1, 1], scope='Conv2d_0a_1x1')\n          branch_2 = slim.conv2d(branch_2, depth(160), [7, 1],\n                                 scope='Conv2d_0b_7x1')\n          branch_2 = slim.conv2d(branch_2, depth(160), [1, 7],\n                                 scope='Conv2d_0c_1x7')\n          branch_2 = slim.conv2d(branch_2, depth(160), [7, 1],\n                                 scope='Conv2d_0d_7x1')\n          branch_2 = slim.conv2d(branch_2, depth(192), [1, 7],\n                                 scope='Conv2d_0e_1x7')\n        with tf.variable_scope('Branch_3'):\n          branch_3 = slim.avg_pool2d(net, [3, 3], scope='AvgPool_0a_3x3')\n          branch_3 = slim.conv2d(branch_3, depth(192), [1, 1],\n                                 scope='Conv2d_0b_1x1')\n        net = tf.concat([branch_0, branch_1, branch_2, branch_3], 3)\n      end_points[end_point] = net\n      if end_point == final_endpoint:\n          return net, end_points\n      # mixed_6: 17 x 17 x 768.\n      end_point = 'Mixed_6d'\n      with tf.variable_scope(end_point):\n        with tf.variable_scope('Branch_0'):\n          branch_0 = slim.conv2d(net, depth(192), [1, 1], scope='Conv2d_0a_1x1')\n        with tf.variable_scope('Branch_1'):\n          branch_1 = slim.conv2d(net, depth(160), [1, 1], scope='Conv2d_0a_1x1')\n          branch_1 = slim.conv2d(branch_1, depth(160), [1, 7],\n                                 scope='Conv2d_0b_1x7')\n          branch_1 = slim.conv2d(branch_1, depth(192), [7, 1],\n                                 scope='Conv2d_0c_7x1')\n        with tf.variable_scope('Branch_2'):\n          branch_2 = slim.conv2d(net, depth(160), [1, 1], scope='Conv2d_0a_1x1')\n          branch_2 = slim.conv2d(branch_2, depth(160), [7, 1],\n                                 scope='Conv2d_0b_7x1')\n          branch_2 = slim.conv2d(branch_2, depth(160), [1, 7],\n                                 scope='Conv2d_0c_1x7')\n          branch_2 = slim.conv2d(branch_2, depth(160), [7, 1],\n                                 scope='Conv2d_0d_7x1')\n          branch_2 = slim.conv2d(branch_2, depth(192), [1, 7],\n                                 scope='Conv2d_0e_1x7')\n        with tf.variable_scope('Branch_3'):\n          branch_3 = slim.avg_pool2d(net, [3, 3], scope='AvgPool_0a_3x3')\n          branch_3 = slim.conv2d(branch_3, depth(192), [1, 1],\n                                 scope='Conv2d_0b_1x1')\n        net = tf.concat([branch_0, branch_1, branch_2, branch_3], 3)\n      end_points[end_point] = net\n      if end_point == final_endpoint:\n          return net, end_points\n\n      # mixed_7: 17 x 17 x 768.\n      end_point = 'Mixed_6e'\n      with tf.variable_scope(end_point):\n        with tf.variable_scope('Branch_0'):\n          branch_0 = slim.conv2d(net, depth(192), [1, 1], scope='Conv2d_0a_1x1')\n        with tf.variable_scope('Branch_1'):\n          branch_1 = slim.conv2d(net, depth(192), [1, 1], scope='Conv2d_0a_1x1')\n          branch_1 = slim.conv2d(branch_1, depth(192), [1, 7],\n                                 scope='Conv2d_0b_1x7')\n          branch_1 = slim.conv2d(branch_1, depth(192), [7, 1],\n                                 scope='Conv2d_0c_7x1')\n        with tf.variable_scope('Branch_2'):\n          branch_2 = slim.conv2d(net, depth(192), [1, 1], scope='Conv2d_0a_1x1')\n          branch_2 = slim.conv2d(branch_2, depth(192), [7, 1],\n                                 scope='Conv2d_0b_7x1')\n          branch_2 = slim.conv2d(branch_2, depth(192), [1, 7],\n                                 scope='Conv2d_0c_1x7')\n          branch_2 = slim.conv2d(branch_2, depth(192), [7, 1],\n                                 scope='Conv2d_0d_7x1')\n          branch_2 = slim.conv2d(branch_2, depth(192), [1, 7],\n                                 scope='Conv2d_0e_1x7')\n        with tf.variable_scope('Branch_3'):\n          branch_3 = slim.avg_pool2d(net, [3, 3], scope='AvgPool_0a_3x3')\n          branch_3 = slim.conv2d(branch_3, depth(192), [1, 1],\n                                 scope='Conv2d_0b_1x1')\n        net = tf.concat([branch_0, branch_1, branch_2, branch_3], 3)\n      end_points[end_point] = net\n      if end_point == final_endpoint:\n          return net, end_points\n\n      # mixed_8: 8 x 8 x 1280.\n      end_point = 'Mixed_7a'\n      with tf.variable_scope(end_point):\n        with tf.variable_scope('Branch_0'):\n          branch_0 = slim.conv2d(net, depth(192), [1, 1], scope='Conv2d_0a_1x1')\n          branch_0 = slim.conv2d(branch_0, depth(320), [3, 3], stride=2,\n                                 padding='VALID', scope='Conv2d_1a_3x3')\n        with tf.variable_scope('Branch_1'):\n          branch_1 = slim.conv2d(net, depth(192), [1, 1], scope='Conv2d_0a_1x1')\n          branch_1 = slim.conv2d(branch_1, depth(192), [1, 7],\n                                 scope='Conv2d_0b_1x7')\n          branch_1 = slim.conv2d(branch_1, depth(192), [7, 1],\n                                 scope='Conv2d_0c_7x1')\n          branch_1 = slim.conv2d(branch_1, depth(192), [3, 3], stride=2,\n                                 padding='VALID', scope='Conv2d_1a_3x3')\n        with tf.variable_scope('Branch_2'):\n          branch_2 = slim.max_pool2d(net, [3, 3], stride=2, padding='VALID',\n                                     scope='MaxPool_1a_3x3')\n        net = tf.concat([branch_0, branch_1, branch_2], 3)\n      end_points[end_point] = net\n      if end_point == final_endpoint:\n          return net, end_points\n      # mixed_9: 8 x 8 x 2048.\n      end_point = 'Mixed_7b'\n      with tf.variable_scope(end_point):\n        with tf.variable_scope('Branch_0'):\n          branch_0 = slim.conv2d(net, depth(320), [1, 1], scope='Conv2d_0a_1x1')\n        with tf.variable_scope('Branch_1'):\n          branch_1 = slim.conv2d(net, depth(384), [1, 1], scope='Conv2d_0a_1x1')\n          branch_1 = tf.concat([\n              slim.conv2d(branch_1, depth(384), [1, 3], scope='Conv2d_0b_1x3'),\n              slim.conv2d(branch_1, depth(384), [3, 1], scope='Conv2d_0b_3x1')], 3)\n        with tf.variable_scope('Branch_2'):\n          branch_2 = slim.conv2d(net, depth(448), [1, 1], scope='Conv2d_0a_1x1')\n          branch_2 = slim.conv2d(\n              branch_2, depth(384), [3, 3], scope='Conv2d_0b_3x3')\n          branch_2 = tf.concat([\n              slim.conv2d(branch_2, depth(384), [1, 3], scope='Conv2d_0c_1x3'),\n              slim.conv2d(branch_2, depth(384), [3, 1], scope='Conv2d_0d_3x1')], 3)\n        with tf.variable_scope('Branch_3'):\n          branch_3 = slim.avg_pool2d(net, [3, 3], scope='AvgPool_0a_3x3')\n          branch_3 = slim.conv2d(\n              branch_3, depth(192), [1, 1], scope='Conv2d_0b_1x1')\n        net = tf.concat([branch_0, branch_1, branch_2, branch_3], 3)\n      end_points[end_point] = net\n      if end_point == final_endpoint:\n          return net, end_points\n\n      # mixed_10: 8 x 8 x 2048.\n      end_point = 'Mixed_7c'\n      with tf.variable_scope(end_point):\n        with tf.variable_scope('Branch_0'):\n          branch_0 = slim.conv2d(net, depth(320), [1, 1], scope='Conv2d_0a_1x1')\n        with tf.variable_scope('Branch_1'):\n          branch_1 = slim.conv2d(net, depth(384), [1, 1], scope='Conv2d_0a_1x1')\n          branch_1 = tf.concat([\n              slim.conv2d(branch_1, depth(384), [1, 3], scope='Conv2d_0b_1x3'),\n              slim.conv2d(branch_1, depth(384), [3, 1], scope='Conv2d_0c_3x1')], 3)\n        with tf.variable_scope('Branch_2'):\n          branch_2 = slim.conv2d(net, depth(448), [1, 1], scope='Conv2d_0a_1x1')\n          branch_2 = slim.conv2d(\n              branch_2, depth(384), [3, 3], scope='Conv2d_0b_3x3')\n          branch_2 = tf.concat([\n              slim.conv2d(branch_2, depth(384), [1, 3], scope='Conv2d_0c_1x3'),\n              slim.conv2d(branch_2, depth(384), [3, 1], scope='Conv2d_0d_3x1')], 3)\n        with tf.variable_scope('Branch_3'):\n          branch_3 = slim.avg_pool2d(net, [3, 3], scope='AvgPool_0a_3x3')\n          branch_3 = slim.conv2d(\n              branch_3, depth(192), [1, 1], scope='Conv2d_0b_1x1')\n        net = tf.concat([branch_0, branch_1, branch_2, branch_3], 3)\n      end_points[end_point] = net\n      if end_point == final_endpoint:\n          return net, end_points\n    raise ValueError('Unknown final endpoint %s' % final_endpoint)\n\n\ndef inception_v3(inputs,\n                 num_classes=1000,\n                 is_training=True,\n                 dropout_keep_prob=0.8,\n                 min_depth=16,\n                 depth_multiplier=1.0,\n                 prediction_fn=slim.softmax,\n                 spatial_squeeze=True,\n                 reuse=None,\n                 scope='InceptionV3'):\n  \"\"\"Inception model from http://arxiv.org/abs/1512.00567.\n\n  \"Rethinking the Inception Architecture for Computer Vision\"\n\n  Christian Szegedy, Vincent Vanhoucke, Sergey Ioffe, Jonathon Shlens,\n  Zbigniew Wojna.\n\n  With the default arguments this method constructs the exact model defined in\n  the paper. However, one can experiment with variations of the inception_v3\n  network by changing arguments dropout_keep_prob, min_depth and\n  depth_multiplier.\n\n  The default image size used to train this network is 299x299.\n\n  Args:\n    inputs: a tensor of size [batch_size, height, width, channels].\n    num_classes: number of predicted classes.\n    is_training: whether is training or not.\n    dropout_keep_prob: the percentage of activation values that are retained.\n    min_depth: Minimum depth value (number of channels) for all convolution ops.\n      Enforced when depth_multiplier < 1, and not an active constraint when\n      depth_multiplier >= 1.\n    depth_multiplier: Float multiplier for the depth (number of channels)\n      for all convolution ops. The value must be greater than zero. Typical\n      usage will be to set this value in (0, 1) to reduce the number of\n      parameters or computation cost of the model.\n    prediction_fn: a function to get predictions out of logits.\n    spatial_squeeze: if True, logits is of shape is [B, C], if false logits is\n        of shape [B, 1, 1, C], where B is batch_size and C is number of classes.\n    reuse: whether or not the network and its variables should be reused. To be\n      able to reuse 'scope' must be given.\n    scope: Optional variable_scope.\n\n  Returns:\n    logits: the pre-softmax activations, a tensor of size\n      [batch_size, num_classes]\n    end_points: a dictionary from components of the network to the corresponding\n      activation.\n\n  Raises:\n    ValueError: if 'depth_multiplier' is less than or equal to zero.\n  \"\"\"\n  if depth_multiplier <= 0:\n    raise ValueError('depth_multiplier is not greater than zero.')\n\n  def depth(d):\n      return max(int(d * depth_multiplier), min_depth)\n\n  with tf.variable_scope(scope, 'InceptionV3', [inputs, num_classes],\n                         reuse=reuse) as scope:\n    with slim.arg_scope([slim.batch_norm, slim.dropout],\n                        is_training=is_training):\n      net, end_points = inception_v3_base(\n          inputs, scope=scope, min_depth=min_depth,\n          depth_multiplier=depth_multiplier)\n\n      # Auxiliary Head logits\n      with slim.arg_scope([slim.conv2d, slim.max_pool2d, slim.avg_pool2d],\n                          stride=1, padding='SAME'):\n        aux_logits = end_points['Mixed_6e']\n        with tf.variable_scope('AuxLogits'):\n          aux_logits = slim.avg_pool2d(\n              aux_logits, [5, 5], stride=3, padding='VALID',\n              scope='AvgPool_1a_5x5')\n          aux_logits = slim.conv2d(aux_logits, depth(128), [1, 1],\n                                   scope='Conv2d_1b_1x1')\n\n          # Shape of feature map before the final layer.\n          kernel_size = _reduced_kernel_size_for_small_input(\n              aux_logits, [5, 5])\n          aux_logits = slim.conv2d(\n              aux_logits, depth(768), kernel_size,\n              weights_initializer=trunc_normal(0.01),\n              padding='VALID', scope='Conv2d_2a_{}x{}'.format(*kernel_size))\n          aux_logits = slim.conv2d(\n              aux_logits, num_classes, [1, 1], activation_fn=None,\n              normalizer_fn=None, weights_initializer=trunc_normal(0.001),\n              scope='Conv2d_2b_1x1')\n          if spatial_squeeze:\n            aux_logits = tf.squeeze(aux_logits, [1, 2], name='SpatialSqueeze')\n          end_points['AuxLogits'] = aux_logits\n\n      # Final pooling and prediction\n      with tf.variable_scope('Logits'):\n        kernel_size = _reduced_kernel_size_for_small_input(net, [8, 8])\n        net = slim.avg_pool2d(net, kernel_size, padding='VALID',\n                              scope='AvgPool_1a_{}x{}'.format(*kernel_size))\n        # 1 x 1 x 2048\n        net = slim.dropout(net, keep_prob=dropout_keep_prob, scope='Dropout_1b')\n        end_points['PreLogits'] = net\n        # 2048\n        logits = slim.conv2d(net, num_classes, [1, 1], activation_fn=None,\n                             normalizer_fn=None, scope='Conv2d_1c_1x1')\n        if spatial_squeeze:\n          logits = tf.squeeze(logits, [1, 2], name='SpatialSqueeze')\n        # 1000\n      end_points['Logits'] = logits\n      end_points['Predictions'] = prediction_fn(logits, scope='Predictions')\n  return logits, end_points\n\n\ninception_v3.default_image_size = 299\n\n\ndef _reduced_kernel_size_for_small_input(input_tensor, kernel_size):\n  \"\"\"Define kernel size which is automatically reduced for small input.\n\n  If the shape of the input images is unknown at graph construction time this\n  function assumes that the input images are is large enough.\n\n  Args:\n    input_tensor: input tensor of size [batch_size, height, width, channels].\n    kernel_size: desired kernel size of length 2: [kernel_height, kernel_width]\n\n  Returns:\n    a tensor with the kernel size.\n\n  TODO(jrru): Make this function work with unknown shapes. Theoretically, this\n  can be done with the code below. Problems are two-fold: (1) If the shape was\n  known, it will be lost. (2) inception.slim.ops._two_element_tuple cannot\n  handle tensors that define the kernel size.\n      shape = tf.shape(input_tensor)\n      return = tf.stack([tf.minimum(shape[1], kernel_size[0]),\n                        tf.minimum(shape[2], kernel_size[1])])\n\n  \"\"\"\n  shape = input_tensor.get_shape().as_list()\n  if shape[1] is None or shape[2] is None:\n    kernel_size_out = kernel_size\n  else:\n    kernel_size_out = [min(shape[1], kernel_size[0]),\n                       min(shape[2], kernel_size[1])]\n  return kernel_size_out\n\n\ndef inception_v3_arg_scope(weight_decay=0.00004,\n                           stddev=0.1,\n                           batch_norm_var_collection='moving_vars'):\n  \"\"\"Defines the default InceptionV3 arg scope.\n\n  Args:\n    weight_decay: The weight decay to use for regularizing the model.\n    stddev: The standard deviation of the trunctated normal weight initializer.\n    batch_norm_var_collection: The name of the collection for the batch norm\n      variables.\n\n  Returns:\n    An `arg_scope` to use for the inception v3 model.\n  \"\"\"\n  batch_norm_params = {\n      # Decay for the moving averages.\n      'decay': 0.9997,\n      # epsilon to prevent 0s in variance.\n      'epsilon': 0.001,\n      # collection containing update_ops.\n      'updates_collections': tf.GraphKeys.UPDATE_OPS,\n      # collection containing the moving mean and moving variance.\n      'variables_collections': {\n          'beta': None,\n          'gamma': None,\n          'moving_mean': [batch_norm_var_collection],\n          'moving_variance': [batch_norm_var_collection],\n      }\n  }\n\n  # Set weight_decay for weights in Conv and FC layers.\n  with slim.arg_scope([slim.conv2d, slim.fully_connected],\n                      weights_regularizer=slim.l2_regularizer(weight_decay)):\n    with slim.arg_scope([slim.conv2d],\n                        weights_initializer=tf.truncated_normal_initializer(stddev=stddev),\n                        activation_fn=tf.nn.relu, normalizer_fn=slim.batch_norm,\n                        normalizer_params=batch_norm_params) as sc:\n      return sc\n"
  },
  {
    "path": "solutionbox/image_classification/mltoolbox/image/classification/_local.py",
    "content": "# Copyright 2017 Google Inc. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\n\"\"\"Local implementation for preprocessing, training and prediction for inception model.\n\"\"\"\n\n\nimport datetime\n\n\nfrom . import _model\nfrom . import _trainer\nfrom . import _util\n\n\nclass Local(object):\n  \"\"\"Class for local training, preprocessing and prediction.\"\"\"\n\n  @staticmethod\n  def preprocess(train_dataset, output_dir, eval_dataset, checkpoint):\n    \"\"\"Preprocess data locally.\"\"\"\n\n    import apache_beam as beam\n    from google.datalab.utils import LambdaJob\n    from . import _preprocess\n\n    if checkpoint is None:\n      checkpoint = _util._DEFAULT_CHECKPOINT_GSURL\n    job_id = ('preprocess-image-classification-' +\n              datetime.datetime.now().strftime('%y%m%d-%H%M%S'))\n    # Project is needed for bigquery data source, even in local run.\n    options = {\n        'project': _util.default_project(),\n    }\n    opts = beam.pipeline.PipelineOptions(flags=[], **options)\n    p = beam.Pipeline('DirectRunner', options=opts)\n    _preprocess.configure_pipeline(p, train_dataset, eval_dataset, checkpoint, output_dir, job_id)\n    job = LambdaJob(lambda: p.run().wait_until_finish(), job_id)\n    return job\n\n  @staticmethod\n  def train(input_dir, batch_size, max_steps, output_dir, checkpoint):\n    \"\"\"Train model locally.\"\"\"\n    from google.datalab.utils import LambdaJob\n\n    if checkpoint is None:\n      checkpoint = _util._DEFAULT_CHECKPOINT_GSURL\n\n    labels = _util.get_labels(input_dir)\n    model = _model.Model(labels, 0.5, checkpoint)\n    task_data = {'type': 'master', 'index': 0}\n    task = type('TaskSpec', (object,), task_data)\n    job = LambdaJob(lambda: _trainer.Trainer(input_dir, batch_size, max_steps, output_dir,\n                                             model, None, task).run_training(), 'training')\n    return job\n\n  @staticmethod\n  def predict(model_dir, image_files, resize, show_image):\n    \"\"\"Predict using an model in a local or GCS directory.\"\"\"\n\n    from . import _predictor\n\n    images = _util.load_images(image_files, resize=resize)\n    labels_and_scores = _predictor.predict(model_dir, images)\n    results = zip(image_files, images, labels_and_scores)\n    ret = _util.process_prediction_results(results, show_image)\n    return ret\n\n  @staticmethod\n  def batch_predict(dataset, model_dir, output_csv, output_bq_table):\n    \"\"\"Batch predict running locally.\"\"\"\n\n    import apache_beam as beam\n    from google.datalab.utils import LambdaJob\n    from . import _predictor\n\n    if output_csv is None and output_bq_table is None:\n      raise ValueError('output_csv and output_bq_table cannot both be None.')\n\n    job_id = ('batch-predict-image-classification-' +\n              datetime.datetime.now().strftime('%y%m%d-%H%M%S'))\n\n    # Project is needed for bigquery data source, even in local run.\n    options = {\n        'project': _util.default_project(),\n    }\n    opts = beam.pipeline.PipelineOptions(flags=[], **options)\n    p = beam.Pipeline('DirectRunner', options=opts)\n    _predictor.configure_pipeline(p, dataset, model_dir, output_csv, output_bq_table)\n    job = LambdaJob(lambda: p.run().wait_until_finish(), job_id)\n    return job\n"
  },
  {
    "path": "solutionbox/image_classification/mltoolbox/image/classification/_model.py",
    "content": "# Copyright 2017 Google Inc. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\n\"\"\"Inception model tensorflow implementation.\n\"\"\"\n\nfrom enum import Enum\nimport logging\nimport tensorflow as tf\nfrom tensorflow.contrib import layers\nfrom tensorflow.python.ops import control_flow_ops\nfrom tensorflow.python.ops import variables\nfrom tensorflow.python.saved_model import builder as saved_model_builder\nfrom tensorflow.python.saved_model import signature_def_utils\nfrom tensorflow.python.saved_model import tag_constants\n\nfrom . import _inceptionlib\nfrom . import _util\n\n\nslim = tf.contrib.slim\n\nLOGITS_TENSOR_NAME = 'logits_tensor'\nIMAGE_URI_COLUMN = 'image_uri'\nLABEL_COLUMN = 'label'\nEMBEDDING_COLUMN = 'embedding'\n\nBOTTLENECK_TENSOR_SIZE = 2048\n\n\nclass GraphMod(Enum):\n  TRAIN = 1\n  EVALUATE = 2\n  PREDICT = 3\n\n\nclass GraphReferences(object):\n  \"\"\"Holder of base tensors used for training model using common task.\"\"\"\n\n  def __init__(self):\n    self.examples = None\n    self.train = None\n    self.global_step = None\n    self.metric_updates = []\n    self.metric_values = []\n    self.keys = None\n    self.predictions = []\n\n\nclass Model(object):\n  \"\"\"TensorFlow model for the flowers problem.\"\"\"\n\n  def __init__(self, labels, dropout, inception_checkpoint_file):\n    self.labels = labels\n    self.labels.sort()\n    self.dropout = dropout\n    self.inception_checkpoint_file = inception_checkpoint_file\n\n  def add_final_training_ops(self,\n                             embeddings,\n                             all_labels_count,\n                             bottleneck_tensor_size,\n                             hidden_layer_size=BOTTLENECK_TENSOR_SIZE / 4,\n                             dropout_keep_prob=None):\n    \"\"\"Adds a new softmax and fully-connected layer for training.\n\n     The set up for the softmax and fully-connected layers is based on:\n     https://tensorflow.org/versions/master/tutorials/mnist/beginners/index.html\n\n     This function can be customized to add arbitrary layers for\n     application-specific requirements.\n    Args:\n      embeddings: The embedding (bottleneck) tensor.\n      all_labels_count: The number of all labels including the default label.\n      bottleneck_tensor_size: The number of embeddings.\n      hidden_layer_size: The size of the hidden_layer. Roughtly, 1/4 of the\n                         bottleneck tensor size.\n      dropout_keep_prob: the percentage of activation values that are retained.\n    Returns:\n      softmax: The softmax or tensor. It stores the final scores.\n      logits: The logits tensor.\n    \"\"\"\n    with tf.name_scope('input'):\n      bottleneck_input = tf.placeholder_with_default(\n          embeddings,\n          shape=[None, bottleneck_tensor_size],\n          name='ReshapeSqueezed')\n      bottleneck_with_no_gradient = tf.stop_gradient(bottleneck_input)\n\n      with tf.name_scope('Wx_plus_b'):\n        hidden = layers.fully_connected(bottleneck_with_no_gradient,\n                                        hidden_layer_size)\n        # We need a dropout when the size of the dataset is rather small.\n        if dropout_keep_prob:\n          hidden = tf.nn.dropout(hidden, dropout_keep_prob)\n        logits = layers.fully_connected(\n            hidden, all_labels_count, activation_fn=None)\n\n    softmax = tf.nn.softmax(logits, name='softmax')\n    return softmax, logits\n\n  def build_inception_graph(self):\n    \"\"\"Builds an inception graph and add the necessary input & output tensors.\n\n      To use other Inception models modify this file. Also preprocessing must be\n      modified accordingly.\n\n      See tensorflow/contrib/slim/python/slim/nets/inception_v3.py for\n      details about InceptionV3.\n\n    Returns:\n      input_jpeg: A placeholder for jpeg string batch that allows feeding the\n                  Inception layer with image bytes for prediction.\n      inception_embeddings: The embeddings tensor.\n    \"\"\"\n    image_str_tensor = tf.placeholder(tf.string, shape=[None])\n\n    # The CloudML Prediction API always \"feeds\" the Tensorflow graph with\n    # dynamic batch sizes e.g. (?,).  decode_jpeg only processes scalar\n    # strings because it cannot guarantee a batch of images would have\n    # the same output size.  We use tf.map_fn to give decode_jpeg a scalar\n    # string from dynamic batches.\n    image = tf.map_fn(\n        _util.decode_and_resize, image_str_tensor, back_prop=False, dtype=tf.uint8)\n    # convert_image_dtype, also scales [0, uint8_max] -> [0 ,1).\n    image = tf.image.convert_image_dtype(image, dtype=tf.float32)\n\n    # Then shift images to [-1, 1) for Inception.\n    image = tf.subtract(image, 0.5)\n    image = tf.multiply(image, 2.0)\n\n    # Build Inception layers, which expect A tensor of type float from [-1, 1)\n    # and shape [batch_size, height, width, channels].\n    with slim.arg_scope(_inceptionlib.inception_v3_arg_scope()):\n      _, end_points = _inceptionlib.inception_v3(image, is_training=False)\n\n    inception_embeddings = end_points['PreLogits']\n    inception_embeddings = tf.squeeze(\n        inception_embeddings, [1, 2], name='SpatialSqueeze')\n    return image_str_tensor, inception_embeddings\n\n  def build_graph(self, data_paths, batch_size, graph_mod):\n    \"\"\"Builds generic graph for training or eval.\"\"\"\n    tensors = GraphReferences()\n    is_training = graph_mod == GraphMod.TRAIN\n    if data_paths:\n      _, tensors.examples = _util.read_examples(\n          data_paths,\n          batch_size,\n          shuffle=is_training,\n          num_epochs=None if is_training else 2)\n    else:\n      tensors.examples = tf.placeholder(tf.string, name='input', shape=(None,))\n\n    if graph_mod == GraphMod.PREDICT:\n      inception_input, inception_embeddings = self.build_inception_graph()\n      # Build the Inception graph. We later add final training layers\n      # to this graph. This is currently used only for prediction.\n      # For training, we use pre-processed data, so it is not needed.\n      embeddings = inception_embeddings\n      tensors.input_jpeg = inception_input\n    else:\n      # For training and evaluation we assume data is preprocessed, so the\n      # inputs are tf-examples.\n      # Generate placeholders for examples.\n      with tf.name_scope('inputs'):\n        feature_map = {\n            'image_uri':\n                tf.FixedLenFeature(\n                    shape=[], dtype=tf.string, default_value=['']),\n            # Some images may have no labels. For those, we assume a default\n            # label. So the number of labels is label_count+1 for the default\n            # label.\n            'label':\n                tf.FixedLenFeature(\n                    shape=[1], dtype=tf.int64,\n                    default_value=[len(self.labels)]),\n            'embedding':\n                tf.FixedLenFeature(\n                    shape=[BOTTLENECK_TENSOR_SIZE], dtype=tf.float32)\n        }\n        parsed = tf.parse_example(tensors.examples, features=feature_map)\n        labels = tf.squeeze(parsed['label'])\n        uris = tf.squeeze(parsed['image_uri'])\n        embeddings = parsed['embedding']\n\n    # We assume a default label, so the total number of labels is equal to\n    # label_count+1.\n    all_labels_count = len(self.labels) + 1\n    with tf.name_scope('final_ops'):\n      softmax, logits = self.add_final_training_ops(\n          embeddings,\n          all_labels_count,\n          BOTTLENECK_TENSOR_SIZE,\n          dropout_keep_prob=self.dropout if is_training else None)\n\n    # Prediction is the index of the label with the highest score. We are\n    # interested only in the top score.\n    prediction = tf.argmax(softmax, 1)\n    tensors.predictions = [prediction, softmax, embeddings]\n\n    if graph_mod == GraphMod.PREDICT:\n      return tensors\n\n    with tf.name_scope('evaluate'):\n      loss_value = loss(logits, labels)\n\n    # Add to the Graph the Ops that calculate and apply gradients.\n    if is_training:\n      tensors.train, tensors.global_step = training(loss_value)\n    else:\n      tensors.global_step = tf.Variable(0, name='global_step', trainable=False)\n      tensors.uris = uris\n\n    # Add means across all batches.\n    loss_updates, loss_op = _util.loss(loss_value)\n    accuracy_updates, accuracy_op = _util.accuracy(logits, labels)\n\n    if not is_training:\n      tf.summary.scalar('accuracy', accuracy_op)\n      tf.summary.scalar('loss', loss_op)\n\n    tensors.metric_updates = loss_updates + accuracy_updates\n    tensors.metric_values = [loss_op, accuracy_op]\n    return tensors\n\n  def build_train_graph(self, data_paths, batch_size):\n    return self.build_graph(data_paths, batch_size, GraphMod.TRAIN)\n\n  def build_eval_graph(self, data_paths, batch_size):\n    return self.build_graph(data_paths, batch_size, GraphMod.EVALUATE)\n\n  def restore_from_checkpoint(self, session, inception_checkpoint_file,\n                              trained_checkpoint_file):\n    \"\"\"To restore model variables from the checkpoint file.\n\n       The graph is assumed to consist of an inception model and other\n       layers including a softmax and a fully connected layer. The former is\n       pre-trained and the latter is trained using the pre-processed data. So\n       we restore this from two checkpoint files.\n    Args:\n      session: The session to be used for restoring from checkpoint.\n      inception_checkpoint_file: Path to the checkpoint file for the Inception\n                                 graph.\n      trained_checkpoint_file: path to the trained checkpoint for the other\n                               layers.\n    \"\"\"\n    inception_exclude_scopes = [\n        'InceptionV3/AuxLogits', 'InceptionV3/Logits', 'global_step',\n        'final_ops'\n    ]\n    reader = tf.train.NewCheckpointReader(inception_checkpoint_file)\n    var_to_shape_map = reader.get_variable_to_shape_map()\n\n    # Get all variables to restore. Exclude Logits and AuxLogits because they\n    # depend on the input data and we do not need to intialize them.\n    all_vars = tf.contrib.slim.get_variables_to_restore(\n        exclude=inception_exclude_scopes)\n    # Remove variables that do not exist in the inception checkpoint (for\n    # example the final softmax and fully-connected layers).\n    inception_vars = {\n        var.op.name: var\n        for var in all_vars if var.op.name in var_to_shape_map\n    }\n    inception_saver = tf.train.Saver(inception_vars)\n    inception_saver.restore(session, inception_checkpoint_file)\n\n    # Restore the rest of the variables from the trained checkpoint.\n    trained_vars = tf.contrib.slim.get_variables_to_restore(\n        exclude=inception_exclude_scopes + inception_vars.keys())\n    trained_saver = tf.train.Saver(trained_vars)\n    trained_saver.restore(session, trained_checkpoint_file)\n\n  def build_prediction_graph(self):\n    \"\"\"Builds prediction graph and registers appropriate endpoints.\"\"\"\n\n    tensors = self.build_graph(None, 1, GraphMod.PREDICT)\n\n    keys_placeholder = tf.placeholder(tf.string, shape=[None])\n    inputs = {\n        'key': keys_placeholder,\n        'image_bytes': tensors.input_jpeg\n    }\n\n    # To extract the id, we need to add the identity function.\n    keys = tf.identity(keys_placeholder)\n    labels = self.labels + ['UNKNOWN']\n    labels_tensor = tf.constant(labels)\n    labels_table = tf.contrib.lookup.index_to_string_table_from_tensor(mapping=labels_tensor)\n    predicted_label = labels_table.lookup(tensors.predictions[0])\n\n    # Need to duplicate the labels by num_of_instances so the output is one batch\n    # (all output members share the same outer dimension).\n    # The labels are needed for client to match class scores list.\n    labels_tensor = tf.expand_dims(tf.constant(labels), 0)\n    num_instance = tf.shape(keys)\n    labels_tensors_n = tf.tile(labels_tensor, tf.concat(axis=0, values=[num_instance, [1]]))\n\n    outputs = {\n        'key': keys,\n        'prediction': predicted_label,\n        'labels': labels_tensors_n,\n        'scores': tensors.predictions[1],\n    }\n    return inputs, outputs\n\n  def export(self, last_checkpoint, output_dir):\n    \"\"\"Builds a prediction graph and xports the model.\n\n    Args:\n      last_checkpoint: Path to the latest checkpoint file from training.\n      output_dir: Path to the folder to be used to output the model.\n    \"\"\"\n    logging.info('Exporting prediction graph to %s', output_dir)\n    with tf.Session(graph=tf.Graph()) as sess:\n      # Build and save prediction meta graph and trained variable values.\n      inputs, outputs = self.build_prediction_graph()\n      signature_def_map = {\n        'serving_default': signature_def_utils.predict_signature_def(inputs, outputs)\n      }\n      init_op = tf.global_variables_initializer()\n      sess.run(init_op)\n      self.restore_from_checkpoint(sess, self.inception_checkpoint_file,\n                                   last_checkpoint)\n      init_op_serving = control_flow_ops.group(\n          variables.local_variables_initializer(),\n          tf.tables_initializer())\n\n      builder = saved_model_builder.SavedModelBuilder(output_dir)\n      builder.add_meta_graph_and_variables(\n          sess, [tag_constants.SERVING],\n          signature_def_map=signature_def_map,\n          legacy_init_op=init_op_serving)\n      builder.save(False)\n\n  def format_metric_values(self, metric_values):\n    \"\"\"Formats metric values - used for logging purpose.\"\"\"\n\n    # Early in training, metric_values may actually be None.\n    loss_str = 'N/A'\n    accuracy_str = 'N/A'\n    try:\n      loss_str = 'loss: %.3f' % metric_values[0]\n      accuracy_str = 'accuracy: %.3f' % metric_values[1]\n    except (TypeError, IndexError):\n      pass\n\n    return '%s, %s' % (loss_str, accuracy_str)\n\n  def format_prediction_values(self, prediction):\n    \"\"\"Formats prediction values - used for writing batch predictions as csv.\"\"\"\n    return '%.3f' % (prediction[0])\n\n\ndef loss(logits, labels):\n  \"\"\"Calculates the loss from the logits and the labels.\n\n  Args:\n    logits: Logits tensor, float - [batch_size, NUM_CLASSES].\n    labels: Labels tensor, int32 - [batch_size].\n  Returns:\n    loss: Loss tensor of type float.\n  \"\"\"\n  labels = tf.to_int64(labels)\n  cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(\n      logits=logits, labels=labels, name='xentropy')\n  return tf.reduce_mean(cross_entropy, name='xentropy_mean')\n\n\ndef training(loss_op):\n  \"\"\"Calculates the loss from the logits and the labels.\n\n  Args:\n    logits: Logits tensor, float - [batch_size, NUM_CLASSES].\n    labels: Labels tensor, int32 - [batch_size].\n  Returns:\n    loss: Loss tensor of type float.\n  \"\"\"\n  global_step = tf.Variable(0, name='global_step', trainable=False)\n  with tf.name_scope('train'):\n    optimizer = tf.train.AdamOptimizer(epsilon=0.001)\n    train_op = optimizer.minimize(loss_op, global_step)\n    return train_op, global_step\n"
  },
  {
    "path": "solutionbox/image_classification/mltoolbox/image/classification/_predictor.py",
    "content": "# Copyright 2017 Google Inc. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\n\"\"\"Local implementation for preprocessing, training and prediction for inception model.\n\"\"\"\n\nimport apache_beam as beam\nfrom apache_beam.transforms import window\nfrom apache_beam.utils.windowed_value import WindowedValue\nimport collections\nimport json\nimport os\n\nfrom . import _util\n\n\ndef _load_tf_model(model_dir):\n  from tensorflow.python.saved_model import tag_constants\n  from tensorflow.contrib.session_bundle import bundle_shim\n\n  model_dir = os.path.join(model_dir, 'model')\n  session, meta_graph = bundle_shim.load_session_bundle_or_saved_model_bundle_from_path(\n      model_dir, tags=[tag_constants.SERVING])\n  signature = meta_graph.signature_def['serving_default']\n  inputs = {friendly_name: tensor_info_proto.name\n            for (friendly_name, tensor_info_proto) in signature.inputs.items()}\n  outputs = {friendly_name: tensor_info_proto.name\n             for (friendly_name, tensor_info_proto) in signature.outputs.items()}\n  return session, inputs, outputs\n\n\ndef _tf_predict(model_dir, images):\n  session, inputs, outputs = _load_tf_model(model_dir)\n\n  with session:\n    feed_dict = collections.defaultdict(list)\n    for ii, image in enumerate(images):\n      feed_dict[inputs['image_bytes']].append(image)\n      feed_dict[inputs['key']].append(str(ii))\n    predictions, labels, scores = session.run(\n      [outputs['prediction'], outputs['labels'], outputs['scores']], feed_dict=feed_dict)\n\n  return zip(predictions, labels, scores)\n\n\ndef predict(model_dir, images):\n  \"\"\"Local instant prediction.\"\"\"\n\n  results = _tf_predict(model_dir, images)\n  predicted_and_scores = [(predicted, label_scores[list(labels).index(predicted)])\n                          for predicted, labels, label_scores in results]\n  return predicted_and_scores\n\n\n# Helpers for batch prediction dataflow pipeline\n\nclass EmitAsBatchDoFn(beam.DoFn):\n  \"\"\"A DoFn that buffers the records and emits them batch by batch.\"\"\"\n\n  def __init__(self, batch_size):\n    self._batch_size = batch_size\n    self._cached = []\n\n  def process(self, element):\n    self._cached.append(element)\n    if len(self._cached) >= self._batch_size:\n      emit = self._cached\n      self._cached = []\n      yield emit\n\n  def finish_bundle(self, context=None):\n    if len(self._cached) > 0:  # pylint: disable=g-explicit-length-test\n      yield WindowedValue(self._cached, -1, [window.GlobalWindow()])\n\n\nclass UnbatchDoFn(beam.DoFn):\n  \"\"\"A DoFn expand batch into elements.\"\"\"\n\n  def process(self, element):\n    for item in element:\n      yield item\n\n\nclass LoadImagesDoFn(beam.DoFn):\n  \"\"\"A DoFn that reads image from url.\"\"\"\n\n  def process(self, element):\n    from tensorflow.python.lib.io import file_io as tf_file_io\n\n    with tf_file_io.FileIO(element['image_url'], 'r') as ff:\n      image_bytes = ff.read()\n    out_element = {'image_bytes': image_bytes}\n    out_element.update(element)\n    yield out_element\n\n\nclass PredictBatchDoFn(beam.DoFn):\n  \"\"\"A DoFn that does batch prediction.\"\"\"\n\n  def __init__(self, model_dir):\n    self._model_dir = model_dir\n    self._session = None\n    self._tf_inputs = None\n    self._tf_outputs = None\n\n  def start_bundle(self, context=None):\n    self._session, self._tf_inputs, self._tf_outputs = _load_tf_model(self._model_dir)\n\n  def finish_bundle(self, context=None):\n    if self._session is not None:\n      self._session.close()\n\n  def process(self, element):\n    import collections\n\n    image_urls = [x['image_url'] for x in element]\n    targets = None\n    if 'label' in element[0] and element[0]['label'] is not None:\n      targets = [x['label'] for x in element]\n\n    feed_dict = collections.defaultdict(list)\n    feed_dict[self._tf_inputs['image_bytes']] = [x['image_bytes'] for x in element]\n    feed_dict[self._tf_inputs['key']] = image_urls\n    predictions, labels, scores = self._session.run(\n        [self._tf_outputs['prediction'], self._tf_outputs['labels'], self._tf_outputs['scores']],\n        feed_dict=feed_dict)\n    if targets is not None:\n      yield zip(image_urls, targets, predictions, labels, scores)\n    else:\n      yield zip(image_urls, predictions, labels, scores)\n\n\nclass ProcessResultsDoFn(beam.DoFn):\n  \"\"\"A DoFn that process prediction results by casting values and calculating\n     target_prob.\n  \"\"\"\n\n  def process(self, element):\n    target = None\n    if len(element) == 5:\n      image_url, target, prediction, labels, scores = element\n    else:\n      image_url, prediction, labels, scores = element\n    labels = list(labels)\n    predicted_prob = scores[labels.index(prediction)]\n    out_element = {\n      'image_url': image_url,\n      'predicted': prediction,\n      # Convert to float from np.float32 because BigQuery Sink can only handle intrinsic types.\n      'predicted_prob': float(predicted_prob)\n    }\n    if target is not None:\n      target_prob = scores[labels.index(target)] if target in labels else 0.0\n      out_element['target_prob'] = float(target_prob)\n      out_element['target'] = target\n    yield out_element\n\n\nclass MakeCsvLineDoFn(beam.DoFn):\n  \"\"\"A DoFn that makes CSV lines out of prediction results.\"\"\"\n\n  def process(self, element):\n    import csv\n    import StringIO\n\n    line = StringIO.StringIO()\n    if len(element) == 5:\n      csv.DictWriter(line, ['image_url', 'target', 'predicted', 'target_prob',\n                            'predicted_prob']).writerow(element)\n    else:\n      csv.DictWriter(line, ['image_url', 'predicted', 'predicted_prob']).writerow(element)\n    yield line.getvalue()\n\n\ndef configure_pipeline(p, dataset, model_dir, output_csv, output_bq_table):\n  \"\"\"Configures a dataflow pipeline for batch prediction.\"\"\"\n\n  data = _util.get_sources_from_dataset(p, dataset, 'predict')\n  if len(dataset.schema) == 2:\n    output_schema = [\n        {'name': 'image_url', 'type': 'STRING'},\n        {'name': 'target', 'type': 'STRING'},\n        {'name': 'predicted', 'type': 'STRING'},\n        {'name': 'target_prob', 'type': 'FLOAT'},\n        {'name': 'predicted_prob', 'type': 'FLOAT'},\n    ]\n  else:\n    output_schema = [\n        {'name': 'image_url', 'type': 'STRING'},\n        {'name': 'predicted', 'type': 'STRING'},\n        {'name': 'predicted_prob', 'type': 'FLOAT'},\n    ]\n  results = (data |\n             'Load Images' >> beam.ParDo(LoadImagesDoFn()) |\n             'Batch Inputs' >> beam.ParDo(EmitAsBatchDoFn(20)) |\n             'Batch Predict' >> beam.ParDo(PredictBatchDoFn(model_dir)) |\n             'Unbatch' >> beam.ParDo(UnbatchDoFn()) |\n             'Process Results' >> beam.ParDo(ProcessResultsDoFn()))\n\n  if output_csv is not None:\n    schema_file = output_csv + '.schema.json'\n    results_save = (results |\n                    'Prepare For Output' >> beam.ParDo(MakeCsvLineDoFn()) |\n                    'Write Csv Results' >> beam.io.textio.WriteToText(output_csv,\n                                                                      shard_name_template=''))\n    (results_save |\n     'Sample One' >> beam.transforms.combiners.Sample.FixedSizeGlobally(1) |\n     'Serialize Schema' >> beam.Map(lambda path: json.dumps(output_schema)) |\n     'Write Schema' >> beam.io.textio.WriteToText(schema_file, shard_name_template=''))\n\n  if output_bq_table is not None:\n    # BigQuery sink takes schema in the form of 'field1:type1,field2:type2...'\n    bq_schema_string = ','.join(x['name'] + ':' + x['type'] for x in output_schema)\n    sink = beam.io.BigQuerySink(output_bq_table, schema=bq_schema_string,\n                                write_disposition=beam.io.BigQueryDisposition.WRITE_TRUNCATE)\n    results | 'Write BQ Results' >> beam.io.Write(sink)\n"
  },
  {
    "path": "solutionbox/image_classification/mltoolbox/image/classification/_preprocess.py",
    "content": "# Copyright 2017 Google Inc. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\n\"\"\"Preprocess pipeline implementation with Cloud DataFlow.\n\"\"\"\n\n\nimport apache_beam as beam\nfrom apache_beam.io import tfrecordio\nfrom apache_beam.metrics import Metrics\nimport cStringIO\nimport logging\nimport os\nfrom PIL import Image\n\nfrom . import _inceptionlib\nfrom . import _util\n\n\nerror_count = Metrics.counter('main', 'errorCount')\nrows_count = Metrics.counter('main', 'rowsCount')\nskipped_empty_line = Metrics.counter('main', 'skippedEmptyLine')\nembedding_good = Metrics.counter('main', 'embedding_good')\nembedding_bad = Metrics.counter('main', 'embedding_bad')\nincompatible_image = Metrics.counter('main', 'incompatible_image')\ninvalid_uri = Metrics.counter('main', 'invalid_file_name')\nunlabeled_image = Metrics.counter('main', 'unlabeled_image')\n\n\nclass ExtractLabelIdsDoFn(beam.DoFn):\n  \"\"\"Extracts (uri, label_ids) tuples from CSV rows.\n  \"\"\"\n\n  def start_bundle(self, context=None):\n    self.label_to_id_map = {}\n\n  def process(self, element, all_labels):\n    all_labels = list(all_labels)\n    # DataFlow cannot garuantee the order of the labels when materializing it.\n    # The labels materialized and consumed by training may not be with the same order\n    # as the one used in preprocessing. So we need to sort it in both preprocessing\n    # and training so the order matches.\n    all_labels.sort()\n    if not self.label_to_id_map:\n      for i, label in enumerate(all_labels):\n        label = label.strip()\n        if label:\n          self.label_to_id_map[label] = i\n\n    # Row format is:\n    # image_uri,label_id\n    if not element:\n      skipped_empty_line.inc()\n      return\n\n    rows_count.inc()\n    uri = element['image_url']\n\n    try:\n      label_id = self.label_to_id_map[element['label'].strip()]\n    except KeyError:\n      unlabeled_image.inc()\n    yield uri, label_id\n\n\nclass ReadImageAndConvertToJpegDoFn(beam.DoFn):\n  \"\"\"Read files from GCS and convert images to JPEG format.\n\n  We do this even for JPEG images to remove variations such as different number\n  of channels.\n  \"\"\"\n\n  def process(self, element):\n    from tensorflow.python.lib.io import file_io as tf_file_io\n\n    uri, label_id = element\n    try:\n      with tf_file_io.FileIO(uri, 'r') as f:\n        img = Image.open(f).convert('RGB')\n    # A variety of different calling libraries throw different exceptions here.\n    # They all correspond to an unreadable file so we treat them equivalently.\n    # pylint: disable broad-except\n    except Exception as e:\n      logging.exception('Error processing image %s: %s', uri, str(e))\n      error_count.inc()\n      return\n\n    # Convert to desired format and output.\n    output = cStringIO.StringIO()\n    img.save(output, 'jpeg')\n    image_bytes = output.getvalue()\n    yield uri, label_id, image_bytes\n\n\nclass EmbeddingsGraph(object):\n  \"\"\"Builds a graph and uses it to extract embeddings from images.\n  \"\"\"\n\n  # These constants are set by Inception v3's expectations.\n  WIDTH = 299\n  HEIGHT = 299\n  CHANNELS = 3\n\n  def __init__(self, tf_session, checkpoint_path):\n    import tensorflow as tf\n\n    self.tf_session = tf_session\n    # input_jpeg is the tensor that contains raw image bytes.\n    # It is used to feed image bytes and obtain embeddings.\n    self.input_jpeg, self.embedding = self.build_graph()\n    self.tf_session.run(tf.global_variables_initializer())\n    self.restore_from_checkpoint(checkpoint_path)\n\n  def build_graph(self):\n    \"\"\"Forms the core by building a wrapper around the inception graph.\n\n      Here we add the necessary input & output tensors, to decode jpegs,\n      serialize embeddings, restore from checkpoint etc.\n\n      To use other Inception models modify this file. Note that to use other\n      models beside Inception, you should make sure input_shape matches\n      their input. Resizing or other modifications may be necessary as well.\n      See tensorflow/contrib/slim/python/slim/nets/inception_v3.py for\n      details about InceptionV3.\n\n    Returns:\n      input_jpeg: A tensor containing raw image bytes as the input layer.\n      embedding: The embeddings tensor, that will be materialized later.\n    \"\"\"\n\n    import tensorflow as tf\n    input_jpeg = tf.placeholder(tf.string, shape=None)\n    image = tf.image.decode_jpeg(input_jpeg, channels=self.CHANNELS)\n\n    # Note resize expects a batch_size, but we are feeding a single image.\n    # So we have to expand then squeeze.  Resize returns float32 in the\n    # range [0, uint8_max]\n    image = tf.expand_dims(image, 0)\n\n    # convert_image_dtype also scales [0, uint8_max] -> [0 ,1).\n    image = tf.image.convert_image_dtype(image, dtype=tf.float32)\n    image = tf.image.resize_bilinear(\n        image, [self.HEIGHT, self.WIDTH], align_corners=False)\n\n    # Then rescale range to [-1, 1) for Inception.\n    image = tf.subtract(image, 0.5)\n    inception_input = tf.multiply(image, 2.0)\n\n    # Build Inception layers, which expect a tensor of type float from [-1, 1)\n    # and shape [batch_size, height, width, channels].\n    with tf.contrib.slim.arg_scope(_inceptionlib.inception_v3_arg_scope()):\n      _, end_points = _inceptionlib.inception_v3(inception_input, is_training=False)\n\n    embedding = end_points['PreLogits']\n    return input_jpeg, embedding\n\n  def restore_from_checkpoint(self, checkpoint_path):\n    \"\"\"To restore inception model variables from the checkpoint file.\n\n       Some variables might be missing in the checkpoint file, so it only\n       loads the ones that are avialable, assuming the rest would be\n       initialized later.\n    Args:\n      checkpoint_path: Path to the checkpoint file for the Inception graph.\n    \"\"\"\n    import tensorflow as tf\n    # Get all variables to restore. Exclude Logits and AuxLogits because they\n    # depend on the input data and we do not need to intialize them from\n    # checkpoint.\n    all_vars = tf.contrib.slim.get_variables_to_restore(\n        exclude=['InceptionV3/AuxLogits', 'InceptionV3/Logits', 'global_step'])\n\n    saver = tf.train.Saver(all_vars)\n    saver.restore(self.tf_session, checkpoint_path)\n\n  def calculate_embedding(self, batch_image_bytes):\n    \"\"\"Get the embeddings for a given JPEG image.\n\n    Args:\n      batch_image_bytes: As if returned from [ff.read() for ff in file_list].\n\n    Returns:\n      The Inception embeddings (bottleneck layer output)\n    \"\"\"\n    return self.tf_session.run(\n        self.embedding, feed_dict={self.input_jpeg: batch_image_bytes})\n\n\nclass TFExampleFromImageDoFn(beam.DoFn):\n  \"\"\"Embeds image bytes and labels, stores them in tensorflow.Example.\n\n  (uri, label_ids, image_bytes) -> (tensorflow.Example).\n\n  Output proto contains 'label', 'image_uri' and 'embedding'.\n  The 'embedding' is calculated by feeding image into input layer of image\n  neural network and reading output of the bottleneck layer of the network.\n\n  Attributes:\n    image_graph_uri: an uri to gcs bucket where serialized image graph is\n                     stored.\n  \"\"\"\n\n  def __init__(self, checkpoint_path):\n    self.tf_session = None\n    self.graph = None\n    self.preprocess_graph = None\n    self._checkpoint_path = checkpoint_path\n\n  def start_bundle(self, context=None):\n    # There is one tensorflow session per instance of TFExampleFromImageDoFn.\n    # The same instance of session is re-used between bundles.\n    # Session is closed by the destructor of Session object, which is called\n    # when instance of TFExampleFromImageDoFn() is destructed.\n    import tensorflow as tf\n    if not self.graph:\n      self.graph = tf.Graph()\n      self.tf_session = tf.InteractiveSession(graph=self.graph)\n      with self.graph.as_default():\n        self.preprocess_graph = EmbeddingsGraph(self.tf_session, self._checkpoint_path)\n\n  def finish_bundle(self, context=None):\n    if self.tf_session is not None:\n      self.tf_session.close()\n\n  def process(self, element):\n\n    import tensorflow as tf\n\n    def _bytes_feature(value):\n      return tf.train.Feature(bytes_list=tf.train.BytesList(value=value))\n\n    def _float_feature(value):\n      return tf.train.Feature(float_list=tf.train.FloatList(value=value))\n\n    uri, label_id, image_bytes = element\n\n    try:\n      embedding = self.preprocess_graph.calculate_embedding(image_bytes)\n    except tf.errors.InvalidArgumentError as e:\n      incompatible_image.inc()\n      logging.warning('Could not encode an image from %s: %s', uri, str(e))\n      return\n\n    if embedding.any():\n      embedding_good.inc()\n    else:\n      embedding_bad.inc()\n\n    example = tf.train.Example(features=tf.train.Features(feature={\n        'image_uri': _bytes_feature([str(uri)]),\n        'embedding': _float_feature(embedding.ravel().tolist()),\n    }))\n\n    example.features.feature['label'].int64_list.value.append(label_id)\n\n    yield example\n\n\nclass TrainEvalSplitPartitionFn(beam.PartitionFn):\n  \"\"\"Split train and eval data.\"\"\"\n  def partition_for(self, element, num_partitions):\n    import random\n    return 1 if random.random() > 0.7 else 0\n\n\nclass ExampleProtoCoder(beam.coders.Coder):\n  \"\"\"A coder to encode and decode TensorFlow Example objects.\"\"\"\n\n  def encode(self, example_proto):\n    return example_proto.SerializeToString()\n\n  def decode(self, serialized_str):\n    import tensorflow as tf\n    example = tf.train.Example()\n    example.ParseFromString(serialized_str)\n    return example\n\n\nclass SaveFeatures(beam.PTransform):\n  \"\"\"Save Features in a TFRecordIO format.\n  \"\"\"\n\n  def __init__(self, file_path_prefix):\n    super(SaveFeatures, self).__init__('SaveFeatures')\n    self._file_path_prefix = file_path_prefix\n\n  def expand(self, features):\n    return (features |\n            'Write to %s' % self._file_path_prefix.replace('/', '_') >>\n            tfrecordio.WriteToTFRecord(file_path_prefix=self._file_path_prefix,\n                                       file_name_suffix='.tfrecord.gz',\n                                       coder=ExampleProtoCoder()))\n\n\ndef _labels_pipeline(sources):\n  labels = (sources |\n            'Flatten Sources for labels' >> beam.Flatten() |\n            'Parse input for labels' >> beam.Map(lambda x: str(x['label'])) |\n            'Combine labels' >> beam.transforms.combiners.Count.PerElement() |\n            'Get labels' >> beam.Map(lambda label_count: label_count[0]))\n  return labels\n\n\ndef _transformation_pipeline(source, checkpoint, labels, mode):\n  transformed = (source |\n                 'Extract label ids(%s)' % mode >>\n                 beam.ParDo(ExtractLabelIdsDoFn(), beam.pvalue.AsIter(labels)) |\n                 'Read and convert to JPEG(%s)' % mode >>\n                 beam.ParDo(ReadImageAndConvertToJpegDoFn()) |\n                 'Embed and make TFExample(%s)' % mode >>\n                 beam.ParDo(TFExampleFromImageDoFn(checkpoint)))\n  return transformed\n\n\ndef configure_pipeline(p, dataset_train, dataset_eval, checkpoint_path, output_dir, job_id):\n  source_train = _util.get_sources_from_dataset(p, dataset_train, 'train')\n  labels_source = [source_train]\n  if dataset_eval is not None:\n    source_eval = _util.get_sources_from_dataset(p, dataset_eval, 'eval')\n    labels_source.append(source_eval)\n\n  labels = _labels_pipeline(labels_source)\n  train_preprocessed = _transformation_pipeline(source_train, checkpoint_path, labels, 'train')\n  if dataset_eval is not None:\n    # explicit eval data.\n    eval_preprocessed = _transformation_pipeline(source_eval, checkpoint_path, labels, 'eval')\n  else:\n    # Split train/eval.\n    train_preprocessed, eval_preprocessed = (train_preprocessed |\n                                             'Random Partition' >>\n                                             beam.Partition(TrainEvalSplitPartitionFn(), 2))\n\n  output_train_path = os.path.join(output_dir, job_id, 'train')\n  output_eval_path = os.path.join(output_dir, job_id, 'eval')\n  labels_file = os.path.join(output_dir, job_id, 'labels')\n  labels_save = (labels |\n                 'Write labels' >>\n                 beam.io.textio.WriteToText(labels_file, shard_name_template=''))\n  train_save = train_preprocessed | 'Save train to disk' >> SaveFeatures(output_train_path)\n  eval_save = eval_preprocessed | 'Save eval to disk' >> SaveFeatures(output_eval_path)\n  # Make sure we write \"latest\" file after train and eval data are successfully written.\n  output_latest_file = os.path.join(output_dir, 'latest')\n  ([eval_save, train_save, labels_save] | 'Wait for train eval saving' >> beam.Flatten() |\n      'Fixed One' >> beam.transforms.combiners.Sample.FixedSizeGlobally(1) |\n      beam.Map(lambda path: job_id) |\n      'WriteLatest' >> beam.io.textio.WriteToText(output_latest_file, shard_name_template=''))\n"
  },
  {
    "path": "solutionbox/image_classification/mltoolbox/image/classification/_trainer.py",
    "content": "# Copyright 2017 Google Inc. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\n\"\"\"Training implementation for inception model.\n\"\"\"\n\nimport logging\nimport os\nimport tensorflow as tf\nimport time\n\nfrom . import _util\n\n\ndef start_server(cluster, task):\n  if not task.type:\n    raise ValueError('--task_type must be specified.')\n  if task.index is None:\n    raise ValueError('--task_index must be specified.')\n\n  # Create and start a server.\n  return tf.train.Server(\n      tf.train.ClusterSpec(cluster),\n      protocol='grpc',\n      job_name=task.type,\n      task_index=task.index)\n\n\nclass Evaluator(object):\n  \"\"\"Loads variables from latest checkpoint and performs model evaluation.\"\"\"\n\n  def __init__(self, model, data_paths, batch_size, output_path, dataset='eval'):\n    data_size = self._data_size(data_paths)\n    if data_size <= batch_size:\n      raise Exception('Data size is smaller than batch size.')\n    self.num_eval_batches = data_size // batch_size\n    self.batch_of_examples = []\n    self.checkpoint_path = os.path.join(output_path, 'train')\n    self.output_path = os.path.join(output_path, dataset)\n    self.eval_data_paths = data_paths\n    self.batch_size = batch_size\n    self.model = model\n\n  def _data_size(self, data_paths):\n    n = 0\n    options = tf.python_io.TFRecordOptions(\n        compression_type=tf.python_io.TFRecordCompressionType.GZIP)\n    for file in data_paths:\n      for line in tf.python_io.tf_record_iterator(file, options=options):\n        n += 1\n    return n\n\n  def evaluate(self, num_eval_batches=None):\n    \"\"\"Run one round of evaluation, return loss and accuracy.\"\"\"\n\n    num_eval_batches = num_eval_batches or self.num_eval_batches\n    with tf.Graph().as_default() as graph:\n      self.tensors = self.model.build_eval_graph(self.eval_data_paths,\n                                                 self.batch_size)\n      self.summary = tf.summary.merge_all()\n      self.saver = tf.train.Saver()\n\n    self.summary_writer = tf.summary.FileWriter(self.output_path)\n    self.sv = tf.train.Supervisor(\n        graph=graph,\n        logdir=self.output_path,\n        summary_op=None,\n        global_step=None,\n        saver=self.saver)\n\n    last_checkpoint = tf.train.latest_checkpoint(self.checkpoint_path)\n    with self.sv.managed_session(master='', start_standard_services=False) as session:\n      self.sv.saver.restore(session, last_checkpoint)\n\n      if not self.batch_of_examples:\n        self.sv.start_queue_runners(session)\n        for i in range(num_eval_batches):\n          self.batch_of_examples.append(session.run(self.tensors.examples))\n\n      for i in range(num_eval_batches):\n        session.run(self.tensors.metric_updates,\n                    {self.tensors.examples: self.batch_of_examples[i]})\n\n      metric_values = session.run(self.tensors.metric_values)\n      global_step = tf.train.global_step(session, self.tensors.global_step)\n      summary = session.run(self.summary)\n      self.summary_writer.add_summary(summary, global_step)\n      self.summary_writer.flush()\n      return metric_values\n\n\nclass Trainer(object):\n  \"\"\"Performs model training and optionally evaluation.\"\"\"\n\n  def __init__(self, input_dir, batch_size, max_steps, output_path, model, cluster, task):\n    train_files, eval_files = _util.get_train_eval_files(input_dir)\n    self.train_data_paths = train_files\n    self.output_path = output_path\n    self.batch_size = batch_size\n    self.model = model\n    self.max_steps = max_steps\n    self.cluster = cluster\n    self.task = task\n    self.evaluator = Evaluator(self.model, eval_files, batch_size, output_path, 'eval_set')\n    self.train_evaluator = Evaluator(self.model, train_files, batch_size, output_path, 'train_set')\n    self.min_train_eval_rate = 8\n\n  def run_training(self):\n    \"\"\"Runs a Master.\"\"\"\n    self.train_path = os.path.join(self.output_path, 'train')\n    self.model_path = os.path.join(self.output_path, 'model')\n    self.is_master = self.task.type != 'worker'\n    log_interval = 15\n    self.eval_interval = 30\n    if self.is_master and self.task.index > 0:\n      raise Exception('Only one replica of master expected')\n\n    if self.cluster:\n      logging.info('Starting %s/%d', self.task.type, self.task.index)\n      server = start_server(self.cluster, self.task)\n      target = server.target\n      device_fn = tf.train.replica_device_setter(\n          ps_device='/job:ps',\n          worker_device='/job:%s/task:%d' % (self.task.type, self.task.index),\n          cluster=self.cluster)\n      # We use a device_filter to limit the communication between this job\n      # and the parameter servers, i.e., there is no need to directly\n      # communicate with the other workers; attempting to do so can result\n      # in reliability problems.\n      device_filters = [\n          '/job:ps', '/job:%s/task:%d' % (self.task.type, self.task.index)\n      ]\n      config = tf.ConfigProto(device_filters=device_filters)\n    else:\n      target = ''\n      device_fn = ''\n      config = None\n\n    with tf.Graph().as_default() as graph:\n      with tf.device(device_fn):\n        # Build the training graph.\n        self.tensors = self.model.build_train_graph(self.train_data_paths,\n                                                    self.batch_size)\n\n        # Add the variable initializer Op.\n        init_op = tf.global_variables_initializer()\n\n        # Create a saver for writing training checkpoints.\n        self.saver = tf.train.Saver()\n\n        # Build the summary operation based on the TF collection of Summaries.\n        self.summary_op = tf.summary.merge_all()\n\n    # Create a \"supervisor\", which oversees the training process.\n    self.sv = tf.train.Supervisor(\n        graph,\n        is_chief=self.is_master,\n        logdir=self.train_path,\n        init_op=init_op,\n        saver=self.saver,\n        # Write summary_ops by hand.\n        summary_op=None,\n        global_step=self.tensors.global_step,\n        # No saving; we do it manually in order to easily evaluate immediately\n        # afterwards.\n        save_model_secs=0)\n\n    should_retry = True\n    to_run = [self.tensors.global_step, self.tensors.train]\n\n    while should_retry:\n      try:\n        should_retry = False\n        with self.sv.managed_session(target, config=config) as session:\n          self.start_time = start_time = time.time()\n          self.last_save = self.last_log = 0\n          self.global_step = self.last_global_step = 0\n          self.local_step = self.last_local_step = 0\n          self.last_global_time = self.last_local_time = start_time\n\n          # Loop until the supervisor shuts down or max_steps have\n          # completed.\n          max_steps = self.max_steps\n          while not self.sv.should_stop() and self.global_step < max_steps:\n            try:\n              # Run one step of the model.\n              self.global_step = session.run(to_run)[0]\n              self.local_step += 1\n\n              self.now = time.time()\n              is_time_to_eval = (self.now - self.last_save) > self.eval_interval\n              is_time_to_log = (self.now - self.last_log) > log_interval\n              should_eval = self.is_master and is_time_to_eval\n              should_log = is_time_to_log or should_eval\n\n              if should_log:\n                self.log(session)\n\n              if should_eval:\n                self.eval(session)\n            except tf.errors.AbortedError:\n              should_retry = True\n\n          if self.is_master:\n            # Take the final checkpoint and compute the final accuracy.\n            # self.saver.save(session, self.sv.save_path, self.tensors.global_step)\n            self.eval(session)\n\n      except tf.errors.AbortedError:\n        print('Hitting an AbortedError. Trying it again.')\n        should_retry = True\n\n    # Export the model for inference.\n    if self.is_master:\n      self.model.export(tf.train.latest_checkpoint(self.train_path), self.model_path)\n\n    # Ask for all the services to stop.\n    self.sv.stop()\n\n  def log(self, session):\n    \"\"\"Logs training progress.\"\"\"\n    logging.info('Train [%s/%d], step %d (%.3f sec) %.1f '\n                 'global steps/s, %.1f local steps/s', self.task.type,\n                 self.task.index, self.global_step,\n                 (self.now - self.start_time),\n                 (self.global_step - self.last_global_step) /\n                 (self.now - self.last_global_time),\n                 (self.local_step - self.last_local_step) /\n                 (self.now - self.last_local_time))\n    self.last_log = self.now\n    self.last_global_step, self.last_global_time = self.global_step, self.now\n    self.last_local_step, self.last_local_time = self.local_step, self.now\n\n  def eval(self, session):\n    \"\"\"Runs evaluation loop.\"\"\"\n    eval_start = time.time()\n    self.saver.save(session, self.sv.save_path, self.tensors.global_step)\n    logging.info(\n        'Eval, step %d:\\n- on train set %s\\n-- on eval set %s',\n        self.global_step,\n        self.model.format_metric_values(self.train_evaluator.evaluate()),\n        self.model.format_metric_values(self.evaluator.evaluate()))\n    now = time.time()\n\n    # Make sure eval doesn't consume too much of total time.\n    eval_time = now - eval_start\n    train_eval_rate = self.eval_interval / eval_time\n    if train_eval_rate < self.min_train_eval_rate and self.last_save > 0:\n      logging.info('Adjusting eval interval from %.2fs to %.2fs',\n                   self.eval_interval, self.min_train_eval_rate * eval_time)\n      self.eval_interval = self.min_train_eval_rate * eval_time\n\n    self.last_save = now\n    self.last_log = now\n\n  def save_summaries(self, session):\n    self.sv.summary_computed(session,\n                             session.run(self.summary_op), self.global_step)\n    self.sv.summary_writer.flush()\n"
  },
  {
    "path": "solutionbox/image_classification/mltoolbox/image/classification/_util.py",
    "content": "# Copyright 2017 Google Inc. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\n\"\"\"Reusable utility functions.\n\"\"\"\n\nimport collections\nimport multiprocessing\nimport os\n\nimport tensorflow as tf\nfrom tensorflow.python.lib.io import file_io\n\n\n_DEFAULT_CHECKPOINT_GSURL = 'gs://cloud-ml-data/img/flower_photos/inception_v3_2016_08_28.ckpt'\n\n\ndef is_in_IPython():\n  try:\n    import IPython # noqa\n    return True\n  except ImportError:\n    return False\n\n\ndef default_project():\n  from google.datalab import Context\n  return Context.default().project_id\n\n\ndef _get_latest_data_dir(input_dir):\n  latest_file = os.path.join(input_dir, 'latest')\n  if not file_io.file_exists(latest_file):\n    raise Exception(('Cannot find \"latest\" file in \"%s\". ' +\n                    'Please use a preprocessing output dir.') % input_dir)\n  with file_io.FileIO(latest_file, 'r') as f:\n    dir_name = f.read().rstrip()\n  return os.path.join(input_dir, dir_name)\n\n\ndef get_train_eval_files(input_dir):\n  \"\"\"Get preprocessed training and eval files.\"\"\"\n  data_dir = _get_latest_data_dir(input_dir)\n  train_pattern = os.path.join(data_dir, 'train*.tfrecord.gz')\n  eval_pattern = os.path.join(data_dir, 'eval*.tfrecord.gz')\n  train_files = file_io.get_matching_files(train_pattern)\n  eval_files = file_io.get_matching_files(eval_pattern)\n  return train_files, eval_files\n\n\ndef get_labels(input_dir):\n  \"\"\"Get a list of labels from preprocessed output dir.\"\"\"\n  data_dir = _get_latest_data_dir(input_dir)\n  labels_file = os.path.join(data_dir, 'labels')\n  with file_io.FileIO(labels_file, 'r') as f:\n    labels = f.read().rstrip().split('\\n')\n  return labels\n\n\ndef read_examples(input_files, batch_size, shuffle, num_epochs=None):\n  \"\"\"Creates readers and queues for reading example protos.\"\"\"\n  files = []\n  for e in input_files:\n    for path in e.split(','):\n      files.extend(file_io.get_matching_files(path))\n  thread_count = multiprocessing.cpu_count()\n\n  # The minimum number of instances in a queue from which examples are drawn\n  # randomly. The larger this number, the more randomness at the expense of\n  # higher memory requirements.\n  min_after_dequeue = 1000\n\n  # When batching data, the queue's capacity will be larger than the batch_size\n  # by some factor. The recommended formula is (num_threads + a small safety\n  # margin). For now, we use a single thread for reading, so this can be small.\n  queue_size_multiplier = thread_count + 3\n\n  # Convert num_epochs == 0 -> num_epochs is None, if necessary\n  num_epochs = num_epochs or None\n\n  # Build a queue of the filenames to be read.\n  filename_queue = tf.train.string_input_producer(files, num_epochs, shuffle)\n\n  options = tf.python_io.TFRecordOptions(\n      compression_type=tf.python_io.TFRecordCompressionType.GZIP)\n  example_id, encoded_example = tf.TFRecordReader(options=options).read_up_to(\n      filename_queue, batch_size)\n\n  if shuffle:\n    capacity = min_after_dequeue + queue_size_multiplier * batch_size\n    return tf.train.shuffle_batch(\n        [example_id, encoded_example],\n        batch_size,\n        capacity,\n        min_after_dequeue,\n        enqueue_many=True,\n        num_threads=thread_count)\n  else:\n    capacity = queue_size_multiplier * batch_size\n    return tf.train.batch(\n        [example_id, encoded_example],\n        batch_size,\n        capacity=capacity,\n        enqueue_many=True,\n        num_threads=thread_count)\n\n\ndef override_if_not_in_args(flag, argument, args):\n  \"\"\"Checks if flags is in args, and if not it adds the flag to args.\"\"\"\n  if flag not in args:\n    args.extend([flag, argument])\n\n\ndef loss(loss_value):\n  \"\"\"Calculates aggregated mean loss.\"\"\"\n  total_loss = tf.Variable(0.0, False)\n  loss_count = tf.Variable(0, False)\n  total_loss_update = tf.assign_add(total_loss, loss_value)\n  loss_count_update = tf.assign_add(loss_count, 1)\n  loss_op = total_loss / tf.cast(loss_count, tf.float32)\n  return [total_loss_update, loss_count_update], loss_op\n\n\ndef accuracy(logits, labels):\n  \"\"\"Calculates aggregated accuracy.\"\"\"\n  is_correct = tf.nn.in_top_k(logits, labels, 1)\n  correct = tf.reduce_sum(tf.cast(is_correct, tf.int32))\n  incorrect = tf.reduce_sum(tf.cast(tf.logical_not(is_correct), tf.int32))\n  correct_count = tf.Variable(0, False)\n  incorrect_count = tf.Variable(0, False)\n  correct_count_update = tf.assign_add(correct_count, correct)\n  incorrect_count_update = tf.assign_add(incorrect_count, incorrect)\n  accuracy_op = tf.cast(correct_count, tf.float32) / tf.cast(\n      correct_count + incorrect_count, tf.float32)\n  return [correct_count_update, incorrect_count_update], accuracy_op\n\n\ndef check_dataset(dataset, mode):\n  \"\"\"Validate we have a good dataset.\"\"\"\n\n  names = [x['name'] for x in dataset.schema]\n  types = [x['type'] for x in dataset.schema]\n  if mode == 'train':\n    if (set(['image_url', 'label']) != set(names) or any(t != 'STRING' for t in types)):\n      raise ValueError('Invalid dataset. Expect only \"image_url,label\" STRING columns.')\n  else:\n    if (set(['image_url']) != set(names) and set(['image_url', 'label']) != set(names)) or \\\n            any(t != 'STRING' for t in types):\n      raise ValueError('Invalid dataset. Expect only \"image_url\" or \"image_url,label\" ' +\n                       'STRING columns.')\n\n\ndef get_sources_from_dataset(p, dataset, mode):\n  \"\"\"get pcollection from dataset.\"\"\"\n\n  import apache_beam as beam\n  import csv\n  from google.datalab.ml import CsvDataSet, BigQueryDataSet\n\n  check_dataset(dataset, mode)\n  if type(dataset) is CsvDataSet:\n    source_list = []\n    for ii, input_path in enumerate(dataset.files):\n      source_list.append(p | 'Read from Csv %d (%s)' % (ii, mode) >>\n                         beam.io.ReadFromText(input_path, strip_trailing_newlines=True))\n    return (source_list |\n            'Flatten Sources (%s)' % mode >>\n            beam.Flatten() |\n            'Create Dict from Csv (%s)' % mode >>\n            beam.Map(lambda line: csv.DictReader([line], fieldnames=['image_url',\n                                                                     'label']).next()))\n  elif type(dataset) is BigQueryDataSet:\n    bq_source = (beam.io.BigQuerySource(table=dataset.table) if dataset.table is not None else\n                 beam.io.BigQuerySource(query=dataset.query))\n    return p | 'Read source from BigQuery (%s)' % mode >> beam.io.Read(bq_source)\n  else:\n    raise ValueError('Invalid DataSet. Expect CsvDataSet or BigQueryDataSet')\n\n\ndef decode_and_resize(image_str_tensor):\n  \"\"\"Decodes jpeg string, resizes it and returns a uint8 tensor.\"\"\"\n\n  # These constants are set by Inception v3's expectations.\n  height = 299\n  width = 299\n  channels = 3\n\n  image = tf.image.decode_jpeg(image_str_tensor, channels=channels)\n  # Note resize expects a batch_size, but tf_map supresses that index,\n  # thus we have to expand then squeeze.  Resize returns float32 in the\n  # range [0, uint8_max]\n  image = tf.expand_dims(image, 0)\n  image = tf.image.resize_bilinear(image, [height, width], align_corners=False)\n  image = tf.squeeze(image, squeeze_dims=[0])\n  image = tf.cast(image, dtype=tf.uint8)\n  return image\n\n\ndef resize_image(image_str_tensor):\n  \"\"\"Decodes jpeg string, resizes it and re-encode it to jpeg.\"\"\"\n\n  image = decode_and_resize(image_str_tensor)\n  image = tf.image.encode_jpeg(image, quality=100)\n  return image\n\n\ndef load_images(image_files, resize=True):\n  \"\"\"Load images from files and optionally resize it.\"\"\"\n\n  images = []\n  for image_file in image_files:\n    with file_io.FileIO(image_file, 'r') as ff:\n      images.append(ff.read())\n  if resize is False:\n    return images\n\n  # To resize, run a tf session so we can reuse 'decode_and_resize()'\n  # which is used in prediction graph. This makes sure we don't lose\n  # any quality in prediction, while decreasing the size of the images\n  # submitted to the model over network.\n  image_str_tensor = tf.placeholder(tf.string, shape=[None])\n  image = tf.map_fn(resize_image, image_str_tensor, back_prop=False)\n  feed_dict = collections.defaultdict(list)\n  feed_dict[image_str_tensor.name] = images\n  with tf.Session() as sess:\n    images_resized = sess.run(image, feed_dict=feed_dict)\n  return images_resized\n\n\ndef process_prediction_results(results, show_image):\n  \"\"\"Create DataFrames out of prediction results, and display images in IPython if requested.\"\"\"\n\n  import pandas as pd\n\n  if (is_in_IPython() and show_image is True):\n    import IPython\n    for image_url, image, label_and_score in results:\n      IPython.display.display_html('<p style=\"font-size:28px\">%s(%.5f)</p>' % label_and_score,\n                                   raw=True)\n      IPython.display.display(IPython.display.Image(data=image))\n  result_dict = [{'image_url': url, 'label': r[0], 'score': r[1]} for url, _, r in results]\n  return pd.DataFrame(result_dict)\n\n\ndef repackage_to_staging(output_path):\n  \"\"\"Repackage it from local installed location and copy it to GCS.\"\"\"\n\n  import google.datalab.ml as ml\n\n  # Find the package root. __file__ is under [package_root]/mltoolbox/image/classification.\n  package_root = os.path.join(os.path.dirname(__file__), '../../../')\n  # We deploy setup.py in the same dir for repackaging purpose.\n  setup_py = os.path.join(os.path.dirname(__file__), 'setup.py')\n  staging_package_url = os.path.join(output_path, 'staging', 'image_classification.tar.gz')\n  ml.package_and_copy(package_root, setup_py, staging_package_url)\n  return staging_package_url\n"
  },
  {
    "path": "solutionbox/image_classification/mltoolbox/image/classification/setup.py",
    "content": "# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n# To publish to PyPi use: python setup.py bdist_wheel upload -r pypi\n\nimport datetime\nfrom setuptools import setup\n\nminor = datetime.datetime.now().strftime(\"%y%m%d%H%M\")\nversion = '0.2'\n\nsetup(\n  name='mltoolbox_datalab_image_classification',\n  namespace_packages=['mltoolbox'],\n  version=version,\n  packages=[\n    'mltoolbox',\n    'mltoolbox.image',\n    'mltoolbox.image.classification',\n  ],\n\n  description='Google Cloud Datalab Inception Package',\n  author='Google',\n  author_email='google-cloud-datalab-feedback@googlegroups.com',\n  keywords=[\n  ],\n  license=\"Apache Software License\",\n  classifiers=[\n      \"Programming Language :: Python\",\n      \"Programming Language :: Python :: 2\",\n      \"Development Status :: 4 - Beta\",\n      \"Environment :: Other Environment\",\n      \"Intended Audience :: Developers\",\n      \"License :: OSI Approved :: Apache Software License\",\n      \"Operating System :: OS Independent\",\n      \"Topic :: Software Development :: Libraries :: Python Modules\"\n  ],\n  long_description=\"\"\"\n  \"\"\",\n  install_requires=[\n    'pillow==3.4.1',\n  ],\n  package_data={\n  }\n)\n"
  },
  {
    "path": "solutionbox/image_classification/mltoolbox/image/classification/task.py",
    "content": "# Copyright 2017 Google Inc. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\n\"\"\"Entry point for CloudML training.\n\n   CloudML training requires a tarball package and a python module to run. This file\n   provides such a \"main\" method and a list of args passed with the program.\n\"\"\"\n\nimport argparse\nimport json\nimport logging\nimport os\nimport tensorflow as tf\n\nfrom . import _model\nfrom . import _trainer\nfrom . import _util\n\n\ndef main(_):\n  parser = argparse.ArgumentParser()\n  parser.add_argument(\n      '--input_dir',\n      type=str,\n      help='The input dir path for training and evaluation data.')\n  parser.add_argument(\n      '--job-dir',\n      dest='job_dir',\n      type=str,\n      help='The GCS path to which checkpoints and other outputs should be saved.')\n  parser.add_argument(\n      '--max_steps',\n      type=int,)\n  parser.add_argument(\n      '--batch_size',\n      type=int,\n      help='Number of examples to be processed per mini-batch.')\n  parser.add_argument(\n      '--checkpoint',\n      type=str,\n      default=_util._DEFAULT_CHECKPOINT_GSURL,\n      help='Pretrained inception checkpoint path.')\n\n  args, _ = parser.parse_known_args()\n  labels = _util.get_labels(args.input_dir)\n  model = _model.Model(labels, 0.5, args.checkpoint)\n\n  env = json.loads(os.environ.get('TF_CONFIG', '{}'))\n  # Print the job data as provided by the service.\n  logging.info('Original job data: %s', env.get('job', {}))\n  task_data = env.get('task', None) or {'type': 'master', 'index': 0}\n  task = type('TaskSpec', (object,), task_data)\n\n  cluster_data = env.get('cluster', None)\n  cluster = tf.train.ClusterSpec(cluster_data) if cluster_data else None\n  if not cluster or not task or task.type == 'master' or task.type == 'worker':\n     _trainer.Trainer(args.input_dir, args.batch_size, args.max_steps,\n                      args.job_dir, model, cluster, task).run_training()\n  elif task.type == 'ps':\n     server = _trainer.start_server(cluster, task)\n     server.join()\n  else:\n    raise ValueError('invalid task_type %s' % (task.type,))\n\n\nif __name__ == '__main__':\n  logging.basicConfig(level=logging.INFO)\n  tf.app.run()\n"
  },
  {
    "path": "solutionbox/image_classification/setup.py",
    "content": "# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n# To publish to PyPi use: python setup.py bdist_wheel upload -r pypi\n\nimport datetime\nfrom setuptools import setup\n\nminor = datetime.datetime.now().strftime(\"%y%m%d%H%M\")\nversion = '0.2'\n\nsetup(\n  name='mltoolbox_datalab_image_classification',\n  namespace_packages=['mltoolbox'],\n  version=version,\n  packages=[\n    'mltoolbox',\n    'mltoolbox.image',\n    'mltoolbox.image.classification',\n  ],\n\n  description='Google Cloud Datalab Inception Package',\n  author='Google',\n  author_email='google-cloud-datalab-feedback@googlegroups.com',\n  keywords=[\n  ],\n  license=\"Apache Software License\",\n  classifiers=[\n      \"Programming Language :: Python\",\n      \"Programming Language :: Python :: 2\",\n      \"Development Status :: 4 - Beta\",\n      \"Environment :: Other Environment\",\n      \"Intended Audience :: Developers\",\n      \"License :: OSI Approved :: Apache Software License\",\n      \"Operating System :: OS Independent\",\n      \"Topic :: Software Development :: Libraries :: Python Modules\"\n  ],\n  long_description=\"\"\"\n  \"\"\",\n  install_requires=[\n    'pillow==6.2.0',\n  ],\n  package_data={\n  }\n)\n"
  },
  {
    "path": "solutionbox/ml_workbench/setup.py",
    "content": "# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom setuptools import setup\n\n\nsetup(\n  name='mltoolbox_code_free',\n  namespace_packages=['mltoolbox'],\n  version='1.0.0',\n  packages=[\n    'mltoolbox',\n    'mltoolbox.code_free_ml',\n    'mltoolbox.code_free_ml.trainer',\n  ],\n  description='Google Cloud Datalab Structured Data Package',\n  author='Google',\n  author_email='google-cloud-datalab-feedback@googlegroups.com',\n  keywords=[\n  ],\n  license=\"Apache Software License\",\n  classifiers=[\n      \"Programming Language :: Python\",\n      \"Programming Language :: Python :: 2\",\n      \"Development Status :: 4 - Beta\",\n      \"Environment :: Other Environment\",\n      \"Intended Audience :: Developers\",\n      \"License :: OSI Approved :: Apache Software License\",\n      \"Operating System :: OS Independent\",\n      \"Topic :: Software Development :: Libraries :: Python Modules\"\n  ],\n  long_description=\"\"\"\n  \"\"\",\n  install_requires=[  # TODO(brandondutra): fill this in. Add pydatalab?\n  ],\n  package_data={\n  },\n  data_files=[],\n)\n"
  },
  {
    "path": "solutionbox/ml_workbench/tensorflow/__init__.py",
    "content": ""
  },
  {
    "path": "solutionbox/ml_workbench/tensorflow/analyze.py",
    "content": "# Copyright 2017 Google Inc. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport argparse\nimport copy\nimport json\nimport os\nimport sys\nimport six\nimport textwrap\nfrom tensorflow.python.lib.io import file_io\n\nfrom trainer import feature_transforms as constant\nfrom trainer import feature_analysis as feature_analysis\n\n\ndef parse_arguments(argv):\n  \"\"\"Parse command line arguments.\n\n  Args:\n    argv: list of command line arguments, including program name.\n\n  Returns:\n    An argparse Namespace object.\n\n  Raises:\n    ValueError: for bad parameters\n  \"\"\"\n  parser = argparse.ArgumentParser(\n      formatter_class=argparse.RawDescriptionHelpFormatter,\n      description=textwrap.dedent(\"\"\"\\\n          Runs analysis on structured data and produces auxiliary files for\n          training. The output files can also be used by the Transform step\n          to materialize TF.Examples files, which for some problems can speed up\n          training.\n\n          Description of input files\n          --------------------------\n\n          1) If using csv files, the --schema parameter must be the file path to\n             a schema file. The format of this file must be a valid BigQuery\n             schema file, which is a JSON file containing a list of dicts.\n             Consider the example schema file below:\n\n             [\n                {\"name\": \"column_name_1\", \"type\": \"integer\"},\n                {\"name\": \"column_name_2\", \"type\": \"float\"},\n                {\"name\": \"column_name_3\", \"type\": \"string\"},\n                {\"name\": \"column_name_4\", \"type\": \"string\"},\n             ]\n\n             Note that the column names in the csv file much match the order\n             in the schema list. Also, we only support three BigQuery types (\n             integer, float, and string).\n\n             If instead of csv files, --bigquery is used, the schema file\n             is not needed as this program will extract it from\n             the table directly.\n\n          2) --features is a file path to a file describing the\n             transformations. Below is an example features file:\n\n             {\n                \"column_name_1\": {\"transform\": \"scale\"},\n                \"column_name_3\": {\"transform\": \"target\"},\n                \"column_name_2\": {\"transform\": \"one_hot\"},\n                \"new_feature_name\": {\"transform\": \"key\", \"source_column\": \"column_name_4\"},\n             }\n\n             The format of the dict is `name`: `transform-dict` where the\n             `name` is the name of the transformed feature. The `source_column`\n             value lists what column in the input data is the source for this\n             transformation. If `source_column` is missing, it is assumed the\n             `name` is a source column and the transformed feature will have\n             the same name as the input column.\n\n             A list of supported `transform-dict`s is below:\n\n             {\"transform\": \"identity\"}: does nothing (for numerical columns).\n             {\"transform\": \"scale\", \"value\": x}: scale a numerical column to\n                [-a, a]. If value is missing, x defaults to 1.\n             {\"transform\": \"one_hot\"}: makes a one-hot encoding of a string\n                column.\n             {\"transform\": \"embedding\", \"embedding_dim\": d}: makes an embedding\n                of a string column.\n             {\"transform\": \"multi_hot\", \"separator\": ' '}: makes a multi-hot\n                encoding of a string column.\n             {\"transform\": \"bag_of_words\"}: bag of words transform for string\n                columns.\n             {\"transform\": \"tfidf\"}: TFIDF transform for string columns.\n             {\"transform\": \"image_to_vec\", \"checkpoint\": \"gs://b/o\"}: From image\n                gs url to embeddings. \"checkpoint\" is a inception v3 checkpoint.\n                If absent, a default checkpoint is used.\n             {\"transform\": \"target\"}: denotes what column is the target. If the\n                schema type of this column is string, a one_hot encoding is\n                automatically applied. If type is numerical, a identity transform\n                is automatically applied.\n             {\"transform\": \"key\"}: column contains metadata-like information\n                and is not included in the model.\n\n             Note that for tfidf and bag_of_words, the input string is assumed\n             to contain text separated by a space. So for example, the string\n             \"a, b c.\" has three tokens 'a,', 'b', and 'c.'.\n  \"\"\"))\n  parser.add_argument('--cloud',\n                      action='store_true',\n                      help='Analysis will use cloud services.')\n  parser.add_argument('--output',\n                      metavar='DIR',\n                      type=str,\n                      required=True,\n                      help='GCS or local folder')\n\n  input_group = parser.add_argument_group(\n      title='Data Source Parameters',\n      description='schema is only needed if using --csv')\n\n  # CSV input\n  input_group.add_argument('--csv',\n                           metavar='FILE',\n                           type=str,\n                           required=False,\n                           action='append',\n                           help='Input CSV absolute file paths. May contain a '\n                                'file pattern.')\n  input_group.add_argument('--schema',\n                           metavar='FILE',\n                           type=str,\n                           required=False,\n                           help='Schema file path. Only required if using csv files')\n\n  # Bigquery input\n  input_group.add_argument('--bigquery',\n                           metavar='PROJECT_ID.DATASET.TABLE_NAME',\n                           type=str,\n                           required=False,\n                           help=('Must be in the form project.dataset.table_name'))\n\n  parser.add_argument('--features',\n                      metavar='FILE',\n                      type=str,\n                      required=True,\n                      help='Features file path')\n\n  args = parser.parse_args(args=argv[1:])\n\n  if args.cloud:\n    if not args.output.startswith('gs://'):\n      raise ValueError('--output must point to a location on GCS')\n    if (args.csv and\n       not all(x.startswith('gs://') for x in args.csv)):\n      raise ValueError('--csv must point to a location on GCS')\n    if args.schema and not args.schema.startswith('gs://'):\n      raise ValueError('--schema must point to a location on GCS')\n\n  if not args.cloud and args.bigquery:\n    raise ValueError('--bigquery must be used with --cloud')\n\n  if not ((args.bigquery and args.csv is None and\n           args.schema is None) or\n          (args.bigquery is None and args.csv and\n           args.schema)):\n    raise ValueError('either --csv and --schema must both'\n                     ' be set or just --bigquery is set')\n\n  return args\n\n\ndef run_cloud_analysis(output_dir, csv_file_pattern, bigquery_table, schema,\n                       features):\n  \"\"\"Use BigQuery to analyze input date.\n\n  Only one of csv_file_pattern or bigquery_table should be non-None.\n\n  Args:\n    output_dir: output folder\n    csv_file_pattern: list of csv file paths, may contain wildcards\n    bigquery_table: project_id.dataset_name.table_name\n    schema: schema list\n    features: features config\n  \"\"\"\n\n  def _execute_sql(sql, table):\n    \"\"\"Runs a BigQuery job and dowloads the results into local memeory.\n\n    Args:\n      sql: a SQL string\n      table: bq.ExternalDataSource or bq.Table\n\n    Returns:\n      A Pandas dataframe.\n    \"\"\"\n    import google.datalab.bigquery as bq\n    if isinstance(table, bq.ExternalDataSource):\n      query = bq.Query(sql, data_sources={'csv_table': table})\n    else:\n      query = bq.Query(sql)\n    return query.execute().result().to_dataframe()\n\n  feature_analysis.expand_defaults(schema, features)  # features are updated.\n  inverted_features = feature_analysis.invert_features(features)\n  feature_analysis.check_schema_transforms_match(schema, inverted_features)\n\n  import google.datalab.bigquery as bq\n  if bigquery_table:\n    table_name = '`%s`' % bigquery_table\n    table = None\n  else:\n    table_name = 'csv_table'\n    table = bq.ExternalDataSource(\n        source=csv_file_pattern,\n        schema=bq.Schema(schema))\n\n  # Make a copy of inverted_features and update the target transform to be\n  # identity or one hot depending on the schema.\n  inverted_features_target = copy.deepcopy(inverted_features)\n  for name, transforms in six.iteritems(inverted_features_target):\n    transform_set = {x['transform'] for x in transforms}\n    if transform_set == set([constant.TARGET_TRANSFORM]):\n      target_schema = next(col['type'].lower() for col in schema if col['name'] == name)\n      if target_schema in constant.NUMERIC_SCHEMA:\n        inverted_features_target[name] = [{'transform': constant.IDENTITY_TRANSFORM}]\n      else:\n        inverted_features_target[name] = [{'transform': constant.ONE_HOT_TRANSFORM}]\n\n  numerical_vocab_stats = {}\n  for col_name, transform_set in six.iteritems(inverted_features_target):\n    sys.stdout.write('Analyzing column %s...\\n' % col_name)\n    sys.stdout.flush()\n    # All transforms in transform_set require the same analysis. So look\n    # at the first transform.\n    transform = next(iter(transform_set))\n    if (transform['transform'] in constant.CATEGORICAL_TRANSFORMS or\n       transform['transform'] in constant.TEXT_TRANSFORMS):\n      if transform['transform'] in constant.TEXT_TRANSFORMS:\n        # Split strings on space, then extract labels and how many rows each\n        # token is in. This is done by making two temp tables:\n        #   SplitTable: each text row is made into an array of strings. The\n        #       array may contain repeat tokens\n        #   TokenTable: SplitTable with repeated tokens removed per row.\n        # Then to flatten the arrays, TokenTable has to be joined with itself.\n        # See the sections 'Flattening Arrays' and 'Filtering Arrays' at\n        # https://cloud.google.com/bigquery/docs/reference/standard-sql/arrays\n        separator = transform.get('separator', ' ')\n        sql = ('WITH SplitTable AS '\n               '         (SELECT SPLIT({name}, \\'{separator}\\') as token_array FROM {table}), '\n               '     TokenTable AS '\n               '         (SELECT ARRAY(SELECT DISTINCT x '\n               '                       FROM UNNEST(token_array) AS x) AS unique_tokens_per_row '\n               '          FROM SplitTable) '\n               'SELECT token, COUNT(token) as token_count '\n               'FROM TokenTable '\n               'CROSS JOIN UNNEST(TokenTable.unique_tokens_per_row) as token '\n               'WHERE LENGTH(token) > 0 '\n               'GROUP BY token '\n               'ORDER BY token_count DESC, token ASC').format(separator=separator,\n                                                              name=col_name,\n                                                              table=table_name)\n      else:\n        # Extract label and frequency\n        sql = ('SELECT {name} as token, count(*) as count '\n               'FROM {table} '\n               'WHERE {name} IS NOT NULL '\n               'GROUP BY {name} '\n               'ORDER BY count DESC, token ASC').format(name=col_name,\n                                                        table=table_name)\n\n      df = _execute_sql(sql, table)\n\n      # Save the vocab\n      csv_string = df.to_csv(index=False, header=False)\n      file_io.write_string_to_file(\n          os.path.join(output_dir, constant.VOCAB_ANALYSIS_FILE % col_name),\n          csv_string)\n      numerical_vocab_stats[col_name] = {'vocab_size': len(df)}\n\n      # free memeory\n      del csv_string\n      del df\n    elif transform['transform'] in constant.NUMERIC_TRANSFORMS:\n      # get min/max/average\n      sql = ('SELECT max({name}) as max_value, min({name}) as min_value, '\n             'avg({name}) as avg_value from {table}').format(name=col_name,\n                                                             table=table_name)\n      df = _execute_sql(sql, table)\n      numerical_vocab_stats[col_name] = {'min': df.iloc[0]['min_value'],\n                                         'max': df.iloc[0]['max_value'],\n                                         'mean': df.iloc[0]['avg_value']}\n    sys.stdout.write('column %s analyzed.\\n' % col_name)\n    sys.stdout.flush()\n\n  # get num examples\n  sql = 'SELECT count(*) as num_examples from {table}'.format(table=table_name)\n  df = _execute_sql(sql, table)\n  num_examples = df.iloc[0]['num_examples']\n\n  # Write the stats file.\n  stats = {'column_stats': numerical_vocab_stats, 'num_examples': num_examples}\n  file_io.write_string_to_file(\n      os.path.join(output_dir, constant.STATS_FILE),\n      json.dumps(stats, indent=2, separators=(',', ': ')))\n\n  feature_analysis.save_schema_features(schema, features, output_dir)\n\n\ndef main(argv=None):\n  args = parse_arguments(sys.argv if argv is None else argv)\n\n  if args.schema:\n    schema = json.loads(\n        file_io.read_file_to_string(args.schema).decode())\n  else:\n    import google.datalab.bigquery as bq\n    schema = bq.Table(args.bigquery).schema._bq_schema\n  features = json.loads(\n      file_io.read_file_to_string(args.features).decode())\n\n  file_io.recursive_create_dir(args.output)\n\n  if args.cloud:\n    run_cloud_analysis(\n        output_dir=args.output,\n        csv_file_pattern=args.csv,\n        bigquery_table=args.bigquery,\n        schema=schema,\n        features=features)\n  else:\n    feature_analysis.run_local_analysis(\n        output_dir=args.output,\n        csv_file_pattern=args.csv,\n        schema=schema,\n        features=features)\n\n\nif __name__ == '__main__':\n  main()\n"
  },
  {
    "path": "solutionbox/ml_workbench/tensorflow/setup.py",
    "content": "# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n# This setup file is used when running cloud training or cloud dataflow jobs.\nfrom setuptools import setup, find_packages\n\n\nsetup(\n  name='trainer',\n  version='1.0.0',\n  packages=find_packages(),\n  description='Google Cloud Datalab helper sub-package',\n  author='Google',\n  author_email='google-cloud-datalab-feedback@googlegroups.com',\n  keywords=[\n  ],\n  license=\"Apache Software License\",\n  long_description=\"\"\"\n  \"\"\",\n  install_requires=[\n    'tensorflow==1.15.2',\n    'protobuf==3.1.0',\n    'pillow==6.2.0',  # ML Engine does not have PIL installed\n  ],\n  package_data={\n  },\n  data_files=[],\n)\n"
  },
  {
    "path": "solutionbox/ml_workbench/tensorflow/trainer/__init__.py",
    "content": ""
  },
  {
    "path": "solutionbox/ml_workbench/tensorflow/trainer/feature_analysis.py",
    "content": "# Copyright 2017 Google Inc. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport collections\nimport copy\nimport csv\nimport json\nimport os\nimport pandas as pd\nimport sys\nimport six\nfrom tensorflow.python.lib.io import file_io\n\nfrom . import feature_transforms as constant\n\n\ndef check_schema_transforms_match(schema, inverted_features):\n  \"\"\"Checks that the transform and schema do not conflict.\n\n  Args:\n    schema: schema list\n    inverted_features: inverted_features dict\n\n  Raises:\n    ValueError if transform cannot be applied given schema type.\n  \"\"\"\n  num_target_transforms = 0\n\n  for col_schema in schema:\n    col_name = col_schema['name']\n    col_type = col_schema['type'].lower()\n\n    # Check each transform and schema are compatible\n    if col_name in inverted_features:\n      for transform in inverted_features[col_name]:\n        transform_name = transform['transform']\n        if transform_name == constant.TARGET_TRANSFORM:\n          num_target_transforms += 1\n          continue\n\n        elif col_type in constant.NUMERIC_SCHEMA:\n          if transform_name not in constant.NUMERIC_TRANSFORMS:\n            raise ValueError(\n                'Transform %s not supported by schema %s' % (transform_name, col_type))\n        elif col_type == constant.STRING_SCHEMA:\n          if (transform_name not in constant.CATEGORICAL_TRANSFORMS + constant.TEXT_TRANSFORMS and\n             transform_name != constant.IMAGE_TRANSFORM):\n            raise ValueError(\n                'Transform %s not supported by schema %s' % (transform_name, col_type))\n        else:\n          raise ValueError('Unsupported schema type %s' % col_type)\n\n    # Check each transform is compatible for the same source column.\n    # inverted_features[col_name] should belong to exactly 1 of the 5 groups.\n    if col_name in inverted_features:\n      transform_set = {x['transform'] for x in inverted_features[col_name]}\n      if 1 != sum([transform_set.issubset(set(constant.NUMERIC_TRANSFORMS)),\n                   transform_set.issubset(set(constant.CATEGORICAL_TRANSFORMS)),\n                   transform_set.issubset(set(constant.TEXT_TRANSFORMS)),\n                   transform_set.issubset(set([constant.IMAGE_TRANSFORM])),\n                   transform_set.issubset(set([constant.TARGET_TRANSFORM]))]):\n        message = \"\"\"\n          The source column of a feature can only be used in multiple\n          features within the same family of transforms. The familes are\n\n          1) text transformations: %s\n          2) categorical transformations: %s\n          3) numerical transformations: %s\n          4) image transformations: %s\n          5) target transform: %s\n\n          Any column can also be a key column.\n\n          But column %s is used by transforms %s.\n          \"\"\" % (str(constant.TEXT_TRANSFORMS),\n                 str(constant.CATEGORICAL_TRANSFORMS),\n                 str(constant.NUMERIC_TRANSFORMS),\n                 constant.IMAGE_TRANSFORM,\n                 constant.TARGET_TRANSFORM,\n                 col_name,\n                 str(transform_set))\n        raise ValueError(message)\n\n  if num_target_transforms != 1:\n    raise ValueError('Must have exactly one target transform')\n\n\ndef save_schema_features(schema, features, output):\n  # Save a copy of the schema and features in the output folder.\n  file_io.write_string_to_file(\n    os.path.join(output, constant.SCHEMA_FILE),\n    json.dumps(schema, indent=2))\n\n  file_io.write_string_to_file(\n    os.path.join(output, constant.FEATURES_FILE),\n    json.dumps(features, indent=2))\n\n\ndef expand_defaults(schema, features):\n  \"\"\"Add to features any default transformations.\n\n  Not every column in the schema has an explicit feature transformation listed\n  in the featurs file. For these columns, add a default transformation based on\n  the schema's type. The features dict is modified by this function call.\n\n  After this function call, every column in schema is used in a feature, and\n  every feature uses a column in the schema.\n\n  Args:\n    schema: schema list\n    features: features dict\n\n  Raises:\n    ValueError: if transform cannot be applied given schema type.\n  \"\"\"\n\n  schema_names = [x['name'] for x in schema]\n\n  # Add missing source columns\n  for name, transform in six.iteritems(features):\n    if 'source_column' not in transform:\n      transform['source_column'] = name\n\n  # Check source columns are in the schema and collect which are used.\n  used_schema_columns = []\n  for name, transform in six.iteritems(features):\n    if transform['source_column'] not in schema_names:\n      raise ValueError('source column %s is not in the schema for transform %s'\n                       % (transform['source_column'], name))\n    used_schema_columns.append(transform['source_column'])\n\n  # Update default transformation based on schema.\n  for col_schema in schema:\n    schema_name = col_schema['name']\n    schema_type = col_schema['type'].lower()\n\n    if schema_type not in constant.NUMERIC_SCHEMA + [constant.STRING_SCHEMA]:\n      raise ValueError(('Only the following schema types are supported: %s'\n                        % ' '.join(constant.NUMERIC_SCHEMA + [constant.STRING_SCHEMA])))\n\n    if schema_name not in used_schema_columns:\n      # add the default transform to the features\n      if schema_type in constant.NUMERIC_SCHEMA:\n        features[schema_name] = {\n            'transform': constant.DEFAULT_NUMERIC_TRANSFORM,\n            'source_column': schema_name}\n      elif schema_type == constant.STRING_SCHEMA:\n        features[schema_name] = {\n            'transform': constant.DEFAULT_CATEGORICAL_TRANSFORM,\n            'source_column': schema_name}\n      else:\n        raise NotImplementedError('Unknown type %s' % schema_type)\n\n\n# TODO(brandondutra): introduce the notion an analysis plan/classes if we\n# support more complicated transforms like binning by quratiles.\ndef invert_features(features):\n  \"\"\"Make a dict in the form source column : set of transforms.\n\n  Note that the key transform is removed.\n  \"\"\"\n  inverted_features = collections.defaultdict(list)\n  for transform in six.itervalues(features):\n    source_column = transform['source_column']\n    if transform['transform'] == constant.KEY_TRANSFORM:\n      continue\n    inverted_features[source_column].append(transform)\n\n  return dict(inverted_features)  # convert from defaultdict to dict\n\n\ndef run_local_analysis(output_dir, csv_file_pattern, schema, features):\n  \"\"\"Use pandas to analyze csv files.\n\n  Produces a stats file and vocab files.\n\n  Args:\n    output_dir: output folder\n    csv_file_pattern: list of csv file paths, may contain wildcards\n    schema: CSV schema list\n    features: features config\n\n  Raises:\n    ValueError: on unknown transfrorms/schemas\n  \"\"\"\n  sys.stdout.write('Expanding any file patterns...\\n')\n  sys.stdout.flush()\n  header = [column['name'] for column in schema]\n  input_files = []\n  for file_pattern in csv_file_pattern:\n    input_files.extend(file_io.get_matching_files(file_pattern))\n  sys.stdout.write('file list computed.\\n')\n  sys.stdout.flush()\n\n  expand_defaults(schema, features)  # features are updated.\n  inverted_features = invert_features(features)\n  check_schema_transforms_match(schema, inverted_features)\n\n  # Make a copy of inverted_features and update the target transform to be\n  # identity or one hot depending on the schema.\n  inverted_features_target = copy.deepcopy(inverted_features)\n  for name, transforms in six.iteritems(inverted_features_target):\n    transform_set = {x['transform'] for x in transforms}\n    if transform_set == set([constant.TARGET_TRANSFORM]):\n      target_schema = next(col['type'].lower() for col in schema if col['name'] == name)\n      if target_schema in constant.NUMERIC_SCHEMA:\n        inverted_features_target[name] = [{'transform': constant.IDENTITY_TRANSFORM}]\n      else:\n        inverted_features_target[name] = [{'transform': constant.ONE_HOT_TRANSFORM}]\n\n  # initialize the results\n  def _init_numerical_results():\n    return {'min': float('inf'),\n            'max': float('-inf'),\n            'count': 0,\n            'sum': 0.0}\n  numerical_results = collections.defaultdict(_init_numerical_results)\n  vocabs = collections.defaultdict(lambda: collections.defaultdict(int))\n\n  num_examples = 0\n  # for each file, update the numerical stats from that file, and update the set\n  # of unique labels.\n  for input_file in input_files:\n    sys.stdout.write('Analyzing file %s...\\n' % input_file)\n    sys.stdout.flush()\n    with file_io.FileIO(input_file, 'r') as f:\n      for line in csv.reader(f):\n        if len(header) != len(line):\n          raise ValueError('Schema has %d columns but a csv line only has %d columns.' %\n                           (len(header), len(line)))\n        parsed_line = dict(zip(header, line))\n        num_examples += 1\n\n        for col_name, transform_set in six.iteritems(inverted_features_target):\n          # All transforms in transform_set require the same analysis. So look\n          # at the first transform.\n          transform = next(iter(transform_set))\n          if transform['transform'] in constant.TEXT_TRANSFORMS:\n            separator = transform.get('separator', ' ')\n            split_strings = parsed_line[col_name].split(separator)\n\n            # If a label is in the row N times, increase it's vocab count by 1.\n            # This is needed for TFIDF, but it's also an interesting stat.\n            for one_label in set(split_strings):\n              # Filter out empty strings\n              if one_label:\n                vocabs[col_name][one_label] += 1\n          elif transform['transform'] in constant.CATEGORICAL_TRANSFORMS:\n            if parsed_line[col_name]:\n              vocabs[col_name][parsed_line[col_name]] += 1\n          elif transform['transform'] in constant.NUMERIC_TRANSFORMS:\n            if not parsed_line[col_name].strip():\n              continue\n\n            numerical_results[col_name]['min'] = (\n              min(numerical_results[col_name]['min'],\n                  float(parsed_line[col_name])))\n            numerical_results[col_name]['max'] = (\n              max(numerical_results[col_name]['max'],\n                  float(parsed_line[col_name])))\n            numerical_results[col_name]['count'] += 1\n            numerical_results[col_name]['sum'] += float(parsed_line[col_name])\n\n    sys.stdout.write('file %s analyzed.\\n' % input_file)\n    sys.stdout.flush()\n\n  # Write the vocab files. Each label is on its own line.\n  vocab_sizes = {}\n  for name, label_count in six.iteritems(vocabs):\n    # df is now:\n    # label1,count\n    # label2,count\n    # ...\n    # where label1 is the most frequent label, and label2 is the 2nd most, etc.\n    df = pd.DataFrame([{'label': label, 'count': count}\n                       for label, count in sorted(six.iteritems(label_count),\n                                                  key=lambda x: x[1],\n                                                  reverse=True)],\n                      columns=['label', 'count'])\n    csv_string = df.to_csv(index=False, header=False)\n\n    file_io.write_string_to_file(\n        os.path.join(output_dir, constant.VOCAB_ANALYSIS_FILE % name),\n        csv_string)\n\n    vocab_sizes[name] = {'vocab_size': len(label_count)}\n\n  # Update numerical_results to just have min/min/mean\n  for col_name in numerical_results:\n    if float(numerical_results[col_name]['count']) == 0:\n      raise ValueError('Column %s has a zero count' % col_name)\n    mean = (numerical_results[col_name]['sum'] /\n            float(numerical_results[col_name]['count']))\n    del numerical_results[col_name]['sum']\n    del numerical_results[col_name]['count']\n    numerical_results[col_name]['mean'] = mean\n\n  # Write the stats file.\n  numerical_results.update(vocab_sizes)\n  stats = {'column_stats': numerical_results, 'num_examples': num_examples}\n  file_io.write_string_to_file(\n      os.path.join(output_dir, constant.STATS_FILE),\n      json.dumps(stats, indent=2, separators=(',', ': ')))\n\n  save_schema_features(schema, features, output_dir)\n"
  },
  {
    "path": "solutionbox/ml_workbench/tensorflow/trainer/feature_transforms.py",
    "content": "from __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport base64\nimport collections\nimport cStringIO\nimport json\nimport os\nfrom PIL import Image\nimport pandas as pd\nimport six\nimport shutil\nimport tensorflow as tf\nimport tempfile\n\n\nfrom tensorflow.contrib.learn.python.learn.utils import input_fn_utils\n\nfrom tensorflow.contrib import lookup\nfrom tensorflow.contrib.slim.python.slim.nets.inception_v3 import inception_v3\nfrom tensorflow.contrib.slim.python.slim.nets.inception_v3 import inception_v3_arg_scope\nfrom tensorflow.python.lib.io import file_io\n\n# ------------------------------------------------------------------------------\n# public constants. Changing these could break user's code\n# ------------------------------------------------------------------------------\n\n# Individual transforms\nIDENTITY_TRANSFORM = 'identity'\nSCALE_TRANSFORM = 'scale'\nONE_HOT_TRANSFORM = 'one_hot'\nEMBEDDING_TRANSFROM = 'embedding'\nMULTI_HOT_TRANSFORM = 'multi_hot'\nBOW_TRANSFORM = 'bag_of_words'\nTFIDF_TRANSFORM = 'tfidf'\nKEY_TRANSFORM = 'key'\nTARGET_TRANSFORM = 'target'\nIMAGE_TRANSFORM = 'image_to_vec'\n\n# ------------------------------------------------------------------------------\n# internal constants.\n# ------------------------------------------------------------------------------\n\n# Files\nSCHEMA_FILE = 'schema.json'\nFEATURES_FILE = 'features.json'\nSTATS_FILE = 'stats.json'\nVOCAB_ANALYSIS_FILE = 'vocab_%s.csv'\n\n# Transform collections\nNUMERIC_TRANSFORMS = [IDENTITY_TRANSFORM, SCALE_TRANSFORM]\nCATEGORICAL_TRANSFORMS = [ONE_HOT_TRANSFORM, EMBEDDING_TRANSFROM]\nTEXT_TRANSFORMS = [MULTI_HOT_TRANSFORM, BOW_TRANSFORM, TFIDF_TRANSFORM]\n\n# If the features file is missing transforms, apply these.\nDEFAULT_NUMERIC_TRANSFORM = IDENTITY_TRANSFORM\nDEFAULT_CATEGORICAL_TRANSFORM = ONE_HOT_TRANSFORM\n\n# BigQuery Schema values supported\nINTEGER_SCHEMA = 'integer'\nFLOAT_SCHEMA = 'float'\nSTRING_SCHEMA = 'string'\nNUMERIC_SCHEMA = [INTEGER_SCHEMA, FLOAT_SCHEMA]\n\n# Inception Checkpoint\nINCEPTION_V3_CHECKPOINT = 'gs://cloud-ml-data/img/flower_photos/inception_v3_2016_08_28.ckpt'\nINCEPTION_EXCLUDED_VARIABLES = ['InceptionV3/AuxLogits', 'InceptionV3/Logits', 'global_step']\n\n_img_buf = cStringIO.StringIO()\nImage.new('RGB', (16, 16)).save(_img_buf, 'jpeg')\nIMAGE_DEFAULT_STRING = base64.urlsafe_b64encode(_img_buf.getvalue())\n\nIMAGE_BOTTLENECK_TENSOR_SIZE = 2048\nIMAGE_HIDDEN_TENSOR_SIZE = int(IMAGE_BOTTLENECK_TENSOR_SIZE / 4)\n\n# ------------------------------------------------------------------------------\n# ------------------------------------------------------------------------------\n# start of transform functions\n# ------------------------------------------------------------------------------\n# ------------------------------------------------------------------------------\n\n\ndef _scale(x, min_x_value, max_x_value, output_min, output_max):\n  \"\"\"Scale a column to [output_min, output_max].\n\n  Assumes the columns's range is [min_x_value, max_x_value]. If this is not\n  true at training or prediction time, the output value of this scale could be\n  outside the range [output_min, output_max].\n\n  Raises:\n    ValueError: if min_x_value = max_x_value, as the column is constant.\n  \"\"\"\n\n  if round(min_x_value - max_x_value, 7) == 0:\n    # There is something wrong with the data.\n    # Why round to 7 places? It's the same as unittest's assertAlmostEqual.\n    raise ValueError('In make_scale_tito, min_x_value == max_x_value')\n\n  def _scale(x):\n    min_x_valuef = tf.to_float(min_x_value)\n    max_x_valuef = tf.to_float(max_x_value)\n    output_minf = tf.to_float(output_min)\n    output_maxf = tf.to_float(output_max)\n    return ((((tf.to_float(x) - min_x_valuef) * (output_maxf - output_minf)) /\n            (max_x_valuef - min_x_valuef)) + output_minf)\n\n  return _scale(x)\n\n\ndef _string_to_int(x, vocab):\n  \"\"\"Given a vocabulary and a string tensor `x`, maps `x` into an int tensor.\n  Args:\n    x: A `Column` representing a string value.\n    vocab: list of strings.\n\n  Returns:\n    A `Column` where each string value is mapped to an integer representing\n    its index in the vocab. Out of vocab values are mapped to len(vocab).\n  \"\"\"\n\n  def _map_to_int(x):\n    \"\"\"Maps string tensor into indexes using vocab.\n\n    Args:\n      x : a Tensor/SparseTensor of string.\n    Returns:\n      a Tensor/SparseTensor of indexes (int) of the same shape as x.\n    \"\"\"\n    table = lookup.index_table_from_tensor(\n        vocab,\n        default_value=len(vocab))\n    return table.lookup(x)\n\n  return _map_to_int(x)\n\n\n# TODO(brandondura): update this to not depend on tf layer's feature column\n# 'sum' combiner in the future.\ndef _tfidf(x, reduced_term_freq, vocab_size, corpus_size):\n  \"\"\"Maps the terms in x to their (1/doc_length) * inverse document frequency.\n  Args:\n    x: A `Column` representing int64 values (most likely that are the result\n        of calling string_to_int on a tokenized string).\n    reduced_term_freq: A dense tensor of shape (vocab_size,) that represents\n        the count of the number of documents with each term. So vocab token i (\n        which is an int) occures in reduced_term_freq[i] examples in the corpus.\n        This means reduced_term_freq should have a count for out-of-vocab tokens\n    vocab_size: An int - the count of vocab used to turn the string into int64s\n        including any out-of-vocab ids\n    corpus_size: A scalar count of the number of documents in the corpus\n  Returns:\n    A `Column` where each int value is mapped to a double equal to\n    (1 if that term appears in that row, 0 otherwise / the number of terms in\n    that row) * the log of (the number of rows in `x` / (1 + the number of\n    rows in `x` where the term appears at least once))\n  NOTE:\n    This is intented to be used with the feature_column 'sum' combiner to arrive\n    at the true term frequncies.\n  \"\"\"\n\n  def _map_to_vocab_range(x):\n    \"\"\"Enforces that the vocab_ids in x are positive.\"\"\"\n    return tf.SparseTensor(\n        indices=x.indices,\n        values=tf.mod(x.values, vocab_size),\n        dense_shape=x.dense_shape)\n\n  def _map_to_tfidf(x):\n    \"\"\"Calculates the inverse document frequency of terms in the corpus.\n    Args:\n      x : a SparseTensor of int64 representing string indices in vocab.\n    Returns:\n      The tf*idf values\n    \"\"\"\n    # Add one to the reduced term freqnencies to avoid dividing by zero.\n    idf = tf.log(tf.to_double(corpus_size) / (\n        1.0 + tf.to_double(reduced_term_freq)))\n\n    dense_doc_sizes = tf.to_double(tf.sparse_reduce_sum(tf.SparseTensor(\n        indices=x.indices,\n        values=tf.ones_like(x.values),\n        dense_shape=x.dense_shape), 1))\n\n    # For every term in x, divide the idf by the doc size.\n    # The two gathers both result in shape <sum_doc_sizes>\n    idf_over_doc_size = (tf.gather(idf, x.values) /\n                         tf.gather(dense_doc_sizes, x.indices[:, 0]))\n\n    return tf.SparseTensor(\n        indices=x.indices,\n        values=idf_over_doc_size,\n        dense_shape=x.dense_shape)\n\n  cleaned_input = _map_to_vocab_range(x)\n\n  weights = _map_to_tfidf(cleaned_input)\n  return tf.to_float(weights)\n\n\n# TODO(brandondura): update this to not depend on tf layer's feature column\n# 'sum' combiner in the future.\ndef _bag_of_words(x):\n  \"\"\"Computes bag of words weights\n\n  Note the return type is a float sparse tensor, not a int sparse tensor. This\n  is so that the output types batch tfidf, and any downstream transformation\n  in tf layers during training can be applied to both.\n  \"\"\"\n  def _bow(x):\n    \"\"\"Comptue BOW weights.\n\n    As tf layer's sum combiner is used, the weights can be just ones. Tokens are\n    not summed together here.\n    \"\"\"\n    return tf.SparseTensor(\n      indices=x.indices,\n      values=tf.to_float(tf.ones_like(x.values)),\n      dense_shape=x.dense_shape)\n\n  return _bow(x)\n\n\ndef _make_image_to_vec_tito(feature_name, tmp_dir=None, checkpoint=None):\n  \"\"\"Creates a tensor-in-tensor-out function that produces embeddings from image bytes.\n\n  Image to embedding is implemented with Tensorflow's inception v3 model and a pretrained\n  checkpoint. It returns 1x2048 'PreLogits' embeddings for each image.\n\n  Args:\n    feature_name: The name of the feature. Used only to identify the image tensors so\n      we can get gradients for probe in image prediction explaining.\n    tmp_dir: a local directory that is used for downloading the checkpoint. If\n      non, a temp folder will be made and deleted.\n    checkpoint: the inception v3 checkpoint gs or local path. If None, default checkpoint\n      is used.\n\n  Returns: a tensor-in-tensor-out function that takes image string tensor and returns embeddings.\n  \"\"\"\n\n  def _image_to_vec(image_str_tensor):\n\n    def _decode_and_resize(image_tensor):\n      \"\"\"Decodes jpeg string, resizes it and returns a uint8 tensor.\"\"\"\n\n      # These constants are set by Inception v3's expectations.\n      height = 299\n      width = 299\n      channels = 3\n\n      image_tensor = tf.where(tf.equal(image_tensor, ''), IMAGE_DEFAULT_STRING, image_tensor)\n\n      # Fork by whether image_tensor value is a file path, or a base64 encoded string.\n      slash_positions = tf.equal(tf.string_split([image_tensor], delimiter=\"\").values, '/')\n      is_file_path = tf.cast(tf.count_nonzero(slash_positions), tf.bool)\n\n      # The following two functions are required for tf.cond. Note that we can not replace them\n      # with lambda. According to TF docs, if using inline lambda, both branches of condition\n      # will be executed. The workaround is to use a function call.\n      def _read_file():\n        return tf.read_file(image_tensor)\n\n      def _decode_base64():\n        return tf.decode_base64(image_tensor)\n\n      image = tf.cond(is_file_path, lambda: _read_file(), lambda: _decode_base64())\n      image = tf.image.decode_jpeg(image, channels=channels)\n      image = tf.expand_dims(image, 0)\n      image = tf.image.resize_bilinear(image, [height, width], align_corners=False)\n      image = tf.squeeze(image, squeeze_dims=[0])\n      image = tf.cast(image, dtype=tf.uint8)\n      return image\n\n    # The CloudML Prediction API always \"feeds\" the Tensorflow graph with\n    # dynamic batch sizes e.g. (?,).  decode_jpeg only processes scalar\n    # strings because it cannot guarantee a batch of images would have\n    # the same output size.  We use tf.map_fn to give decode_jpeg a scalar\n    # string from dynamic batches.\n    image = tf.map_fn(_decode_and_resize, image_str_tensor, back_prop=False, dtype=tf.uint8)\n    image = tf.image.convert_image_dtype(image, dtype=tf.float32)\n    # \"gradients_[feature_name]\" will be used for computing integrated gradients.\n    image = tf.identity(image, name='gradients_' + feature_name)\n    image = tf.subtract(image, 0.5)\n    inception_input = tf.multiply(image, 2.0)\n\n    # Build Inception layers, which expect a tensor of type float from [-1, 1)\n    # and shape [batch_size, height, width, channels].\n    with tf.contrib.slim.arg_scope(inception_v3_arg_scope()):\n      _, end_points = inception_v3(inception_input, is_training=False)\n\n    embeddings = end_points['PreLogits']\n    inception_embeddings = tf.squeeze(embeddings, [1, 2], name='SpatialSqueeze')\n    return inception_embeddings\n\n  def _tito_from_checkpoint(tito_in, checkpoint, exclude):\n    \"\"\" Create an all-constants tito function from an original tito function.\n\n    Given a tensor-in-tensor-out function which contains variables and a checkpoint path,\n    create a new tensor-in-tensor-out function which includes only constants, and can be\n    used in tft.map.\n    \"\"\"\n\n    def _tito_out(tensor_in):\n      checkpoint_dir = tmp_dir\n      if tmp_dir is None:\n        checkpoint_dir = tempfile.mkdtemp()\n\n      g = tf.Graph()\n      with g.as_default():\n        si = tf.placeholder(dtype=tensor_in.dtype, shape=tensor_in.shape, name=tensor_in.op.name)\n        so = tito_in(si)\n        all_vars = tf.contrib.slim.get_variables_to_restore(exclude=exclude)\n        saver = tf.train.Saver(all_vars)\n        # Downloading the checkpoint from GCS to local speeds up saver.restore() a lot.\n        checkpoint_tmp = os.path.join(checkpoint_dir, 'checkpoint')\n        with file_io.FileIO(checkpoint, 'r') as f_in, file_io.FileIO(checkpoint_tmp, 'w') as f_out:\n          f_out.write(f_in.read())\n        with tf.Session() as sess:\n          saver.restore(sess, checkpoint_tmp)\n          output_graph_def = tf.graph_util.convert_variables_to_constants(sess,\n                                                                          g.as_graph_def(),\n                                                                          [so.op.name])\n        file_io.delete_file(checkpoint_tmp)\n        if tmp_dir is None:\n          shutil.rmtree(checkpoint_dir)\n\n      tensors_out = tf.import_graph_def(output_graph_def,\n                                        input_map={si.name: tensor_in},\n                                        return_elements=[so.name])\n      return tensors_out[0]\n\n    return _tito_out\n\n  if not checkpoint:\n    checkpoint = INCEPTION_V3_CHECKPOINT\n  return _tito_from_checkpoint(_image_to_vec, checkpoint, INCEPTION_EXCLUDED_VARIABLES)\n# ------------------------------------------------------------------------------\n# ------------------------------------------------------------------------------\n# end of transform functions\n# ------------------------------------------------------------------------------\n# ------------------------------------------------------------------------------\n\n\ndef make_preprocessing_fn(output_dir, features, keep_target):\n  \"\"\"Makes a preprocessing function.\n\n  Args:\n    output_dir: folder path that contains the vocab and stats files.\n    features: the features dict\n\n  Returns:\n    a function that takes a dict of input tensors\n  \"\"\"\n  def preprocessing_fn(inputs):\n    \"\"\"Preprocessing function.\n\n    Args:\n      inputs: dictionary of raw input tensors\n\n    Returns:\n      A dictionary of transformed tensors\n    \"\"\"\n    stats = json.loads(\n      file_io.read_file_to_string(\n          os.path.join(output_dir, STATS_FILE)).decode())\n\n    result = {}\n    for name, transform in six.iteritems(features):\n      transform_name = transform['transform']\n      source_column = transform['source_column']\n\n      if transform_name == KEY_TRANSFORM:\n        transform_name = 'identity'\n      elif transform_name == TARGET_TRANSFORM:\n        if not keep_target:\n          continue\n        if file_io.file_exists(os.path.join(output_dir, VOCAB_ANALYSIS_FILE % source_column)):\n          transform_name = 'one_hot'\n        else:\n          transform_name = 'identity'\n\n      if transform_name == 'identity':\n        result[name] = inputs[source_column]\n      elif transform_name == 'scale':\n        result[name] = _scale(\n            inputs[name],\n            min_x_value=stats['column_stats'][source_column]['min'],\n            max_x_value=stats['column_stats'][source_column]['max'],\n            output_min=transform.get('value', 1) * (-1),\n            output_max=transform.get('value', 1))\n      elif transform_name in [ONE_HOT_TRANSFORM, EMBEDDING_TRANSFROM, MULTI_HOT_TRANSFORM,\n                              TFIDF_TRANSFORM, BOW_TRANSFORM]:\n        vocab, ex_count = read_vocab_file(\n            os.path.join(output_dir, VOCAB_ANALYSIS_FILE % source_column))\n\n        if transform_name == TFIDF_TRANSFORM:\n          separator = transform.get('separator', ' ')\n          tokens = tf.string_split(inputs[source_column], separator)\n          ids = _string_to_int(tokens, vocab)\n          weights = _tfidf(\n              x=ids,\n              reduced_term_freq=ex_count + [0],\n              vocab_size=len(vocab) + 1,\n              corpus_size=stats['num_examples'])\n\n          result[name + '_ids'] = ids\n          result[name + '_weights'] = weights\n        elif transform_name == BOW_TRANSFORM:\n          separator = transform.get('separator', ' ')\n          tokens = tf.string_split(inputs[source_column], separator)\n          ids = _string_to_int(tokens, vocab)\n          weights = _bag_of_words(x=ids)\n\n          result[name + '_ids'] = ids\n          result[name + '_weights'] = weights\n        elif transform_name == MULTI_HOT_TRANSFORM:\n          separator = transform.get('separator', ' ')\n          tokens = tf.string_split(inputs[source_column], separator)\n          result[name] = _string_to_int(tokens, vocab)\n        else:\n          # ONE_HOT_TRANSFORM: making a dense vector is done at training\n          # EMBEDDING_TRANSFROM: embedding vectors have to be done at training\n          result[name] = _string_to_int(inputs[source_column], vocab)\n      elif transform_name == IMAGE_TRANSFORM:\n        make_image_to_vec_fn = _make_image_to_vec_tito(\n            name, checkpoint=transform.get('checkpoint', None))\n        result[name] = make_image_to_vec_fn(inputs[source_column])\n      else:\n        raise ValueError('unknown transform %s' % transform_name)\n    return result\n\n  return preprocessing_fn\n\n\ndef get_transformed_feature_info(features, schema):\n  \"\"\"Returns information about the transformed features.\n\n  Returns:\n    Dict in the from\n    {transformed_feature_name: {dtype: tf type, size: int or None}}. If the size\n    is None, then the tensor is a sparse tensor.\n  \"\"\"\n\n  info = collections.defaultdict(dict)\n\n  for name, transform in six.iteritems(features):\n    transform_name = transform['transform']\n    source_column = transform['source_column']\n\n    if transform_name == IDENTITY_TRANSFORM:\n      schema_type = next(col['type'].lower() for col in schema if col['name'] == source_column)\n      if schema_type == FLOAT_SCHEMA:\n        info[name]['dtype'] = tf.float32\n      elif schema_type == INTEGER_SCHEMA:\n        info[name]['dtype'] = tf.int64\n      else:\n        raise ValueError('itentity should only be applied to integer or float'\n                         'columns, but was used on %s' % name)\n      info[name]['size'] = 1\n    elif transform_name == SCALE_TRANSFORM:\n      info[name]['dtype'] = tf.float32\n      info[name]['size'] = 1\n    elif transform_name == ONE_HOT_TRANSFORM:\n      info[name]['dtype'] = tf.int64\n      info[name]['size'] = 1\n    elif transform_name == EMBEDDING_TRANSFROM:\n      info[name]['dtype'] = tf.int64\n      info[name]['size'] = 1\n    elif transform_name == MULTI_HOT_TRANSFORM:\n      info[name]['dtype'] = tf.int64\n      info[name]['size'] = None\n    elif transform_name == BOW_TRANSFORM or transform_name == TFIDF_TRANSFORM:\n      info[name + '_ids']['dtype'] = tf.int64\n      info[name + '_weights']['dtype'] = tf.float32\n      info[name + '_ids']['size'] = None\n      info[name + '_weights']['size'] = None\n    elif transform_name == KEY_TRANSFORM:\n      schema_type = next(col['type'].lower() for col in schema if col['name'] == source_column)\n      if schema_type == FLOAT_SCHEMA:\n        info[name]['dtype'] = tf.float32\n      elif schema_type == INTEGER_SCHEMA:\n        info[name]['dtype'] = tf.int64\n      else:\n        info[name]['dtype'] = tf.string\n      info[name]['size'] = 1\n    elif transform_name == TARGET_TRANSFORM:\n      # If the input is a string, it gets converted to an int (id)\n      schema_type = next(col['type'].lower() for col in schema if col['name'] == source_column)\n      if schema_type in NUMERIC_SCHEMA:\n        info[name]['dtype'] = tf.float32\n      else:\n        info[name]['dtype'] = tf.int64\n      info[name]['size'] = 1\n    elif transform_name == IMAGE_TRANSFORM:\n      info[name]['dtype'] = tf.float32\n      info[name]['size'] = IMAGE_BOTTLENECK_TENSOR_SIZE\n    else:\n      raise ValueError('Unknown transfrom %s' % transform_name)\n\n  return info\n\n\ndef csv_header_and_defaults(features, schema, stats, keep_target):\n  \"\"\"Gets csv header and default lists.\"\"\"\n\n  target_name = get_target_name(features)\n  if keep_target and not target_name:\n    raise ValueError('Cannot find target transform')\n\n  csv_header = []\n  record_defaults = []\n  for col in schema:\n    if not keep_target and col['name'] == target_name:\n      continue\n\n    # Note that numerical key columns do not have a stats entry, hence the use\n    # of get(col['name'], {})\n    csv_header.append(col['name'])\n    if col['type'].lower() == INTEGER_SCHEMA:\n      dtype = tf.int64\n      default = int(stats['column_stats'].get(col['name'], {}).get('mean', 0))\n    elif col['type'].lower() == FLOAT_SCHEMA:\n      dtype = tf.float32\n      default = float(stats['column_stats'].get(col['name'], {}).get('mean', 0.0))\n    else:\n      dtype = tf.string\n      default = ''\n\n    record_defaults.append(tf.constant([default], dtype=dtype))\n\n  return csv_header, record_defaults\n\n\ndef build_csv_serving_tensors_for_transform_step(analysis_path,\n                                                 features,\n                                                 schema,\n                                                 stats,\n                                                 keep_target):\n  \"\"\"Builds a serving function starting from raw csv.\n\n  This should only be used by transform.py (the transform step), and the\n\n  For image columns, the image should be a base64 string encoding the image.\n  The output of this function will transform that image to a 2048 long vector\n  using the inception model.\n  \"\"\"\n\n  csv_header, record_defaults = csv_header_and_defaults(features, schema, stats, keep_target)\n\n  placeholder = tf.placeholder(dtype=tf.string, shape=(None,),\n                               name='csv_input_placeholder')\n  tensors = tf.decode_csv(placeholder, record_defaults)\n  raw_features = dict(zip(csv_header, tensors))\n\n  transform_fn = make_preprocessing_fn(analysis_path, features, keep_target)\n  transformed_tensors = transform_fn(raw_features)\n\n  transformed_features = {}\n  # Expand the dims of non-sparse tensors\n  for k, v in six.iteritems(transformed_tensors):\n    if isinstance(v, tf.Tensor) and v.get_shape().ndims == 1:\n      transformed_features[k] = tf.expand_dims(v, -1)\n    else:\n      transformed_features[k] = v\n\n  return input_fn_utils.InputFnOps(\n      transformed_features, None, {\"csv_example\": placeholder})\n\n\ndef build_csv_serving_tensors_for_training_step(analysis_path,\n                                                features,\n                                                schema,\n                                                stats,\n                                                keep_target):\n  \"\"\"Builds a serving function starting from raw csv, used at model export time.\n\n  For image columns, the image should be a base64 string encoding the image.\n  The output of this function will transform that image to a 2048 long vector\n  using the inception model and then a fully connected net is attached to\n  the 2048 long image embedding.\n  \"\"\"\n\n  transformed_features, _, placeholder_dict = build_csv_serving_tensors_for_transform_step(\n      analysis_path=analysis_path,\n      features=features,\n      schema=schema,\n      stats=stats,\n      keep_target=keep_target)\n\n  transformed_features = image_feature_engineering(\n      features=features,\n      feature_tensors_dict=transformed_features)\n\n  return input_fn_utils.InputFnOps(\n      transformed_features, None, placeholder_dict)\n\n\ndef build_csv_transforming_training_input_fn(schema,\n                                             features,\n                                             stats,\n                                             analysis_output_dir,\n                                             raw_data_file_pattern,\n                                             training_batch_size,\n                                             num_epochs=None,\n                                             randomize_input=False,\n                                             min_after_dequeue=1,\n                                             reader_num_threads=1,\n                                             allow_smaller_final_batch=True):\n  \"\"\"Creates training input_fn that reads raw csv data and applies transforms.\n\n  Args:\n    schema: schema list\n    features: features dict\n    stats: stats dict\n    analysis_output_dir: output folder from analysis\n    raw_data_file_pattern: file path, or list of files\n    training_batch_size: An int specifying the batch size to use.\n    num_epochs: numer of epochs to read from the files. Use None to read forever.\n    randomize_input: If true, the input rows are read out of order. This\n        randomness is limited by the min_after_dequeue value.\n    min_after_dequeue: Minimum number elements in the reading queue after a\n        dequeue, used to ensure a level of mixing of elements. Only used if\n        randomize_input is True.\n    reader_num_threads: The number of threads enqueuing data.\n    allow_smaller_final_batch: If false, fractional batches at the end of\n        training or evaluation are not used.\n\n  Returns:\n    An input_fn suitable for training that reads raw csv training data and\n    applies transforms.\n\n  \"\"\"\n\n  def raw_training_input_fn():\n    \"\"\"Training input function that reads raw data and applies transforms.\"\"\"\n\n    if isinstance(raw_data_file_pattern, six.string_types):\n      filepath_list = [raw_data_file_pattern]\n    else:\n      filepath_list = raw_data_file_pattern\n\n    files = []\n    for path in filepath_list:\n      files.extend(file_io.get_matching_files(path))\n\n    filename_queue = tf.train.string_input_producer(\n        files, num_epochs=num_epochs, shuffle=randomize_input)\n\n    csv_id, csv_lines = tf.TextLineReader().read_up_to(filename_queue, training_batch_size)\n\n    queue_capacity = (reader_num_threads + 3) * training_batch_size + min_after_dequeue\n    if randomize_input:\n      _, batch_csv_lines = tf.train.shuffle_batch(\n          tensors=[csv_id, csv_lines],\n          batch_size=training_batch_size,\n          capacity=queue_capacity,\n          min_after_dequeue=min_after_dequeue,\n          enqueue_many=True,\n          num_threads=reader_num_threads,\n          allow_smaller_final_batch=allow_smaller_final_batch)\n\n    else:\n      _, batch_csv_lines = tf.train.batch(\n          tensors=[csv_id, csv_lines],\n          batch_size=training_batch_size,\n          capacity=queue_capacity,\n          enqueue_many=True,\n          num_threads=reader_num_threads,\n          allow_smaller_final_batch=allow_smaller_final_batch)\n\n    csv_header, record_defaults = csv_header_and_defaults(features, schema, stats, keep_target=True)\n    parsed_tensors = tf.decode_csv(batch_csv_lines, record_defaults, name='csv_to_tensors')\n    raw_features = dict(zip(csv_header, parsed_tensors))\n\n    transform_fn = make_preprocessing_fn(analysis_output_dir, features, keep_target=True)\n    transformed_tensors = transform_fn(raw_features)\n\n    # Expand the dims of non-sparse tensors. This is needed by tf.learn.\n    transformed_features = {}\n    for k, v in six.iteritems(transformed_tensors):\n      if isinstance(v, tf.Tensor) and v.get_shape().ndims == 1:\n        transformed_features[k] = tf.expand_dims(v, -1)\n      else:\n        transformed_features[k] = v\n\n    # image_feature_engineering does not need to be called as images are not\n    # supported in raw csv for training.\n\n    # Remove the target tensor, and return it directly\n    target_name = get_target_name(features)\n    if not target_name or target_name not in transformed_features:\n      raise ValueError('Cannot find target transform in features')\n\n    transformed_target = transformed_features.pop(target_name)\n\n    return transformed_features, transformed_target\n\n  return raw_training_input_fn\n\n\ndef build_tfexample_transfored_training_input_fn(schema,\n                                                 features,\n                                                 analysis_output_dir,\n                                                 raw_data_file_pattern,\n                                                 training_batch_size,\n                                                 num_epochs=None,\n                                                 randomize_input=False,\n                                                 min_after_dequeue=1,\n                                                 reader_num_threads=1,\n                                                 allow_smaller_final_batch=True):\n  \"\"\"Creates training input_fn that reads transformed tf.example files.\n\n  Args:\n    schema: schema list\n    features: features dict\n    analysis_output_dir: output folder from analysis\n    raw_data_file_pattern: file path, or list of files\n    training_batch_size: An int specifying the batch size to use.\n    num_epochs: numer of epochs to read from the files. Use None to read forever.\n    randomize_input: If true, the input rows are read out of order. This\n        randomness is limited by the min_after_dequeue value.\n    min_after_dequeue: Minimum number elements in the reading queue after a\n        dequeue, used to ensure a level of mixing of elements. Only used if\n        randomize_input is True.\n    reader_num_threads: The number of threads enqueuing data.\n    allow_smaller_final_batch: If false, fractional batches at the end of\n        training or evaluation are not used.\n\n  Returns:\n    An input_fn suitable for training that reads transformed data in tf record\n      files of tf.example.\n  \"\"\"\n\n  def transformed_training_input_fn():\n    \"\"\"Training input function that reads transformed data.\"\"\"\n\n    if isinstance(raw_data_file_pattern, six.string_types):\n      filepath_list = [raw_data_file_pattern]\n    else:\n      filepath_list = raw_data_file_pattern\n\n    files = []\n    for path in filepath_list:\n      files.extend(file_io.get_matching_files(path))\n\n    filename_queue = tf.train.string_input_producer(\n        files, num_epochs=num_epochs, shuffle=randomize_input)\n\n    options = tf.python_io.TFRecordOptions(\n        compression_type=tf.python_io.TFRecordCompressionType.GZIP)\n    ex_id, ex_str = tf.TFRecordReader(options=options).read_up_to(\n        filename_queue, training_batch_size)\n\n    queue_capacity = (reader_num_threads + 3) * training_batch_size + min_after_dequeue\n    if randomize_input:\n      _, batch_ex_str = tf.train.shuffle_batch(\n          tensors=[ex_id, ex_str],\n          batch_size=training_batch_size,\n          capacity=queue_capacity,\n          min_after_dequeue=min_after_dequeue,\n          enqueue_many=True,\n          num_threads=reader_num_threads,\n          allow_smaller_final_batch=allow_smaller_final_batch)\n\n    else:\n      _, batch_ex_str = tf.train.batch(\n          tensors=[ex_id, ex_str],\n          batch_size=training_batch_size,\n          capacity=queue_capacity,\n          enqueue_many=True,\n          num_threads=reader_num_threads,\n          allow_smaller_final_batch=allow_smaller_final_batch)\n\n    feature_spec = {}\n    feature_info = get_transformed_feature_info(features, schema)\n    for name, info in six.iteritems(feature_info):\n      if info['size'] is None:\n        feature_spec[name] = tf.VarLenFeature(dtype=info['dtype'])\n      else:\n        feature_spec[name] = tf.FixedLenFeature(shape=[info['size']], dtype=info['dtype'])\n\n    parsed_tensors = tf.parse_example(batch_ex_str, feature_spec)\n\n    # Expand the dims of non-sparse tensors. This is needed by tf.learn.\n    transformed_features = {}\n    for k, v in six.iteritems(parsed_tensors):\n      if isinstance(v, tf.Tensor) and v.get_shape().ndims == 1:\n        transformed_features[k] = tf.expand_dims(v, -1)\n      else:\n        # Sparse tensor\n        transformed_features[k] = v\n\n    transformed_features = image_feature_engineering(\n        features=features,\n        feature_tensors_dict=transformed_features)\n\n    # Remove the target tensor, and return it directly\n    target_name = get_target_name(features)\n    if not target_name or target_name not in transformed_features:\n      raise ValueError('Cannot find target transform in features')\n\n    transformed_target = transformed_features.pop(target_name)\n\n    return transformed_features, transformed_target\n\n  return transformed_training_input_fn\n\n\ndef image_feature_engineering(features, feature_tensors_dict):\n  \"\"\"Add a hidden layer on image features.\n\n  Args:\n    features: features dict\n    feature_tensors_dict: dict of feature-name: tensor\n  \"\"\"\n  engineered_features = {}\n  for name, feature_tensor in six.iteritems(feature_tensors_dict):\n    if name in features and features[name]['transform'] == IMAGE_TRANSFORM:\n      with tf.name_scope(name, 'Wx_plus_b'):\n        hidden = tf.contrib.layers.fully_connected(\n            feature_tensor,\n            IMAGE_HIDDEN_TENSOR_SIZE)\n        engineered_features[name] = hidden\n    else:\n      engineered_features[name] = feature_tensor\n  return engineered_features\n\n\ndef get_target_name(features):\n  for name, transform in six.iteritems(features):\n    if transform['transform'] == TARGET_TRANSFORM:\n      return name\n\n  return None\n\n\ndef read_vocab_file(file_path):\n  \"\"\"Reads a vocab file to memeory.\n\n  Args:\n    file_path: Each line of the vocab is in the form \"token,example_count\"\n\n  Returns:\n    Two lists, one for the vocab, and one for just the example counts.\n  \"\"\"\n  with file_io.FileIO(file_path, 'r') as f:\n    vocab_pd = pd.read_csv(\n        f,\n        header=None,\n        names=['vocab', 'count'],\n        dtype=str,  # Prevent pd from converting numerical categories.\n        na_filter=False)  # Prevent pd from converting 'NA' to a NaN.\n\n  vocab = vocab_pd['vocab'].tolist()\n  ex_count = vocab_pd['count'].astype(int).tolist()\n\n  return vocab, ex_count\n"
  },
  {
    "path": "solutionbox/ml_workbench/tensorflow/trainer/task.py",
    "content": "# Copyright 2017 Google Inc. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\nfrom __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport argparse\nimport json\nimport math\nimport multiprocessing\nimport os\nimport re\nimport sys\nimport six\nimport tensorflow as tf\n\nfrom tensorflow.contrib.framework.python.ops import variables as contrib_variables\nfrom tensorflow.contrib.learn.python.learn import export_strategy\nfrom tensorflow.contrib.learn.python.learn import learn_runner\nfrom tensorflow.contrib.learn.python.learn.estimators import model_fn as model_fn_lib\nfrom tensorflow.contrib.learn.python.learn.utils import saved_model_export_utils\nfrom tensorflow.python.client import session as tf_session\nfrom tensorflow.python.framework import dtypes\nfrom tensorflow.python.framework import ops\nfrom tensorflow.python.lib.io import file_io\nfrom tensorflow.python.ops import resources\nfrom tensorflow.python.ops import control_flow_ops\nfrom tensorflow.python.ops import variables\nfrom tensorflow.python.saved_model import builder as saved_model_builder\nfrom tensorflow.python.saved_model import signature_def_utils\nfrom tensorflow.python.saved_model import tag_constants\nfrom tensorflow.python.training import saver\nfrom tensorflow.python.util import compat\n\n\nfrom . import feature_transforms\nfrom . import feature_analysis\n\n# Constants for the Prediction Graph fetch tensors.\nPG_TARGET = 'target'  # from input\n\nPG_REGRESSION_PREDICTED_TARGET = 'predicted'\n\nPG_CLASSIFICATION_FIRST_LABEL = 'predicted'\nPG_CLASSIFICATION_FIRST_SCORE = 'probability'\nPG_CLASSIFICATION_LABEL_TEMPLATE = 'predicted_%s'\nPG_CLASSIFICATION_SCORE_TEMPLATE = 'probability_%s'\n\n\nclass DatalabParser():\n  \"\"\"An arg parser that also prints package specific args with --datalab-help.\n\n  When using Datalab magic's to run this trainer, it prints it's own help menu\n  that describes the required options that are common to all trainers. In order\n  to print just the options that are unique to this trainer, datalab calls this\n  file with --datalab-help.\n\n  This class implements --datalab-help by building a list of help string that only\n  includes the unique parameters.\n  \"\"\"\n\n  def __init__(self, epilog=None, datalab_epilog=None):\n    self.full_parser = argparse.ArgumentParser(epilog=epilog)\n    self.datalab_help = []\n    self.datalab_epilog = datalab_epilog\n\n    # Datalab help string\n    self.full_parser.add_argument(\n        '--datalab-help', action=self.make_datalab_help_action(),\n        help='Show a smaller help message for DataLab only and exit')\n\n    # The arguments added here are required to exist by Datalab's \"%%ml train\" magics.\n    self.full_parser.add_argument(\n        '--train', type=str, required=True, action='append', metavar='FILE')\n    self.full_parser.add_argument(\n        '--eval', type=str, required=True, action='append', metavar='FILE')\n    self.full_parser.add_argument('--job-dir', type=str, required=True)\n    self.full_parser.add_argument(\n        '--analysis', type=str,\n        metavar='ANALYSIS_OUTPUT_DIR',\n        help=('Output folder of analysis. Should contain the schema, stats, and '\n              'vocab files. Path must be on GCS if running cloud training. ' +\n              'If absent, --schema and --features must be provided and ' +\n              'the master trainer will do analysis locally.'))\n    self.full_parser.add_argument(\n        '--transform', action='store_true', default=False,\n        help='If used, input data is raw csv that needs transformation. If analysis ' +\n             'is required to run in trainerm this is automatically set to true.')\n    self.full_parser.add_argument(\n        '--schema', type=str,\n        help='Schema of the training csv file. Only needed if analysis is required.')\n    self.full_parser.add_argument(\n        '--features', type=str,\n        help='Feature transform config. Only needed if analysis is required.')\n\n  def make_datalab_help_action(self):\n    \"\"\"Custom action for --datalab-help.\n\n    The action output the package specific parameters and will be part of \"%%ml train\"\n    help string.\n    \"\"\"\n    datalab_help = self.datalab_help\n    epilog = self.datalab_epilog\n\n    class _CustomAction(argparse.Action):\n\n      def __init__(self, option_strings, dest, help=None):\n        super(_CustomAction, self).__init__(\n            option_strings=option_strings, dest=dest, nargs=0, help=help)\n\n      def __call__(self, parser, args, values, option_string=None):\n        print('\\n\\n'.join(datalab_help))\n        if epilog:\n          print(epilog)\n\n        # We have printed all help string datalab needs. If we don't quit, it will complain about\n        # missing required arguments later.\n        quit()\n    return _CustomAction\n\n  def add_argument(self, name, **kwargs):\n    # Any argument added here is not required by Datalab, and so is unique\n    # to this trainer. Add each argument to the main parser and the datalab helper string.\n    self.full_parser.add_argument(name, **kwargs)\n    name = name.replace('--', '')\n    # leading spaces are needed for datalab's help formatting.\n    msg = '  ' + name + ': '\n    if 'help' in kwargs:\n      msg += kwargs['help'] + ' '\n    if kwargs.get('required', False):\n      msg += 'Required. '\n    else:\n      msg += 'Optional. '\n    if 'choices' in kwargs:\n      msg += 'One of ' + str(kwargs['choices']) + '. '\n    if 'default' in kwargs:\n      msg += 'default: ' + str(kwargs['default']) + '.'\n    self.datalab_help.append(msg)\n\n  def parse_known_args(self, args=None):\n    return self.full_parser.parse_known_args(args=args)\n\n\ndef parse_arguments(argv):\n  \"\"\"Parse the command line arguments.\"\"\"\n  parser = DatalabParser(\n      epilog=('Note that if using a DNN model, --hidden-layer-size1=NUM, '\n              '--hidden-layer-size2=NUM, ..., is also required. '),\n      datalab_epilog=(\"\"\"\n  Note that if using a DNN model,\n  hidden-layer-size1: NUM\n  hidden-layer-size2: NUM\n  ...\n  is also required. \"\"\"))\n\n  # HP parameters\n  parser.add_argument(\n      '--epsilon', type=float, default=0.0005, metavar='R',\n      help='tf.train.AdamOptimizer epsilon. Only used in dnn models.')\n  parser.add_argument(\n      '--l1-regularization', type=float, default=0.0, metavar='R',\n      help='L1 term for linear models.')\n  parser.add_argument(\n      '--l2-regularization', type=float, default=0.0, metavar='R',\n      help='L2 term for linear models.')\n\n  # Model parameters\n  parser.add_argument(\n    '--model', required=True,\n    choices=['linear_classification', 'linear_regression', 'dnn_classification', 'dnn_regression'])\n  parser.add_argument(\n      '--top-n', type=int, default=0, metavar='N',\n      help=('For classification problems, the output graph will contain the '\n            'labels and scores for the top n classes, and results will be in the form of '\n            '\"predicted, predicted_2, ..., probability, probability_2, ...\". '\n            'If --top-n=0, then all labels and scores are returned in the form of '\n            '\"predicted, class_name1, class_name2,...\".'))\n\n  # HP parameters\n  parser.add_argument(\n      '--learning-rate', type=float, default=0.01, metavar='R',\n      help='optimizer learning rate.')\n\n  # Training input parameters\n  parser.add_argument(\n      '--max-steps', type=int, metavar='N',\n      help='Maximum number of training steps to perform. If unspecified, will '\n           'honor \"max-epochs\".')\n  parser.add_argument(\n      '--max-epochs', type=int, default=1000, metavar='N',\n      help='Maximum number of training data epochs on which to train. If '\n           'both \"max-steps\" and \"max-epochs\" are specified, the training '\n           'job will run for \"max-steps\" or \"num-epochs\", whichever occurs '\n           'first. If early stopping is enabled, training may also stop '\n           'earlier.')\n  parser.add_argument(\n      '--train-batch-size', type=int, default=64, metavar='N',\n      help='How many training examples are used per step. If num-epochs is '\n           'used, the last batch may not be full.')\n  parser.add_argument(\n      '--eval-batch-size', type=int, default=64, metavar='N',\n      help='Batch size during evaluation. Larger values increase performance '\n           'but also increase peak memory usgae on the master node. One pass '\n           'over the full eval set is performed per evaluation run.')\n  parser.add_argument(\n      '--min-eval-frequency', type=int, default=1000, metavar='N',\n      help='Minimum number of training steps between evaluations. Evaluation '\n           'does not occur if no new checkpoint is available, hence, this is '\n           'the minimum. If 0, the evaluation will only happen after training. ')\n  parser.add_argument(\n      '--early-stopping-num_evals', type=int, default=3,\n      help='Automatic training stop after results of specified number of evals '\n           'in a row show the model performance does not improve. Set to 0 to '\n           'disable early stopping.')\n  parser.add_argument(\n      '--logging-level', choices=['error', 'warning', 'info'],\n      help='The TF logging level. If absent, use info for cloud training '\n           'and warning for local training.')\n\n  args, remaining_args = parser.parse_known_args(args=argv[1:])\n\n  # All HP parambeters must be unique, so we need to support an unknown number\n  # of --hidden-layer-size1=10 --lhidden-layer-size2=10 ...\n  # Look at remaining_args for hidden-layer-size\\d+ to get the layer info.\n\n  # Get number of layers\n  pattern = re.compile('hidden-layer-size(\\d+)')\n  num_layers = 0\n  for other_arg in remaining_args:\n    match = re.search(pattern, other_arg)\n    if match:\n      if int(match.group(1)) <= 0:\n        raise ValueError('layer size must be a positive integer. Was given %s' % other_arg)\n      num_layers = max(num_layers, int(match.group(1)))\n\n  # Build a new parser so we catch unknown args and missing layer_sizes.\n  parser = argparse.ArgumentParser()\n  for i in range(num_layers):\n    parser.add_argument('--hidden-layer-size%s' % str(i + 1), type=int, required=True)\n\n  layer_args = vars(parser.parse_args(args=remaining_args))\n  hidden_layer_sizes = []\n  for i in range(num_layers):\n    key = 'hidden_layer_size%s' % str(i + 1)\n    hidden_layer_sizes.append(layer_args[key])\n\n  assert len(hidden_layer_sizes) == num_layers\n  args.hidden_layer_sizes = hidden_layer_sizes\n\n  return args\n\n\ndef is_linear_model(model_type):\n  return model_type.startswith('linear_')\n\n\ndef is_dnn_model(model_type):\n  return model_type.startswith('dnn_')\n\n\ndef is_regression_model(model_type):\n  return model_type.endswith('_regression')\n\n\ndef is_classification_model(model_type):\n  return model_type.endswith('_classification')\n\n\ndef build_feature_columns(features, stats, model_type):\n  feature_columns = []\n  is_dnn = is_dnn_model(model_type)\n\n  # Supported transforms:\n  # for DNN\n  #   numerical number\n  #   one hot: sparse int column -> one_hot_column\n  #   ebmedding: sparse int column -> embedding_column\n  #   text: sparse int weighted column -> embedding_column\n  # for linear\n  #   numerical number\n  #   one hot: sparse int column\n  #   ebmedding: sparse int column -> hash int\n  #   text: sparse int weighted column\n  # It is unfortunate that tf.layers has different feature transforms if the\n  # model is linear or DNN. This pacakge should not expose to the user that\n  # we are using tf.layers.\n  for name, transform in six.iteritems(features):\n    transform_name = transform['transform']\n    source_column = transform['source_column']\n\n    if transform_name in feature_transforms.NUMERIC_TRANSFORMS:\n      new_feature = tf.contrib.layers.real_valued_column(name, dimension=1)\n    elif (transform_name == feature_transforms.ONE_HOT_TRANSFORM or\n          transform_name == feature_transforms.MULTI_HOT_TRANSFORM):\n      sparse = tf.contrib.layers.sparse_column_with_integerized_feature(\n          name,\n          bucket_size=stats['column_stats'][source_column]['vocab_size'])\n      if is_dnn:\n        new_feature = tf.contrib.layers.one_hot_column(sparse)\n      else:\n        new_feature = sparse\n    elif transform_name == feature_transforms.EMBEDDING_TRANSFROM:\n      if is_dnn:\n        sparse = tf.contrib.layers.sparse_column_with_integerized_feature(\n            name,\n            bucket_size=stats['column_stats'][source_column]['vocab_size'])\n        new_feature = tf.contrib.layers.embedding_column(\n            sparse,\n            dimension=transform['embedding_dim'])\n      else:\n        new_feature = tf.contrib.layers.sparse_column_with_hash_bucket(\n            name,\n            hash_bucket_size=transform['embedding_dim'],\n            dtype=dtypes.int64)\n    elif transform_name in feature_transforms.TEXT_TRANSFORMS:\n      sparse_ids = tf.contrib.layers.sparse_column_with_integerized_feature(\n          name + '_ids',\n          bucket_size=stats['column_stats'][source_column]['vocab_size'],\n          combiner='sum')\n      sparse_weights = tf.contrib.layers.weighted_sparse_column(\n          sparse_id_column=sparse_ids,\n          weight_column_name=name + '_weights',\n          dtype=dtypes.float32)\n      if is_dnn:\n        new_feature = tf.contrib.layers.one_hot_column(sparse_ids)\n        dimension = int(math.log(stats['column_stats'][source_column]['vocab_size'])) + 1\n        new_feature = tf.contrib.layers.embedding_column(\n            sparse_weights,\n            dimension=dimension,\n            combiner='sqrtn')\n      else:\n        new_feature = sparse_weights\n    elif (transform_name == feature_transforms.TARGET_TRANSFORM or\n          transform_name == feature_transforms.KEY_TRANSFORM):\n      continue\n    elif transform_name == feature_transforms.IMAGE_TRANSFORM:\n      new_feature = tf.contrib.layers.real_valued_column(\n          name,\n          dimension=feature_transforms.IMAGE_HIDDEN_TENSOR_SIZE)\n    else:\n      raise ValueError('Unknown transfrom %s' % transform_name)\n\n    feature_columns.append(new_feature)\n\n  return feature_columns\n\n\ndef recursive_copy(src_dir, dest_dir):\n  \"\"\"Copy the contents of src_dir into the folder dest_dir.\n  Args:\n    src_dir: gsc or local path.\n    dest_dir: gcs or local path.\n  \"\"\"\n\n  file_io.recursive_create_dir(dest_dir)\n  for file_name in file_io.list_directory(src_dir):\n    old_path = os.path.join(src_dir, file_name)\n    new_path = os.path.join(dest_dir, file_name)\n\n    if file_io.is_directory(old_path):\n      recursive_copy(old_path, new_path)\n    else:\n      file_io.copy(old_path, new_path, overwrite=True)\n\n\ndef make_prediction_output_tensors(args, features, input_ops, model_fn_ops,\n                                   keep_target):\n  \"\"\"Makes the final prediction output layer.\"\"\"\n  target_name = feature_transforms.get_target_name(features)\n  key_names = get_key_names(features)\n\n  outputs = {}\n  outputs.update({key_name: tf.squeeze(input_ops.features[key_name])\n                  for key_name in key_names})\n\n  if is_classification_model(args.model):\n\n    # build maps from ints to the origional categorical strings.\n    class_names = read_vocab(args, target_name)\n    table = tf.contrib.lookup.index_to_string_table_from_tensor(\n        mapping=class_names,\n        default_value='UNKNOWN')\n\n    # Get the label of the input target.\n    if keep_target:\n      input_target_label = table.lookup(input_ops.features[target_name])\n      outputs[PG_TARGET] = tf.squeeze(input_target_label)\n\n    # TODO(brandondutra): get the score of the target label too.\n    probabilities = model_fn_ops.predictions['probabilities']\n\n    # if top_n == 0, this means use all the classes. We will use class names as\n    # probabilities labels.\n    if args.top_n == 0:\n      predicted_index = tf.argmax(probabilities, axis=1)\n      predicted = table.lookup(predicted_index)\n      outputs.update({PG_CLASSIFICATION_FIRST_LABEL: predicted})\n      probabilities_list = tf.unstack(probabilities, axis=1)\n      for class_name, p in zip(class_names, probabilities_list):\n        outputs[class_name] = p\n    else:\n      top_n = args.top_n\n\n      # get top k labels and their scores.\n      (top_k_values, top_k_indices) = tf.nn.top_k(probabilities, k=top_n)\n      top_k_labels = table.lookup(tf.to_int64(top_k_indices))\n\n      # Write the top_k values using 2*top_n columns.\n      num_digits = int(math.ceil(math.log(top_n, 10)))\n      if num_digits == 0:\n        num_digits = 1\n      for i in range(0, top_n):\n        # Pad i based on the size of k. So if k = 100, i = 23 -> i = '023'. This\n        # makes sorting the columns easy.\n        padded_i = str(i + 1).zfill(num_digits)\n\n        if i == 0:\n          label_alias = PG_CLASSIFICATION_FIRST_LABEL\n        else:\n          label_alias = PG_CLASSIFICATION_LABEL_TEMPLATE % padded_i\n\n        label_tensor_name = (tf.squeeze(\n            tf.slice(top_k_labels, [0, i], [tf.shape(top_k_labels)[0], 1])))\n\n        if i == 0:\n          score_alias = PG_CLASSIFICATION_FIRST_SCORE\n        else:\n          score_alias = PG_CLASSIFICATION_SCORE_TEMPLATE % padded_i\n\n        score_tensor_name = (tf.squeeze(\n            tf.slice(top_k_values,\n                     [0, i],\n                     [tf.shape(top_k_values)[0], 1])))\n\n        outputs.update({label_alias: label_tensor_name,\n                        score_alias: score_tensor_name})\n\n  else:\n    if keep_target:\n      outputs[PG_TARGET] = tf.squeeze(input_ops.features[target_name])\n\n    scores = model_fn_ops.predictions['scores']\n    outputs[PG_REGRESSION_PREDICTED_TARGET] = tf.squeeze(scores)\n\n  return outputs\n\n\n# This function is strongly based on\n# tensorflow/contrib/learn/python/learn/estimators/estimator.py:export_savedmodel()\n# The difference is we need to modify estimator's output layer.\ndef make_export_strategy(\n        args,\n        keep_target,\n        assets_extra,\n        features,\n        schema,\n        stats):\n  \"\"\"Makes prediction graph that takes json input.\n\n  Args:\n    args: command line args\n    keep_target: If ture, target column is returned in prediction graph. Target\n        column must also exist in input data\n    assets_extra: other fiels to copy to the output folder\n    job_dir: root job folder\n    features: features dict\n    schema: schema list\n    stats: stats dict\n  \"\"\"\n  target_name = feature_transforms.get_target_name(features)\n  csv_header = [col['name'] for col in schema]\n  if not keep_target:\n    csv_header.remove(target_name)\n\n  def export_fn(estimator, export_dir_base, checkpoint_path=None, eval_result=None):\n    with ops.Graph().as_default() as g:\n      contrib_variables.create_global_step(g)\n\n      input_ops = feature_transforms.build_csv_serving_tensors_for_training_step(\n          args.analysis, features, schema, stats, keep_target)\n      model_fn_ops = estimator._call_model_fn(input_ops.features,\n                                              None,\n                                              model_fn_lib.ModeKeys.INFER)\n      output_fetch_tensors = make_prediction_output_tensors(\n          args=args,\n          features=features,\n          input_ops=input_ops,\n          model_fn_ops=model_fn_ops,\n          keep_target=keep_target)\n\n      # Don't use signature_def_utils.predict_signature_def as that renames\n      # tensor names if there is only 1 input/output tensor!\n      signature_inputs = {key: tf.saved_model.utils.build_tensor_info(tensor)\n                          for key, tensor in six.iteritems(input_ops.default_inputs)}\n      signature_outputs = {key: tf.saved_model.utils.build_tensor_info(tensor)\n                           for key, tensor in six.iteritems(output_fetch_tensors)}\n      signature_def_map = {\n          'serving_default':\n              signature_def_utils.build_signature_def(\n                  signature_inputs,\n                  signature_outputs,\n                  tf.saved_model.signature_constants.PREDICT_METHOD_NAME)}\n\n      if not checkpoint_path:\n        # Locate the latest checkpoint\n        checkpoint_path = saver.latest_checkpoint(estimator._model_dir)\n      if not checkpoint_path:\n        raise ValueError(\"Couldn't find trained model at %s.\"\n                         % estimator._model_dir)\n\n      export_dir = saved_model_export_utils.get_timestamped_export_dir(\n          export_dir_base)\n\n      if (model_fn_ops.scaffold is not None and\n         model_fn_ops.scaffold.saver is not None):\n        saver_for_restore = model_fn_ops.scaffold.saver\n      else:\n        saver_for_restore = saver.Saver(sharded=True)\n\n      with tf_session.Session('') as session:\n        saver_for_restore.restore(session, checkpoint_path)\n        init_op = control_flow_ops.group(\n            variables.local_variables_initializer(),\n            resources.initialize_resources(resources.shared_resources()),\n            tf.tables_initializer())\n\n        # Perform the export\n        builder = saved_model_builder.SavedModelBuilder(export_dir)\n        builder.add_meta_graph_and_variables(\n            session, [tag_constants.SERVING],\n            signature_def_map=signature_def_map,\n            assets_collection=ops.get_collection(\n                ops.GraphKeys.ASSET_FILEPATHS),\n            legacy_init_op=init_op)\n        builder.save(False)\n\n      # Add the extra assets\n      if assets_extra:\n        assets_extra_path = os.path.join(compat.as_bytes(export_dir),\n                                         compat.as_bytes('assets.extra'))\n        for dest_relative, source in assets_extra.items():\n          dest_absolute = os.path.join(compat.as_bytes(assets_extra_path),\n                                       compat.as_bytes(dest_relative))\n          dest_path = os.path.dirname(dest_absolute)\n          file_io.recursive_create_dir(dest_path)\n          file_io.copy(source, dest_absolute)\n\n    # only keep the last 3 models\n    saved_model_export_utils.garbage_collect_exports(\n        export_dir_base,\n        exports_to_keep=3)\n\n    # save the last model to the model folder.\n    # export_dir_base = A/B/intermediate_models/\n    if keep_target:\n      final_dir = os.path.join(args.job_dir, 'evaluation_model')\n    else:\n      final_dir = os.path.join(args.job_dir, 'model')\n    if file_io.is_directory(final_dir):\n      file_io.delete_recursively(final_dir)\n    file_io.recursive_create_dir(final_dir)\n    recursive_copy(export_dir, final_dir)\n\n    return export_dir\n\n  if keep_target:\n    intermediate_dir = 'intermediate_evaluation_models'\n  else:\n    intermediate_dir = 'intermediate_prediction_models'\n\n  return export_strategy.ExportStrategy(intermediate_dir, export_fn)\n\n\ndef get_estimator(args, output_dir, features, stats, target_vocab_size):\n  # Check layers used for dnn models.\n  if is_dnn_model(args.model) and not args.hidden_layer_sizes:\n    raise ValueError('--hidden-layer-size* must be used with DNN models')\n  if is_linear_model(args.model) and args.hidden_layer_sizes:\n    raise ValueError('--hidden-layer-size* cannot be used with linear models')\n\n  # Build tf.learn features\n  feature_columns = build_feature_columns(features, stats, args.model)\n\n  # Set how often to run checkpointing in terms of steps.\n  config = tf.contrib.learn.RunConfig(\n      save_checkpoints_steps=args.min_eval_frequency)\n\n  train_dir = os.path.join(output_dir, 'train')\n  if args.model == 'dnn_regression':\n    estimator = tf.contrib.learn.DNNRegressor(\n        feature_columns=feature_columns,\n        hidden_units=args.hidden_layer_sizes,\n        config=config,\n        model_dir=train_dir,\n        optimizer=tf.train.AdamOptimizer(\n            args.learning_rate, epsilon=args.epsilon))\n  elif args.model == 'linear_regression':\n    estimator = tf.contrib.learn.LinearRegressor(\n        feature_columns=feature_columns,\n        config=config,\n        model_dir=train_dir,\n        optimizer=tf.train.FtrlOptimizer(\n            args.learning_rate,\n            l1_regularization_strength=args.l1_regularization,\n            l2_regularization_strength=args.l2_regularization))\n  elif args.model == 'dnn_classification':\n    estimator = tf.contrib.learn.DNNClassifier(\n        feature_columns=feature_columns,\n        hidden_units=args.hidden_layer_sizes,\n        n_classes=target_vocab_size,\n        config=config,\n        model_dir=train_dir,\n        optimizer=tf.train.AdamOptimizer(\n            args.learning_rate, epsilon=args.epsilon))\n  elif args.model == 'linear_classification':\n    estimator = tf.contrib.learn.LinearClassifier(\n        feature_columns=feature_columns,\n        n_classes=target_vocab_size,\n        config=config,\n        model_dir=train_dir,\n        optimizer=tf.train.FtrlOptimizer(\n            args.learning_rate,\n            l1_regularization_strength=args.l1_regularization,\n            l2_regularization_strength=args.l2_regularization))\n  else:\n    raise ValueError('bad --model-type value')\n\n  return estimator\n\n\ndef read_vocab(args, column_name):\n  \"\"\"Reads a vocab file if it exists.\n\n  Args:\n    args: command line flags\n    column_name: name of column to that has a vocab file.\n\n  Returns:\n    List of vocab words or [] if the vocab file is not found.\n  \"\"\"\n  vocab_path = os.path.join(args.analysis,\n                            feature_transforms.VOCAB_ANALYSIS_FILE % column_name)\n\n  if not file_io.file_exists(vocab_path):\n    return []\n\n  vocab, _ = feature_transforms.read_vocab_file(vocab_path)\n  return vocab\n\n\ndef get_key_names(features):\n  names = []\n  for name, transform in six.iteritems(features):\n    if transform['transform'] == feature_transforms.KEY_TRANSFORM:\n      names.append(name)\n  return names\n\n\ndef read_json_file(file_path):\n  if not file_io.file_exists(file_path):\n    raise ValueError('File not found: %s' % file_path)\n  return json.loads(file_io.read_file_to_string(file_path).decode())\n\n\ndef get_experiment_fn(args):\n  \"\"\"Builds the experiment function for learn_runner.run.\n\n  Args:\n    args: the command line args\n\n  Returns:\n    A function that returns a tf.learn experiment object.\n  \"\"\"\n\n  def get_experiment(output_dir):\n    # Read schema, input features, and transforms.\n    schema_path_with_target = os.path.join(args.analysis,\n                                           feature_transforms.SCHEMA_FILE)\n    features_path = os.path.join(args.analysis,\n                                 feature_transforms.FEATURES_FILE)\n    stats_path = os.path.join(args.analysis,\n                              feature_transforms.STATS_FILE)\n\n    schema = read_json_file(schema_path_with_target)\n    features = read_json_file(features_path)\n    stats = read_json_file(stats_path)\n\n    target_column_name = feature_transforms.get_target_name(features)\n    if not target_column_name:\n      raise ValueError('target missing from features file.')\n\n    # Make a copy of the schema file without the target column.\n    schema_without_target = [col for col in schema if col['name'] != target_column_name]\n    schema_path_without_target = os.path.join(args.job_dir, 'schema_without_target.json')\n    file_io.recursive_create_dir(args.job_dir)\n    file_io.write_string_to_file(schema_path_without_target,\n                                 json.dumps(schema_without_target, indent=2))\n\n    # Make list of files to save with the trained model.\n    additional_assets_with_target = {\n        feature_transforms.FEATURES_FILE: features_path,\n        feature_transforms.SCHEMA_FILE: schema_path_with_target}\n    additional_assets_without_target = {\n        feature_transforms.FEATURES_FILE: features_path,\n        feature_transforms.SCHEMA_FILE: schema_path_without_target}\n\n    # Get the model to train.\n    target_vocab = read_vocab(args, target_column_name)\n    estimator = get_estimator(args, output_dir, features, stats, len(target_vocab))\n\n    export_strategy_csv_notarget = make_export_strategy(\n        args=args,\n        keep_target=False,\n        assets_extra=additional_assets_without_target,\n        features=features,\n        schema=schema,\n        stats=stats)\n    export_strategy_csv_target = make_export_strategy(\n        args=args,\n        keep_target=True,\n        assets_extra=additional_assets_with_target,\n        features=features,\n        schema=schema,\n        stats=stats)\n\n    # Build readers for training.\n    if args.transform:\n      if any(v['transform'] == feature_transforms.IMAGE_TRANSFORM\n             for k, v in six.iteritems(features)):\n        raise ValueError('\"image_to_vec\" transform requires transformation step. ' +\n                         'Cannot train from raw data.')\n\n      input_reader_for_train = feature_transforms.build_csv_transforming_training_input_fn(\n          schema=schema,\n          features=features,\n          stats=stats,\n          analysis_output_dir=args.analysis,\n          raw_data_file_pattern=args.train,\n          training_batch_size=args.train_batch_size,\n          num_epochs=args.max_epochs,\n          randomize_input=True,\n          min_after_dequeue=10,\n          reader_num_threads=multiprocessing.cpu_count())\n      input_reader_for_eval = feature_transforms.build_csv_transforming_training_input_fn(\n          schema=schema,\n          features=features,\n          stats=stats,\n          analysis_output_dir=args.analysis,\n          raw_data_file_pattern=args.eval,\n          training_batch_size=args.eval_batch_size,\n          num_epochs=1,\n          randomize_input=False,\n          reader_num_threads=multiprocessing.cpu_count())\n    else:\n      input_reader_for_train = feature_transforms.build_tfexample_transfored_training_input_fn(\n          schema=schema,\n          features=features,\n          analysis_output_dir=args.analysis,\n          raw_data_file_pattern=args.train,\n          training_batch_size=args.train_batch_size,\n          num_epochs=args.max_epochs,\n          randomize_input=True,\n          min_after_dequeue=10,\n          reader_num_threads=multiprocessing.cpu_count())\n      input_reader_for_eval = feature_transforms.build_tfexample_transfored_training_input_fn(\n          schema=schema,\n          features=features,\n          analysis_output_dir=args.analysis,\n          raw_data_file_pattern=args.eval,\n          training_batch_size=args.eval_batch_size,\n          num_epochs=1,\n          randomize_input=False,\n          reader_num_threads=multiprocessing.cpu_count())\n\n    if args.early_stopping_num_evals == 0:\n      train_monitors = None\n    else:\n      if is_classification_model(args.model):\n        early_stop_monitor = tf.contrib.learn.monitors.ValidationMonitor(\n            input_fn=input_reader_for_eval,\n            every_n_steps=args.min_eval_frequency,\n            early_stopping_rounds=(args.early_stopping_num_evals * args.min_eval_frequency),\n            early_stopping_metric='accuracy',\n            early_stopping_metric_minimize=False)\n      else:\n        early_stop_monitor = tf.contrib.learn.monitors.ValidationMonitor(\n            input_fn=input_reader_for_eval,\n            every_n_steps=args.min_eval_frequency,\n            early_stopping_rounds=(args.early_stopping_num_evals * args.min_eval_frequency))\n      train_monitors = [early_stop_monitor]\n\n    return tf.contrib.learn.Experiment(\n        estimator=estimator,\n        train_input_fn=input_reader_for_train,\n        eval_input_fn=input_reader_for_eval,\n        train_steps=args.max_steps,\n        train_monitors=train_monitors,\n        export_strategies=[export_strategy_csv_notarget, export_strategy_csv_target],\n        min_eval_frequency=args.min_eval_frequency,\n        eval_steps=None)\n\n  # Return a function to create an Experiment.\n  return get_experiment\n\n\ndef local_analysis(args):\n  if args.analysis:\n    # Already analyzed.\n    return\n\n  if not args.schema or not args.features:\n    raise ValueError('Either --analysis, or both --schema and --features are provided.')\n\n  tf_config = json.loads(os.environ.get('TF_CONFIG', '{}'))\n  cluster_spec = tf_config.get('cluster', {})\n  if len(cluster_spec.get('worker', [])) > 0:\n    raise ValueError('If \"schema\" and \"features\" are provided, local analysis will run and ' +\n                     'only BASIC scale-tier (no workers node) is supported.')\n\n  if cluster_spec and not (args.schema.startswith('gs://') and args.features.startswith('gs://')):\n    raise ValueError('Cloud trainer requires GCS paths for --schema and --features.')\n\n  print('Running analysis.')\n  schema = json.loads(file_io.read_file_to_string(args.schema).decode())\n  features = json.loads(file_io.read_file_to_string(args.features).decode())\n  args.analysis = os.path.join(args.job_dir, 'analysis')\n  args.transform = True\n  file_io.recursive_create_dir(args.analysis)\n  feature_analysis.run_local_analysis(args.analysis, args.train, schema, features)\n  print('Analysis done.')\n\n\ndef set_logging_level(args):\n  if 'TF_CONFIG' in os.environ:\n    tf.logging.set_verbosity(tf.logging.INFO)\n  else:\n    tf.logging.set_verbosity(tf.logging.ERROR)\n  if args.logging_level == 'error':\n    tf.logging.set_verbosity(tf.logging.ERROR)\n  elif args.logging_level == 'warning':\n    tf.logging.set_verbosity(tf.logging.WARN)\n  elif args.logging_level == 'info':\n    tf.logging.set_verbosity(tf.logging.INFO)\n\n\ndef main(argv=None):\n  args = parse_arguments(sys.argv if argv is None else argv)\n  local_analysis(args)\n  set_logging_level(args)\n  # Supress TensorFlow Debugging info.\n  os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'\n\n  learn_runner.run(\n      experiment_fn=get_experiment_fn(args),\n      output_dir=args.job_dir)\n\n\nif __name__ == '__main__':\n  main()\n"
  },
  {
    "path": "solutionbox/ml_workbench/tensorflow/transform.py",
    "content": "# Copyright 2017 Google Inc. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n# Flake8 cannot disable a warning for the file. Flake8 does not like beam code\n# and reports many 'W503 line break before binary operator' errors. So turn off\n# flake8 for this file.\n# flake8: noqa\nfrom __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport argparse\nimport datetime\nimport json\nimport logging\nimport os\nimport sys\nimport apache_beam as beam\nimport textwrap\n\n\ndef parse_arguments(argv):\n  \"\"\"Parse command line arguments.\n  Args:\n    argv: list of command line arguments including program name.\n  Returns:\n    The parsed arguments as returned by argparse.ArgumentParser.\n  \"\"\"\n  parser = argparse.ArgumentParser(\n      formatter_class=argparse.RawDescriptionHelpFormatter,\n      description=textwrap.dedent(\"\"\"\\\n          Runs preprocessing on raw data for TensorFlow training.\n\n          This script applies some transformations to raw data to improve\n          training performance. Some data transformations can be expensive\n          such as the tf-idf text column transformation. During training, the\n          same raw data row might be used multiply times to train a model. This\n          means the same transformations are applied to the same data row\n          multiple times. This can be very inefficient, so this script applies\n          partial transformations to the raw data and writes an intermediate \n          preprocessed datasource to disk for training. \n\n          Running this transformation step is required for two usage paths:\n            1) If the img_url_to_vec transform is used. This is because\n               preprocessing as image is expensive and TensorFlow cannot easily\n               read raw image files during training.\n            2) If the raw data is in BigQuery. TensorFlow cannot read from a \n               BigQuery source.\n\n          Running this transformation step is recommended if a text transform is\n          used (like tf-idf or bag-of-words), and the text value for each row\n          is very long.\n\n          Running this transformation step may not have an interesting training\n          performance impact if the transforms are all simple like scaling\n          numerical values.\"\"\"))\n\n  source_group = parser.add_mutually_exclusive_group(required=True)\n\n  source_group.add_argument(\n      '--csv',\n      metavar='FILE',\n      required=False,\n      action='append',\n      help='CSV data to transform.')\n\n  source_group.add_argument(\n      '--bigquery',\n      metavar='PROJECT_ID.DATASET.TABLE_NAME',\n      type=str,\n      required=False,\n      help=('Must be in the form `project.dataset.table_name`. BigQuery '\n            'data to transform'))\n\n  parser.add_argument(\n      '--analysis',\n      metavar='ANALYSIS_OUTPUT_DIR',\n      required=True,\n      help='The output folder of analyze')\n\n  parser.add_argument(\n      '--prefix',\n      metavar='OUTPUT_FILENAME_PREFIX',\n      required=True,\n      type=str)\n\n  parser.add_argument(\n      '--output',\n      metavar='DIR',\n      default=None,\n      required=True,\n      help=('Google Cloud Storage or Local directory in which '\n            'to place outputs.'))\n\n  parser.add_argument(\n      '--shuffle',\n      action='store_true',\n      default=False,\n      help='If used, data source is shuffled. This is recommended for training data.')\n\n  parser.add_argument(\n      '--batch-size',\n      metavar='N',\n      type=int,\n      default=100,\n      help='Larger values increase performance and peak memory usage.')\n\n  cloud_group = parser.add_argument_group(\n      title='Cloud Parameters',\n      description='These parameters are only used if --cloud is used.')\n\n  cloud_group.add_argument(\n      '--cloud',\n      action='store_true',\n      help='Run preprocessing on the cloud.')\n\n  cloud_group.add_argument(\n      '--job-name',\n      type=str,\n      help='Unique dataflow job name.')\n\n  cloud_group.add_argument(\n      '--project-id',\n      help='The project to which the job will be submitted.')\n\n  cloud_group.add_argument(\n      '--num-workers',\n      metavar='N',\n      type=int,\n      default=0,\n      help='Set to 0 to use the default size determined by the Dataflow service.')\n\n  cloud_group.add_argument(\n      '--worker-machine-type',\n      metavar='NAME',\n      type=str,\n      help='A machine name from https://cloud.google.com/compute/docs/machine-types. '\n           ' If not given, the service uses the default machine type.')\n\n  cloud_group.add_argument(\n      '--async',\n      action='store_true',\n      help='If used, this script returns before the dataflow job is completed.')\n\n  args = parser.parse_args(args=argv[1:])\n\n  if args.cloud and not args.project_id:\n    raise ValueError('--project-id is needed for --cloud')\n\n  if args.async and not args.cloud:\n    raise ValueError('--async should only be used with --cloud')\n\n  if not args.job_name:\n    args.job_name = ('dataflow-job-{}'.format(\n        datetime.datetime.now().strftime('%Y%m%d%H%M%S')))\n  return args\n\n\n@beam.ptransform_fn\ndef shuffle(pcoll):  # pylint: disable=invalid-name\n  import random\n  return (pcoll\n          | 'PairWithRandom' >> beam.Map(lambda x: (random.random(), x))\n          | 'GroupByRandom' >> beam.GroupByKey()\n          | 'DropRandom' >> beam.FlatMap(lambda (k, vs): vs))\n\n\ndef image_transform_columns(features):\n  \"\"\"Returns a list of columns that prepare_image_transforms() should run on.\n\n  Because of beam + pickle, IMAGE_URL_TO_VEC_TRANSFORM cannot be used inside of\n  a beam function, so we extract the columns prepare_image_transforms() should \n  run on outside of beam.\n  \"\"\"\n  import six\n  from trainer import feature_transforms\n\n  img_cols = []\n  for name, transform in six.iteritems(features):\n    if transform['transform'] == feature_transforms.IMAGE_TRANSFORM:\n      img_cols.append(name)\n\n  return img_cols\n\n\ndef prepare_image_transforms(element, image_columns):\n  \"\"\"Replace an images url with its jpeg bytes.\n\n  Args: \n    element: one input row, as a dict\n    image_columns: list of columns that are image paths\n\n  Return:\n    element, where each image file path has been replaced by a base64 image.\n  \"\"\"\n  import base64\n  import cStringIO\n  from PIL import Image\n  from tensorflow.python.lib.io import file_io as tf_file_io\n  from apache_beam.metrics import Metrics\n\n  img_error_count = Metrics.counter('main', 'ImgErrorCount')\n  img_missing_count = Metrics.counter('main', 'ImgMissingCount')\n\n  for name in image_columns:\n    uri = element[name]\n    if not uri:\n      img_missing_count.inc()\n      continue\n    try:\n      with tf_file_io.FileIO(uri, 'r') as f:\n        img = Image.open(f).convert('RGB')\n\n    # A variety of different calling libraries throw different exceptions here.\n    # They all correspond to an unreadable file so we treat them equivalently.\n    # pylint: disable broad-except\n    except Exception as e:\n      logging.exception('Error processing image %s: %s', uri, str(e))\n      img_error_count.inc()\n      return\n\n    # Convert to desired format and output.\n    output = cStringIO.StringIO()\n    img.save(output, 'jpeg')\n    element[name] = base64.urlsafe_b64encode(output.getvalue())\n\n  return element\n\n\nclass EmitAsBatchDoFn(beam.DoFn):\n  \"\"\"A DoFn that buffers the records and emits them batch by batch.\"\"\"\n\n  def __init__(self, batch_size):\n    \"\"\"Constructor of EmitAsBatchDoFn beam.DoFn class.\n\n    Args:\n      batch_size: the max size we want to buffer the records before emitting.\n    \"\"\"\n    self._batch_size = batch_size\n    self._cached = []\n\n  def process(self, element):\n    self._cached.append(element)\n    if len(self._cached) >= self._batch_size:\n      emit = self._cached\n      self._cached = []\n      yield emit\n\n  def finish_bundle(self, element=None):\n    from apache_beam.transforms import window\n    from apache_beam.utils.windowed_value import WindowedValue\n\n    if len(self._cached) > 0:  # pylint: disable=g-explicit-length-test\n      yield WindowedValue(self._cached, -1, [window.GlobalWindow()])\n\n\nclass TransformFeaturesDoFn(beam.DoFn):\n  \"\"\"Converts raw data into transformed data.\"\"\"\n\n  def __init__(self, analysis_output_dir, features, schema, stats):\n    self._analysis_output_dir = analysis_output_dir\n    self._features = features\n    self._schema = schema\n    self._stats = stats\n    self._session = None\n\n  def start_bundle(self, element=None):\n    \"\"\"Build the transfromation graph once.\"\"\"\n    import tensorflow as tf\n    from trainer import feature_transforms\n\n    g = tf.Graph()\n    session = tf.Session(graph=g)\n\n    # Build the transformation graph\n    with g.as_default():\n      transformed_features, _, placeholders = (\n          feature_transforms.build_csv_serving_tensors_for_transform_step(\n              analysis_path=self._analysis_output_dir, \n              features=self._features, \n              schema=self._schema,\n              stats=self._stats,\n              keep_target=True))\n      session.run(tf.tables_initializer())\n    \n    self._session = session\n    self._transformed_features = transformed_features\n    self._input_placeholder_tensor = placeholders['csv_example']\n\n  def finish_bundle(self, element=None):\n    self._session.close()\n\n  def process(self, element):\n    \"\"\"Run the transformation graph on batched input data\n\n    Args:\n      element: list of csv strings, representing one batch input to the TF graph.\n\n    Returns:\n      dict containing the transformed data. Results are un-batched. Sparse\n      tensors are converted to lists.\n    \"\"\"\n    import apache_beam as beam\n    import six\n    import tensorflow as tf\n\n    # This function is invoked by a separate sub-process so setting the logging level\n    # does not affect Datalab's kernel process.\n    tf.logging.set_verbosity(tf.logging.ERROR)\n    try:\n      clean_element = []\n      for line in element:\n        clean_element.append(line.rstrip())\n\n      # batch_result is list of numpy arrays with batch_size many rows.\n      batch_result = self._session.run(\n          fetches=self._transformed_features,\n          feed_dict={self._input_placeholder_tensor: clean_element})\n\n      # ex batch_result. \n      # Dense tensor: {'col1': array([[batch_1], [batch_2]])}\n      # Sparse tensor: {'col1': tf.SparseTensorValue(\n      #   indices=array([[batch_1, 0], [batch_1, 1], ...,\n      #                  [batch_2, 0], [batch_2, 1], ...]],\n      #   values=array[value, value, value, ...])}\n\n      # Unbatch the results.\n      for i in range(len(clean_element)):\n        transformed_features = {}\n        for name, value in six.iteritems(batch_result):\n          if isinstance(value, tf.SparseTensorValue):\n            batch_i_indices = value.indices[:, 0] == i\n            batch_i_values = value.values[batch_i_indices]\n            transformed_features[name] = batch_i_values.tolist()\n          else:\n            transformed_features[name] = value[i].tolist()\n\n        yield transformed_features\n\n    except Exception as e:  # pylint: disable=broad-except\n      yield beam.pvalue.TaggedOutput('errors', (str(e), element))\n\n\ndef decode_csv(csv_string, column_names):\n  \"\"\"Parse a csv line into a dict.\n\n  Args:\n    csv_string: a csv string. May contain missing values \"a,,c\"\n    column_names: list of column names\n\n  Returns:\n    Dict of {column_name, value_from_csv}. If there are missing values, \n    value_from_csv will be ''.\n  \"\"\"\n  import csv\n  r = next(csv.reader([csv_string]))\n  if len(r) != len(column_names):\n    raise ValueError('csv line %s does not have %d columns' % (csv_string, len(column_names)))\n  return {k: v for k, v in zip(column_names, r)}\n\n\ndef encode_csv(data_dict, column_names):\n  \"\"\"Builds a csv string.\n\n  Args:\n    data_dict: dict of {column_name: 1 value}\n    column_names: list of column names\n\n  Returns:\n    A csv string version of data_dict\n  \"\"\"\n  import csv\n  import six\n  values = [str(data_dict[x]) for x in column_names]\n  str_buff = six.StringIO()\n  writer = csv.writer(str_buff, lineterminator='')\n  writer.writerow(values)\n  return str_buff.getvalue()\n\n\ndef serialize_example(transformed_json_data, info_dict):\n  \"\"\"Makes a serialized tf.example.\n\n  Args:\n    transformed_json_data: dict of transformed data.\n    info_dict: output of feature_transforms.get_transfrormed_feature_info()\n\n  Returns:\n    The serialized tf.example version of transformed_json_data.\n  \"\"\"\n  import six\n  import tensorflow as tf\n\n  def _make_int64_list(x):\n    return tf.train.Feature(int64_list=tf.train.Int64List(value=x))\n  def _make_bytes_list(x):\n    return tf.train.Feature(bytes_list=tf.train.BytesList(value=x))\n  def _make_float_list(x):\n    return tf.train.Feature(float_list=tf.train.FloatList(value=x))\n\n  if sorted(six.iterkeys(transformed_json_data)) != sorted(six.iterkeys(info_dict)):\n    raise ValueError('Keys do not match %s, %s' % (list(six.iterkeys(transformed_json_data)),\n                     list(six.iterkeys(info_dict))))\n\n  ex_dict = {}\n  for name, info in six.iteritems(info_dict):\n    if info['dtype'] == tf.int64:\n      ex_dict[name] = _make_int64_list(transformed_json_data[name])\n    elif info['dtype'] == tf.float32:\n      ex_dict[name] = _make_float_list(transformed_json_data[name])\n    elif info['dtype'] == tf.string:\n      ex_dict[name] = _make_bytes_list(transformed_json_data[name])      \n    else:\n      raise ValueError('Unsupported data type %s' % info['dtype'])\n\n  ex = tf.train.Example(features=tf.train.Features(feature=ex_dict))\n  return ex.SerializeToString()\n\n\ndef preprocess(pipeline, args):\n  \"\"\"Transfrom csv data into transfromed tf.example files.\n\n  Outline:\n    1) read the input data (as csv or bigquery) into a dict format\n    2) replace image paths with base64 encoded image files\n    3) build a csv input string with images paths replaced with base64. This \n       matches the serving csv that a trained model would expect.\n    4) batch the csv strings\n    5) run the transformations\n    6) write the results to tf.example files and save any errors.\n  \"\"\"\n  from tensorflow.python.lib.io import file_io\n  from trainer import feature_transforms\n\n  schema = json.loads(file_io.read_file_to_string(\n      os.path.join(args.analysis, feature_transforms.SCHEMA_FILE)).decode())\n  features = json.loads(file_io.read_file_to_string(\n      os.path.join(args.analysis, feature_transforms.FEATURES_FILE)).decode())\n  stats = json.loads(file_io.read_file_to_string(\n      os.path.join(args.analysis, feature_transforms.STATS_FILE)).decode())\n\n  column_names = [col['name'] for col in schema]\n\n  if args.csv:\n    all_files = []\n    for i, file_pattern in enumerate(args.csv):\n      all_files.append(pipeline | ('ReadCSVFile%d' % i) >> beam.io.ReadFromText(file_pattern))\n    raw_data = (\n        all_files\n        | 'MergeCSVFiles' >> beam.Flatten()\n        | 'ParseCSVData' >> beam.Map(decode_csv, column_names))\n  else:\n    columns = ', '.join(column_names)\n    query = 'SELECT {columns} FROM `{table}`'.format(columns=columns,\n                                                     table=args.bigquery)\n    raw_data = (\n        pipeline\n        | 'ReadBiqQueryData'\n        >> beam.io.Read(beam.io.BigQuerySource(query=query,\n                                               use_standard_sql=True)))\n\n  # Note that prepare_image_transforms does not make embeddings, it justs reads\n  # the image files and converts them to byte stings. TransformFeaturesDoFn()\n  # will make the image embeddings.\n  image_columns = image_transform_columns(features)\n  \n  clean_csv_data = (\n      raw_data\n      | 'PreprocessTransferredLearningTransformations'\n      >> beam.Map(prepare_image_transforms, image_columns)\n      | 'BuildCSVString'\n      >> beam.Map(encode_csv, column_names))\n\n  if args.shuffle:\n    clean_csv_data = clean_csv_data | 'ShuffleData' >> shuffle()\n\n  transform_dofn = TransformFeaturesDoFn(args.analysis, features, schema, stats)\n  (transformed_data, errors) = (\n       clean_csv_data\n       | 'Batch Input' \n       >> beam.ParDo(EmitAsBatchDoFn(args.batch_size)) \n       | 'Run TF Graph on Batches' \n       >> beam.ParDo(transform_dofn).with_outputs('errors', main='main'))\n\n  _ = (transformed_data\n        | 'SerializeExamples' >> beam.Map(serialize_example, feature_transforms.get_transformed_feature_info(features, schema))\n        | 'WriteExamples'\n        >> beam.io.WriteToTFRecord(\n            os.path.join(args.output, args.prefix),\n            file_name_suffix='.tfrecord.gz'))\n  _ = (errors\n       | 'WriteErrors'\n       >> beam.io.WriteToText(\n           os.path.join(args.output, 'errors_' + args.prefix),\n           file_name_suffix='.txt'))\n\n\ndef main(argv=None):\n  \"\"\"Run Preprocessing as a Dataflow.\"\"\"\n  args = parse_arguments(sys.argv if argv is None else argv)\n  temp_dir = os.path.join(args.output, 'tmp')\n\n  if args.cloud:\n    pipeline_name = 'DataflowRunner'\n  else:\n    pipeline_name = 'DirectRunner'\n    # Suppress TF warnings.\n    os.environ['TF_CPP_MIN_LOG_LEVEL']='3'\n\n  options = {\n      'job_name': args.job_name,\n      'temp_location': temp_dir,\n      'project': args.project_id,\n      'setup_file':\n          os.path.abspath(os.path.join(\n              os.path.dirname(__file__),\n              'setup.py')),\n  }\n  if args.num_workers:\n    options['num_workers'] = args.num_workers\n  if args.worker_machine_type:\n    options['worker_machine_type'] = args.worker_machine_type\n\n  pipeline_options = beam.pipeline.PipelineOptions(flags=[], **options)\n\n  p = beam.Pipeline(pipeline_name, options=pipeline_options)\n  preprocess(pipeline=p, args=args)\n  pipeline_result = p.run()\n\n  if not args.async:\n    pipeline_result.wait_until_finish()\n  if args.async and args.cloud:\n    print('View job at https://console.developers.google.com/dataflow/job/%s?project=%s' %\n        (pipeline_result.job_id(), args.project_id))\n\n\nif __name__ == '__main__':\n  main()\n"
  },
  {
    "path": "solutionbox/ml_workbench/test_tensorflow/run_all.sh",
    "content": "#! /bin/bash\nset -e\n\necho '*** Running tensorflow test_analyze.py ***'\npython test_analyze.py --verbose\n\necho '*** Running tensorflow test_feature_transforms.py ***'\npython test_feature_transforms.py --verbose\n\necho '*** Running tensorflow test_transform.py ***'\npython test_transform.py --verbose\n\necho '*** Running tensorflow test_training.py ***'\npython test_training.py --verbose\n\necho 'Finished tensorflow run_all.sh!'\n"
  },
  {
    "path": "solutionbox/ml_workbench/test_tensorflow/test_analyze.py",
    "content": "from __future__ import absolute_import\nfrom __future__ import print_function\n\nimport json\nimport os\nimport shutil\nimport subprocess\nimport sys\nimport tempfile\nimport uuid\nimport unittest\nimport pandas as pd\nimport six\n\nfrom tensorflow.python.lib.io import file_io\n\nimport google.datalab as dl\nimport google.datalab.bigquery as bq\nimport google.datalab.storage as storage\n\n# To make 'import analyze' work without installing it.\nCODE_PATH = os.path.abspath(\n    os.path.join(os.path.dirname(__file__), '..', '', 'tensorflow'))\nsys.path.append(CODE_PATH)\n\n\nfrom trainer import feature_analysis as feature_analysis  # noqa: E303\nimport analyze  # noqa: E303\n\n\n# TODO: travis tests failed because sometimes a VM has gcloud signed-in\n# (maybe due to failed cleanup) with default project set and BQ is not enabled.\n# In that case the cloud tests will fail. Disable it for now.\nRUN_CLOUD_TESTS = False\n\n\nclass TestConfigFiles(unittest.TestCase):\n  \"\"\"Tests for checking the format between the schema and features files.\"\"\"\n\n  def test_expand_defaults_do_nothing(self):\n    schema = [{'name': 'col1', 'type': 'FLOAT'},\n              {'name': 'col2', 'type': 'INTEGER'}]\n    features = {'col1': {'transform': 'x'},\n                'col2': {'transform': 'y'}}\n    expected_features = {\n        'col1': {'transform': 'x', 'source_column': 'col1'},\n        'col2': {'transform': 'y', 'source_column': 'col2'}}\n\n    feature_analysis.expand_defaults(schema, features)\n\n    # Nothing should change.\n    self.assertEqual(expected_features, features)\n\n  def test_expand_defaults_unknown_schema_type(self):\n    schema = [{'name': 'col1', 'type': 'BYTES'},\n              {'name': 'col2', 'type': 'INTEGER'}]\n    features = {'col1': {'transform': 'x'},\n                'col2': {'transform': 'y'}}\n\n    with self.assertRaises(ValueError):\n      feature_analysis.expand_defaults(schema, features)\n\n  def test_expand_defaults(self):\n    schema = [{'name': 'col1', 'type': 'FLOAT'},\n              {'name': 'col2', 'type': 'INTEGER'},\n              {'name': 'col3', 'type': 'STRING'},\n              {'name': 'col4', 'type': 'FLOAT'},\n              {'name': 'col5', 'type': 'INTEGER'},\n              {'name': 'col6', 'type': 'STRING'}]\n    features = {'col1': {'transform': 'x'},\n                'col2': {'transform': 'y'},\n                'col3': {'transform': 'z'}}\n\n    feature_analysis.expand_defaults(schema, features)\n\n    self.assertEqual(\n      features,\n      {'col1': {'transform': 'x', 'source_column': 'col1'},\n       'col2': {'transform': 'y', 'source_column': 'col2'},\n       'col3': {'transform': 'z', 'source_column': 'col3'},\n       'col4': {'transform': 'identity', 'source_column': 'col4'},\n       'col5': {'transform': 'identity', 'source_column': 'col5'},\n       'col6': {'transform': 'one_hot', 'source_column': 'col6'}})\n\n  def test_check_schema_transforms_match(self):\n    with self.assertRaises(ValueError):\n      feature_analysis.check_schema_transforms_match(\n         [{'name': 'col1', 'type': 'INTEGER'}],\n         feature_analysis.invert_features(\n             {'col1': {'transform': 'one_hot', 'source_column': 'col1'}}))\n\n    with self.assertRaises(ValueError):\n      feature_analysis.check_schema_transforms_match(\n         [{'name': 'col1', 'type': 'FLOAT'}],\n         feature_analysis.invert_features(\n             {'col1': {'transform': 'embedding', 'source_column': 'col1'}}))\n\n    with self.assertRaises(ValueError):\n      feature_analysis.check_schema_transforms_match(\n         [{'name': 'col1', 'type': 'STRING'}],\n         feature_analysis.invert_features(\n             {'col1': {'transform': 'scale', 'source_column': 'col1'}}))\n\n    with self.assertRaises(ValueError):\n      feature_analysis.check_schema_transforms_match(\n         [{'name': 'col1', 'type': 'xxx'}],\n         feature_analysis.invert_features(\n             {'col1': {'transform': 'scale', 'source_column': 'col1'}}))\n\n    with self.assertRaises(ValueError):\n      feature_analysis.check_schema_transforms_match(\n         [{'name': 'col1', 'type': 'INTEGER'}],\n         feature_analysis.invert_features(\n             {'col1': {'transform': 'xxx', 'source_column': 'col1'}}))\n\n    with self.assertRaises(ValueError):\n      # scale and one_hot different transform family\n      feature_analysis.check_schema_transforms_match(\n         [{'name': 'col1', 'type': 'INTEGER'}],\n         feature_analysis.invert_features(\n            {'col1': {'transform': 'scale', 'source_column': 'col1'},\n             'col2': {'transform': 'one_hot', 'source_column': 'col1'},\n             'col3': {'transform': 'key', 'source_column': 'col1'}}))\n\n    with self.assertRaises(ValueError):\n      # Unknown transform\n      feature_analysis.check_schema_transforms_match(\n         [{'name': 'col1', 'type': 'INTEGER'}],\n         feature_analysis.invert_features({'col1': {'transform': 'x', 'source_column': 'col1'}}))\n\n\nclass TestLocalAnalyze(unittest.TestCase):\n  \"\"\"Test local analyze functions.\"\"\"\n\n  def test_numerics(self):\n    output_folder = tempfile.mkdtemp()\n    input_file_path = tempfile.mkstemp(dir=output_folder)[1]\n    try:\n      file_io.write_string_to_file(\n        input_file_path,\n        '\\n'.join(['%s,%s,%s' % (i, 10 * i + 0.5, i + 0.5) for i in range(100)]))\n\n      schema = [{'name': 'col1', 'type': 'INTEGER'},\n                {'name': 'col2', 'type': 'FLOAT'},\n                {'name': 'col3', 'type': 'FLOAT'}]\n      features = {'col1': {'transform': 'scale', 'source_column': 'col1'},\n                  'col2': {'transform': 'identity', 'source_column': 'col2'},\n                  'col3': {'transform': 'target'}}\n      feature_analysis.run_local_analysis(\n          output_folder, [input_file_path], schema, features)\n\n      stats = json.loads(\n          file_io.read_file_to_string(\n              os.path.join(output_folder, analyze.constant.STATS_FILE)).decode())\n\n      self.assertEqual(stats['num_examples'], 100)\n      col = stats['column_stats']['col1']\n      self.assertAlmostEqual(col['max'], 99.0)\n      self.assertAlmostEqual(col['min'], 0.0)\n      self.assertAlmostEqual(col['mean'], 49.5)\n\n      col = stats['column_stats']['col2']\n      self.assertAlmostEqual(col['max'], 990.5)\n      self.assertAlmostEqual(col['min'], 0.5)\n      self.assertAlmostEqual(col['mean'], 495.5)\n    finally:\n      shutil.rmtree(output_folder)\n\n  def test_categorical(self):\n    output_folder = tempfile.mkdtemp()\n    input_file_path = tempfile.mkstemp(dir=output_folder)[1]\n    try:\n      csv_file = ['red,car,apple', 'red,truck,pepper', 'red,van,apple', 'blue,bike,grape',\n                  'blue,train,apple', 'green,airplane,pepper']\n      file_io.write_string_to_file(\n        input_file_path,\n        '\\n'.join(csv_file))\n\n      schema = [{'name': 'color', 'type': 'STRING'},\n                {'name': 'transport', 'type': 'STRING'},\n                {'name': 'type', 'type': 'STRING'}]\n      features = {'color': {'transform': 'one_hot', 'source_column': 'color'},\n                  'transport': {'transform': 'embedding', 'source_column': 'transport'},\n                  'type': {'transform': 'target'}}\n      feature_analysis.run_local_analysis(\n        output_folder, [input_file_path], schema, features)\n\n      stats = json.loads(\n          file_io.read_file_to_string(\n              os.path.join(output_folder, analyze.constant.STATS_FILE)).decode())\n      self.assertEqual(stats['column_stats']['color']['vocab_size'], 3)\n      self.assertEqual(stats['column_stats']['transport']['vocab_size'], 6)\n\n      # Color column.\n      vocab_str = file_io.read_file_to_string(\n        os.path.join(output_folder, analyze.constant.VOCAB_ANALYSIS_FILE % 'color'))\n      vocab = pd.read_csv(six.StringIO(vocab_str),\n                          header=None,\n                          names=['color', 'count'])\n      expected_vocab = pd.DataFrame(\n          {'color': ['red', 'blue', 'green'], 'count': [3, 2, 1]},\n          columns=['color', 'count'])\n      pd.util.testing.assert_frame_equal(vocab, expected_vocab)\n\n      # transport column. As each vocab has the same count, order in file is\n      # not known.\n      vocab_str = file_io.read_file_to_string(\n          os.path.join(output_folder,\n                       analyze.constant.VOCAB_ANALYSIS_FILE % 'transport'))\n      vocab = pd.read_csv(six.StringIO(vocab_str),\n                          header=None,\n                          names=['transport', 'count'])\n      self.assertEqual(vocab['count'].tolist(), [1 for i in range(6)])\n      self.assertItemsEqual(vocab['transport'].tolist(),\n                            ['car', 'truck', 'van', 'bike', 'train', 'airplane'])\n    finally:\n      shutil.rmtree(output_folder)\n\n  def test_text(self):\n    output_folder = tempfile.mkdtemp()\n    input_file_path = tempfile.mkstemp(dir=output_folder)[1]\n    try:\n      csv_file = ['the quick brown fox,raining in kir,cat1|cat2,true',\n                  'quick   brown brown chicken,raining in pdx,cat2|cat3|cat4,false']\n      file_io.write_string_to_file(\n        input_file_path,\n        '\\n'.join(csv_file))\n\n      schema = [{'name': 'col1', 'type': 'STRING'},\n                {'name': 'col2', 'type': 'STRING'},\n                {'name': 'col3', 'type': 'STRING'},\n                {'name': 'col4', 'type': 'STRING'}]\n      features = {'col1': {'transform': 'bag_of_words', 'source_column': 'col1'},\n                  'col2': {'transform': 'tfidf', 'source_column': 'col2'},\n                  'col3': {'transform': 'multi_hot', 'source_column': 'col3', 'separator': '|'},\n                  'col4': {'transform': 'target'}}\n      feature_analysis.run_local_analysis(\n        output_folder, [input_file_path], schema, features)\n\n      stats = json.loads(\n          file_io.read_file_to_string(\n              os.path.join(output_folder, analyze.constant.STATS_FILE)).decode())\n      self.assertEqual(stats['column_stats']['col1']['vocab_size'], 5)\n      self.assertEqual(stats['column_stats']['col2']['vocab_size'], 4)\n      self.assertEqual(stats['column_stats']['col3']['vocab_size'], 4)\n\n      vocab_str = file_io.read_file_to_string(\n          os.path.join(output_folder,\n                       analyze.constant.VOCAB_ANALYSIS_FILE % 'col1'))\n      vocab = pd.read_csv(six.StringIO(vocab_str),\n                          header=None,\n                          names=['col1', 'count'])\n\n      # vocabs are sorted by count only\n      col1_vocab = vocab['col1'].tolist()\n      self.assertItemsEqual(col1_vocab[:2], ['brown', 'quick'])\n      self.assertItemsEqual(col1_vocab[2:], ['chicken', 'fox', 'the'])\n      self.assertEqual(vocab['count'].tolist(), [2, 2, 1, 1, 1])\n\n      vocab_str = file_io.read_file_to_string(\n          os.path.join(output_folder,\n                       analyze.constant.VOCAB_ANALYSIS_FILE % 'col2'))\n      vocab = pd.read_csv(six.StringIO(vocab_str),\n                          header=None,\n                          names=['col2', 'count'])\n\n      # vocabs are sorted by count only\n      col2_vocab = vocab['col2'].tolist()\n      self.assertItemsEqual(col2_vocab[:2], ['in', 'raining'])\n      self.assertItemsEqual(col2_vocab[2:], ['kir', 'pdx'])\n      self.assertEqual(vocab['count'].tolist(), [2, 2, 1, 1])\n    finally:\n      shutil.rmtree(output_folder)\n\n\n@unittest.skipIf(not RUN_CLOUD_TESTS, 'GCS access missing')\nclass TestCloudAnalyzeFromBQTable(unittest.TestCase):\n  \"\"\"Test the analyze functions using data in a BigQuery table.\n\n  As the SQL statements do not change if the BigQuery source is csv fiels or a\n  real table, there is no need to test every SQL analyze statement. We only run\n  one test to make sure this path works.\n  \"\"\"\n\n  def test_numerics(self):\n    \"\"\"Build a BQ table, and then call analyze on it.\"\"\"\n    schema = [{'name': 'col1', 'type': 'INTEGER'},\n              {'name': 'col2', 'type': 'FLOAT'},\n              {'name': 'col3', 'type': 'FLOAT'}]\n    project_id = dl.Context.default().project_id\n    dataset_name = 'temp_pydatalab_test_%s' % uuid.uuid4().hex\n    table_name = 'temp_table'\n    full_table_name = '%s.%s.%s' % (project_id, dataset_name, table_name)\n\n    output_folder = tempfile.mkdtemp()\n\n    try:\n      # Make a dataset, a table, and insert data.\n      db = bq.Dataset((project_id, dataset_name))\n      db.create()\n\n      table = bq.Table(full_table_name)\n      table.create(schema=bq.Schema(schema), overwrite=True)\n\n      data = [{'col1': i, 'col2': 10 * i + 0.5, 'col3': i + 0.5} for i in range(100)]\n      table.insert(data)\n\n      features = {'col1': {'transform': 'scale', 'source_column': 'col1'},\n                  'col2': {'transform': 'identity', 'source_column': 'col2'},\n                  'col3': {'transform': 'target'}}\n      analyze.run_cloud_analysis(\n          output_dir=output_folder,\n          csv_file_pattern=None,\n          bigquery_table=full_table_name,\n          schema=schema,\n          features=features)\n\n      stats = json.loads(\n          file_io.read_file_to_string(\n              os.path.join(output_folder, analyze.constant.STATS_FILE)).decode())\n\n      self.assertEqual(stats['num_examples'], 100)\n      col = stats['column_stats']['col1']\n      self.assertAlmostEqual(col['max'], 99.0)\n      self.assertAlmostEqual(col['min'], 0.0)\n      self.assertAlmostEqual(col['mean'], 49.5)\n\n      col = stats['column_stats']['col2']\n      self.assertAlmostEqual(col['max'], 990.5)\n      self.assertAlmostEqual(col['min'], 0.5)\n      self.assertAlmostEqual(col['mean'], 495.5)\n    finally:\n      shutil.rmtree(output_folder)\n      db.delete(delete_contents=True)\n\n\n@unittest.skipIf(not RUN_CLOUD_TESTS, 'GCS access missing')\nclass TestCloudAnalyzeFromCSVFiles(unittest.TestCase):\n  \"\"\"Test the analyze function using BigQuery from csv files that are on GCS.\"\"\"\n\n  @classmethod\n  def setUpClass(cls):\n    cls._bucket_name = 'temp_pydatalab_test_%s' % uuid.uuid4().hex\n    cls._bucket_root = 'gs://%s' % cls._bucket_name\n    storage.Bucket(cls._bucket_name).create()\n\n  @classmethod\n  def tearDownClass(cls):\n    bucket = storage.Bucket(cls._bucket_name)\n    for obj in bucket.objects():\n      obj.delete()\n    bucket.delete()\n\n  def test_numerics(self):\n    test_folder = os.path.join(self._bucket_root, 'test_numerics')\n    input_file_path = os.path.join(test_folder, 'input.csv')\n    output_folder = os.path.join(test_folder, 'test_output')\n    file_io.recursive_create_dir(output_folder)\n\n    file_io.write_string_to_file(\n      input_file_path,\n      '\\n'.join(['%s,%s,%s' % (i, 10 * i + 0.5, i) for i in range(100)]))\n\n    schema = [{'name': 'col1', 'type': 'INTEGER'},\n              {'name': 'col2', 'type': 'FLOAT'},\n              {'name': 'col3', 'type': 'FLOAT'}]\n    features = {'col1': {'transform': 'scale', 'source_column': 'col1'},\n                'col2': {'transform': 'identity', 'source_column': 'col2'},\n                'col3': {'transform': 'target'}}\n    analyze.run_cloud_analysis(\n        output_dir=output_folder,\n        csv_file_pattern=input_file_path,\n        bigquery_table=None,\n        schema=schema,\n        features=features)\n\n    stats = json.loads(\n        file_io.read_file_to_string(\n            os.path.join(output_folder, analyze.constant.STATS_FILE)).decode())\n\n    self.assertEqual(stats['num_examples'], 100)\n    col = stats['column_stats']['col1']\n    self.assertAlmostEqual(col['max'], 99.0)\n    self.assertAlmostEqual(col['min'], 0.0)\n    self.assertAlmostEqual(col['mean'], 49.5)\n\n    col = stats['column_stats']['col2']\n    self.assertAlmostEqual(col['max'], 990.5)\n    self.assertAlmostEqual(col['min'], 0.5)\n    self.assertAlmostEqual(col['mean'], 495.5)\n\n  def test_categorical(self):\n    test_folder = os.path.join(self._bucket_root, 'test_categorical')\n    input_file_path = os.path.join(test_folder, 'input.csv')\n    output_folder = os.path.join(test_folder, 'test_output')\n    file_io.recursive_create_dir(output_folder)\n\n    csv_file = ['red,car,apple', 'red,truck,pepper', 'red,van,apple', 'blue,bike,grape',\n                'blue,train,apple', 'green,airplane,pepper']\n    file_io.write_string_to_file(\n      input_file_path,\n      '\\n'.join(csv_file))\n\n    schema = [{'name': 'color', 'type': 'STRING'},\n              {'name': 'transport', 'type': 'STRING'},\n              {'name': 'type', 'type': 'STRING'}]\n    features = {'color': {'transform': 'one_hot', 'source_column': 'color'},\n                'transport': {'transform': 'embedding', 'source_column': 'transport'},\n                'type': {'transform': 'target'}}\n    analyze.run_cloud_analysis(\n        output_dir=output_folder,\n        csv_file_pattern=input_file_path,\n        bigquery_table=None,\n        schema=schema,\n        features=features)\n\n    stats = json.loads(\n        file_io.read_file_to_string(\n            os.path.join(output_folder, analyze.constant.STATS_FILE)).decode())\n    self.assertEqual(stats['column_stats']['color']['vocab_size'], 3)\n    self.assertEqual(stats['column_stats']['transport']['vocab_size'], 6)\n\n    # Color column.\n    vocab_str = file_io.read_file_to_string(\n      os.path.join(output_folder, analyze.constant.VOCAB_ANALYSIS_FILE % 'color'))\n    vocab = pd.read_csv(six.StringIO(vocab_str),\n                        header=None,\n                        names=['color', 'count'])\n    expected_vocab = pd.DataFrame(\n        {'color': ['red', 'blue', 'green'], 'count': [3, 2, 1]},\n        columns=['color', 'count'])\n    pd.util.testing.assert_frame_equal(vocab, expected_vocab)\n\n    # transport column.\n    vocab_str = file_io.read_file_to_string(\n        os.path.join(output_folder,\n                     analyze.constant.VOCAB_ANALYSIS_FILE % 'transport'))\n    vocab = pd.read_csv(six.StringIO(vocab_str),\n                        header=None,\n                        names=['transport', 'count'])\n    self.assertEqual(vocab['count'].tolist(), [1 for i in range(6)])\n    self.assertEqual(vocab['transport'].tolist(),\n                     ['airplane', 'bike', 'car', 'train', 'truck', 'van'])\n\n  def test_text(self):\n    test_folder = os.path.join(self._bucket_root, 'test_text')\n    input_file_path = os.path.join(test_folder, 'input.csv')\n    output_folder = os.path.join(test_folder, 'test_output')\n    file_io.recursive_create_dir(output_folder)\n\n    csv_file = ['the quick brown fox,raining in kir,cat1|cat2,true',\n                'quick   brown brown chicken,raining in pdx,cat2|cat3|cat4,false']\n    file_io.write_string_to_file(\n      input_file_path,\n      '\\n'.join(csv_file))\n\n    schema = [{'name': 'col1', 'type': 'STRING'},\n              {'name': 'col2', 'type': 'STRING'},\n              {'name': 'col3', 'type': 'STRING'},\n              {'name': 'col4', 'type': 'STRING'}]\n    features = {'col1': {'transform': 'bag_of_words', 'source_column': 'col1'},\n                'col2': {'transform': 'tfidf', 'source_column': 'col2'},\n                'col3': {'transform': 'multi_hot', 'source_column': 'col3', 'separator': '|'},\n                'col4': {'transform': 'target'}}\n    analyze.run_cloud_analysis(\n        output_dir=output_folder,\n        csv_file_pattern=input_file_path,\n        bigquery_table=None,\n        schema=schema,\n        features=features)\n\n    stats = json.loads(\n        file_io.read_file_to_string(\n            os.path.join(output_folder, analyze.constant.STATS_FILE)).decode())\n    self.assertEqual(stats['column_stats']['col1']['vocab_size'], 5)\n    self.assertEqual(stats['column_stats']['col2']['vocab_size'], 4)\n    self.assertEqual(stats['column_stats']['col3']['vocab_size'], 4)\n\n    vocab_str = file_io.read_file_to_string(\n        os.path.join(output_folder,\n                     analyze.constant.VOCAB_ANALYSIS_FILE % 'col1'))\n    vocab = pd.read_csv(six.StringIO(vocab_str),\n                        header=None,\n                        names=['col1', 'count'])\n    self.assertEqual(vocab['col1'].tolist(),\n                     ['brown', 'quick', 'chicken', 'fox', 'the', ])\n    self.assertEqual(vocab['count'].tolist(), [2, 2, 1, 1, 1])\n\n    vocab_str = file_io.read_file_to_string(\n        os.path.join(output_folder,\n                     analyze.constant.VOCAB_ANALYSIS_FILE % 'col2'))\n    vocab = pd.read_csv(six.StringIO(vocab_str),\n                        header=None,\n                        names=['col2', 'count'])\n    self.assertEqual(vocab['col2'].tolist(), ['in', 'raining', 'kir', 'pdx'])\n    self.assertEqual(vocab['count'].tolist(), [2, 2, 1, 1])\n\n\nclass TestOneSourceColumnManyFeatures(unittest.TestCase):\n  \"\"\"Test input column can be used more than once.\"\"\"\n\n  def test_multiple_usage(self):\n    def _make_csv_row(i):\n      \"\"\"Makes a csv file with the following header.\n\n      target,number,category,text,image\n      \"\"\"\n      return \"%d,%d,%s,%s,%s\" % (i * 2,\n                                 i,\n                                 'red' if i % 2 else 'blue',\n                                 'hello world' if i % 2 else 'bye moon',\n                                 '/image%d.jpeg' % i)\n\n    output_folder = tempfile.mkdtemp()\n    try:\n      input_data_path = tempfile.mkstemp(dir=output_folder, prefix='data')[1]\n      file_io.write_string_to_file(\n        input_data_path,\n        '\\n'.join([_make_csv_row(i) for i in range(100)]))\n\n      input_schema_path = tempfile.mkstemp(dir=output_folder, prefix='sch')[1]\n      file_io.write_string_to_file(\n        input_schema_path,\n        json.dumps([{'name': 'target', 'type': 'INTEGER'},\n                    {'name': 'int', 'type': 'INTEGER'},\n                    {'name': 'cat', 'type': 'STRING'},\n                    {'name': 'text', 'type': 'STRING'},\n                    {'name': 'img', 'type': 'STRING'}], indent=2))\n\n      input_feature_path = tempfile.mkstemp(dir=output_folder, prefix='feat')[1]\n      file_io.write_string_to_file(\n        input_feature_path,\n        json.dumps({'target': {'transform': 'target'},\n                    'int': {'transform': 'scale'},\n                    'int2': {'transform': 'identity', 'source_column': 'int'},\n                    'int3': {'transform': 'key', 'source_column': 'int'},\n                    'cat1': {'transform': 'one_hot', 'source_column': 'cat'},\n                    'cat2': {'transform': 'embedding', 'source_column': 'cat'},\n                    'text': {'transform': 'tfidf', 'source_column': 'text'},\n                    'text2': {'transform': 'bag_of_words', 'source_column': 'text'},\n                    'text3': {'transform': 'key', 'source_column': 'text'},\n                    'img': {'transform': 'image_to_vec'}}, indent=2))\n\n      cmd = ['python %s/analyze.py' % CODE_PATH,\n             '--output=' + output_folder,\n             '--csv=' + input_data_path,\n             '--schema=' + input_schema_path,\n             '--features=' + input_feature_path]\n      subprocess.check_call(' '.join(cmd), shell=True)\n\n      self.assertTrue(os.path.isfile(os.path.join(output_folder, 'vocab_cat.csv')))\n      self.assertTrue(os.path.isfile(os.path.join(output_folder, 'vocab_text.csv')))\n\n      stats = json.loads(\n          file_io.read_file_to_string(\n              os.path.join(output_folder, analyze.constant.STATS_FILE)).decode())\n\n      self.assertEqual(stats['num_examples'], 100)\n      col = stats['column_stats']['int']\n      self.assertAlmostEqual(col['max'], 99.0)\n      self.assertAlmostEqual(col['min'], 0.0)\n      self.assertAlmostEqual(col['mean'], 49.5)\n\n      col = stats['column_stats']['target']\n      self.assertAlmostEqual(col['max'], 198.0)\n      self.assertAlmostEqual(col['min'], 0.0)\n      self.assertAlmostEqual(col['mean'], 99.0)\n\n      col = stats['column_stats']['cat']\n      self.assertEqual(col['vocab_size'], 2)\n    finally:\n      shutil.rmtree(output_folder)\n\n\nif __name__ == '__main__':\n    unittest.main()\n"
  },
  {
    "path": "solutionbox/ml_workbench/test_tensorflow/test_cloud_workflow.py",
    "content": "from __future__ import absolute_import\n\nimport base64\nimport json\nimport logging\nimport os\nfrom PIL import Image\nimport random\nimport six\nimport shutil\nimport subprocess\nimport sys\nimport tempfile\nimport unittest\nimport uuid\n\nfrom tensorflow.python.lib.io import file_io\n\nCODE_PATH = os.path.abspath(os.path.join(\n    os.path.dirname(__file__), '..', 'tensorflow'))\n\n\nclass TestCloudServices(unittest.TestCase):\n  \"\"\"Tests everything using the cloud services.\n\n  Run cloud analyze, cloud transformation, cloud training, and cloud batch\n  prediction. Easy step is done by making a subprocess call to python or\n  gcloud.\n\n  Each step has a local 'cloud' variable that can be mannually set to False to\n  run the local version of the step. This is usefull when debugging as not\n  every step needs to use cloud services.\n\n  Because of the cloud overhead, this test easily takes 30-40 mins to finish.\n\n  Test files will be uploaded into a new bucket named temp_pydatalab_test_*\n  using the default project from gcloud. The bucket is removed at the end\n  of the test.\n\n  To run this test, the following evironment is needed:\n\n  * gcloud version >= 156\n  * gcloud with a default project that has access to dataflow and ml engine\n  * google-cloud-dataflow 0.6.0\n  \"\"\"\n  def __init__(self, *args, **kwargs):\n    super(TestCloudServices, self).__init__(*args, **kwargs)\n\n    self._max_steps = 2000\n\n    # Log everything\n    self._logger = logging.getLogger('TestStructuredDataLogger')\n    self._logger.setLevel(logging.DEBUG)\n    if not self._logger.handlers:\n      self._logger.addHandler(logging.StreamHandler(stream=sys.stdout))\n\n  def setUp(self):\n    random.seed(12321)\n    self._local_dir = tempfile.mkdtemp()  # Local folder for temp files.\n    self._gs_dir = 'gs://temp_pydatalab_test_%s' % uuid.uuid4().hex\n    subprocess.check_call('gsutil mb %s' % self._gs_dir, shell=True)\n\n    self._input_files = os.path.join(self._gs_dir, 'input_files')\n\n    self._analysis_output = os.path.join(self._gs_dir, 'analysis_output')\n    self._transform_output = os.path.join(self._gs_dir, 'transform_output')\n    self._train_output = os.path.join(self._gs_dir, 'train_output')\n    self._prediction_output = os.path.join(self._gs_dir, 'prediction_output')\n\n    file_io.recursive_create_dir(self._input_files)\n\n    self._csv_train_filename = os.path.join(self._input_files, 'train_csv_data.csv')\n    self._csv_eval_filename = os.path.join(self._input_files, 'eval_csv_data.csv')\n    self._csv_predict_filename = os.path.join(self._input_files, 'predict_csv_data.csv')\n    self._schema_filename = os.path.join(self._input_files, 'schema_file.json')\n    self._features_filename = os.path.join(self._input_files, 'features_file.json')\n\n    self._image_files = None\n\n  def tearDown(self):\n    self._logger.debug('TestCloudServices: removing folders %s, %s' %\n                       (self._local_dir, self._gs_dir))\n    shutil.rmtree(self._local_dir)\n    subprocess.check_call('gsutil -m rm -r %s' % self._gs_dir, shell=True)\n\n  def _make_image_files(self):\n    \"\"\"Makes random images and uploads them to GCS.\n\n    The images are first made locally and then moved to GCS for speed.\n    \"\"\"\n    self._image_files = []\n\n    for i in range(10):\n      r = random.randint(0, 255)\n      g = random.randint(0, 255)\n      b = random.randint(0, 255)\n      img_name = 'img%02d.jpg' % i\n      local_img = os.path.join(self._local_dir, img_name)\n      img = Image.new('RGBA', size=(300, 300), color=(155, 0, 0))\n      img.save(local_img)\n\n      self._image_files.append((r, g, b, os.path.join(self._input_files, img_name)))\n\n    cmd = 'gsutil -m mv %s/img*.jpg %s/' % (self._local_dir, self._input_files)\n    subprocess.check_call(cmd, shell=True)\n\n  def _make_csv_data(self, filename, num_rows, keep_target=True, embedded_image=False):\n    \"\"\"Writes csv data.\n\n    Builds a linear model that uses 1 numerical column and an image column.\n\n    Args:\n      filename: gcs filepath\n      num_rows: how many rows of data will be generated.\n      keep_target: if false, the target column is missing.\n      embedded_image: if true, the image column will be the base64 data\n    \"\"\"\n    def _drop_out(x):\n      # Make 5% of the data missing\n      if random.uniform(0, 1) < 0.05:\n        return ''\n      return x\n\n    local_file = os.path.join(self._local_dir, 'data.csv')\n    with open(local_file, 'w') as f:\n      for i in range(num_rows):\n        num = random.randint(0, 20)\n        r, g, b, img_path = random.choice(self._image_files)\n\n        if embedded_image:\n          with file_io.FileIO(img_path, 'r') as img_file:\n            img_bytes = Image.open(img_file)\n          buf = six.StringIO()\n          img_bytes.save(buf, 'JPEG')\n          img_data = base64.urlsafe_b64encode(buf.getvalue())\n        else:\n          img_data = img_path\n\n        # Build a simple linear model\n        t = -10 + 0.5 * num + 0.1 * r\n\n        num = _drop_out(num)\n        if num is not '':  # Don't drop every column\n          img_data = _drop_out(img_data)\n\n        if keep_target:\n          csv_line = \"{key},{target},{num},{img_data}\\n\".format(\n              key=i,\n              target=t,\n              num=num,\n              img_data=img_data)\n        else:\n          csv_line = \"{key},{num},{img_data}\\n\".format(\n              key=i,\n              num=num,\n              img_data=img_data)\n\n        f.write(csv_line)\n    subprocess.check_call('gsutil cp %s %s' % (local_file, filename), shell=True)\n\n  def _get_default_project_id(self):\n    with open(os.devnull, 'w') as dev_null:\n      cmd = 'gcloud config list project --format=\\'value(core.project)\\''\n      return subprocess.check_output(cmd, shell=True, stderr=dev_null).strip()\n\n  def _run_analyze(self):\n    \"\"\"Runs analysis using BigQuery from csv files.\"\"\"\n\n    cloud = True\n    self._logger.debug('Create input files')\n\n    features = {\n        'num': {'transform': 'scale'},\n        'img': {'transform': 'image_to_vec'},\n        'target': {'transform': 'target'},\n        'key': {'transform': 'key'}}\n    file_io.write_string_to_file(self._features_filename, json.dumps(features, indent=2))\n\n    schema = [\n        {'name': 'key', 'type': 'integer'},\n        {'name': 'target', 'type': 'float'},\n        {'name': 'num', 'type': 'integer'},\n        {'name': 'img', 'type': 'string'}]\n    file_io.write_string_to_file(self._schema_filename, json.dumps(schema, indent=2))\n\n    self._make_image_files()\n\n    self._make_csv_data(self._csv_train_filename, 30, True, False)\n    self._make_csv_data(self._csv_eval_filename, 10, True, False)\n    self._make_csv_data(self._csv_predict_filename, 5, False, True)\n\n    cmd = ['python %s' % os.path.join(CODE_PATH, 'analyze.py'),\n           '--cloud' if cloud else '',\n           '--output=' + self._analysis_output,\n           '--csv=' + self._csv_train_filename,\n           '--schema=' + self._schema_filename,\n           '--features=' + self._features_filename]\n\n    self._logger.debug('Running subprocess: %s \\n\\n' % ' '.join(cmd))\n    subprocess.check_call(' '.join(cmd), shell=True)\n    self.assertTrue(file_io.file_exists(os.path.join(self._analysis_output, 'stats.json')))\n    self.assertTrue(file_io.file_exists(os.path.join(self._analysis_output, 'schema.json')))\n    self.assertTrue(file_io.file_exists(os.path.join(self._analysis_output, 'features.json')))\n\n  def _run_transform(self):\n    \"\"\"Runs DataFlow for makint tf.example files.\n\n    Only the train file uses DataFlow, the eval file runs beam locally to save\n    time.\n    \"\"\"\n    cloud = True\n    extra_args = []\n    if cloud:\n      extra_args = ['--cloud',\n                    '--job-name=test-mltoolbox-df-%s' % uuid.uuid4().hex,\n                    '--project-id=%s' % self._get_default_project_id(),\n                    '--num-workers=3']\n\n    cmd = ['python %s' % os.path.join(CODE_PATH, 'transform.py'),\n           '--csv=' + self._csv_train_filename,\n           '--analysis=' + self._analysis_output,\n           '--prefix=features_train',\n           '--output=' + self._transform_output,\n           '--shuffle'] + extra_args\n\n    self._logger.debug('Running subprocess: %s \\n\\n' % ' '.join(cmd))\n    subprocess.check_call(' '.join(cmd), shell=True)\n\n    # Don't wate time running a 2nd DF job, run it locally.\n    cmd = ['python %s' % os.path.join(CODE_PATH, 'transform.py'),\n           '--csv=' + self._csv_eval_filename,\n           '--analysis=' + self._analysis_output,\n           '--prefix=features_eval',\n           '--output=' + self._transform_output]\n\n    self._logger.debug('Running subprocess: %s \\n\\n' % ' '.join(cmd))\n    subprocess.check_call(' '.join(cmd), shell=True)\n\n    # Check the files were made\n    train_files = file_io.get_matching_files(\n        os.path.join(self._transform_output, 'features_train*'))\n    eval_files = file_io.get_matching_files(\n        os.path.join(self._transform_output, 'features_eval*'))\n    self.assertNotEqual([], train_files)\n    self.assertNotEqual([], eval_files)\n\n  def _run_training_transform(self):\n    \"\"\"Runs training starting with transformed tf.example files.\"\"\"\n\n    cloud = True\n    if cloud:\n      cmd = ['gcloud ml-engine jobs submit training test_mltoolbox_train_%s' % uuid.uuid4().hex,\n             '--runtime-version=1.0',\n             '--scale-tier=STANDARD_1',\n             '--stream-logs']\n    else:\n      cmd = ['gcloud ml-engine local train']\n\n    cmd = cmd + [\n        '--module-name trainer.task',\n        '--job-dir=' + self._train_output,\n        '--package-path=' + os.path.join(CODE_PATH, 'trainer'),\n        '--',\n        '--train=' + os.path.join(self._transform_output, 'features_train*'),\n        '--eval=' + os.path.join(self._transform_output, 'features_eval*'),\n        '--analysis=' + self._analysis_output,\n        '--model=linear_regression',\n        '--train-batch-size=10',\n        '--eval-batch-size=10',\n        '--max-steps=' + str(self._max_steps)]\n\n    self._logger.debug('Running subprocess: %s \\n\\n' % ' '.join(cmd))\n    subprocess.check_call(' '.join(cmd), shell=True)\n\n    # Check the saved model was made.\n    self.assertTrue(file_io.file_exists(\n        os.path.join(self._train_output, 'model', 'saved_model.pb')))\n    self.assertTrue(file_io.file_exists(\n        os.path.join(self._train_output, 'evaluation_model', 'saved_model.pb')))\n\n  def _run_batch_prediction(self):\n    \"\"\"Run batch prediction using the cloudml engine prediction service.\n\n    There is no local version of this step as it's the last step.\n    \"\"\"\n\n    job_name = 'test_mltoolbox_batchprediction_%s' % uuid.uuid4().hex\n    cmd = ['gcloud ml-engine jobs submit prediction ' + job_name,\n           '--data-format=TEXT',\n           '--input-paths=' + self._csv_predict_filename,\n           '--output-path=' + self._prediction_output,\n           '--model-dir=' + os.path.join(self._train_output, 'model'),\n           '--runtime-version=1.0',\n           '--region=us-central1']\n    self._logger.debug('Running subprocess: %s \\n\\n' % ' '.join(cmd))\n    subprocess.check_call(' '.join(cmd), shell=True)  # async call.\n    subprocess.check_call('gcloud ml-engine jobs stream-logs ' + job_name, shell=True)\n\n    # check that there was no errors.\n    error_files = file_io.get_matching_files(\n        os.path.join(self._prediction_output, 'prediction.errors_stats*'))\n    self.assertEqual(1, len(error_files))\n    error_str = file_io.read_file_to_string(error_files[0])\n    self.assertEqual('', error_str)\n\n  def test_cloud_workflow(self):\n    self._run_analyze()\n    self._run_transform()\n    self._run_training_transform()\n    self._run_batch_prediction()\n\n\nif __name__ == '__main__':\n    unittest.main()\n"
  },
  {
    "path": "solutionbox/ml_workbench/test_tensorflow/test_feature_transforms.py",
    "content": "from __future__ import absolute_import\nfrom __future__ import print_function\n\nimport base64\nimport cStringIO\nfrom PIL import Image\nimport json\nimport math\nimport numpy as np\nimport os\nimport shutil\nimport sys\nimport tempfile\nimport unittest\nimport tensorflow as tf\n\nfrom tensorflow.python.lib.io import file_io\n\n# To make 'import analyze' work without installing it.\nsys.path.append(os.path.abspath(\n    os.path.join(os.path.dirname(__file__), '..', 'tensorflow', 'trainer')))\n\nimport feature_transforms  # noqa: E303\n\n# Some tests put files in GCS or use BigQuery. If HAS_CREDENTIALS is false,\n# those tests will not run.\nHAS_CREDENTIALS = True\ntry:\n  import google.datalab as dl\n  dl.Context.default().project_id\nexcept Exception:\n  HAS_CREDENTIALS = False\n\n\nclass TestGraphBuilding(unittest.TestCase):\n  \"\"\"Test the TITO functions work and can produce a working TF graph.\"\"\"\n\n  def _run_graph(self, analysis_path, features, schema, stats, predict_data):\n    \"\"\"Runs the preprocessing graph.\n\n    Args:\n      analysis_path: path to folder containing analysis output. Should contain\n          the stats file.\n      features: features dict\n      schema: schema list\n      stats: stats dict\n      predict_data: list of csv strings\n    \"\"\"\n    stats = {'column_stats': {}}\n    with tf.Graph().as_default():\n      with tf.Session().as_default() as session:\n        outputs, labels, inputs = feature_transforms.build_csv_serving_tensors_for_transform_step(\n            analysis_path, features, schema, stats, keep_target=False)\n        feed_inputs = {inputs['csv_example']: predict_data}\n\n        session.run(tf.tables_initializer())\n        result = session.run(outputs, feed_dict=feed_inputs)\n        return result\n\n  def test_make_transform_graph_numerics(self):\n    output_folder = tempfile.mkdtemp()\n    stats_file_path = os.path.join(output_folder, feature_transforms.STATS_FILE)\n    try:\n      stats = {'column_stats':\n                {'num1': {'max': 10.0, 'mean': 9.5, 'min': 0.0},  # noqa\n                 'num2': {'max': 1.0, 'mean': 2.0, 'min': -1.0},\n                 'num3': {'max': 10.0, 'mean': 2.0, 'min': 5.0}}}\n      schema = [{'name': 'num1', 'type': 'FLOAT'},\n                {'name': 'num2', 'type': 'FLOAT'},\n                {'name': 'num3', 'type': 'INTEGER'}]\n      features = {'num1': {'transform': 'identity', 'source_column': 'num1'},\n                  'num2': {'transform': 'scale', 'value': 10, 'source_column': 'num2'},\n                  'num3': {'transform': 'scale', 'source_column': 'num3'}}\n      input_data = ['5.0,-1.0,10',\n                    '10.0,1.0,5',\n                    '15.0,0.5,7']\n      file_io.write_string_to_file(\n          stats_file_path,\n          json.dumps(stats))\n\n      results = self._run_graph(output_folder, features, schema, stats, input_data)\n\n      for result, expected_result in zip(results['num1'].flatten().tolist(),\n                                         [5, 10, 15]):\n        self.assertAlmostEqual(result, expected_result)\n\n      for result, expected_result in zip(results['num2'].flatten().tolist(),\n                                         [-10, 10, 5]):\n        self.assertAlmostEqual(result, expected_result)\n\n      for result, expected_result in zip(results['num3'].flatten().tolist(),\n                                         [1, -1, (7.0 - 5) * 2.0 / 5.0 - 1]):\n        self.assertAlmostEqual(result, expected_result)\n    finally:\n      shutil.rmtree(output_folder)\n\n  def test_make_transform_graph_category(self):\n    output_folder = tempfile.mkdtemp()\n    try:\n      file_io.write_string_to_file(\n          os.path.join(output_folder, feature_transforms.VOCAB_ANALYSIS_FILE % 'cat1'),\n          '\\n'.join(['red,300', 'blue,200', 'green,100']))\n\n      file_io.write_string_to_file(\n          os.path.join(output_folder, feature_transforms.VOCAB_ANALYSIS_FILE % 'cat2'),\n          '\\n'.join(['pizza,300', 'ice_cream,200', 'cookies,100']))\n\n      stats = {'column_stats': {}}  # stats file needed but unused.\n      file_io.write_string_to_file(\n          os.path.join(output_folder, feature_transforms.STATS_FILE),\n          json.dumps(stats))\n\n      schema = [{'name': 'cat1', 'type': 'STRING'}, {'name': 'cat2', 'type': 'STRING'}]\n      features = {'cat1': {'transform': 'one_hot', 'source_column': 'cat1'},\n                  'cat2': {'transform': 'embedding', 'source_column': 'cat2'}}\n      input_data = ['red,pizza',\n                    'blue,',\n                    'green,extra']\n\n      results = self._run_graph(output_folder, features, schema, stats, input_data)\n\n      for result, expected_result in zip(results['cat1'].flatten().tolist(), [0, 1, 2]):\n        self.assertEqual(result, expected_result)\n\n      for result, expected_result in zip(results['cat2'].flatten().tolist(),\n                                         [0, 3, 3]):\n        self.assertEqual(result, expected_result)\n    finally:\n      shutil.rmtree(output_folder)\n\n  def test_make_transform_graph_text_tfidf(self):\n    output_folder = tempfile.mkdtemp()\n    try:\n      # vocab  id\n      # red    0\n      # blue   1\n      # green  2\n      # oov    3 (out of vocab)\n      # corpus size aka num_examples = 4\n      # IDF: log(num_examples/(1+number of examples that have this token))\n      #  red: log(4/3)\n      #  blue: log(4/3)\n      #  green: log(4/2)\n      #  oov:  log(4/1)\n      file_io.write_string_to_file(\n          os.path.join(output_folder, feature_transforms.VOCAB_ANALYSIS_FILE % 'cat1'),\n          '\\n'.join(['red,2', 'blue,2', 'green,1']))\n\n      stats = {'column_stats': {}, 'num_examples': 4}\n      file_io.write_string_to_file(\n          os.path.join(output_folder, feature_transforms.STATS_FILE),\n          json.dumps(stats))\n\n      # decode_csv does not like 1 column files with an empty row, so add\n      # a key column\n      schema = [{'name': 'key', 'type': 'STRING'},\n                {'name': 'cat1', 'type': 'STRING'}]\n      features = {'key': {'transform': 'key', 'source_column': 'key'},\n                  'cat1': {'transform': 'tfidf', 'source_column': 'cat1'}}\n      input_data = ['0,red red red',    # doc 0\n                    '1,red green red',  # doc 1\n                    '2,blue',           # doc 2\n                    '3,blue blue',      # doc 3\n                    '4,',               # doc 4\n                    '5,brown',          # doc 5\n                    '6,brown blue']     # doc 6\n\n      results = self._run_graph(output_folder, features, schema, stats, input_data)\n\n      # indices are in the form [doc id, vocab id]\n      expected_indices = [[0, 0], [0, 1], [0, 2],\n                          [1, 0], [1, 1], [1, 2],\n                          [2, 0],\n                          [3, 0], [3, 1],\n                          [5, 0],\n                          [6, 0], [6, 1]]\n      expected_ids = [0, 0, 0, 0, 2, 0, 1, 1, 1, 3, 3, 1]\n      self.assertEqual(results['cat1_ids'].indices.tolist(), expected_indices)\n      self.assertEqual(results['cat1_ids'].dense_shape.tolist(), [7, 3])\n      self.assertEqual(results['cat1_ids'].values.tolist(), expected_ids)\n\n      # Note, these are natural logs.\n      log_4_3 = math.log(4.0 / 3.0)\n      expected_weights = [\n          1.0 / 3.0 * log_4_3, 1.0 / 3.0 * log_4_3, 1.0 / 3.0 * log_4_3,  # doc 0\n          1.0 / 3.0 * log_4_3, 1.0 / 3.0 * math.log(2.0), 1.0 / 3.0 * log_4_3,  # doc 1\n          math.log(4.0 / 3.0),  # doc 2\n          1.0 / 2.0 * log_4_3, 1.0 / 2.0 * log_4_3,  # doc 3\n          math.log(4.0),  # doc 5\n          1.0 / 2.0 * math.log(4.0), 1.0 / 2.0 * log_4_3]  # doc 6\n\n      self.assertEqual(results['cat1_weights'].indices.tolist(), expected_indices)\n      self.assertEqual(results['cat1_weights'].dense_shape.tolist(), [7, 3])\n      self.assertEqual(results['cat1_weights'].values.size, len(expected_weights))\n      for weight, expected_weight in zip(results['cat1_weights'].values.tolist(), expected_weights):\n        self.assertAlmostEqual(weight, expected_weight)\n\n    finally:\n      shutil.rmtree(output_folder)\n\n  def test_make_transform_graph_text_multi_hot(self):\n    output_folder = tempfile.mkdtemp()\n    try:\n      # vocab  id\n      # red    0\n      # blue   1\n      # green  2\n      # oov    3 (out of vocab)\n      file_io.write_string_to_file(\n          os.path.join(output_folder,\n                       feature_transforms.VOCAB_ANALYSIS_FILE % 'cat1'),\n          '\\n'.join(['red,2', 'blue,2', 'green,1']))\n\n      stats = {'column_stats': {}}\n      file_io.write_string_to_file(\n          os.path.join(output_folder, feature_transforms.STATS_FILE),\n          json.dumps(stats))  # Stats file needed but unused.\n\n      # decode_csv does not like 1 column files with an empty row, so add\n      # a key column\n      schema = [{'name': 'key', 'type': 'STRING'},\n                {'name': 'cat1', 'type': 'STRING'}]\n      features = {'key': {'transform': 'key', 'source_column': 'key'},\n                  'cat1': {'transform': 'multi_hot', 'source_column': 'cat1', 'separator': '|'}}\n      input_data = ['0,red',    # doc 0\n                    '1,red|green',  # doc 1\n                    '2,blue',           # doc 2\n                    '3,red|blue|green',      # doc 3\n                    '4,']               # doc 4\n\n      results = self._run_graph(output_folder, features, schema, stats, input_data)\n\n      # indices are in the form [doc id, vocab id]\n      expected_indices = [[0, 0],\n                          [1, 0], [1, 1],\n                          [2, 0],\n                          [3, 0], [3, 1], [3, 2]]\n\n      # doc id            0  1  1  2  3  3  3\n      expected_ids =     [0, 0, 2, 1, 0, 1, 2] # noqa\n      self.assertEqual(results['cat1'].indices.tolist(), expected_indices)\n      self.assertEqual(results['cat1'].dense_shape.tolist(), [5, 3])\n      self.assertEqual(results['cat1'].values.tolist(), expected_ids)\n\n    finally:\n      shutil.rmtree(output_folder)\n\n  def test_make_transform_graph_text_bag_of_words(self):\n    output_folder = tempfile.mkdtemp()\n    try:\n      # vocab  id\n      # red    0\n      # blue   1\n      # green  2\n      # oov    3 (out of vocab)\n      file_io.write_string_to_file(\n          os.path.join(output_folder,\n                       feature_transforms.VOCAB_ANALYSIS_FILE % 'cat1'),\n          '\\n'.join(['red,2', 'blue,2', 'green,1']))\n\n      stats = {'column_stats': {}}\n      file_io.write_string_to_file(\n          os.path.join(output_folder, feature_transforms.STATS_FILE),\n          json.dumps(stats))  # Stats file needed but unused.\n\n      # decode_csv does not like 1 column files with an empty row, so add\n      # a key column\n      schema = [{'name': 'key', 'type': 'STRING'},\n                {'name': 'cat1', 'type': 'STRING'}]\n      features = {'key': {'transform': 'key', 'source_column': 'key'},\n                  'cat1': {'transform': 'bag_of_words', 'source_column': 'cat1'}}\n      input_data = ['0,red red red',    # doc 0\n                    '1,red green red',  # doc 1\n                    '2,blue',           # doc 2\n                    '3,blue blue',      # doc 3\n                    '4,',               # doc 4\n                    '5,brown',          # doc 5\n                    '6,brown blue']     # doc 6\n\n      results = self._run_graph(output_folder, features, schema, stats, input_data)\n\n      # indices are in the form [doc id, vocab id]\n      expected_indices = [[0, 0], [0, 1], [0, 2],\n                          [1, 0], [1, 1], [1, 2],\n                          [2, 0],\n                          [3, 0], [3, 1],\n                          [5, 0],\n                          [6, 0], [6, 1]]\n\n      # Note in doc 6, is is blue, then brown.\n      # doc id            0  0  0  1  1  1  2  3  3  5  6  6\n      expected_ids =     [0, 0, 0, 0, 2, 0, 1, 1, 1, 3, 3, 1] # noqa\n      expected_weights = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]\n      self.assertEqual(results['cat1_ids'].indices.tolist(), expected_indices)\n      self.assertEqual(results['cat1_ids'].dense_shape.tolist(), [7, 3])\n      self.assertEqual(results['cat1_ids'].values.tolist(), expected_ids)\n\n      self.assertEqual(results['cat1_weights'].indices.tolist(),\n                       expected_indices)\n      self.assertEqual(results['cat1_weights'].dense_shape.tolist(), [7, 3])\n      self.assertEqual(results['cat1_weights'].values.size,\n                       len(expected_weights))\n      for weight, exp_weight in zip(results['cat1_weights'].values.tolist(),\n                                    expected_weights):\n        self.assertAlmostEqual(weight, exp_weight)\n\n    finally:\n      shutil.rmtree(output_folder)\n\n  @unittest.skipIf(not HAS_CREDENTIALS, 'GCS access missing')\n  def test_make_transform_graph_images(self):\n\n    print('Testing make_transform_graph with image_to_vec. ' +\n          'It may take a few minutes because it needs to download a large inception checkpoint.')\n\n    def _open_and_encode_image(img_url):\n      with file_io.FileIO(img_url, 'r') as f:\n        img = Image.open(f).convert('RGB')\n        output = cStringIO.StringIO()\n        img.save(output, 'jpeg')\n      return base64.urlsafe_b64encode(output.getvalue())\n\n    try:\n      output_folder = tempfile.mkdtemp()\n      stats_file_path = os.path.join(output_folder, feature_transforms.STATS_FILE)\n      stats = {'column_stats': {}}\n      file_io.write_string_to_file(stats_file_path, json.dumps(stats))\n\n      schema = [{'name': 'img', 'type': 'STRING'}]\n      features = {'img': {'transform': 'image_to_vec', 'source_column': 'img'}}\n\n      # Test transformation with encoded image content.\n      img_string1 = _open_and_encode_image(\n          'gs://cloud-ml-data/img/flower_photos/daisy/15207766_fc2f1d692c_n.jpg')\n      img_string2 = _open_and_encode_image(\n          'gs://cloud-ml-data/img/flower_photos/dandelion/8980164828_04fbf64f79_n.jpg')\n      # Test transformation with direct file path.\n      img_string3 = 'gs://cloud-ml-data/img/flower_photos/daisy/15207766_fc2f1d692c_n.jpg'\n      img_string4 = 'gs://cloud-ml-data/img/flower_photos/dandelion/8980164828_04fbf64f79_n.jpg'\n      input_data = [img_string1, img_string2, img_string3, img_string4]\n      results = self._run_graph(output_folder, features, schema, stats, input_data)\n      embeddings = results['img']\n      self.assertEqual(len(embeddings), 4)\n      self.assertEqual(len(embeddings[0]), 2048)\n      self.assertEqual(embeddings[0].dtype, np.float32)\n      self.assertTrue(any(x != 0.0 for x in embeddings[1]))\n      self.assertTrue(any(x != 0.0 for x in embeddings[3]))\n\n    finally:\n      shutil.rmtree(output_folder)\n\n\nif __name__ == '__main__':\n  unittest.main()\n"
  },
  {
    "path": "solutionbox/ml_workbench/test_tensorflow/test_training.py",
    "content": "from __future__ import absolute_import\n\nimport base64\nimport glob\nimport json\nimport logging\nimport os\nimport pandas as pd\nfrom PIL import Image\nimport random\nimport shutil\nfrom six.moves.urllib.request import urlopen\nimport subprocess\nimport sys\nimport tempfile\nimport unittest\n\nimport tensorflow as tf\nfrom tensorflow.python.lib.io import file_io\n\n\nCODE_PATH = os.path.abspath(os.path.join(\n    os.path.dirname(__file__), '..', 'tensorflow'))\n\n\ndef run_exported_model(model_path, csv_data):\n  \"\"\"Runs an exported model.\n\n  Model should have one placeholder of csv data.\n\n  Args:\n    model_path: path to the saved_model.pb\n    csv_data: list of csv strings\n\n  Return:\n    The result of session.run\n  \"\"\"\n  with tf.Graph().as_default(), tf.Session() as sess:\n    meta_graph_pb = tf.saved_model.loader.load(\n        sess=sess,\n        tags=[tf.saved_model.tag_constants.SERVING],\n        export_dir=model_path)\n    signature = meta_graph_pb.signature_def['serving_default']\n\n    input_alias_map = {\n        friendly_name: tensor_info_proto.name\n        for (friendly_name, tensor_info_proto) in signature.inputs.items()}\n    output_alias_map = {\n        friendly_name: tensor_info_proto.name\n        for (friendly_name, tensor_info_proto) in signature.outputs.items()}\n\n    _, csv_tensor_name = input_alias_map.items()[0]\n    result = sess.run(fetches=output_alias_map,\n                      feed_dict={csv_tensor_name: csv_data})\n\n  return result\n\n\nclass TestSpecialCharacters(unittest.TestCase):\n  \"\"\"Test special characters are supported.\"\"\"\n\n  def testCommaQuote(self):\n    \"\"\"Test when csv input data has quotes and commas.\"\"\"\n    output_dir = tempfile.mkdtemp()\n    try:\n      features = {\n          'target': {'transform': 'target'},\n          'cat': {'transform': 'one_hot'},\n          'text': {'transform': 'bag_of_words'}}\n      schema = [\n          {'name': 'target', 'type': 'string'},\n          {'name': 'cat', 'type': 'string'},\n          {'name': 'text', 'type': 'string'}]\n      # Target column = cat  column\n      data = [{'cat': 'red,', 'text': 'one, two, three', 'target': 'red,'},\n              {'cat': 'blue\"', 'text': 'one, \"two\"', 'target': 'blue\"'},\n              {'cat': '\"green\"', 'text': '\"two', 'target': '\"green\"'},\n              {'cat': \"yellow, 'brown\", 'text': \"'one, two'\", 'target': \"yellow, 'brown\"}]\n\n      file_io.recursive_create_dir(output_dir)\n      file_io.write_string_to_file(os.path.join(output_dir, 'schema.json'),\n                                   json.dumps(schema, indent=2))\n      file_io.write_string_to_file(os.path.join(output_dir, 'features.json'),\n                                   json.dumps(features, indent=2))\n      file_io.write_string_to_file(\n          os.path.join(output_dir, 'data.csv'),\n          pd.DataFrame(data, columns=['target', 'cat', 'text']).to_csv(index=False, header=False))\n\n      # Run analysis and check the output vocabs are correctly encoded in csv\n      cmd = ['python %s' % os.path.join(CODE_PATH, 'analyze.py'),\n             '--output=' + os.path.join(output_dir, 'analysis'),\n             '--csv=' + os.path.join(output_dir, 'data.csv'),\n             '--schema=' + os.path.join(output_dir, 'schema.json'),\n             '--features=' + os.path.join(output_dir, 'features.json')]\n      subprocess.check_call(' '.join(cmd), shell=True)\n\n      df_vocab_cat = pd.read_csv(\n          os.path.join(output_dir, 'analysis', 'vocab_cat.csv'),\n          header=None,\n          names=['label', 'count'],\n          dtype=str,\n          na_filter=False)\n      self.assertEqual(df_vocab_cat['count'].tolist(), ['1', '1', '1', '1'])\n      self.assertItemsEqual(\n          df_vocab_cat['label'].tolist(),\n          ['blue\"', '\"green\"', \"yellow, 'brown\", 'red,'])\n\n      df_vocab_target = pd.read_csv(\n          os.path.join(output_dir, 'analysis', 'vocab_target.csv'),\n          header=None,\n          names=['label', 'count'],\n          dtype=str,\n          na_filter=False)\n      self.assertEqual(df_vocab_target['count'].tolist(), ['1', '1', '1', '1'])\n      self.assertItemsEqual(\n          df_vocab_target['label'].tolist(),\n          ['blue\"', '\"green\"', \"yellow, 'brown\", 'red,'])\n\n      df_vocab_text = pd.read_csv(\n          os.path.join(output_dir, 'analysis', 'vocab_text.csv'),\n          header=None,\n          names=['label', 'count'],\n          dtype=str,\n          na_filter=False)\n      vocab_text = df_vocab_text['label'].tolist()\n      self.assertEqual(vocab_text[0], 'one,')\n      self.assertItemsEqual(vocab_text[1:], ['two,', '\"two\"', \"'one,\", '\"two', \"two'\", 'three'])\n      vocab_count = df_vocab_text['count'].tolist()\n      self.assertEqual(vocab_count[0], '2')\n      self.assertEqual(vocab_count[1:], ['1', '1', '1', '1', '1', '1'])\n\n      # Run transform, and check there are no reported errors.\n      cmd = ['python %s' % os.path.join(CODE_PATH, 'transform.py'),\n             '--csv=' + os.path.join(output_dir, 'data.csv'),\n             '--analysis=' + os.path.join(output_dir, 'analysis'),\n             '--prefix=features_train',\n             '--output=' + os.path.join(output_dir, 'transform')]\n      subprocess.check_call(' '.join(cmd), shell=True)\n\n      error_files = glob.glob(os.path.join(output_dir, 'transform', 'error*'))\n      self.assertEqual(1, len(error_files))\n      self.assertEqual(0, os.path.getsize(error_files[0]))\n\n      # Run training\n      cmd = ['cd %s && ' % CODE_PATH,\n             'python -m trainer.task',\n             '--train=' + os.path.join(output_dir, 'data.csv'),\n             '--eval=' + os.path.join(output_dir, 'data.csv'),\n             '--job-dir=' + os.path.join(output_dir, 'training'),\n             '--analysis=' + os.path.join(output_dir, 'analysis'),\n             '--model=linear_classification',\n             '--train-batch-size=4',\n             '--eval-batch-size=4',\n             '--max-steps=500',\n             '--learning-rate=1.0',\n             '--transform']\n      subprocess.check_call(' '.join(cmd), shell=True)\n\n      result = run_exported_model(\n          model_path=os.path.join(output_dir, 'training', 'model'),\n          csv_data=['\"red,\",\"one, two, three\"'])\n\n      # The prediction data is a training row. As the data is samll, the model\n      # should have near 100% accuracy. Check it made the correct prediction.\n      self.assertEqual(result['predicted'], 'red,')\n    finally:\n      shutil.rmtree(output_dir)\n\n\nclass TestClassificationTopN(unittest.TestCase):\n  \"\"\"Test top_n works.\"\"\"\n\n  def testTopNZero(self):\n    \"\"\"Test top_n=0 gives all the classes.\"\"\"\n    output_dir = tempfile.mkdtemp()\n    try:\n      features = {\n          'num': {'transform': 'identity'},\n          'target': {'transform': 'target'}}\n      schema = [\n          {'name': 'num', 'type': 'integer'},\n          {'name': 'target', 'type': 'string'}]\n      data = ['1,1\\n', '4,2\\n', '5,3\\n', '11,1\\n']\n      file_io.recursive_create_dir(output_dir)\n      file_io.write_string_to_file(os.path.join(output_dir, 'schema.json'),\n                                   json.dumps(schema, indent=2))\n      file_io.write_string_to_file(os.path.join(output_dir, 'features.json'),\n                                   json.dumps(features, indent=2))\n      file_io.write_string_to_file(os.path.join(output_dir, 'data.csv'),\n                                   ''.join(data))\n\n      cmd = ['python %s' % os.path.join(CODE_PATH, 'analyze.py'),\n             '--output=' + os.path.join(output_dir, 'analysis'),\n             '--csv=' + os.path.join(output_dir, 'data.csv'),\n             '--schema=' + os.path.join(output_dir, 'schema.json'),\n             '--features=' + os.path.join(output_dir, 'features.json')]\n      subprocess.check_call(' '.join(cmd), shell=True)\n\n      cmd = ['cd %s && ' % CODE_PATH,\n             'python -m trainer.task',\n             '--train=' + os.path.join(output_dir, 'data.csv'),\n             '--eval=' + os.path.join(output_dir, 'data.csv'),\n             '--job-dir=' + os.path.join(output_dir, 'training'),\n             '--analysis=' + os.path.join(output_dir, 'analysis'),\n             '--model=linear_classification',\n             '--train-batch-size=4',\n             '--eval-batch-size=4',\n             '--max-steps=1',\n             '--top-n=0',  # This parameter is tested in this test!\n             '--learning-rate=0.1',\n             '--transform']\n\n      subprocess.check_call(' '.join(cmd), shell=True)\n\n      result = run_exported_model(\n          model_path=os.path.join(output_dir, 'training', 'model'),\n          csv_data=['20'])\n\n      keys = result.keys()\n      self.assertIn('predicted', keys)\n      self.assertIn('1', keys)\n      self.assertIn('2', keys)\n      self.assertIn('3', keys)\n    finally:\n      shutil.rmtree(output_dir)\n\n\nclass TestMultipleFeatures(unittest.TestCase):\n  \"\"\"Test one source column can be used in many features.\"\"\"\n\n  def testMultipleColumnsRaw(self):\n    \"\"\"Test training starting from raw csv.\"\"\"\n    output_dir = tempfile.mkdtemp()\n    try:\n      features = {\n          'num': {'transform': 'identity'},\n          'num2': {'transform': 'key', 'source_column': 'num'},\n          'target': {'transform': 'target'},\n          'text': {'transform': 'bag_of_words'},\n          'text2': {'transform': 'multi_hot', 'source_column': 'text'},\n          'text3': {'transform': 'tfidf', 'source_column': 'text'},\n          'text4': {'transform': 'key', 'source_column': 'text'}}\n      schema = [\n          {'name': 'num', 'type': 'integer'},\n          {'name': 'target', 'type': 'float'},\n          {'name': 'text', 'type': 'string'}]\n      data = ['1,2,hello world\\n', '4,8,bye moon\\n', '5,10,hello moon\\n', '11,22,moon moon\\n']\n      file_io.recursive_create_dir(output_dir)\n      file_io.write_string_to_file(os.path.join(output_dir, 'schema.json'),\n                                   json.dumps(schema, indent=2))\n      file_io.write_string_to_file(os.path.join(output_dir, 'features.json'),\n                                   json.dumps(features, indent=2))\n      file_io.write_string_to_file(os.path.join(output_dir, 'data.csv'),\n                                   ''.join(data))\n\n      cmd = ['python %s' % os.path.join(CODE_PATH, 'analyze.py'),\n             '--output=' + os.path.join(output_dir, 'analysis'),\n             '--csv=' + os.path.join(output_dir, 'data.csv'),\n             '--schema=' + os.path.join(output_dir, 'schema.json'),\n             '--features=' + os.path.join(output_dir, 'features.json')]\n      subprocess.check_call(' '.join(cmd), shell=True)\n\n      cmd = ['cd %s && ' % CODE_PATH,\n             'python -m trainer.task',\n             '--train=' + os.path.join(output_dir, 'data.csv'),\n             '--eval=' + os.path.join(output_dir, 'data.csv'),\n             '--job-dir=' + os.path.join(output_dir, 'training'),\n             '--analysis=' + os.path.join(output_dir, 'analysis'),\n             '--model=linear_regression',\n             '--train-batch-size=4',\n             '--eval-batch-size=4',\n             '--max-steps=200',\n             '--learning-rate=0.1',\n             '--transform']\n\n      subprocess.check_call(' '.join(cmd), shell=True)\n\n      result = run_exported_model(\n          model_path=os.path.join(output_dir, 'training', 'model'),\n          csv_data=['20,hello moon'])\n\n      # check keys were made\n      self.assertEqual(20, result['num2'])\n      self.assertEqual('hello moon', result['text4'])\n    finally:\n      shutil.rmtree(output_dir)\n\n  def testMultipleColumnsTransformed(self):\n    \"\"\"Test training starting from tf.example.\"\"\"\n    output_dir = tempfile.mkdtemp()\n    try:\n      features = {\n          'num': {'transform': 'identity'},\n          'num2': {'transform': 'key', 'source_column': 'num'},\n          'target': {'transform': 'target'},\n          'text': {'transform': 'bag_of_words'},\n          'text2': {'transform': 'multi_hot', 'source_column': 'text'},\n          'text3': {'transform': 'tfidf', 'source_column': 'text'},\n          'text4': {'transform': 'key', 'source_column': 'text'}}\n      schema = [\n          {'name': 'num', 'type': 'integer'},\n          {'name': 'target', 'type': 'float'},\n          {'name': 'text', 'type': 'string'}]\n      data = ['1,2,hello world\\n', '4,8,bye moon\\n', '5,10,hello moon\\n', '11,22,moon moon\\n']\n      file_io.recursive_create_dir(output_dir)\n      file_io.write_string_to_file(os.path.join(output_dir, 'schema.json'),\n                                   json.dumps(schema, indent=2))\n      file_io.write_string_to_file(os.path.join(output_dir, 'features.json'),\n                                   json.dumps(features, indent=2))\n      file_io.write_string_to_file(os.path.join(output_dir, 'data.csv'),\n                                   ''.join(data))\n\n      cmd = ['python %s' % os.path.join(CODE_PATH, 'analyze.py'),\n             '--output=' + os.path.join(output_dir, 'analysis'),\n             '--csv=' + os.path.join(output_dir, 'data.csv'),\n             '--schema=' + os.path.join(output_dir, 'schema.json'),\n             '--features=' + os.path.join(output_dir, 'features.json')]\n      subprocess.check_call(' '.join(cmd), shell=True)\n\n      cmd = ['python %s' % os.path.join(CODE_PATH, 'transform.py'),\n             '--output=' + os.path.join(output_dir, 'transform'),\n             '--csv=' + os.path.join(output_dir, 'data.csv'),\n             '--analysis=' + os.path.join(output_dir, 'analysis'),\n             '--prefix=features']\n      subprocess.check_call(' '.join(cmd), shell=True)\n\n      # Check tf.example file has the expected features\n      file_list = file_io.get_matching_files(os.path.join(output_dir, 'transform', 'features*'))\n      options = tf.python_io.TFRecordOptions(\n          compression_type=tf.python_io.TFRecordCompressionType.GZIP)\n      record_iter = tf.python_io.tf_record_iterator(path=file_list[0], options=options)\n      tf_example = tf.train.Example()\n      tf_example.ParseFromString(next(record_iter))\n\n      self.assertEqual(1, len(tf_example.features.feature['num'].int64_list.value))\n      self.assertEqual(1, len(tf_example.features.feature['num2'].int64_list.value))\n      self.assertEqual(1, len(tf_example.features.feature['target'].float_list.value))\n      self.assertEqual(2, len(tf_example.features.feature['text_ids'].int64_list.value))\n      self.assertEqual(2, len(tf_example.features.feature['text_weights'].float_list.value))\n      self.assertEqual(2, len(tf_example.features.feature['text2'].int64_list.value))\n      self.assertEqual(2, len(tf_example.features.feature['text3_ids'].int64_list.value))\n      self.assertEqual(2, len(tf_example.features.feature['text3_weights'].float_list.value))\n      self.assertEqual(1, len(tf_example.features.feature['text4'].bytes_list.value))\n\n      cmd = ['cd %s && ' % CODE_PATH,\n             'python -m trainer.task',\n             '--train=' + os.path.join(output_dir, 'transform', 'features*'),\n             '--eval=' + os.path.join(output_dir, 'transform', 'features*'),\n             '--job-dir=' + os.path.join(output_dir, 'training'),\n             '--analysis=' + os.path.join(output_dir, 'analysis'),\n             '--model=linear_regression',\n             '--train-batch-size=4',\n             '--eval-batch-size=4',\n             '--max-steps=200',\n             '--learning-rate=0.1']\n      subprocess.check_call(' '.join(cmd), shell=True)\n\n      result = run_exported_model(\n          model_path=os.path.join(output_dir, 'training', 'model'),\n          csv_data=['20,hello moon'])\n\n      # check keys were made\n      self.assertEqual(20, result['num2'])\n      self.assertEqual('hello moon', result['text4'])\n    finally:\n      shutil.rmtree(output_dir)\n\n\nclass TestOptionalKeys(unittest.TestCase):\n  def testNoKeys(self):\n    output_dir = tempfile.mkdtemp()\n    try:\n      features = {\n          'num': {'transform': 'identity'},\n          'target': {'transform': 'target'}}\n      schema = [\n          {'name': 'num', 'type': 'integer'},\n          {'name': 'target', 'type': 'float'}]\n      data = ['1,2\\n', '4,8\\n', '5,10\\n', '11,22\\n']\n      file_io.recursive_create_dir(output_dir)\n      file_io.write_string_to_file(os.path.join(output_dir, 'schema.json'),\n                                   json.dumps(schema, indent=2))\n      file_io.write_string_to_file(os.path.join(output_dir, 'features.json'),\n                                   json.dumps(features, indent=2))\n      file_io.write_string_to_file(os.path.join(output_dir, 'data.csv'),\n                                   ''.join(data))\n\n      cmd = ['python %s' % os.path.join(CODE_PATH, 'analyze.py'),\n             '--output=' + os.path.join(output_dir, 'analysis'),\n             '--csv=' + os.path.join(output_dir, 'data.csv'),\n             '--schema=' + os.path.join(output_dir, 'schema.json'),\n             '--features=' + os.path.join(output_dir, 'features.json')]\n      subprocess.check_call(' '.join(cmd), shell=True)\n\n      cmd = ['cd %s && ' % CODE_PATH,\n             'python -m trainer.task',\n             '--train=' + os.path.join(output_dir, 'data.csv'),\n             '--eval=' + os.path.join(output_dir, 'data.csv'),\n             '--job-dir=' + os.path.join(output_dir, 'training'),\n             '--analysis=' + os.path.join(output_dir, 'analysis'),\n             '--model=linear_regression',\n             '--train-batch-size=4',\n             '--eval-batch-size=4',\n             '--max-steps=2000',\n             '--learning-rate=0.1',\n             '--transform']\n\n      subprocess.check_call(' '.join(cmd), shell=True)\n\n      result = run_exported_model(\n          model_path=os.path.join(output_dir, 'training', 'model'),\n          csv_data=['20'])\n\n      self.assertTrue(abs(40 - result['predicted']) < 5)\n    finally:\n      shutil.rmtree(output_dir)\n\n  def testManyKeys(self):\n    output_dir = tempfile.mkdtemp()\n    try:\n      features = {\n          'keyint': {'transform': 'key'},\n          'keyfloat': {'transform': 'key'},\n          'keystr': {'transform': 'key'},\n          'num': {'transform': 'identity'},\n          'target': {'transform': 'target'}}\n      schema = [\n          {'name': 'keyint', 'type': 'integer'},\n          {'name': 'keyfloat', 'type': 'float'},\n          {'name': 'keystr', 'type': 'string'},\n          {'name': 'num', 'type': 'integer'},\n          {'name': 'target', 'type': 'float'}]\n      data = ['1,1.5,one,1,2\\n', '2,2.5,two,4,8\\n', '3,3.5,three,5,10\\n']\n      file_io.recursive_create_dir(output_dir)\n      file_io.write_string_to_file(os.path.join(output_dir, 'schema.json'),\n                                   json.dumps(schema, indent=2))\n      file_io.write_string_to_file(os.path.join(output_dir, 'features.json'),\n                                   json.dumps(features, indent=2))\n      file_io.write_string_to_file(os.path.join(output_dir, 'data.csv'),\n                                   ''.join(data))\n\n      cmd = ['python %s' % os.path.join(CODE_PATH, 'analyze.py'),\n             '--output=' + os.path.join(output_dir, 'analysis'),\n             '--csv=' + os.path.join(output_dir, 'data.csv'),\n             '--schema=' + os.path.join(output_dir, 'schema.json'),\n             '--features=' + os.path.join(output_dir, 'features.json')]\n      subprocess.check_call(' '.join(cmd), shell=True)\n\n      cmd = ['cd %s && ' % CODE_PATH,\n             'python -m trainer.task',\n             '--train=' + os.path.join(output_dir, 'data.csv'),\n             '--eval=' + os.path.join(output_dir, 'data.csv'),\n             '--job-dir=' + os.path.join(output_dir, 'training'),\n             '--analysis=' + os.path.join(output_dir, 'analysis'),\n             '--model=linear_regression',\n             '--train-batch-size=4',\n             '--eval-batch-size=4',\n             '--max-steps=2000',\n             '--transform']\n\n      subprocess.check_call(' '.join(cmd), shell=True)\n\n      result = run_exported_model(\n          model_path=os.path.join(output_dir, 'training', 'model'),\n          csv_data=['7,4.5,hello,1'])\n      self.assertEqual(7, result['keyint'])\n      self.assertAlmostEqual(4.5, result['keyfloat'])\n      self.assertEqual('hello', result['keystr'])\n    finally:\n      shutil.rmtree(output_dir)\n\n\nclass TestTrainer(unittest.TestCase):\n  \"\"\"Tests training.\n\n  Runs analyze.py and transform.py on generated test data. Also loads\n  the exported graphs and checks they run. No validation of the test results is\n  done (i.e., the training loss is not checked).\n  \"\"\"\n  def __init__(self, *args, **kwargs):\n    super(TestTrainer, self).__init__(*args, **kwargs)\n\n    # Allow this class to be subclassed for quick tests that only care about\n    # training working, not model loss/accuracy.\n    self._max_steps = 2000\n    self._check_model_fit = True\n\n    # Log everything\n    self._logger = logging.getLogger('TestStructuredDataLogger')\n    self._logger.setLevel(logging.DEBUG)\n    if not self._logger.handlers:\n      self._logger.addHandler(logging.StreamHandler(stream=sys.stdout))\n\n  def setUp(self):\n    self._test_dir = tempfile.mkdtemp()\n\n    self._analysis_output = os.path.join(self._test_dir, 'analysis_output')\n    self._transform_output = os.path.join(self._test_dir, 'transform_output')\n    self._train_output = os.path.join(self._test_dir, 'train_output')\n\n    file_io.recursive_create_dir(self._analysis_output)\n    file_io.recursive_create_dir(self._transform_output)\n    file_io.recursive_create_dir(self._train_output)\n\n    self._csv_train_filename = os.path.join(self._test_dir, 'train_csv_data.csv')\n    self._csv_eval_filename = os.path.join(self._test_dir, 'eval_csv_data.csv')\n    self._csv_predict_filename = os.path.join(self._test_dir, 'predict_csv_data.csv')\n    self._schema_filename = os.path.join(self._test_dir, 'schema_file.json')\n    self._features_filename = os.path.join(self._test_dir, 'features_file.json')\n\n  def tearDown(self):\n    self._logger.debug('TestTrainer: removing test dir ' + self._test_dir)\n    shutil.rmtree(self._test_dir)\n\n  def make_image_files(self):\n    img1_file = os.path.join(self._test_dir, 'img1.jpg')\n    image1 = Image.new('RGB', size=(300, 300), color=(155, 0, 0))\n    image1.save(img1_file)\n    img2_file = os.path.join(self._test_dir, 'img2.jpg')\n    image2 = Image.new('RGB', size=(50, 50), color=(125, 240, 0))\n    image2.save(img2_file)\n    img3_file = os.path.join(self._test_dir, 'img3.jpg')\n    image3 = Image.new('RGB', size=(800, 600), color=(33, 55, 77))\n    image3.save(img3_file)\n    self._image_files = [img1_file, img2_file, img3_file]\n\n  def make_csv_data(self, filename, num_rows, problem_type, keep_target=True, with_image=False):\n    \"\"\"Writes csv data for preprocessing and training.\n\n    There is one csv column for each supported transform.\n\n    Args:\n      filename: writes data to local csv file.\n      num_rows: how many rows of data will be generated.\n      problem_type: 'classification' or 'regression'. Changes the target value.\n      keep_target: if false, the csv file will have an empty column ',,' for the\n          target.\n    \"\"\"\n    random.seed(12321)\n\n    def _drop_out(x):\n      # Make 5% of the data missing\n      if random.uniform(0, 1) < 0.05:\n        return ''\n      return x\n\n    with open(filename, 'w') as f:\n      for i in range(num_rows):\n        num_id = random.randint(0, 20)\n        num_scale = random.uniform(0, 30)\n\n        str_one_hot = random.choice(['red', 'blue', 'green', 'pink', 'yellow',\n                                     'brown', 'black'])\n        str_embedding = random.choice(['abc', 'def', 'ghi', 'jkl', 'mno', 'pqr'])\n\n        def _word_fn():\n          return random.choice(['car', 'truck', 'van', 'bike', 'train', 'drone'])\n\n        str_bow = [_word_fn() for _ in range(random.randint(1, 4))]\n        str_tfidf = [_word_fn() for _ in range(random.randint(1, 4))]\n\n        color_map = {'red': 2, 'blue': 6, 'green': 4, 'pink': -5, 'yellow': -6,\n                     'brown': -1, 'black': -7}\n        abc_map = {'abc': -1, 'def': -1, 'ghi': 1, 'jkl': 1, 'mno': 2, 'pqr': 1}\n        transport_map = {'car': 5, 'truck': 10, 'van': 15, 'bike': 20,\n                         'train': -25, 'drone': -30}\n\n        # Build some model: t id the dependent variable\n        t = 0.5 + 0.5 * num_id - 2.5 * num_scale\n        t += color_map[str_one_hot]\n        t += abc_map[str_embedding]\n        t += sum([transport_map[x] for x in str_bow])\n        t += sum([transport_map[x] * 0.5 for x in str_tfidf])\n\n        if problem_type == 'classification':\n          # If you cange the weights above or add more columns, look at the new\n          # distribution of t values and try to divide them into 3 buckets.\n          if t < -40:\n            t = 100\n          elif t < 0:\n            t = 101\n          else:\n            t = 102\n\n        str_bow = ' '.join(str_bow)\n        str_tfidf = ' '.join(str_tfidf)\n        if with_image:\n          img_url = random.choice(self._image_files)\n          _drop_out(img_url)\n\n        num_id = _drop_out(num_id)\n        num_scale = _drop_out(num_scale)\n        str_one_hot = _drop_out(str_one_hot)\n        str_embedding = _drop_out(str_embedding)\n        str_bow = _drop_out(str_bow)\n        str_tfidf = _drop_out(str_tfidf)\n\n        if keep_target:\n          if with_image:\n            csv_line = \"{key},{target},{num_id},{num_scale},{str_one_hot},{str_embedding},{str_bow},{str_tfidf},{img_url}\\n\".format( # noqa\n              key=i,\n              target=t,\n              num_id=num_id,\n              num_scale=num_scale,\n              str_one_hot=str_one_hot,\n              str_embedding=str_embedding,\n              str_bow=str_bow,\n              str_tfidf=str_tfidf,\n              img_url=img_url)\n          else:\n            csv_line = \"{key},{target},{num_id},{num_scale},{str_one_hot},{str_embedding},{str_bow},{str_tfidf}\\n\".format( # noqa\n              key=i,\n              target=t,\n              num_id=num_id,\n              num_scale=num_scale,\n              str_one_hot=str_one_hot,\n              str_embedding=str_embedding,\n              str_bow=str_bow,\n              str_tfidf=str_tfidf)\n        else:\n          if with_image:\n            csv_line = \"{key},{num_id},{num_scale},{str_one_hot},{str_embedding},{str_bow},{str_tfidf},{img_url}\\n\".format(  # noqa\n              key=i,\n              num_id=num_id,\n              num_scale=num_scale,\n              str_one_hot=str_one_hot,\n              str_embedding=str_embedding,\n              str_bow=str_bow,\n              str_tfidf=str_tfidf,\n              img_url=img_url)\n          else:\n            csv_line = \"{key},{num_id},{num_scale},{str_one_hot},{str_embedding},{str_bow},{str_tfidf}\\n\".format(  # noqa\n              key=i,\n              num_id=num_id,\n              num_scale=num_scale,\n              str_one_hot=str_one_hot,\n              str_embedding=str_embedding,\n              str_bow=str_bow,\n              str_tfidf=str_tfidf)\n        f.write(csv_line)\n\n  def _create_schema_features(self, problem_type, with_image=False):\n    features = {\n        'num_id': {'transform': 'identity'},\n        'num_scale': {'transform': 'scale', 'value': 4},\n        'str_one_hot': {'transform': 'one_hot'},\n        'str_embedding': {'transform': 'embedding', 'embedding_dim': 3},\n        'str_bow': {'transform': 'bag_of_words'},\n        'str_tfidf': {'transform': 'tfidf'},\n        'target': {'transform': 'target'},\n        'key': {'transform': 'key'}}\n    if with_image:\n      # Download inception checkpoint. Note that gs url doesn't work because\n      # we may not have gcloud signed in when running the test.\n      url = ('https://storage.googleapis.com/cloud-ml-data/img/' +\n             'flower_photos/inception_v3_2016_08_28.ckpt')\n      checkpoint_path = os.path.join(self._test_dir, \"checkpoint\")\n      response = urlopen(url)\n      with open(checkpoint_path, 'wb') as f:\n        f.write(response.read())\n\n      features['image'] = {'transform': 'image_to_vec', 'checkpoint': checkpoint_path}\n\n    schema = [\n        {'name': 'key', 'type': 'integer'},\n        {'name': 'target', 'type': 'string' if problem_type == 'classification' else 'float'},\n        {'name': 'num_id', 'type': 'integer'},\n        {'name': 'num_scale', 'type': 'float'},\n        {'name': 'str_one_hot', 'type': 'string'},\n        {'name': 'str_embedding', 'type': 'string'},\n        {'name': 'str_bow', 'type': 'string'},\n        {'name': 'str_tfidf', 'type': 'string'}]\n    if with_image:\n      schema.append({'name': 'image', 'type': 'string'})\n\n    self._schema = schema\n\n    file_io.write_string_to_file(self._schema_filename, json.dumps(schema, indent=2))\n    file_io.write_string_to_file(self._features_filename, json.dumps(features, indent=2))\n\n    if with_image:\n      self.make_image_files()\n\n    self.make_csv_data(self._csv_train_filename, 50, problem_type, True, with_image)\n    self.make_csv_data(self._csv_eval_filename, 30, problem_type, True, with_image)\n    self.make_csv_data(self._csv_predict_filename, 10, problem_type, False, with_image)\n\n  def _run_analyze(self, problem_type, with_image=False):\n\n    self._create_schema_features(problem_type, with_image=with_image)\n    cmd = ['python %s' % os.path.join(CODE_PATH, 'analyze.py'),\n           '--output=' + self._analysis_output,\n           '--csv=' + self._csv_train_filename,\n           '--schema=' + self._schema_filename,\n           '--features=' + self._features_filename]\n\n    subprocess.check_call(' '.join(cmd), shell=True)\n\n  def _run_transform(self):\n    cmd = ['python %s' % os.path.join(CODE_PATH, 'transform.py'),\n           '--csv=' + self._csv_train_filename,\n           '--analysis=' + self._analysis_output,\n           '--prefix=features_train',\n           '--output=' + self._transform_output,\n           '--shuffle']\n\n    self._logger.debug('Running subprocess: %s \\n\\n' % ' '.join(cmd))\n    subprocess.check_call(' '.join(cmd), shell=True)\n\n    cmd = ['python %s' % os.path.join(CODE_PATH, 'transform.py'),\n           '--csv=' + self._csv_eval_filename,\n           '--analysis=' + self._analysis_output,\n           '--prefix=features_eval',\n           '--output=' + self._transform_output]\n\n    self._logger.debug('Running subprocess: %s \\n\\n' % ' '.join(cmd))\n    subprocess.check_call(' '.join(cmd), shell=True)\n\n  def _run_training_transform(self, problem_type, model_type, extra_args=[]):\n    \"\"\"Runs training starting with transformed tf.example files.\n\n    Args:\n      problem_type: 'regression' or 'classification'\n      model_type: 'linear' or 'dnn'\n      extra_args: list of strings to pass to the trainer.\n    \"\"\"\n    cmd = ['cd %s && ' % CODE_PATH,\n           'python -m trainer.task',\n           '--train=' + os.path.join(self._transform_output, 'features_train*'),\n           '--eval=' + os.path.join(self._transform_output, 'features_eval*'),\n           '--job-dir=' + self._train_output,\n           '--analysis=' + self._analysis_output,\n           '--model=%s_%s' % (model_type, problem_type),\n           '--train-batch-size=100',\n           '--eval-batch-size=50',\n           '--max-steps=' + str(self._max_steps)] + extra_args\n\n    self._logger.debug('Running subprocess: %s \\n\\n' % ' '.join(cmd))\n    subprocess.check_call(' '.join(cmd), shell=True)\n\n  def _run_training_raw(self, problem_type, model_type, extra_args=[]):\n    \"\"\"Runs training starting from raw csv data.\n\n    Args:\n      problem_type: 'regression' or 'classification'\n      model_type: 'linear' or 'dnn'\n      extra_args: list of strings to pass to the trainer.\n    \"\"\"\n    cmd = ['cd %s && ' % CODE_PATH,\n           'python -m trainer.task',\n           '--train=' + self._csv_train_filename,\n           '--eval=' + self._csv_eval_filename,\n           '--job-dir=' + self._train_output,\n           '--analysis=' + self._analysis_output,\n           '--model=%s_%s' % (model_type, problem_type),\n           '--train-batch-size=100',\n           '--eval-batch-size=50',\n           '--max-steps=' + str(self._max_steps),\n           '--transform'] + extra_args\n\n    self._logger.debug('Running subprocess: %s \\n\\n' % ' '.join(cmd))\n    subprocess.check_call(' '.join(cmd), shell=True)\n\n  def _run_training_with_analysis(self, problem_type, model_type, extra_args=[]):\n    \"\"\"Runs training starting from raw csv data.\n\n    Args:\n      problem_type: 'regression' or 'classification'\n      model_type: 'linear' or 'dnn'\n      extra_args: list of strings to pass to the trainer.\n    \"\"\"\n    cmd = ['cd %s && ' % CODE_PATH,\n           'python -m trainer.task',\n           '--train=' + self._csv_train_filename,\n           '--eval=' + self._csv_eval_filename,\n           '--job-dir=' + self._train_output,\n           '--model=%s_%s' % (model_type, problem_type),\n           '--train-batch-size=100',\n           '--eval-batch-size=50',\n           '--max-steps=' + str(self._max_steps),\n           '--features=' + self._features_filename,\n           '--schema=' + self._schema_filename,\n           '--transform'] + extra_args\n\n    self._logger.debug('Running subprocess: %s \\n\\n' % ' '.join(cmd))\n    subprocess.check_call(' '.join(cmd), shell=True)\n\n  def _check_model(self, problem_type, model_type, with_image=False):\n    \"\"\"Checks that both exported prediction graphs work.\"\"\"\n\n    for has_target in [True, False]:\n      if has_target:\n        model_path = os.path.join(self._train_output, 'evaluation_model')\n      else:\n        model_path = os.path.join(self._train_output, 'model')\n\n      self._logger.debug('Checking model %s %s at %s' % (problem_type, model_type, model_path))\n\n      # Check there is a saved model.\n      self.assertTrue(os.path.isfile(os.path.join(model_path, 'saved_model.pb')))\n\n      # Must create new graphs as multiple graphs are loaded into memory.\n      with tf.Graph().as_default(), tf.Session() as sess:\n        meta_graph_pb = tf.saved_model.loader.load(\n            sess=sess,\n            tags=[tf.saved_model.tag_constants.SERVING],\n            export_dir=model_path)\n        signature = meta_graph_pb.signature_def['serving_default']\n\n        input_alias_map = {\n            friendly_name: tensor_info_proto.name\n            for (friendly_name, tensor_info_proto) in signature.inputs.items()}\n        output_alias_map = {\n            friendly_name: tensor_info_proto.name\n            for (friendly_name, tensor_info_proto) in signature.outputs.items()}\n\n        prediction_data = {\n            'key': [12, 11],\n            'target': [-49, -9] if problem_type == 'regression' else ['100', '101'],\n            'num_id': [11, 10],\n            'num_scale': [22.29, 5.20],\n            'str_one_hot': ['brown', 'brown'],\n            'str_embedding': ['def', 'def'],\n            'str_bow': ['drone', 'drone truck bike truck'],\n            'str_tfidf': ['bike train train car', 'train']}\n        if with_image:\n          image_bytes = []\n          for image_file in [self._image_files[0], self._image_files[2]]:\n            with file_io.FileIO(image_file, 'r') as ff:\n              image_bytes.append(base64.urlsafe_b64encode(ff.read()))\n\n          prediction_data.update({'image': image_bytes})\n\n        # Convert the prediciton data to csv.\n        csv_header = [col['name']\n                      for col in self._schema\n                      if (has_target or col['name'] != 'target')]\n        if not has_target:\n          del prediction_data['target']\n\n        csv_data = []\n        for i in range(2):\n          data = [str(prediction_data[name][i]) for name in csv_header]\n          csv_data.append(','.join(data))\n\n        # Test the *_alias_maps have the expected keys\n        expected_output_keys = ['predicted', 'key']\n        if has_target:\n          expected_output_keys.append('target')\n        if problem_type == 'classification':\n          expected_output_keys.extend(\n            ['probability', 'probability_2', 'probability_3', 'predicted_2', 'predicted_3'])\n\n        self.assertEqual(1, len(input_alias_map.keys()))\n        self.assertItemsEqual(expected_output_keys, output_alias_map.keys())\n\n        _, csv_tensor_name = input_alias_map.items()[0]\n        result = sess.run(fetches=output_alias_map,\n                          feed_dict={csv_tensor_name: csv_data})\n\n        self.assertItemsEqual(expected_output_keys, result.keys())\n        self.assertEqual([12, 11], result['key'].flatten().tolist())\n\n  def testClassificationLinear(self):\n    self._logger.debug('\\n\\nTesting Classification Linear')\n\n    problem_type = 'classification'\n    model_type = 'linear'\n    self._run_analyze(problem_type)\n    self._run_training_raw(\n        problem_type=problem_type,\n        model_type=model_type,\n        extra_args=['--top-n=3'])\n    self._check_model(\n        problem_type=problem_type,\n        model_type=model_type)\n\n  def testRegressionLinear(self):\n    self._logger.debug('\\n\\nTesting Regression Linear')\n\n    problem_type = 'regression'\n    model_type = 'linear'\n    self._run_analyze(problem_type)\n    self._run_transform()\n    self._run_training_transform(\n        problem_type=problem_type,\n        model_type=model_type)\n    self._check_model(\n        problem_type=problem_type,\n        model_type=model_type)\n\n  def testRegressionDNN(self):\n    self._logger.debug('\\n\\nTesting Regression DNN')\n\n    problem_type = 'regression'\n    model_type = 'dnn'\n    self._run_analyze(problem_type)\n    self._run_training_raw(\n        problem_type=problem_type,\n        model_type=model_type,\n        extra_args=['--top-n=3',\n                    '--hidden-layer-size1=10',\n                    '--hidden-layer-size2=2'])\n    self._check_model(\n        problem_type=problem_type,\n        model_type=model_type)\n\n  def testClassificationDNNWithImage(self):\n    self._logger.debug('\\n\\nTesting Classification DNN With Image')\n\n    problem_type = 'classification'\n    model_type = 'dnn'\n    self._run_analyze(problem_type, with_image=True)\n    self._run_transform()\n    self._run_training_transform(\n        problem_type=problem_type,\n        model_type=model_type,\n        extra_args=['--top-n=3',\n                    '--hidden-layer-size1=10'])\n    self._check_model(\n        problem_type=problem_type,\n        model_type=model_type,\n        with_image=True)\n\n  def testTrainingWithAnalysis(self):\n    self._logger.debug('\\n\\nTesting Training with Analysis')\n    self._create_schema_features('classification')\n    self._run_training_with_analysis(\n        problem_type='classification',\n        model_type='linear',\n        extra_args=['--top-n=3'])\n    self._check_model(\n        problem_type='classification',\n        model_type='linear')\n\n\nif __name__ == '__main__':\n    unittest.main()\n"
  },
  {
    "path": "solutionbox/ml_workbench/test_tensorflow/test_transform.py",
    "content": "from __future__ import absolute_import\nfrom __future__ import print_function\n\nimport json\nimport os\nimport pandas as pd\nfrom PIL import Image\nimport shutil\nfrom six.moves.urllib.request import urlopen\nimport subprocess\nimport tempfile\nimport unittest\nimport uuid\n\nimport tensorflow as tf\nfrom tensorflow.python.lib.io import file_io\n\nimport google.datalab as dl\nimport google.datalab.bigquery as bq\nimport google.datalab.storage as storage\n\nCODE_PATH = os.path.abspath(os.path.join(\n    os.path.dirname(__file__), '..', 'tensorflow'))\n\n# TODO: travis tests failed because sometimes a VM has gcloud signed-in\n# (maybe due to failed cleanup) with default project set and BQ is not enabled.\n# In that case the cloud tests will fail. Disable it for now.\nRUN_CLOUD_TESTS = False\n\n\nclass TestTransformRawData(unittest.TestCase):\n  \"\"\"Tests for applying a saved model\"\"\"\n\n  @classmethod\n  def setUpClass(cls):\n\n    # Set up dirs.\n    cls.working_dir = tempfile.mkdtemp()\n    cls.source_dir = os.path.join(cls.working_dir, 'source')\n    cls.analysis_dir = os.path.join(cls.working_dir, 'analysis')\n    cls.output_dir = os.path.join(cls.working_dir, 'output')\n    file_io.create_dir(cls.source_dir)\n\n    # Make test image files.\n    img1_file = os.path.join(cls.source_dir, 'img1.jpg')\n    image1 = Image.new('RGB', size=(300, 300), color=(155, 0, 0))\n    image1.save(img1_file)\n    img2_file = os.path.join(cls.source_dir, 'img2.jpg')\n    image2 = Image.new('RGB', size=(50, 50), color=(125, 240, 0))\n    image2.save(img2_file)\n    img3_file = os.path.join(cls.source_dir, 'img3.jpg')\n    image3 = Image.new('RGB', size=(800, 600), color=(33, 55, 77))\n    image3.save(img3_file)\n\n    # Download inception checkpoint. Note that gs url doesn't work because\n    # we may not have gcloud signed in when running the test.\n    url = ('https://storage.googleapis.com/cloud-ml-data/img/' +\n           'flower_photos/inception_v3_2016_08_28.ckpt')\n    checkpoint_path = os.path.join(cls.working_dir, \"checkpoint\")\n    response = urlopen(url)\n    with open(checkpoint_path, 'wb') as f:\n      f.write(response.read())\n\n    # Make csv input file\n    cls.csv_input_filepath = os.path.join(cls.source_dir, 'input.csv')\n    file_io.write_string_to_file(\n        cls.csv_input_filepath,\n        '1,1,Monday,23.0,%s\\n' % img1_file +\n        '2,0,Friday,18.0,%s\\n' % img2_file +\n        '3,0,Sunday,12.0,%s\\n' % img3_file)\n\n    # Call analyze.py to create analysis results.\n    schema = [{'name': 'key_col', 'type': 'INTEGER'},\n              {'name': 'target_col', 'type': 'FLOAT'},\n              {'name': 'cat_col', 'type': 'STRING'},\n              {'name': 'num_col', 'type': 'FLOAT'},\n              {'name': 'img_col', 'type': 'STRING'}]\n    schema_file = os.path.join(cls.source_dir, 'schema.json')\n    file_io.write_string_to_file(schema_file, json.dumps(schema))\n    features = {'key_col': {'transform': 'key'},\n                'target_col': {'transform': 'target'},\n                'cat_col': {'transform': 'one_hot'},\n                'num_col': {'transform': 'identity'},\n                'img_col': {'transform': 'image_to_vec', 'checkpoint': checkpoint_path}}\n    features_file = os.path.join(cls.source_dir, 'features.json')\n    file_io.write_string_to_file(features_file, json.dumps(features))\n    cmd = ['python ' + os.path.join(CODE_PATH, 'analyze.py'),\n           '--output=' + cls.analysis_dir,\n           '--csv=' + cls.csv_input_filepath,\n           '--schema=' + schema_file,\n           '--features=' + features_file]\n    subprocess.check_call(' '.join(cmd), shell=True)\n\n  @classmethod\n  def tearDownClass(cls):\n    shutil.rmtree(cls.working_dir)\n\n  def test_local_csv_transform(self):\n    \"\"\"Test transfrom from local csv files.\"\"\"\n\n    cmd = ['python ' + os.path.join(CODE_PATH, 'transform.py'),\n           '--csv=' + self.csv_input_filepath,\n           '--analysis=' + self.analysis_dir,\n           '--prefix=features',\n           '--output=' + self.output_dir]\n    print('cmd ', ' '.join(cmd))\n    subprocess.check_call(' '.join(cmd), shell=True)\n\n    # Read the tf record file. There should only be one file.\n    record_filepath = os.path.join(self.output_dir,\n                                   'features-00000-of-00001.tfrecord.gz')\n    options = tf.python_io.TFRecordOptions(\n        compression_type=tf.python_io.TFRecordCompressionType.GZIP)\n    serialized_examples = list(tf.python_io.tf_record_iterator(record_filepath, options=options))\n    self.assertEqual(len(serialized_examples), 3)\n\n    # Find the example with key=1 in the file.\n    first_example = None\n    for ex in serialized_examples:\n      example = tf.train.Example()\n      example.ParseFromString(ex)\n      if example.features.feature['key_col'].int64_list.value[0] == 1:\n        first_example = example\n    self.assertIsNotNone(first_example)\n\n    transformed_number = first_example.features.feature['num_col'].float_list.value[0]\n    self.assertAlmostEqual(transformed_number, 23.0)\n\n    # transformed category = row number in the vocab file.\n    transformed_category = first_example.features.feature['cat_col'].int64_list.value[0]\n    vocab = pd.read_csv(\n        os.path.join(self.analysis_dir, 'vocab_cat_col.csv'),\n        header=None,\n        names=['label', 'count'],\n        dtype=str)\n    origional_category = vocab.iloc[transformed_category]['label']\n    self.assertEqual(origional_category, 'Monday')\n\n    image_bytes = first_example.features.feature['img_col'].float_list.value\n    self.assertEqual(len(image_bytes), 2048)\n    self.assertTrue(any(x != 0.0 for x in image_bytes))\n\n  @unittest.skipIf(not RUN_CLOUD_TESTS, 'GCS access missing')\n  def test_local_bigquery_transform(self):\n    \"\"\"Test transfrom locally, but the data comes from bigquery.\"\"\"\n\n    # Make a BQ table, and insert 1 row.\n    try:\n      bucket_name = 'temp_pydatalab_test_%s' % uuid.uuid4().hex\n      bucket_root = 'gs://%s' % bucket_name\n      bucket = storage.Bucket(bucket_name)\n      bucket.create()\n\n      project_id = dl.Context.default().project_id\n\n      dataset_name = 'test_transform_raw_data_%s' % uuid.uuid4().hex\n      table_name = 'tmp_table'\n\n      dataset = bq.Dataset((project_id, dataset_name)).create()\n      table = bq.Table((project_id, dataset_name, table_name))\n      table.create([{'name': 'key_col', 'type': 'INTEGER'},\n                    {'name': 'target_col', 'type': 'FLOAT'},\n                    {'name': 'cat_col', 'type': 'STRING'},\n                    {'name': 'num_col', 'type': 'FLOAT'},\n                    {'name': 'img_col', 'type': 'STRING'}])\n\n      img1_file = os.path.join(self.source_dir, 'img1.jpg')\n      dest_file = os.path.join(bucket_root, 'img1.jpg')\n      file_io.copy(img1_file, dest_file)\n\n      data = [\n          {\n           'key_col': 1,\n           'target_col': 1.0,\n           'cat_col': 'Monday',\n           'num_col': 23.0,\n           'img_col': dest_file,\n          },\n      ]\n      table.insert(data=data)\n\n      cmd = ['python ' + os.path.join(CODE_PATH, 'transform.py'),\n             '--bigquery=%s.%s.%s' % (project_id, dataset_name, table_name),\n             '--analysis=' + self.analysis_dir,\n             '--prefix=features',\n             '--project-id=' + project_id,\n             '--output=' + self.output_dir]\n      print('cmd ', ' '.join(cmd))\n      subprocess.check_call(' '.join(cmd), shell=True)\n\n      # Read the tf record file. There should only be one file.\n      record_filepath = os.path.join(self.output_dir,\n                                     'features-00000-of-00001.tfrecord.gz')\n      options = tf.python_io.TFRecordOptions(\n          compression_type=tf.python_io.TFRecordCompressionType.GZIP)\n      serialized_examples = list(tf.python_io.tf_record_iterator(record_filepath, options=options))\n      self.assertEqual(len(serialized_examples), 1)\n\n      example = tf.train.Example()\n      example.ParseFromString(serialized_examples[0])\n\n      transformed_number = example.features.feature['num_col'].float_list.value[0]\n      self.assertAlmostEqual(transformed_number, 23.0)\n      transformed_category = example.features.feature['cat_col'].int64_list.value[0]\n      self.assertEqual(transformed_category, 2)\n      image_bytes = example.features.feature['img_col'].float_list.value\n      self.assertEqual(len(image_bytes), 2048)\n      self.assertTrue(any(x != 0.0 for x in image_bytes))\n    finally:\n      dataset.delete(delete_contents=True)\n\n      for obj in bucket.objects():\n        obj.delete()\n      bucket.delete()\n\n\nif __name__ == '__main__':\n    unittest.main()\n"
  },
  {
    "path": "solutionbox/ml_workbench/test_xgboost/run_all.sh",
    "content": "#! /bin/bash\nset -e\n\necho '*** Running xgboost test_analyze.py ***'\npython test_analyze.py --verbose\n\necho '*** Running xgboost test_transform.py ***'\npython test_transform.py --verbose\n\necho 'Finished xgboost run_all.sh!'\n"
  },
  {
    "path": "solutionbox/ml_workbench/test_xgboost/test_analyze.py",
    "content": "from __future__ import absolute_import\nfrom __future__ import print_function\n\nimport json\nimport os\nimport shutil\nimport sys\nimport tempfile\nimport unittest\nimport pandas as pd\nimport six\n\nfrom tensorflow.python.lib.io import file_io\n\n\n# To make 'import analyze' work without installing it.\nCODE_PATH = os.path.abspath(\n    os.path.join(os.path.dirname(__file__), '..', '', 'xgboost'))\nsys.path.append(CODE_PATH)\n\n\nfrom trainer import feature_analysis as feature_analysis  # noqa: E303\nimport analyze  # noqa: E303\n\n\nclass TestConfigFiles(unittest.TestCase):\n  \"\"\"Tests for checking the format between the schema and features files.\"\"\"\n\n  def test_expand_defaults_do_nothing(self):\n    schema = [{'name': 'col1', 'type': 'FLOAT'},\n              {'name': 'col2', 'type': 'INTEGER'}]\n    features = {'col1': {'transform': 'x'},\n                'col2': {'transform': 'y'}}\n    expected_features = {\n        'col1': {'transform': 'x', 'source_column': 'col1'},\n        'col2': {'transform': 'y', 'source_column': 'col2'}}\n\n    feature_analysis.expand_defaults(schema, features)\n\n    # Nothing should change.\n    self.assertEqual(expected_features, features)\n\n  def test_expand_defaults_unknown_schema_type(self):\n    schema = [{'name': 'col1', 'type': 'BYTES'},\n              {'name': 'col2', 'type': 'INTEGER'}]\n    features = {'col1': {'transform': 'x'},\n                'col2': {'transform': 'y'}}\n\n    with self.assertRaises(ValueError):\n      feature_analysis.expand_defaults(schema, features)\n\n  def test_expand_defaults(self):\n    schema = [{'name': 'col1', 'type': 'FLOAT'},\n              {'name': 'col2', 'type': 'INTEGER'},\n              {'name': 'col3', 'type': 'STRING'},\n              {'name': 'col4', 'type': 'FLOAT'},\n              {'name': 'col5', 'type': 'INTEGER'},\n              {'name': 'col6', 'type': 'STRING'}]\n    features = {'col1': {'transform': 'x'},\n                'col2': {'transform': 'y'},\n                'col3': {'transform': 'z'}}\n\n    feature_analysis.expand_defaults(schema, features)\n\n    self.assertEqual(\n      features,\n      {'col1': {'transform': 'x', 'source_column': 'col1'},\n       'col2': {'transform': 'y', 'source_column': 'col2'},\n       'col3': {'transform': 'z', 'source_column': 'col3'},\n       'col4': {'transform': 'identity', 'source_column': 'col4'},\n       'col5': {'transform': 'identity', 'source_column': 'col5'},\n       'col6': {'transform': 'one_hot', 'source_column': 'col6'}})\n\n\nclass TestLocalAnalyze(unittest.TestCase):\n  \"\"\"Test local analyze functions.\"\"\"\n\n  def test_numerics(self):\n    output_folder = tempfile.mkdtemp()\n    input_file_path = tempfile.mkstemp(dir=output_folder)[1]\n    try:\n      file_io.write_string_to_file(\n        input_file_path,\n        '\\n'.join(['%s,%s,%s' % (i, 10 * i + 0.5, i + 0.5) for i in range(100)]))\n\n      schema = [{'name': 'col1', 'type': 'INTEGER'},\n                {'name': 'col2', 'type': 'FLOAT'},\n                {'name': 'col3', 'type': 'FLOAT'}]\n      features = {'col1': {'transform': 'scale', 'source_column': 'col1'},\n                  'col2': {'transform': 'identity', 'source_column': 'col2'},\n                  'col3': {'transform': 'target'}}\n      feature_analysis.run_local_analysis(\n          output_folder, [input_file_path], schema, features)\n\n      stats = json.loads(\n          file_io.read_file_to_string(\n              os.path.join(output_folder, analyze.constant.STATS_FILE)).decode())\n\n      self.assertEqual(stats['num_examples'], 100)\n      col = stats['column_stats']['col1']\n      self.assertAlmostEqual(col['max'], 99.0)\n      self.assertAlmostEqual(col['min'], 0.0)\n      self.assertAlmostEqual(col['mean'], 49.5)\n\n      col = stats['column_stats']['col2']\n      self.assertAlmostEqual(col['max'], 990.5)\n      self.assertAlmostEqual(col['min'], 0.5)\n      self.assertAlmostEqual(col['mean'], 495.5)\n    finally:\n      shutil.rmtree(output_folder)\n\n  def test_categorical(self):\n    output_folder = tempfile.mkdtemp()\n    input_file_path = tempfile.mkstemp(dir=output_folder)[1]\n    try:\n      csv_file = ['red,apple', 'red,pepper', 'red,apple', 'blue,grape',\n                  'blue,apple', 'green,pepper']\n      file_io.write_string_to_file(\n        input_file_path,\n        '\\n'.join(csv_file))\n\n      schema = [{'name': 'color', 'type': 'STRING'},\n                {'name': 'type', 'type': 'STRING'}]\n      features = {'color': {'transform': 'one_hot', 'source_column': 'color'},\n                  'type': {'transform': 'target'}}\n      feature_analysis.run_local_analysis(\n        output_folder, [input_file_path], schema, features)\n\n      stats = json.loads(\n          file_io.read_file_to_string(\n              os.path.join(output_folder, analyze.constant.STATS_FILE)).decode())\n      self.assertEqual(stats['column_stats']['color']['vocab_size'], 3)\n\n      # Color column.\n      vocab_str = file_io.read_file_to_string(\n        os.path.join(output_folder, analyze.constant.VOCAB_ANALYSIS_FILE % 'color'))\n      vocab = pd.read_csv(six.StringIO(vocab_str),\n                          header=None,\n                          names=['color', 'count'])\n      expected_vocab = pd.DataFrame(\n          {'color': ['red', 'blue', 'green'], 'count': [3, 2, 1]},\n          columns=['color', 'count'])\n      pd.util.testing.assert_frame_equal(vocab, expected_vocab)\n\n    finally:\n      shutil.rmtree(output_folder)\n\n  def test_text(self):\n    output_folder = tempfile.mkdtemp()\n    input_file_path = tempfile.mkstemp(dir=output_folder)[1]\n    try:\n      csv_file = ['the quick brown fox,cat1|cat2,true',\n                  'quick   brown brown chicken,cat2|cat3|cat4,false']\n      file_io.write_string_to_file(\n        input_file_path,\n        '\\n'.join(csv_file))\n\n      schema = [{'name': 'col1', 'type': 'STRING'},\n                {'name': 'col2', 'type': 'STRING'},\n                {'name': 'col3', 'type': 'STRING'}]\n      features = {'col1': {'transform': 'multi_hot', 'source_column': 'col1'},\n                  'col2': {'transform': 'multi_hot', 'source_column': 'col2', 'separator': '|'},\n                  'col3': {'transform': 'target'}}\n      feature_analysis.run_local_analysis(\n        output_folder, [input_file_path], schema, features)\n\n      stats = json.loads(\n          file_io.read_file_to_string(\n              os.path.join(output_folder, analyze.constant.STATS_FILE)).decode())\n      self.assertEqual(stats['column_stats']['col1']['vocab_size'], 5)\n      self.assertEqual(stats['column_stats']['col2']['vocab_size'], 4)\n\n      vocab_str = file_io.read_file_to_string(\n          os.path.join(output_folder,\n                       analyze.constant.VOCAB_ANALYSIS_FILE % 'col1'))\n      vocab = pd.read_csv(six.StringIO(vocab_str),\n                          header=None,\n                          names=['col1', 'count'])\n\n      # vocabs are sorted by count only\n      col1_vocab = vocab['col1'].tolist()\n      self.assertItemsEqual(col1_vocab[:2], ['brown', 'quick'])\n      self.assertItemsEqual(col1_vocab[2:], ['chicken', 'fox', 'the'])\n      self.assertEqual(vocab['count'].tolist(), [2, 2, 1, 1, 1])\n\n      vocab_str = file_io.read_file_to_string(\n          os.path.join(output_folder,\n                       analyze.constant.VOCAB_ANALYSIS_FILE % 'col2'))\n      vocab = pd.read_csv(six.StringIO(vocab_str),\n                          header=None,\n                          names=['col2', 'count'])\n\n      # vocabs are sorted by count only\n      col2_vocab = vocab['col2'].tolist()\n      self.assertItemsEqual(col2_vocab, ['cat2', 'cat1', 'cat3', 'cat4'])\n      self.assertEqual(vocab['count'].tolist(), [2, 1, 1, 1])\n    finally:\n      shutil.rmtree(output_folder)\n\n\nif __name__ == '__main__':\n    unittest.main()\n"
  },
  {
    "path": "solutionbox/ml_workbench/test_xgboost/test_transform.py",
    "content": "from __future__ import absolute_import\nfrom __future__ import print_function\n\nimport json\nimport os\nimport pandas as pd\nfrom PIL import Image\nfrom six.moves.urllib.request import urlopen\nimport subprocess\nimport tempfile\nimport unittest\nimport xgboost as xgb\n\nfrom tensorflow.python.lib.io import file_io\n\n\nCODE_PATH = os.path.abspath(os.path.join(\n    os.path.dirname(__file__), '..', 'xgboost'))\n\n\nclass TestTransformRawData(unittest.TestCase):\n  \"\"\"Tests for applying a saved model\"\"\"\n\n  @classmethod\n  def setUpClass(cls):\n\n    # Set up dirs.\n    cls.working_dir = tempfile.mkdtemp()\n    cls.source_dir = os.path.join(cls.working_dir, 'source')\n    cls.analysis_dir = os.path.join(cls.working_dir, 'analysis')\n    cls.output_dir = os.path.join(cls.working_dir, 'output')\n    file_io.create_dir(cls.source_dir)\n\n    # Make test image files.\n    img1_file = os.path.join(cls.source_dir, 'img1.jpg')\n    image1 = Image.new('RGB', size=(300, 300), color=(155, 0, 0))\n    image1.save(img1_file)\n    img2_file = os.path.join(cls.source_dir, 'img2.jpg')\n    image2 = Image.new('RGB', size=(50, 50), color=(125, 240, 0))\n    image2.save(img2_file)\n    img3_file = os.path.join(cls.source_dir, 'img3.jpg')\n    image3 = Image.new('RGB', size=(800, 600), color=(33, 55, 77))\n    image3.save(img3_file)\n\n    # Download inception checkpoint. Note that gs url doesn't work because\n    # we may not have gcloud signed in when running the test.\n    url = ('https://storage.googleapis.com/cloud-ml-data/img/' +\n           'flower_photos/inception_v3_2016_08_28.ckpt')\n    checkpoint_path = os.path.join(cls.working_dir, \"checkpoint\")\n    response = urlopen(url)\n    with open(checkpoint_path, 'wb') as f:\n      f.write(response.read())\n\n    # Make csv input file\n    cls.csv_input_filepath = os.path.join(cls.source_dir, 'input.csv')\n    file_io.write_string_to_file(\n        cls.csv_input_filepath,\n        '1,Monday,23.0,red blue,%s\\n' % img1_file +\n        '0,Friday,18.0,green,%s\\n' % img2_file +\n        '0,Sunday,12.0,green red blue green,%s\\n' % img3_file)\n\n    # Call analyze.py to create analysis results.\n    schema = [{'name': 'target_col', 'type': 'FLOAT'},\n              {'name': 'cat_col', 'type': 'STRING'},\n              {'name': 'num_col', 'type': 'FLOAT'},\n              {'name': 'text_col', 'type': 'STRING'},\n              {'name': 'img_col', 'type': 'STRING'}]\n    schema_file = os.path.join(cls.source_dir, 'schema.json')\n    file_io.write_string_to_file(schema_file, json.dumps(schema))\n    features = {'target_col': {'transform': 'target'},\n                'cat_col': {'transform': 'one_hot'},\n                'num_col': {'transform': 'identity'},\n                'text_col': {'transform': 'multi_hot'},\n                'img_col': {'transform': 'image_to_vec', 'checkpoint': checkpoint_path}}\n    features_file = os.path.join(cls.source_dir, 'features.json')\n    file_io.write_string_to_file(features_file, json.dumps(features))\n    cmd = ['python ' + os.path.join(CODE_PATH, 'analyze.py'),\n           '--output=' + cls.analysis_dir,\n           '--csv=' + cls.csv_input_filepath,\n           '--schema=' + schema_file,\n           '--features=' + features_file]\n    subprocess.check_call(' '.join(cmd), shell=True)\n\n  @classmethod\n  def tearDownClass(cls):\n    pass\n    # shutil.rmtree(cls.working_dir)\n\n  def test_local_csv_transform(self):\n    \"\"\"Test transfrom from local csv files.\"\"\"\n\n    cmd = ['python ' + os.path.join(CODE_PATH, 'transform.py'),\n           '--csv=' + self.csv_input_filepath,\n           '--analysis=' + self.analysis_dir,\n           '--prefix=features',\n           '--output=' + self.output_dir]\n    print('cmd ', ' '.join(cmd))\n    subprocess.check_call(' '.join(cmd), shell=True)\n\n    # Verify transformed file.\n    libsvm_filepath = os.path.join(self.output_dir, 'features-00000-of-00001.libsvm')\n    dtrain = xgb.DMatrix(libsvm_filepath)\n    self.assertTrue(2056, dtrain.num_col())\n    self.assertTrue(3, dtrain.num_row())\n\n    # Verify featuremap file.\n    featuremap_filepath = os.path.join(self.output_dir, 'featuremap-00000-of-00001.txt')\n    df = pd.read_csv(featuremap_filepath, names=['index', 'description'])\n    pd.util.testing.assert_series_equal(pd.Series(range(1, 2056), name='index'), df['index'])\n    expected_descriptions = ['cat_col=Sunday', 'cat_col=Monday', 'img_col image feature 1000',\n                             'num_col', 'text_col has \"blue\"']\n    self.assertTrue(all(x in df['description'].values for x in expected_descriptions))\n\n\nif __name__ == '__main__':\n    unittest.main()\n"
  },
  {
    "path": "solutionbox/ml_workbench/xgboost/__init__.py",
    "content": ""
  },
  {
    "path": "solutionbox/ml_workbench/xgboost/analyze.py",
    "content": "# Copyright 2017 Google Inc. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport argparse\nimport copy\nimport json\nimport os\nimport sys\nimport six\nimport textwrap\nfrom tensorflow.python.lib.io import file_io\n\nfrom trainer import feature_transforms as constant\nfrom trainer import feature_analysis as feature_analysis\n\n\ndef parse_arguments(argv):\n  \"\"\"Parse command line arguments.\n\n  Args:\n    argv: list of command line arguments, including program name.\n\n  Returns:\n    An argparse Namespace object.\n\n  Raises:\n    ValueError: for bad parameters\n  \"\"\"\n  parser = argparse.ArgumentParser(\n      formatter_class=argparse.RawDescriptionHelpFormatter,\n      description=textwrap.dedent(\"\"\"\\\n          Runs analysis on structured data and produces auxiliary files for\n          training. The output files can also be used by the Transform step\n          to materialize TF.Examples files, which for some problems can speed up\n          training.\n\n          Description of input files\n          --------------------------\n\n          1) If using csv files, the --schema parameter must be the file path to\n             a schema file. The format of this file must be a valid BigQuery\n             schema file, which is a JSON file containing a list of dicts.\n             Consider the example schema file below:\n\n             [\n                {\"name\": \"column_name_1\", \"type\": \"integer\"},\n                {\"name\": \"column_name_2\", \"type\": \"float\"},\n                {\"name\": \"column_name_3\", \"type\": \"string\"},\n                {\"name\": \"column_name_4\", \"type\": \"string\"},\n             ]\n\n             Note that the column names in the csv file much match the order\n             in the schema list. Also, we only support three BigQuery types (\n             integer, float, and string).\n\n             If instead of csv files, --bigquery is used, the schema file\n             is not needed as this program will extract it from\n             the table directly.\n\n          2) --features is a file path to a file describing the\n             transformations. Below is an example features file:\n\n             {\n                \"column_name_1\": {\"transform\": \"scale\"},\n                \"column_name_3\": {\"transform\": \"target\"},\n                \"column_name_2\": {\"transform\": \"one_hot\"},\n                \"new_feature_name\": {\"transform\": \"multi_hot\", \"source_column\": \"column_name_4\"},\n             }\n\n             The format of the dict is `name`: `transform-dict` where the\n             `name` is the name of the transformed feature. The `source_column`\n             value lists what column in the input data is the source for this\n             transformation. If `source_column` is missing, it is assumed the\n             `name` is a source column and the transformed feature will have\n             the same name as the input column.\n\n             A list of supported `transform-dict`s for xgboost is below:\n\n             {\"transform\": \"identity\"}: does nothing (for numerical columns).\n             {\"transform\": \"scale\", \"value\": x}: scale a numerical column to\n                [-a, a]. If value is missing, x defaults to 1.\n             {\"transform\": \"one_hot\"}: makes a one-hot encoding of a string\n                column.\n             {\"transform\": \"multi_hot\", \"separator\": ' '}: makes a multi-hot\n                encoding of a string column.\n             {\"transform\": \"image_to_vec\", \"checkpoint\": \"gs://b/o\"}: From image\n                gs url to embeddings. \"checkpoint\" is a inception v3 checkpoint.\n                If absent, a default checkpoint is used.\n             {\"transform\": \"target\"}: denotes what column is the target. If the\n                schema type of this column is string, a one_hot encoding is\n                automatically applied. If type is numerical, a identity transform\n                is automatically applied.\n  \"\"\"))\n  parser.add_argument('--cloud',\n                      action='store_true',\n                      help='Analysis will use cloud services.')\n  parser.add_argument('--output',\n                      metavar='DIR',\n                      type=str,\n                      required=True,\n                      help='GCS or local folder')\n\n  input_group = parser.add_argument_group(\n      title='Data Source Parameters',\n      description='schema is only needed if using --csv')\n\n  # CSV input\n  input_group.add_argument('--csv',\n                           metavar='FILE',\n                           type=str,\n                           required=False,\n                           action='append',\n                           help='Input CSV absolute file paths. May contain a '\n                                'file pattern.')\n  input_group.add_argument('--schema',\n                           metavar='FILE',\n                           type=str,\n                           required=False,\n                           help='Schema file path. Only required if using csv files')\n\n  # Bigquery input\n  input_group.add_argument('--bigquery',\n                           metavar='PROJECT_ID.DATASET.TABLE_NAME',\n                           type=str,\n                           required=False,\n                           help=('Must be in the form project.dataset.table_name'))\n\n  parser.add_argument('--features',\n                      metavar='FILE',\n                      type=str,\n                      required=True,\n                      help='Features file path')\n\n  args = parser.parse_args(args=argv[1:])\n\n  if args.cloud:\n    if not args.output.startswith('gs://'):\n      raise ValueError('--output must point to a location on GCS')\n    if (args.csv and\n       not all(x.startswith('gs://') for x in args.csv)):\n      raise ValueError('--csv must point to a location on GCS')\n    if args.schema and not args.schema.startswith('gs://'):\n      raise ValueError('--schema must point to a location on GCS')\n\n  if not args.cloud and args.bigquery:\n    raise ValueError('--bigquery must be used with --cloud')\n\n  if not ((args.bigquery and args.csv is None and\n           args.schema is None) or\n          (args.bigquery is None and args.csv and\n           args.schema)):\n    raise ValueError('either --csv and --schema must both'\n                     ' be set or just --bigquery is set')\n\n  return args\n\n\ndef run_cloud_analysis(output_dir, csv_file_pattern, bigquery_table, schema,\n                       features):\n  \"\"\"Use BigQuery to analyze input date.\n\n  Only one of csv_file_pattern or bigquery_table should be non-None.\n\n  Args:\n    output_dir: output folder\n    csv_file_pattern: list of csv file paths, may contain wildcards\n    bigquery_table: project_id.dataset_name.table_name\n    schema: schema list\n    features: features config\n  \"\"\"\n\n  def _execute_sql(sql, table):\n    \"\"\"Runs a BigQuery job and dowloads the results into local memeory.\n\n    Args:\n      sql: a SQL string\n      table: bq.ExternalDataSource or bq.Table\n\n    Returns:\n      A Pandas dataframe.\n    \"\"\"\n    import google.datalab.bigquery as bq\n    if isinstance(table, bq.ExternalDataSource):\n      query = bq.Query(sql, data_sources={'csv_table': table})\n    else:\n      query = bq.Query(sql)\n    return query.execute().result().to_dataframe()\n\n  feature_analysis.expand_defaults(schema, features)  # features are updated.\n  inverted_features = feature_analysis.invert_features(features)\n  feature_analysis.check_schema_transforms_match(schema, inverted_features)\n\n  import google.datalab.bigquery as bq\n  if bigquery_table:\n    table_name = '`%s`' % bigquery_table\n    table = None\n  else:\n    table_name = 'csv_table'\n    table = bq.ExternalDataSource(\n        source=csv_file_pattern,\n        schema=bq.Schema(schema))\n\n  # Make a copy of inverted_features and update the target transform to be\n  # identity or one hot depending on the schema.\n  inverted_features_target = copy.deepcopy(inverted_features)\n  for name, transforms in six.iteritems(inverted_features_target):\n    transform_set = {x['transform'] for x in transforms}\n    if transform_set == set([constant.TARGET_TRANSFORM]):\n      target_schema = next(col['type'].lower() for col in schema if col['name'] == name)\n      if target_schema in constant.NUMERIC_SCHEMA:\n        inverted_features_target[name] = [{'transform': constant.IDENTITY_TRANSFORM}]\n      else:\n        inverted_features_target[name] = [{'transform': constant.ONE_HOT_TRANSFORM}]\n\n  numerical_vocab_stats = {}\n  for col_name, transform_set in six.iteritems(inverted_features_target):\n    sys.stdout.write('Analyzing column %s...\\n' % col_name)\n    sys.stdout.flush()\n    # All transforms in transform_set require the same analysis. So look\n    # at the first transform.\n    transform = next(iter(transform_set))\n    if (transform['transform'] in constant.CATEGORICAL_TRANSFORMS or\n       transform['transform'] in constant.TEXT_TRANSFORMS):\n      if transform['transform'] in constant.TEXT_TRANSFORMS:\n        # Split strings on space, then extract labels and how many rows each\n        # token is in. This is done by making two temp tables:\n        #   SplitTable: each text row is made into an array of strings. The\n        #       array may contain repeat tokens\n        #   TokenTable: SplitTable with repeated tokens removed per row.\n        # Then to flatten the arrays, TokenTable has to be joined with itself.\n        # See the sections 'Flattening Arrays' and 'Filtering Arrays' at\n        # https://cloud.google.com/bigquery/docs/reference/standard-sql/arrays\n        separator = transform.get('separator', ' ')\n        sql = ('WITH SplitTable AS '\n               '         (SELECT SPLIT({name}, \\'{separator}\\') as token_array FROM {table}), '\n               '     TokenTable AS '\n               '         (SELECT ARRAY(SELECT DISTINCT x '\n               '                       FROM UNNEST(token_array) AS x) AS unique_tokens_per_row '\n               '          FROM SplitTable) '\n               'SELECT token, COUNT(token) as token_count '\n               'FROM TokenTable '\n               'CROSS JOIN UNNEST(TokenTable.unique_tokens_per_row) as token '\n               'WHERE LENGTH(token) > 0 '\n               'GROUP BY token '\n               'ORDER BY token_count DESC, token ASC').format(separator=separator,\n                                                              name=col_name,\n                                                              table=table_name)\n      else:\n        # Extract label and frequency\n        sql = ('SELECT {name} as token, count(*) as count '\n               'FROM {table} '\n               'WHERE {name} IS NOT NULL '\n               'GROUP BY {name} '\n               'ORDER BY count DESC, token ASC').format(name=col_name,\n                                                        table=table_name)\n\n      df = _execute_sql(sql, table)\n\n      # Save the vocab\n      csv_string = df.to_csv(index=False, header=False)\n      file_io.write_string_to_file(\n          os.path.join(output_dir, constant.VOCAB_ANALYSIS_FILE % col_name),\n          csv_string)\n      numerical_vocab_stats[col_name] = {'vocab_size': len(df)}\n\n      # free memeory\n      del csv_string\n      del df\n    elif transform['transform'] in constant.NUMERIC_TRANSFORMS:\n      # get min/max/average\n      sql = ('SELECT max({name}) as max_value, min({name}) as min_value, '\n             'avg({name}) as avg_value from {table}').format(name=col_name,\n                                                             table=table_name)\n      df = _execute_sql(sql, table)\n      numerical_vocab_stats[col_name] = {'min': df.iloc[0]['min_value'],\n                                         'max': df.iloc[0]['max_value'],\n                                         'mean': df.iloc[0]['avg_value']}\n    sys.stdout.write('column %s analyzed.\\n' % col_name)\n    sys.stdout.flush()\n\n  # get num examples\n  sql = 'SELECT count(*) as num_examples from {table}'.format(table=table_name)\n  df = _execute_sql(sql, table)\n  num_examples = df.iloc[0]['num_examples']\n\n  # Write the stats file.\n  stats = {'column_stats': numerical_vocab_stats, 'num_examples': num_examples}\n  file_io.write_string_to_file(\n      os.path.join(output_dir, constant.STATS_FILE),\n      json.dumps(stats, indent=2, separators=(',', ': ')))\n\n  feature_analysis.save_schema_features(schema, features, output_dir)\n\n\ndef main(argv=None):\n  args = parse_arguments(sys.argv if argv is None else argv)\n\n  if args.schema:\n    schema = json.loads(\n        file_io.read_file_to_string(args.schema).decode())\n  else:\n    import google.datalab.bigquery as bq\n    schema = bq.Table(args.bigquery).schema._bq_schema\n  features = json.loads(\n      file_io.read_file_to_string(args.features).decode())\n\n  file_io.recursive_create_dir(args.output)\n\n  if args.cloud:\n    run_cloud_analysis(\n        output_dir=args.output,\n        csv_file_pattern=args.csv,\n        bigquery_table=args.bigquery,\n        schema=schema,\n        features=features)\n  else:\n    feature_analysis.run_local_analysis(\n        output_dir=args.output,\n        csv_file_pattern=args.csv,\n        schema=schema,\n        features=features)\n\n\nif __name__ == '__main__':\n  main()\n"
  },
  {
    "path": "solutionbox/ml_workbench/xgboost/setup.py",
    "content": "# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n# This setup file is used when running cloud training or cloud dataflow jobs.\nfrom setuptools import setup, find_packages\n\n\nsetup(\n  name='trainer',\n  version='1.0.0',\n  packages=find_packages(),\n  description='Google Cloud Datalab helper sub-package',\n  author='Google',\n  author_email='google-cloud-datalab-feedback@googlegroups.com',\n  keywords=[\n  ],\n  license=\"Apache Software License\",\n  long_description=\"\"\"\n  \"\"\",\n  install_requires=[\n    'tensorflow==1.15.2',\n    'protobuf==3.4.0',\n    'pillow==6.2.0',  # ML Engine does not have PIL installed\n    'xgboost==0.6a2',\n  ],\n  package_data={\n  },\n  data_files=[],\n)\n"
  },
  {
    "path": "solutionbox/ml_workbench/xgboost/trainer/__init__.py",
    "content": ""
  },
  {
    "path": "solutionbox/ml_workbench/xgboost/trainer/feature_analysis.py",
    "content": "# Copyright 2017 Google Inc. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport collections\nimport copy\nimport csv\nimport json\nimport os\nimport pandas as pd\nimport sys\nimport six\nfrom tensorflow.python.lib.io import file_io\n\nfrom . import feature_transforms as constant\n\n\ndef check_schema_transforms_match(schema, inverted_features):\n  \"\"\"Checks that the transform and schema do not conflict.\n\n  Args:\n    schema: schema list\n    inverted_features: inverted_features dict\n\n  Raises:\n    ValueError if transform cannot be applied given schema type.\n  \"\"\"\n  num_target_transforms = 0\n\n  for col_schema in schema:\n    col_name = col_schema['name']\n    col_type = col_schema['type'].lower()\n\n    # Check each transform and schema are compatible\n    if col_name in inverted_features:\n      for transform in inverted_features[col_name]:\n        transform_name = transform['transform']\n        if transform_name == constant.TARGET_TRANSFORM:\n          num_target_transforms += 1\n          continue\n\n        elif col_type in constant.NUMERIC_SCHEMA:\n          if transform_name not in constant.NUMERIC_TRANSFORMS:\n            raise ValueError(\n                'Transform %s not supported by schema %s' % (transform_name, col_type))\n        elif col_type == constant.STRING_SCHEMA:\n          if (transform_name not in constant.CATEGORICAL_TRANSFORMS + constant.TEXT_TRANSFORMS and\n             transform_name != constant.IMAGE_TRANSFORM):\n            raise ValueError(\n                'Transform %s not supported by schema %s' % (transform_name, col_type))\n        else:\n          raise ValueError('Unsupported schema type %s' % col_type)\n\n    # Check each transform is compatible for the same source column.\n    # inverted_features[col_name] should belong to exactly 1 of the 5 groups.\n    if col_name in inverted_features:\n      transform_set = {x['transform'] for x in inverted_features[col_name]}\n      if 1 != sum([transform_set.issubset(set(constant.NUMERIC_TRANSFORMS)),\n                   transform_set.issubset(set(constant.CATEGORICAL_TRANSFORMS)),\n                   transform_set.issubset(set(constant.TEXT_TRANSFORMS)),\n                   transform_set.issubset(set([constant.IMAGE_TRANSFORM])),\n                   transform_set.issubset(set([constant.TARGET_TRANSFORM]))]):\n        message = \"\"\"\n          The source column of a feature can only be used in multiple\n          features within the same family of transforms. The familes are\n\n          1) text transformations: %s\n          2) categorical transformations: %s\n          3) numerical transformations: %s\n          4) image transformations: %s\n          5) target transform: %s\n\n          Any column can also be a key column.\n\n          But column %s is used by transforms %s.\n          \"\"\" % (str(constant.TEXT_TRANSFORMS),\n                 str(constant.CATEGORICAL_TRANSFORMS),\n                 str(constant.NUMERIC_TRANSFORMS),\n                 constant.IMAGE_TRANSFORM,\n                 constant.TARGET_TRANSFORM,\n                 col_name,\n                 str(transform_set))\n        raise ValueError(message)\n\n  if num_target_transforms != 1:\n    raise ValueError('Must have exactly one target transform')\n\n\ndef save_schema_features(schema, features, output):\n  # Save a copy of the schema and features in the output folder.\n  file_io.write_string_to_file(\n    os.path.join(output, constant.SCHEMA_FILE),\n    json.dumps(schema, indent=2))\n\n  file_io.write_string_to_file(\n    os.path.join(output, constant.FEATURES_FILE),\n    json.dumps(features, indent=2))\n\n\ndef expand_defaults(schema, features):\n  \"\"\"Add to features any default transformations.\n\n  Not every column in the schema has an explicit feature transformation listed\n  in the featurs file. For these columns, add a default transformation based on\n  the schema's type. The features dict is modified by this function call.\n\n  After this function call, every column in schema is used in a feature, and\n  every feature uses a column in the schema.\n\n  Args:\n    schema: schema list\n    features: features dict\n\n  Raises:\n    ValueError: if transform cannot be applied given schema type.\n  \"\"\"\n\n  schema_names = [x['name'] for x in schema]\n\n  # Add missing source columns\n  for name, transform in six.iteritems(features):\n    if 'source_column' not in transform:\n      transform['source_column'] = name\n\n  # Check source columns are in the schema and collect which are used.\n  used_schema_columns = []\n  for name, transform in six.iteritems(features):\n    if transform['source_column'] not in schema_names:\n      raise ValueError('source column %s is not in the schema for transform %s'\n                       % (transform['source_column'], name))\n    used_schema_columns.append(transform['source_column'])\n\n  # Update default transformation based on schema.\n  for col_schema in schema:\n    schema_name = col_schema['name']\n    schema_type = col_schema['type'].lower()\n\n    if schema_type not in constant.NUMERIC_SCHEMA + [constant.STRING_SCHEMA]:\n      raise ValueError(('Only the following schema types are supported: %s'\n                        % ' '.join(constant.NUMERIC_SCHEMA + [constant.STRING_SCHEMA])))\n\n    if schema_name not in used_schema_columns:\n      # add the default transform to the features\n      if schema_type in constant.NUMERIC_SCHEMA:\n        features[schema_name] = {\n            'transform': constant.DEFAULT_NUMERIC_TRANSFORM,\n            'source_column': schema_name}\n      elif schema_type == constant.STRING_SCHEMA:\n        features[schema_name] = {\n            'transform': constant.DEFAULT_CATEGORICAL_TRANSFORM,\n            'source_column': schema_name}\n      else:\n        raise NotImplementedError('Unknown type %s' % schema_type)\n\n\n# TODO(qimingj): introduce the notion an analysis plan/classes if we\n# support more complicated transforms like binning by quratiles.\ndef invert_features(features):\n  \"\"\"Make a dict in the form source column : set of transforms.\n\n  Note that the key transform is removed.\n  \"\"\"\n  inverted_features = collections.defaultdict(list)\n  for transform in six.itervalues(features):\n    source_column = transform['source_column']\n    inverted_features[source_column].append(transform)\n\n  return dict(inverted_features)  # convert from defaultdict to dict\n\n\ndef run_local_analysis(output_dir, csv_file_pattern, schema, features):\n  \"\"\"Use pandas to analyze csv files.\n\n  Produces a stats file and vocab files.\n\n  Args:\n    output_dir: output folder\n    csv_file_pattern: list of csv file paths, may contain wildcards\n    schema: CSV schema list\n    features: features config\n\n  Raises:\n    ValueError: on unknown transfrorms/schemas\n  \"\"\"\n  sys.stdout.write('Expanding any file patterns...\\n')\n  sys.stdout.flush()\n  header = [column['name'] for column in schema]\n  input_files = []\n  for file_pattern in csv_file_pattern:\n    input_files.extend(file_io.get_matching_files(file_pattern))\n  sys.stdout.write('file list computed.\\n')\n  sys.stdout.flush()\n\n  expand_defaults(schema, features)  # features are updated.\n  inverted_features = invert_features(features)\n  check_schema_transforms_match(schema, inverted_features)\n\n  # Make a copy of inverted_features and update the target transform to be\n  # identity or one hot depending on the schema.\n  inverted_features_target = copy.deepcopy(inverted_features)\n  for name, transforms in six.iteritems(inverted_features_target):\n    transform_set = {x['transform'] for x in transforms}\n    if transform_set == set([constant.TARGET_TRANSFORM]):\n      target_schema = next(col['type'].lower() for col in schema if col['name'] == name)\n      if target_schema in constant.NUMERIC_SCHEMA:\n        inverted_features_target[name] = [{'transform': constant.IDENTITY_TRANSFORM}]\n      else:\n        inverted_features_target[name] = [{'transform': constant.ONE_HOT_TRANSFORM}]\n\n  # initialize the results\n  def _init_numerical_results():\n    return {'min': float('inf'),\n            'max': float('-inf'),\n            'count': 0,\n            'sum': 0.0}\n  numerical_results = collections.defaultdict(_init_numerical_results)\n  vocabs = collections.defaultdict(lambda: collections.defaultdict(int))\n\n  num_examples = 0\n  # for each file, update the numerical stats from that file, and update the set\n  # of unique labels.\n  for input_file in input_files:\n    sys.stdout.write('Analyzing file %s...\\n' % input_file)\n    sys.stdout.flush()\n    with file_io.FileIO(input_file, 'r') as f:\n      for line in csv.reader(f):\n        if len(header) != len(line):\n          raise ValueError('Schema has %d columns but a csv line only has %d columns.' %\n                           (len(header), len(line)))\n        parsed_line = dict(zip(header, line))\n        num_examples += 1\n\n        for col_name, transform_set in six.iteritems(inverted_features_target):\n          # All transforms in transform_set require the same analysis. So look\n          # at the first transform.\n          transform = next(iter(transform_set))\n          if transform['transform'] in constant.TEXT_TRANSFORMS:\n            separator = transform.get('separator', ' ')\n            split_strings = parsed_line[col_name].split(separator)\n\n            # If a label is in the row N times, increase it's vocab count by 1.\n            # This is needed for TFIDF, but it's also an interesting stat.\n            for one_label in set(split_strings):\n              # Filter out empty strings\n              if one_label:\n                vocabs[col_name][one_label] += 1\n          elif transform['transform'] in constant.CATEGORICAL_TRANSFORMS:\n            if parsed_line[col_name]:\n              vocabs[col_name][parsed_line[col_name]] += 1\n          elif transform['transform'] in constant.NUMERIC_TRANSFORMS:\n            if not parsed_line[col_name].strip():\n              continue\n\n            numerical_results[col_name]['min'] = (\n              min(numerical_results[col_name]['min'],\n                  float(parsed_line[col_name])))\n            numerical_results[col_name]['max'] = (\n              max(numerical_results[col_name]['max'],\n                  float(parsed_line[col_name])))\n            numerical_results[col_name]['count'] += 1\n            numerical_results[col_name]['sum'] += float(parsed_line[col_name])\n\n    sys.stdout.write('file %s analyzed.\\n' % input_file)\n    sys.stdout.flush()\n\n  # Write the vocab files. Each label is on its own line.\n  vocab_sizes = {}\n  for name, label_count in six.iteritems(vocabs):\n    # df is now:\n    # label1,count\n    # label2,count\n    # ...\n    # where label1 is the most frequent label, and label2 is the 2nd most, etc.\n    df = pd.DataFrame([{'label': label, 'count': count}\n                       for label, count in sorted(six.iteritems(label_count),\n                                                  key=lambda x: x[1],\n                                                  reverse=True)],\n                      columns=['label', 'count'])\n    csv_string = df.to_csv(index=False, header=False)\n\n    file_io.write_string_to_file(\n        os.path.join(output_dir, constant.VOCAB_ANALYSIS_FILE % name),\n        csv_string)\n\n    vocab_sizes[name] = {'vocab_size': len(label_count)}\n\n  # Update numerical_results to just have min/min/mean\n  for col_name in numerical_results:\n    if float(numerical_results[col_name]['count']) == 0:\n      raise ValueError('Column %s has a zero count' % col_name)\n    mean = (numerical_results[col_name]['sum'] /\n            float(numerical_results[col_name]['count']))\n    del numerical_results[col_name]['sum']\n    del numerical_results[col_name]['count']\n    numerical_results[col_name]['mean'] = mean\n\n  # Write the stats file.\n  numerical_results.update(vocab_sizes)\n  stats = {'column_stats': numerical_results, 'num_examples': num_examples}\n  file_io.write_string_to_file(\n      os.path.join(output_dir, constant.STATS_FILE),\n      json.dumps(stats, indent=2, separators=(',', ': ')))\n\n  save_schema_features(schema, features, output_dir)\n"
  },
  {
    "path": "solutionbox/ml_workbench/xgboost/trainer/feature_transforms.py",
    "content": "from __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport base64\nimport cStringIO\nimport json\nimport os\nfrom PIL import Image\nimport pandas as pd\nimport six\nimport shutil\nimport tensorflow as tf\nimport tempfile\n\n\nfrom tensorflow.contrib.learn.python.learn.utils import input_fn_utils\n\nfrom tensorflow.contrib import lookup\nfrom tensorflow.contrib.slim.python.slim.nets.inception_v3 import inception_v3\nfrom tensorflow.contrib.slim.python.slim.nets.inception_v3 import inception_v3_arg_scope\nfrom tensorflow.python.lib.io import file_io\n\n# ------------------------------------------------------------------------------\n# public constants. Changing these could break user's code\n# ------------------------------------------------------------------------------\n\n# Individual transforms\nIDENTITY_TRANSFORM = 'identity'\nSCALE_TRANSFORM = 'scale'\nONE_HOT_TRANSFORM = 'one_hot'\nMULTI_HOT_TRANSFORM = 'multi_hot'\nTARGET_TRANSFORM = 'target'\nIMAGE_TRANSFORM = 'image_to_vec'\n\n# ------------------------------------------------------------------------------\n# internal constants.\n# ------------------------------------------------------------------------------\n\n# Files\nSCHEMA_FILE = 'schema.json'\nFEATURES_FILE = 'features.json'\nSTATS_FILE = 'stats.json'\nVOCAB_ANALYSIS_FILE = 'vocab_%s.csv'\n\n# Transform collections\nNUMERIC_TRANSFORMS = [IDENTITY_TRANSFORM, SCALE_TRANSFORM]\nCATEGORICAL_TRANSFORMS = [ONE_HOT_TRANSFORM]\nTEXT_TRANSFORMS = [MULTI_HOT_TRANSFORM]\n\n# If the features file is missing transforms, apply these.\nDEFAULT_NUMERIC_TRANSFORM = IDENTITY_TRANSFORM\nDEFAULT_CATEGORICAL_TRANSFORM = ONE_HOT_TRANSFORM\n\n# BigQuery Schema values supported\nINTEGER_SCHEMA = 'integer'\nFLOAT_SCHEMA = 'float'\nSTRING_SCHEMA = 'string'\nNUMERIC_SCHEMA = [INTEGER_SCHEMA, FLOAT_SCHEMA]\n\n# Inception Checkpoint\nINCEPTION_V3_CHECKPOINT = 'gs://cloud-ml-data/img/flower_photos/inception_v3_2016_08_28.ckpt'\nINCEPTION_EXCLUDED_VARIABLES = ['InceptionV3/AuxLogits', 'InceptionV3/Logits', 'global_step']\n\n_img_buf = cStringIO.StringIO()\nImage.new('RGB', (16, 16)).save(_img_buf, 'jpeg')\nIMAGE_DEFAULT_STRING = base64.urlsafe_b64encode(_img_buf.getvalue())\n\nIMAGE_BOTTLENECK_TENSOR_SIZE = 2048\n\n# ------------------------------------------------------------------------------\n# ------------------------------------------------------------------------------\n# start of transform functions\n# ------------------------------------------------------------------------------\n# ------------------------------------------------------------------------------\n\n\ndef _scale(x, min_x_value, max_x_value, output_min, output_max):\n  \"\"\"Scale a column to [output_min, output_max].\n\n  Assumes the columns's range is [min_x_value, max_x_value]. If this is not\n  true at training or prediction time, the output value of this scale could be\n  outside the range [output_min, output_max].\n\n  Raises:\n    ValueError: if min_x_value = max_x_value, as the column is constant.\n  \"\"\"\n\n  if round(min_x_value - max_x_value, 7) == 0:\n    # There is something wrong with the data.\n    # Why round to 7 places? It's the same as unittest's assertAlmostEqual.\n    raise ValueError('In make_scale_tito, min_x_value == max_x_value')\n\n  def _scale(x):\n    min_x_valuef = tf.to_float(min_x_value)\n    max_x_valuef = tf.to_float(max_x_value)\n    output_minf = tf.to_float(output_min)\n    output_maxf = tf.to_float(output_max)\n    return ((((tf.to_float(x) - min_x_valuef) * (output_maxf - output_minf)) /\n            (max_x_valuef - min_x_valuef)) + output_minf)\n\n  return _scale(x)\n\n\ndef _string_to_int(x, vocab):\n  \"\"\"Given a vocabulary and a string tensor `x`, maps `x` into an int tensor.\n  Args:\n    x: A `Column` representing a string value.\n    vocab: list of strings.\n\n  Returns:\n    A `Column` where each string value is mapped to an integer representing\n    its index in the vocab. Out of vocab values are mapped to len(vocab).\n  \"\"\"\n\n  def _map_to_int(x):\n    \"\"\"Maps string tensor into indexes using vocab.\n\n    Args:\n      x : a Tensor/SparseTensor of string.\n    Returns:\n      a Tensor/SparseTensor of indexes (int) of the same shape as x.\n    \"\"\"\n    table = lookup.index_table_from_tensor(\n        vocab,\n        default_value=len(vocab))\n    return table.lookup(x)\n\n  return _map_to_int(x)\n\n\ndef _make_image_to_vec_tito(feature_name, tmp_dir=None, checkpoint=None):\n  \"\"\"Creates a tensor-in-tensor-out function that produces embeddings from image bytes.\n\n  Image to embedding is implemented with Tensorflow's inception v3 model and a pretrained\n  checkpoint. It returns 1x2048 'PreLogits' embeddings for each image.\n\n  Args:\n    feature_name: The name of the feature. Used only to identify the image tensors so\n      we can get gradients for probe in image prediction explaining.\n    tmp_dir: a local directory that is used for downloading the checkpoint. If\n      non, a temp folder will be made and deleted.\n    checkpoint: the inception v3 checkpoint gs or local path. If None, default checkpoint\n      is used.\n\n  Returns: a tensor-in-tensor-out function that takes image string tensor and returns embeddings.\n  \"\"\"\n\n  def _image_to_vec(image_str_tensor):\n\n    def _decode_and_resize(image_tensor):\n      \"\"\"Decodes jpeg string, resizes it and returns a uint8 tensor.\"\"\"\n\n      # These constants are set by Inception v3's expectations.\n      height = 299\n      width = 299\n      channels = 3\n\n      image_tensor = tf.where(tf.equal(image_tensor, ''), IMAGE_DEFAULT_STRING, image_tensor)\n\n      # Fork by whether image_tensor value is a file path, or a base64 encoded string.\n      slash_positions = tf.equal(tf.string_split([image_tensor], delimiter=\"\").values, '/')\n      is_file_path = tf.cast(tf.count_nonzero(slash_positions), tf.bool)\n\n      # The following two functions are required for tf.cond. Note that we can not replace them\n      # with lambda. According to TF docs, if using inline lambda, both branches of condition\n      # will be executed. The workaround is to use a function call.\n      def _read_file():\n        return tf.read_file(image_tensor)\n\n      def _decode_base64():\n        return tf.decode_base64(image_tensor)\n\n      image = tf.cond(is_file_path, lambda: _read_file(), lambda: _decode_base64())\n      image = tf.image.decode_jpeg(image, channels=channels)\n      image = tf.expand_dims(image, 0)\n      image = tf.image.resize_bilinear(image, [height, width], align_corners=False)\n      image = tf.squeeze(image, squeeze_dims=[0])\n      image = tf.cast(image, dtype=tf.uint8)\n      return image\n\n    # The CloudML Prediction API always \"feeds\" the Tensorflow graph with\n    # dynamic batch sizes e.g. (?,).  decode_jpeg only processes scalar\n    # strings because it cannot guarantee a batch of images would have\n    # the same output size.  We use tf.map_fn to give decode_jpeg a scalar\n    # string from dynamic batches.\n    image = tf.map_fn(_decode_and_resize, image_str_tensor, back_prop=False, dtype=tf.uint8)\n    image = tf.image.convert_image_dtype(image, dtype=tf.float32)\n    # \"gradients_[feature_name]\" will be used for computing integrated gradients.\n    image = tf.identity(image, name='gradients_' + feature_name)\n    image = tf.subtract(image, 0.5)\n    inception_input = tf.multiply(image, 2.0)\n\n    # Build Inception layers, which expect a tensor of type float from [-1, 1)\n    # and shape [batch_size, height, width, channels].\n    with tf.contrib.slim.arg_scope(inception_v3_arg_scope()):\n      _, end_points = inception_v3(inception_input, is_training=False)\n\n    embeddings = end_points['PreLogits']\n    inception_embeddings = tf.squeeze(embeddings, [1, 2], name='SpatialSqueeze')\n    return inception_embeddings\n\n  def _tito_from_checkpoint(tito_in, checkpoint, exclude):\n    \"\"\" Create an all-constants tito function from an original tito function.\n\n    Given a tensor-in-tensor-out function which contains variables and a checkpoint path,\n    create a new tensor-in-tensor-out function which includes only constants, and can be\n    used in tft.map.\n    \"\"\"\n\n    def _tito_out(tensor_in):\n      checkpoint_dir = tmp_dir\n      if tmp_dir is None:\n        checkpoint_dir = tempfile.mkdtemp()\n\n      g = tf.Graph()\n      with g.as_default():\n        si = tf.placeholder(dtype=tensor_in.dtype, shape=tensor_in.shape, name=tensor_in.op.name)\n        so = tito_in(si)\n        all_vars = tf.contrib.slim.get_variables_to_restore(exclude=exclude)\n        saver = tf.train.Saver(all_vars)\n        # Downloading the checkpoint from GCS to local speeds up saver.restore() a lot.\n        checkpoint_tmp = os.path.join(checkpoint_dir, 'checkpoint')\n        with file_io.FileIO(checkpoint, 'r') as f_in, file_io.FileIO(checkpoint_tmp, 'w') as f_out:\n          f_out.write(f_in.read())\n        with tf.Session() as sess:\n          saver.restore(sess, checkpoint_tmp)\n          output_graph_def = tf.graph_util.convert_variables_to_constants(sess,\n                                                                          g.as_graph_def(),\n                                                                          [so.op.name])\n        file_io.delete_file(checkpoint_tmp)\n        if tmp_dir is None:\n          shutil.rmtree(checkpoint_dir)\n\n      tensors_out = tf.import_graph_def(output_graph_def,\n                                        input_map={si.name: tensor_in},\n                                        return_elements=[so.name])\n      return tensors_out[0]\n\n    return _tito_out\n\n  if not checkpoint:\n    checkpoint = INCEPTION_V3_CHECKPOINT\n  return _tito_from_checkpoint(_image_to_vec, checkpoint, INCEPTION_EXCLUDED_VARIABLES)\n# ------------------------------------------------------------------------------\n# ------------------------------------------------------------------------------\n# end of transform functions\n# ------------------------------------------------------------------------------\n# ------------------------------------------------------------------------------\n\n\ndef make_preprocessing_fn(output_dir, features, keep_target):\n  \"\"\"Makes a preprocessing function.\n\n  Args:\n    output_dir: folder path that contains the vocab and stats files.\n    features: the features dict\n\n  Returns:\n    a function that takes a dict of input tensors\n  \"\"\"\n  def preprocessing_fn(inputs):\n    \"\"\"Preprocessing function.\n\n    Args:\n      inputs: dictionary of raw input tensors\n\n    Returns:\n      A dictionary of transformed tensors\n    \"\"\"\n    stats = json.loads(\n      file_io.read_file_to_string(\n          os.path.join(output_dir, STATS_FILE)).decode())\n\n    result = {}\n    for name, transform in six.iteritems(features):\n      transform_name = transform['transform']\n      source_column = transform['source_column']\n\n      if transform_name == TARGET_TRANSFORM:\n        if not keep_target:\n          continue\n        if file_io.file_exists(os.path.join(output_dir, VOCAB_ANALYSIS_FILE % source_column)):\n          transform_name = 'one_hot'\n        else:\n          transform_name = 'identity'\n\n      if transform_name == 'identity':\n        result[name] = inputs[source_column]\n      elif transform_name == 'scale':\n        result[name] = _scale(\n            inputs[name],\n            min_x_value=stats['column_stats'][source_column]['min'],\n            max_x_value=stats['column_stats'][source_column]['max'],\n            output_min=transform.get('value', 1) * (-1),\n            output_max=transform.get('value', 1))\n      elif transform_name in [ONE_HOT_TRANSFORM, MULTI_HOT_TRANSFORM]:\n        vocab, ex_count = read_vocab_file(\n            os.path.join(output_dir, VOCAB_ANALYSIS_FILE % source_column))\n        if transform_name == MULTI_HOT_TRANSFORM:\n          separator = transform.get('separator', ' ')\n          tokens = tf.string_split(inputs[source_column], separator)\n          result[name] = _string_to_int(tokens, vocab)\n        else:\n          result[name] = _string_to_int(inputs[source_column], vocab)\n      elif transform_name == IMAGE_TRANSFORM:\n        make_image_to_vec_fn = _make_image_to_vec_tito(\n            name, checkpoint=transform.get('checkpoint', None))\n        result[name] = make_image_to_vec_fn(inputs[source_column])\n      else:\n        raise ValueError('unknown transform %s' % transform_name)\n    return result\n\n  return preprocessing_fn\n\n\ndef csv_header_and_defaults(features, schema, stats, keep_target):\n  \"\"\"Gets csv header and default lists.\"\"\"\n\n  target_name = get_target_name(features)\n  if keep_target and not target_name:\n    raise ValueError('Cannot find target transform')\n\n  csv_header = []\n  record_defaults = []\n  for col in schema:\n    if not keep_target and col['name'] == target_name:\n      continue\n\n    # Note that numerical key columns do not have a stats entry, hence the use\n    # of get(col['name'], {})\n    csv_header.append(col['name'])\n    if col['type'].lower() == INTEGER_SCHEMA:\n      dtype = tf.int64\n      default = int(stats['column_stats'].get(col['name'], {}).get('mean', 0))\n    elif col['type'].lower() == FLOAT_SCHEMA:\n      dtype = tf.float32\n      default = float(stats['column_stats'].get(col['name'], {}).get('mean', 0.0))\n    else:\n      dtype = tf.string\n      default = ''\n\n    record_defaults.append(tf.constant([default], dtype=dtype))\n\n  return csv_header, record_defaults\n\n\ndef build_csv_serving_tensors_for_transform_step(analysis_path,\n                                                 features,\n                                                 schema,\n                                                 stats,\n                                                 keep_target):\n  \"\"\"Builds a serving function starting from raw csv.\n\n  This should only be used by transform.py (the transform step), and the\n\n  For image columns, the image should be a base64 string encoding the image.\n  The output of this function will transform that image to a 2048 long vector\n  using the inception model.\n  \"\"\"\n\n  csv_header, record_defaults = csv_header_and_defaults(features, schema, stats, keep_target)\n\n  placeholder = tf.placeholder(dtype=tf.string, shape=(None,),\n                               name='csv_input_placeholder')\n  tensors = tf.decode_csv(placeholder, record_defaults)\n  raw_features = dict(zip(csv_header, tensors))\n\n  transform_fn = make_preprocessing_fn(analysis_path, features, keep_target)\n  transformed_tensors = transform_fn(raw_features)\n\n  transformed_features = {}\n  # Expand the dims of non-sparse tensors\n  for k, v in six.iteritems(transformed_tensors):\n    if isinstance(v, tf.Tensor) and v.get_shape().ndims == 1:\n      transformed_features[k] = tf.expand_dims(v, -1)\n    else:\n      transformed_features[k] = v\n\n  return input_fn_utils.InputFnOps(\n      transformed_features, None, {\"csv_example\": placeholder})\n\n\ndef get_target_name(features):\n  for name, transform in six.iteritems(features):\n    if transform['transform'] == TARGET_TRANSFORM:\n      return name\n\n  return None\n\n\ndef read_vocab_file(file_path):\n  \"\"\"Reads a vocab file to memeory.\n\n  Args:\n    file_path: Each line of the vocab is in the form \"token,example_count\"\n\n  Returns:\n    Two lists, one for the vocab, and one for just the example counts.\n  \"\"\"\n  with file_io.FileIO(file_path, 'r') as f:\n    vocab_pd = pd.read_csv(\n        f,\n        header=None,\n        names=['vocab', 'count'],\n        dtype=str,  # Prevent pd from converting numerical categories.\n        na_filter=False)  # Prevent pd from converting 'NA' to a NaN.\n\n  vocab = vocab_pd['vocab'].tolist()\n  ex_count = vocab_pd['count'].astype(int).tolist()\n\n  return vocab, ex_count\n\n\ndef get_transformed_feature_indices(features, stats):\n  \"\"\"Returns information about the transformed features.\n\n  Returns:\n    List in the from\n    [(transformed_feature_name, {size: int, index_start: int})]\n  \"\"\"\n\n  feature_indices = []\n  index_start = 1\n  for name, transform in sorted(six.iteritems(features)):\n    transform_name = transform['transform']\n    source_column = transform['source_column']\n    info = {}\n    if transform_name in [IDENTITY_TRANSFORM, SCALE_TRANSFORM]:\n      info['size'] = 1\n    elif transform_name in [ONE_HOT_TRANSFORM, MULTI_HOT_TRANSFORM]:\n      info['size'] = stats['column_stats'][source_column]['vocab_size']\n    elif transform_name == IMAGE_TRANSFORM:\n      info['size'] = IMAGE_BOTTLENECK_TENSOR_SIZE\n    elif transform_name == TARGET_TRANSFORM:\n      info['size'] = 0\n    else:\n      raise ValueError('xgboost does not support transform \"%s\"' % transform)\n\n    info['index_start'] = index_start\n    index_start += info['size']\n    feature_indices.append((name, info))\n\n  return feature_indices\n\n\ndef create_feature_map(features, feature_indices, output_dir):\n  \"\"\"Returns feature_map about the transformed features.\n\n  feature_map includes information such as:\n    1, cat1=0\n    2, cat1=1\n    3, numeric1\n    ...\n  Returns:\n    List in the from\n    [(index, feature_description)]\n  \"\"\"\n  feature_map = []\n  for name, info in feature_indices:\n    transform_name = features[name]['transform']\n    source_column = features[name]['source_column']\n    if transform_name in [IDENTITY_TRANSFORM, SCALE_TRANSFORM]:\n      feature_map.append((info['index_start'], name))\n    elif transform_name in [ONE_HOT_TRANSFORM, MULTI_HOT_TRANSFORM]:\n      vocab, _ = read_vocab_file(\n          os.path.join(output_dir, VOCAB_ANALYSIS_FILE % source_column))\n      for i, word in enumerate(vocab):\n        if transform_name == ONE_HOT_TRANSFORM:\n          feature_map.append((info['index_start'] + i, '%s=%s' % (source_column, word)))\n        elif transform_name == MULTI_HOT_TRANSFORM:\n          feature_map.append((info['index_start'] + i, '%s has \"%s\"' % (source_column, word)))\n    elif transform_name == IMAGE_TRANSFORM:\n      for i in range(info['size']):\n        feature_map.append((info['index_start'] + i, '%s image feature %d' % (source_column, i)))\n\n  return feature_map\n"
  },
  {
    "path": "solutionbox/ml_workbench/xgboost/trainer/task.py",
    "content": "# Copyright 2017 Google Inc. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\nfrom __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport argparse\nimport json\nimport math\nimport multiprocessing\nimport os\nimport re\nimport sys\nimport six\nimport tensorflow as tf\n\nfrom tensorflow.contrib.framework.python.ops import variables as contrib_variables\nfrom tensorflow.contrib.learn.python.learn import export_strategy\nfrom tensorflow.contrib.learn.python.learn import learn_runner\nfrom tensorflow.contrib.learn.python.learn.estimators import model_fn as model_fn_lib\nfrom tensorflow.contrib.learn.python.learn.utils import saved_model_export_utils\nfrom tensorflow.python.client import session as tf_session\nfrom tensorflow.python.framework import dtypes\nfrom tensorflow.python.framework import ops\nfrom tensorflow.python.lib.io import file_io\nfrom tensorflow.python.ops import resources\nfrom tensorflow.python.ops import control_flow_ops\nfrom tensorflow.python.ops import variables\nfrom tensorflow.python.saved_model import builder as saved_model_builder\nfrom tensorflow.python.saved_model import signature_def_utils\nfrom tensorflow.python.saved_model import tag_constants\nfrom tensorflow.python.training import saver\nfrom tensorflow.python.util import compat\n\n\nfrom . import feature_transforms\nfrom . import feature_analysis\n\n# Constants for the Prediction Graph fetch tensors.\nPG_TARGET = 'target'  # from input\n\nPG_REGRESSION_PREDICTED_TARGET = 'predicted'\n\nPG_CLASSIFICATION_FIRST_LABEL = 'predicted'\nPG_CLASSIFICATION_FIRST_SCORE = 'probability'\nPG_CLASSIFICATION_LABEL_TEMPLATE = 'predicted_%s'\nPG_CLASSIFICATION_SCORE_TEMPLATE = 'probability_%s'\n\n\nclass DatalabParser():\n  \"\"\"An arg parser that also prints package specific args with --datalab-help.\n\n  When using Datalab magic's to run this trainer, it prints it's own help menu\n  that describes the required options that are common to all trainers. In order\n  to print just the options that are unique to this trainer, datalab calls this\n  file with --datalab-help.\n\n  This class implements --datalab-help by building a list of help string that only\n  includes the unique parameters.\n  \"\"\"\n\n  def __init__(self, epilog=None, datalab_epilog=None):\n    self.full_parser = argparse.ArgumentParser(epilog=epilog)\n    self.datalab_help = []\n    self.datalab_epilog = datalab_epilog\n\n    # Datalab help string\n    self.full_parser.add_argument(\n        '--datalab-help', action=self.make_datalab_help_action(),\n        help='Show a smaller help message for DataLab only and exit')\n\n    # The arguments added here are required to exist by Datalab's \"%%ml train\" magics.\n    self.full_parser.add_argument(\n        '--train', type=str, required=True, action='append', metavar='FILE')\n    self.full_parser.add_argument(\n        '--eval', type=str, required=True, action='append', metavar='FILE')\n    self.full_parser.add_argument('--job-dir', type=str, required=True)\n    self.full_parser.add_argument(\n        '--analysis', type=str,\n        metavar='ANALYSIS_OUTPUT_DIR',\n        help=('Output folder of analysis. Should contain the schema, stats, and '\n              'vocab files. Path must be on GCS if running cloud training. ' +\n              'If absent, --schema and --features must be provided and ' +\n              'the master trainer will do analysis locally.'))\n    self.full_parser.add_argument(\n        '--transform', action='store_true', default=False,\n        help='If used, input data is raw csv that needs transformation. If analysis ' +\n             'is required to run in trainerm this is automatically set to true.')\n    self.full_parser.add_argument(\n        '--schema', type=str,\n        help='Schema of the training csv file. Only needed if analysis is required.')\n    self.full_parser.add_argument(\n        '--features', type=str,\n        help='Feature transform config. Only needed if analysis is required.')\n\n  def make_datalab_help_action(self):\n    \"\"\"Custom action for --datalab-help.\n\n    The action output the package specific parameters and will be part of \"%%ml train\"\n    help string.\n    \"\"\"\n    datalab_help = self.datalab_help\n    epilog = self.datalab_epilog\n\n    class _CustomAction(argparse.Action):\n\n      def __init__(self, option_strings, dest, help=None):\n        super(_CustomAction, self).__init__(\n            option_strings=option_strings, dest=dest, nargs=0, help=help)\n\n      def __call__(self, parser, args, values, option_string=None):\n        print('\\n\\n'.join(datalab_help))\n        if epilog:\n          print(epilog)\n\n        # We have printed all help string datalab needs. If we don't quit, it will complain about\n        # missing required arguments later.\n        quit()\n    return _CustomAction\n\n  def add_argument(self, name, **kwargs):\n    # Any argument added here is not required by Datalab, and so is unique\n    # to this trainer. Add each argument to the main parser and the datalab helper string.\n    self.full_parser.add_argument(name, **kwargs)\n    name = name.replace('--', '')\n    # leading spaces are needed for datalab's help formatting.\n    msg = '  ' + name + ': '\n    if 'help' in kwargs:\n      msg += kwargs['help'] + ' '\n    if kwargs.get('required', False):\n      msg += 'Required. '\n    else:\n      msg += 'Optional. '\n    if 'choices' in kwargs:\n      msg += 'One of ' + str(kwargs['choices']) + '. '\n    if 'default' in kwargs:\n      msg += 'default: ' + str(kwargs['default']) + '.'\n    self.datalab_help.append(msg)\n\n  def parse_known_args(self, args=None):\n    return self.full_parser.parse_known_args(args=args)\n\n\ndef parse_arguments(argv):\n  \"\"\"Parse the command line arguments.\"\"\"\n  parser = DatalabParser(\n      epilog=('Note that if using a DNN model, --hidden-layer-size1=NUM, '\n              '--hidden-layer-size2=NUM, ..., is also required. '),\n      datalab_epilog=(\"\"\"\n  Note that if using a DNN model,\n  hidden-layer-size1: NUM\n  hidden-layer-size2: NUM\n  ...\n  is also required. \"\"\"))\n\n  # HP parameters\n  parser.add_argument(\n      '--epsilon', type=float, default=0.0005, metavar='R',\n      help='tf.train.AdamOptimizer epsilon. Only used in dnn models.')\n  parser.add_argument(\n      '--l1-regularization', type=float, default=0.0, metavar='R',\n      help='L1 term for linear models.')\n  parser.add_argument(\n      '--l2-regularization', type=float, default=0.0, metavar='R',\n      help='L2 term for linear models.')\n\n  # Model parameters\n  parser.add_argument(\n    '--model', required=True,\n    choices=['linear_classification', 'linear_regression', 'dnn_classification', 'dnn_regression'])\n  parser.add_argument(\n      '--top-n', type=int, default=0, metavar='N',\n      help=('For classification problems, the output graph will contain the '\n            'labels and scores for the top n classes, and results will be in the form of '\n            '\"predicted, predicted_2, ..., probability, probability_2, ...\". '\n            'If --top-n=0, then all labels and scores are returned in the form of '\n            '\"predicted, class_name1, class_name2,...\".'))\n\n  # HP parameters\n  parser.add_argument(\n      '--learning-rate', type=float, default=0.01, metavar='R',\n      help='optimizer learning rate.')\n\n  # Training input parameters\n  parser.add_argument(\n      '--max-steps', type=int, metavar='N',\n      help='Maximum number of training steps to perform. If unspecified, will '\n           'honor \"max-epochs\".')\n  parser.add_argument(\n      '--max-epochs', type=int, default=1000, metavar='N',\n      help='Maximum number of training data epochs on which to train. If '\n           'both \"max-steps\" and \"max-epochs\" are specified, the training '\n           'job will run for \"max-steps\" or \"num-epochs\", whichever occurs '\n           'first. If early stopping is enabled, training may also stop '\n           'earlier.')\n  parser.add_argument(\n      '--train-batch-size', type=int, default=64, metavar='N',\n      help='How many training examples are used per step. If num-epochs is '\n           'used, the last batch may not be full.')\n  parser.add_argument(\n      '--eval-batch-size', type=int, default=64, metavar='N',\n      help='Batch size during evaluation. Larger values increase performance '\n           'but also increase peak memory usgae on the master node. One pass '\n           'over the full eval set is performed per evaluation run.')\n  parser.add_argument(\n      '--min-eval-frequency', type=int, default=1000, metavar='N',\n      help='Minimum number of training steps between evaluations. Evaluation '\n           'does not occur if no new checkpoint is available, hence, this is '\n           'the minimum. If 0, the evaluation will only happen after training. ')\n  parser.add_argument(\n      '--early-stopping-num_evals', type=int, default=3,\n      help='Automatic training stop after results of specified number of evals '\n           'in a row show the model performance does not improve. Set to 0 to '\n           'disable early stopping.')\n  parser.add_argument(\n      '--logging-level', choices=['error', 'warning', 'info'],\n      help='The TF logging level. If absent, use info for cloud training '\n           'and warning for local training.')\n\n  args, remaining_args = parser.parse_known_args(args=argv[1:])\n\n  # All HP parambeters must be unique, so we need to support an unknown number\n  # of --hidden-layer-size1=10 --lhidden-layer-size2=10 ...\n  # Look at remaining_args for hidden-layer-size\\d+ to get the layer info.\n\n  # Get number of layers\n  pattern = re.compile('hidden-layer-size(\\d+)')\n  num_layers = 0\n  for other_arg in remaining_args:\n    match = re.search(pattern, other_arg)\n    if match:\n      if int(match.group(1)) <= 0:\n        raise ValueError('layer size must be a positive integer. Was given %s' % other_arg)\n      num_layers = max(num_layers, int(match.group(1)))\n\n  # Build a new parser so we catch unknown args and missing layer_sizes.\n  parser = argparse.ArgumentParser()\n  for i in range(num_layers):\n    parser.add_argument('--hidden-layer-size%s' % str(i + 1), type=int, required=True)\n\n  layer_args = vars(parser.parse_args(args=remaining_args))\n  hidden_layer_sizes = []\n  for i in range(num_layers):\n    key = 'hidden_layer_size%s' % str(i + 1)\n    hidden_layer_sizes.append(layer_args[key])\n\n  assert len(hidden_layer_sizes) == num_layers\n  args.hidden_layer_sizes = hidden_layer_sizes\n\n  return args\n\n\ndef is_linear_model(model_type):\n  return model_type.startswith('linear_')\n\n\ndef is_dnn_model(model_type):\n  return model_type.startswith('dnn_')\n\n\ndef is_regression_model(model_type):\n  return model_type.endswith('_regression')\n\n\ndef is_classification_model(model_type):\n  return model_type.endswith('_classification')\n\n\ndef build_feature_columns(features, stats, model_type):\n  feature_columns = []\n  is_dnn = is_dnn_model(model_type)\n\n  # Supported transforms:\n  # for DNN\n  #   numerical number\n  #   one hot: sparse int column -> one_hot_column\n  #   ebmedding: sparse int column -> embedding_column\n  #   text: sparse int weighted column -> embedding_column\n  # for linear\n  #   numerical number\n  #   one hot: sparse int column\n  #   ebmedding: sparse int column -> hash int\n  #   text: sparse int weighted column\n  # It is unfortunate that tf.layers has different feature transforms if the\n  # model is linear or DNN. This pacakge should not expose to the user that\n  # we are using tf.layers.\n  for name, transform in six.iteritems(features):\n    transform_name = transform['transform']\n    source_column = transform['source_column']\n\n    if transform_name in feature_transforms.NUMERIC_TRANSFORMS:\n      new_feature = tf.contrib.layers.real_valued_column(name, dimension=1)\n    elif (transform_name == feature_transforms.ONE_HOT_TRANSFORM or\n          transform_name == feature_transforms.MULTI_HOT_TRANSFORM):\n      sparse = tf.contrib.layers.sparse_column_with_integerized_feature(\n          name,\n          bucket_size=stats['column_stats'][source_column]['vocab_size'])\n      if is_dnn:\n        new_feature = tf.contrib.layers.one_hot_column(sparse)\n      else:\n        new_feature = sparse\n    elif transform_name == feature_transforms.EMBEDDING_TRANSFROM:\n      if is_dnn:\n        sparse = tf.contrib.layers.sparse_column_with_integerized_feature(\n            name,\n            bucket_size=stats['column_stats'][source_column]['vocab_size'])\n        new_feature = tf.contrib.layers.embedding_column(\n            sparse,\n            dimension=transform['embedding_dim'])\n      else:\n        new_feature = tf.contrib.layers.sparse_column_with_hash_bucket(\n            name,\n            hash_bucket_size=transform['embedding_dim'],\n            dtype=dtypes.int64)\n    elif transform_name in feature_transforms.TEXT_TRANSFORMS:\n      sparse_ids = tf.contrib.layers.sparse_column_with_integerized_feature(\n          name + '_ids',\n          bucket_size=stats['column_stats'][source_column]['vocab_size'],\n          combiner='sum')\n      sparse_weights = tf.contrib.layers.weighted_sparse_column(\n          sparse_id_column=sparse_ids,\n          weight_column_name=name + '_weights',\n          dtype=dtypes.float32)\n      if is_dnn:\n        new_feature = tf.contrib.layers.one_hot_column(sparse_ids)\n        dimension = int(math.log(stats['column_stats'][source_column]['vocab_size'])) + 1\n        new_feature = tf.contrib.layers.embedding_column(\n            sparse_weights,\n            dimension=dimension,\n            combiner='sqrtn')\n      else:\n        new_feature = sparse_weights\n    elif (transform_name == feature_transforms.TARGET_TRANSFORM or\n          transform_name == feature_transforms.KEY_TRANSFORM):\n      continue\n    elif transform_name == feature_transforms.IMAGE_TRANSFORM:\n      new_feature = tf.contrib.layers.real_valued_column(\n          name,\n          dimension=feature_transforms.IMAGE_HIDDEN_TENSOR_SIZE)\n    else:\n      raise ValueError('Unknown transfrom %s' % transform_name)\n\n    feature_columns.append(new_feature)\n\n  return feature_columns\n\n\ndef recursive_copy(src_dir, dest_dir):\n  \"\"\"Copy the contents of src_dir into the folder dest_dir.\n  Args:\n    src_dir: gsc or local path.\n    dest_dir: gcs or local path.\n  \"\"\"\n\n  file_io.recursive_create_dir(dest_dir)\n  for file_name in file_io.list_directory(src_dir):\n    old_path = os.path.join(src_dir, file_name)\n    new_path = os.path.join(dest_dir, file_name)\n\n    if file_io.is_directory(old_path):\n      recursive_copy(old_path, new_path)\n    else:\n      file_io.copy(old_path, new_path, overwrite=True)\n\n\ndef make_prediction_output_tensors(args, features, input_ops, model_fn_ops,\n                                   keep_target):\n  \"\"\"Makes the final prediction output layer.\"\"\"\n  target_name = feature_transforms.get_target_name(features)\n  key_names = get_key_names(features)\n\n  outputs = {}\n  outputs.update({key_name: tf.squeeze(input_ops.features[key_name])\n                  for key_name in key_names})\n\n  if is_classification_model(args.model):\n\n    # build maps from ints to the origional categorical strings.\n    class_names = read_vocab(args, target_name)\n    table = tf.contrib.lookup.index_to_string_table_from_tensor(\n        mapping=class_names,\n        default_value='UNKNOWN')\n\n    # Get the label of the input target.\n    if keep_target:\n      input_target_label = table.lookup(input_ops.features[target_name])\n      outputs[PG_TARGET] = tf.squeeze(input_target_label)\n\n    # TODO(brandondutra): get the score of the target label too.\n    probabilities = model_fn_ops.predictions['probabilities']\n\n    # if top_n == 0, this means use all the classes. We will use class names as\n    # probabilities labels.\n    if args.top_n == 0:\n      predicted_index = tf.argmax(probabilities, axis=1)\n      predicted = table.lookup(predicted_index)\n      outputs.update({PG_CLASSIFICATION_FIRST_LABEL: predicted})\n      probabilities_list = tf.unstack(probabilities, axis=1)\n      for class_name, p in zip(class_names, probabilities_list):\n        outputs[class_name] = p\n    else:\n      top_n = args.top_n\n\n      # get top k labels and their scores.\n      (top_k_values, top_k_indices) = tf.nn.top_k(probabilities, k=top_n)\n      top_k_labels = table.lookup(tf.to_int64(top_k_indices))\n\n      # Write the top_k values using 2*top_n columns.\n      num_digits = int(math.ceil(math.log(top_n, 10)))\n      if num_digits == 0:\n        num_digits = 1\n      for i in range(0, top_n):\n        # Pad i based on the size of k. So if k = 100, i = 23 -> i = '023'. This\n        # makes sorting the columns easy.\n        padded_i = str(i + 1).zfill(num_digits)\n\n        if i == 0:\n          label_alias = PG_CLASSIFICATION_FIRST_LABEL\n        else:\n          label_alias = PG_CLASSIFICATION_LABEL_TEMPLATE % padded_i\n\n        label_tensor_name = (tf.squeeze(\n            tf.slice(top_k_labels, [0, i], [tf.shape(top_k_labels)[0], 1])))\n\n        if i == 0:\n          score_alias = PG_CLASSIFICATION_FIRST_SCORE\n        else:\n          score_alias = PG_CLASSIFICATION_SCORE_TEMPLATE % padded_i\n\n        score_tensor_name = (tf.squeeze(\n            tf.slice(top_k_values,\n                     [0, i],\n                     [tf.shape(top_k_values)[0], 1])))\n\n        outputs.update({label_alias: label_tensor_name,\n                        score_alias: score_tensor_name})\n\n  else:\n    if keep_target:\n      outputs[PG_TARGET] = tf.squeeze(input_ops.features[target_name])\n\n    scores = model_fn_ops.predictions['scores']\n    outputs[PG_REGRESSION_PREDICTED_TARGET] = tf.squeeze(scores)\n\n  return outputs\n\n\n# This function is strongly based on\n# tensorflow/contrib/learn/python/learn/estimators/estimator.py:export_savedmodel()\n# The difference is we need to modify estimator's output layer.\ndef make_export_strategy(\n        args,\n        keep_target,\n        assets_extra,\n        features,\n        schema,\n        stats):\n  \"\"\"Makes prediction graph that takes json input.\n\n  Args:\n    args: command line args\n    keep_target: If ture, target column is returned in prediction graph. Target\n        column must also exist in input data\n    assets_extra: other fiels to copy to the output folder\n    job_dir: root job folder\n    features: features dict\n    schema: schema list\n    stats: stats dict\n  \"\"\"\n  target_name = feature_transforms.get_target_name(features)\n  csv_header = [col['name'] for col in schema]\n  if not keep_target:\n    csv_header.remove(target_name)\n\n  def export_fn(estimator, export_dir_base, checkpoint_path=None, eval_result=None):\n    with ops.Graph().as_default() as g:\n      contrib_variables.create_global_step(g)\n\n      input_ops = feature_transforms.build_csv_serving_tensors_for_training_step(\n          args.analysis, features, schema, stats, keep_target)\n      model_fn_ops = estimator._call_model_fn(input_ops.features,\n                                              None,\n                                              model_fn_lib.ModeKeys.INFER)\n      output_fetch_tensors = make_prediction_output_tensors(\n          args=args,\n          features=features,\n          input_ops=input_ops,\n          model_fn_ops=model_fn_ops,\n          keep_target=keep_target)\n\n      # Don't use signature_def_utils.predict_signature_def as that renames\n      # tensor names if there is only 1 input/output tensor!\n      signature_inputs = {key: tf.saved_model.utils.build_tensor_info(tensor)\n                          for key, tensor in six.iteritems(input_ops.default_inputs)}\n      signature_outputs = {key: tf.saved_model.utils.build_tensor_info(tensor)\n                           for key, tensor in six.iteritems(output_fetch_tensors)}\n      signature_def_map = {\n          'serving_default':\n              signature_def_utils.build_signature_def(\n                  signature_inputs,\n                  signature_outputs,\n                  tf.saved_model.signature_constants.PREDICT_METHOD_NAME)}\n\n      if not checkpoint_path:\n        # Locate the latest checkpoint\n        checkpoint_path = saver.latest_checkpoint(estimator._model_dir)\n      if not checkpoint_path:\n        raise ValueError(\"Couldn't find trained model at %s.\"\n                         % estimator._model_dir)\n\n      export_dir = saved_model_export_utils.get_timestamped_export_dir(\n          export_dir_base)\n\n      if (model_fn_ops.scaffold is not None and\n         model_fn_ops.scaffold.saver is not None):\n        saver_for_restore = model_fn_ops.scaffold.saver\n      else:\n        saver_for_restore = saver.Saver(sharded=True)\n\n      with tf_session.Session('') as session:\n        saver_for_restore.restore(session, checkpoint_path)\n        init_op = control_flow_ops.group(\n            variables.local_variables_initializer(),\n            resources.initialize_resources(resources.shared_resources()),\n            tf.tables_initializer())\n\n        # Perform the export\n        builder = saved_model_builder.SavedModelBuilder(export_dir)\n        builder.add_meta_graph_and_variables(\n            session, [tag_constants.SERVING],\n            signature_def_map=signature_def_map,\n            assets_collection=ops.get_collection(\n                ops.GraphKeys.ASSET_FILEPATHS),\n            legacy_init_op=init_op)\n        builder.save(False)\n\n      # Add the extra assets\n      if assets_extra:\n        assets_extra_path = os.path.join(compat.as_bytes(export_dir),\n                                         compat.as_bytes('assets.extra'))\n        for dest_relative, source in assets_extra.items():\n          dest_absolute = os.path.join(compat.as_bytes(assets_extra_path),\n                                       compat.as_bytes(dest_relative))\n          dest_path = os.path.dirname(dest_absolute)\n          file_io.recursive_create_dir(dest_path)\n          file_io.copy(source, dest_absolute)\n\n    # only keep the last 3 models\n    saved_model_export_utils.garbage_collect_exports(\n        export_dir_base,\n        exports_to_keep=3)\n\n    # save the last model to the model folder.\n    # export_dir_base = A/B/intermediate_models/\n    if keep_target:\n      final_dir = os.path.join(args.job_dir, 'evaluation_model')\n    else:\n      final_dir = os.path.join(args.job_dir, 'model')\n    if file_io.is_directory(final_dir):\n      file_io.delete_recursively(final_dir)\n    file_io.recursive_create_dir(final_dir)\n    recursive_copy(export_dir, final_dir)\n\n    return export_dir\n\n  if keep_target:\n    intermediate_dir = 'intermediate_evaluation_models'\n  else:\n    intermediate_dir = 'intermediate_prediction_models'\n\n  return export_strategy.ExportStrategy(intermediate_dir, export_fn)\n\n\ndef get_estimator(args, output_dir, features, stats, target_vocab_size):\n  # Check layers used for dnn models.\n  if is_dnn_model(args.model) and not args.hidden_layer_sizes:\n    raise ValueError('--hidden-layer-size* must be used with DNN models')\n  if is_linear_model(args.model) and args.hidden_layer_sizes:\n    raise ValueError('--hidden-layer-size* cannot be used with linear models')\n\n  # Build tf.learn features\n  feature_columns = build_feature_columns(features, stats, args.model)\n\n  # Set how often to run checkpointing in terms of steps.\n  config = tf.contrib.learn.RunConfig(\n      save_checkpoints_steps=args.min_eval_frequency)\n\n  train_dir = os.path.join(output_dir, 'train')\n  if args.model == 'dnn_regression':\n    estimator = tf.contrib.learn.DNNRegressor(\n        feature_columns=feature_columns,\n        hidden_units=args.hidden_layer_sizes,\n        config=config,\n        model_dir=train_dir,\n        optimizer=tf.train.AdamOptimizer(\n            args.learning_rate, epsilon=args.epsilon))\n  elif args.model == 'linear_regression':\n    estimator = tf.contrib.learn.LinearRegressor(\n        feature_columns=feature_columns,\n        config=config,\n        model_dir=train_dir,\n        optimizer=tf.train.FtrlOptimizer(\n            args.learning_rate,\n            l1_regularization_strength=args.l1_regularization,\n            l2_regularization_strength=args.l2_regularization))\n  elif args.model == 'dnn_classification':\n    estimator = tf.contrib.learn.DNNClassifier(\n        feature_columns=feature_columns,\n        hidden_units=args.hidden_layer_sizes,\n        n_classes=target_vocab_size,\n        config=config,\n        model_dir=train_dir,\n        optimizer=tf.train.AdamOptimizer(\n            args.learning_rate, epsilon=args.epsilon))\n  elif args.model == 'linear_classification':\n    estimator = tf.contrib.learn.LinearClassifier(\n        feature_columns=feature_columns,\n        n_classes=target_vocab_size,\n        config=config,\n        model_dir=train_dir,\n        optimizer=tf.train.FtrlOptimizer(\n            args.learning_rate,\n            l1_regularization_strength=args.l1_regularization,\n            l2_regularization_strength=args.l2_regularization))\n  else:\n    raise ValueError('bad --model-type value')\n\n  return estimator\n\n\ndef read_vocab(args, column_name):\n  \"\"\"Reads a vocab file if it exists.\n\n  Args:\n    args: command line flags\n    column_name: name of column to that has a vocab file.\n\n  Returns:\n    List of vocab words or [] if the vocab file is not found.\n  \"\"\"\n  vocab_path = os.path.join(args.analysis,\n                            feature_transforms.VOCAB_ANALYSIS_FILE % column_name)\n\n  if not file_io.file_exists(vocab_path):\n    return []\n\n  vocab, _ = feature_transforms.read_vocab_file(vocab_path)\n  return vocab\n\n\ndef get_key_names(features):\n  names = []\n  for name, transform in six.iteritems(features):\n    if transform['transform'] == feature_transforms.KEY_TRANSFORM:\n      names.append(name)\n  return names\n\n\ndef read_json_file(file_path):\n  if not file_io.file_exists(file_path):\n    raise ValueError('File not found: %s' % file_path)\n  return json.loads(file_io.read_file_to_string(file_path).decode())\n\n\ndef get_experiment_fn(args):\n  \"\"\"Builds the experiment function for learn_runner.run.\n\n  Args:\n    args: the command line args\n\n  Returns:\n    A function that returns a tf.learn experiment object.\n  \"\"\"\n\n  def get_experiment(output_dir):\n    # Read schema, input features, and transforms.\n    schema_path_with_target = os.path.join(args.analysis,\n                                           feature_transforms.SCHEMA_FILE)\n    features_path = os.path.join(args.analysis,\n                                 feature_transforms.FEATURES_FILE)\n    stats_path = os.path.join(args.analysis,\n                              feature_transforms.STATS_FILE)\n\n    schema = read_json_file(schema_path_with_target)\n    features = read_json_file(features_path)\n    stats = read_json_file(stats_path)\n\n    target_column_name = feature_transforms.get_target_name(features)\n    if not target_column_name:\n      raise ValueError('target missing from features file.')\n\n    # Make a copy of the schema file without the target column.\n    schema_without_target = [col for col in schema if col['name'] != target_column_name]\n    schema_path_without_target = os.path.join(args.job_dir, 'schema_without_target.json')\n    file_io.recursive_create_dir(args.job_dir)\n    file_io.write_string_to_file(schema_path_without_target,\n                                 json.dumps(schema_without_target, indent=2))\n\n    # Make list of files to save with the trained model.\n    additional_assets_with_target = {\n        feature_transforms.FEATURES_FILE: features_path,\n        feature_transforms.SCHEMA_FILE: schema_path_with_target}\n    additional_assets_without_target = {\n        feature_transforms.FEATURES_FILE: features_path,\n        feature_transforms.SCHEMA_FILE: schema_path_without_target}\n\n    # Get the model to train.\n    target_vocab = read_vocab(args, target_column_name)\n    estimator = get_estimator(args, output_dir, features, stats, len(target_vocab))\n\n    export_strategy_csv_notarget = make_export_strategy(\n        args=args,\n        keep_target=False,\n        assets_extra=additional_assets_without_target,\n        features=features,\n        schema=schema,\n        stats=stats)\n    export_strategy_csv_target = make_export_strategy(\n        args=args,\n        keep_target=True,\n        assets_extra=additional_assets_with_target,\n        features=features,\n        schema=schema,\n        stats=stats)\n\n    # Build readers for training.\n    if args.transform:\n      if any(v['transform'] == feature_transforms.IMAGE_TRANSFORM\n             for k, v in six.iteritems(features)):\n        raise ValueError('\"image_to_vec\" transform requires transformation step. ' +\n                         'Cannot train from raw data.')\n\n      input_reader_for_train = feature_transforms.build_csv_transforming_training_input_fn(\n          schema=schema,\n          features=features,\n          stats=stats,\n          analysis_output_dir=args.analysis,\n          raw_data_file_pattern=args.train,\n          training_batch_size=args.train_batch_size,\n          num_epochs=args.max_epochs,\n          randomize_input=True,\n          min_after_dequeue=10,\n          reader_num_threads=multiprocessing.cpu_count())\n      input_reader_for_eval = feature_transforms.build_csv_transforming_training_input_fn(\n          schema=schema,\n          features=features,\n          stats=stats,\n          analysis_output_dir=args.analysis,\n          raw_data_file_pattern=args.eval,\n          training_batch_size=args.eval_batch_size,\n          num_epochs=1,\n          randomize_input=False,\n          reader_num_threads=multiprocessing.cpu_count())\n    else:\n      input_reader_for_train = feature_transforms.build_tfexample_transfored_training_input_fn(\n          schema=schema,\n          features=features,\n          analysis_output_dir=args.analysis,\n          raw_data_file_pattern=args.train,\n          training_batch_size=args.train_batch_size,\n          num_epochs=args.max_epochs,\n          randomize_input=True,\n          min_after_dequeue=10,\n          reader_num_threads=multiprocessing.cpu_count())\n      input_reader_for_eval = feature_transforms.build_tfexample_transfored_training_input_fn(\n          schema=schema,\n          features=features,\n          analysis_output_dir=args.analysis,\n          raw_data_file_pattern=args.eval,\n          training_batch_size=args.eval_batch_size,\n          num_epochs=1,\n          randomize_input=False,\n          reader_num_threads=multiprocessing.cpu_count())\n\n    if args.early_stopping_num_evals == 0:\n      train_monitors = None\n    else:\n      if is_classification_model(args.model):\n        early_stop_monitor = tf.contrib.learn.monitors.ValidationMonitor(\n            input_fn=input_reader_for_eval,\n            every_n_steps=args.min_eval_frequency,\n            early_stopping_rounds=(args.early_stopping_num_evals * args.min_eval_frequency),\n            early_stopping_metric='accuracy',\n            early_stopping_metric_minimize=False)\n      else:\n        early_stop_monitor = tf.contrib.learn.monitors.ValidationMonitor(\n            input_fn=input_reader_for_eval,\n            every_n_steps=args.min_eval_frequency,\n            early_stopping_rounds=(args.early_stopping_num_evals * args.min_eval_frequency))\n      train_monitors = [early_stop_monitor]\n\n    return tf.contrib.learn.Experiment(\n        estimator=estimator,\n        train_input_fn=input_reader_for_train,\n        eval_input_fn=input_reader_for_eval,\n        train_steps=args.max_steps,\n        train_monitors=train_monitors,\n        export_strategies=[export_strategy_csv_notarget, export_strategy_csv_target],\n        min_eval_frequency=args.min_eval_frequency,\n        eval_steps=None)\n\n  # Return a function to create an Experiment.\n  return get_experiment\n\n\ndef local_analysis(args):\n  if args.analysis:\n    # Already analyzed.\n    return\n\n  if not args.schema or not args.features:\n    raise ValueError('Either --analysis, or both --schema and --features are provided.')\n\n  tf_config = json.loads(os.environ.get('TF_CONFIG', '{}'))\n  cluster_spec = tf_config.get('cluster', {})\n  if len(cluster_spec.get('worker', [])) > 0:\n    raise ValueError('If \"schema\" and \"features\" are provided, local analysis will run and ' +\n                     'only BASIC scale-tier (no workers node) is supported.')\n\n  if cluster_spec and not (args.schema.startswith('gs://') and args.features.startswith('gs://')):\n    raise ValueError('Cloud trainer requires GCS paths for --schema and --features.')\n\n  print('Running analysis.')\n  schema = json.loads(file_io.read_file_to_string(args.schema).decode())\n  features = json.loads(file_io.read_file_to_string(args.features).decode())\n  args.analysis = os.path.join(args.job_dir, 'analysis')\n  args.transform = True\n  file_io.recursive_create_dir(args.analysis)\n  feature_analysis.run_local_analysis(args.analysis, args.train, schema, features)\n  print('Analysis done.')\n\n\ndef set_logging_level(args):\n  if 'TF_CONFIG' in os.environ:\n    tf.logging.set_verbosity(tf.logging.INFO)\n  else:\n    tf.logging.set_verbosity(tf.logging.ERROR)\n  if args.logging_level == 'error':\n    tf.logging.set_verbosity(tf.logging.ERROR)\n  elif args.logging_level == 'warning':\n    tf.logging.set_verbosity(tf.logging.WARN)\n  elif args.logging_level == 'info':\n    tf.logging.set_verbosity(tf.logging.INFO)\n\n\ndef main(argv=None):\n  args = parse_arguments(sys.argv if argv is None else argv)\n  local_analysis(args)\n  set_logging_level(args)\n  # Supress TensorFlow Debugging info.\n  os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'\n\n  learn_runner.run(\n      experiment_fn=get_experiment_fn(args),\n      output_dir=args.job_dir)\n\n\nif __name__ == '__main__':\n  main()\n"
  },
  {
    "path": "solutionbox/ml_workbench/xgboost/transform.py",
    "content": "# Copyright 2017 Google Inc. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n# Flake8 cannot disable a warning for the file. Flake8 does not like beam code\n# and reports many 'W503 line break before binary operator' errors. So turn off\n# flake8 for this file.\n# flake8: noqa\nfrom __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport argparse\nimport datetime\nimport json\nimport logging\nimport os\nimport sys\nimport apache_beam as beam\nimport textwrap\n\n\ndef parse_arguments(argv):\n  \"\"\"Parse command line arguments.\n  Args:\n    argv: list of command line arguments including program name.\n  Returns:\n    The parsed arguments as returned by argparse.ArgumentParser.\n  \"\"\"\n  parser = argparse.ArgumentParser(\n      formatter_class=argparse.RawDescriptionHelpFormatter,\n      description=textwrap.dedent(\"\"\"\\\n          Runs preprocessing on raw data for TensorFlow training.\n\n          This script applies some transformations to raw data to improve\n          training performance. Some data transformations can be expensive\n          such as the tf-idf text column transformation. During training, the\n          same raw data row might be used multiply times to train a model. This\n          means the same transformations are applied to the same data row\n          multiple times. This can be very inefficient, so this script applies\n          partial transformations to the raw data and writes an intermediate \n          preprocessed datasource to disk for training. \n\n          Running this transformation step is required for two usage paths:\n            1) If the img_url_to_vec transform is used. This is because\n               preprocessing as image is expensive and TensorFlow cannot easily\n               read raw image files during training.\n            2) If the raw data is in BigQuery. TensorFlow cannot read from a \n               BigQuery source.\n\n          Running this transformation step is recommended if a text transform is\n          used (like tf-idf or bag-of-words), and the text value for each row\n          is very long.\n\n          Running this transformation step may not have an interesting training\n          performance impact if the transforms are all simple like scaling\n          numerical values.\"\"\"))\n\n  source_group = parser.add_mutually_exclusive_group(required=True)\n\n  source_group.add_argument(\n      '--csv',\n      metavar='FILE',\n      required=False,\n      action='append',\n      help='CSV data to transform.')\n\n  source_group.add_argument(\n      '--bigquery',\n      metavar='PROJECT_ID.DATASET.TABLE_NAME',\n      type=str,\n      required=False,\n      help=('Must be in the form `project.dataset.table_name`. BigQuery '\n            'data to transform'))\n\n  parser.add_argument(\n      '--analysis',\n      metavar='ANALYSIS_OUTPUT_DIR',\n      required=True,\n      help='The output folder of analyze')\n\n  parser.add_argument(\n      '--prefix',\n      metavar='OUTPUT_FILENAME_PREFIX',\n      required=True,\n      type=str)\n\n  parser.add_argument(\n      '--output',\n      metavar='DIR',\n      default=None,\n      required=True,\n      help=('Google Cloud Storage or Local directory in which '\n            'to place outputs.'))\n\n  parser.add_argument(\n      '--shuffle',\n      action='store_true',\n      default=False,\n      help='If used, data source is shuffled. This is recommended for training data.')\n\n  parser.add_argument(\n      '--batch-size',\n      metavar='N',\n      type=int,\n      default=100,\n      help='Larger values increase performance and peak memory usage.')\n\n  cloud_group = parser.add_argument_group(\n      title='Cloud Parameters',\n      description='These parameters are only used if --cloud is used.')\n\n  cloud_group.add_argument(\n      '--cloud',\n      action='store_true',\n      help='Run preprocessing on the cloud.')\n\n  cloud_group.add_argument(\n      '--job-name',\n      type=str,\n      help='Unique dataflow job name.')\n\n  cloud_group.add_argument(\n      '--project-id',\n      help='The project to which the job will be submitted.')\n\n  cloud_group.add_argument(\n      '--num-workers',\n      metavar='N',\n      type=int,\n      default=0,\n      help='Set to 0 to use the default size determined by the Dataflow service.')\n\n  cloud_group.add_argument(\n      '--worker-machine-type',\n      metavar='NAME',\n      type=str,\n      help='A machine name from https://cloud.google.com/compute/docs/machine-types. '\n           ' If not given, the service uses the default machine type.')\n\n  cloud_group.add_argument(\n      '--async',\n      action='store_true',\n      help='If used, this script returns before the dataflow job is completed.')\n\n  args = parser.parse_args(args=argv[1:])\n\n  if args.cloud and not args.project_id:\n    raise ValueError('--project-id is needed for --cloud')\n\n  if args.async and not args.cloud:\n    raise ValueError('--async should only be used with --cloud')\n\n  if not args.job_name:\n    args.job_name = ('dataflow-job-{}'.format(\n        datetime.datetime.now().strftime('%Y%m%d%H%M%S')))\n  return args\n\n\n@beam.ptransform_fn\ndef shuffle(pcoll):  # pylint: disable=invalid-name\n  import random\n  return (pcoll\n          | 'PairWithRandom' >> beam.Map(lambda x: (random.random(), x))\n          | 'GroupByRandom' >> beam.GroupByKey()\n          | 'DropRandom' >> beam.FlatMap(lambda (k, vs): vs))\n\n\ndef image_transform_columns(features):\n  \"\"\"Returns a list of columns that prepare_image_transforms() should run on.\n\n  Because of beam + pickle, IMAGE_URL_TO_VEC_TRANSFORM cannot be used inside of\n  a beam function, so we extract the columns prepare_image_transforms() should \n  run on outside of beam.\n  \"\"\"\n  import six\n  from trainer import feature_transforms\n\n  img_cols = []\n  for name, transform in six.iteritems(features):\n    if transform['transform'] == feature_transforms.IMAGE_TRANSFORM:\n      img_cols.append(name)\n\n  return img_cols\n\n\ndef prepare_image_transforms(element, image_columns):\n  \"\"\"Replace an images url with its jpeg bytes.\n\n  Args: \n    element: one input row, as a dict\n    image_columns: list of columns that are image paths\n\n  Return:\n    element, where each image file path has been replaced by a base64 image.\n  \"\"\"\n  import base64\n  import cStringIO\n  from PIL import Image\n  from tensorflow.python.lib.io import file_io as tf_file_io\n  from apache_beam.metrics import Metrics\n\n  img_error_count = Metrics.counter('main', 'ImgErrorCount')\n  img_missing_count = Metrics.counter('main', 'ImgMissingCount')\n\n  for name in image_columns:\n    uri = element[name]\n    if not uri:\n      img_missing_count.inc()\n      continue\n    try:\n      with tf_file_io.FileIO(uri, 'r') as f:\n        img = Image.open(f).convert('RGB')\n\n    # A variety of different calling libraries throw different exceptions here.\n    # They all correspond to an unreadable file so we treat them equivalently.\n    # pylint: disable broad-except\n    except Exception as e:\n      logging.exception('Error processing image %s: %s', uri, str(e))\n      img_error_count.inc()\n      return\n\n    # Convert to desired format and output.\n    output = cStringIO.StringIO()\n    img.save(output, 'jpeg')\n    element[name] = base64.urlsafe_b64encode(output.getvalue())\n\n  return element\n\n\nclass EmitAsBatchDoFn(beam.DoFn):\n  \"\"\"A DoFn that buffers the records and emits them batch by batch.\"\"\"\n\n  def __init__(self, batch_size):\n    \"\"\"Constructor of EmitAsBatchDoFn beam.DoFn class.\n\n    Args:\n      batch_size: the max size we want to buffer the records before emitting.\n    \"\"\"\n    self._batch_size = batch_size\n    self._cached = []\n\n  def process(self, element):\n    self._cached.append(element)\n    if len(self._cached) >= self._batch_size:\n      emit = self._cached\n      self._cached = []\n      yield emit\n\n  def finish_bundle(self, element=None):\n    from apache_beam.transforms import window\n    from apache_beam.utils.windowed_value import WindowedValue\n\n    if len(self._cached) > 0:  # pylint: disable=g-explicit-length-test\n      yield WindowedValue(self._cached, -1, [window.GlobalWindow()])\n\n\nclass TransformFeaturesDoFn(beam.DoFn):\n  \"\"\"Converts raw data into transformed data.\"\"\"\n\n  def __init__(self, analysis_output_dir, features, schema, stats):\n    self._analysis_output_dir = analysis_output_dir\n    self._features = features\n    self._schema = schema\n    self._stats = stats\n    self._session = None\n\n  def start_bundle(self, element=None):\n    \"\"\"Build the transfromation graph once.\"\"\"\n    import tensorflow as tf\n    from trainer import feature_transforms\n\n    g = tf.Graph()\n    session = tf.Session(graph=g)\n\n    # Build the transformation graph\n    with g.as_default():\n      transformed_features, _, placeholders = (\n          feature_transforms.build_csv_serving_tensors_for_transform_step(\n              analysis_path=self._analysis_output_dir, \n              features=self._features, \n              schema=self._schema,\n              stats=self._stats,\n              keep_target=True))\n      session.run(tf.tables_initializer())\n    \n    self._session = session\n    self._transformed_features = transformed_features\n    self._input_placeholder_tensor = placeholders['csv_example']\n\n  def finish_bundle(self, element=None):\n    self._session.close()\n\n  def process(self, element):\n    \"\"\"Run the transformation graph on batched input data\n\n    Args:\n      element: list of csv strings, representing one batch input to the TF graph.\n\n    Returns:\n      dict containing the transformed data. Results are un-batched. Sparse\n      tensors are converted to lists.\n    \"\"\"\n    import apache_beam as beam\n    import six\n    import tensorflow as tf\n\n    # This function is invoked by a separate sub-process so setting the logging level\n    # does not affect Datalab's kernel process.\n    tf.logging.set_verbosity(tf.logging.ERROR)\n    try:\n      clean_element = []\n      for line in element:\n        clean_element.append(line.rstrip())\n\n      # batch_result is list of numpy arrays with batch_size many rows.\n      batch_result = self._session.run(\n          fetches=self._transformed_features,\n          feed_dict={self._input_placeholder_tensor: clean_element})\n\n      # ex batch_result. \n      # Dense tensor: {'col1': array([[batch_1], [batch_2]])}\n      # Sparse tensor: {'col1': tf.SparseTensorValue(\n      #   indices=array([[batch_1, 0], [batch_1, 1], ...,\n      #                  [batch_2, 0], [batch_2, 1], ...]],\n      #   values=array[value, value, value, ...])}\n\n      # Unbatch the results.\n      for i in range(len(clean_element)):\n        transformed_features = {}\n        for name, value in six.iteritems(batch_result):\n          if isinstance(value, tf.SparseTensorValue):\n            batch_i_indices = value.indices[:, 0] == i\n            batch_i_values = value.values[batch_i_indices]\n            transformed_features[name] = batch_i_values.tolist()\n          else:\n            transformed_features[name] = value[i].tolist()\n\n        yield transformed_features\n\n    except Exception as e:  # pylint: disable=broad-except\n      yield beam.pvalue.TaggedOutput('errors', (str(e), element))\n\n\ndef decode_csv(csv_string, column_names):\n  \"\"\"Parse a csv line into a dict.\n\n  Args:\n    csv_string: a csv string. May contain missing values \"a,,c\"\n    column_names: list of column names\n\n  Returns:\n    Dict of {column_name, value_from_csv}. If there are missing values, \n    value_from_csv will be ''.\n  \"\"\"\n  import csv\n  r = next(csv.reader([csv_string]))\n  if len(r) != len(column_names):\n    raise ValueError('csv line %s does not have %d columns' % (csv_string, len(column_names)))\n  return {k: v for k, v in zip(column_names, r)}\n\n\ndef encode_csv(data_dict, column_names):\n  \"\"\"Builds a csv string.\n\n  Args:\n    data_dict: dict of {column_name: 1 value}\n    column_names: list of column names\n\n  Returns:\n    A csv string version of data_dict\n  \"\"\"\n  import csv\n  import six\n  values = [str(data_dict[x]) for x in column_names]\n  str_buff = six.StringIO()\n  writer = csv.writer(str_buff, lineterminator='')\n  writer.writerow(values)\n  return str_buff.getvalue()\n  \n\ndef serialize_example(transformed_json_data, features, feature_indices, target_name):\n  \"\"\"Makes an instance of data in libsvm format.\n\n  Args:\n    transformed_json_data: dict of transformed data.\n    features: features config.\n    feature_indices: output of feature_transforms.get_transformed_feature_indices()\n\n  Returns:\n    The text line representation of an instance in libsvm format.\n  \"\"\"\n  import six\n  import tensorflow as tf\n  from trainer import feature_transforms\n\n  line = str(transformed_json_data[target_name][0])\n  for name, info in feature_indices:\n    if features[name]['transform'] in [feature_transforms.IDENTITY_TRANSFORM,\n                                       feature_transforms.SCALE_TRANSFORM]:\n      line += ' %d:%s' % (info['index_start'], str(transformed_json_data[name][0]))\n    elif features[name]['transform'] in [feature_transforms.ONE_HOT_TRANSFORM,\n                                         feature_transforms.MULTI_HOT_TRANSFORM]:\n      for i in range(info['size']):\n        if i in transformed_json_data[name]:\n          line += ' %d:1' % (info['index_start'] + i)\n    elif features[name]['transform'] in [feature_transforms.IMAGE_TRANSFORM]:\n      for i in range(info['size']):\n        line += ' %d:%s' % (info['index_start'] + i, str(transformed_json_data[name][i]))\n\n  return line\n\n\ndef preprocess(pipeline, args):\n  \"\"\"Transfrom csv data into transfromed tf.example files.\n\n  Outline:\n    1) read the input data (as csv or bigquery) into a dict format\n    2) replace image paths with base64 encoded image files\n    3) build a csv input string with images paths replaced with base64. This \n       matches the serving csv that a trained model would expect.\n    4) batch the csv strings\n    5) run the transformations\n    6) write the results to tf.example files and save any errors.\n  \"\"\"\n  import six\n  from tensorflow.python.lib.io import file_io\n  from trainer import feature_transforms\n\n  schema = json.loads(file_io.read_file_to_string(\n      os.path.join(args.analysis, feature_transforms.SCHEMA_FILE)).decode())\n  features = json.loads(file_io.read_file_to_string(\n      os.path.join(args.analysis, feature_transforms.FEATURES_FILE)).decode())\n  stats = json.loads(file_io.read_file_to_string(\n      os.path.join(args.analysis, feature_transforms.STATS_FILE)).decode())\n\n  column_names = [col['name'] for col in schema]\n\n  if args.csv:\n    all_files = []\n    for i, file_pattern in enumerate(args.csv):\n      all_files.append(pipeline | ('ReadCSVFile%d' % i) >> beam.io.ReadFromText(file_pattern))\n    raw_data = (\n        all_files\n        | 'MergeCSVFiles' >> beam.Flatten()\n        | 'ParseCSVData' >> beam.Map(decode_csv, column_names))\n  else:\n    columns = ', '.join(column_names)\n    query = 'SELECT {columns} FROM `{table}`'.format(columns=columns,\n                                                     table=args.bigquery)\n    raw_data = (\n        pipeline\n        | 'ReadBiqQueryData'\n        >> beam.io.Read(beam.io.BigQuerySource(query=query,\n                                               use_standard_sql=True)))\n\n  # Note that prepare_image_transforms does not make embeddings, it justs reads\n  # the image files and converts them to byte stings. TransformFeaturesDoFn()\n  # will make the image embeddings.\n  image_columns = image_transform_columns(features)\n  \n  clean_csv_data = (\n      raw_data\n      | 'PreprocessTransferredLearningTransformations'\n      >> beam.Map(prepare_image_transforms, image_columns)\n      | 'BuildCSVString'\n      >> beam.Map(encode_csv, column_names))\n\n  if args.shuffle:\n    clean_csv_data = clean_csv_data | 'ShuffleData' >> shuffle()\n\n  transform_dofn = TransformFeaturesDoFn(args.analysis, features, schema, stats)\n  (transformed_data, errors) = (\n       clean_csv_data\n       | 'Batch Input' \n       >> beam.ParDo(EmitAsBatchDoFn(args.batch_size)) \n       | 'Run TF Graph on Batches' \n       >> beam.ParDo(transform_dofn).with_outputs('errors', main='main'))\n\n  target_name = next((name for name, transform in six.iteritems(features)\n                      if transform['transform'] == feature_transforms.TARGET_TRANSFORM),\n                     None)\n  feature_indices = feature_transforms.get_transformed_feature_indices(features, stats)\n  _ = (transformed_data\n        | 'SerializeExamples' >> beam.Map(serialize_example, features,\n                                          feature_indices, target_name)\n        | 'WriteExamples' >> beam.io.WriteToText(\n            os.path.join(args.output, args.prefix),\n            file_name_suffix='.libsvm',\n            num_shards=1))\n\n  feature_map = feature_transforms.create_feature_map(features, feature_indices, args.analysis)\n  # Create the whole file content as one string to avoid dataflow reordering the entries.\n  feature_map_content = ['\\n'.join(['%d,%s' % x for x in feature_map])]\n  _ = (pipeline\n         | beam.Create(feature_map_content)\n         | 'WriteFeatureMap'\n         >> beam.io.WriteToText(\n             os.path.join(args.output, 'featuremap'),\n             file_name_suffix='.txt',\n             num_shards=1))\n\n\ndef main(argv=None):\n  \"\"\"Run Preprocessing as a Dataflow.\"\"\"\n  args = parse_arguments(sys.argv if argv is None else argv)\n  temp_dir = os.path.join(args.output, 'tmp')\n\n  if args.cloud:\n    pipeline_name = 'DataflowRunner'\n  else:\n    pipeline_name = 'DirectRunner'\n    # Suppress TF warnings.\n    os.environ['TF_CPP_MIN_LOG_LEVEL']='3'\n\n  options = {\n      'job_name': args.job_name,\n      'temp_location': temp_dir,\n      'project': args.project_id,\n      'setup_file':\n          os.path.abspath(os.path.join(\n              os.path.dirname(__file__),\n              'setup.py')),\n  }\n  if args.num_workers:\n    options['num_workers'] = args.num_workers\n  if args.worker_machine_type:\n    options['worker_machine_type'] = args.worker_machine_type\n\n  pipeline_options = beam.pipeline.PipelineOptions(flags=[], **options)\n\n  p = beam.Pipeline(pipeline_name, options=pipeline_options)\n  preprocess(pipeline=p, args=args)\n  pipeline_result = p.run()\n\n  if not args.async:\n    pipeline_result.wait_until_finish()\n  if args.async and args.cloud:\n    print('View job at https://console.developers.google.com/dataflow/job/%s?project=%s' %\n        (pipeline_result.job_id(), args.project_id))\n\n\nif __name__ == '__main__':\n  main()\n"
  },
  {
    "path": "solutionbox/structured_data/build.sh",
    "content": "#! /bin/bash\n\nrm -fr dist \ncp setup.py  mltoolbox/_structured_data/master_setup.py\npython setup.py sdist\n\n\n"
  },
  {
    "path": "solutionbox/structured_data/mltoolbox/__init__.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n__import__('pkg_resources').declare_namespace(__name__)\n"
  },
  {
    "path": "solutionbox/structured_data/mltoolbox/_structured_data/__init__.py",
    "content": "# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom ._package import analyze, analyze_async, train_async, predict, batch_predict, \\\n    batch_predict_async\n\n__all__ = ['analyze', 'analyze_async', 'train_async', 'predict', 'batch_predict',\n           'batch_predict_async']\n"
  },
  {
    "path": "solutionbox/structured_data/mltoolbox/_structured_data/__version__.py",
    "content": "# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n# Source of truth for the version of this package.\n__version__ = '1.0.1'\n"
  },
  {
    "path": "solutionbox/structured_data/mltoolbox/_structured_data/_package.py",
    "content": "# Copyright 2017 Google Inc. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\n\"\"\"Provides interface for Datalab.\n\n  Datalab will look for functions with the below names:\n     local_preprocess\n     local_train\n     local_predict\n     cloud_preprocess\n     cloud_train\n     cloud_predict\n\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport datetime\nimport io\nimport os\nimport shutil\nimport sys\nimport tempfile\nimport json\nimport glob\nimport six\nimport subprocess\nimport pandas as pd\nfrom tensorflow.python.lib.io import file_io\nimport warnings\n\n# Note that subpackages of _structured_data are locally imported.\n# This is because this part of the mltoolbox is packaged up during training\n# and batch prediction. This package depends on datafow, but the trainer\n# workers should not need it; therefore at training time, a package cannot\n# import apache_beam.\n\n# Likewise, datalab packages are locally imported. This is because TF and\n# dataflow workers should not need it.\n\n\n_TF_GS_URL = 'gs://cloud-datalab/deploy/tf/tensorflow-1.2.0-cp27-none-linux_x86_64.whl'\n_PROTOBUF_GS_URL = 'gs://cloud-datalab/deploy/tf/protobuf-3.1.0-py2.py3-none-any.whl'\n\n\nclass FileNotFoundError(IOError):\n    pass\n\n\ndef _default_project():\n  from google.datalab import Context\n  return Context.default().project_id\n\n\ndef _assert_gcs_files(files):\n  \"\"\"Check files starts wtih gs://.\n\n  Args:\n    files: string to file path, or list of file paths.\n  \"\"\"\n\n  if sys.version_info.major > 2:\n    string_type = (str, bytes)  # for python 3 compatibility\n  else:\n    string_type = basestring  # noqa\n\n  if isinstance(files, string_type):\n    files = [files]\n\n  for f in files:\n    if f is not None and not f.startswith('gs://'):\n      raise ValueError('File %s is not a gcs path' % f)\n\n\ndef _package_to_staging(staging_package_url):\n    \"\"\"Repackage this package from local installed location and copy it to GCS.\n\n    Args:\n      staging_package_url: GCS path.\n    \"\"\"\n    import google.datalab.ml as ml\n\n    # Find the package root. __file__ is under [package_root]/mltoolbox/_structured_data/this_file\n    package_root = os.path.abspath(\n        os.path.join(os.path.dirname(__file__), '../../'))\n    setup_path = os.path.abspath(\n        os.path.join(os.path.dirname(__file__), 'master_setup.py'))\n    tar_gz_path = os.path.join(staging_package_url, 'staging', 'trainer.tar.gz')\n\n    print('Building package and uploading to %s' % tar_gz_path)\n    ml.package_and_copy(package_root, setup_path, tar_gz_path)\n\n    return tar_gz_path\n\n\ndef _wait_and_kill(pid_to_wait, pids_to_kill):\n  \"\"\" Helper function.\n\n      Wait for a process to finish if it exists, and then try to kill a list of\n      processes.\n\n      Used by local_train\n\n  Args:\n    pid_to_wait: the process to wait for.\n    pids_to_kill: a list of processes to kill after the process of pid_to_wait finishes.\n  \"\"\"\n  # cloud workers don't have psutil\n  import psutil\n  if psutil.pid_exists(pid_to_wait):\n    psutil.Process(pid=pid_to_wait).wait()\n\n  for pid_to_kill in pids_to_kill:\n    if psutil.pid_exists(pid_to_kill):\n      p = psutil.Process(pid=pid_to_kill)\n      p.kill()\n      p.wait()\n\n\n# ==============================================================================\n# Analyze\n# ==============================================================================\n\ndef analyze(output_dir, dataset, cloud=False, project_id=None):\n  \"\"\"Blocking version of analyze_async. See documentation of analyze_async.\"\"\"\n  job = analyze_async(\n      output_dir=output_dir,\n      dataset=dataset,\n      cloud=cloud,\n      project_id=project_id)\n  job.wait()\n  print('Analyze: ' + str(job.state))\n\n\ndef analyze_async(output_dir, dataset, cloud=False, project_id=None):\n  \"\"\"Analyze data locally or in the cloud with BigQuery.\n\n  Produce analysis used by training. This can take a while, even for small\n  datasets. For small datasets, it may be faster to use local_analysis.\n\n  Args:\n    output_dir: The output directory to use.\n    dataset: only CsvDataSet is supported currently.\n    cloud: If False, runs analysis locally with Pandas. If Ture, runs analysis\n        in the cloud with BigQuery.\n    project_id: Uses BigQuery with this project id. Default is datalab's\n        default project id.\n\n  Returns:\n    A google.datalab.utils.Job object that can be used to query state from or wait.\n  \"\"\"\n  import google.datalab.utils as du\n  with warnings.catch_warnings():\n    warnings.simplefilter(\"ignore\")\n    fn = lambda: _analyze(output_dir, dataset, cloud, project_id)  # noqa\n    return du.LambdaJob(fn, job_id=None)\n\n\ndef _analyze(output_dir, dataset, cloud=False, project_id=None):\n  import google.datalab.ml as ml\n  from . import preprocess\n\n  if not isinstance(dataset, ml.CsvDataSet):\n    raise ValueError('Only CsvDataSet is supported')\n\n  if len(dataset.input_files) != 1:\n    raise ValueError('CsvDataSet should be built with a file pattern, not a '\n                     'list of files.')\n\n  if project_id and not cloud:\n    raise ValueError('project_id only needed if cloud is True')\n\n  if cloud:\n    _assert_gcs_files([output_dir, dataset.input_files[0]])\n\n  tmp_dir = tempfile.mkdtemp()\n  try:\n    # write the schema file.\n    _, schema_file_path = tempfile.mkstemp(dir=tmp_dir, suffix='.json',\n                                           prefix='schema')\n    file_io.write_string_to_file(schema_file_path, json.dumps(dataset.schema))\n\n    # TODO(brandondutra) use project_id in the local preprocess function.\n    args = ['preprocess',\n            '--input-file-pattern=%s' % dataset.input_files[0],\n            '--output-dir=%s' % output_dir,\n            '--schema-file=%s' % schema_file_path]\n\n    if cloud:\n      if not project_id:\n        project_id = _default_project()\n      print('Track BigQuery status at')\n      print('https://bigquery.cloud.google.com/queries/%s' % project_id)\n      preprocess.cloud_preprocess.main(args)\n    else:\n      preprocess.local_preprocess.main(args)\n  finally:\n    shutil.rmtree(tmp_dir)\n\n\n# ==============================================================================\n# Train\n# ==============================================================================\ndef train_async(train_dataset,\n                eval_dataset,\n                analysis_dir,\n                output_dir,\n                features,\n                model_type,\n                max_steps=5000,\n                num_epochs=None,\n                train_batch_size=100,\n                eval_batch_size=16,\n                min_eval_frequency=100,\n                top_n=None,\n                layer_sizes=None,\n                learning_rate=0.01,\n                epsilon=0.0005,\n                job_name=None,  # cloud param\n                job_name_prefix='',  # cloud param\n                cloud=None,  # cloud param\n                ):\n  # NOTE: if you make a chane go this doc string, you MUST COPY it 4 TIMES in\n  # mltoolbox.{classification|regression}.{dnn|linear}, but you must remove\n  # the model_type parameter, and maybe change the layer_sizes and top_n\n  # parameters!\n  # Datalab does some tricky things and messing with train.__doc__ will\n  # not work!\n  \"\"\"Train model locally or in the cloud.\n\n  Local Training:\n\n  Args:\n    train_dataset: CsvDataSet\n    eval_dataset: CsvDataSet\n    analysis_dir:  The output directory from local_analysis\n    output_dir:  Output directory of training.\n    features: file path or features object. Example:\n        {\n          \"col_A\": {\"transform\": \"scale\", \"default\": 0.0},\n          \"col_B\": {\"transform\": \"scale\",\"value\": 4},\n          # Note col_C is missing, so default transform used.\n          \"col_D\": {\"transform\": \"hash_one_hot\", \"hash_bucket_size\": 4},\n          \"col_target\": {\"transform\": \"target\"},\n          \"col_key\": {\"transform\": \"key\"}\n        }\n        The keys correspond to the columns in the input files as defined by the\n        schema file during preprocessing. Some notes\n        1) The \"key\" and \"target\" transforms are required.\n        2) Default values are optional. These are used if the input data has\n           missing values during training and prediction. If not supplied for a\n           column, the default value for a numerical column is that column's\n           mean vlaue, and for a categorical column the empty string is used.\n        3) For numerical colums, the following transforms are supported:\n           i) {\"transform\": \"identity\"}: does nothing to the number. (default)\n           ii) {\"transform\": \"scale\"}: scales the colum values to -1, 1.\n           iii) {\"transform\": \"scale\", \"value\": a}: scales the colum values\n              to -a, a.\n\n           For categorical colums, the following transforms are supported:\n          i) {\"transform\": \"one_hot\"}: A one-hot vector using the full\n              vocabulary is used. (default)\n          ii) {\"transform\": \"embedding\", \"embedding_dim\": d}: Each label is\n              embedded into an d-dimensional space.\n    model_type: One of 'linear_classification', 'linear_regression',\n        'dnn_classification', 'dnn_regression'.\n    max_steps: Int. Number of training steps to perform.\n    num_epochs: Maximum number of training data epochs on which to train.\n        The training job will run for max_steps or num_epochs, whichever occurs\n        first.\n    train_batch_size: number of rows to train on in one step.\n    eval_batch_size: number of rows to eval in one step. One pass of the eval\n        dataset is done. If eval_batch_size does not perfectly divide the numer\n        of eval instances, the last fractional batch is not used.\n    min_eval_frequency: Minimum number of training steps between evaluations.\n    top_n: Int. For classification problems, the output graph will contain the\n        labels and scores for the top n classes with a default of n=1. Use\n        None for regression problems.\n    layer_sizes: List. Represents the layers in the connected DNN.\n        If the model type is DNN, this must be set. Example [10, 3, 2], this\n        will create three DNN layers where the first layer will have 10 nodes,\n        the middle layer will have 3 nodes, and the laster layer will have 2\n        nodes.\n    learning_rate: tf.train.AdamOptimizer's learning rate,\n    epsilon: tf.train.AdamOptimizer's epsilon value.\n\n  Cloud Training:\n\n  Args:\n    All local training arguments are valid for cloud training. Cloud training\n    contains two additional args:\n\n    cloud: A CloudTrainingConfig object.\n    job_name: Training job name. A default will be picked if None.\n    job_name_prefix: If job_name is None, the job will be named\n        '<job_name_prefix>_<timestamp>'.\n\n  Returns:\n    A google.datalab.utils.Job object that can be used to query state from or wait.\n  \"\"\"\n  import google.datalab.utils as du\n\n  if model_type not in ['linear_classification', 'linear_regression', 'dnn_classification',\n                        'dnn_regression']:\n    raise ValueError('Unknown model_type %s' % model_type)\n\n  with warnings.catch_warnings():\n    warnings.simplefilter(\"ignore\")\n    if cloud:\n      return cloud_train(\n          train_dataset=train_dataset,\n          eval_dataset=eval_dataset,\n          analysis_dir=analysis_dir,\n          output_dir=output_dir,\n          features=features,\n          model_type=model_type,\n          max_steps=max_steps,\n          num_epochs=num_epochs,\n          train_batch_size=train_batch_size,\n          eval_batch_size=eval_batch_size,\n          min_eval_frequency=min_eval_frequency,\n          top_n=top_n,\n          layer_sizes=layer_sizes,\n          learning_rate=learning_rate,\n          epsilon=epsilon,\n          job_name=job_name,\n          job_name_prefix=job_name_prefix,\n          config=cloud,\n      )\n    else:\n      def fn():\n        return local_train(\n            train_dataset=train_dataset,\n            eval_dataset=eval_dataset,\n            analysis_dir=analysis_dir,\n            output_dir=output_dir,\n            features=features,\n            model_type=model_type,\n            max_steps=max_steps,\n            num_epochs=num_epochs,\n            train_batch_size=train_batch_size,\n            eval_batch_size=eval_batch_size,\n            min_eval_frequency=min_eval_frequency,\n            top_n=top_n,\n            layer_sizes=layer_sizes,\n            learning_rate=learning_rate,\n            epsilon=epsilon)\n      return du.LambdaJob(fn, job_id=None)\n\n\ndef local_train(train_dataset,\n                eval_dataset,\n                analysis_dir,\n                output_dir,\n                features,\n                model_type,\n                max_steps,\n                num_epochs,\n                train_batch_size,\n                eval_batch_size,\n                min_eval_frequency,\n                top_n,\n                layer_sizes,\n                learning_rate,\n                epsilon):\n  if len(train_dataset.input_files) != 1 or len(eval_dataset.input_files) != 1:\n    raise ValueError('CsvDataSets must be built with a file pattern, not list '\n                     'of files.')\n\n  if file_io.file_exists(output_dir):\n    raise ValueError('output_dir already exist. Use a new output path.')\n\n  if eval_dataset.size < eval_batch_size:\n    raise ValueError('Eval batch size must be smaller than the eval data size.')\n\n  if isinstance(features, dict):\n    # Make a features file.\n    if not file_io.file_exists(output_dir):\n      file_io.recursive_create_dir(output_dir)\n    features_file = os.path.join(output_dir, 'features_file.json')\n    file_io.write_string_to_file(\n        features_file,\n        json.dumps(features))\n  else:\n    features_file = features\n\n  def _get_abs_path(input_path):\n    cur_path = os.getcwd()\n    full_path = os.path.abspath(os.path.join(cur_path, input_path))\n    # put path in quotes as it could contain spaces.\n    return \"'\" + full_path + \"'\"\n\n  args = ['cd %s &&' % os.path.abspath(os.path.dirname(__file__)),\n          'python -m trainer.task',\n          '--train-data-paths=%s' % _get_abs_path(train_dataset.input_files[0]),\n          '--eval-data-paths=%s' % _get_abs_path(eval_dataset.input_files[0]),\n          '--job-dir=%s' % _get_abs_path(output_dir),\n          '--preprocess-output-dir=%s' % _get_abs_path(analysis_dir),\n          '--transforms-file=%s' % _get_abs_path(features_file),\n          '--model-type=%s' % model_type,\n          '--max-steps=%s' % str(max_steps),\n          '--train-batch-size=%s' % str(train_batch_size),\n          '--eval-batch-size=%s' % str(eval_batch_size),\n          '--min-eval-frequency=%s' % str(min_eval_frequency),\n          '--learning-rate=%s' % str(learning_rate),\n          '--epsilon=%s' % str(epsilon)]\n  if num_epochs:\n    args.append('--num-epochs=%s' % str(num_epochs))\n  if top_n:\n    args.append('--top-n=%s' % str(top_n))\n  if layer_sizes:\n    for i in range(len(layer_sizes)):\n      args.append('--layer-size%s=%s' % (i + 1, str(layer_sizes[i])))\n\n  monitor_process = None\n  try:\n    p = subprocess.Popen(' '.join(args),\n                         shell=True,\n                         stdout=subprocess.PIPE,\n                         stderr=subprocess.STDOUT)\n    pids_to_kill = [p.pid]\n\n    # script -> name = datalab_structured_data._package\n    script = 'import %s; %s._wait_and_kill(%s, %s)' % (__name__, __name__, str(os.getpid()),\n                                                       str(pids_to_kill))\n    monitor_process = subprocess.Popen(['python', '-c', script])\n\n    while p.poll() is None:\n      line = p.stdout.readline()\n\n      if not six.PY2:\n        line = line.decode()\n\n      if (line.startswith('INFO:tensorflow:global') or line.startswith('INFO:tensorflow:loss') or\n              line.startswith('INFO:tensorflow:Saving dict')):\n\n        sys.stdout.write(line)\n  finally:\n    if monitor_process:\n      monitor_process.kill()\n      monitor_process.wait()\n\n\ndef cloud_train(train_dataset,\n                eval_dataset,\n                analysis_dir,\n                output_dir,\n                features,\n                model_type,\n                max_steps,\n                num_epochs,\n                train_batch_size,\n                eval_batch_size,\n                min_eval_frequency,\n                top_n,\n                layer_sizes,\n                learning_rate,\n                epsilon,\n                job_name,\n                job_name_prefix,\n                config):\n  \"\"\"Train model using CloudML.\n\n  See local_train() for a description of the args.\n  Args:\n    config: A CloudTrainingConfig object.\n    job_name: Training job name. A default will be picked if None.\n  \"\"\"\n  import google.datalab.ml as ml\n\n  if len(train_dataset.input_files) != 1 or len(eval_dataset.input_files) != 1:\n    raise ValueError('CsvDataSets must be built with a file pattern, not list '\n                     'of files.')\n\n  if file_io.file_exists(output_dir):\n    raise ValueError('output_dir already exist. Use a new output path.')\n\n  if isinstance(features, dict):\n    # Make a features file.\n    if not file_io.file_exists(output_dir):\n      file_io.recursive_create_dir(output_dir)\n    features_file = os.path.join(output_dir, 'features_file.json')\n    file_io.write_string_to_file(\n        features_file,\n        json.dumps(features))\n  else:\n    features_file = features\n\n  if not isinstance(config, ml.CloudTrainingConfig):\n    raise ValueError('cloud should be an instance of '\n                     'google.datalab.ml.CloudTrainingConfig for cloud training.')\n\n  _assert_gcs_files([output_dir, train_dataset.input_files[0], eval_dataset.input_files[0],\n                     features_file, analysis_dir])\n\n  args = ['--train-data-paths=%s' % train_dataset.input_files[0],\n          '--eval-data-paths=%s' % eval_dataset.input_files[0],\n          '--preprocess-output-dir=%s' % analysis_dir,\n          '--transforms-file=%s' % features_file,\n          '--model-type=%s' % model_type,\n          '--max-steps=%s' % str(max_steps),\n          '--train-batch-size=%s' % str(train_batch_size),\n          '--eval-batch-size=%s' % str(eval_batch_size),\n          '--min-eval-frequency=%s' % str(min_eval_frequency),\n          '--learning-rate=%s' % str(learning_rate),\n          '--epsilon=%s' % str(epsilon)]\n  if num_epochs:\n    args.append('--num-epochs=%s' % str(num_epochs))\n  if top_n:\n    args.append('--top-n=%s' % str(top_n))\n  if layer_sizes:\n    for i in range(len(layer_sizes)):\n      args.append('--layer-size%s=%s' % (i + 1, str(layer_sizes[i])))\n\n  job_request = {\n    'package_uris': [_package_to_staging(output_dir), _TF_GS_URL, _PROTOBUF_GS_URL],\n    'python_module': 'mltoolbox._structured_data.trainer.task',\n    'job_dir': output_dir,\n    'args': args\n  }\n  job_request.update(dict(config._asdict()))\n\n  if not job_name:\n    job_name = job_name_prefix or 'structured_data_train'\n    job_name += '_' + datetime.datetime.now().strftime('%y%m%d_%H%M%S')\n  job = ml.Job.submit_training(job_request, job_name)\n  print('Job request send. View status of job at')\n  print('https://console.developers.google.com/ml/jobs?project=%s' %\n        _default_project())\n\n  return job\n\n# ==============================================================================\n# Predict\n# ==============================================================================\n\n\ndef predict(data, training_dir=None, model_name=None, model_version=None, cloud=False):\n  \"\"\"Runs prediction locally or on the cloud.\n\n  Args:\n    data: List of csv strings or a Pandas DataFrame that match the model schema.\n    training_dir: local path to the trained output folder.\n    model_name: deployed model name\n    model_version: depoyed model version\n    cloud: bool. If False, does local prediction and data and training_dir\n        must be set. If True, does cloud prediction and data, model_name,\n        and model_version must be set.\n\n\n  For cloud prediction, the model must be created. This can be done by running\n  two gcloud commands::\n    1) gcloud beta ml models create NAME\n    2) gcloud beta ml versions create VERSION --model NAME --origin gs://BUCKET/training_dir/model\n  or these datalab commands:\n    1) import google.datalab as datalab\n      model = datalab.ml.ModelVersions(MODEL_NAME)\n      model.deploy(version_name=VERSION, path='gs://BUCKET/training_dir/model')\n  Note that the model must be on GCS.\n\n  Returns:\n    Pandas DataFrame.\n  \"\"\"\n  if cloud:\n    if not model_version or not model_name:\n      raise ValueError('model_version or model_name is not set')\n    if training_dir:\n      raise ValueError('training_dir not needed when cloud is True')\n    with warnings.catch_warnings():\n      warnings.simplefilter(\"ignore\")\n      return cloud_predict(model_name, model_version, data)\n  else:\n    if not training_dir:\n      raise ValueError('training_dir is not set')\n    if model_version or model_name:\n      raise ValueError('model_name and model_version not needed when cloud is '\n                       'False.')\n    with warnings.catch_warnings():\n      warnings.simplefilter(\"ignore\")\n      return local_predict(training_dir, data)\n\n\ndef local_predict(training_dir, data):\n  \"\"\"Runs local prediction on the prediction graph.\n\n  Runs local prediction and returns the result in a Pandas DataFrame. For\n  running prediction on a large dataset or saving the results, run\n  local_batch_prediction or batch_prediction. Input data should fully match\n  the schema that was used at training, except the target column should not\n  exist.\n\n  Args:\n    training_dir: local path to the trained output folder.\n    data: List of csv strings or a Pandas DataFrame that match the model schema.\n\n  Raises:\n    ValueError: if training_dir does not contain the folder 'model'.\n    FileNotFoundError: if the prediction data is not found.\n\n  \"\"\"\n  # from . import predict as predict_module\n  from .prediction import predict as predict_module\n\n  # Save the instances to a file, call local batch prediction, and return it\n  tmp_dir = tempfile.mkdtemp()\n  _, input_file_path = tempfile.mkstemp(dir=tmp_dir, suffix='.csv',\n                                        prefix='input')\n\n  try:\n    if isinstance(data, pd.DataFrame):\n      data.to_csv(input_file_path, header=False, index=False)\n    else:\n      with open(input_file_path, 'w') as f:\n        for line in data:\n          f.write(line + '\\n')\n\n    model_dir = os.path.join(training_dir, 'model')\n    if not file_io.file_exists(model_dir):\n      raise ValueError('training_dir should contain the folder model')\n\n    cmd = ['predict.py',\n           '--predict-data=%s' % input_file_path,\n           '--trained-model-dir=%s' % model_dir,\n           '--output-dir=%s' % tmp_dir,\n           '--output-format=csv',\n           '--batch-size=16',\n           '--mode=prediction',\n           '--no-shard-files']\n\n    # runner_results = predict_module.predict.main(cmd)\n    runner_results = predict_module.main(cmd)\n    runner_results.wait_until_finish()\n\n    # Read the header file.\n    schema_file = os.path.join(tmp_dir, 'csv_schema.json')\n    with open(schema_file, 'r') as f:\n      schema = json.loads(f.read())\n\n    # Print any errors to the screen.\n    errors_file = glob.glob(os.path.join(tmp_dir, 'errors*'))\n    if errors_file and os.path.getsize(errors_file[0]) > 0:\n      print('Warning: there are errors. See below:')\n      with open(errors_file[0], 'r') as f:\n        text = f.read()\n        print(text)\n\n    # Read the predictions data.\n    prediction_file = glob.glob(os.path.join(tmp_dir, 'predictions*'))\n    if not prediction_file:\n      raise FileNotFoundError('Prediction results not found')\n    predictions = pd.read_csv(prediction_file[0],\n                              header=None,\n                              names=[col['name'] for col in schema])\n    return predictions\n  finally:\n    shutil.rmtree(tmp_dir)\n\n\ndef cloud_predict(model_name, model_version, data):\n  \"\"\"Use Online prediction.\n\n  Runs online prediction in the cloud and prints the results to the screen. For\n  running prediction on a large dataset or saving the results, run\n  local_batch_prediction or batch_prediction.\n\n  Args:\n    model_name: deployed model name\n    model_version: depoyed model version\n    data: List of csv strings or a Pandas DataFrame that match the model schema.\n\n  Before using this, the model must be created. This can be done by running\n  two gcloud commands:\n  1) gcloud beta ml models create NAME\n  2) gcloud beta ml versions create VERSION --model NAME \\\n      --origin gs://BUCKET/training_dir/model\n  or these datalab commands:\n  1) import google.datalab as datalab\n     model = datalab.ml.ModelVersions(MODEL_NAME)\n     model.deploy(version_name=VERSION,\n                  path='gs://BUCKET/training_dir/model')\n  Note that the model must be on GCS.\n  \"\"\"\n  import google.datalab.ml as ml\n\n  if isinstance(data, pd.DataFrame):\n    # write the df to csv.\n    string_buffer = io.StringIO()\n    data.to_csv(string_buffer, header=None, index=False)\n    input_data = string_buffer.getvalue().split('\\n')\n\n    # remove empty strings\n    input_data = [line for line in input_data if line]\n  else:\n    input_data = data\n\n  predictions = ml.ModelVersions(model_name).predict(model_version, input_data)\n\n  # Convert predictions into a dataframe\n  df = pd.DataFrame(columns=sorted(predictions[0].keys()))\n  for i in range(len(predictions)):\n    for k, v in predictions[i].iteritems():\n      df.loc[i, k] = v\n  return df\n\n# ==============================================================================\n# Batch predict\n# ==============================================================================\n\n\ndef batch_predict(training_dir, prediction_input_file, output_dir,\n                  mode, batch_size=16, shard_files=True, output_format='csv',\n                  cloud=False):\n  \"\"\"Blocking versoin of batch_predict.\n\n  See documentation of batch_prediction_async.\n  \"\"\"\n  job = batch_predict_async(\n      training_dir=training_dir,\n      prediction_input_file=prediction_input_file,\n      output_dir=output_dir,\n      mode=mode,\n      batch_size=batch_size,\n      shard_files=shard_files,\n      output_format=output_format,\n      cloud=cloud)\n  job.wait()\n  print('Batch predict: ' + str(job.state))\n\n\ndef batch_predict_async(training_dir, prediction_input_file, output_dir,\n                        mode, batch_size=16, shard_files=True, output_format='csv', cloud=False):\n  \"\"\"Local and cloud batch prediction.\n\n  Args:\n    training_dir: The output folder of training.\n    prediction_input_file: csv file pattern to a file. File must be on GCS if\n        running cloud prediction\n    output_dir: output location to save the results. Must be a GSC path if\n        running cloud prediction.\n    mode: 'evaluation' or 'prediction'. If 'evaluation', the input data must\n        contain a target column. If 'prediction', the input data must not\n        contain a target column.\n    batch_size: Int. How many instances to run in memory at once. Larger values\n        mean better performace but more memeory consumed.\n    shard_files: If False, the output files are not shardded.\n    output_format: csv or json. Json file are json-newlined.\n    cloud: If ture, does cloud batch prediction. If False, runs batch prediction\n        locally.\n\n  Returns:\n    A google.datalab.utils.Job object that can be used to query state from or wait.\n  \"\"\"\n  import google.datalab.utils as du\n  with warnings.catch_warnings():\n    warnings.simplefilter(\"ignore\")\n    if cloud:\n      runner_results = cloud_batch_predict(training_dir, prediction_input_file, output_dir, mode,\n                                           batch_size, shard_files, output_format)\n      job = du.DataflowJob(runner_results)\n    else:\n      runner_results = local_batch_predict(training_dir, prediction_input_file, output_dir, mode,\n                                           batch_size, shard_files, output_format)\n      job = du.LambdaJob(lambda: runner_results.wait_until_finish(), job_id=None)\n\n  return job\n\n\ndef local_batch_predict(training_dir, prediction_input_file, output_dir, mode, batch_size,\n                        shard_files, output_format):\n  \"\"\"See batch_predict\"\"\"\n  # from . import predict as predict_module\n  from .prediction import predict as predict_module\n\n  if mode == 'evaluation':\n    model_dir = os.path.join(training_dir, 'evaluation_model')\n  elif mode == 'prediction':\n    model_dir = os.path.join(training_dir, 'model')\n  else:\n    raise ValueError('mode must be evaluation or prediction')\n\n  if not file_io.file_exists(model_dir):\n    raise ValueError('Model folder %s does not exist' % model_dir)\n\n  cmd = ['predict.py',\n         '--predict-data=%s' % prediction_input_file,\n         '--trained-model-dir=%s' % model_dir,\n         '--output-dir=%s' % output_dir,\n         '--output-format=%s' % output_format,\n         '--batch-size=%s' % str(batch_size),\n         '--shard-files' if shard_files else '--no-shard-files',\n         '--has-target' if mode == 'evaluation' else '--no-has-target'\n         ]\n\n  # return predict_module.predict.main(cmd)\n  return predict_module.main(cmd)\n\n\ndef cloud_batch_predict(training_dir, prediction_input_file, output_dir, mode, batch_size,\n                        shard_files, output_format):\n  \"\"\"See batch_predict\"\"\"\n  # from . import predict as predict_module\n  from .prediction import predict as predict_module\n\n  if mode == 'evaluation':\n    model_dir = os.path.join(training_dir, 'evaluation_model')\n  elif mode == 'prediction':\n    model_dir = os.path.join(training_dir, 'model')\n  else:\n    raise ValueError('mode must be evaluation or prediction')\n\n  if not file_io.file_exists(model_dir):\n    raise ValueError('Model folder %s does not exist' % model_dir)\n\n  _assert_gcs_files([training_dir, prediction_input_file, output_dir])\n\n  cmd = ['predict.py',\n         '--cloud',\n         '--project-id=%s' % _default_project(),\n         '--predict-data=%s' % prediction_input_file,\n         '--trained-model-dir=%s' % model_dir,\n         '--output-dir=%s' % output_dir,\n         '--output-format=%s' % output_format,\n         '--batch-size=%s' % str(batch_size),\n         '--shard-files' if shard_files else '--no-shard-files',\n         '--extra-package=%s' % _TF_GS_URL,\n         '--extra-package=%s' % _PROTOBUF_GS_URL,\n         '--extra-package=%s' % _package_to_staging(output_dir)\n         ]\n\n  return predict_module.main(cmd)\n"
  },
  {
    "path": "solutionbox/structured_data/mltoolbox/_structured_data/master_setup.py",
    "content": "# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n# A copy of this file must be made in datalab_structured_data/setup.py\n\nimport os\nimport re\nfrom setuptools import setup\n\n\n# The version is saved in an __init__ file.\ndef get_version():\n    VERSIONFILE = 'mltoolbox/_structured_data/__version__.py'\n    if not os.path.isfile(VERSIONFILE):\n      raise ValueError('setup.py: File not found %s' % VERSIONFILE)\n    initfile_lines = open(VERSIONFILE, 'rt').readlines()\n    VSRE = r\"^__version__ = ['\\\"]([^'\\\"]*)['\\\"]\"\n    for line in initfile_lines:\n        mo = re.search(VSRE, line, re.M)\n        if mo:\n            return mo.group(1)\n    raise RuntimeError('Unable to find version string in %s.' % (VERSIONFILE,))\n\n\n# Calling setuptools.find_packages does not work with cloud training repackaging\n# because this script is not ran from this folder.\n\nsetup(\n  name='mltoolbox_datalab_classification_and_regression',\n  namespace_packages=['mltoolbox'],\n  version=get_version(),\n  packages=[\n    'mltoolbox',\n    'mltoolbox.classification',\n    'mltoolbox.classification.linear',\n    'mltoolbox.classification.dnn',\n    'mltoolbox.regression',\n    'mltoolbox.regression.linear',\n    'mltoolbox.regression.dnn',\n    'mltoolbox._structured_data',\n    'mltoolbox._structured_data.preprocess',\n    'mltoolbox._structured_data.prediction',\n    # 'mltoolbox._structured_data.test',\n    'mltoolbox._structured_data.trainer',\n  ],\n  description='Google Cloud Datalab Structured Data Package',\n  author='Google',\n  author_email='google-cloud-datalab-feedback@googlegroups.com',\n  keywords=[\n  ],\n  license=\"Apache Software License\",\n  classifiers=[\n      \"Programming Language :: Python\",\n      \"Programming Language :: Python :: 2\",\n      \"Development Status :: 4 - Beta\",\n      \"Environment :: Other Environment\",\n      \"Intended Audience :: Developers\",\n      \"License :: OSI Approved :: Apache Software License\",\n      \"Operating System :: OS Independent\",\n      \"Topic :: Software Development :: Libraries :: Python Modules\"\n  ],\n  long_description=\"\"\"\n  \"\"\",\n  install_requires=[\n  ],\n  package_data={\n  },\n  data_files=[],\n)\n"
  },
  {
    "path": "solutionbox/structured_data/mltoolbox/_structured_data/prediction/__init__.py",
    "content": "# Copyright 2017 Google Inc. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n# ==============================================================================\nfrom __future__ import absolute_import\n\nfrom . import predict\n\n__all__ = ['predict']\n"
  },
  {
    "path": "solutionbox/structured_data/mltoolbox/_structured_data/prediction/predict.py",
    "content": "# Copyright 2017 Google Inc. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\"\"\"Runs prediction on a trained model.\"\"\"\n\n\nimport argparse\nimport datetime\nimport os\nimport shutil\nimport sys\nimport tempfile\nfrom tensorflow.python.lib.io import file_io\n\nimport apache_beam as beam\nfrom apache_beam.transforms import window\nfrom apache_beam.utils.windowed_value import WindowedValue\n\n\ndef parse_arguments(argv):\n  \"\"\"Parse command line arguments.\n\n  Args:\n    argv: includes the script's name.\n\n  Returns:\n    argparse object\n  \"\"\"\n  parser = argparse.ArgumentParser(\n      description='Runs Prediction inside a beam or Dataflow job.')\n  # cloud options\n  parser.add_argument('--project-id',\n                      help='The project to which the job will be submitted.')\n  parser.add_argument('--cloud',\n                      action='store_true',\n                      help='Run preprocessing on the cloud.')\n  parser.add_argument('--job-name',\n                      default=('mltoolbox-batch-prediction-' +\n                               datetime.datetime.now().strftime('%Y%m%d%H%M%S')),\n                      help='Dataflow job name. Must be unique over all jobs.')\n  parser.add_argument('--extra-package',\n                      default=[],\n                      action='append',\n                      help=('If using --cloud, also installs these packages on '\n                            'each dataflow worker'))\n\n  # I/O args\n  parser.add_argument('--predict-data',\n                      required=True,\n                      help='Data to run prediction on')\n  parser.add_argument('--trained-model-dir',\n                      required=True,\n                      help='Usually train_output_path/model.')\n  parser.add_argument('--output-dir',\n                      required=True,\n                      help=('Location to save output.'))\n\n  # Other args\n  parser.add_argument('--batch-size',\n                      required=False,\n                      default=1000,\n                      type=int,\n                      help=('Batch size. Larger values consumes more memrory '\n                            'but takes less time to finish.'))\n  parser.add_argument('--shard-files',\n                      dest='shard_files',\n                      action='store_true',\n                      help='Shard files')\n  parser.add_argument('--no-shard-files',\n                      dest='shard_files',\n                      action='store_false',\n                      help='Don\\'t shard files')\n  parser.set_defaults(shard_files=True)\n\n  parser.add_argument('--output-format',\n                      choices=['csv', 'json'],\n                      default='csv',\n                      help=\"\"\"\n      The output results.\n        raw_json: produces a newline file where each line is json. No\n            post processing is performed and the output matches what the trained\n            model produces.\n        csv: produces a csv file without a header row and a header csv file.\n            For classification problems, the vector of probabalities for each\n            target class is split into individual csv columns.\"\"\")\n\n  args, _ = parser.parse_known_args(args=argv[1:])\n\n  if args.cloud:\n    if not args.project_id:\n      raise ValueError('--project-id needed with --cloud')\n    if not args.trained_model_dir.startswith('gs://'):\n      raise ValueError('--trained-model-dir needs to be a GCS path,')\n    if not args.output_dir.startswith('gs://'):\n      raise ValueError('--output-dir needs to be a GCS path.')\n    if not args.predict_data.startswith('gs://'):\n      raise ValueError('--predict-data needs to be a GCS path.')\n\n  return args\n\n\nclass EmitAsBatchDoFn(beam.DoFn):\n  \"\"\"A DoFn that buffers the records and emits them batch by batch.\"\"\"\n\n  def __init__(self, batch_size):\n    \"\"\"Constructor of EmitAsBatchDoFn beam.DoFn class.\n\n    Args:\n      batch_size: the max size we want to buffer the records before emitting.\n    \"\"\"\n    self._batch_size = batch_size\n    self._cached = []\n\n  def process(self, element):\n    self._cached.append(element)\n    if len(self._cached) >= self._batch_size:\n      emit = self._cached\n      self._cached = []\n      yield emit\n\n  def finish_bundle(self, element=None):\n    if len(self._cached) > 0:  # pylint: disable=g-explicit-length-test\n      yield WindowedValue(self._cached, -1, [window.GlobalWindow()])\n\n\nclass RunGraphDoFn(beam.DoFn):\n  \"\"\"A DoFn for running the TF graph.\"\"\"\n\n  def __init__(self, trained_model_dir):\n    self._trained_model_dir = trained_model_dir\n    self._session = None\n\n  def start_bundle(self, element=None):\n    from tensorflow.python.saved_model import tag_constants\n    from tensorflow.contrib.session_bundle import bundle_shim\n\n    self._session, meta_graph = bundle_shim.load_session_bundle_or_saved_model_bundle_from_path(\n        self._trained_model_dir, tags=[tag_constants.SERVING])\n    signature = meta_graph.signature_def['serving_default']\n\n    # get the mappings between aliases and tensor names\n    # for both inputs and outputs\n    self._input_alias_map = {friendly_name: tensor_info_proto.name\n                             for (friendly_name, tensor_info_proto) in signature.inputs.items()}\n    self._output_alias_map = {friendly_name: tensor_info_proto.name\n                              for (friendly_name, tensor_info_proto) in signature.outputs.items()}\n    self._aliases, self._tensor_names = zip(*self._output_alias_map.items())\n\n  def finish_bundle(self, element=None):\n    import tensorflow as tf\n\n    self._session.close()\n    tf.reset_default_graph()\n\n  def process(self, element):\n    \"\"\"Run batch prediciton on a TF graph.\n\n    Args:\n      element: list of strings, representing one batch input to the TF graph.\n    \"\"\"\n    import collections\n    import apache_beam as beam\n\n    num_in_batch = 0\n    try:\n      assert self._session is not None\n\n      feed_dict = collections.defaultdict(list)\n      for line in element:\n\n        # Remove trailing newline.\n        if line.endswith('\\n'):\n          line = line[:-1]\n\n        feed_dict[self._input_alias_map.values()[0]].append(line)\n        num_in_batch += 1\n\n      # batch_result is list of numpy arrays with batch_size many rows.\n      batch_result = self._session.run(fetches=self._tensor_names,\n                                       feed_dict=feed_dict)\n\n      # ex batch_result for batch_size > 1:\n      # (array([value1, value2, ..., value_batch_size]),\n      #  array([[a1, b1, c1]], ..., [a_batch_size, b_batch_size, c_batch_size]]),\n      #  ...)\n      # ex batch_result for batch_size == 1:\n      # (value,\n      #  array([a1, b1, c1]),\n      #  ...)\n\n      # Convert the results into a dict and unbatch the results.\n      if num_in_batch > 1:\n        for result in zip(*batch_result):\n          predictions = {}\n          for name, value in zip(self._aliases, result):\n            predictions[name] = (value.tolist() if getattr(value, 'tolist', None) else value)\n          yield predictions\n      else:\n        predictions = {}\n        for i in range(len(self._aliases)):\n          value = batch_result[i]\n          value = (value.tolist() if getattr(value, 'tolist', None)\n                   else value)\n          predictions[self._aliases[i]] = value\n        yield predictions\n\n    except Exception as e:  # pylint: disable=broad-except\n      yield beam.pvalue.TaggedOutput('errors', (str(e), element))\n\n\nclass RawJsonCoder(beam.coders.Coder):\n  \"\"\"Coder for json newline files.\"\"\"\n\n  def encode(self, obj):\n    \"\"\"Encodes a python object into a JSON string.\n\n    Args:\n      obj: python object.\n\n    Returns:\n      JSON string.\n    \"\"\"\n    import json\n    return json.dumps(obj, separators=(',', ': '))\n\n\nclass CSVCoder(beam.coders.Coder):\n  \"\"\"Coder for CSV files containing the output of prediction.\"\"\"\n\n  def __init__(self, header):\n    \"\"\"Sets the headers in the csv file.\n\n    Args:\n      header: list of strings that correspond to keys in the predictions dict.\n    \"\"\"\n    self._header = header\n\n  def make_header_string(self):\n    return ','.join(self._header)\n\n  def encode(self, tf_graph_predictions):\n    \"\"\"Encodes the graph json prediction into csv.\n\n    Args:\n      tf_graph_predictions: python dict.\n\n    Returns:\n      csv string.\n    \"\"\"\n    row = []\n    for col in self._header:\n      row.append(str(tf_graph_predictions[col]))\n\n    return ','.join(row)\n\n\nclass FormatAndSave(beam.PTransform):\n\n  def __init__(self, args):\n    self._shard_name_template = None if args.shard_files else ''\n    self._output_format = args.output_format\n    self._output_dir = args.output_dir\n\n    # Get the BQ schema if csv.\n    if self._output_format == 'csv':\n      from tensorflow.python.saved_model import tag_constants\n      from tensorflow.contrib.session_bundle import bundle_shim\n      from tensorflow.core.framework import types_pb2\n\n      session, meta_graph = bundle_shim.load_session_bundle_or_saved_model_bundle_from_path(\n          args.trained_model_dir, tags=[tag_constants.SERVING])\n      signature = meta_graph.signature_def['serving_default']\n\n      self._schema = []\n      for friendly_name in sorted(signature.outputs):\n        tensor_info_proto = signature.outputs[friendly_name]\n\n        # TODO(brandondutra): Could dtype be DT_INVALID?\n        # Consider getting the dtype from the graph via\n        # session.graph.get_tensor_by_name(tensor_info_proto.name).dtype)\n        dtype = tensor_info_proto.dtype\n        if dtype == types_pb2.DT_FLOAT or dtype == types_pb2.DT_DOUBLE:\n          bq_type = 'FLOAT'\n        elif dtype == types_pb2.DT_INT32 or dtype == types_pb2.DT_INT64:\n          bq_type = 'INTEGER'\n        else:\n          bq_type = 'STRING'\n\n        self._schema.append({'mode': 'NULLABLE',\n                             'name': friendly_name,\n                             'type': bq_type})\n      session.close()\n\n  def apply(self, datasets):\n    return self.expand(datasets)\n\n  def expand(self, datasets):\n    import json\n\n    tf_graph_predictions, errors = datasets\n\n    if self._output_format == 'json':\n      (tf_graph_predictions |\n       'Write Raw JSON' >>\n       beam.io.textio.WriteToText(os.path.join(self._output_dir, 'predictions'),\n                                  file_name_suffix='.json',\n                                  coder=RawJsonCoder(),\n                                  shard_name_template=self._shard_name_template))\n    elif self._output_format == 'csv':\n      # make a csv header file\n      header = [col['name'] for col in self._schema]\n      csv_coder = CSVCoder(header)\n      (tf_graph_predictions.pipeline |\n       'Make CSV Header' >>\n       beam.Create([json.dumps(self._schema, indent=2)]) |\n       'Write CSV Schema File' >>\n       beam.io.textio.WriteToText(os.path.join(self._output_dir, 'csv_schema'),\n                                  file_name_suffix='.json',\n                                  shard_name_template=''))\n\n      # Write the csv predictions\n      (tf_graph_predictions |\n       'Write CSV' >>\n       beam.io.textio.WriteToText(os.path.join(self._output_dir, 'predictions'),\n                                  file_name_suffix='.csv',\n                                  coder=csv_coder,\n                                  shard_name_template=self._shard_name_template))\n    else:\n      raise ValueError('FormatAndSave: unknown format %s', self._output_format)\n\n    # Write the errors to a text file.\n    (errors |\n     'Write Errors' >>\n     beam.io.textio.WriteToText(os.path.join(self._output_dir, 'errors'),\n                                file_name_suffix='.txt',\n                                shard_name_template=self._shard_name_template))\n\n\ndef make_prediction_pipeline(pipeline, args):\n  \"\"\"Builds the prediction pipeline.\n\n  Reads the csv files, prepends a ',' if the target column is missing, run\n  prediction, and then prints the formated results to a file.\n\n  Args:\n    pipeline: the pipeline\n    args: command line args\n  \"\"\"\n\n  # DF bug: DF does not work with unicode strings\n  predicted_values, errors = (\n      pipeline |\n      'Read CSV Files' >>\n      beam.io.ReadFromText(str(args.predict_data),\n                           strip_trailing_newlines=True) |\n      'Batch Input' >>\n      beam.ParDo(EmitAsBatchDoFn(args.batch_size)) |\n      'Run TF Graph on Batches' >>\n      beam.ParDo(RunGraphDoFn(args.trained_model_dir)).with_outputs('errors', main='main'))\n\n  ((predicted_values, errors) |\n   'Format and Save' >>\n   FormatAndSave(args))\n\n\ndef main(argv=None):\n  args = parse_arguments(sys.argv if argv is None else argv)\n\n  if args.cloud:\n    tmpdir = tempfile.mkdtemp()\n    try:\n      local_packages = [os.path.join(tmpdir, os.path.basename(p)) for p in args.extra_package]\n      for source, dest in zip(args.extra_package, local_packages):\n        file_io.copy(source, dest, overwrite=True)\n\n      options = {\n          'staging_location': os.path.join(args.output_dir, 'tmp', 'staging'),\n          'temp_location': os.path.join(args.output_dir, 'tmp', 'staging'),\n          'job_name': args.job_name,\n          'project': args.project_id,\n          'no_save_main_session': True,\n          'extra_packages': local_packages,\n          'teardown_policy': 'TEARDOWN_ALWAYS',\n      }\n      opts = beam.pipeline.PipelineOptions(flags=[], **options)\n      # Or use BlockingDataflowPipelineRunner\n      p = beam.Pipeline('DataflowRunner', options=opts)\n      make_prediction_pipeline(p, args)\n      print(('Dataflow Job submitted, see Job %s at '\n             'https://console.developers.google.com/dataflow?project=%s') %\n            (options['job_name'], args.project_id))\n      sys.stdout.flush()\n      runner_results = p.run()\n    finally:\n      shutil.rmtree(tmpdir)\n  else:\n    p = beam.Pipeline('DirectRunner')\n    make_prediction_pipeline(p, args)\n    runner_results = p.run()\n\n  return runner_results\n\n\nif __name__ == '__main__':\n  runner_results = main()\n  runner_results.wait_until_finish()\n"
  },
  {
    "path": "solutionbox/structured_data/mltoolbox/_structured_data/preprocess/__init__.py",
    "content": "# Copyright 2017 Google Inc. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n# ==============================================================================\nfrom __future__ import absolute_import\n\nfrom . import cloud_preprocess\nfrom . import local_preprocess\n\n__all__ = ['cloud_preprocess', 'local_preprocess']\n"
  },
  {
    "path": "solutionbox/structured_data/mltoolbox/_structured_data/preprocess/cloud_preprocess.py",
    "content": "# Copyright 2017 Google Inc. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport argparse\nimport json\nimport os\nimport six\nimport sys\n\n\nfrom tensorflow.python.lib.io import file_io\n\nSCHEMA_FILE = 'schema.json'\nNUMERICAL_ANALYSIS_FILE = 'stats.json'\nCATEGORICAL_ANALYSIS_FILE = 'vocab_%s.csv'\n\n\ndef parse_arguments(argv):\n  \"\"\"Parse command line arguments.\n\n  Args:\n    argv: list of command line arguments, includeing programe name.\n\n  Returns:\n    An argparse Namespace object.\n\n  Raises:\n    ValueError: for bad parameters\n  \"\"\"\n  parser = argparse.ArgumentParser(\n      description='Runs Preprocessing on structured data.')\n  parser.add_argument('--output-dir',\n                      type=str,\n                      required=True,\n                      help='Google Cloud Storage which to place outputs.')\n\n  parser.add_argument('--schema-file',\n                      type=str,\n                      required=False,\n                      help=('BigQuery json schema file'))\n  parser.add_argument('--input-file-pattern',\n                      type=str,\n                      required=False,\n                      help='Input CSV file names. May contain a file pattern')\n\n  # If using bigquery table\n  # TODO(brandondutra): maybe also support an sql input, so the table can be\n  # ad-hoc.\n  parser.add_argument('--bigquery-table',\n                      type=str,\n                      required=False,\n                      help=('project:dataset.table_name'))\n\n  args = parser.parse_args(args=argv[1:])\n\n  if not args.output_dir.startswith('gs://'):\n    raise ValueError('--output-dir must point to a location on GCS')\n\n  if args.bigquery_table:\n    if args.schema_file or args.input_file_pattern:\n      raise ValueError('If using --bigquery-table, then --schema-file and '\n                       '--input-file-pattern, '\n                       'are not needed.')\n  else:\n    if not args.schema_file or not args.input_file_pattern:\n      raise ValueError('If not using --bigquery-table, then --schema-file and '\n                       '--input-file-pattern '\n                       'are required.')\n\n    if not args.input_file_pattern.startswith('gs://'):\n      raise ValueError('--input-file-pattern must point to files on GCS')\n\n  return args\n\n\ndef parse_table_name(bigquery_table):\n  \"\"\"Giving a string a:b.c, returns b.c.\n\n  Args:\n    bigquery_table: full table name project_id:dataset:table\n\n  Returns:\n    dataset:table\n\n  Raises:\n    ValueError: if a, b, or c contain the character ':'.\n  \"\"\"\n\n  id_name = bigquery_table.split(':')\n  if len(id_name) != 2:\n    raise ValueError('Bigquery table name should be in the form '\n                     'project_id:dataset.table_name. Got %s' % bigquery_table)\n  return id_name[1]\n\n\ndef run_numerical_analysis(table, schema_list, args):\n  \"\"\"Find min/max values for the numerical columns and writes a json file.\n\n  Args:\n    table: Reference to FederatedTable (if bigquery_table is false) or a\n        regular Table (otherwise)\n    schema_list: Bigquery schema json object\n    args: the command line args\n  \"\"\"\n  import google.datalab.bigquery as bq\n\n  # Get list of numerical columns.\n  numerical_columns = []\n  for col_schema in schema_list:\n    col_type = col_schema['type'].lower()\n    if col_type == 'integer' or col_type == 'float':\n      numerical_columns.append(col_schema['name'])\n\n  # Run the numerical analysis\n  if numerical_columns:\n    sys.stdout.write('Running numerical analysis...')\n    max_min = [\n        ('max({name}) as max_{name}, '\n         'min({name}) as min_{name}, '\n         'avg({name}) as avg_{name} ').format(name=name)\n        for name in numerical_columns]\n    if args.bigquery_table:\n      sql = 'SELECT  %s from `%s`' % (', '.join(max_min), parse_table_name(args.bigquery_table))\n      numerical_results = bq.Query(sql).execute().result().to_dataframe()\n    else:\n      sql = 'SELECT  %s from csv_table' % ', '.join(max_min)\n      query = bq.Query(sql, data_sources={'csv_table': table})\n      numerical_results = query.execute().result().to_dataframe()\n\n    # Convert the numerical results to a json file.\n    results_dict = {}\n    for name in numerical_columns:\n      results_dict[name] = {'max': numerical_results.iloc[0]['max_%s' % name],\n                            'min': numerical_results.iloc[0]['min_%s' % name],\n                            'mean': numerical_results.iloc[0]['avg_%s' % name]}\n\n    file_io.write_string_to_file(\n        os.path.join(args.output_dir, NUMERICAL_ANALYSIS_FILE),\n        json.dumps(results_dict, indent=2, separators=(',', ': ')))\n\n    sys.stdout.write('done.\\n')\n\n\ndef run_categorical_analysis(table, schema_list, args):\n  \"\"\"Find vocab values for the categorical columns and writes a csv file.\n\n  The vocab files are in the from\n  label1\n  label2\n  label3\n  ...\n\n  Args:\n    table: Reference to FederatedTable (if bigquery_table is false) or a\n        regular Table (otherwise)\n    schema_list: Bigquery schema json object\n    args: the command line args\n  \"\"\"\n  import google.datalab.bigquery as bq\n\n  # Get list of categorical columns.\n  categorical_columns = []\n  for col_schema in schema_list:\n    col_type = col_schema['type'].lower()\n    if col_type == 'string':\n      categorical_columns.append(col_schema['name'])\n\n  if categorical_columns:\n    sys.stdout.write('Running categorical analysis...')\n    for name in categorical_columns:\n      if args.bigquery_table:\n        table_name = parse_table_name(args.bigquery_table)\n      else:\n        table_name = 'table_name'\n\n      sql = \"\"\"\n            SELECT\n              {name}\n            FROM\n              {table}\n            WHERE\n              {name} IS NOT NULL\n            GROUP BY\n              {name}\n            ORDER BY\n              {name}\n      \"\"\".format(name=name, table=table_name)\n      out_file = os.path.join(args.output_dir,\n                              CATEGORICAL_ANALYSIS_FILE % name)\n\n      # extract_async seems to have a bug and sometimes hangs. So get the\n      # results direclty.\n      if args.bigquery_table:\n        df = bq.Query(sql).execute().result().to_dataframe()\n      else:\n        query = bq.Query(sql, data_sources={'table_name': table})\n        df = query.execute().result().to_dataframe()\n\n      # Write the results to a file.\n      string_buff = six.StringIO()\n      df.to_csv(string_buff, index=False, header=False)\n      file_io.write_string_to_file(out_file, string_buff.getvalue())\n\n    sys.stdout.write('done.\\n')\n\n\ndef run_analysis(args):\n  \"\"\"Builds an analysis file for training.\n\n  Uses BiqQuery tables to do the analysis.\n\n  Args:\n    args: command line args\n\n  Raises:\n    ValueError if schema contains unknown types.\n  \"\"\"\n  import google.datalab.bigquery as bq\n  if args.bigquery_table:\n    table = bq.Table(args.bigquery_table)\n    schema_list = table.schema._bq_schema\n  else:\n    schema_list = json.loads(\n        file_io.read_file_to_string(args.schema_file).decode())\n    table = bq.ExternalDataSource(\n        source=args.input_file_pattern,\n        schema=bq.Schema(schema_list))\n\n  # Check the schema is supported.\n  for col_schema in schema_list:\n    col_type = col_schema['type'].lower()\n    if col_type != 'string' and col_type != 'integer' and col_type != 'float':\n      raise ValueError('Schema contains an unsupported type %s.' % col_type)\n\n  run_numerical_analysis(table, schema_list, args)\n  run_categorical_analysis(table, schema_list, args)\n\n  # Save a copy of the schema to the output location.\n  file_io.write_string_to_file(\n      os.path.join(args.output_dir, SCHEMA_FILE),\n      json.dumps(schema_list, indent=2, separators=(',', ': ')))\n\n\ndef main(argv=None):\n  args = parse_arguments(sys.argv if argv is None else argv)\n  run_analysis(args)\n\n\nif __name__ == '__main__':\n  main()\n"
  },
  {
    "path": "solutionbox/structured_data/mltoolbox/_structured_data/preprocess/local_preprocess.py",
    "content": "# Copyright 2017 Google Inc. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\nfrom __future__ import unicode_literals\n\n\nimport argparse\nimport collections\nimport json\nimport os\nimport six\nimport sys\n\n\nfrom tensorflow.python.lib.io import file_io\n\n\nSCHEMA_FILE = 'schema.json'\nNUMERICAL_ANALYSIS_FILE = 'stats.json'\nCATEGORICAL_ANALYSIS_FILE = 'vocab_%s.csv'\n\n\ndef parse_arguments(argv):\n  \"\"\"Parse command line arguments.\n\n  Args:\n    argv: list of command line arguments, includeing programe name.\n\n  Returns:\n    An argparse Namespace object.\n  \"\"\"\n  parser = argparse.ArgumentParser(\n      description='Runs Preprocessing on structured CSV data.')\n  parser.add_argument('--input-file-pattern',\n                      type=str,\n                      required=True,\n                      help='Input CSV file names. May contain a file pattern')\n  parser.add_argument('--output-dir',\n                      type=str,\n                      required=True,\n                      help='Google Cloud Storage which to place outputs.')\n  parser.add_argument('--schema-file',\n                      type=str,\n                      required=True,\n                      help=('BigQuery json schema file'))\n\n  args = parser.parse_args(args=argv[1:])\n\n  # Make sure the output folder exists if local folder.\n  file_io.recursive_create_dir(args.output_dir)\n\n  return args\n\n\ndef run_numerical_categorical_analysis(args, schema_list):\n  \"\"\"Makes the numerical and categorical analysis files.\n\n  Args:\n    args: the command line args\n    schema_list: python object of the schema json file.\n\n  Raises:\n    ValueError: if schema contains unknown column types.\n  \"\"\"\n  header = [column['name'] for column in schema_list]\n  input_files = file_io.get_matching_files(args.input_file_pattern)\n\n  # Check the schema is valid\n  for col_schema in schema_list:\n    col_type = col_schema['type'].lower()\n    if col_type != 'string' and col_type != 'integer' and col_type != 'float':\n      raise ValueError('Schema contains an unsupported type %s.' % col_type)\n\n  # initialize the results\n  def _init_numerical_results():\n    return {'min': float('inf'),\n            'max': float('-inf'),\n            'count': 0,\n            'sum': 0.0}\n  numerical_results = collections.defaultdict(_init_numerical_results)\n  categorical_results = collections.defaultdict(set)\n\n  # for each file, update the numerical stats from that file, and update the set\n  # of unique labels.\n  for input_file in input_files:\n    with file_io.FileIO(input_file, 'r') as f:\n      for line in f:\n        parsed_line = dict(zip(header, line.strip().split(',')))\n\n        for col_schema in schema_list:\n          col_name = col_schema['name']\n          col_type = col_schema['type']\n          if col_type.lower() == 'string':\n            categorical_results[col_name].update([parsed_line[col_name]])\n          else:\n            # numerical column.\n\n            # if empty, skip\n            if not parsed_line[col_name].strip():\n              continue\n\n            numerical_results[col_name]['min'] = (\n              min(numerical_results[col_name]['min'],\n                  float(parsed_line[col_name])))\n            numerical_results[col_name]['max'] = (\n              max(numerical_results[col_name]['max'],\n                  float(parsed_line[col_name])))\n            numerical_results[col_name]['count'] += 1\n            numerical_results[col_name]['sum'] += float(parsed_line[col_name])\n\n  # Update numerical_results to just have min/min/mean\n  for col_schema in schema_list:\n    if col_schema['type'].lower() != 'string':\n      col_name = col_schema['name']\n      mean = numerical_results[col_name]['sum'] / numerical_results[col_name]['count']\n      del numerical_results[col_name]['sum']\n      del numerical_results[col_name]['count']\n      numerical_results[col_name]['mean'] = mean\n\n  # Write the numerical_results to a json file.\n  file_io.write_string_to_file(\n      os.path.join(args.output_dir, NUMERICAL_ANALYSIS_FILE),\n      json.dumps(numerical_results, indent=2, separators=(',', ': ')))\n\n  # Write the vocab files. Each label is on its own line.\n  for name, unique_labels in six.iteritems(categorical_results):\n    labels = '\\n'.join(list(unique_labels))\n    file_io.write_string_to_file(\n        os.path.join(args.output_dir, CATEGORICAL_ANALYSIS_FILE % name),\n        labels)\n\n\ndef run_analysis(args):\n  \"\"\"Builds an analysis files for training.\"\"\"\n\n  # Read the schema and input feature types\n  schema_list = json.loads(\n      file_io.read_file_to_string(args.schema_file))\n\n  run_numerical_categorical_analysis(args, schema_list)\n\n  # Also save a copy of the schema in the output folder.\n  file_io.copy(args.schema_file,\n               os.path.join(args.output_dir, SCHEMA_FILE),\n               overwrite=True)\n\n\ndef main(argv=None):\n  args = parse_arguments(sys.argv if argv is None else argv)\n  run_analysis(args)\n\n\nif __name__ == '__main__':\n  main()\n"
  },
  {
    "path": "solutionbox/structured_data/mltoolbox/_structured_data/trainer/__init__.py",
    "content": "# Copyright 2017 Google Inc. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n# ==============================================================================\nfrom __future__ import absolute_import\n\nfrom . import task\n\n__all__ = ['task']\n"
  },
  {
    "path": "solutionbox/structured_data/mltoolbox/_structured_data/trainer/task.py",
    "content": "# Copyright 2017 Google Inc. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\nfrom __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport argparse\nimport os\nimport re\nimport sys\n\nfrom . import util\nimport tensorflow as tf\n\nfrom tensorflow.contrib.learn.python.learn import learn_runner\nfrom tensorflow.python.lib.io import file_io\n\n\ndef get_reader_input_fn(train_config, preprocess_output_dir, model_type,\n                        data_paths, batch_size, shuffle, num_epochs=None):\n  \"\"\"Builds input layer for training.\"\"\"\n\n  def get_input_features():\n    \"\"\"Read the input features from the given data paths.\"\"\"\n    _, examples = util.read_examples(\n        input_files=data_paths,\n        batch_size=batch_size,\n        shuffle=shuffle,\n        num_epochs=num_epochs)\n    features = util.parse_example_tensor(examples=examples,\n                                         train_config=train_config,\n                                         keep_target=True)\n\n    target_name = train_config['target_column']\n    target = features.pop(target_name)\n    features, target = util.preprocess_input(\n        features=features,\n        target=target,\n        train_config=train_config,\n        preprocess_output_dir=preprocess_output_dir,\n        model_type=model_type)\n\n    return features, target\n\n  # Return a function to input the feaures into the model from a data path.\n  return get_input_features\n\n\ndef get_experiment_fn(args):\n  \"\"\"Builds the experiment function for learn_runner.run.\n\n  Args:\n    args: the command line args\n\n  Returns:\n    A function that returns a tf.learn experiment object.\n  \"\"\"\n\n  def get_experiment(output_dir):\n    # Merge schema, input features, and transforms.\n    train_config = util.merge_metadata(args.preprocess_output_dir,\n                                       args.transforms_file)\n\n    # Get the model to train.\n    estimator = util.get_estimator(output_dir, train_config, args)\n\n    # Save a copy of the scehma and input to the model folder.\n    schema_file = os.path.join(args.preprocess_output_dir, util.SCHEMA_FILE)\n\n    # Make list of files to save with the trained model.\n    additional_assets = {'features.json': args.transforms_file,\n                         util.SCHEMA_FILE: schema_file}\n    if util.is_classification_model(args.model_type):\n      target_name = train_config['target_column']\n      vocab_file_name = util.CATEGORICAL_ANALYSIS % target_name\n      vocab_file_path = os.path.join(\n          args.preprocess_output_dir, vocab_file_name)\n      assert file_io.file_exists(vocab_file_path)\n      additional_assets[vocab_file_name] = vocab_file_path\n\n    export_strategy_target = util.make_export_strategy(\n        train_config=train_config,\n        args=args,\n        keep_target=True,\n        assets_extra=additional_assets)\n    export_strategy_notarget = util.make_export_strategy(\n        train_config=train_config,\n        args=args,\n        keep_target=False,\n        assets_extra=additional_assets)\n\n    input_reader_for_train = get_reader_input_fn(\n        train_config=train_config,\n        preprocess_output_dir=args.preprocess_output_dir,\n        model_type=args.model_type,\n        data_paths=args.train_data_paths,\n        batch_size=args.train_batch_size,\n        shuffle=True,\n        num_epochs=args.num_epochs)\n\n    input_reader_for_eval = get_reader_input_fn(\n        train_config=train_config,\n        preprocess_output_dir=args.preprocess_output_dir,\n        model_type=args.model_type,\n        data_paths=args.eval_data_paths,\n        batch_size=args.eval_batch_size,\n        shuffle=False,\n        num_epochs=1)\n\n    return tf.contrib.learn.Experiment(\n        estimator=estimator,\n        train_input_fn=input_reader_for_train,\n        eval_input_fn=input_reader_for_eval,\n        train_steps=args.max_steps,\n        export_strategies=[export_strategy_target, export_strategy_notarget],\n        min_eval_frequency=args.min_eval_frequency,\n        eval_steps=None,\n    )\n\n  # Return a function to create an Experiment.\n  return get_experiment\n\n\ndef parse_arguments(argv):\n  \"\"\"Parse the command line arguments.\"\"\"\n  parser = argparse.ArgumentParser(\n      description=('Train a regression or classification model. Note that if '\n                   'using a DNN model, --layer-size1=NUM, --layer-size2=NUM, '\n                   'should be used. '))\n\n  # I/O file parameters\n  parser.add_argument('--train-data-paths', type=str, action='append',\n                      required=True)\n  parser.add_argument('--eval-data-paths', type=str, action='append',\n                      required=True)\n  parser.add_argument('--job-dir', type=str, required=True)\n  parser.add_argument('--preprocess-output-dir',\n                      type=str,\n                      required=True,\n                      help=('Output folder of preprocessing. Should contain the'\n                            ' schema file, and numerical stats and vocab files.'\n                            ' Path must be on GCS if running'\n                            ' cloud training.'))\n  parser.add_argument('--transforms-file',\n                      type=str,\n                      required=True,\n                      help=('File describing the the transforms to apply on '\n                            'each column'))\n\n  # HP parameters\n  parser.add_argument('--learning-rate', type=float, default=0.01,\n                      help='tf.train.AdamOptimizer learning rate')\n  parser.add_argument('--epsilon', type=float, default=0.0005,\n                      help='tf.train.AdamOptimizer epsilon')\n  # --layer_size See below\n\n  # Model problems\n  parser.add_argument('--model-type',\n                      choices=['linear_classification', 'linear_regression',\n                               'dnn_classification', 'dnn_regression'],\n                      required=True)\n  parser.add_argument('--top-n',\n                      type=int,\n                      default=1,\n                      help=('For classification problems, the output graph '\n                            'will contain the labels and scores for the top '\n                            'n classes.'))\n  # Training input parameters\n  parser.add_argument('--max-steps', type=int, default=5000,\n                      help='Maximum number of training steps to perform.')\n  parser.add_argument('--num-epochs',\n                      type=int,\n                      help=('Maximum number of training data epochs on which '\n                            'to train. If both --max-steps and --num-epochs '\n                            'are specified, the training job will run for '\n                            '--max-steps or --num-epochs, whichever occurs '\n                            'first. If unspecified will run for --max-steps.'))\n  parser.add_argument('--train-batch-size', type=int, default=1000)\n  parser.add_argument('--eval-batch-size', type=int, default=1000)\n  parser.add_argument('--min-eval-frequency', type=int, default=100,\n                      help=('Minimum number of training steps between '\n                            'evaluations'))\n\n  # other parameters\n  parser.add_argument('--save-checkpoints-secs', type=int, default=600,\n                      help=('How often the model should be checkpointed/saved '\n                            'in seconds'))\n\n  args, remaining_args = parser.parse_known_args(args=argv[1:])\n\n  # All HP parambeters must be unique, so we need to support an unknown number\n  # of --layer_size1=10 --layer_size2=10 ...\n  # Look at remaining_args for layer_size\\d+ to get the layer info.\n\n  # Get number of layers\n  pattern = re.compile('layer-size(\\d+)')\n  num_layers = 0\n  for other_arg in remaining_args:\n    match = re.search(pattern, other_arg)\n    if match:\n      num_layers = max(num_layers, int(match.group(1)))\n\n  # Build a new parser so we catch unknown args and missing layer_sizes.\n  parser = argparse.ArgumentParser()\n  for i in range(num_layers):\n    parser.add_argument('--layer-size%s' % str(i + 1), type=int, required=True)\n\n  layer_args = vars(parser.parse_args(args=remaining_args))\n  layer_sizes = []\n  for i in range(num_layers):\n    key = 'layer_size%s' % str(i + 1)\n    layer_sizes.append(layer_args[key])\n\n  assert len(layer_sizes) == num_layers\n  args.layer_sizes = layer_sizes\n\n  return args\n\n\ndef main(argv=None):\n  \"\"\"Run a Tensorflow model on the Iris dataset.\"\"\"\n  args = parse_arguments(sys.argv if argv is None else argv)\n\n  tf.logging.set_verbosity(tf.logging.INFO)\n  learn_runner.run(\n      experiment_fn=get_experiment_fn(args),\n      output_dir=args.job_dir)\n\n\nif __name__ == '__main__':\n  main()\n"
  },
  {
    "path": "solutionbox/structured_data/mltoolbox/_structured_data/trainer/util.py",
    "content": "# Copyright 2017 Google Inc. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n# ==============================================================================\n\nimport json\nimport multiprocessing\nimport os\nimport math\nimport six\n\nimport tensorflow as tf\nfrom tensorflow.python.lib.io import file_io\n\nfrom tensorflow.contrib.learn.python.learn.utils import input_fn_utils\nfrom tensorflow.contrib.learn.python.learn import export_strategy\nfrom tensorflow.contrib.learn.python.learn.utils import (\n    saved_model_export_utils)\n\nfrom tensorflow.python.ops import resources\nfrom tensorflow.python.ops import variables\nfrom tensorflow.contrib.framework.python.ops import variables as contrib_variables\nfrom tensorflow.contrib.learn.python.learn.estimators import model_fn as model_fn_lib\nfrom tensorflow.python.training import saver\nfrom tensorflow.python.framework import ops\nfrom tensorflow.python.client import session as tf_session\nfrom tensorflow.python.saved_model import builder as saved_model_builder\nfrom tensorflow.python.saved_model import tag_constants\nfrom tensorflow.python.ops import control_flow_ops\nfrom tensorflow.python.util import compat\nfrom tensorflow.python.platform import gfile\nfrom tensorflow.python.saved_model import signature_def_utils\n\n\nSCHEMA_FILE = 'schema.json'\nNUMERICAL_ANALYSIS = 'stats.json'\nCATEGORICAL_ANALYSIS = 'vocab_%s.csv'\n\n\n# Constants for the Prediction Graph fetch tensors.\nPG_TARGET = 'target'  # from input\n\nPG_REGRESSION_PREDICTED_TARGET = 'predicted'\n\nPG_CLASSIFICATION_FIRST_LABEL = 'predicted'\nPG_CLASSIFICATION_FIRST_SCORE = 'score'\nPG_CLASSIFICATION_LABEL_TEMPLATE = 'predicted_%s'\nPG_CLASSIFICATION_SCORE_TEMPLATE = 'score_%s'\n\n\nclass NotFittedError(ValueError):\n    pass\n\n# ==============================================================================\n# Functions for saving the exported graphs.\n# ==============================================================================\n\n\ndef _recursive_copy(src_dir, dest_dir):\n  \"\"\"Copy the contents of src_dir into the folder dest_dir.\n  Args:\n    src_dir: gsc or local path.\n    dest_dir: gcs or local path.\n  When called, dest_dir should exist.\n  \"\"\"\n  src_dir = python_portable_string(src_dir)\n  dest_dir = python_portable_string(dest_dir)\n\n  file_io.recursive_create_dir(dest_dir)\n  for file_name in file_io.list_directory(src_dir):\n    old_path = os.path.join(src_dir, file_name)\n    new_path = os.path.join(dest_dir, file_name)\n\n    if file_io.is_directory(old_path):\n      _recursive_copy(old_path, new_path)\n    else:\n      file_io.copy(old_path, new_path, overwrite=True)\n\n\ndef serving_from_csv_input(train_config, args, keep_target):\n  \"\"\"Read the input features from a placeholder csv string tensor.\"\"\"\n  examples = tf.placeholder(\n      dtype=tf.string,\n      shape=(None,),\n      name='csv_input_string')\n\n  features = parse_example_tensor(examples=examples,\n                                  train_config=train_config,\n                                  keep_target=keep_target)\n\n  if keep_target:\n    target = features.pop(train_config['target_column'])\n  else:\n    target = None\n  features, target = preprocess_input(\n      features=features,\n      target=target,\n      train_config=train_config,\n      preprocess_output_dir=args.preprocess_output_dir,\n      model_type=args.model_type)\n\n  return input_fn_utils.InputFnOps(features,\n                                   target,\n                                   {'csv_line': examples}\n                                   )\n\n\ndef make_output_tensors(train_config, args, input_ops, model_fn_ops, keep_target=True):\n    target_name = train_config['target_column']\n    key_name = train_config['key_column']\n\n    outputs = {}\n    outputs[key_name] = tf.squeeze(input_ops.features[key_name])\n\n    if is_classification_model(args.model_type):\n\n      # build maps from ints to the origional categorical strings.\n      string_value = get_vocabulary(args.preprocess_output_dir, target_name)\n      table = tf.contrib.lookup.index_to_string_table_from_tensor(\n          mapping=string_value,\n          default_value='UNKNOWN')\n\n      # Get the label of the input target.\n      if keep_target:\n        input_target_label = table.lookup(input_ops.labels)\n        outputs[PG_TARGET] = tf.squeeze(input_target_label)\n\n      # TODO(brandondutra): get the score of the target label too.\n      probabilities = model_fn_ops.predictions['probabilities']\n\n      # get top k labels and their scores.\n      (top_k_values, top_k_indices) = tf.nn.top_k(probabilities, k=args.top_n)\n      top_k_labels = table.lookup(tf.to_int64(top_k_indices))\n\n      # Write the top_k values using 2*top_k columns.\n      num_digits = int(math.ceil(math.log(args.top_n, 10)))\n      if num_digits == 0:\n        num_digits = 1\n      for i in range(0, args.top_n):\n        # Pad i based on the size of k. So if k = 100, i = 23 -> i = '023'. This\n        # makes sorting the columns easy.\n        padded_i = str(i + 1).zfill(num_digits)\n\n        if i == 0:\n          label_alias = PG_CLASSIFICATION_FIRST_LABEL\n        else:\n          label_alias = PG_CLASSIFICATION_LABEL_TEMPLATE % padded_i\n\n        label_tensor_name = (tf.squeeze(\n            tf.slice(top_k_labels, [0, i], [tf.shape(top_k_labels)[0], 1])))\n\n        if i == 0:\n          score_alias = PG_CLASSIFICATION_FIRST_SCORE\n        else:\n          score_alias = PG_CLASSIFICATION_SCORE_TEMPLATE % padded_i\n\n        score_tensor_name = (tf.squeeze(\n            tf.slice(top_k_values,\n                     [0, i],\n                     [tf.shape(top_k_values)[0], 1])))\n\n        outputs.update({label_alias: label_tensor_name,\n                        score_alias: score_tensor_name})\n\n    else:\n      if keep_target:\n        outputs[PG_TARGET] = tf.squeeze(input_ops.labels)\n\n      scores = model_fn_ops.predictions['scores']\n      outputs[PG_REGRESSION_PREDICTED_TARGET] = tf.squeeze(scores)\n\n    return outputs\n\n\ndef make_export_strategy(train_config, args, keep_target, assets_extra=None):\n  def export_fn(estimator, export_dir_base, checkpoint_path=None, eval_result=None):\n    with ops.Graph().as_default() as g:\n      contrib_variables.create_global_step(g)\n\n      input_ops = serving_from_csv_input(train_config, args, keep_target)\n      model_fn_ops = estimator._call_model_fn(input_ops.features,\n                                              None,\n                                              model_fn_lib.ModeKeys.INFER)\n      output_fetch_tensors = make_output_tensors(\n          train_config=train_config,\n          args=args,\n          input_ops=input_ops,\n          model_fn_ops=model_fn_ops,\n          keep_target=keep_target)\n\n      signature_def_map = {\n        'serving_default': signature_def_utils.predict_signature_def(input_ops.default_inputs,\n                                                                     output_fetch_tensors)\n      }\n\n      if not checkpoint_path:\n        # Locate the latest checkpoint\n        checkpoint_path = saver.latest_checkpoint(estimator._model_dir)\n      if not checkpoint_path:\n        raise NotFittedError(\"Couldn't find trained model at %s.\"\n                             % estimator._model_dir)\n\n      export_dir = saved_model_export_utils.get_timestamped_export_dir(\n          export_dir_base)\n\n      if (model_fn_ops.scaffold is not None and\n         model_fn_ops.scaffold.saver is not None):\n        saver_for_restore = model_fn_ops.scaffold.saver\n      else:\n        saver_for_restore = saver.Saver(sharded=True)\n\n      with tf_session.Session('') as session:\n        saver_for_restore.restore(session, checkpoint_path)\n        init_op = control_flow_ops.group(\n            variables.local_variables_initializer(),\n            resources.initialize_resources(resources.shared_resources()),\n            tf.tables_initializer())\n\n        # Perform the export\n        builder = saved_model_builder.SavedModelBuilder(export_dir)\n        builder.add_meta_graph_and_variables(\n            session, [tag_constants.SERVING],\n            signature_def_map=signature_def_map,\n            assets_collection=ops.get_collection(\n                ops.GraphKeys.ASSET_FILEPATHS),\n            legacy_init_op=init_op)\n        builder.save(False)\n\n      # Add the extra assets\n      if assets_extra:\n        assets_extra_path = os.path.join(compat.as_bytes(export_dir),\n                                         compat.as_bytes('assets.extra'))\n        for dest_relative, source in assets_extra.items():\n          dest_absolute = os.path.join(compat.as_bytes(assets_extra_path),\n                                       compat.as_bytes(dest_relative))\n          dest_path = os.path.dirname(dest_absolute)\n          gfile.MakeDirs(dest_path)\n          gfile.Copy(source, dest_absolute)\n\n    # only keep the last 3 models\n    saved_model_export_utils.garbage_collect_exports(\n        python_portable_string(export_dir_base),\n        exports_to_keep=3)\n\n    # save the last model to the model folder.\n    # export_dir_base = A/B/intermediate_models/\n    if keep_target:\n      final_dir = os.path.join(args.job_dir, 'evaluation_model')\n    else:\n      final_dir = os.path.join(args.job_dir, 'model')\n    if file_io.is_directory(final_dir):\n      file_io.delete_recursively(final_dir)\n    file_io.recursive_create_dir(final_dir)\n    _recursive_copy(export_dir, final_dir)\n\n    return export_dir\n\n  if keep_target:\n    intermediate_dir = 'intermediate_evaluation_models'\n  else:\n    intermediate_dir = 'intermediate_prediction_models'\n\n  return export_strategy.ExportStrategy(intermediate_dir, export_fn)\n\n\n# ==============================================================================\n# Reading the input csv files and parsing its output into tensors.\n# ==============================================================================\n\n\ndef parse_example_tensor(examples, train_config, keep_target):\n  \"\"\"Read the csv files.\n\n  Args:\n    examples: string tensor\n    train_config: training config\n    keep_target: if true, the target column is expected to exist and it is\n        returned in the features dict.\n\n  Returns:\n    Dict of feature_name to tensor. Target feature is in the dict.\n  \"\"\"\n\n  csv_header = []\n  if keep_target:\n    csv_header = train_config['csv_header']\n  else:\n    csv_header = [name for name in train_config['csv_header']\n                  if name != train_config['target_column']]\n\n  # record_defaults are used by tf.decode_csv to insert defaults, and to infer\n  # the datatype.\n  record_defaults = [[train_config['csv_defaults'][name]]\n                     for name in csv_header]\n  tensors = tf.decode_csv(examples, record_defaults, name='csv_to_tensors')\n\n  # I'm not really sure why expand_dims needs to be called. If using regression\n  # models, it errors without it.\n  tensors = [tf.expand_dims(x, axis=1) for x in tensors]\n\n  tensor_dict = dict(zip(csv_header, tensors))\n  return tensor_dict\n\n\ndef read_examples(input_files, batch_size, shuffle, num_epochs=None):\n  \"\"\"Creates readers and queues for reading example protos.\"\"\"\n  files = []\n  for e in input_files:\n    for path in e.split(','):\n      files.extend(file_io.get_matching_files(path))\n  thread_count = multiprocessing.cpu_count()\n\n  # The minimum number of instances in a queue from which examples are drawn\n  # randomly. The larger this number, the more randomness at the expense of\n  # higher memory requirements.\n  min_after_dequeue = 1000\n\n  # When batching data, the queue's capacity will be larger than the batch_size\n  # by some factor. The recommended formula is (num_threads + a small safety\n  # margin). For now, we use a single thread for reading, so this can be small.\n  queue_size_multiplier = thread_count + 3\n\n  # Convert num_epochs == 0 -> num_epochs is None, if necessary\n  num_epochs = num_epochs or None\n\n  # Build a queue of the filenames to be read.\n  filename_queue = tf.train.string_input_producer(files, num_epochs, shuffle)\n\n  example_id, encoded_example = tf.TextLineReader().read_up_to(\n      filename_queue, batch_size)\n\n  if shuffle:\n    capacity = min_after_dequeue + queue_size_multiplier * batch_size\n    return tf.train.shuffle_batch(\n        [example_id, encoded_example],\n        batch_size,\n        capacity,\n        min_after_dequeue,\n        enqueue_many=True,\n        num_threads=thread_count)\n\n  else:\n    capacity = queue_size_multiplier * batch_size\n    return tf.train.batch(\n        [example_id, encoded_example],\n        batch_size,\n        capacity=capacity,\n        enqueue_many=True,\n        num_threads=thread_count)\n\n\n# ==============================================================================\n# Building the TF learn estimators\n# ==============================================================================\n\n\ndef get_estimator(output_dir, train_config, args):\n  \"\"\"Returns a tf learn estimator.\n\n  We only support {DNN, Linear}Regressor and {DNN, Linear}Classifier. This is\n  controlled by the values of model_type in the args.\n\n  Args:\n    output_dir: Modes are saved into outputdir/train\n    train_config: our training config\n    args: command line parameters\n\n  Returns:\n    TF lean estimator\n\n  Raises:\n    ValueError: if config is wrong.\n  \"\"\"\n\n  # Check the requested mode fits the preprocessed data.\n  target_name = train_config['target_column']\n  if is_classification_model(args.model_type) and target_name not in \\\n          train_config['categorical_columns']:\n    raise ValueError('When using a classification model, the target must be a '\n                     'categorical variable.')\n  if is_regression_model(args.model_type) and target_name not in \\\n          train_config['numerical_columns']:\n    raise ValueError('When using a regression model, the target must be a '\n                     'numerical variable.')\n\n  # Check layers used for dnn models.\n  if is_dnn_model(args.model_type) and not args.layer_sizes:\n    raise ValueError('--layer-size* must be used with DNN models')\n  if is_linear_model(args.model_type) and args.layer_sizes:\n    raise ValueError('--layer-size* cannot be used with linear models')\n\n  # Build tf.learn features\n  feature_columns = _tflearn_features(train_config, args)\n\n  # Set how often to run checkpointing in terms of time.\n  config = tf.contrib.learn.RunConfig(\n      save_checkpoints_secs=args.save_checkpoints_secs)\n\n  train_dir = os.path.join(output_dir, 'train')\n  if args.model_type == 'dnn_regression':\n    estimator = tf.contrib.learn.DNNRegressor(\n        feature_columns=feature_columns,\n        hidden_units=args.layer_sizes,\n        config=config,\n        model_dir=train_dir,\n        optimizer=tf.train.AdamOptimizer(\n            args.learning_rate, epsilon=args.epsilon))\n  elif args.model_type == 'linear_regression':\n    estimator = tf.contrib.learn.LinearRegressor(\n        feature_columns=feature_columns,\n        config=config,\n        model_dir=train_dir,\n        optimizer=tf.train.AdamOptimizer(\n            args.learning_rate, epsilon=args.epsilon))\n  elif args.model_type == 'dnn_classification':\n    estimator = tf.contrib.learn.DNNClassifier(\n        feature_columns=feature_columns,\n        hidden_units=args.layer_sizes,\n        n_classes=train_config['vocab_stats'][target_name]['n_classes'],\n        config=config,\n        model_dir=train_dir,\n        optimizer=tf.train.AdamOptimizer(\n            args.learning_rate, epsilon=args.epsilon))\n  elif args.model_type == 'linear_classification':\n    estimator = tf.contrib.learn.LinearClassifier(\n        feature_columns=feature_columns,\n        n_classes=train_config['vocab_stats'][target_name]['n_classes'],\n        config=config,\n        model_dir=train_dir,\n        optimizer=tf.train.AdamOptimizer(\n            args.learning_rate, epsilon=args.epsilon))\n  else:\n    raise ValueError('bad --model-type value')\n\n  return estimator\n\n\ndef preprocess_input(features, target, train_config, preprocess_output_dir,\n                     model_type):\n  \"\"\"Perform some transformations after reading in the input tensors.\n\n  Args:\n    features: dict of feature_name to tensor\n    target: tensor\n    train_config: our training config object\n    preprocess_output_dir: folder should contain the vocab files.\n    model_type: the tf model type.\n\n  Raises:\n    ValueError: if wrong transforms are used\n\n  Returns:\n    New features dict and new target tensor.\n  \"\"\"\n\n  target_name = train_config['target_column']\n  key_name = train_config['key_column']\n\n  # Do the numerical transforms.\n  # Numerical transforms supported for regression/classification\n  # 1) num -> do nothing (identity, default)\n  # 2) num -> scale to -1, 1 (scale)\n  # 3) num -> scale to -a, a (scale with value parameter)\n  with tf.name_scope('numerical_feature_preprocess'):\n    if train_config['numerical_columns']:\n      numerical_analysis_file = os.path.join(preprocess_output_dir,\n                                             NUMERICAL_ANALYSIS)\n      if not file_io.file_exists(numerical_analysis_file):\n        raise ValueError('File %s not found in %s' %\n                         (NUMERICAL_ANALYSIS, preprocess_output_dir))\n\n      numerical_anlysis = json.loads(\n          python_portable_string(\n              file_io.read_file_to_string(numerical_analysis_file)))\n\n      for name in train_config['numerical_columns']:\n        if name == target_name or name == key_name:\n          continue\n\n        transform_config = train_config['transforms'].get(name, {})\n        transform_name = transform_config.get('transform', None)\n        if transform_name == 'scale':\n          value = float(transform_config.get('value', 1.0))\n          features[name] = _scale_tensor(\n              features[name],\n              range_min=numerical_anlysis[name]['min'],\n              range_max=numerical_anlysis[name]['max'],\n              scale_min=-value,\n              scale_max=value)\n        elif transform_name == 'identity' or transform_name is None:\n          pass\n        else:\n          raise ValueError(('For numerical variables, only scale '\n                            'and identity are supported: '\n                            'Error for %s') % name)\n\n  # Do target transform if it exists.\n  if target is not None:\n    with tf.name_scope('target_feature_preprocess'):\n      if target_name in train_config['categorical_columns']:\n        labels = train_config['vocab_stats'][target_name]['labels']\n        table = tf.contrib.lookup.string_to_index_table_from_tensor(labels)\n        target = table.lookup(target)\n        # target = tf.contrib.lookup.string_to_index(target, labels)\n\n  # Do categorical transforms. Only apply vocab mapping. The real\n  # transforms are done with tf learn column features.\n  with tf.name_scope('categorical_feature_preprocess'):\n    for name in train_config['categorical_columns']:\n      if name == key_name or name == target_name:\n        continue\n      transform_config = train_config['transforms'].get(name, {})\n      transform_name = transform_config.get('transform', None)\n\n      if is_dnn_model(model_type):\n        if transform_name == 'embedding' or transform_name == 'one_hot' or transform_name is None:\n          map_vocab = True\n        else:\n          raise ValueError('Unknown transform %s' % transform_name)\n      elif is_linear_model(model_type):\n        if (transform_name == 'one_hot' or transform_name is None):\n          map_vocab = True\n        elif transform_name == 'embedding':\n          map_vocab = False\n        else:\n          raise ValueError('Unknown transform %s' % transform_name)\n      if map_vocab:\n        labels = train_config['vocab_stats'][name]['labels']\n        table = tf.contrib.lookup.string_to_index_table_from_tensor(labels)\n        features[name] = table.lookup(features[name])\n\n  return features, target\n\n\ndef _scale_tensor(tensor, range_min, range_max, scale_min, scale_max):\n  \"\"\"Scale a tensor to scale_min to scale_max.\n\n  Args:\n    tensor: input tensor. Should be a numerical tensor.\n    range_min: min expected value for this feature/tensor.\n    range_max: max expected Value.\n    scale_min: new expected min value.\n    scale_max: new expected max value.\n\n  Returns:\n    scaled tensor.\n  \"\"\"\n  if range_min == range_max:\n    return tensor\n\n  float_tensor = tf.to_float(tensor)\n  scaled_tensor = tf.divide((tf.subtract(float_tensor, range_min) *\n                             tf.constant(float(scale_max - scale_min))),\n                            tf.constant(float(range_max - range_min)))\n  shifted_tensor = scaled_tensor + tf.constant(float(scale_min))\n\n  return shifted_tensor\n\n\ndef _tflearn_features(train_config, args):\n  \"\"\"Builds the tf.learn feature list.\n\n  All numerical features are just given real_valued_column because all the\n  preprocessing transformations are done in preprocess_input. Categoriacl\n  features are processed here depending if the vocab map (from string to int)\n  was applied in preprocess_input.\n\n  Args:\n    train_config: our train config object\n    args: command line args.\n\n  Returns:\n    List of TF lean feature columns.\n\n  Raises:\n    ValueError: if wrong transforms are used for the model type.\n  \"\"\"\n  feature_columns = []\n  target_name = train_config['target_column']\n  key_name = train_config['key_column']\n\n  for name in train_config['numerical_columns']:\n    if name != target_name and name != key_name:\n      feature_columns.append(tf.contrib.layers.real_valued_column(\n          name,\n          dimension=1))\n\n      # Supported transforms:\n      # for DNN\n      # 1) string -> make int -> embedding (embedding)\n      # 2) string -> make int -> one_hot (one_hot, default)\n      # for linear\n      # 1) string -> sparse_column_with_hash_bucket (embedding)\n      # 2) string -> make int -> sparse_column_with_integerized_feature (one_hot, default)\n      # It is unfortunate that tf.layers has different feature transforms if the\n      # model is linear or DNN. This pacakge should not expose to the user that\n      # we are using tf.layers. It is crazy that DNN models support more feature\n      # types (like string -> hash sparse column -> embedding)\n  for name in train_config['categorical_columns']:\n    if name != target_name and name != key_name:\n      transform_config = train_config['transforms'].get(name, {})\n      transform_name = transform_config.get('transform', None)\n\n      if is_dnn_model(args.model_type):\n        if transform_name == 'embedding':\n          sparse = tf.contrib.layers.sparse_column_with_integerized_feature(\n              name,\n              bucket_size=train_config['vocab_stats'][name]['n_classes'])\n          learn_feature = tf.contrib.layers.embedding_column(\n              sparse,\n              dimension=transform_config['embedding_dim'])\n        elif transform_name == 'one_hot' or transform_name is None:\n          sparse = tf.contrib.layers.sparse_column_with_integerized_feature(\n              name,\n              bucket_size=train_config['vocab_stats'][name]['n_classes'])\n          learn_feature = tf.contrib.layers.one_hot_column(sparse)\n        else:\n          raise ValueError(('Unknown transform name. Only \\'embedding\\' '\n                            'and \\'one_hot\\' transforms are supported. Got %s')\n                           % transform_name)\n      elif is_linear_model(args.model_type):\n        if transform_name == 'one_hot' or transform_name is None:\n          learn_feature = tf.contrib.layers.sparse_column_with_integerized_feature(\n              name,\n              bucket_size=train_config['vocab_stats'][name]['n_classes'])\n        elif transform_name == 'embedding':\n          learn_feature = tf.contrib.layers.sparse_column_with_hash_bucket(\n              name,\n              hash_bucket_size=transform_config['embedding_dim'])\n        else:\n          raise ValueError(('Unknown transform name. Only \\'embedding\\' '\n                            'and \\'one_hot\\' transforms are supported. Got %s')\n                           % transform_name)\n\n      # Save the feature\n      feature_columns.append(learn_feature)\n  return feature_columns\n\n\n# ==============================================================================\n# Functions for dealing with the parameter files.\n# ==============================================================================\n\n\ndef get_vocabulary(preprocess_output_dir, name):\n  \"\"\"Loads the vocabulary file as a list of strings.\n\n  Args:\n    preprocess_output_dir: Should contain the file CATEGORICAL_ANALYSIS % name.\n    name: name of the csv column.\n\n  Returns:\n    List of strings.\n\n  Raises:\n    ValueError: if file is missing.\n  \"\"\"\n  vocab_file = os.path.join(preprocess_output_dir, CATEGORICAL_ANALYSIS % name)\n  if not file_io.file_exists(vocab_file):\n    raise ValueError('File %s not found in %s' %\n                     (CATEGORICAL_ANALYSIS % name, preprocess_output_dir))\n\n  labels = python_portable_string(\n      file_io.read_file_to_string(vocab_file)).split('\\n')\n  label_values = [x for x in labels if x]  # remove empty lines\n\n  return label_values\n\n\ndef merge_metadata(preprocess_output_dir, transforms_file):\n  \"\"\"Merge schema, analysis, and transforms files into one python object.\n\n  Args:\n    preprocess_output_dir: the output folder of preprocessing. Should contain\n        the schema, and the numerical and categorical\n        analysis files.\n    transforms_file: the training transforms file.\n\n  Returns:\n    A dict in the form\n    {\n      csv_header: [name1, name2, ...],\n      csv_defaults: {name1: value, name2: value},\n      key_column: name,\n      target_column: name,\n      categorical_columns: []\n      numerical_columns: []\n      transforms: { name1: {transform: scale, value: 2},\n                    name2: {transform: embedding, dim: 50}, ...\n                  }\n      vocab_stats: { name3: {n_classes: 23, labels: ['1', '2', ..., '23']},\n                     name4: {n_classes: 102, labels: ['red', 'blue', ...]}}\n    }\n\n  Raises:\n    ValueError: if one of the input metadata files is wrong.\n  \"\"\"\n  numerical_anlysis_file = os.path.join(preprocess_output_dir,\n                                        NUMERICAL_ANALYSIS)\n  schema_file = os.path.join(preprocess_output_dir, SCHEMA_FILE)\n\n  numerical_anlysis = json.loads(\n      python_portable_string(\n          file_io.read_file_to_string(numerical_anlysis_file)))\n  schema = json.loads(\n      python_portable_string(file_io.read_file_to_string(schema_file)))\n  transforms = json.loads(\n      python_portable_string(file_io.read_file_to_string(transforms_file)))\n\n  result_dict = {}\n  result_dict['csv_header'] = [col_schema['name'] for col_schema in schema]\n  result_dict['key_column'] = None\n  result_dict['target_column'] = None\n  result_dict['categorical_columns'] = []\n  result_dict['numerical_columns'] = []\n  result_dict['transforms'] = {}\n  result_dict['csv_defaults'] = {}\n  result_dict['vocab_stats'] = {}\n\n  # get key column.\n  for name, trans_config in six.iteritems(transforms):\n    if trans_config.get('transform', None) == 'key':\n      result_dict['key_column'] = name\n      break\n  if result_dict['key_column'] is None:\n    raise ValueError('Key transform missing form transfroms file.')\n\n  # get target column.\n  result_dict['target_column'] = schema[0]['name']\n  for name, trans_config in six.iteritems(transforms):\n    if trans_config.get('transform', None) == 'target':\n      result_dict['target_column'] = name\n      break\n  if result_dict['target_column'] is None:\n    raise ValueError('Target transform missing from transforms file.')\n\n  # Get the numerical/categorical columns.\n  for col_schema in schema:\n    col_name = col_schema['name']\n    col_type = col_schema['type'].lower()\n    if col_name == result_dict['key_column']:\n      continue\n\n    if col_type == 'string':\n      result_dict['categorical_columns'].append(col_name)\n    elif col_type == 'integer' or col_type == 'float':\n      result_dict['numerical_columns'].append(col_name)\n    else:\n      raise ValueError('Unsupported schema type %s' % col_type)\n\n  # Get the transforms.\n  for name, trans_config in six.iteritems(transforms):\n    if name != result_dict['target_column'] and name != result_dict['key_column']:\n      result_dict['transforms'][name] = trans_config\n\n  # Get the vocab_stats\n  for name in result_dict['categorical_columns']:\n    if name == result_dict['key_column']:\n      continue\n\n    label_values = get_vocabulary(preprocess_output_dir, name)\n    if name != result_dict['target_column'] and '' not in label_values:\n      label_values.append('')  # append a 'missing' label.\n    n_classes = len(label_values)\n    result_dict['vocab_stats'][name] = {'n_classes': n_classes,\n                                        'labels': label_values}\n\n  # Get the csv_defaults\n  for col_schema in schema:\n    name = col_schema['name']\n    col_type = col_schema['type'].lower()\n    default = transforms.get(name, {}).get('default', None)\n\n    if name == result_dict['target_column']:\n      if name in result_dict['numerical_columns']:\n        default = float(default or 0.0)\n      else:\n        default = default or ''\n    elif name == result_dict['key_column']:\n      if col_type == 'string':\n        default = str(default or '')\n      elif col_type == 'float':\n        default = float(default or 0.0)\n      else:\n        default = int(default or 0)\n    else:\n      if col_type == 'string':\n        default = str(default or '')\n        if default not in result_dict['vocab_stats'][name]['labels']:\n          raise ValueError('Default %s is not in the vocab for %s' %\n                           (default, name))\n      else:\n        default = float(default or numerical_anlysis[name]['mean'])\n\n    result_dict['csv_defaults'][name] = default\n\n  validate_metadata(result_dict)\n  return result_dict\n\n\ndef validate_metadata(train_config):\n  \"\"\"Perform some checks that the trainig config is correct.\n\n  Args:\n    train_config: train config as produced by merge_metadata()\n\n  Raises:\n    ValueError: if columns look wrong.\n  \"\"\"\n\n  # Make sure we have a default for every column\n  if len(train_config['csv_header']) != len(train_config['csv_defaults']):\n    raise ValueError('Unequal number of columns in input features file and '\n                     'schema file.')\n\n  # Check there are no missing columns. sorted_colums has two copies of the\n  # target column because the target column is also listed in\n  # categorical_columns or numerical_columns.\n  sorted_columns = sorted(train_config['csv_header'] +\n                          [train_config['target_column']])\n\n  sorted_columns2 = sorted(train_config['categorical_columns'] +\n                           train_config['numerical_columns'] +\n                           [train_config['key_column']] +\n                           [train_config['target_column']])\n  if sorted_columns2 != sorted_columns:\n    raise ValueError('Each csv header must be a numerical/categorical type, a '\n                     ' key, or a target.')\n\n\ndef is_linear_model(model_type):\n  return model_type.startswith('linear_')\n\n\ndef is_dnn_model(model_type):\n  return model_type.startswith('dnn_')\n\n\ndef is_regression_model(model_type):\n  return model_type.endswith('_regression')\n\n\ndef is_classification_model(model_type):\n  return model_type.endswith('_classification')\n\n\n# Note that this function exists in google.datalab.utils, but that is not\n# installed on the training workers.\ndef python_portable_string(string, encoding='utf-8'):\n  \"\"\"Converts bytes into a string type.\n\n  Valid string types are retuned without modification. So in Python 2, type str\n  and unicode are not converted.\n\n  In Python 3, type bytes is converted to type str (unicode)\n  \"\"\"\n  if isinstance(string, six.string_types):\n    return string\n\n  if six.PY3:\n    return string.decode(encoding)\n\n  raise ValueError('Unsupported type %s' % str(type(string)))\n"
  },
  {
    "path": "solutionbox/structured_data/mltoolbox/classification/__init__.py",
    "content": "# Copyright 2017 Google Inc. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n# ==============================================================================\n\nfrom mltoolbox._structured_data.__version__ import __version__\n\n__all__ = ['__version__']\n"
  },
  {
    "path": "solutionbox/structured_data/mltoolbox/classification/dnn/__init__.py",
    "content": "# Copyright 2017 Google Inc. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n# ==============================================================================\n\n\"\"\"This module contains functions for classification problems modeled as a fully connected\nfeedforward deep neural network.\n\nEvery function can run locally or use Google Cloud Platform.\n\"\"\"\n\nfrom ._classification_dnn import train, train_async\nfrom mltoolbox._structured_data import analyze, analyze_async, predict, batch_predict, \\\n    batch_predict_async\nfrom mltoolbox._structured_data.__version__ import __version__\n\n__all__ = ['train', 'train_async', 'analyze', 'analyze_async', 'predict', 'batch_predict',\n           'batch_predict_async', '__version__']\n"
  },
  {
    "path": "solutionbox/structured_data/mltoolbox/classification/dnn/_classification_dnn.py",
    "content": "from mltoolbox._structured_data import train_async as core_train\n\n\ndef train(train_dataset,\n          eval_dataset,\n          analysis_dir,\n          output_dir,\n          features,\n          layer_sizes,\n          max_steps=5000,\n          num_epochs=None,\n          train_batch_size=100,\n          eval_batch_size=16,\n          min_eval_frequency=100,\n          top_n=None,\n          learning_rate=0.01,\n          epsilon=0.0005,\n          job_name=None,\n          cloud=None,\n          ):\n  \"\"\"Blocking version of train_async. See documentation for train_async.\"\"\"\n  job = train_async(\n      train_dataset=train_dataset,\n      eval_dataset=eval_dataset,\n      analysis_dir=analysis_dir,\n      output_dir=output_dir,\n      features=features,\n      layer_sizes=layer_sizes,\n      max_steps=max_steps,\n      num_epochs=num_epochs,\n      train_batch_size=train_batch_size,\n      eval_batch_size=eval_batch_size,\n      min_eval_frequency=min_eval_frequency,\n      top_n=top_n,\n      learning_rate=learning_rate,\n      epsilon=epsilon,\n      job_name=job_name,\n      cloud=cloud,\n  )\n  job.wait()\n  print('Training: ' + str(job.state))\n\n\ndef train_async(train_dataset,\n                eval_dataset,\n                analysis_dir,\n                output_dir,\n                features,\n                layer_sizes,\n                max_steps=5000,\n                num_epochs=None,\n                train_batch_size=100,\n                eval_batch_size=16,\n                min_eval_frequency=100,\n                top_n=None,\n                learning_rate=0.01,\n                epsilon=0.0005,\n                job_name=None,\n                cloud=None,\n                ):\n  \"\"\"Train model locally or in the cloud.\n\n  Local Training:\n\n  Args:\n    train_dataset: CsvDataSet\n    eval_dataset: CsvDataSet\n    analysis_dir:  The output directory from local_analysis\n    output_dir:  Output directory of training.\n    features: file path or features object. Example:\n        {\n          \"col_A\": {\"transform\": \"scale\", \"default\": 0.0},\n          \"col_B\": {\"transform\": \"scale\",\"value\": 4},\n          # Note col_C is missing, so default transform used.\n          \"col_D\": {\"transform\": \"hash_one_hot\", \"hash_bucket_size\": 4},\n          \"col_target\": {\"transform\": \"target\"},\n          \"col_key\": {\"transform\": \"key\"}\n        }\n        The keys correspond to the columns in the input files as defined by the\n        schema file during preprocessing. Some notes\n        1) The \"key\" and \"target\" transforms are required.\n        2) Default values are optional. These are used if the input data has\n           missing values during training and prediction. If not supplied for a\n           column, the default value for a numerical column is that column's\n           mean vlaue, and for a categorical column the empty string is used.\n        3) For numerical colums, the following transforms are supported:\n           i) {\"transform\": \"identity\"}: does nothing to the number. (default)\n           ii) {\"transform\": \"scale\"}: scales the colum values to -1, 1.\n           iii) {\"transform\": \"scale\", \"value\": a}: scales the colum values\n              to -a, a.\n\n           For categorical colums, the following transforms are supported:\n          i) {\"transform\": \"one_hot\"}: A one-hot vector using the full\n              vocabulary is used. (default)\n          ii) {\"transform\": \"embedding\", \"embedding_dim\": d}: Each label is\n              embedded into an d-dimensional space.\n    max_steps: Int. Number of training steps to perform.\n    num_epochs: Maximum number of training data epochs on which to train.\n        The training job will run for max_steps or num_epochs, whichever occurs\n        first.\n    train_batch_size: number of rows to train on in one step.\n    eval_batch_size: number of rows to eval in one step. One pass of the eval\n        dataset is done. If eval_batch_size does not perfectly divide the numer\n        of eval instances, the last fractional batch is not used.\n    min_eval_frequency: Minimum number of training steps between evaluations.\n    top_n: Int. For classification problems, the output graph will contain the\n        labels and scores for the top n classes with a default of n=1. Use\n        None for regression problems.\n    layer_sizes: List. Represents the layers in the connected DNN.\n        If the model type is DNN, this must be set. Example [10, 3, 2], this\n        will create three DNN layers where the first layer will have 10 nodes,\n        the middle layer will have 3 nodes, and the laster layer will have 2\n        nodes.\n    learning_rate: tf.train.AdamOptimizer's learning rate,\n    epsilon: tf.train.AdamOptimizer's epsilon value.\n\n  Cloud Training:\n\n  All local training arguments are valid for cloud training. Cloud training\n  contains two additional args:\n\n  Args:\n    cloud: A CloudTrainingConfig object.\n    job_name: Training job name. A default will be picked if None.\n\n  Returns:\n    Datalab job\n  \"\"\"\n  return core_train(\n      train_dataset=train_dataset,\n      eval_dataset=eval_dataset,\n      analysis_dir=analysis_dir,\n      output_dir=output_dir,\n      features=features,\n      model_type='dnn_classification',\n      max_steps=max_steps,\n      num_epochs=num_epochs,\n      train_batch_size=train_batch_size,\n      eval_batch_size=eval_batch_size,\n      min_eval_frequency=min_eval_frequency,\n      top_n=top_n,\n      layer_sizes=layer_sizes,\n      learning_rate=learning_rate,\n      epsilon=epsilon,\n      job_name=job_name,\n      job_name_prefix='mltoolbox_classification_dnn',\n      cloud=cloud,\n  )\n"
  },
  {
    "path": "solutionbox/structured_data/mltoolbox/classification/linear/__init__.py",
    "content": "\"\"\"This module contains functions for multinomial logistic regression problems.\n\nEvery function can run locally or use Google Cloud Platform.\n\"\"\"\n\nfrom ._classification_linear import train, train_async\nfrom mltoolbox._structured_data import analyze, analyze_async, predict, batch_predict, \\\n    batch_predict_async\nfrom mltoolbox._structured_data.__version__ import __version__\n\n__all__ = ['train', 'train_async', 'analyze', 'analyze_async', 'predict', 'batch_predict',\n           'batch_predict_async', '__version__']\n"
  },
  {
    "path": "solutionbox/structured_data/mltoolbox/classification/linear/_classification_linear.py",
    "content": "from mltoolbox._structured_data import train_async as core_train\n\n\ndef train(train_dataset,\n          eval_dataset,\n          analysis_dir,\n          output_dir,\n          features,\n          max_steps=5000,\n          num_epochs=None,\n          train_batch_size=100,\n          eval_batch_size=16,\n          min_eval_frequency=100,\n          top_n=None,\n          learning_rate=0.01,\n          epsilon=0.0005,\n          job_name=None,\n          cloud=None,\n          ):\n  \"\"\"Blocking version of train_async. See documentation for train_async.\"\"\"\n  job = train_async(\n      train_dataset=train_dataset,\n      eval_dataset=eval_dataset,\n      analysis_dir=analysis_dir,\n      output_dir=output_dir,\n      features=features,\n      max_steps=max_steps,\n      num_epochs=num_epochs,\n      train_batch_size=train_batch_size,\n      eval_batch_size=eval_batch_size,\n      min_eval_frequency=min_eval_frequency,\n      top_n=top_n,\n      learning_rate=learning_rate,\n      epsilon=epsilon,\n      job_name=job_name,\n      cloud=cloud,\n  )\n  job.wait()\n  print('Training: ' + str(job.state))\n\n\ndef train_async(train_dataset,\n                eval_dataset,\n                analysis_dir,\n                output_dir,\n                features,\n                max_steps=5000,\n                num_epochs=None,\n                train_batch_size=100,\n                eval_batch_size=16,\n                min_eval_frequency=100,\n                top_n=None,\n                learning_rate=0.01,\n                epsilon=0.0005,\n                job_name=None,\n                cloud=None,\n                ):\n  \"\"\"Train model locally or in the cloud.\n\n  Local Training:\n\n  Args:\n    train_dataset: CsvDataSet\n    eval_dataset: CsvDataSet\n    analysis_dir:  The output directory from local_analysis\n    output_dir:  Output directory of training.\n    features: file path or features object. Example:\n        {\n          \"col_A\": {\"transform\": \"scale\", \"default\": 0.0},\n          \"col_B\": {\"transform\": \"scale\",\"value\": 4},\n          # Note col_C is missing, so default transform used.\n          \"col_D\": {\"transform\": \"hash_one_hot\", \"hash_bucket_size\": 4},\n          \"col_target\": {\"transform\": \"target\"},\n          \"col_key\": {\"transform\": \"key\"}\n        }\n        The keys correspond to the columns in the input files as defined by the\n        schema file during preprocessing. Some notes\n        1) The \"key\" and \"target\" transforms are required.\n        2) Default values are optional. These are used if the input data has\n           missing values during training and prediction. If not supplied for a\n           column, the default value for a numerical column is that column's\n           mean vlaue, and for a categorical column the empty string is used.\n        3) For numerical colums, the following transforms are supported:\n           i) {\"transform\": \"identity\"}: does nothing to the number. (default)\n           ii) {\"transform\": \"scale\"}: scales the colum values to -1, 1.\n           iii) {\"transform\": \"scale\", \"value\": a}: scales the colum values\n              to -a, a.\n\n           For categorical colums, the following transforms are supported:\n          i) {\"transform\": \"one_hot\"}: A one-hot vector using the full\n              vocabulary is used. (default)\n          ii) {\"transform\": \"embedding\", \"embedding_dim\": d}: Each label is\n              embedded into an d-dimensional space.\n    max_steps: Int. Number of training steps to perform.\n    num_epochs: Maximum number of training data epochs on which to train.\n        The training job will run for max_steps or num_epochs, whichever occurs\n        first.\n    train_batch_size: number of rows to train on in one step.\n    eval_batch_size: number of rows to eval in one step. One pass of the eval\n        dataset is done. If eval_batch_size does not perfectly divide the numer\n        of eval instances, the last fractional batch is not used.\n    min_eval_frequency: Minimum number of training steps between evaluations.\n    top_n: Int. For classification problems, the output graph will contain the\n        labels and scores for the top n classes with a default of n=1. Use\n        None for regression problems.\n    learning_rate: tf.train.AdamOptimizer's learning rate,\n    epsilon: tf.train.AdamOptimizer's epsilon value.\n\n  Cloud Training:\n\n  All local training arguments are valid for cloud training. Cloud training\n  contains two additional args:\n\n  Args:\n    cloud: A CloudTrainingConfig object.\n    job_name: Training job name. A default will be picked if None.\n  Returns:\n    Datalab job\n  \"\"\"\n  return core_train(\n      train_dataset=train_dataset,\n      eval_dataset=eval_dataset,\n      analysis_dir=analysis_dir,\n      output_dir=output_dir,\n      features=features,\n      model_type='linear_classification',\n      max_steps=max_steps,\n      num_epochs=num_epochs,\n      train_batch_size=train_batch_size,\n      eval_batch_size=eval_batch_size,\n      min_eval_frequency=min_eval_frequency,\n      top_n=top_n,\n      layer_sizes=None,\n      learning_rate=learning_rate,\n      epsilon=epsilon,\n      job_name=job_name,\n      job_name_prefix='mltoolbox_classification_linear',\n      cloud=cloud,\n  )\n"
  },
  {
    "path": "solutionbox/structured_data/mltoolbox/regression/__init__.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom mltoolbox._structured_data.__version__ import __version__\n\n__all__ = ['__version__']\n"
  },
  {
    "path": "solutionbox/structured_data/mltoolbox/regression/dnn/__init__.py",
    "content": "# Copyright 2017 Google Inc. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n# ==============================================================================\n\n\"\"\"This module contains functions for regression problems modeled as a fully connected\nfeedforward deep neural network.\n\nEvery function can run locally or use Google Cloud Platform.\n\"\"\"\n\nfrom ._regression_dnn import train, train_async\nfrom mltoolbox._structured_data import analyze, analyze_async, predict, batch_predict, \\\n    batch_predict_async\nfrom mltoolbox._structured_data.__version__ import __version__\n\n__all__ = ['train', 'train_async', 'analyze', 'analyze_async', 'predict', 'batch_predict',\n           'batch_predict_async', '__version__']\n"
  },
  {
    "path": "solutionbox/structured_data/mltoolbox/regression/dnn/_regression_dnn.py",
    "content": "from mltoolbox._structured_data import train_async as core_train\n\n\ndef train(train_dataset,\n          eval_dataset,\n          analysis_dir,\n          output_dir,\n          features,\n          layer_sizes,\n          max_steps=5000,\n          num_epochs=None,\n          train_batch_size=100,\n          eval_batch_size=16,\n          min_eval_frequency=100,\n          learning_rate=0.01,\n          epsilon=0.0005,\n          job_name=None,\n          cloud=None,\n          ):\n  \"\"\"Blocking version of train_async. See documentation for train_async.\"\"\"\n  job = train_async(\n      train_dataset=train_dataset,\n      eval_dataset=eval_dataset,\n      analysis_dir=analysis_dir,\n      output_dir=output_dir,\n      features=features,\n      layer_sizes=layer_sizes,\n      max_steps=max_steps,\n      num_epochs=num_epochs,\n      train_batch_size=train_batch_size,\n      eval_batch_size=eval_batch_size,\n      min_eval_frequency=min_eval_frequency,\n      learning_rate=learning_rate,\n      epsilon=epsilon,\n      job_name=job_name,\n      cloud=cloud,\n  )\n  job.wait()\n  print('Training: ' + str(job.state))\n\n\ndef train_async(train_dataset,\n                eval_dataset,\n                analysis_dir,\n                output_dir,\n                features,\n                layer_sizes,\n                max_steps=5000,\n                num_epochs=None,\n                train_batch_size=100,\n                eval_batch_size=16,\n                min_eval_frequency=100,\n                learning_rate=0.01,\n                epsilon=0.0005,\n                job_name=None,\n                cloud=None,\n                ):\n  \"\"\"Train model locally or in the cloud.\n\n  Local Training:\n\n  Args:\n    train_dataset: CsvDataSet\n    eval_dataset: CsvDataSet\n    analysis_dir:  The output directory from local_analysis\n    output_dir:  Output directory of training.\n    features: file path or features object. Example:\n        {\n          \"col_A\": {\"transform\": \"scale\", \"default\": 0.0},\n          \"col_B\": {\"transform\": \"scale\",\"value\": 4},\n          # Note col_C is missing, so default transform used.\n          \"col_D\": {\"transform\": \"hash_one_hot\", \"hash_bucket_size\": 4},\n          \"col_target\": {\"transform\": \"target\"},\n          \"col_key\": {\"transform\": \"key\"}\n        }\n        The keys correspond to the columns in the input files as defined by the\n        schema file during preprocessing. Some notes\n        1) The \"key\" and \"target\" transforms are required.\n        2) Default values are optional. These are used if the input data has\n           missing values during training and prediction. If not supplied for a\n           column, the default value for a numerical column is that column's\n           mean vlaue, and for a categorical column the empty string is used.\n        3) For numerical colums, the following transforms are supported:\n           i) {\"transform\": \"identity\"}: does nothing to the number. (default)\n           ii) {\"transform\": \"scale\"}: scales the colum values to -1, 1.\n           iii) {\"transform\": \"scale\", \"value\": a}: scales the colum values\n              to -a, a.\n\n           For categorical colums, the following transforms are supported:\n          i) {\"transform\": \"one_hot\"}: A one-hot vector using the full\n              vocabulary is used. (default)\n          ii) {\"transform\": \"embedding\", \"embedding_dim\": d}: Each label is\n              embedded into an d-dimensional space.\n    max_steps: Int. Number of training steps to perform.\n    num_epochs: Maximum number of training data epochs on which to train.\n        The training job will run for max_steps or num_epochs, whichever occurs\n        first.\n    train_batch_size: number of rows to train on in one step.\n    eval_batch_size: number of rows to eval in one step. One pass of the eval\n        dataset is done. If eval_batch_size does not perfectly divide the numer\n        of eval instances, the last fractional batch is not used.\n    min_eval_frequency: Minimum number of training steps between evaluations.\n    layer_sizes: List. Represents the layers in the connected DNN.\n        If the model type is DNN, this must be set. Example [10, 3, 2], this\n        will create three DNN layers where the first layer will have 10 nodes,\n        the middle layer will have 3 nodes, and the laster layer will have 2\n        nodes.\n    learning_rate: tf.train.AdamOptimizer's learning rate,\n    epsilon: tf.train.AdamOptimizer's epsilon value.\n\n  Cloud Training:\n\n  All local training arguments are valid for cloud training. Cloud training\n  contains two additional args:\n\n  Args:\n    cloud: A CloudTrainingConfig object.\n    job_name: Training job name. A default will be picked if None.\n\n  Returns:\n    Datalab job\n  \"\"\"\n  return core_train(\n      train_dataset=train_dataset,\n      eval_dataset=eval_dataset,\n      analysis_dir=analysis_dir,\n      output_dir=output_dir,\n      features=features,\n      model_type='dnn_regression',\n      max_steps=max_steps,\n      num_epochs=num_epochs,\n      train_batch_size=train_batch_size,\n      eval_batch_size=eval_batch_size,\n      min_eval_frequency=min_eval_frequency,\n      top_n=None,\n      layer_sizes=layer_sizes,\n      learning_rate=learning_rate,\n      epsilon=epsilon,\n      job_name=job_name,\n      job_name_prefix='mltoolbox_regression_dnn',\n      cloud=cloud,\n  )\n"
  },
  {
    "path": "solutionbox/structured_data/mltoolbox/regression/linear/__init__.py",
    "content": "# Copyright 2017 Google Inc. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n# ==============================================================================\n\n\"\"\"This module contains functions for linear regression problems.\n\nEvery function can run locally or use Google Cloud Platform.\n\"\"\"\n\nfrom ._regression_linear import train, train_async\nfrom mltoolbox._structured_data import analyze, analyze_async, predict, batch_predict, \\\n    batch_predict_async\nfrom mltoolbox._structured_data.__version__ import __version__\n\n__all__ = ['train', 'train_async', 'analyze', 'analyze_async', 'predict', 'batch_predict',\n           'batch_predict_async', '__version__']\n"
  },
  {
    "path": "solutionbox/structured_data/mltoolbox/regression/linear/_regression_linear.py",
    "content": "from mltoolbox._structured_data import train_async as core_train\n\n\ndef train(train_dataset,\n          eval_dataset,\n          analysis_dir,\n          output_dir,\n          features,\n          max_steps=5000,\n          num_epochs=None,\n          train_batch_size=100,\n          eval_batch_size=16,\n          min_eval_frequency=100,\n          learning_rate=0.01,\n          epsilon=0.0005,\n          job_name=None,\n          cloud=None,\n          ):\n  \"\"\"Blocking version of train_async. See documentation for train_async.\"\"\"\n  job = train_async(\n      train_dataset=train_dataset,\n      eval_dataset=eval_dataset,\n      analysis_dir=analysis_dir,\n      output_dir=output_dir,\n      features=features,\n      max_steps=max_steps,\n      num_epochs=num_epochs,\n      train_batch_size=train_batch_size,\n      eval_batch_size=eval_batch_size,\n      min_eval_frequency=min_eval_frequency,\n      learning_rate=learning_rate,\n      epsilon=epsilon,\n      job_name=job_name,\n      cloud=cloud,\n  )\n  job.wait()\n  print('Training: ' + str(job.state))\n\n\ndef train_async(train_dataset,\n                eval_dataset,\n                analysis_dir,\n                output_dir,\n                features,\n                max_steps=5000,\n                num_epochs=None,\n                train_batch_size=100,\n                eval_batch_size=16,\n                min_eval_frequency=100,\n                learning_rate=0.01,\n                epsilon=0.0005,\n                job_name=None,\n                cloud=None,\n                ):\n  \"\"\"Train model locally or in the cloud.\n\n  Local Training:\n\n  Args:\n    train_dataset: CsvDataSet\n    eval_dataset: CsvDataSet\n    analysis_dir:  The output directory from local_analysis\n    output_dir:  Output directory of training.\n    features: file path or features object. Example:\n        {\n          \"col_A\": {\"transform\": \"scale\", \"default\": 0.0},\n          \"col_B\": {\"transform\": \"scale\",\"value\": 4},\n          # Note col_C is missing, so default transform used.\n          \"col_D\": {\"transform\": \"hash_one_hot\", \"hash_bucket_size\": 4},\n          \"col_target\": {\"transform\": \"target\"},\n          \"col_key\": {\"transform\": \"key\"}\n        }\n        The keys correspond to the columns in the input files as defined by the\n        schema file during preprocessing. Some notes\n        1) The \"key\" and \"target\" transforms are required.\n        2) Default values are optional. These are used if the input data has\n           missing values during training and prediction. If not supplied for a\n           column, the default value for a numerical column is that column's\n           mean vlaue, and for a categorical column the empty string is used.\n        3) For numerical colums, the following transforms are supported:\n           i) {\"transform\": \"identity\"}: does nothing to the number. (default)\n           ii) {\"transform\": \"scale\"}: scales the colum values to -1, 1.\n           iii) {\"transform\": \"scale\", \"value\": a}: scales the colum values\n              to -a, a.\n\n           For categorical colums, the following transforms are supported:\n          i) {\"transform\": \"one_hot\"}: A one-hot vector using the full\n              vocabulary is used. (default)\n          ii) {\"transform\": \"embedding\", \"embedding_dim\": d}: Each label is\n              embedded into an d-dimensional space.\n    max_steps: Int. Number of training steps to perform.\n    num_epochs: Maximum number of training data epochs on which to train.\n        The training job will run for max_steps or num_epochs, whichever occurs\n        first.\n    train_batch_size: number of rows to train on in one step.\n    eval_batch_size: number of rows to eval in one step. One pass of the eval\n        dataset is done. If eval_batch_size does not perfectly divide the numer\n        of eval instances, the last fractional batch is not used.\n    min_eval_frequency: Minimum number of training steps between evaluations.\n    learning_rate: tf.train.AdamOptimizer's learning rate,\n    epsilon: tf.train.AdamOptimizer's epsilon value.\n\n  Cloud Training:\n\n  All local training arguments are valid for cloud training. Cloud training\n  contains two additional args:\n\n  Args:\n    cloud: A CloudTrainingConfig object.\n    job_name: Training job name. A default will be picked if None.\n  Returns:\n    Datalab job\n  \"\"\"\n  return core_train(\n      train_dataset=train_dataset,\n      eval_dataset=eval_dataset,\n      analysis_dir=analysis_dir,\n      output_dir=output_dir,\n      features=features,\n      model_type='linear_regression',\n      max_steps=max_steps,\n      num_epochs=num_epochs,\n      train_batch_size=train_batch_size,\n      eval_batch_size=eval_batch_size,\n      min_eval_frequency=min_eval_frequency,\n      top_n=None,\n      layer_sizes=None,\n      learning_rate=learning_rate,\n      epsilon=epsilon,\n      job_name=job_name,\n      job_name_prefix='mltoolbox_regression_linear',\n      cloud=cloud,\n  )\n"
  },
  {
    "path": "solutionbox/structured_data/setup.py",
    "content": "# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n# A copy of this file must be made in datalab_structured_data/setup.py\n\nimport os\nimport re\nfrom setuptools import setup\n\n\n# The version is saved in an __init__ file.\ndef get_version():\n    VERSIONFILE = 'mltoolbox/_structured_data/__version__.py'\n    if not os.path.isfile(VERSIONFILE):\n      raise ValueError('setup.py: File not found %s' % VERSIONFILE)\n    initfile_lines = open(VERSIONFILE, 'rt').readlines()\n    VSRE = r\"^__version__ = ['\\\"]([^'\\\"]*)['\\\"]\"\n    for line in initfile_lines:\n        mo = re.search(VSRE, line, re.M)\n        if mo:\n            return mo.group(1)\n    raise RuntimeError('Unable to find version string in %s.' % (VERSIONFILE,))\n\n\n# Calling setuptools.find_packages does not work with cloud training repackaging\n# because this script is not ran from this folder.\n\nsetup(\n  name='mltoolbox_datalab_classification_and_regression',\n  namespace_packages=['mltoolbox'],\n  version=get_version(),\n  packages=[\n    'mltoolbox',\n    'mltoolbox.classification',\n    'mltoolbox.classification.linear',\n    'mltoolbox.classification.dnn',\n    'mltoolbox.regression',\n    'mltoolbox.regression.linear',\n    'mltoolbox.regression.dnn',\n    'mltoolbox._structured_data',\n    'mltoolbox._structured_data.preprocess',\n    'mltoolbox._structured_data.prediction',\n    # 'mltoolbox._structured_data.test',\n    'mltoolbox._structured_data.trainer',\n  ],\n  description='Google Cloud Datalab Structured Data Package',\n  author='Google',\n  author_email='google-cloud-datalab-feedback@googlegroups.com',\n  keywords=[\n  ],\n  license=\"Apache Software License\",\n  classifiers=[\n      \"Programming Language :: Python\",\n      \"Programming Language :: Python :: 2\",\n      \"Development Status :: 4 - Beta\",\n      \"Environment :: Other Environment\",\n      \"Intended Audience :: Developers\",\n      \"License :: OSI Approved :: Apache Software License\",\n      \"Operating System :: OS Independent\",\n      \"Topic :: Software Development :: Libraries :: Python Modules\"\n  ],\n  long_description=\"\"\"\n  \"\"\",\n  install_requires=[\n  ],\n  package_data={\n  },\n  data_files=[],\n)\n"
  },
  {
    "path": "solutionbox/structured_data/test_mltoolbox/__init__.py",
    "content": ""
  },
  {
    "path": "solutionbox/structured_data/test_mltoolbox/e2e_functions.py",
    "content": "# Copyright 2017 Google Inc. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n# ==============================================================================\nfrom __future__ import absolute_import\n\nimport os\nimport random\nimport json\nimport six\nimport subprocess\n\n\ndef make_csv_data(filename, num_rows, problem_type, keep_target=True):\n  \"\"\"Writes csv data for preprocessing and training.\n\n  Args:\n    filename: writes data to local csv file.\n    num_rows: how many rows of data will be generated.\n    problem_type: 'classification' or 'regression'. Changes the target value.\n    keep_target: if false, the csv file will have an empty column ',,' for the\n        target.\n  \"\"\"\n  random.seed(12321)\n  with open(filename, 'w') as f1:\n    for i in range(num_rows):\n      num1 = random.uniform(0, 30)\n      num2 = random.randint(0, 20)\n      num3 = random.uniform(0, 10)\n\n      str1 = random.choice(['red', 'blue', 'green', 'pink', 'yellow', 'brown', 'black'])\n      str2 = random.choice(['abc', 'def', 'ghi', 'jkl', 'mno', 'pqr'])\n      str3 = random.choice(['car', 'truck', 'van', 'bike', 'train', 'drone'])\n\n      map1 = {'red': 2, 'blue': 6, 'green': 4, 'pink': -5, 'yellow': -6, 'brown': -1, 'black': 7}\n      map2 = {'abc': 10, 'def': 1, 'ghi': 1, 'jkl': 1, 'mno': 1, 'pqr': 1}\n      map3 = {'car': 5, 'truck': 10, 'van': 15, 'bike': 20, 'train': 25, 'drone': 30}\n\n      # Build some model.\n      t = 0.5 + 0.5 * num1 - 2.5 * num2 + num3\n      t += map1[str1] + map2[str2] + map3[str3]\n\n      if problem_type == 'classification':\n        if t < 0:\n          t = 100\n        elif t < 20:\n          t = 101\n        else:\n          t = 102\n\n      if keep_target:\n          csv_line = \"{id},{target},{num1},{num2},{num3},{str1},{str2},{str3}\\n\".format(\n            id=i,\n            target=t,\n            num1=num1,\n            num2=num2,\n            num3=num3,\n            str1=str1,\n            str2=str2,\n            str3=str3)\n      else:\n          csv_line = \"{id},{num1},{num2},{num3},{str1},{str2},{str3}\\n\".format(\n            id=i,\n            num1=num1,\n            num2=num2,\n            num3=num3,\n            str1=str1,\n            str2=str2,\n            str3=str3)\n      f1.write(csv_line)\n\n\ndef make_preprocess_schema(filename, problem_type):\n  \"\"\"Makes a schema file compatable with the output of make_csv_data.\n\n  Writes a json file.\n\n  Args:\n    filename: local output file path\n    problem_type: regression or classification\n  \"\"\"\n  schema = [\n      {\n          \"mode\": \"NULLABLE\",\n          \"name\": \"key\",\n          \"type\": \"STRING\"\n      },\n      {\n          \"mode\": \"REQUIRED\",\n          \"name\": \"target\",\n          \"type\": (\"STRING\" if problem_type == 'classification' else \"FLOAT\")\n      },\n      {\n          \"mode\": \"NULLABLE\",\n          \"name\": \"num1\",\n          \"type\": \"FLOAT\"\n      },\n      {\n          \"mode\": \"NULLABLE\",\n          \"name\": \"num2\",\n          \"type\": \"INTEGER\"\n      },\n      {\n          \"mode\": \"NULLABLE\",\n          \"name\": \"num3\",\n          \"type\": \"FLOAT\"\n      },\n      {\n          \"mode\": \"NULLABLE\",\n          \"name\": \"str1\",\n          \"type\": \"STRING\"\n      },\n      {\n          \"mode\": \"NULLABLE\",\n          \"name\": \"str2\",\n          \"type\": \"STRING\"\n      },\n      {\n          \"mode\": \"NULLABLE\",\n          \"name\": \"str3\",\n          \"type\": \"STRING\"\n      }\n  ]\n  with open(filename, 'w') as f:\n    f.write(json.dumps(schema))\n\n\ndef run_preprocess(output_dir, csv_filename, schema_filename, logger):\n  \"\"\"Run preprocess via subprocess call to local_preprocess.py\n\n  Args:\n    output_dir: local or gcs folder to write output to\n    csv_filename: local or gcs file to do analysis on\n    schema_filename: local or gcs file path to schema file\n    logger: python logging object\n  \"\"\"\n  preprocess_script = os.path.abspath(\n      os.path.join(os.path.dirname(__file__),\n                   '../mltoolbox/_structured_data/preprocess/local_preprocess.py'))\n\n  cmd = ['python', preprocess_script,\n         '--output-dir', output_dir,\n         '--input-file-pattern', csv_filename,\n         '--schema-file', schema_filename\n         ]\n  logger.debug('Going to run command: %s' % ' '.join(cmd))\n  subprocess.check_call(cmd)  # , stderr=open(os.devnull, 'wb'))\n\n\ndef run_training(\n        train_data_paths,\n        eval_data_paths,\n        output_path,\n        preprocess_output_dir,\n        transforms_file,\n        max_steps,\n        model_type,\n        logger,\n        extra_args=[]):\n  \"\"\"Runs Training via subprocess call to python -m\n\n  Args:\n    train_data_paths: local or gcs training csv files\n    eval_data_paths: local or gcs eval csv files\n    output_path: local or gcs folder to write output to\n    preprocess_output_dir: local or gcs output location of preprocessing\n    transforms_file: local or gcs path to transforms file\n    max_steps: max training steps\n    model_type: {dnn,linear}_{regression,classification}\n    logger: python logging object\n    extra_args: array of strings, passed to the trainer.\n\n  Returns:\n    The stderr of training as one string. TF writes to stderr, so basically, the\n    output of training.\n  \"\"\"\n\n  # Gcloud has the fun bug that you have to be in the parent folder of task.py\n  # when you call it. So cd there first.\n  task_parent_folder = os.path.abspath(os.path.join(os.path.dirname(__file__),\n                                                    '../mltoolbox/_structured_data'))\n  cmd = ['cd %s &&' % task_parent_folder,\n         'python -m trainer.task',\n         '--train-data-paths=%s' % train_data_paths,\n         '--eval-data-paths=%s' % eval_data_paths,\n         '--job-dir=%s' % output_path,\n         '--preprocess-output-dir=%s' % preprocess_output_dir,\n         '--transforms-file=%s' % transforms_file,\n         '--model-type=%s' % model_type,\n         '--train-batch-size=100',\n         '--eval-batch-size=10',\n         '--max-steps=%s' % max_steps] + extra_args\n  logger.debug('Going to run command: %s' % ' '.join(cmd))\n  sp = subprocess.Popen(' '.join(cmd), shell=True, stderr=subprocess.PIPE)\n  _, err = sp.communicate()\n\n  if not six.PY2:\n    err = err.decode()\n\n  return err\n\n\nif __name__ == '__main__':\n  make_csv_data('raw_train_regression.csv', 5000, 'regression', True)\n  make_csv_data('raw_eval_regression.csv', 1000, 'regression', True)\n  make_csv_data('raw_predict_regression.csv', 100, 'regression', False)\n  make_preprocess_schema('schema_regression.json', 'regression')\n\n  make_csv_data('raw_train_classification.csv', 5000, 'classification', True)\n  make_csv_data('raw_eval_classification.csv', 1000, 'classification', True)\n  make_csv_data('raw_predict_classification.csv', 100, 'classification', False)\n  make_preprocess_schema('schema_classification.json', 'classification')\n"
  },
  {
    "path": "solutionbox/structured_data/test_mltoolbox/test_datalab_e2e.py",
    "content": "# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\"\"\"Test analyze, training, and prediction.\n\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import print_function\n\nimport json\nimport logging\nimport os\nimport pandas as pd\nimport shutil\nimport six\nimport sys\nimport tempfile\nimport unittest\n\nfrom . import e2e_functions\nfrom tensorflow.python.lib.io import file_io\n\nsys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))\nsys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__),\n                                             '../../..')))\n\nimport mltoolbox.regression.linear as reglinear  # noqa: E402\nimport google.datalab.ml as dlml  # noqa: E402\n\n\nclass TestLinearRegression(unittest.TestCase):\n  \"\"\"Test linear regression works e2e locally.\n\n  Note that there should be little need for testing the other scenarios (linear\n  classification, dnn regression, dnn classification) as they should only\n  differ at training time. The training coverage of task.py is already done in\n  test_sd_trainer.\n  \"\"\"\n  def __init__(self, *args, **kwargs):\n    super(TestLinearRegression, self).__init__(*args, **kwargs)\n\n    # Log everything\n    self._logger = logging.getLogger('TestStructuredDataLogger')\n    self._logger.setLevel(logging.DEBUG)\n    if not self._logger.handlers:\n      self._logger.addHandler(logging.StreamHandler(stream=sys.stdout))\n\n  def _make_test_files(self):\n    \"\"\"Builds test files and folders\"\"\"\n\n    # Make the output folders\n    self._test_dir = tempfile.mkdtemp()\n    self._preprocess_output = os.path.join(self._test_dir, 'preprocess')\n    self._train_output = os.path.join(self._test_dir, 'train')\n    self._batch_predict_output = os.path.join(self._test_dir, 'batch_predict')\n\n    # Don't make train_output folder as it should not exist at training time.\n    os.mkdir(self._preprocess_output)\n    os.mkdir(self._batch_predict_output)\n\n    # Make csv files\n    self._csv_train_filename = os.path.join(self._test_dir,\n                                            'train_csv_data.csv')\n    self._csv_eval_filename = os.path.join(self._test_dir,\n                                           'eval_csv_data.csv')\n    self._csv_predict_filename = os.path.join(self._test_dir,\n                                              'predict_csv_data.csv')\n    e2e_functions.make_csv_data(self._csv_train_filename, 100, 'regression',\n                                True)\n    e2e_functions.make_csv_data(self._csv_eval_filename, 100, 'regression',\n                                True)\n    self._predict_num_rows = 10\n    e2e_functions.make_csv_data(self._csv_predict_filename,\n                                self._predict_num_rows, 'regression', False)\n\n    # Make schema file\n    self._schema_filename = os.path.join(self._test_dir, 'schema.json')\n    e2e_functions.make_preprocess_schema(self._schema_filename, 'regression')\n\n    # Make feature file\n    self._input_features_filename = os.path.join(self._test_dir,\n                                                 'input_features_file.json')\n    transforms = {\n        \"num1\": {\"transform\": \"scale\"},\n        \"num2\": {\"transform\": \"scale\", \"value\": 4},\n        \"str1\": {\"transform\": \"one_hot\"},\n        \"str2\": {\"transform\": \"embedding\", \"embedding_dim\": 3},\n        \"target\": {\"transform\": \"target\"},\n        \"key\": {\"transform\": \"key\"},\n    }\n    file_io.write_string_to_file(\n        self._input_features_filename,\n        json.dumps(transforms, indent=2))\n\n  def _run_analyze(self):\n    reglinear.analyze(\n        output_dir=self._preprocess_output,\n        dataset=dlml.CsvDataSet(\n            file_pattern=self._csv_train_filename,\n            schema_file=self._schema_filename))\n\n    self.assertTrue(os.path.isfile(\n        os.path.join(self._preprocess_output, 'stats.json')))\n    self.assertTrue(os.path.isfile(\n        os.path.join(self._preprocess_output, 'vocab_str1.csv')))\n\n  def _run_train(self):\n    reglinear.train(\n        train_dataset=dlml.CsvDataSet(\n            file_pattern=self._csv_train_filename,\n            schema_file=self._schema_filename),\n        eval_dataset=dlml.CsvDataSet(\n            file_pattern=self._csv_eval_filename,\n            schema_file=self._schema_filename),\n        analysis_dir=self._preprocess_output,\n        output_dir=self._train_output,\n        features=self._input_features_filename,\n        max_steps=100,\n        train_batch_size=100)\n\n    self.assertTrue(os.path.isfile(\n        os.path.join(self._train_output, 'model', 'saved_model.pb')))\n    self.assertTrue(os.path.isfile(\n        os.path.join(self._train_output, 'evaluation_model', 'saved_model.pb')))\n\n  def _run_predict(self):\n    data = pd.read_csv(self._csv_predict_filename,\n                       header=None)\n    df = reglinear.predict(data=data,\n                           training_dir=self._train_output)\n\n    self.assertEqual(len(df.index), self._predict_num_rows)\n    self.assertEqual(list(df), ['key', 'predicted'])\n\n  def _run_batch_prediction(self, output_dir, use_target):\n    reglinear.batch_predict(\n        training_dir=self._train_output,\n        prediction_input_file=(self._csv_eval_filename if use_target\n                               else self._csv_predict_filename),\n        output_dir=output_dir,\n        mode='evaluation' if use_target else 'prediction',\n        batch_size=4,\n        output_format='csv')\n\n    # check errors file is empty\n    errors = file_io.get_matching_files(os.path.join(output_dir, 'errors*'))\n    self.assertEqual(len(errors), 1)\n    if os.path.getsize(errors[0]):\n      with open(errors[0]) as errors_file:\n        self.fail(msg=errors_file.read())\n\n    # check predictions files are not empty\n    predictions = file_io.get_matching_files(os.path.join(output_dir,\n                                                          'predictions*'))\n    self.assertGreater(os.path.getsize(predictions[0]), 0)\n\n    # check the schema is correct\n    schema_file = os.path.join(output_dir, 'csv_schema.json')\n    self.assertTrue(os.path.isfile(schema_file))\n    schema = json.loads(file_io.read_file_to_string(schema_file))\n    self.assertEqual(schema[0]['name'], 'key')\n    self.assertEqual(schema[1]['name'], 'predicted')\n    if use_target:\n      self.assertEqual(schema[2]['name'], 'target')\n      self.assertEqual(len(schema), 3)\n    else:\n      self.assertEqual(len(schema), 2)\n\n  def _cleanup(self):\n    shutil.rmtree(self._test_dir)\n\n  def test_e2e(self):\n    try:\n      self._make_test_files()\n      self._run_analyze()\n      self._run_train()\n      if six.PY2:\n        # Dataflow is only supported by python 2. Prediction assumes Dataflow\n        # is installed.\n        self._run_predict()\n        self._run_batch_prediction(\n            os.path.join(self._batch_predict_output, 'with_target'),\n            True)\n        self._run_batch_prediction(\n            os.path.join(self._batch_predict_output, 'without_target'),\n            False)\n      else:\n        print('only tested analyze in TestLinearRegression')\n    finally:\n      self._cleanup()\n\n\nif __name__ == '__main__':\n    unittest.main()\n"
  },
  {
    "path": "solutionbox/structured_data/test_mltoolbox/test_package_functions.py",
    "content": "# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\"\"\"Test the datalab interface functions in _package.py\n\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import print_function\n\nimport os\nimport six\nimport sys\n\nsys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))\nsys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__),\n                                             '../../..')))\n\nimport inspect  # noqa: E402\nimport mltoolbox._structured_data._package as core_sd  # noqa: E402\nimport mltoolbox.classification.linear as classlin  # noqa: E402\nimport mltoolbox.classification.dnn as classdnn  # noqa: E402\nimport mltoolbox.regression.linear as reglin  # noqa: E402\nimport mltoolbox.regression.dnn as regdnn  # noqa: E402\nimport google.datalab.ml as dlml  # noqa: E402\nimport unittest  # noqa: E402\n\n\n@unittest.skipIf(not six.PY2, 'Python 2 is required')\nclass TestAnalyze(unittest.TestCase):\n\n  def test_not_csvdataset(self):\n    \"\"\"Test csvdataset is used\"\"\"\n    # not a CsvDataSet\n    job = core_sd.analyze_async('some_dir', 'some_file.txt').wait()\n    self.assertIn('Only CsvDataSet is supported', job.fatal_error.message)\n\n  def test_csvdataset_one_file(self):\n    \"\"\"Test CsvDataSet has only one file/pattern\"\"\"\n    # TODO(brandondutra) remove this restriction\n    job = core_sd.analyze_async(\n        'some_dir',\n        dlml.CsvDataSet(\n            file_pattern=['file1.txt', 'file2.txt'],\n            schema='col1:STRING,col2:INTEGER,col3:FLOAT')).wait()\n    self.assertIn('should be built with a file pattern',\n                  job.fatal_error.message)\n\n  def test_projectid(self):\n    \"\"\"Test passing project id but cloud is false\"\"\"\n    job = core_sd.analyze_async(\n        'some_dir',\n        dlml.CsvDataSet(\n            file_pattern=['file1.txt'],\n            schema='col1:STRING,col2:INTEGER,col3:FLOAT'),\n        project_id='project_id').wait()\n    self.assertIn('project_id only needed if cloud is True',\n                  job.fatal_error.message)\n\n  def test_cloud_with_local_output_folder(self):\n    job = core_sd.analyze_async(\n        'some_dir',\n        dlml.CsvDataSet(\n            file_pattern=['gs://file1.txt'],\n            schema='col1:STRING,col2:INTEGER,col3:FLOAT'),\n        project_id='project_id',\n        cloud=True).wait()\n    self.assertIn('File some_dir is not a gcs path', job.fatal_error.message)\n\n  def test_cloud_but_local_files(self):\n    job = core_sd.analyze_async(\n        'gs://some_dir',\n        dlml.CsvDataSet(\n            file_pattern=['file1.txt'],\n            schema='col1:STRING,col2:INTEGER,col3:FLOAT'),\n        project_id='project_id',\n        cloud=True).wait()\n    self.assertIn('File file1.txt is not a gcs path', job.fatal_error.message)\n\n  def test_unsupported_schema(self):\n    \"\"\"Test supported schema values.\n\n    Note that not all valid BQ schema values are valid/used in the structured\n    data package\n    \"\"\"\n\n    unsupported_col_types = ['bytes', 'boolean', 'timestamp', 'date', 'time',\n                             'datetime', 'record']\n    for col_type in unsupported_col_types:\n      schema = 'col_name:%s' % col_type\n\n      job = core_sd.analyze_async(\n        'some_dir',\n        dlml.CsvDataSet(\n            file_pattern=['file1.txt'],\n            schema=schema),\n        cloud=False).wait()\n      self.assertIn('Schema contains an unsupported type %s.' % col_type,\n                    job.fatal_error.message)\n\n      job = core_sd.analyze_async(\n        'gs://some_dir',\n        dlml.CsvDataSet(\n            file_pattern=['gs://file1.txt'],\n            schema=schema),\n        cloud=True,\n        project_id='junk_project_id').wait()\n      self.assertIn('Schema contains an unsupported type %s.' % col_type,\n                    job.fatal_error.message)\n\n\n@unittest.skipIf(not six.PY2, 'Python 2 is required')\nclass TestFunctionSignature(unittest.TestCase):\n\n  def _argspec(self, fn_obj):\n    if six.PY2:\n      return inspect.getargspec(fn_obj)\n    else:\n      return inspect.getfullargspec(fn_obj)\n\n  def test_same_analysis(self):\n    \"\"\"Test that there is only one analyze function\"\"\"\n    self.assertIs(core_sd.analyze, classlin.analyze)\n    self.assertIs(core_sd.analyze, classdnn.analyze)\n    self.assertIs(core_sd.analyze, reglin.analyze)\n    self.assertIs(core_sd.analyze, regdnn.analyze)\n\n  def test_same_analysis_async(self):\n    \"\"\"Test that there is only one analyze_async function\"\"\"\n    self.assertIs(core_sd.analyze_async, classlin.analyze_async)\n    self.assertIs(core_sd.analyze_async, classdnn.analyze_async)\n    self.assertIs(core_sd.analyze_async, reglin.analyze_async)\n    self.assertIs(core_sd.analyze_async, regdnn.analyze_async)\n\n  def test_analysis_argspec(self):\n    \"\"\"Test all analyze functions have the same parameters\"\"\"\n\n    self.assertEqual(self._argspec(core_sd.analyze),\n                     self._argspec(core_sd.analyze_async))\n    self.assertEqual(self._argspec(core_sd.analyze),\n                     self._argspec(core_sd._analyze))\n"
  },
  {
    "path": "solutionbox/structured_data/test_mltoolbox/test_sd_preprocess.py",
    "content": "# Copyright 2017 Google Inc. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n# ==============================================================================\nfrom __future__ import absolute_import\n\nimport glob\nimport json\nimport logging\nimport os\nimport shutil\nimport sys\nimport filecmp\nimport tempfile\nimport unittest\n\nfrom . import e2e_functions\n\n\nclass TestPreprocess(unittest.TestCase):\n  \"\"\"Tests preprocessing.\n\n  Runs analysis on a test dataset. Checks that the expected files are made.\n  \"\"\"\n  def __init__(self, *args, **kwargs):\n    super(TestPreprocess, self).__init__(*args, **kwargs)\n\n    # Log everything\n    self._logger = logging.getLogger('TestStructuredDataLogger')\n    self._logger.setLevel(logging.DEBUG)\n    if not self._logger.handlers:\n      self._logger.addHandler(logging.StreamHandler(stream=sys.stdout))\n\n  def setUp(self):\n    self._test_dir = tempfile.mkdtemp()\n\n    self._csv_filename = os.path.join(self._test_dir, 'raw_csv_data.csv')\n    self._schema_filename = os.path.join(self._test_dir, 'schema.json')\n\n    self._preprocess_output = os.path.join(self._test_dir, 'pout')\n\n  def tearDown(self):\n    self._logger.debug('TestPreprocess: removing test dir: ' + self._test_dir)\n    shutil.rmtree(self._test_dir)\n\n  def _make_test_data(self, problem_type):\n    \"\"\"Makes input files to run preprocessing on.\n\n    Args:\n      problem_type: 'regression' or 'classification'\n    \"\"\"\n    e2e_functions.make_csv_data(self._csv_filename, 100, problem_type, True)\n    e2e_functions.make_preprocess_schema(self._schema_filename, problem_type)\n\n  def _test_preprocess(self, problem_type):\n    self._make_test_data(problem_type)\n\n    e2e_functions.run_preprocess(\n        output_dir=self._preprocess_output,\n        csv_filename=self._csv_filename,\n        schema_filename=self._schema_filename,\n        logger=self._logger)\n\n    schema_file = os.path.join(self._preprocess_output, 'schema.json')\n    numerical_analysis_file = os.path.join(self._preprocess_output, 'stats.json')\n\n    # test schema file was copied\n    self.assertTrue(filecmp.cmp(schema_file, self._schema_filename))\n\n    expected_numerical_keys = ['num1', 'num2', 'num3']\n    if problem_type == 'regression':\n      expected_numerical_keys.append('target')\n\n    # Load the numerical analysis file and check it has the right keys\n    with open(numerical_analysis_file, 'r') as f:\n      analysis = json.load(f)\n    self.assertEqual(sorted(expected_numerical_keys), sorted(analysis.keys()))\n\n    # Check that the vocab files are made\n    expected_vocab_files = ['vocab_str1.csv', 'vocab_str2.csv',\n                            'vocab_str3.csv', 'vocab_key.csv']\n    if problem_type == 'classification':\n      expected_vocab_files.append('vocab_target.csv')\n\n    for name in expected_vocab_files:\n      vocab_file = os.path.join(self._preprocess_output, name)\n      self.assertTrue(os.path.exists(vocab_file))\n      self.assertGreater(os.path.getsize(vocab_file), 0)\n\n    all_expected_files = (expected_vocab_files + ['stats.json', 'schema.json'])\n    all_file_paths = glob.glob(os.path.join(self._preprocess_output, '*'))\n    all_files = [os.path.basename(path) for path in all_file_paths]\n    self.assertEqual(sorted(all_expected_files), sorted(all_files))\n\n  def testRegression(self):\n    self._test_preprocess('regression')\n\n  def testClassification(self):\n    self._test_preprocess('classification')\n\n\nif __name__ == '__main__':\n    unittest.main()\n"
  },
  {
    "path": "solutionbox/structured_data/test_mltoolbox/test_sd_trainer.py",
    "content": "# Copyright 2017 Google Inc. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n# ==============================================================================\nfrom __future__ import absolute_import\n\nimport json\nimport logging\nimport os\nimport re\nimport shutil\nimport sys\nimport tempfile\nimport unittest\n\nfrom . import e2e_functions\n\n\nclass TestTrainer(unittest.TestCase):\n  \"\"\"Tests training.\n\n  Each test builds a csv test dataset. Preprocessing is run on the data to\n  produce analysis. Training is then ran, and the output is collected and the\n  accuracy/loss values are inspected.\n  \"\"\"\n  def __init__(self, *args, **kwargs):\n    super(TestTrainer, self).__init__(*args, **kwargs)\n\n    # Allow this class to be subclassed for quick tests that only care about\n    # training working, not model loss/accuracy.\n    self._max_steps = 2500\n    self._check_model_fit = True\n\n    # Log everything\n    self._logger = logging.getLogger('TestStructuredDataLogger')\n    self._logger.setLevel(logging.DEBUG)\n    if not self._logger.handlers:\n      self._logger.addHandler(logging.StreamHandler(stream=sys.stdout))\n\n  def setUp(self):\n    self._test_dir = tempfile.mkdtemp()\n    self._preprocess_output = os.path.join(self._test_dir, 'pre')\n    self._train_output = os.path.join(self._test_dir, 'train')\n\n    os.mkdir(self._preprocess_output)\n    os.mkdir(self._train_output)\n\n    self._csv_train_filename = os.path.join(self._test_dir, 'train_csv_data.csv')\n    self._csv_eval_filename = os.path.join(self._test_dir, 'eval_csv_data.csv')\n    self._schema_filename = os.path.join(self._test_dir, 'schema.json')\n    self._input_features_filename = os.path.join(self._test_dir,\n                                                 'input_features_file.json')\n\n    self._transforms_filename = os.path.join(self._test_dir, 'features.json')\n\n  def tearDown(self):\n    self._logger.debug('TestTrainer: removing test dir ' + self._test_dir)\n    shutil.rmtree(self._test_dir)\n\n  def _run_training(self, problem_type, model_type, transforms, extra_args=[]):\n    \"\"\"Runs training.\n\n    Output is saved to _training_screen_output. Nothing from training should be\n    printed to the screen.\n\n    Args:\n      problem_type: 'regression' or 'classification'\n      model_type: 'linear' or 'dnn'\n      transform: JSON object of the transforms file.\n      extra_args: list of strings to pass to the trainer.\n    \"\"\"\n    # Run preprocessing.\n    e2e_functions.make_csv_data(self._csv_train_filename, 100, problem_type, True)\n    e2e_functions.make_csv_data(self._csv_eval_filename, 100, problem_type, True)\n    e2e_functions.make_preprocess_schema(self._schema_filename, problem_type)\n\n    e2e_functions.run_preprocess(\n        output_dir=self._preprocess_output,\n        csv_filename=self._csv_train_filename,\n        schema_filename=self._schema_filename,\n        logger=self._logger)\n\n    # Write the transforms file.\n    with open(self._transforms_filename, 'w') as f:\n      f.write(json.dumps(transforms, indent=2, separators=(',', ': ')))\n\n    # Run training and save the output.\n    output = e2e_functions.run_training(\n        train_data_paths=self._csv_train_filename,\n        eval_data_paths=self._csv_eval_filename,\n        output_path=self._train_output,\n        preprocess_output_dir=self._preprocess_output,\n        transforms_file=self._transforms_filename,\n        max_steps=self._max_steps,\n        model_type=model_type + '_' + problem_type,\n        logger=self._logger,\n        extra_args=extra_args)\n    self._training_screen_output = output\n\n  def _check_training_screen_output(self, accuracy=None, loss=None):\n    \"\"\"Should be called after _run_training.\n\n    Inspects self._training_screen_output for correct output.\n\n    Args:\n      accuracy: float. Eval accuracy should be > than this number.\n      loss: flaot. Eval loss should be < than this number.\n    \"\"\"\n    if not self._check_model_fit:\n      self._logger.debug('Skipping model loss/accuracy checks')\n      return\n\n    # Find the last training loss line in the output\n    lines = self._training_screen_output.splitlines()\n    last_line = None\n    for line in lines:\n      if line.startswith('INFO:tensorflow:Saving dict for global step %d' % self._max_steps):\n        last_line = line\n        break\n\n    if not last_line:\n      self._logger.debug('Skipping _check_training_screen_output as could not '\n                         'find last eval line')\n      return\n    self._logger.debug(last_line)\n\n    # supports positive numbers (int, real) with exponential form support.\n    positive_number_re = re.compile('[+]?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?')\n\n    # Check it made it to step 2500\n    saving_num_re = re.compile('global_step = \\d+')\n    saving_num = saving_num_re.findall(last_line)\n    # saving_num == ['Saving evaluation summary for step NUM']\n    self.assertEqual(len(saving_num), 1)\n    step_num = positive_number_re.findall(saving_num[0])\n    # step_num == ['2500']\n    self.assertEqual(len(step_num), 1)\n    self.assertEqual(int(step_num[0]), self._max_steps)\n\n    # Check the accuracy\n    if accuracy is not None:\n      accuracy_eq_num_re = re.compile('accuracy = [+]?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?')\n      accuracy_eq_num = accuracy_eq_num_re.findall(last_line)\n      # accuracy_eq_num == ['accuracy = NUM']\n      self.assertEqual(len(accuracy_eq_num), 1)\n      accuracy_num = positive_number_re.findall(accuracy_eq_num[0])\n      # accuracy_num == ['X.XXX']\n      self.assertEqual(len(accuracy_num), 1)\n      self.assertGreater(float(accuracy_num[0]), accuracy)\n\n    if loss is not None:\n      loss_eq_num_re = re.compile('loss = [+]?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?')\n      loss_eq_num = loss_eq_num_re.findall(last_line)\n      # loss_eq_num == ['loss = NUM']\n      self.assertEqual(len(loss_eq_num), 1)\n      loss_num = positive_number_re.findall(loss_eq_num[0])\n      # loss_num == ['X.XXX']\n      self.assertEqual(len(loss_num), 1)\n      self.assertLess(float(loss_num[0]), loss)\n\n  def _check_train_files(self):\n    self._check_savedmodel(os.path.join(self._train_output, 'model'))\n    self._check_savedmodel(os.path.join(self._train_output, 'evaluation_model'))\n\n  def _check_savedmodel(self, model_folder):\n    self.assertTrue(\n        os.path.isfile(os.path.join(model_folder, 'saved_model.pb')))\n    self.assertTrue(\n        os.path.isfile(os.path.join(model_folder, 'variables/variables.index')))\n    self.assertTrue(\n        os.path.isfile(os.path.join(model_folder, 'assets.extra/schema.json')))\n    self.assertTrue(\n        os.path.isfile(os.path.join(model_folder, 'assets.extra/features.json')))\n\n  def testRegressionDnn(self):\n    self._logger.debug('\\n\\nTesting Regression DNN')\n\n    transforms = {\n        \"num1\": {\"transform\": \"scale\"},\n        \"num2\": {\"transform\": \"scale\", \"value\": 4},\n        \"str1\": {\"transform\": \"one_hot\"},\n        \"str2\": {\"transform\": \"embedding\", \"embedding_dim\": 3},\n        \"target\": {\"transform\": \"target\"},\n        \"key\": {\"transform\": \"key\"},\n    }\n\n    extra_args = ['--layer-size1=10', '--layer-size2=10', '--layer-size3=5']\n    self._run_training(problem_type='regression',\n                       model_type='dnn',\n                       transforms=transforms,\n                       extra_args=extra_args)\n\n    self._check_training_screen_output(loss=20)\n    self._check_train_files()\n\n  def testRegressionLinear(self):\n    self._logger.debug('\\n\\nTesting Regression Linear')\n\n    transforms = {\n        \"num1\": {\"transform\": \"scale\"},\n        \"num2\": {\"transform\": \"scale\", \"value\": 4},\n        \"str1\": {\"transform\": \"one_hot\"},\n        \"str2\": {\"transform\": \"embedding\", \"embedding_dim\": 3},\n        \"target\": {\"transform\": \"target\"},\n        \"key\": {\"transform\": \"key\"},\n    }\n\n    self._run_training(problem_type='regression',\n                       model_type='linear',\n                       transforms=transforms)\n\n    self._check_training_screen_output(loss=20)\n    self._check_train_files()\n\n  def testClassificationDnn(self):\n    self._logger.debug('\\n\\nTesting classification DNN')\n\n    transforms = {\n        \"num1\": {\"transform\": \"scale\"},\n        \"num2\": {\"transform\": \"scale\", \"value\": 4},\n        \"str1\": {\"transform\": \"one_hot\"},\n        \"str2\": {\"transform\": \"embedding\", \"embedding_dim\": 3},\n        \"target\": {\"transform\": \"target\"},\n        \"key\": {\"transform\": \"key\"},\n    }\n\n    extra_args = ['--layer-size1=10', '--layer-size2=10', '--layer-size3=5']\n    self._run_training(problem_type='classification',\n                       model_type='dnn',\n                       transforms=transforms,\n                       extra_args=extra_args)\n\n    self._check_training_screen_output(accuracy=0.70, loss=0.10)\n    self._check_train_files()\n\n  def testClassificationLinear(self):\n    self._logger.debug('\\n\\nTesting classification Linear')\n\n    transforms = {\n        \"num1\": {\"transform\": \"scale\"},\n        \"num2\": {\"transform\": \"scale\", \"value\": 4},\n        \"str1\": {\"transform\": \"one_hot\"},\n        \"str2\": {\"transform\": \"embedding\", \"embedding_dim\": 3},\n        \"target\": {\"transform\": \"target\"},\n        \"key\": {\"transform\": \"key\"},\n    }\n\n    self._run_training(problem_type='classification',\n                       model_type='linear',\n                       transforms=transforms)\n\n    self._check_training_screen_output(accuracy=0.70, loss=0.2)\n    self._check_train_files()\n\n\nif __name__ == '__main__':\n    unittest.main()\n"
  },
  {
    "path": "tests/_util/__init__.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n"
  },
  {
    "path": "tests/_util/commands_tests.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\n\nimport argparse\nimport contextlib\nimport six\nimport sys\nimport unittest\nimport yaml\n\n\nfrom google.datalab.utils.commands import CommandParser\n\n\nclass TestCases(unittest.TestCase):\n\n  @staticmethod\n  @contextlib.contextmanager\n  # Redirects some stderr temporarily; can be used to prevent console output from some tests.\n  def redirect_stderr(target):\n    original = sys.stderr\n    sys.stderr = target\n    yield\n    sys.stderr = original\n\n  def test_subcommand_line(self):\n\n    parser = CommandParser(\n        prog='%test_subcommand_line',\n        description='test_subcommand_line description')\n\n    subcommand1 = parser.subcommand('subcommand1', help='subcommand1 help')\n    subcommand1.add_argument('--string1', help='string1 help.')\n    subcommand1.add_argument('--flag1', action='store_true', default=False,\n                             help='flag1 help.')\n\n    args, cell = parser.parse('subcommand1 --string1 value1 --flag1', None)\n    self.assertEqual(args, {'string1': 'value1', 'flag1': True})\n    self.assertIsNone(cell)\n\n    args, cell = parser.parse('subcommand1 --string1 value1', None)\n    self.assertEqual(args, {'string1': 'value1', 'flag1': False})\n    self.assertIsNone(cell)\n\n    args, cell = parser.parse('subcommand1', None)\n    self.assertEqual(args, {'string1': None, 'flag1': False})\n    self.assertIsNone(cell)\n\n    # Adding same arg twice will cause argparse to raise its own ArgumentError.\n    with self.assertRaises(argparse.ArgumentError):\n      subcommand1.add_argument('--string2', help='string2 help.')\n      subcommand1.add_argument('--string2', help='string2 help.')\n\n  def test_subcommand_line_cell(self):\n\n    parser = CommandParser(\n        prog='%test_subcommand_line',\n        description='test_subcommand_line description')\n\n    subcommand1 = parser.subcommand('subcommand1', help='subcommand1 help')\n    subcommands_of_subcommand1 = subcommand1.add_subparsers(dest='command')\n    subcommand2 = subcommands_of_subcommand1.add_parser('subcommand2', help='subcommand2 help')\n    subcommand2.add_argument('--string1', '-s', required=True, help='string1 help.')\n    subcommand2.add_argument('--string2', '--string2again', dest='string2', help='string2 help.')\n    subcommand2.add_cell_argument('string3', help='string3 help.')\n    subcommand2.add_argument('--flag1', action='store_true', default=False,\n                             help='flag1 help.')\n\n    args, cell = parser.parse('subcommand1 subcommand2 -s value1 --string2 value2',\n                              'flag1: true')\n    self.assertEqual(args, {'string1': 'value1', 'string2': 'value2', 'string3': None,\n                            'command': 'subcommand2', 'flag1': True})\n    self.assertIsNone(cell)\n\n    args, cell = parser.parse('subcommand1 subcommand2 --flag1',\n                              'string1: value1\\nstring2again: value2')\n    self.assertEqual(args, {'string1': 'value1', 'string2': 'value2', 'string3': None,\n                            'command': 'subcommand2', 'flag1': True})\n    self.assertIsNone(cell)\n\n    args, cell = parser.parse('subcommand1 subcommand2',\n                              'string1: value1\\nstring2: value2\\nstring3: value3\\n' +\n                              'string4: value4\\nflag1: false')\n    self.assertEqual(args, {'string1': 'value1', 'string2': 'value2', 'string3': 'value3',\n                            'command': 'subcommand2', 'flag1': False})\n    self.assertEqual(yaml.load(cell), {'string3': 'value3', 'string4': 'value4'})\n\n    # Regular arg and cell arg cannot be the same name.\n    with self.assertRaises(ValueError):\n      subcommand2.add_argument('--duparg', help='help.')\n      subcommand2.add_cell_argument('duparg', help='help.')\n\n    # Do not allow same arg in both line and cell.\n    with self.assertRaises(ValueError):\n      parser.parse('subcommand1 subcommand2 -s value1 --duparg v1', 'duparg: v2')\n\n    # 'string3' is a cell arg. Argparse will raise Exception after finding an unrecognized param.\n    with self.assertRaisesRegexp(Exception, 'unrecognized arguments: --string3 value3'):\n      with TestCases.redirect_stderr(six.StringIO()):\n        parser.parse('subcommand1 subcommand2 -s value1 --string3 value3', 'a: b')\n\n    # 'string4' is required but missing.\n    subcommand2.add_cell_argument('string4', required=True, help='string4 help.')\n    with self.assertRaises(ValueError):\n      parser.parse('subcommand1 subcommand2 -s value1', 'a: b')\n\n  def test_subcommand_var_replacement(self):\n\n    parser = CommandParser(\n        prog='%test_subcommand_line',\n        description='test_subcommand_line description')\n\n    subcommand1 = parser.subcommand('subcommand1', help='subcommand1 help')\n    subcommand1.add_argument('--string1', help='string1 help.')\n    subcommand1.add_argument('--flag1', action='store_true', default=False,\n                             help='flag1 help.')\n    subcommand1.add_cell_argument('string2', help='string2 help.')\n    subcommand1.add_cell_argument('dict1', help='dict1 help.')\n\n    namespace = {'var1': 'value1', 'var2': 'value2', 'var3': [1, 2]}\n    args, cell = parser.parse('subcommand1 --string1 $var1', 'a: b\\nstring2: $var2', namespace)\n    self.assertEqual(args,\n                     {'string1': 'value1', 'string2': 'value2', 'flag1': False, 'dict1': None})\n    self.assertEqual(yaml.load(cell), {'a': 'b', 'string2': '$var2'})\n\n    cell = \"\"\"\ndict1:\n  k1: $var1\n  k2: $var3\n\"\"\"\n    args, cell = parser.parse('subcommand1', cell, namespace)\n    self.assertEqual(args['dict1'], {'k1': 'value1', 'k2': [1, 2]})\n\n  def test_subcommand_help(self):\n\n    parser = CommandParser(\n        prog='%test_subcommand_line',\n        description='test_subcommand_line description')\n\n    subcommand1 = parser.subcommand('subcommand1', help='subcommand1 help')\n    subcommands_of_subcommand1 = subcommand1.add_subparsers(dest='command')\n    subcommand2 = subcommands_of_subcommand1.add_parser('subcommand2', help='subcommand2 help')\n    subcommand2.add_argument('--string1', '-s', required=True, help='string1 help.')\n    subcommand2.add_argument('--string2', '--string2again', dest='string2', help='string2 help.')\n    subcommand2.add_cell_argument('string3', help='string3 help.')\n    subcommand2.add_argument('--flag1', action='store_true', default=False,\n                             help='flag1 help.')\n\n    old_stdout = sys.stdout\n    buf = six.StringIO()\n    sys.stdout = buf\n    with self.assertRaises(Exception):\n      parser.parse('subcommand1 subcommand2 --help', None)\n    sys.stdout = old_stdout\n    help_string = buf.getvalue()\n    self.assertIn('string1 help.', help_string)\n    self.assertIn('string2 help.', help_string)\n    self.assertIn('string3 help.', help_string)\n    self.assertIn('flag1 help.', help_string)\n"
  },
  {
    "path": "tests/_util/feature_statistics_generator_test.py",
    "content": "# Copyright 2017 Google Inc. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n# ==============================================================================\nfrom google.datalab.utils.facets.feature_statistics_generator import FeatureStatisticsGenerator\nimport numpy as np\nimport tensorflow as tf\nfrom tensorflow.python.platform import googletest\n\n\nclass FeatureStatisticsGeneratorTest(googletest.TestCase):\n\n  def setUp(self):\n    self.fs = FeatureStatisticsGenerator()\n\n  def testParseExampleInt(self):\n    # Tests parsing examples of integers\n    examples = []\n    for i in range(50):\n      example = tf.train.Example()\n      example.features.feature['num'].int64_list.value.append(i)\n      examples.append(example)\n\n    entries = {}\n    for i, example in enumerate(examples):\n      self.fs._ParseExample(example.features.feature, [], entries, i)\n\n    self.assertEqual(1, len(entries))\n    self.assertIn('num', entries)\n    info = entries['num']\n    self.assertEqual(0, info['missing'])\n    self.assertEqual(self.fs.fs_proto.INT, info['type'])\n    for i in range(len(examples)):\n      self.assertEqual(1, info['counts'][i])\n      self.assertEqual(i, info['vals'][i])\n\n  def testParseExampleMissingValueList(self):\n    # Tests parsing examples of integers\n    examples = []\n    example = tf.train.Example()\n    # pylint: disable=pointless-statement\n    example.features.feature['str']\n    # pylint: enable=pointless-statement\n    examples.append(example)\n    example = tf.train.Example()\n    example.features.feature['str'].bytes_list.value.append(b'test')\n    examples.append(example)\n\n    entries = {}\n    for i, example in enumerate(examples):\n      self.fs._ParseExample(example.features.feature, [], entries, i)\n\n    self.assertEqual(1, len(entries))\n    self.assertIn('str', entries)\n    info = entries['str']\n    self.assertEqual(1, info['missing'])\n    self.assertEqual(self.fs.fs_proto.STRING, info['type'])\n    self.assertEqual(0, info['counts'][0])\n    self.assertEqual(1, info['counts'][1])\n\n  def _check_sequence_example_entries(self,\n                                      entries,\n                                      n_examples,\n                                      n_features,\n                                      feat_len=None):\n    self.assertIn('num', entries)\n    info = entries['num']\n    self.assertEqual(0, info['missing'])\n    self.assertEqual(self.fs.fs_proto.INT, info['type'])\n    for i in range(n_examples):\n      self.assertEqual(n_features, info['counts'][i])\n      if feat_len is not None:\n        self.assertEqual(feat_len, info['feat_lens'][i])\n    for i in range(n_examples * n_features):\n      self.assertEqual(i, info['vals'][i])\n    if feat_len is None:\n      self.assertEqual(0, len(info['feat_lens']))\n\n  def testParseExampleSequenceContext(self):\n    # Tests parsing examples of integers in context field\n    examples = []\n    for i in range(50):\n      example = tf.train.SequenceExample()\n      example.context.feature['num'].int64_list.value.append(i)\n      examples.append(example)\n\n    entries = {}\n    for i, example in enumerate(examples):\n      self.fs._ParseExample(example.context.feature,\n                            example.feature_lists.feature_list, entries, i)\n    self._check_sequence_example_entries(entries, 50, 1)\n    self.assertEqual(1, len(entries))\n\n  def testParseExampleSequenceFeatureList(self):\n    examples = []\n    for i in range(50):\n      example = tf.train.SequenceExample()\n      feat = example.feature_lists.feature_list['num'].feature.add()\n      feat.int64_list.value.append(i)\n      examples.append(example)\n\n    entries = {}\n    for i, example in enumerate(examples):\n      self.fs._ParseExample(example.context.feature,\n                            example.feature_lists.feature_list, entries, i)\n    self._check_sequence_example_entries(entries, 50, 1, 1)\n\n  def testParseExampleSequenceFeatureListMultipleEntriesInner(self):\n    examples = []\n    for i in range(2):\n      example = tf.train.SequenceExample()\n      feat = example.feature_lists.feature_list['num'].feature.add()\n      for j in range(25):\n        feat.int64_list.value.append(i * 25 + j)\n      examples.append(example)\n\n    entries = {}\n    for i, example in enumerate(examples):\n      self.fs._ParseExample(example.context.feature,\n                            example.feature_lists.feature_list, entries, i)\n\n    self._check_sequence_example_entries(entries, 2, 25, 1)\n\n  def testParseExampleSequenceFeatureListMultipleEntriesOuter(self):\n    # Tests parsing examples of integers in context field\n    examples = []\n    for i in range(2):\n      example = tf.train.SequenceExample()\n      for j in range(25):\n        feat = example.feature_lists.feature_list['num'].feature.add()\n        feat.int64_list.value.append(i * 25 + j)\n      examples.append(example)\n\n    entries = {}\n    for i, example in enumerate(examples):\n      self.fs._ParseExample(example.context.feature,\n                            example.feature_lists.feature_list, entries, i)\n    self._check_sequence_example_entries(entries, 2, 25, 25)\n\n  def testVaryingCountsAndMissing(self):\n    # Tests parsing examples of when some examples have missing features\n    examples = []\n    for i in range(5):\n      example = tf.train.Example()\n      example.features.feature['other'].int64_list.value.append(0)\n      for _ in range(i):\n        example.features.feature['num'].int64_list.value.append(i)\n      examples.append(example)\n    example = tf.train.Example()\n    example.features.feature['other'].int64_list.value.append(0)\n    examples.append(example)\n\n    entries = {}\n    for i, example in enumerate(examples):\n      self.fs._ParseExample(example.features.feature, [], entries, i)\n\n    info = entries['num']\n    self.assertEqual(2, info['missing'])\n    self.assertEqual(4, len(info['counts']))\n    for i in range(4):\n      self.assertEqual(i + 1, info['counts'][i])\n    self.assertEqual(10, len(info['vals']))\n\n  def testParseExampleStringsAndFloats(self):\n    # Tests parsing examples of string and float features\n    examples = []\n    for i in range(50):\n      example = tf.train.Example()\n      example.features.feature['str'].bytes_list.value.append(b'hi')\n      example.features.feature['float'].float_list.value.append(i)\n      examples.append(example)\n\n    entries = {}\n    for i, example in enumerate(examples):\n      self.fs._ParseExample(example.features.feature, [], entries, i)\n\n    self.assertEqual(2, len(entries))\n    self.assertEqual(self.fs.fs_proto.FLOAT, entries['float']['type'])\n    self.assertEqual(self.fs.fs_proto.STRING, entries['str']['type'])\n    for i in range(len(examples)):\n      self.assertEqual(1, entries['str']['counts'][i])\n      self.assertEqual(1, entries['float']['counts'][i])\n      self.assertEqual(i, entries['float']['vals'][i])\n      self.assertEqual('hi', entries['str']['vals'][i].decode(\n          'UTF-8', 'strict'))\n\n  def testParseExamplesTypeMismatch(self):\n    examples = []\n    example = tf.train.Example()\n    example.features.feature['feat'].int64_list.value.append(0)\n    examples.append(example)\n    example = tf.train.Example()\n    example.features.feature['feat'].bytes_list.value.append(b'str')\n    examples.append(example)\n\n    entries = {}\n    self.fs._ParseExample(examples[0].features.feature, [], entries, 0)\n\n    with self.assertRaises(TypeError):\n      self.fs._ParseExample(examples[1].features.feature, [], entries, 1)\n\n  def testGetDatasetsProtoFromEntriesLists(self):\n    entries = {}\n    entries['testFeature'] = {\n        'vals': [1, 2, 3],\n        'counts': [1, 1, 1],\n        'missing': 0,\n        'type': self.fs.fs_proto.INT\n    }\n    datasets = [{'entries': entries, 'size': 3, 'name': 'testDataset'}]\n    p = self.fs.GetDatasetsProto(datasets)\n\n    self.assertEqual(1, len(p.datasets))\n    test_data = p.datasets[0]\n    self.assertEqual('testDataset', test_data.name)\n    self.assertEqual(3, test_data.num_examples)\n    self.assertEqual(1, len(test_data.features))\n    numfeat = test_data.features[0]\n    self.assertEqual('testFeature', numfeat.name)\n    self.assertEqual(self.fs.fs_proto.INT, numfeat.type)\n    self.assertEqual(1, numfeat.num_stats.min)\n    self.assertEqual(3, numfeat.num_stats.max)\n\n  def testGetProtoNums(self):\n    # Tests converting int examples into the feature stats proto\n    examples = []\n    for i in range(50):\n      example = tf.train.Example()\n      example.features.feature['num'].int64_list.value.append(i)\n      examples.append(example)\n    example = tf.train.Example()\n    example.features.feature['other'].int64_list.value.append(0)\n    examples.append(example)\n\n    entries = {}\n    for i, example in enumerate(examples):\n      self.fs._ParseExample(example.features.feature, [], entries, i)\n\n    datasets = [{'entries': entries, 'size': len(examples), 'name': 'test'}]\n    p = self.fs.GetDatasetsProto(datasets)\n\n    self.assertEqual(1, len(p.datasets))\n    test_data = p.datasets[0]\n    self.assertEqual('test', test_data.name)\n    self.assertEqual(51, test_data.num_examples)\n\n    numfeat = test_data.features[0] if (\n        test_data.features[0].name == 'num') else test_data.features[1]\n    self.assertEqual('num', numfeat.name)\n    self.assertEqual(self.fs.fs_proto.INT, numfeat.type)\n    self.assertEqual(0, numfeat.num_stats.min)\n    self.assertEqual(49, numfeat.num_stats.max)\n    self.assertEqual(24.5, numfeat.num_stats.mean)\n    self.assertEqual(24.5, numfeat.num_stats.median)\n    self.assertEqual(1, numfeat.num_stats.num_zeros)\n    self.assertAlmostEqual(14.430869689, numfeat.num_stats.std_dev, 4)\n    self.assertEqual(1, numfeat.num_stats.common_stats.num_missing)\n    self.assertEqual(50, numfeat.num_stats.common_stats.num_non_missing)\n    self.assertEqual(1, numfeat.num_stats.common_stats.min_num_values)\n    self.assertEqual(1, numfeat.num_stats.common_stats.max_num_values)\n    self.assertAlmostEqual(1, numfeat.num_stats.common_stats.avg_num_values, 4)\n    hist = numfeat.num_stats.common_stats.num_values_histogram\n    buckets = hist.buckets\n    self.assertEqual(self.fs.histogram_proto.QUANTILES, hist.type)\n    self.assertEqual(10, len(buckets))\n    self.assertEqual(1, buckets[0].low_value)\n    self.assertEqual(1, buckets[0].high_value)\n    self.assertEqual(5, buckets[0].sample_count)\n    self.assertEqual(1, buckets[9].low_value)\n    self.assertEqual(1, buckets[9].high_value)\n    self.assertEqual(5, buckets[9].sample_count)\n\n    self.assertEqual(2, len(numfeat.num_stats.histograms))\n    buckets = numfeat.num_stats.histograms[0].buckets\n    self.assertEqual(self.fs.histogram_proto.STANDARD,\n                     numfeat.num_stats.histograms[0].type)\n    self.assertEqual(10, len(buckets))\n    self.assertEqual(0, buckets[0].low_value)\n    self.assertEqual(4.9, buckets[0].high_value)\n    self.assertEqual(5, buckets[0].sample_count)\n    self.assertAlmostEqual(44.1, buckets[9].low_value)\n    self.assertEqual(49, buckets[9].high_value)\n    self.assertEqual(5, buckets[9].sample_count)\n\n    buckets = numfeat.num_stats.histograms[1].buckets\n    self.assertEqual(self.fs.histogram_proto.QUANTILES,\n                     numfeat.num_stats.histograms[1].type)\n    self.assertEqual(10, len(buckets))\n    self.assertEqual(0, buckets[0].low_value)\n    self.assertEqual(4.9, buckets[0].high_value)\n    self.assertEqual(5, buckets[0].sample_count)\n    self.assertAlmostEqual(44.1, buckets[9].low_value)\n    self.assertEqual(49, buckets[9].high_value)\n    self.assertEqual(5, buckets[9].sample_count)\n\n  def testQuantiles(self):\n    examples = []\n    for i in range(50):\n      example = tf.train.Example()\n      example.features.feature['num'].int64_list.value.append(i)\n      examples.append(example)\n    for i in range(50):\n      example = tf.train.Example()\n      example.features.feature['num'].int64_list.value.append(100)\n      examples.append(example)\n\n    entries = {}\n    for i, example in enumerate(examples):\n      self.fs._ParseExample(example.features.feature, [], entries, i)\n\n    datasets = [{'entries': entries, 'size': len(examples), 'name': 'test'}]\n    p = self.fs.GetDatasetsProto(datasets)\n\n    numfeat = p.datasets[0].features[0]\n    self.assertEqual(2, len(numfeat.num_stats.histograms))\n    self.assertEqual(self.fs.histogram_proto.QUANTILES,\n                     numfeat.num_stats.histograms[1].type)\n    buckets = numfeat.num_stats.histograms[1].buckets\n    self.assertEqual(10, len(buckets))\n    self.assertEqual(0, buckets[0].low_value)\n    self.assertEqual(9.9, buckets[0].high_value)\n    self.assertEqual(10, buckets[0].sample_count)\n    self.assertEqual(100, buckets[9].low_value)\n    self.assertEqual(100, buckets[9].high_value)\n    self.assertEqual(10, buckets[9].sample_count)\n\n  def testInfinityAndNan(self):\n    examples = []\n    for i in range(50):\n      example = tf.train.Example()\n      example.features.feature['num'].float_list.value.append(i)\n      examples.append(example)\n    example = tf.train.Example()\n    example.features.feature['num'].float_list.value.append(float('inf'))\n    examples.append(example)\n    example = tf.train.Example()\n    example.features.feature['num'].float_list.value.append(float('-inf'))\n    examples.append(example)\n    example = tf.train.Example()\n    example.features.feature['num'].float_list.value.append(float('nan'))\n    examples.append(example)\n\n    entries = {}\n    for i, example in enumerate(examples):\n      self.fs._ParseExample(example.features.feature, [], entries, i)\n\n    datasets = [{'entries': entries, 'size': len(examples), 'name': 'test'}]\n    p = self.fs.GetDatasetsProto(datasets)\n\n    numfeat = p.datasets[0].features[0]\n\n    self.assertEqual('num', numfeat.name)\n    self.assertEqual(self.fs.fs_proto.FLOAT, numfeat.type)\n    self.assertTrue(np.isnan(numfeat.num_stats.min))\n    self.assertTrue(np.isnan(numfeat.num_stats.max))\n    self.assertTrue(np.isnan(numfeat.num_stats.mean))\n    self.assertTrue(np.isnan(numfeat.num_stats.median))\n    self.assertEqual(1, numfeat.num_stats.num_zeros)\n    self.assertTrue(np.isnan(numfeat.num_stats.std_dev))\n    self.assertEqual(53, numfeat.num_stats.common_stats.num_non_missing)\n    hist = buckets = numfeat.num_stats.histograms[0]\n    buckets = hist.buckets\n    self.assertEqual(self.fs.histogram_proto.STANDARD, hist.type)\n    self.assertEqual(1, hist.num_nan)\n    self.assertEqual(10, len(buckets))\n    self.assertEqual(float('-inf'), buckets[0].low_value)\n    self.assertEqual(4.9, buckets[0].high_value)\n    self.assertEqual(6, buckets[0].sample_count)\n    self.assertEqual(44.1, buckets[9].low_value)\n    self.assertEqual(float('inf'), buckets[9].high_value)\n    self.assertEqual(6, buckets[9].sample_count)\n\n  def testInfinitysOnly(self):\n    examples = []\n    example = tf.train.Example()\n    example.features.feature['num'].float_list.value.append(float('inf'))\n    examples.append(example)\n    example = tf.train.Example()\n    example.features.feature['num'].float_list.value.append(float('-inf'))\n    examples.append(example)\n\n    entries = {}\n    for i, example in enumerate(examples):\n      self.fs._ParseExample(example.features.feature, [], entries, i)\n\n    datasets = [{'entries': entries, 'size': len(examples), 'name': 'test'}]\n    p = self.fs.GetDatasetsProto(datasets)\n\n    numfeat = p.datasets[0].features[0]\n    hist = buckets = numfeat.num_stats.histograms[0]\n    buckets = hist.buckets\n    self.assertEqual(self.fs.histogram_proto.STANDARD, hist.type)\n    self.assertEqual(10, len(buckets))\n    self.assertEqual(float('-inf'), buckets[0].low_value)\n    self.assertEqual(0.1, buckets[0].high_value)\n    self.assertEqual(1, buckets[0].sample_count)\n    self.assertEqual(0.9, buckets[9].low_value)\n    self.assertEqual(float('inf'), buckets[9].high_value)\n    self.assertEqual(1, buckets[9].sample_count)\n\n  def testGetProtoStrings(self):\n    # Tests converting string examples into the feature stats proto\n    examples = []\n    for i in range(2):\n      example = tf.train.Example()\n      example.features.feature['str'].bytes_list.value.append(b'hello')\n      examples.append(example)\n    for i in range(3):\n      example = tf.train.Example()\n      example.features.feature['str'].bytes_list.value.append(b'hi')\n      examples.append(example)\n    example = tf.train.Example()\n    example.features.feature['str'].bytes_list.value.append(b'hey')\n    examples.append(example)\n\n    entries = {}\n    for i, example in enumerate(examples):\n      self.fs._ParseExample(example.features.feature, [], entries, i)\n\n    datasets = [{'entries': entries, 'size': len(examples), 'name': 'test'}]\n    p = self.fs.GetDatasetsProto(datasets)\n\n    self.assertEqual(1, len(p.datasets))\n    test_data = p.datasets[0]\n    self.assertEqual('test', test_data.name)\n    self.assertEqual(6, test_data.num_examples)\n\n    strfeat = test_data.features[0]\n    self.assertEqual('str', strfeat.name)\n    self.assertEqual(self.fs.fs_proto.STRING, strfeat.type)\n    self.assertEqual(3, strfeat.string_stats.unique)\n    self.assertAlmostEqual(19 / 6.0, strfeat.string_stats.avg_length, 4)\n    self.assertEqual(0, strfeat.string_stats.common_stats.num_missing)\n    self.assertEqual(6, strfeat.string_stats.common_stats.num_non_missing)\n    self.assertEqual(1, strfeat.string_stats.common_stats.min_num_values)\n    self.assertEqual(1, strfeat.string_stats.common_stats.max_num_values)\n    self.assertEqual(1, strfeat.string_stats.common_stats.avg_num_values)\n    hist = strfeat.string_stats.common_stats.num_values_histogram\n    buckets = hist.buckets\n    self.assertEqual(self.fs.histogram_proto.QUANTILES, hist.type)\n    self.assertEqual(10, len(buckets))\n    self.assertEqual(1, buckets[0].low_value)\n    self.assertEqual(1, buckets[0].high_value)\n    self.assertEqual(.6, buckets[0].sample_count)\n    self.assertEqual(1, buckets[9].low_value)\n    self.assertEqual(1, buckets[9].high_value)\n    self.assertEqual(.6, buckets[9].sample_count)\n\n    self.assertEqual(2, len(strfeat.string_stats.top_values))\n    self.assertEqual(3, strfeat.string_stats.top_values[0].frequency)\n    self.assertEqual('hi', strfeat.string_stats.top_values[0].value)\n    self.assertEqual(2, strfeat.string_stats.top_values[1].frequency)\n    self.assertEqual('hello', strfeat.string_stats.top_values[1].value)\n\n    buckets = strfeat.string_stats.rank_histogram.buckets\n    self.assertEqual(3, len(buckets))\n    self.assertEqual(0, buckets[0].low_rank)\n    self.assertEqual(0, buckets[0].high_rank)\n    self.assertEqual(3, buckets[0].sample_count)\n    self.assertEqual('hi', buckets[0].label)\n    self.assertEqual(2, buckets[2].low_rank)\n    self.assertEqual(2, buckets[2].high_rank)\n    self.assertEqual(1, buckets[2].sample_count)\n    self.assertEqual('hey', buckets[2].label)\n\n  def testGetProtoMultipleDatasets(self):\n    # Tests converting multiple datsets into the feature stats proto\n    # including ensuring feature order is consistent in the protos.\n    examples1 = []\n    for i in range(2):\n      example = tf.train.Example()\n      example.features.feature['str'].bytes_list.value.append(b'one')\n      example.features.feature['num'].int64_list.value.append(0)\n      examples1.append(example)\n    examples2 = []\n    example = tf.train.Example()\n    example.features.feature['num'].int64_list.value.append(1)\n    example.features.feature['str'].bytes_list.value.append(b'two')\n    examples2.append(example)\n\n    entries1 = {}\n    for i, example1 in enumerate(examples1):\n      self.fs._ParseExample(example1.features.feature, [], entries1, i)\n    entries2 = {}\n    for i, example2 in enumerate(examples2):\n      self.fs._ParseExample(example2.features.feature, [], entries2, i)\n\n    datasets = [{\n        'entries': entries1,\n        'size': len(examples1),\n        'name': 'test1'\n    }, {\n        'entries': entries2,\n        'size': len(examples2),\n        'name': 'test2'\n    }]\n    p = self.fs.GetDatasetsProto(datasets)\n\n    self.assertEqual(2, len(p.datasets))\n    test_data_1 = p.datasets[0]\n    self.assertEqual('test1', test_data_1.name)\n    self.assertEqual(2, test_data_1.num_examples)\n    num_feat_index = 0 if test_data_1.features[0].name == 'num' else 1\n    self.assertEqual(0, test_data_1.features[num_feat_index].num_stats.max)\n    test_data_2 = p.datasets[1]\n    self.assertEqual('test2', test_data_2.name)\n    self.assertEqual(1, test_data_2.num_examples)\n    self.assertEqual(1, test_data_2.features[num_feat_index].num_stats.max)\n\n  def testGetEntriesNoFiles(self):\n    features, num_examples = self.fs._GetEntries(['test'], 10,\n                                                 lambda unused_path: [])\n    self.assertEqual(0, num_examples)\n    self.assertEqual({}, features)\n\n  @staticmethod\n  def get_example_iter():\n\n    def ex_iter(unused_filename):\n      examples = []\n      for i in range(50):\n        example = tf.train.Example()\n        example.features.feature['num'].int64_list.value.append(i)\n        examples.append(example.SerializeToString())\n      return examples\n\n    return ex_iter\n\n  def testGetEntries_one(self):\n    features, num_examples = self.fs._GetEntries(['test'], 1,\n                                                 self.get_example_iter())\n    self.assertEqual(1, num_examples)\n    self.assertTrue('num' in features)\n\n  def testGetEntries_oneFile(self):\n    unused_features, num_examples = self.fs._GetEntries(['test'], 1000,\n                                                        self.get_example_iter())\n    self.assertEqual(50, num_examples)\n\n  def testGetEntries_twoFiles(self):\n    unused_features, num_examples = self.fs._GetEntries(['test0', 'test1'],\n                                                        1000,\n                                                        self.get_example_iter())\n    self.assertEqual(100, num_examples)\n\n  def testGetEntries_stopInSecondFile(self):\n    unused_features, num_examples = self.fs._GetEntries([\n        'test@0', 'test@1', 'test@2', 'test@3', 'test@4', 'test@5', 'test@6',\n        'test@7', 'test@8', 'test@9'\n    ], 75, self.get_example_iter())\n    self.assertEqual(75, num_examples)\n\n\nif __name__ == '__main__':\n  googletest.main()\n"
  },
  {
    "path": "tests/_util/generic_feature_statistics_generator_test.py",
    "content": "# Copyright 2017 Google Inc. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n# ==============================================================================\nfrom google.datalab.utils.facets.generic_feature_statistics_generator \\\n    import GenericFeatureStatisticsGenerator\nimport numpy as np\nimport pandas as pd\nfrom tensorflow.python.platform import googletest\n\n\nclass GenericFeatureStatisticsGeneratorTest(googletest.TestCase):\n\n  def setUp(self):\n    self.gfsg = GenericFeatureStatisticsGenerator()\n\n  def testProtoFromDataFrames(self):\n    data = [[1, 'hi'], [2, 'hello'], [3, 'hi']]\n    df = pd.DataFrame(data, columns=['testFeatureInt', 'testFeatureString'])\n    dataframes = [{'table': df, 'name': 'testDataset'}]\n    p = self.gfsg.ProtoFromDataFrames(dataframes)\n\n    self.assertEqual(1, len(p.datasets))\n    test_data = p.datasets[0]\n    self.assertEqual('testDataset', test_data.name)\n    self.assertEqual(3, test_data.num_examples)\n    self.assertEqual(2, len(test_data.features))\n\n    if test_data.features[0].name == 'testFeatureInt':\n      numfeat = test_data.features[0]\n      stringfeat = test_data.features[1]\n    else:\n      numfeat = test_data.features[1]\n      stringfeat = test_data.features[0]\n\n    self.assertEqual('testFeatureInt', numfeat.name)\n    self.assertEqual(self.gfsg.fs_proto.INT, numfeat.type)\n    self.assertEqual(1, numfeat.num_stats.min)\n    self.assertEqual(3, numfeat.num_stats.max)\n    self.assertEqual('testFeatureString', stringfeat.name)\n    self.assertEqual(self.gfsg.fs_proto.STRING, stringfeat.type)\n    self.assertEqual(2, stringfeat.string_stats.unique)\n\n  def testNdarrayToEntry(self):\n    arr = np.array([1.0, 2.0, None, float('nan'), 3.0], dtype=float)\n\n    entry = self.gfsg.NdarrayToEntry(arr)\n    self.assertEqual(2, entry['missing'])\n\n    arr = np.array(['a', 'b', float('nan'), 'c'], dtype=str)\n    entry = self.gfsg.NdarrayToEntry(arr)\n    self.assertEqual(1, entry['missing'])\n\n  def testNdarrayToEntryTimeTypes(self):\n    arr = np.array(\n        [np.datetime64('2005-02-25'),\n         np.datetime64('2006-02-25')],\n        dtype=np.datetime64)\n    entry = self.gfsg.NdarrayToEntry(arr)\n    self.assertEqual([1109289600000000000, 1140825600000000000], entry['vals'])\n\n    arr = np.array(\n        [np.datetime64('2009-01-01') - np.datetime64('2008-01-01')],\n        dtype=np.timedelta64)\n    entry = self.gfsg.NdarrayToEntry(arr)\n    self.assertEqual([31622400000000000], entry['vals'])\n\n  def testDTypeToType(self):\n    self.assertEqual(self.gfsg.fs_proto.INT,\n                     self.gfsg.DtypeToType(np.dtype(np.int32)))\n    # Boolean and time types treated as int\n    self.assertEqual(self.gfsg.fs_proto.INT,\n                     self.gfsg.DtypeToType(np.dtype(np.bool)))\n    self.assertEqual(self.gfsg.fs_proto.INT,\n                     self.gfsg.DtypeToType(np.dtype(np.datetime64)))\n    self.assertEqual(self.gfsg.fs_proto.INT,\n                     self.gfsg.DtypeToType(np.dtype(np.timedelta64)))\n    self.assertEqual(self.gfsg.fs_proto.FLOAT,\n                     self.gfsg.DtypeToType(np.dtype(np.float32)))\n    self.assertEqual(self.gfsg.fs_proto.STRING,\n                     self.gfsg.DtypeToType(np.dtype(np.str)))\n    # Unsupported types treated as string for now\n    self.assertEqual(self.gfsg.fs_proto.STRING,\n                     self.gfsg.DtypeToType(np.dtype(np.void)))\n\n  def testGetDatasetsProtoFromEntriesLists(self):\n    entries = {}\n    entries['testFeature'] = {\n        'vals': [1, 2, 3],\n        'counts': [1, 1, 1],\n        'missing': 0,\n        'type': self.gfsg.fs_proto.INT\n    }\n    datasets = [{'entries': entries, 'size': 3, 'name': 'testDataset'}]\n    p = self.gfsg.GetDatasetsProto(datasets)\n\n    self.assertEqual(1, len(p.datasets))\n    test_data = p.datasets[0]\n    self.assertEqual('testDataset', test_data.name)\n    self.assertEqual(3, test_data.num_examples)\n    self.assertEqual(1, len(test_data.features))\n    numfeat = test_data.features[0]\n    self.assertEqual('testFeature', numfeat.name)\n    self.assertEqual(self.gfsg.fs_proto.INT, numfeat.type)\n    self.assertEqual(1, numfeat.num_stats.min)\n    self.assertEqual(3, numfeat.num_stats.max)\n    hist = numfeat.num_stats.common_stats.num_values_histogram\n    buckets = hist.buckets\n    self.assertEqual(self.gfsg.histogram_proto.QUANTILES, hist.type)\n    self.assertEqual(10, len(buckets))\n    self.assertEqual(1, buckets[0].low_value)\n    self.assertEqual(1, buckets[0].high_value)\n    self.assertEqual(.3, buckets[0].sample_count)\n    self.assertEqual(1, buckets[9].low_value)\n    self.assertEqual(1, buckets[9].high_value)\n    self.assertEqual(.3, buckets[9].sample_count)\n\n  def testGetDatasetsProtoSequenceExampleHistogram(self):\n    entries = {}\n    entries['testFeature'] = {\n        'vals': [1, 2, 2, 3],\n        'counts': [1, 2, 1],\n        'feat_lens': [1, 2, 1],\n        'missing': 0,\n        'type': self.gfsg.fs_proto.INT\n    }\n    datasets = [{'entries': entries, 'size': 3, 'name': 'testDataset'}]\n    p = self.gfsg.GetDatasetsProto(datasets)\n    hist = p.datasets[0].features[\n        0].num_stats.common_stats.feature_list_length_histogram\n    buckets = hist.buckets\n    self.assertEqual(self.gfsg.histogram_proto.QUANTILES, hist.type)\n    self.assertEqual(10, len(buckets))\n    self.assertEqual(1, buckets[0].low_value)\n    self.assertEqual(1, buckets[0].high_value)\n    self.assertEqual(.3, buckets[0].sample_count)\n    self.assertEqual(1.8, buckets[9].low_value)\n    self.assertEqual(2, buckets[9].high_value)\n    self.assertEqual(.3, buckets[9].sample_count)\n\n  def testGetDatasetsProtoWithAllowlist(self):\n    entries = {}\n    entries['testFeature'] = {\n        'vals': [1, 2, 3],\n        'counts': [1, 1, 1],\n        'missing': 0,\n        'type': self.gfsg.fs_proto.INT\n    }\n    entries['ignoreFeature'] = {\n        'vals': [5, 6],\n        'counts': [1, 1],\n        'missing': 1,\n        'type': self.gfsg.fs_proto.INT\n    }\n    datasets = [{'entries': entries, 'size': 3, 'name': 'testDataset'}]\n    p = self.gfsg.GetDatasetsProto(datasets, features=['testFeature'])\n\n    self.assertEqual(1, len(p.datasets))\n    test_data = p.datasets[0]\n    self.assertEqual('testDataset', test_data.name)\n    self.assertEqual(3, test_data.num_examples)\n    self.assertEqual(1, len(test_data.features))\n    numfeat = test_data.features[0]\n    self.assertEqual('testFeature', numfeat.name)\n    self.assertEqual(1, numfeat.num_stats.min)\n\n\nif __name__ == '__main__':\n  googletest.main()\n"
  },
  {
    "path": "tests/_util/http_tests.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nimport mock\nimport unittest\n\n# The httplib2 import is implicitly used when mocking its functionality.\n# pylint: disable=unused-import\nfrom google.datalab.utils._http import Http\n\n\nclass TestCases(unittest.TestCase):\n\n  @mock.patch('httplib2.Response')\n  @mock.patch('google.datalab.utils._http.Http.http.request')\n  def test_get_request_is_invoked(self, mock_request, mock_response):\n    TestCases._setup_mocks(mock_request, mock_response, '{}')\n\n    Http.request('http://www.example.org')\n    self.assertEqual(mock_request.call_count, 1)\n    self.assertEqual(mock_request.call_args[1]['method'], 'GET')\n\n  @mock.patch('httplib2.Response')\n  @mock.patch('google.datalab.utils._http.Http.http.request')\n  def test_post_request_is_invoked(self, mock_request, mock_response):\n    TestCases._setup_mocks(mock_request, mock_response, '{}')\n\n    Http.request('http://www.example.org', data={})\n    self.assertEqual(mock_request.call_args[1]['method'], 'POST')\n\n  @mock.patch('httplib2.Response')\n  @mock.patch('google.datalab.utils._http.Http.http.request')\n  def test_explicit_post_request_is_invoked(self, mock_request, mock_response):\n    TestCases._setup_mocks(mock_request, mock_response, '{}')\n\n    Http.request('http://www.example.org', method='POST')\n    self.assertEqual(mock_request.call_args[1]['method'], 'POST')\n\n  @mock.patch('httplib2.Response')\n  @mock.patch('google.datalab.utils._http.Http.http.request')\n  def test_query_string_format(self, mock_request, mock_response):\n    TestCases._setup_mocks(mock_request, mock_response, '{}')\n\n    Http.request('http://www.example.org', args={'a': 1, 'b': 'a b c'})\n    parts = mock_request.call_args[0][0].replace('?', '&').split('&')\n    self.assertEqual(parts[0], 'http://www.example.org')\n    self.assertTrue('a=1' in parts[1:])\n    self.assertTrue('b=a+b+c' in parts[1:])\n\n  @mock.patch('httplib2.Response')\n  @mock.patch('google.datalab.utils._http.Http.http.request')\n  def test_formats_json_request(self, mock_request, mock_response):\n    TestCases._setup_mocks(mock_request, mock_response, '{}')\n\n    data = {'abc': 123}\n    Http.request('http://www.example.org', data=data)\n\n    self.assertEqual(mock_request.call_args[1]['body'], '{\"abc\": 123}')\n    self.assertEqual(mock_request.call_args[1]['headers']['Content-Type'],\n                     'application/json')\n\n  @mock.patch('httplib2.Response')\n  @mock.patch('google.datalab.utils._http.Http.http.request')\n  def test_supports_custom_content(self, mock_request, mock_response):\n    TestCases._setup_mocks(mock_request, mock_response, '{}')\n\n    headers = {'Content-Type': 'text/plain'}\n    data = 'custom text'\n    Http.request('http://www.example.org', data=data, headers=headers)\n\n    self.assertEqual(mock_request.call_args[1]['body'], 'custom text')\n    self.assertEqual(mock_request.call_args[1]['headers']['Content-Type'], 'text/plain')\n\n  @mock.patch('httplib2.Response')\n  @mock.patch('google.datalab.utils._http.Http.http.request')\n  def test_parses_json_response(self, mock_request, mock_response):\n    TestCases._setup_mocks(mock_request, mock_response, '{\"abc\":123}')\n\n    data = Http.request('http://www.example.org')\n    self.assertEqual(data['abc'], 123)\n\n  @mock.patch('httplib2.Response')\n  @mock.patch('google.datalab.utils._http.Http.http.request')\n  def test_raises_http_error_json(self, mock_request, mock_response):\n    TestCases._setup_mocks(\n      mock_request, mock_response,\n      b'{\"error\": {\"errors\": [{\"message\": \"Not Found\"}]}}', 404)\n    with self.assertRaises(Exception) as error:\n      Http.request('http://www.example.org')\n\n    e = error.exception\n    self.assertEqual(e.status, 404)\n    self.assertEqual(e.message, 'HTTP request failed: Not Found')\n\n  @mock.patch('httplib2.Response')\n  @mock.patch('google.datalab.utils._http.Http.http.request')\n  def test_raises_http_error_str(self, mock_request, mock_response):\n    TestCases._setup_mocks(mock_request, mock_response, 'Not Found', 404)\n\n    with self.assertRaises(Exception) as error:\n      Http.request('http://www.example.org')\n\n    e = error.exception\n    self.assertEqual(e.status, 404)\n    self.assertEqual(e.content, 'Not Found')\n\n  @mock.patch('httplib2.Response')\n  @mock.patch('google.datalab.utils._http.Http.http.request')\n  def test_raises_http_error_bytes(self, mock_request, mock_response):\n    TestCases._setup_mocks(mock_request, mock_response, b'Not Found', 404)\n\n    with self.assertRaises(Exception) as error:\n      Http.request('http://www.example.org')\n\n    e = error.exception\n    self.assertEqual(e.status, 404)\n    self.assertEqual(e.content, b'Not Found')\n\n  @staticmethod\n  def _setup_mocks(mock_request, mock_response, content, status=200):\n    response = mock_response()\n    response.status = status\n    mock_request.return_value = (response, content)\n"
  },
  {
    "path": "tests/_util/lru_cache_tests.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nimport unittest\n\nfrom google.datalab.utils._lru_cache import LRUCache\n\n\nclass TestCases(unittest.TestCase):\n\n  def test_cache_no_entry(self):\n    cache = LRUCache(3)\n    with self.assertRaises(KeyError):\n      cache['a']\n\n  def test_cache_lookup(self):\n    cache = LRUCache(4)\n    for x in ['a', 'b', 'c', 'd']:\n      cache[x] = x\n\n    for x in ['a', 'b', 'c', 'd']:\n      self.assertEqual(x, cache[x])\n\n  def test_cache_overflow(self):\n    cache = LRUCache(3)\n    for x in ['a', 'b', 'c', 'd']:\n      cache[x] = x\n\n    for x in ['b', 'c', 'd']:\n      self.assertEqual(x, cache[x])\n\n    with self.assertRaises(KeyError):\n      cache['a']\n\n    cache['b']\n    cache['d']\n    # 'c' should be LRU now\n    cache['e'] = 'e'\n\n    with self.assertRaises(KeyError):\n      cache['c']\n\n    for x in ['b', 'd', 'e']:\n      self.assertEqual(x, cache[x])\n"
  },
  {
    "path": "tests/_util/util_tests.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nimport imp\nimport unittest\nimport pytz\nimport mock\nimport os\n\nimport google.datalab.utils._utils as _utils\nimport google.datalab.utils._iterator as _iterator\nfrom datetime import datetime\nimport google.auth\nimport google.auth.exceptions\n\n\nclass TestCases(unittest.TestCase):\n\n  @staticmethod\n  def _get_data():\n    m = imp.new_module('baz')\n    exec('x = 99', m.__dict__)\n    data = {\n      'foo': {\n        'bar': {\n          'xyz': 0\n        },\n        'm': m\n      }\n    }\n    return data\n\n  def test_no_entry(self):\n    data = TestCases._get_data()\n    self.assertIsNone(_utils.get_item(data, ''))\n    self.assertIsNone(_utils.get_item(data, 'x'))\n    self.assertIsNone(_utils.get_item(data, 'bar.x'))\n    self.assertIsNone(_utils.get_item(data, 'foo.bar.x'))\n    self.assertIsNone(_utils.get_item(globals(), 'datetime.bar.x'))\n\n  def test_entry(self):\n    data = TestCases._get_data()\n    self.assertEquals(data['foo']['bar']['xyz'], _utils.get_item(data, 'foo.bar.xyz'))\n    self.assertEquals(data['foo']['bar'], _utils.get_item(data, 'foo.bar'))\n    self.assertEquals(data['foo'], _utils.get_item(data, 'foo'))\n    self.assertEquals(data['foo']['m'], _utils.get_item(data, 'foo.m'))\n    self.assertEquals(99, _utils.get_item(data, 'foo.m.x'))\n\n  def test_compare_datetimes(self):\n    t1, t2 = datetime(2017, 2, 2, 12, 0, 0), datetime(2017, 2, 2, 12, 0, 0)\n    self.assertEquals(_utils.compare_datetimes(t1, t2), 0)\n\n    t2 = t2.replace(hour=11)\n    self.assertEquals(_utils.compare_datetimes(t1, t2), 1)\n\n  def test_compare_datetimes_tz(self):\n    t1 = datetime(2017, 2, 2, 12, 0, 0)\n    t2 = datetime(2017, 2, 2, 12, 0, 0, tzinfo=pytz.timezone('US/Eastern'))\n\n    self.assertEquals(_utils.compare_datetimes(t1, t2), -1)\n\n    t1 = t1.replace(tzinfo=pytz.timezone('US/Pacific'))\n\n    self.assertEquals(_utils.compare_datetimes(t1, t2), 1)\n\n  @mock.patch('os.path.expanduser')\n  def test_get_config_dir(self, mock_expand_user):\n    mock_expand_user.return_value = 'user/relative/path'\n    with mock.patch.dict(os.environ, {'CLOUDSDK_CONFIG': 'test/path'}):\n      self.assertEquals(_utils.get_config_dir(), 'test/path')\n\n    self.assertEquals(_utils.get_config_dir(), 'user/relative/path/.config/gcloud')\n\n  @mock.patch('os.name', 'nt')\n  @mock.patch('os.path.join')\n  def test_get_config_dir_win(self, mock_path_join):\n    mock_path_join.side_effect = lambda x, y: x + y\n    self.assertEquals(_utils.get_config_dir(), 'C:\\\\gcloud')\n\n    mock_path_join.side_effect = lambda x, y: x + '\\\\' + y\n    with mock.patch.dict(os.environ, {'APPDATA': 'test\\\\path'}):\n      self.assertEquals(_utils.get_config_dir(), 'test\\\\path\\\\gcloud')\n\n  @mock.patch('google.datalab.utils._utils._in_datalab_docker')\n  @mock.patch('google.auth.credentials.with_scopes_if_required')\n  @mock.patch('google.auth.default')\n  @mock.patch('os.path.exists')\n  def test_get_credentials_from_file(self, mock_path_exists, mock_google_auth_default,\n                                     mock_with_scopes_if_required, mock_in_datalab):\n    # If application default credentials exist, use them\n    creds = mock.Mock(spec=google.auth.credentials.Credentials)\n    mock_google_auth_default.return_value = [creds, '']\n    _utils.get_credentials()\n    mock_google_auth_default.assert_called_once()\n    mock_with_scopes_if_required.assert_called_once()\n\n    # If application default credentials are not defined, should load from file\n    test_creds = '''\n      {\n        \"data\": [{\n          \"key\": {\n            \"type\": \"google-cloud-sdk\"\n          },\n          \"credential\": {\n            \"access_token\": \"test-access-token\",\n            \"client_id\": \"test-id\",\n            \"client_secret\": \"test-secret\",\n            \"refresh_token\": \"test-token\",\n            \"token_expiry\": \"test-expiry\",\n            \"token_uri\": \"test-url\",\n            \"user_agent\": \"test-agent\",\n            \"invalid\": \"false\"\n          }\n        }]\n      }\n    '''\n    with mock.patch('google.datalab.utils._utils.open', mock.mock_open(read_data=test_creds)):\n      mock_google_auth_default.side_effect = Exception\n      cred = _utils.get_credentials()\n\n      self.assertEquals(cred.token, 'test-access-token')\n\n    mock_path_exists.return_value = False\n    with self.assertRaises(Exception):\n      cred = _utils.get_credentials()\n\n    # If default creds are not defined, and no file exists with credentials, throw\n    # something more meaningful.\n    mock_google_auth_default.side_effect = google.auth.exceptions.DefaultCredentialsError\n    with self.assertRaisesRegexp(Exception,\n                                 'No application credentials found. Perhaps you should sign in'):\n      cred = _utils.get_credentials()\n\n  @mock.patch('subprocess.call')\n  @mock.patch('os.path.exists')\n  def test_save_project_id(self, mock_path_exists, mock_subprocess_call):\n    _utils.save_project_id('test-project')\n    mock_subprocess_call.assert_called_with([\n      'gcloud', 'config', 'set', 'project', 'test-project'\n    ])\n\n    mock_subprocess_call.side_effect = Exception\n\n    test_config = '''\n      {\n        \"project_id\": \"\"\n      }\n    '''\n    opener = mock.mock_open(read_data=test_config)\n    with mock.patch('google.datalab.utils._utils.open', opener):\n      _utils.save_project_id('test-project')\n      opener.assert_has_calls([mock.call().write('{\"project_id\": \"test-project\"}')])\n\n  @mock.patch('subprocess.Popen')\n  @mock.patch('os.path.exists')\n  def test_get_default_project_id(self, mock_path_exists, mock_subprocess_call):\n    mock_subprocess_call.return_value.communicate.return_value = ('test-project', '')\n    mock_subprocess_call.return_value.poll.return_value = 0\n    self.assertEquals(_utils.get_default_project_id(), 'test-project')\n    mock_subprocess_call.assert_called_with(\n      ['gcloud', 'config', 'list', '--format', 'value(core.project)'], stdout=-1)\n\n    mock_subprocess_call.side_effect = Exception\n\n    test_config = '''\n      {\n        \"project_id\": \"test-project2\"\n      }\n    '''\n    opener = mock.mock_open(read_data=test_config)\n    with mock.patch('google.datalab.utils._utils.open', opener):\n      self.assertEquals(_utils.get_default_project_id(), 'test-project2')\n\n    mock_path_exists.return_value = False\n    self.assertIsNone(_utils.get_default_project_id())\n\n    with mock.patch.dict(os.environ, {'PROJECT_ID': 'test-project3'}):\n      self.assertEquals(_utils.get_default_project_id(), 'test-project3')\n\n  def test_iterator(self):\n    max_count = 100\n    page_size = 10\n\n    def limited_retriever(next_item, running_count):\n      next_item = next_item or 1\n      result_count = min(page_size, max_count - running_count)\n      if result_count <= 0:\n        return [], None\n      return range(next_item, next_item + result_count), next_item + result_count\n\n    read_count = 0\n    for item in _iterator.Iterator(limited_retriever):\n      read_count += 1\n      self.assertLessEqual(read_count, max_count)\n"
  },
  {
    "path": "tests/bigquery/__init__.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n"
  },
  {
    "path": "tests/bigquery/api_tests.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nimport unittest\nimport mock\n\nimport google.auth\nimport google.datalab\nimport google.datalab.bigquery\nimport google.datalab.utils\nfrom google.datalab.bigquery._api import Api\n\n\nclass TestCases(unittest.TestCase):\n\n  def validate(self, mock_http_request, expected_url, expected_args=None, expected_data=None,\n               expected_headers=None, expected_method=None):\n    url = mock_http_request.call_args[0][0]\n    kwargs = mock_http_request.call_args[1]\n    self.assertEquals(expected_url, url)\n    if expected_args is not None:\n      self.assertEquals(expected_args, kwargs['args'])\n    else:\n      self.assertNotIn('args', kwargs)\n    if expected_data is not None:\n      self.assertEquals(expected_data, kwargs['data'])\n    else:\n      self.assertNotIn('data', kwargs)\n    if expected_headers is not None:\n      self.assertEquals(expected_headers, kwargs['headers'])\n    else:\n      self.assertNotIn('headers', kwargs)\n    if expected_method is not None:\n      self.assertEquals(expected_method, kwargs['method'])\n    else:\n      self.assertNotIn('method', kwargs)\n\n  @mock.patch('google.datalab.utils.Http.request')\n  def test_jobs_insert_load(self, mock_http_request):\n    api = TestCases._create_api()\n    api.jobs_insert_load('SOURCE', google.datalab.bigquery._utils.TableName('p', 'd', 't', ''))\n    self.maxDiff = None\n    expected_data = {\n      'kind': 'bigquery#job',\n      'configuration': {\n        'load': {\n          'sourceUris': ['SOURCE'],\n          'destinationTable': {\n            'projectId': 'p',\n            'datasetId': 'd',\n            'tableId': 't'\n          },\n          'createDisposition': 'CREATE_NEVER',\n          'writeDisposition': 'WRITE_EMPTY',\n          'sourceFormat': 'CSV',\n          'fieldDelimiter': ',',\n          'allowJaggedRows': False,\n          'allowQuotedNewlines': False,\n          'encoding': 'UTF-8',\n          'ignoreUnknownValues': False,\n          'maxBadRecords': 0,\n          'quote': '\"',\n          'skipLeadingRows': 0\n        }\n      }\n    }\n    self.validate(mock_http_request, 'https://www.googleapis.com/bigquery/v2/projects/p/jobs/',\n                  expected_data=expected_data)\n\n    api.jobs_insert_load('SOURCE2', google.datalab.bigquery._utils.TableName('p2', 'd2', 't2', ''),\n                         append=True, create=True, allow_jagged_rows=True,\n                         allow_quoted_newlines=True, ignore_unknown_values=True,\n                         source_format='JSON', max_bad_records=1)\n    expected_data = {\n      'kind': 'bigquery#job',\n      'configuration': {\n        'load': {\n          'sourceUris': ['SOURCE2'],\n          'destinationTable': {\n            'projectId': 'p2',\n            'datasetId': 'd2',\n            'tableId': 't2'\n          },\n          'createDisposition': 'CREATE_IF_NEEDED',\n          'writeDisposition': 'WRITE_APPEND',\n          'sourceFormat': 'JSON',\n          'ignoreUnknownValues': True,\n          'maxBadRecords': 1\n        }\n      }\n    }\n    self.validate(mock_http_request, 'https://www.googleapis.com/bigquery/v2/projects/p2/jobs/',\n                  expected_data=expected_data)\n\n  @mock.patch('google.datalab.utils.Http.request')\n  def test_jobs_insert_query(self, mock_http_request):\n    context = TestCases._create_context()\n    context.config['bigquery_billing_tier'] = None\n    api = TestCases._create_api(context)\n    api.jobs_insert_query('SQL')\n    expected_data = {\n      'kind': 'bigquery#job',\n      'configuration': {\n        'query': {\n          'query': 'SQL',\n          'useQueryCache': True,\n          'allowLargeResults': False,\n          'useLegacySql': False,\n        },\n        'dryRun': False,\n        'priority': 'BATCH',\n      },\n    }\n    self.validate(mock_http_request, 'https://www.googleapis.com/bigquery/v2/projects/test/jobs/',\n                  expected_data=expected_data)\n\n    context.config['bigquery_billing_tier'] = 1\n    api.jobs_insert_query('SQL2',\n                          table_name=google.datalab.bigquery._utils.TableName('p', 'd', 't', ''),\n                          append=True, dry_run=True, use_cache=False, batch=False,\n                          allow_large_results=True)\n    expected_data = {\n      'kind': 'bigquery#job',\n      'configuration': {\n        'query': {\n          'query': 'SQL2',\n          'useQueryCache': False,\n          'allowLargeResults': True,\n          'useLegacySql': False,\n          'maximumBillingTier': 1,\n          'destinationTable': {\n            'projectId': 'p',\n            'datasetId': 'd',\n            'tableId': 't'\n          },\n          'writeDisposition': 'WRITE_APPEND',\n        },\n        'dryRun': True,\n        'priority': 'INTERACTIVE',\n      },\n    }\n    self.maxDiff = None\n    self.validate(mock_http_request, 'https://www.googleapis.com/bigquery/v2/projects/test/jobs/',\n                  expected_data=expected_data)\n\n  @mock.patch('google.datalab.utils.Http.request')\n  def test_jobs_query_results(self, mock_http_request):\n    api = TestCases._create_api()\n    api.jobs_query_results('JOB', 'PROJECT', 10, 20, 30)\n    self.validate(mock_http_request,\n                  'https://www.googleapis.com/bigquery/v2/projects/PROJECT/queries/JOB',\n                  expected_args={'maxResults': 10, 'timeoutMs': 20, 'startIndex': 30})\n\n  @mock.patch('google.datalab.utils.Http.request')\n  def test_jobs_get(self, mock_http_request):\n    api = TestCases._create_api()\n    api.jobs_get('JOB', 'PROJECT')\n    self.validate(mock_http_request,\n                  'https://www.googleapis.com/bigquery/v2/projects/PROJECT/jobs/JOB')\n\n  @mock.patch('google.datalab.utils.Http.request')\n  def test_datasets_insert(self, mock_http_request):\n    api = TestCases._create_api()\n    api.datasets_insert(google.datalab.bigquery._utils.DatasetName('p', 'd'))\n    expected_data = {\n      'kind': 'bigquery#dataset',\n      'datasetReference': {\n        'projectId': 'p',\n        'datasetId': 'd',\n      }\n    }\n    self.validate(mock_http_request, 'https://www.googleapis.com/bigquery/v2/projects/p/datasets/',\n                  expected_data=expected_data)\n    api.datasets_insert(google.datalab.bigquery._utils.DatasetName('p', 'd'), 'FRIENDLY',\n                        'DESCRIPTION')\n    expected_data = {\n      'kind': 'bigquery#dataset',\n      'datasetReference': {\n        'projectId': 'p',\n        'datasetId': 'd'\n      },\n      'friendlyName': 'FRIENDLY',\n      'description': 'DESCRIPTION'\n    }\n    self.validate(mock_http_request, 'https://www.googleapis.com/bigquery/v2/projects/p/datasets/',\n                  expected_data=expected_data)\n\n  @mock.patch('google.datalab.utils.Http.request')\n  def test_datasets_delete(self, mock_http_request):\n    api = TestCases._create_api()\n    api.datasets_delete(google.datalab.bigquery._utils.DatasetName('p', 'd'), False)\n    self.validate(mock_http_request, 'https://www.googleapis.com/bigquery/v2/projects/p/datasets/d',\n                  expected_args={},\n                  expected_method='DELETE')\n    api.datasets_delete(google.datalab.bigquery._utils.DatasetName('p', 'd'), True)\n    self.validate(mock_http_request, 'https://www.googleapis.com/bigquery/v2/projects/p/datasets/d',\n                  expected_args={'deleteContents': True},\n                  expected_method='DELETE')\n\n  @mock.patch('google.datalab.utils.Http.request')\n  def test_datasets_update(self, mock_http_request):\n    api = TestCases._create_api()\n    api.datasets_update(google.datalab.bigquery._utils.DatasetName('p', 'd'), 'INFO')\n    self.validate(mock_http_request, 'https://www.googleapis.com/bigquery/v2/projects/p/datasets/d',\n                  expected_method='PUT', expected_data='INFO')\n\n  @mock.patch('google.datalab.utils.Http.request')\n  def test_datasets_get(self, mock_http_request):\n    api = TestCases._create_api()\n    api.datasets_get(google.datalab.bigquery._utils.DatasetName('p', 'd'))\n    self.validate(mock_http_request, 'https://www.googleapis.com/bigquery/v2/projects/p/datasets/d')\n\n  @mock.patch('google.datalab.utils.Http.request')\n  def test_datasets_list(self, mock_http_request):\n    api = TestCases._create_api()\n    api.datasets_list()\n    self.validate(mock_http_request,\n                  'https://www.googleapis.com/bigquery/v2/projects/test/datasets/',\n                  expected_args={})\n\n    api.datasets_list('PROJECT', 10, 'TOKEN')\n    self.validate(mock_http_request,\n                  'https://www.googleapis.com/bigquery/v2/projects/PROJECT/datasets/',\n                  expected_args={'maxResults': 10, 'pageToken': 'TOKEN'})\n\n  @mock.patch('google.datalab.utils.Http.request')\n  def test_tables_get(self, mock_http_request):\n    api = TestCases._create_api()\n    api.tables_get(google.datalab.bigquery._utils.TableName('p', 'd', 't', ''))\n    self.validate(mock_http_request,\n                  'https://www.googleapis.com/bigquery/v2/projects/p/datasets/d/tables/t')\n\n  @mock.patch('google.datalab.utils.Http.request')\n  def test_tables_list(self, mock_http_request):\n    api = TestCases._create_api()\n    api.tables_list(google.datalab.bigquery._utils.DatasetName('p', 'd'))\n    self.validate(mock_http_request,\n                  'https://www.googleapis.com/bigquery/v2/projects/p/datasets/d/tables/',\n                  expected_args={})\n\n    api.tables_list(google.datalab.bigquery._utils.DatasetName('p', 'd'), 10, 'TOKEN')\n    self.validate(mock_http_request,\n                  'https://www.googleapis.com/bigquery/v2/projects/p/datasets/d/tables/',\n                  expected_args={'maxResults': 10, 'pageToken': 'TOKEN'})\n\n  @mock.patch('google.datalab.utils.Http.request')\n  def test_tables_insert(self, mock_http_request):\n    api = TestCases._create_api()\n    api.tables_insert(google.datalab.bigquery._utils.TableName('p', 'd', 't', ''))\n    expected_data = {\n      'kind': 'bigquery#table',\n      'tableReference': {\n        'projectId': 'p',\n        'datasetId': 'd',\n        'tableId': 't'\n      }\n    }\n    self.validate(mock_http_request,\n                  'https://www.googleapis.com/bigquery/v2/projects/p/datasets/d/tables/',\n                  expected_data=expected_data)\n\n    api.tables_insert(google.datalab.bigquery._utils.TableName('p', 'd', 't', ''),\n                      'SCHEMA', 'QUERY', 'FRIENDLY', 'DESCRIPTION')\n    expected_data = {\n      'kind': 'bigquery#table',\n      'tableReference': {\n        'projectId': 'p',\n        'datasetId': 'd',\n        'tableId': 't'\n      },\n      'schema': {\n        'fields': 'SCHEMA'\n      },\n      'view': {'query': 'QUERY'},\n      'friendlyName': 'FRIENDLY',\n      'description': 'DESCRIPTION'\n    }\n    self.validate(mock_http_request,\n                  'https://www.googleapis.com/bigquery/v2/projects/p/datasets/d/tables/',\n                  expected_data=expected_data)\n\n  @mock.patch('google.datalab.utils.Http.request')\n  def test_tabledata_insertAll(self, mock_http_request):\n    api = TestCases._create_api()\n    api.tabledata_insert_all(google.datalab.bigquery._utils.TableName('p', 'd', 't', ''), 'ROWS')\n    expected_data = {\n      'kind': 'bigquery#tableDataInsertAllRequest',\n      'rows': 'ROWS'\n    }\n    self.validate(mock_http_request,\n                  'https://www.googleapis.com/bigquery/v2/projects/p/datasets/d/tables/t/insertAll',\n                  expected_data=expected_data)\n\n  @mock.patch('google.datalab.utils.Http.request')\n  def test_tabledata_list(self, mock_http_request):\n    api = TestCases._create_api()\n    api.tabledata_list(google.datalab.bigquery._utils.TableName('p', 'd', 't', ''))\n    self.validate(mock_http_request,\n                  'https://www.googleapis.com/bigquery/v2/projects/p/datasets/d/tables/t/data',\n                  expected_args={})\n\n    api.tabledata_list(google.datalab.bigquery._utils.TableName('p', 'd', 't', ''), 10, 20, 'TOKEN')\n    self.validate(mock_http_request,\n                  'https://www.googleapis.com/bigquery/v2/projects/p/datasets/d/tables/t/data',\n                  expected_args={\n                    'startIndex': 10,\n                    'maxResults': 20,\n                    'pageToken': 'TOKEN'\n                  })\n\n  @mock.patch('google.datalab.utils.Http.request')\n  def test_table_delete(self, mock_http_request):\n    api = TestCases._create_api()\n    api.table_delete(google.datalab.bigquery._utils.TableName('p', 'd', 't', ''))\n    self.validate(mock_http_request,\n                  'https://www.googleapis.com/bigquery/v2/projects/p/datasets/d/tables/t',\n                  expected_method='DELETE')\n\n  @mock.patch('google.datalab.utils.Http.request')\n  def test_table_extract(self, mock_http_request):\n    api = TestCases._create_api()\n    api.table_extract(google.datalab.bigquery._utils.TableName('p', 'd', 't', ''), 'DEST')\n    expected_data = {\n      'kind': 'bigquery#job',\n      'configuration': {\n        'extract': {\n          'sourceTable': {\n            'projectId': 'p',\n            'datasetId': 'd',\n            'tableId': 't'\n          },\n          'compression': 'GZIP',\n          'fieldDelimiter': ',',\n          'printHeader': True,\n          'destinationUris': ['DEST'],\n          'destinationFormat': 'CSV',\n        }\n      }\n    }\n    self.validate(mock_http_request,\n                  'https://www.googleapis.com/bigquery/v2/projects/p/jobs/',\n                  expected_data=expected_data)\n\n    api.table_extract(google.datalab.bigquery._utils.TableName('p', 'd', 't', ''),\n                      ['DEST'], format='JSON', compress=False, field_delimiter=':',\n                      print_header=False)\n    expected_data = {\n      'kind': 'bigquery#job',\n      'configuration': {\n        'extract': {\n          'sourceTable': {\n            'projectId': 'p',\n            'datasetId': 'd',\n            'tableId': 't'\n          },\n          'compression': 'NONE',\n          'fieldDelimiter': ':',\n          'printHeader': False,\n          'destinationUris': ['DEST'],\n          'destinationFormat': 'JSON',\n        }\n      }\n    }\n    self.validate(mock_http_request, 'https://www.googleapis.com/bigquery/v2/projects/p/jobs/',\n                  expected_data=expected_data)\n\n  @mock.patch('google.datalab.utils.Http.request')\n  def test_table_update(self, mock_http_request):\n    api = TestCases._create_api()\n    api.table_update(google.datalab.bigquery._utils.TableName('p', 'd', 't', ''), 'INFO')\n    self.validate(mock_http_request,\n                  'https://www.googleapis.com/bigquery/v2/projects/p/datasets/d/tables/t',\n                  expected_method='PUT', expected_data='INFO')\n\n  @staticmethod\n  def _create_api(context=None):\n    if not context:\n      context = TestCases._create_context()\n    return Api(context)\n\n  @staticmethod\n  def _create_context():\n    project_id = 'test'\n    creds = mock.Mock(spec=google.auth.credentials.Credentials)\n    return google.datalab.Context(project_id, creds)\n"
  },
  {
    "path": "tests/bigquery/dataset_tests.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom builtins import str\nimport mock\nimport unittest\n\nimport google.auth\nimport google.datalab\nimport google.datalab.bigquery\nimport google.datalab.utils\n\n\nclass TestCases(unittest.TestCase):\n\n  def _check_name_parts(self, dataset):\n    parsed_name = dataset._name_parts\n    self.assertEqual('test', parsed_name[0])\n    self.assertEqual('requestlogs', parsed_name[1])\n    self.assertEqual('test.requestlogs', dataset._full_name)\n    self.assertEqual('test.requestlogs', str(dataset))\n\n  def test_parse_full_name(self):\n    dataset = TestCases._create_dataset('test.requestlogs')\n    self._check_name_parts(dataset)\n\n  def test_parse_local_name(self):\n    dataset = TestCases._create_dataset('requestlogs')\n    self._check_name_parts(dataset)\n\n  def test_parse_dict_full_name(self):\n    dataset = TestCases._create_dataset({'project_id': 'test', 'dataset_id': 'requestlogs'})\n    self._check_name_parts(dataset)\n\n  def test_parse_dict_local_name(self):\n    dataset = TestCases._create_dataset({'dataset_id': 'requestlogs'})\n    self._check_name_parts(dataset)\n\n  def test_parse_named_tuple_name(self):\n    dataset = TestCases._create_dataset(google.datalab.bigquery._utils.DatasetName('test',\n                                                                                   'requestlogs'))\n    self._check_name_parts(dataset)\n\n  def test_parse_tuple_full_name(self):\n    dataset = TestCases._create_dataset(('test', 'requestlogs'))\n    self._check_name_parts(dataset)\n\n  def test_parse_tuple_local(self):\n    dataset = TestCases._create_dataset(('requestlogs'))\n    self._check_name_parts(dataset)\n\n  def test_parse_array_full_name(self):\n    dataset = TestCases._create_dataset(['test', 'requestlogs'])\n    self._check_name_parts(dataset)\n\n  def test_parse_array_local(self):\n    dataset = TestCases._create_dataset(['requestlogs'])\n    self._check_name_parts(dataset)\n\n  def test_parse_invalid_name(self):\n    with self.assertRaises(Exception):\n      TestCases._create_dataset('today@')\n\n  @mock.patch('google.datalab.bigquery._api.Api.datasets_get')\n  def test_dataset_exists(self, mock_api_datasets_get):\n    mock_api_datasets_get.return_value = ''\n    dataset = TestCases._create_dataset('test.requestlogs')\n    self.assertTrue(dataset.exists())\n    mock_api_datasets_get.side_effect = google.datalab.utils.RequestException(404, None)\n    dataset._info = None\n    self.assertFalse(dataset.exists())\n\n  @mock.patch('google.datalab.bigquery._api.Api.datasets_insert')\n  @mock.patch('google.datalab.bigquery._api.Api.datasets_get')\n  def test_datasets_create_fails(self, mock_api_datasets_get, mock_api_datasets_insert):\n    mock_api_datasets_get.side_effect = google.datalab.utils.RequestException(None, 404)\n    mock_api_datasets_insert.return_value = {}\n\n    ds = TestCases._create_dataset('requestlogs')\n    with self.assertRaises(Exception):\n      ds.create()\n\n  @mock.patch('google.datalab.bigquery._api.Api.datasets_insert')\n  @mock.patch('google.datalab.bigquery._api.Api.datasets_get')\n  def test_datasets_create_succeeds(self, mock_api_datasets_get, mock_api_datasets_insert):\n    mock_api_datasets_get.side_effect = google.datalab.utils.RequestException(404, None)\n    mock_api_datasets_insert.return_value = {'selfLink': None}\n    ds = TestCases._create_dataset('requestlogs')\n    self.assertEqual(ds, ds.create())\n\n  @mock.patch('google.datalab.bigquery._api.Api.datasets_insert')\n  @mock.patch('google.datalab.bigquery._api.Api.datasets_get')\n  def test_datasets_create_redundant(self, mock_api_datasets_get, mock_api_datasets_insert):\n    ds = TestCases._create_dataset('requestlogs', {})\n    mock_api_datasets_get.return_value = None\n    mock_api_datasets_insert.return_value = {}\n    self.assertEqual(ds, ds.create())\n\n  @mock.patch('google.datalab.bigquery._api.Api.datasets_get')\n  @mock.patch('google.datalab.bigquery._api.Api.datasets_delete')\n  def test_datasets_delete_succeeds(self, mock_api_datasets_delete, mock_api_datasets_get):\n    mock_api_datasets_get.return_value = ''\n    mock_api_datasets_delete.return_value = None\n    ds = TestCases._create_dataset('requestlogs')\n    self.assertIsNone(ds.delete())\n\n  @mock.patch('google.datalab.bigquery._api.Api.datasets_get')\n  @mock.patch('google.datalab.bigquery._api.Api.datasets_delete')\n  def test_datasets_delete_fails(self, mock_api_datasets_delete, mock_api_datasets_get):\n    mock_api_datasets_delete.return_value = None\n    mock_api_datasets_get.side_effect = google.datalab.utils.RequestException(404, None)\n    ds = TestCases._create_dataset('requestlogs')\n    with self.assertRaises(Exception):\n      ds.delete()\n\n  @mock.patch('google.datalab.bigquery._api.Api.tables_list')\n  def test_tables_list(self, mock_api_tables_list):\n    mock_api_tables_list.return_value = {\n      'tables': [\n          {\n            'type': 'TABLE',\n            'tableReference': {'projectId': 'p', 'datasetId': 'd', 'tableId': 't1'}\n          },\n          {\n            'type': 'TABLE',\n            'tableReference': {'projectId': 'p', 'datasetId': 'd', 'tableId': 't2'}\n          },\n      ]\n    }\n    ds = TestCases._create_dataset('requestlogs')\n    tables = [table for table in ds]\n    self.assertEqual(2, len(tables))\n    self.assertEqual('`p.d.t1`', tables[0]._repr_sql_())\n    self.assertEqual('`p.d.t2`', tables[1]._repr_sql_())\n\n  @mock.patch('google.datalab.bigquery.Dataset._get_info')\n  @mock.patch('google.datalab.bigquery._api.Api.datasets_list')\n  def test_datasets_list(self, mock_api_datasets_list, mock_dataset_get_info):\n    mock_api_datasets_list.return_value = {\n      'datasets': [\n        {'datasetReference': {'projectId': 'p', 'datasetId': 'd1'}},\n        {'datasetReference': {'projectId': 'p', 'datasetId': 'd2'}},\n      ]\n    }\n    mock_dataset_get_info.return_value = {}\n    datasets = [dataset\n                for dataset in google.datalab.bigquery.Datasets(TestCases._create_context())]\n    self.assertEqual(2, len(datasets))\n    self.assertEqual('p.d1', str(datasets[0]))\n    self.assertEqual('p.d2', str(datasets[1]))\n\n  @mock.patch('google.datalab.bigquery._api.Api.tables_list')\n  @mock.patch('google.datalab.bigquery._api.Api.datasets_get')\n  @mock.patch('google.datalab.bigquery._api.Api.datasets_update')\n  def test_datasets_update(self, mock_api_datasets_update, mock_api_datasets_get,\n                           mock_api_tables_list):\n    mock_api_tables_list.return_value = {\n      'tables': [\n        {'type': 'TABLE', 'tableReference': {'projectId': 'p', 'datasetId': 'd', 'tableId': 't1'}},\n        {'type': 'TABLE', 'tableReference': {'projectId': 'p', 'datasetId': 'd', 'tableId': 't2'}},\n      ]\n    }\n    info = {'friendlyName': 'casper', 'description': 'ghostly logs'}\n    mock_api_datasets_get.return_value = info\n    ds = TestCases._create_dataset('requestlogs')\n\n    new_friendly_name = 'aziraphale'\n    new_description = 'demon duties'\n    ds.update(new_friendly_name, new_description)\n\n    name, info = mock_api_datasets_update.call_args[0]\n    self.assertEqual(ds.name, name)\n\n    self.assertEqual(new_friendly_name, ds.friendly_name)\n    self.assertEqual(new_description, ds.description)\n\n  @staticmethod\n  def _create_context():\n    project_id = 'test'\n    creds = mock.Mock(spec=google.auth.credentials.Credentials)\n    return google.datalab.Context(project_id, creds)\n\n  @staticmethod\n  def _create_dataset(name, metadata=None):\n    # Patch get_info so we don't have to mock it everywhere else.\n    orig = google.datalab.bigquery.Dataset._get_info\n    google.datalab.bigquery.Dataset._get_info = mock.Mock(return_value=metadata)\n    ds = google.datalab.bigquery.Dataset(name, context=TestCases._create_context())\n    google.datalab.bigquery.Dataset._get_info = orig\n    return ds\n"
  },
  {
    "path": "tests/bigquery/external_data_source_tests.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nimport collections\nimport mock\nimport unittest\n\nimport google.auth\nimport google.datalab\nimport google.datalab.bigquery\nimport google.datalab.utils\n\n\nclass TestCases(unittest.TestCase):\n\n  # The main thing we need to test is a query that references an external table and how\n  # that translates into a REST call.\n\n  @staticmethod\n  def _request_result():\n    return {\n      'jobReference': {\n        'jobId': 'job1234'\n      },\n      'configuration': {\n        'query': {\n          'destinationTable': {\n            'projectId': 'test',\n            'datasetId': 'dataset',\n            'tableId': 'table'\n          }\n        }\n      },\n      'jobComplete': True\n    }\n\n  @staticmethod\n  def _get_data():\n    data = []\n    day = 1\n    for weight in [220, 221, 220, 219, 218]:\n      d = collections.OrderedDict()\n      data.append(d)\n      d['day'] = day\n      day += 1\n      d['weight'] = weight\n    return data\n\n  @staticmethod\n  def _get_table_definition(uris, skip_rows=0):\n    if not isinstance(uris, list):\n      uris = [uris]\n    return {\n      'compression': 'NONE',\n      'csvOptions': {\n        'allowJaggedRows': False,\n        'quote': '\"',\n        'encoding': 'UTF-8',\n        'skipLeadingRows': skip_rows,\n        'fieldDelimiter': ',',\n        'allowQuotedNewlines': False\n      },\n      'sourceFormat': 'CSV',\n      'maxBadRecords': 0,\n      'ignoreUnknownValues': False,\n      'sourceUris': uris,\n      'schema': {\n        'fields': [\n          {'type': 'INTEGER', 'name': 'day'},\n          {'type': 'INTEGER', 'name': 'weight'}\n        ]\n      }\n    }\n\n  @staticmethod\n  def _get_expected_request_data(sql, table_definitions):\n    return {\n      'kind': 'bigquery#job',\n      'configuration': {\n        'priority': 'INTERACTIVE',\n        'query': {\n          'query': sql,\n          'useLegacySql': True,\n          'allowLargeResults': False,\n          'tableDefinitions': table_definitions,\n          'useQueryCache': True,\n          'userDefinedFunctionResources': []\n        },\n        'dryRun': False\n      }\n    }\n\n  @mock.patch('google.datalab.utils.Http.request')\n  def test_external_table_query(self, mock_http_request):\n    mock_http_request.return_value = self._request_result()\n\n    data = self._get_data()\n    schema = google.datalab.bigquery.Schema.from_data(data)\n\n    table_uri = 'gs://google.datalab/weight.csv'\n    options = google.datalab.bigquery.CSVOptions(skip_leading_rows=1)\n    sql = 'SELECT * FROM weight'\n\n    weight = google.datalab.bigquery.ExternalDataSource(table_uri, schema=schema,\n                                                        csv_options=options)\n    q = google.datalab.bigquery.Query(sql, data_sources={'weight': weight})\n    q.execute_async()\n\n    table_definition = self._get_table_definition(table_uri, skip_rows=1)\n    expected_data = self._get_expected_request_data(sql, {'weight': table_definition})\n    request_url = 'https://www.googleapis.com/bigquery/v2/projects/test/jobs/'\n\n    mock_http_request.assert_called_with(request_url, credentials=mock.ANY, data=expected_data)\n\n  # Test with multiple URLs and no non-default options\n  @mock.patch('google.datalab.utils.Http.request')\n  def test_external_table_query2(self, mock_http_request):\n    mock_http_request.return_value = self._request_result()\n\n    data = self._get_data()\n    schema = google.datalab.bigquery.Schema.from_data(data)\n\n    table_uris = ['gs://google.datalab/weight1.csv', 'gs://google.datalab/weight2.csv']\n    sql = 'SELECT * FROM weight'\n\n    weight = google.datalab.bigquery.ExternalDataSource(table_uris, schema=schema)\n    q = google.datalab.bigquery.Query(sql, data_sources={'weight': weight})\n    q.execute_async()\n\n    table_definition = self._get_table_definition(table_uris)\n    expected_data = self._get_expected_request_data(sql, {'weight': table_definition})\n    request_url = 'https://www.googleapis.com/bigquery/v2/projects/test/jobs/'\n\n    mock_http_request.assert_called_with(request_url, credentials=mock.ANY, data=expected_data)\n\n  # Test with multiple tables and using keyword args\n  @mock.patch('google.datalab.utils.Http.request')\n  def test_external_tables_query(self, mock_http_request):\n    mock_http_request.return_value = self._request_result()\n\n    data = self._get_data()\n    schema = google.datalab.bigquery.Schema.from_data(data)\n\n    table_uri1 = 'gs://google.datalab/weight1.csv'\n    table_uri2 = 'gs://google.datalab/weight2.csv'\n    sql = 'SELECT * FROM weight1 JOIN weight2 ON day'\n\n    options = google.datalab.bigquery.CSVOptions(skip_leading_rows=1)\n    weight1 = google.datalab.bigquery.ExternalDataSource(table_uri1, schema=schema,\n                                                         csv_options=options)\n    weight2 = google.datalab.bigquery.ExternalDataSource(table_uri2, schema=schema)\n    q = google.datalab.bigquery.Query(sql, env={'weight1': weight1, 'weight2': weight2})\n    q.execute_async()\n\n    table_definition1 = self._get_table_definition(table_uri1, skip_rows=1)\n    table_definition2 = self._get_table_definition(table_uri2)\n    table_definitions = {'weight1': table_definition1, 'weight2': table_definition2}\n    expected_data = self._get_expected_request_data(sql, table_definitions)\n    request_url = 'https://www.googleapis.com/bigquery/v2/projects/test/jobs/'\n\n    mock_http_request.assert_called_with(request_url, credentials=mock.ANY, data=expected_data)\n\n  @staticmethod\n  def _create_context():\n    project_id = 'test'\n    creds = mock.Mock(spec=google.auth.credentials.Credentials)\n    return google.datalab.Context(project_id, creds)\n"
  },
  {
    "path": "tests/bigquery/jobs_tests.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nimport mock\nimport unittest\n\nimport google.auth\nimport google.datalab\nimport google.datalab.bigquery\n\nfrom google.datalab.bigquery._job import Job\n\n\nclass TestCases(unittest.TestCase):\n\n  @staticmethod\n  def _make_job(id):\n    return Job(id, TestCases._create_context())\n\n  @mock.patch('google.datalab.bigquery._api.Api.jobs_get')\n  def test_job_complete(self, mock_api_jobs_get):\n    mock_api_jobs_get.return_value = {}\n    j = TestCases._make_job('foo')\n    self.assertFalse(j.is_complete)\n    self.assertFalse(j.failed)\n    mock_api_jobs_get.return_value = {'status': {'state': 'DONE'}}\n    self.assertTrue(j.is_complete)\n    self.assertFalse(j.failed)\n\n  @mock.patch('google.datalab.bigquery._api.Api.jobs_get')\n  def test_job_fatal_error(self, mock_api_jobs_get):\n    mock_api_jobs_get.return_value = {\n      'status': {\n        'state': 'DONE',\n        'errorResult': {\n          'location': 'A',\n          'message': 'B',\n          'reason': 'C'\n        }\n      }\n    }\n    j = TestCases._make_job('foo')\n    self.assertTrue(j.is_complete)\n    self.assertTrue(j.failed)\n    e = j.fatal_error\n    self.assertIsNotNone(e)\n    self.assertEqual('A', e.location)\n    self.assertEqual('B', e.message)\n    self.assertEqual('C', e.reason)\n\n  @mock.patch('google.datalab.bigquery._api.Api.jobs_get')\n  def test_job_errors(self, mock_api_jobs_get):\n    mock_api_jobs_get.return_value = {\n      'status': {\n        'state': 'DONE',\n        'errors': [\n          {\n            'location': 'A',\n            'message': 'B',\n            'reason': 'C'\n          },\n          {\n            'location': 'D',\n            'message': 'E',\n            'reason': 'F'\n          }\n        ]\n      }\n    }\n    j = TestCases._make_job('foo')\n    self.assertTrue(j.is_complete)\n    self.assertFalse(j.failed)\n    self.assertEqual(2, len(j.errors))\n    self.assertEqual('A', j.errors[0].location)\n    self.assertEqual('B', j.errors[0].message)\n    self.assertEqual('C', j.errors[0].reason)\n    self.assertEqual('D', j.errors[1].location)\n    self.assertEqual('E', j.errors[1].message)\n    self.assertEqual('F', j.errors[1].reason)\n\n  @staticmethod\n  def _create_context():\n    project_id = 'test'\n    creds = mock.Mock(spec=google.auth.credentials.Credentials)\n    return google.datalab.Context(project_id, creds)\n\n  @staticmethod\n  def _create_api():\n    return google.datalab.bigquery._api.Api(TestCases._create_context())\n"
  },
  {
    "path": "tests/bigquery/operator_tests.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nimport google.datalab.contrib.pipeline._pipeline as pipeline\nimport mock\nimport unittest\n\n# import Python so we can mock the parts we need to here.\nimport IPython.core.magic\n\n\ndef noop_decorator(func):\n    return func\n\n\nIPython.core.magic.register_line_cell_magic = noop_decorator\nIPython.core.magic.register_line_magic = noop_decorator\nIPython.core.magic.register_cell_magic = noop_decorator\nIPython.get_ipython = mock.Mock()\n\nimport google.datalab  # noqa\nimport google.datalab.bigquery  # noqa\nimport google.datalab.bigquery.commands  # noqa\nimport google.datalab.utils.commands  # noqa\n\nfrom google.datalab.contrib.bigquery.operators._bq_extract_operator import ExtractOperator  # noqa\nfrom google.datalab.contrib.bigquery.operators._bq_execute_operator import ExecuteOperator  # noqa\nfrom google.datalab.contrib.bigquery.operators._bq_load_operator import LoadOperator  # noqa\n\n\nclass TestCases(unittest.TestCase):\n\n  test_project_id = 'test_project'\n  test_table_name = 'project.test.table'\n  test_schema = [\n      {\"type\": \"INTEGER\", \"name\": \"key\"},\n      {\"type\": \"FLOAT\", \"name\": \"var1\"},\n      {\"type\": \"FLOAT\", \"name\": \"var2\"}\n  ]\n\n  @staticmethod\n  def _create_context():\n    project_id = TestCases.test_project_id\n    creds = mock.Mock(spec=google.auth.credentials.Credentials)\n    return google.datalab.Context(project_id, creds)\n\n  @mock.patch('google.datalab.Context.default')\n  @mock.patch('google.datalab.bigquery.Table.extract')\n  def test_extract_operator(self, mock_table_extract, mock_context_default):\n    mock_context_default.return_value = TestCases._create_context()\n    extract_operator = ExtractOperator(table=TestCases.test_project_id + '.test_table',\n                                       path='test_path', format=None,\n                                       task_id='test_extract_operator',\n                                       csv_options={'delimiter': '$'})\n\n    # Happy path\n    mock_table_extract.return_value.result = lambda: 'test-results'\n    mock_table_extract.return_value.failed = False\n    mock_table_extract.return_value.errors = None\n    self.assertDictEqual(extract_operator.execute(context=None), {'result': 'test-results'})\n    mock_table_extract.assert_called_with('test_path', format='NEWLINE_DELIMITED_JSON',\n                                          csv_delimiter='$')\n\n    # Extract failed\n    mock_table_extract.return_value.result = lambda: 'test-results'\n    mock_table_extract.return_value.failed = True\n    mock_table_extract.return_value.errors = None\n    with self.assertRaisesRegexp(Exception, \"Extract failed:\"):\n      extract_operator.execute(context=None)\n\n    # Extract completed with errors\n    mock_table_extract.return_value.result = lambda: 'test-results'\n    mock_table_extract.return_value.failed = False\n    mock_table_extract.return_value.errors = 'foo_error'\n    with self.assertRaisesRegexp(Exception, 'Extract completed with errors: foo_error'):\n      extract_operator.execute(context=None)\n\n  @mock.patch('google.datalab.bigquery.Query.execute')\n  @mock.patch('google.datalab.utils.commands.get_notebook_item')\n  def test_execute_operator_definition(self, mock_get_notebook_item, mock_query_execute):\n    mock_get_notebook_item.return_value = google.datalab.bigquery.Query('test_sql')\n    task_id = 'foo'\n    task_details = {}\n    task_details['type'] = 'pydatalab.bq.execute'\n    task_details['sql'] = 'test_sql'\n    task_details['mode'] = 'create'\n\n    actual = pipeline.PipelineGenerator._get_operator_definition(task_id, task_details, None)\n    expected = \"\"\"foo = ExecuteOperator(task_id='foo_id', mode=\\\"\\\"\\\"create\\\"\\\"\\\", sql=\\\"\\\"\\\"test_sql\\\"\\\"\\\", dag=dag)\n\"\"\"  # noqa\n    self.assertEqual(actual, expected)\n\n  @mock.patch('google.datalab.Context.default')\n  @mock.patch('google.datalab.bigquery.Query.execute')\n  @mock.patch('google.datalab.bigquery.QueryOutput.table')\n  @mock.patch('google.datalab.bigquery._query_job.QueryJob')\n  def test_execute_operator(self, mock_query_job, mock_query_output_table, mock_query_execute,\n                            mock_context_default):\n    mock_context_default.return_value = self._create_context()\n\n    execute_operator = ExecuteOperator(task_id='test_execute_operator', sql='test_sql')\n    mock_query_execute.return_value = mock_query_job\n    mock_query_job.result.return_value = google.datalab.bigquery.Table(TestCases.test_table_name)\n    self.assertDictEqual(execute_operator.execute(context=None),\n                         {'table': TestCases.test_table_name})\n    mock_query_output_table.assert_called_with(name=None, use_cache=False,\n                                               allow_large_results=False)\n\n  @mock.patch('google.datalab.Context.default')\n  @mock.patch('google.datalab.bigquery.ExternalDataSource')\n  @mock.patch('google.datalab.bigquery.Query')\n  @mock.patch('google.datalab.bigquery.QueryOutput.table')\n  @mock.patch('google.datalab.bigquery._query_job.QueryJob')\n  def test_execute_operator_with_data_source(self, mock_query_job, mock_query_output_table,\n                                             mock_query_class, mock_external_data_source,\n                                             mock_context_default):\n    mock_context_default.return_value = self._create_context()\n    csv_options = {'delimiter': 'f', 'skip': 9, 'strict': True, 'quote': 'l'}\n    execute_operator = ExecuteOperator(task_id='test_execute_operator', sql='test_sql',\n                                       data_source='foo_data_source', path='foo_path',\n                                       max_bad_records=20, schema=TestCases.test_schema,\n                                       csv_options=csv_options, format='csv')\n    mock_query_instance = mock_query_class.return_value\n    mock_query_instance.execute.return_value = mock_query_job\n    mock_query_job.result.return_value = google.datalab.bigquery.Table(TestCases.test_table_name)\n    self.assertDictEqual(execute_operator.execute(context=None),\n                         {'table': TestCases.test_table_name})\n    mock_query_output_table.assert_called_with(name=None, use_cache=False,\n                                               allow_large_results=False)\n    mock_query_class.assert_called_with(\n        sql='test_sql', data_sources={'foo_data_source': mock_external_data_source.return_value})\n    mock_external_data_source.assert_called_with(\n      source='foo_path', max_bad_records=20, csv_options=mock.ANY, source_format='csv',\n      schema=google.datalab.bigquery.Schema(TestCases.test_schema))\n\n    execute_operator = ExecuteOperator(task_id='test_execute_operator', sql='test_sql',\n                                       data_source='foo_data_source', path='foo_path',\n                                       schema=TestCases.test_schema)\n    mock_query_instance = mock_query_class.return_value\n    mock_query_instance.execute.return_value = mock_query_job\n    execute_operator.execute(None)\n    mock_query_output_table.assert_called_with(name=None, use_cache=False,\n                                               allow_large_results=False)\n    mock_query_class.assert_called_with(sql='test_sql',\n                                        data_sources={'foo_data_source':\n                                                      mock_external_data_source.return_value})\n    mock_external_data_source.assert_called_with(source='foo_path',\n                                                 schema=google.datalab.bigquery.Schema(\n                                                   TestCases.test_schema))\n\n  @mock.patch('google.datalab.Context.default')\n  @mock.patch('google.datalab.bigquery._api.Api.tables_insert')\n  @mock.patch('google.datalab.bigquery.Table.create')\n  @mock.patch('google.datalab.bigquery.Table.exists')\n  @mock.patch('google.datalab.bigquery.Table.load')\n  def test_load_operator(self, mock_table_load, mock_table_exists, mock_table_create,\n                         mock_api_tables_insert, mock_context_default):\n      mock_context_default.return_value = self._create_context()\n\n      # Table exists\n      mock_table_exists.return_value = True\n      load_operator = LoadOperator(table=TestCases.test_table_name, path='test/path', mode='append',\n                                   format=None, csv_options=None, schema=None,\n                                   task_id='test_operator_id')\n      mock_job = mock.Mock()\n      mock_job.result.return_value = 'test-result'\n      mock_job.failed = False\n      mock_job.errors = False\n      mock_table_load.return_value = mock_job\n      load_operator.execute(context=None)\n      mock_table_load.assert_called_with('test/path', mode='append',\n                                         source_format='NEWLINE_DELIMITED_JSON',\n                                         csv_options=mock.ANY, ignore_unknown_values=True)\n\n      # Table does not exist\n      mock_table_exists.return_value = False\n      csv_options = {'delimiter': 'f', 'skip': 9, 'strict': True, 'quote': '\"'}\n      schema = [\n        {\"type\": \"INTEGER\", \"name\": \"key\"},\n        {\"type\": \"FLOAT\", \"name\": \"var1\"},\n        {\"type\": \"FLOAT\", \"name\": \"var2\"}\n      ]\n      load_operator = LoadOperator(table=TestCases.test_table_name, path='test/path', mode='append',\n                                   format=None, csv_options=csv_options, schema=schema,\n                                   task_id='test_operator_id')\n      mock_job = mock.Mock()\n      mock_job.result.return_value = 'test-result'\n      mock_job.failed = False\n      mock_job.errors = False\n      mock_table_load.return_value = mock_job\n      load_operator.execute(context=None)\n      mock_table_load.assert_called_with('test/path', mode='append',\n                                         source_format='NEWLINE_DELIMITED_JSON',\n                                         csv_options=mock.ANY, ignore_unknown_values=False)\n      mock_table_create.assert_called_with(schema=schema)\n\n      # Table load fails\n      load_operator = LoadOperator(table=TestCases.test_table_name, path='test/path', mode='append',\n                                   format=None, csv_options=None, schema=schema,\n                                   task_id='test_operator_id')\n      mock_job = mock.Mock()\n      mock_job.failed = True\n      mock_job.fatal_error = 'fatal error'\n      mock_table_load.return_value = mock_job\n      with self.assertRaisesRegexp(Exception, 'Load failed: fatal error'):\n        load_operator.execute(context=None)\n\n      # Table load completes with errors\n      load_operator = LoadOperator(table=TestCases.test_table_name, path='test/path', mode='append',\n                                   format=None, csv_options=None, schema=TestCases.test_schema,\n                                   task_id='test_operator_id')\n      mock_job = mock.Mock()\n      mock_job.failed = False\n      mock_job.errors = 'error'\n      mock_table_load.return_value = mock_job\n      with self.assertRaisesRegexp(Exception, 'Load completed with errors: error'):\n        load_operator.execute(context=None)\n\n  def test_execute_operator_defaults(self):\n    execute_operator = ExecuteOperator(task_id='foo_task_id', sql='foo_sql')\n    self.assertIsNone(execute_operator.parameters)\n    self.assertIsNone(execute_operator.table)\n    self.assertIsNone(execute_operator.mode)\n    self.assertEqual(execute_operator.template_fields, ('table', 'parameters', 'path', 'sql'))\n\n  def test_extract_operator_defaults(self):\n    extract_operator = ExtractOperator(task_id='foo_task_id', path='foo_path', table='foo_table')\n    self.assertEquals(extract_operator.format, 'csv')\n    self.assertDictEqual(extract_operator.csv_options, {})\n    self.assertEqual(extract_operator.template_fields, ('table', 'path'))\n\n  def test_load_operator_defaults(self):\n    load_operator = LoadOperator(task_id='foo_task_id', path='foo_path', table='foo_table')\n    self.assertEquals(load_operator.format, 'csv')\n    self.assertEquals(load_operator.mode, 'append')\n    self.assertIsNone(load_operator.schema)\n    self.assertDictEqual(load_operator.csv_options, {})\n    self.assertEqual(load_operator.template_fields, ('table', 'path'))\n"
  },
  {
    "path": "tests/bigquery/parser_tests.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nimport unittest\nimport google.datalab.bigquery as bq\n\n\nclass TestCases(unittest.TestCase):\n\n  def test_repeating_data(self):\n    schema = [{'name': 'counts', 'type': 'INTEGER', 'mode': 'REPEATED'}]\n    data = {'f': [{'v': [{'v': 0}, {'v': 1}, {'v': 2}]}]}\n    parsed = {'counts': [0, 1, 2]}\n    result = bq._parser.Parser.parse_row(schema, data)\n    self.assertEqual(parsed, result)\n\n  def test_non_nested_data(self):\n\n    data = {u'f': [{u'v': u'1969'},\n                   {u'v': u'1969'},\n                   {u'v': u'1'},\n                   {u'v': u'20'},\n                   {u'v': None},\n                   {u'v': u'AL'},\n                   {u'v': u'true'},\n                   {u'v': u'1'},\n                   {u'v': u'7.81318256528'},\n                   {u'v': None},\n                   {u'v': None},\n                   {u'v': None},\n                   {u'v': u'AL'},\n                   {u'v': u'1'},\n                   {u'v': u'20'},\n                   {u'v': None},\n                   {u'v': u'88881998'},\n                   {u'v': u'true'},\n                   {u'v': u''},\n                   {u'v': None},\n                   {u'v': None},\n                   {u'v': None},\n                   {u'v': None},\n                   {u'v': None},\n                   {u'v': u'1'},\n                   {u'v': u'0'},\n                   {u'v': u'0'},\n                   {u'v': u'2'},\n                   {u'v': u'1'},\n                   {u'v': u'19'},\n                   {u'v': u'2'}]}\n\n    natality_schema = [{u'description': u'Four-digit year of the birth. Example: 1975.',\n                        u'mode': u'REQUIRED',\n                        u'name': u'source_year',\n                        u'type': u'INTEGER'},\n                       {u'description': u'Four-digit year of the birth. Example: 1975.',\n                        u'mode': u'NULLABLE',\n                        u'name': u'year',\n                        u'type': u'INTEGER'},\n                       {u'description': u'Month index of the date of birth, where 1=January.',\n                        u'mode': u'NULLABLE',\n                        u'name': u'month',\n                        u'type': u'INTEGER'},\n                       {u'description': u'Day of birth, starting from 1.',\n                        u'mode': u'NULLABLE',\n                        u'name': u'day',\n                        u'type': u'INTEGER'},\n                       {u'description': u'Day of the week, where 1 is Sunday and 7 is Saturday.',\n                        u'mode': u'NULLABLE',\n                        u'name': u'wday',\n                        u'type': u'INTEGER'},\n                       {u'description': u'The two character postal code for the state. '\n                                        u'Entries after 2004 do not include this value.',\n                        u'mode': u'NULLABLE',\n                        u'name': u'state',\n                        u'type': u'STRING'},\n                       {u'description': u'TRUE if the child is male, FALSE if female.',\n                        u'mode': u'REQUIRED',\n                        u'name': u'is_male',\n                        u'type': u'BOOLEAN'},\n                       {u'description': u'The race of the child. One of the following numbers:\\n\\n'\n                                        u'1 - White\\n2 - Black\\n3 - American Indian\\n4 - Chinese\\n'\n                                        u'5 - Japanese\\n6 - Hawaiian\\n7 - Filipino\\n'\n                                        u'9 - Unknown/Other\\n18 - Asian Indian\\n28 - Korean\\n'\n                                        u'39 - Samoan\\n48 - Vietnamese',\n                        u'mode': u'NULLABLE',\n                        u'name': u'child_race',\n                        u'type': u'INTEGER'},\n                       {u'description': u'Weight of the child, in pounds.',\n                        u'mode': u'NULLABLE',\n                        u'name': u'weight_pounds',\n                        u'type': u'FLOAT'},\n                       {u'description': u'How many children were born as a result of this '\n                                        u'pregnancy. twins=2, triplets=3, and so on.',\n                        u'mode': u'NULLABLE',\n                        u'name': u'plurality',\n                        u'type': u'INTEGER'},\n                       {u'description': u'Apgar scores measure the health of a newborn child on a '\n                                        u'scale from 0-10. Value after 1 minute. Available from '\n                                        u'1978-2002.',\n                        u'mode': u'NULLABLE',\n                        u'name': u'apgar_1min',\n                        u'type': u'INTEGER'},\n                       {u'description': u'Apgar scores measure the health of a newborn child on a '\n                                        u'scale from 0-10. Value after 5 minutes. Available from '\n                                        u'1978-2002.',\n                        u'mode': u'NULLABLE',\n                        u'name': u'apgar_5min',\n                        u'type': u'INTEGER'},\n                       {u'description': u\"The two-letter postal code of the mother's state of \"\n                                        u\"residence when the child was born.\",\n                        u'mode': u'NULLABLE',\n                        u'name': u'mother_residence_state',\n                        u'type': u'STRING'},\n                       {u'description': u'Race of the mother. Same values as child_race.',\n                        u'mode': u'NULLABLE',\n                        u'name': u'mother_race',\n                        u'type': u'INTEGER'},\n                       {u'description': u'Reported age of the mother when giving birth.',\n                        u'mode': u'NULLABLE',\n                        u'name': u'mother_age',\n                        u'type': u'INTEGER'},\n                       {u'description': u'The number of weeks of the pregnancy.',\n                        u'mode': u'NULLABLE',\n                        u'name': u'gestation_weeks',\n                        u'type': u'INTEGER'},\n                       {u'description': u'Date of the last menstrual period in the format '\n                                        u'MMDDYYYY. Unknown values are recorded as \"99\" or \"9999\".',\n                        u'mode': u'NULLABLE',\n                        u'name': u'lmp',\n                        u'type': u'STRING'},\n                       {u'description': u'True if the mother was married when she gave birth.',\n                        u'mode': u'NULLABLE',\n                        u'name': u'mother_married',\n                        u'type': u'BOOLEAN'},\n                       {u'description': u\"The two-letter postal code of the mother's birth state.\",\n                        u'mode': u'NULLABLE',\n                        u'name': u'mother_birth_state',\n                        u'type': u'STRING'},\n                       {u'description': u'True if the mother smoked cigarettes. Available starting '\n                                        u'2003.',\n                        u'mode': u'NULLABLE',\n                        u'name': u'cigarette_use',\n                        u'type': u'BOOLEAN'},\n                       {u'description': u'Number of cigarettes smoked by the mother per day. '\n                                        u'Available starting 2003.',\n                        u'mode': u'NULLABLE',\n                        u'name': u'cigarettes_per_day',\n                        u'type': u'INTEGER'},\n                       {u'description': u'True if the mother used alcohol. Available starting '\n                                        u'1989.',\n                        u'mode': u'NULLABLE',\n                        u'name': u'alcohol_use',\n                        u'type': u'BOOLEAN'},\n                       {u'description': u'Number of drinks per week consumed by the mother. '\n                                        u'Available starting 1989.',\n                        u'mode': u'NULLABLE',\n                        u'name': u'drinks_per_week',\n                        u'type': u'INTEGER'},\n                       {u'description': u'Number of pounds gained by the mother during pregnancy.',\n                        u'mode': u'NULLABLE',\n                        u'name': u'weight_gain_pounds',\n                        u'type': u'INTEGER'},\n                       {u'description': u'Number of children previously born to the mother who are '\n                                        u'now living.',\n                        u'mode': u'NULLABLE',\n                        u'name': u'born_alive_alive',\n                        u'type': u'INTEGER'},\n                       {u'description': u'Number of children previously born to the mother who are '\n                                        u'now dead.',\n                        u'mode': u'NULLABLE',\n                        u'name': u'born_alive_dead',\n                        u'type': u'INTEGER'},\n                       {u'description': u'Number of children who were born dead '\n                                        u'(i.e. miscarriages)',\n                        u'mode': u'NULLABLE',\n                        u'name': u'born_dead',\n                        u'type': u'INTEGER'},\n                       {u'description': u'Total number of children to whom the woman has ever '\n                                        u'given birth (includes the current birth).',\n                        u'mode': u'NULLABLE',\n                        u'name': u'ever_born',\n                        u'type': u'INTEGER'},\n                       {u'description': u'Race of the father. Same values as child_race.',\n                        u'mode': u'NULLABLE',\n                        u'name': u'father_race',\n                        u'type': u'INTEGER'},\n                       {u'description': u'Age of the father when the child was born.',\n                        u'mode': u'NULLABLE',\n                        u'name': u'father_age',\n                        u'type': u'INTEGER'},\n                       {u'description': u'1 or 2, where 1 is a row from a full-reporting area, and '\n                                        u'2 is a row from a 50% sample area.',\n                        u'mode': u'NULLABLE',\n                        u'name': u'record_weight',\n                        u'type': u'INTEGER'}]\n\n    parsed = {u'alcohol_use': None,\n              u'apgar_1min': None,\n              u'apgar_5min': None,\n              u'born_alive_alive': 1,\n              u'born_alive_dead': 0,\n              u'born_dead': 0,\n              u'child_race': 1,\n              u'cigarette_use': None,\n              u'cigarettes_per_day': None,\n              u'day': 20,\n              u'drinks_per_week': None,\n              u'ever_born': 2,\n              u'father_age': 19,\n              u'father_race': 1,\n              u'gestation_weeks': None,\n              u'is_male': True,\n              u'lmp': u'88881998',\n              u'month': 1,\n              u'mother_age': 20,\n              u'mother_birth_state': u'',\n              u'mother_married': True,\n              u'mother_race': 1,\n              u'mother_residence_state': u'AL',\n              u'plurality': None,\n              u'record_weight': 2,\n              u'source_year': 1969,\n              u'state': u'AL',\n              u'wday': None,\n              u'weight_gain_pounds': None,\n              u'weight_pounds': 7.81318256528,\n              u'year': 1969}\n\n    self.assertEqual(parsed, bq._parser.Parser.parse_row(natality_schema, data))\n\n  def test_parse_nested_data(self):\n\n    self.maxDiff = None  # Show full diff on failure\n    data = {u'f': [{u'v': {u'f': [{u'v': u'https://github.com/foo'},\n                                  {u'v': u'true'},\n                                  {u'v': u'2011/04/12 20:04:19 -0700'},\n                                  {u'v': u'true'},\n                                  {u'v': u'A website.'},\n                                  {u'v': u'17'},\n                                  {u'v': u'false'},\n                                  {u'v': u'true'},\n                                  {u'v': u'http://foo.com/'},\n                                  {u'v': None},\n                                  {u'v': None},\n                                  {u'v': u'424'},\n                                  {u'v': u'false'},\n                                  {u'v': u'foo'},\n                                  {u'v': None},\n                                  {u'v': u'foo'},\n                                  {u'v': u'0'},\n                                  {u'v': u'95'},\n                                  {u'v': u'2012/03/15 00:00:00 -0700'},\n                                  {u'v': u'Ruby'}]}},\n                   {u'v': {u'f': [{u'v': u'http://foo.com/'},\n                                  {u'v': u'Flickr'},\n                                  {u'v': u'd+github@foo.com'},\n                                  {u'v': u'94c21234567890abcdef25e704b88407'},\n                                  {u'v': u'San Francisco, California'},\n                                  {u'v': u'foo'},\n                                  {u'v': u'Foo Bar'},\n                                  {u'v': u'User'}]}},\n                   {u'v': u'2012/03/15 00:00:01 -0700'},\n                   {u'v': u'true'},\n                   {u'v': u'foo'},\n                   {u'v':\n                       {u'f': [\n                           {u'v': None},\n                           {u'v': None},\n                           {u'v': None},\n                           {u'v': None},\n                           {u'v': None},\n                           {u'v': None},\n                           {u'v': None},\n                           {u'v': None},\n                           {u'v': u'2de950123456789abcdef01234451feaf8ce6ae'},\n                           {u'v': None},\n                           {u'v': None},\n                           {u'v': None},\n                           {u'v': None},\n                           {u'v': None},\n                           {u'v': None},\n                           {u'v': None},\n                           {u'v': None},\n                           {u'v': []},\n                           {u'v': None},\n                           {u'v': u'refs/heads/master'},\n                           {u'v': None},\n                           {u'v': u'1'},\n                           {u'v': [\n                               {u'v': {u'f': [{u'v': u'2de958ab480eabe2501b343425b451feaf8ce6ae'},\n                                              {u'v': u'd+github@foo.com'},\n                                              {u'v': u'Foo tastes good.'},\n                                              {u'v': u'Foo Bar'}]}}]},\n                           {u'v': None},\n                           {u'v': None}]}},\n                   {u'v': u'https://github.com/compare/d3e91cb736...2de958ab48'},\n                   {u'v': u'PushEvent'}]}\n\n    github_nested_schema = [{u'fields': [{u'name': u'url', u'type': u'STRING'},\n                                         {u'name': u'has_downloads', u'type': u'BOOLEAN'},\n                                         {u'name': u'created_at', u'type': u'STRING'},\n                                         {u'name': u'has_issues', u'type': u'BOOLEAN'},\n                                         {u'name': u'description', u'type': u'STRING'},\n                                         {u'name': u'forks', u'type': u'INTEGER'},\n                                         {u'name': u'fork', u'type': u'BOOLEAN'},\n                                         {u'name': u'has_wiki', u'type': u'BOOLEAN'},\n                                         {u'name': u'homepage', u'type': u'STRING'},\n                                         {u'name': u'integrate_branch', u'type': u'STRING'},\n                                         {u'name': u'master_branch', u'type': u'STRING'},\n                                         {u'name': u'size', u'type': u'INTEGER'},\n                                         {u'name': u'private', u'type': u'BOOLEAN'},\n                                         {u'name': u'name', u'type': u'STRING'},\n                                         {u'name': u'organization', u'type': u'STRING'},\n                                         {u'name': u'owner', u'type': u'STRING'},\n                                         {u'name': u'open_issues', u'type': u'INTEGER'},\n                                         {u'name': u'watchers', u'type': u'INTEGER'},\n                                         {u'name': u'pushed_at', u'type': u'STRING'},\n                                         {u'name': u'language', u'type': u'STRING'}],\n                             u'name': u'repository',\n                             u'type': u'RECORD'},\n                            {u'fields': [{u'name': u'blog', u'type': u'STRING'},\n                                         {u'name': u'company', u'type': u'STRING'},\n                                         {u'name': u'email', u'type': u'STRING'},\n                                         {u'name': u'gravatar_id', u'type': u'STRING'},\n                                         {u'name': u'location', u'type': u'STRING'},\n                                         {u'name': u'login', u'type': u'STRING'},\n                                         {u'name': u'name', u'type': u'STRING'},\n                                         {u'name': u'type', u'type': u'STRING'}],\n                             u'name': u'actor_attributes',\n                             u'type': u'RECORD'},\n                            {u'name': u'created_at', u'type': u'STRING'},\n                            {u'name': u'public', u'type': u'BOOLEAN'},\n                            {u'name': u'actor', u'type': u'STRING'},\n                            {u'fields': [\n                                {u'name': u'action', u'type': u'STRING'},\n                                {u'name': u'after', u'type': u'STRING'},\n                                {u'name': u'before', u'type': u'STRING'},\n                                {u'name': u'commit', u'type': u'STRING'},\n                                {u'fields': [\n                                    {u'name': u'commit_id', u'type': u'STRING'},\n                                    {u'name': u'body', u'type': u'STRING'},\n                                    {u'name': u'created_at', u'type': u'STRING'},\n                                    {u'name': u'id', u'type': u'INTEGER'},\n                                    {u'name': u'original_commit_id', u'type': u'STRING'},\n                                    {u'name': u'original_position', u'type': u'INTEGER'},\n                                    {u'name': u'path', u'type': u'STRING'},\n                                    {u'name': u'position', u'type': u'INTEGER'},\n                                    {u'name': u'updated_at', u'type': u'STRING'},\n                                    {u'fields': [{u'name': u'id', u'type': u'INTEGER'},\n                                                 {u'name': u'gravatar_id', u'type': u'STRING'},\n                                                 {u'name': u'avatar_url', u'type': u'STRING'},\n                                                 {u'name': u'login', u'type': u'STRING'},\n                                                 {u'name': u'url', u'type': u'STRING'}],\n                                     u'name': u'user', u'type': u'RECORD'},\n                                    {u'name': u'url', u'type': u'STRING'}],\n                                    u'name': u'comment', u'type': u'RECORD'},\n                                {u'name': u'comment_id', u'type': u'INTEGER'},\n                                {u'name': u'desc', u'type': u'STRING'},\n                                {u'name': u'description', u'type': u'STRING'},\n                                {u'name': u'head', u'type': u'STRING'},\n                                {u'name': u'id', u'type': u'INTEGER'},\n                                {u'name': u'issue', u'type': u'INTEGER'},\n                                {u'name': u'issue_id', u'type': u'INTEGER'},\n                                {u'name': u'master_branch', u'type': u'STRING'},\n                                {u'name': u'master', u'type': u'STRING'},\n                                {u'fields': [{u'name': u'id', u'type': u'INTEGER'},\n                                             {u'name': u'gravatar_id', u'type': u'STRING'},\n                                             {u'name': u'avatar_url', u'type': u'STRING'},\n                                             {u'name': u'login', u'type': u'STRING'},\n                                             {u'name': u'url', u'type': u'STRING'}],\n                                 u'name': u'member', u'type': u'RECORD'},\n                                {u'name': u'name', u'type': u'STRING'},\n                                {u'name': u'number', u'type': u'INTEGER'},\n                                {u'fields': [{u'name': u'action', u'type': u'STRING'},\n                                             {u'name': u'html_url', u'type': u'STRING'},\n                                             {u'name': u'page_name', u'type': u'STRING'},\n                                             {u'name': u'sha', u'type': u'STRING'},\n                                             {u'name': u'summary', u'type': u'STRING'},\n                                             {u'name': u'title', u'type': u'STRING'}],\n                                 u'mode': u'REPEATED', u'name': u'pages', u'type': u'RECORD'},\n                                {u'fields': [\n                                    {u'name': u'additions', u'type': u'INTEGER'},\n                                    {u'fields': [\n                                        {u'fields': [\n                                            {u'name': u'clone_url', u'type': u'STRING'},\n                                            {u'name': u'created_at', u'type': u'STRING'},\n                                            {u'name': u'description', u'type': u'STRING'},\n                                            {u'name': u'fork', u'type': u'BOOLEAN'},\n                                            {u'name': u'forks', u'type': u'INTEGER'},\n                                            {u'name': u'git_url', u'type': u'STRING'},\n                                            {u'name': u'has_downloads', u'type': u'BOOLEAN'},\n                                            {u'name': u'has_issues', u'type': u'BOOLEAN'},\n                                            {u'name': u'has_wiki', u'type': u'BOOLEAN'},\n                                            {u'name': u'homepage', u'type': u'STRING'},\n                                            {u'name': u'html_url', u'type': u'STRING'},\n                                            {u'name': u'id', u'type': u'INTEGER'},\n                                            {u'name': u'language', u'type': u'STRING'},\n                                            {u'name': u'master_branch', u'type': u'STRING'},\n                                            {u'name': u'name', u'type': u'STRING'},\n                                            {u'name': u'open_issues', u'type': u'INTEGER'},\n                                            {u'fields': [\n                                                {u'name': u'id', u'type': u'INTEGER'},\n                                                {u'name': u'gravatar_id', u'type': u'STRING'},\n                                                {u'name': u'avatar_url', u'type': u'STRING'},\n                                                {u'name': u'login', u'type': u'STRING'},\n                                                {u'name': u'url', u'type': u'STRING'}],\n                                                u'name': u'owner', u'type': u'RECORD'},\n                                            {u'name': u'private', u'type': u'BOOLEAN'},\n                                            {u'name': u'pushed_at', u'type': u'STRING'},\n                                            {u'name': u'size', u'type': u'INTEGER'},\n                                            {u'name': u'ssh_url', u'type': u'STRING'},\n                                            {u'name': u'svn_url', u'type': u'STRING'},\n                                            {u'name': u'updated_at', u'type': u'STRING'},\n                                            {u'name': u'watchers', u'type': u'INTEGER'},\n                                            {u'name': u'url', u'type': u'STRING'}],\n                                            u'name': u'repo', u'type': u'RECORD'},\n                                        {u'name': u'sha', u'type': u'STRING'},\n                                        {u'name': u'ref', u'type': u'STRING'},\n                                        {u'fields': [{u'name': u'id', u'type': u'INTEGER'},\n                                                     {u'name': u'gravatar_id', u'type': u'STRING'},\n                                                     {u'name': u'avatar_url', u'type': u'STRING'},\n                                                     {u'name': u'login', u'type': u'STRING'},\n                                                     {u'name': u'url', u'type': u'STRING'}],\n                                         u'name': u'user', u'type': u'RECORD'},\n                                        {u'name': u'label', u'type': u'STRING'}],\n                                        u'name': u'base', u'type': u'RECORD'},\n                                    {u'name': u'body', u'type': u'STRING'},\n                                    {u'name': u'changed_files', u'type': u'INTEGER'},\n                                    {u'name': u'closed_at', u'type': u'STRING'},\n                                    {u'name': u'comments', u'type': u'INTEGER'},\n                                    {u'name': u'commits', u'type': u'INTEGER'},\n                                    {u'name': u'created_at', u'type': u'STRING'},\n                                    {u'name': u'deletions', u'type': u'INTEGER'},\n                                    {u'name': u'diff_url', u'type': u'STRING'},\n                                    {u'fields': [\n                                        {u'fields': [\n                                            {u'name': u'clone_url', u'type': u'STRING'},\n                                            {u'name': u'created_at', u'type': u'STRING'},\n                                            {u'name': u'description', u'type': u'STRING'},\n                                            {u'name': u'fork', u'type': u'BOOLEAN'},\n                                            {u'name': u'forks', u'type': u'INTEGER'},\n                                            {u'name': u'git_url', u'type': u'STRING'},\n                                            {u'name': u'has_downloads', u'type': u'BOOLEAN'},\n                                            {u'name': u'has_issues', u'type': u'BOOLEAN'},\n                                            {u'name': u'has_wiki', u'type': u'BOOLEAN'},\n                                            {u'name': u'homepage', u'type': u'STRING'},\n                                            {u'name': u'html_url', u'type': u'STRING'},\n                                            {u'name': u'id', u'type': u'INTEGER'},\n                                            {u'name': u'language', u'type': u'STRING'},\n                                            {u'name': u'master_branch', u'type': u'STRING'},\n                                            {u'name': u'name', u'type': u'STRING'},\n                                            {u'name': u'open_issues', u'type': u'INTEGER'},\n                                            {u'fields': [\n                                                {u'name': u'id', u'type': u'INTEGER'},\n                                                {u'name': u'gravatar_id', u'type': u'STRING'},\n                                                {u'name': u'avatar_url', u'type': u'STRING'},\n                                                {u'name': u'login', u'type': u'STRING'},\n                                                {u'name': u'url', u'type': u'STRING'}],\n                                                u'name': u'owner', u'type': u'RECORD'},\n                                            {u'name': u'private', u'type': u'BOOLEAN'},\n                                            {u'name': u'pushed_at', u'type': u'STRING'},\n                                            {u'name': u'size', u'type': u'INTEGER'},\n                                            {u'name': u'ssh_url', u'type': u'STRING'},\n                                            {u'name': u'svn_url', u'type': u'STRING'},\n                                            {u'name': u'updated_at', u'type': u'STRING'},\n                                            {u'name': u'watchers', u'type': u'INTEGER'},\n                                            {u'name': u'url', u'type': u'STRING'}],\n                                            u'name': u'repo', u'type': u'RECORD'},\n                                        {u'name': u'sha', u'type': u'STRING'},\n                                        {u'name': u'ref', u'type': u'STRING'},\n                                        {u'fields': [{u'name': u'id', u'type': u'INTEGER'},\n                                                     {u'name': u'gravatar_id', u'type': u'STRING'},\n                                                     {u'name': u'avatar_url', u'type': u'STRING'},\n                                                     {u'name': u'login', u'type': u'STRING'},\n                                                     {u'name': u'url', u'type': u'STRING'}],\n                                         u'name': u'user', u'type': u'RECORD'},\n                                        {u'name': u'label', u'type': u'STRING'}],\n                                        u'name': u'head',\n                                        u'type': u'RECORD'},\n                                    {u'name': u'html_url', u'type': u'STRING'},\n                                    {u'name': u'issue_url', u'type': u'STRING'},\n                                    {u'name': u'id', u'type': u'INTEGER'},\n                                    {u'fields': [\n                                        {u'fields': [\n                                            {u'name': u'href', u'type': u'STRING'}],\n                                            u'name': u'self', u'type': u'RECORD'},\n                                        {u'fields': [{u'name': u'href', u'type': u'STRING'}],\n                                         u'name': u'html', u'type': u'RECORD'},\n                                        {u'fields': [{u'name': u'href', u'type': u'STRING'}],\n                                         u'name': u'review_comments', u'type': u'RECORD'},\n                                        {u'fields': [{u'name': u'href', u'type': u'STRING'}],\n                                         u'name': u'comments', u'type': u'RECORD'}],\n                                        u'name': u'_links', u'type': u'RECORD'},\n                                    {u'name': u'mergeable', u'type': u'BOOLEAN'},\n                                    {u'name': u'merged', u'type': u'BOOLEAN'},\n                                    {u'name': u'merged_at', u'type': u'STRING'},\n                                    {u'fields': [{u'name': u'id', u'type': u'INTEGER'},\n                                                 {u'name': u'gravatar_id', u'type': u'STRING'},\n                                                 {u'name': u'avatar_url', u'type': u'STRING'},\n                                                 {u'name': u'login', u'type': u'STRING'},\n                                                 {u'name': u'url', u'type': u'STRING'}],\n                                     u'name': u'merged_by', u'type': u'RECORD'},\n                                    {u'name': u'number', u'type': u'INTEGER'},\n                                    {u'name': u'patch_url', u'type': u'STRING'},\n                                    {u'name': u'review_comments', u'type': u'INTEGER'},\n                                    {u'name': u'state', u'type': u'STRING'},\n                                    {u'name': u'title', u'type': u'STRING'},\n                                    {u'name': u'updated_at', u'type': u'STRING'},\n                                    {u'name': u'url', u'type': u'STRING'},\n                                    {u'fields': [{u'name': u'id', u'type': u'INTEGER'},\n                                                 {u'name': u'gravatar_id', u'type': u'STRING'},\n                                                 {u'name': u'avatar_url', u'type': u'STRING'},\n                                                 {u'name': u'login', u'type': u'STRING'},\n                                                 {u'name': u'url', u'type': u'STRING'}],\n                                     u'name': u'user', u'type': u'RECORD'}],\n                                    u'name': u'pull_request', u'type': u'RECORD'},\n                                {u'name': u'ref', u'type': u'STRING'},\n                                {u'name': u'ref_type', u'type': u'STRING'},\n                                {u'name': u'size', u'type': u'INTEGER'},\n                                {u'fields': [\n                                    {u'name': u'encoded', u'type': u'STRING'},\n                                    {u'name': u'actor_email', u'type': u'STRING'},\n                                    {u'name': u'message', u'type': u'STRING'},\n                                    {u'name': u'actor_login', u'type': u'STRING'}],\n                                    u'mode': u'REPEATED', u'name': u'shas', u'type': u'RECORD'},\n                                {u'fields': [{u'name': u'login', u'type': u'STRING'},\n                                             {u'name': u'repos', u'type': u'INTEGER'},\n                                             {u'name': u'followers', u'type': u'INTEGER'},\n                                             {u'name': u'id', u'type': u'INTEGER'},\n                                             {u'name': u'gravatar_id', u'type': u'STRING'}],\n                                 u'name': u'target', u'type': u'RECORD'},\n                                {u'name': u'url', u'type': u'STRING'}],\n                                u'name': u'payload', u'type': u'RECORD'},\n                            {u'name': u'url', u'type': u'STRING'},\n                            {u'name': u'type', u'type': u'STRING'}]\n\n    parsed = {u'actor': u'foo',\n              u'actor_attributes': {u'blog': u'http://foo.com/',\n                                    u'company': u'Flickr',\n                                    u'email': u'd+github@foo.com',\n                                    u'gravatar_id': u'94c21234567890abcdef25e704b88407',\n                                    u'location': u'San Francisco, California',\n                                    u'login': u'foo',\n                                    u'name': u'Foo Bar',\n                                    u'type': u'User'},\n              u'created_at': u'2012/03/15 00:00:01 -0700',\n              u'payload': {u'action': None,\n                           u'after': None,\n                           u'before': None,\n                           u'comment': {},\n                           u'comment_id': None,\n                           u'commit': None,\n                           u'desc': None,\n                           u'description': None,\n                           u'head': u'2de950123456789abcdef01234451feaf8ce6ae',\n                           u'id': None,\n                           u'issue': None,\n                           u'issue_id': None,\n                           u'master': None,\n                           u'master_branch': None,\n                           u'member': {},\n                           u'name': None,\n                           u'number': None,\n                           u'pages': [],\n                           u'pull_request': {},\n                           u'ref': u'refs/heads/master',\n                           u'ref_type': None,\n                           u'shas': [{u'actor_email': u'd+github@foo.com',\n                                      u'actor_login': u'Foo Bar',\n                                      u'encoded': u'2de958ab480eabe2501b343425b451feaf8ce6ae',\n                                      u'message': u'Foo tastes good.'}],\n                           u'size': 1,\n                           u'target': {},\n                           u'url': None},\n              u'public': True,\n              u'repository': {u'created_at': u'2011/04/12 20:04:19 -0700',\n                              u'description': u'A website.',\n                              u'fork': False,\n                              u'forks': 17,\n                              u'has_downloads': True,\n                              u'has_issues': True,\n                              u'has_wiki': True,\n                              u'homepage': u'http://foo.com/',\n                              u'integrate_branch': None,\n                              u'language': u'Ruby',\n                              u'master_branch': None,\n                              u'name': u'foo',\n                              u'open_issues': 0,\n                              u'organization': None,\n                              u'owner': u'foo',\n                              u'private': False,\n                              u'pushed_at': u'2012/03/15 00:00:00 -0700',\n                              u'size': 424,\n                              u'url': u'https://github.com/foo',\n                              u'watchers': 95},\n              u'type': u'PushEvent',\n              u'url': u'https://github.com/compare/d3e91cb736...2de958ab48'}\n\n    self.assertEqual(parsed, bq._parser.Parser.parse_row(github_nested_schema, data))\n"
  },
  {
    "path": "tests/bigquery/pipeline_tests.py",
    "content": "#!/usr/bin/python\n# -*- coding: utf-8 -*-\n# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nimport google\nimport google.auth\nimport google.datalab.contrib.bigquery.commands._bigquery as bq\nimport mock\nimport re\nimport unittest\n\n\nclass TestCases(unittest.TestCase):\n\n  test_input_config = {\n    'path': 'test_path_%(_ts_month)s',\n    'table': 'test_table',\n    'schema': 'test_schema',\n    'mode': 'append',\n    'format': 'csv',\n    'csv': {\n      'delimiter': ';',\n      'skip': 9,\n      'strict': False,\n      'quote': '\"'\n    },\n  }\n\n  test_pipeline_config = {\n    'input': test_input_config,\n  }\n\n  @staticmethod\n  def _create_context():\n    project_id = 'test'\n    creds = mock.Mock(spec=google.auth.credentials.Credentials)\n    return google.datalab.Context(project_id, creds)\n\n  def assertPipelineConfigEquals(self, actual, expected, expected_pipeline_parameters):\n    expected_copy = expected.copy()\n\n    actual_execute_config = actual['tasks'].get('bq_pipeline_execute_task', None)\n    expected_execute_config = expected_copy['tasks'].get('bq_pipeline_execute_task', None)\n    if actual_execute_config and expected_execute_config:\n      self.assertExecuteConfigEquals(actual_execute_config, expected_execute_config,\n                                     expected_pipeline_parameters)\n      del actual['tasks']['bq_pipeline_execute_task']\n      del expected_copy['tasks']['bq_pipeline_execute_task']\n\n    actual_params = actual['parameters'] or []\n    actual_paramaters_dict = {item['name']: (item['value'], item['type']) for item in actual_params}\n    expected_pipeline_parameters = expected_pipeline_parameters or []\n    expected_paramaters_dict = {item['name']: (item['value'], item['type'])\n                                for item in expected_pipeline_parameters}\n    self.assertDictEqual(actual_paramaters_dict, expected_paramaters_dict)\n\n    del actual['parameters']\n    self.assertDictEqual(actual, expected_copy)\n\n  @mock.patch('google.datalab.utils.commands.get_notebook_item')\n  def test_get_pipeline_spec_from_config(self, mock_notebook_item):\n    mock_notebook_item.return_value = google.datalab.bigquery.Query('foo_query_sql_string')\n\n    # empty pipeline_spec\n    with self.assertRaisesRegexp(Exception, 'Pipeline has no tasks to execute.'):\n      bq._get_pipeline_spec_from_config({})\n\n    # empty input , transformation, output as path\n    pipeline_config = {\n      'transformation': {\n        'query': 'foo_query'\n      },\n      'output': {\n        'path': 'foo_table'\n      }\n    }\n    expected = {\n      'tasks': {\n        'bq_pipeline_execute_task': {\n          'sql': u'foo_query_sql_string',\n          'type': 'pydatalab.bq.execute',\n        },\n        'bq_pipeline_extract_task': {\n          'table': \"\"\"{{ ti.xcom_pull(task_ids='bq_pipeline_execute_task_id').get('table') }}\"\"\",\n          'path': 'foo_table',\n          'type': 'pydatalab.bq.extract',\n          'up_stream': ['bq_pipeline_execute_task']\n        }\n      }\n    }\n\n    actual = bq._get_pipeline_spec_from_config(pipeline_config)\n    self.assertPipelineConfigEquals(actual, expected, None)\n\n    # input as path, transformation, output as path\n    pipeline_config = {\n      'input': {\n        'path': 'foo_path',\n        'data_source': 'foo_data_source',\n      },\n      'transformation': {\n        'query': 'foo_query'\n      },\n      'output': {\n        'path': 'foo_table'\n      }\n    }\n    expected = {\n      'tasks': {\n        'bq_pipeline_execute_task': {\n          'sql': u'foo_query_sql_string',\n          'data_source': 'foo_data_source',\n          'path': 'foo_path',\n          'type': 'pydatalab.bq.execute',\n        },\n        'bq_pipeline_extract_task': {\n          'table': \"\"\"{{ ti.xcom_pull(task_ids='bq_pipeline_execute_task_id').get('table') }}\"\"\",\n          'path': 'foo_table',\n          'type': 'pydatalab.bq.extract',\n          'up_stream': ['bq_pipeline_execute_task']\n        }\n      }\n    }\n    actual = bq._get_pipeline_spec_from_config(pipeline_config)\n    self.assertPipelineConfigEquals(actual, expected, None)\n\n    # input as path->table, transformation, output as path\n    pipeline_config = {\n      'input': {\n        'path': 'foo_path',\n        'table': 'foo_table_1'\n      },\n      'transformation': {\n        'query': 'foo_query'\n      },\n      'output': {\n        'path': 'foo_path_2'\n      }\n    }\n    expected = {\n      'tasks': {\n        'bq_pipeline_load_task': {\n          'type': 'pydatalab.bq.load',\n          'path': 'foo_path',\n          'table': 'foo_table_1',\n        },\n        'bq_pipeline_execute_task': {\n          'sql': u'WITH input AS (\\n  SELECT * FROM `foo_table_1`\\n)\\n\\nfoo_query_sql_string',\n          'type': 'pydatalab.bq.execute',\n          'up_stream': ['bq_pipeline_load_task'],\n        },\n        'bq_pipeline_extract_task': {\n          'table': \"\"\"{{ ti.xcom_pull(task_ids='bq_pipeline_execute_task_id').get('table') }}\"\"\",\n          'path': 'foo_path_2',\n          'type': 'pydatalab.bq.extract',\n          'up_stream': ['bq_pipeline_execute_task']\n        }\n      }\n    }\n    actual = bq._get_pipeline_spec_from_config(pipeline_config)\n    self.assertPipelineConfigEquals(actual, expected, None)\n\n    # input as table, transformation, output as path\n    pipeline_config = {\n      'input': {\n        'table': 'foo_table_1'\n      },\n      'transformation': {\n        'query': 'foo_query'\n      },\n      'output': {\n        'path': 'foo_path_2'\n      }\n    }\n    expected = {\n      'tasks': {\n        'bq_pipeline_execute_task': {\n          'sql': u'WITH input AS (\\n  SELECT * FROM `foo_table_1`\\n)\\n\\nfoo_query_sql_string',\n          'type': 'pydatalab.bq.execute',\n        },\n        'bq_pipeline_extract_task': {\n          'table': \"\"\"{{ ti.xcom_pull(task_ids='bq_pipeline_execute_task_id').get('table') }}\"\"\",\n          'path': 'foo_path_2',\n          'type': 'pydatalab.bq.extract',\n          'up_stream': ['bq_pipeline_execute_task']\n        }\n      }\n    }\n    actual = bq._get_pipeline_spec_from_config(pipeline_config)\n    self.assertPipelineConfigEquals(actual, expected, None)\n\n    # input as table, transformation, output as table\n    pipeline_config = {\n      'input': {\n        'table': 'foo_table_1'\n      },\n      'transformation': {\n        'query': 'foo_query'\n      },\n      'output': {\n        'table': 'foo_table_1'\n      }\n    }\n    expected = {\n      'tasks': {\n        'bq_pipeline_execute_task': {\n          'sql': u'WITH input AS (\\n  SELECT * FROM `foo_table_1`\\n)\\n\\nfoo_query_sql_string',\n          'type': 'pydatalab.bq.execute',\n          'table': 'foo_table_1',\n        },\n      }\n    }\n    actual = bq._get_pipeline_spec_from_config(pipeline_config)\n    self.assertPipelineConfigEquals(actual, expected, None)\n\n    # input as table, no transformation, output as path\n    pipeline_config = {\n      'input': {\n        'table': 'foo_table'\n      },\n      'output': {\n        'path': 'foo_path'\n      }\n    }\n    expected = {\n      'tasks': {\n        'bq_pipeline_extract_task': {\n          'type': 'pydatalab.bq.extract',\n          'path': 'foo_path',\n          'table': 'foo_table'\n        },\n      }\n    }\n    actual = bq._get_pipeline_spec_from_config(pipeline_config)\n    self.assertPipelineConfigEquals(actual, expected, None)\n\n    # output only; this should be identical to the above\n    pipeline_config = {\n      'output': {\n        'table': 'foo_table',\n        'path': 'foo_path'\n      }\n    }\n    actual = bq._get_pipeline_spec_from_config(pipeline_config)\n    self.assertPipelineConfigEquals(actual, expected, None)\n\n    # output can also be called extract, and it should be identical to the above\n    pipeline_config = {\n      'extract': {\n        'table': 'foo_table',\n        'path': 'foo_path'\n      }\n    }\n    actual = bq._get_pipeline_spec_from_config(pipeline_config)\n    self.assertPipelineConfigEquals(actual, expected, None)\n\n    # input as path, no transformation, output as table\n    pipeline_config = {\n      'input': {\n        'path': 'foo_path'\n      },\n      'output': {\n        'table': 'foo_table'\n      }\n    }\n    expected = {\n      'tasks': {\n        'bq_pipeline_load_task': {\n          'type': 'pydatalab.bq.load',\n          'path': 'foo_path',\n          'table': 'foo_table'\n        },\n      }\n    }\n    actual = bq._get_pipeline_spec_from_config(pipeline_config)\n    self.assertPipelineConfigEquals(actual, expected, None)\n\n    # input only; this should be identical to the above\n    pipeline_config = {\n      'input': {\n        'path': 'foo_path',\n        'table': 'foo_table'\n      },\n    }\n    actual = bq._get_pipeline_spec_from_config(pipeline_config)\n    self.assertPipelineConfigEquals(actual, expected, None)\n\n    # input can also be called load, and it should be identical to the above\n    pipeline_config = {\n      'load': {\n        'path': 'foo_path',\n        'table': 'foo_table'\n      },\n    }\n    actual = bq._get_pipeline_spec_from_config(pipeline_config)\n    self.assertPipelineConfigEquals(actual, expected, None)\n\n    # only transformation\n    pipeline_config = {\n      'transformation': {\n        'query': 'foo_query'\n      },\n    }\n    expected = {\n      'tasks': {\n        'bq_pipeline_execute_task': {\n          'sql': u'foo_query_sql_string',\n          'type': 'pydatalab.bq.execute',\n        },\n      }\n    }\n    actual = bq._get_pipeline_spec_from_config(pipeline_config)\n    self.assertPipelineConfigEquals(actual, expected, None)\n\n    user_parameters = [\n      {'name': 'foo1', 'value': 'foo1', 'type': 'STRING'},\n      {'name': 'foo2', 'value': 'foo2', 'type': 'INTEGER'},\n    ]\n    # only transformation with parameters\n    pipeline_config = {\n      'transformation': {\n        'query': 'foo_query'\n      },\n      'parameters': user_parameters\n    }\n\n    expected = {\n      'tasks': {\n        'bq_pipeline_execute_task': {\n          'sql': u'foo_query_sql_string',\n          'type': 'pydatalab.bq.execute',\n        },\n      }\n    }\n    actual = bq._get_pipeline_spec_from_config(pipeline_config)\n    self.assertPipelineConfigEquals(actual, expected, user_parameters)\n\n  def test_get_load_parameters(self):\n    actual_load_config = bq._get_load_parameters(TestCases.test_input_config, None, None)\n    expected_load_config = {\n      'type': 'pydatalab.bq.load',\n      'path': 'test_path_%(_ts_month)s',\n      'table': 'test_table',\n      'schema': 'test_schema',\n      'mode': 'append',\n      'format': 'csv',\n      'csv_options': {'delimiter': ';', 'quote': '\"', 'skip': 9, 'strict': False},\n    }\n    self.assertDictEqual(actual_load_config, expected_load_config)\n\n    # Table is present in output config\n    input_config = {\n      'path': 'test_path_%(_ts_month)s',\n      'format': 'csv',\n      'csv': {'delimiter': ';', 'quote': '\"', 'skip': 9, 'strict': False},\n    }\n    output_config = {\n      'table': 'test_table',\n      'schema': 'test_schema',\n      'mode': 'append',\n    }\n    actual_load_config = bq._get_load_parameters(input_config, None, output_config)\n    self.assertDictEqual(actual_load_config, expected_load_config)\n\n    # Path is absent\n    input_config = {\n      'table': 'test_table',\n      'schema': 'test_schema'\n    }\n    actual_load_config = bq._get_load_parameters(input_config, None, None)\n    self.assertIsNone(actual_load_config)\n\n    # Path and table are absent\n    input_config = {\n      'schema': 'test_schema'\n    }\n    actual_load_config = bq._get_load_parameters(input_config, None, None)\n    self.assertIsNone(actual_load_config)\n\n    # Table is absent\n    input_config = {\n      'path': 'test_path',\n      'schema': 'test_schema'\n    }\n    actual_load_config = bq._get_load_parameters(input_config, None, None)\n    self.assertIsNone(actual_load_config)\n\n  def test_get_extract_parameters(self):\n    output_config = {\n      'path': 'test_path_%(_ts_month)s',\n      'table': 'test_table_%(_ts_month)s',\n    }\n    actual_extract_config = bq._get_extract_parameters('foo_execute_task', None, None,\n                                                       output_config)\n    expected_extract_config = {\n      'type': 'pydatalab.bq.extract',\n      'up_stream': ['foo_execute_task'],\n      'path': 'test_path_%(_ts_month)s',\n      'table': 'test_table_%(_ts_month)s',\n    }\n\n    self.assertDictEqual(actual_extract_config, expected_extract_config)\n\n    input_config = {\n      'table': 'test_table_%(_ts_month)s',\n    }\n    output_config = {\n      'path': 'test_path_%(_ts_month)s',\n    }\n    actual_extract_config = bq._get_extract_parameters('foo_execute_task', input_config, None,\n                                                       output_config)\n    self.assertDictEqual(actual_extract_config, expected_extract_config)\n\n  @mock.patch('google.datalab.utils.commands.get_notebook_item')\n  def test_get_execute_parameters(self, mock_notebook_item):\n    mock_notebook_item.return_value = google.datalab.bigquery.Query(\"\"\"SELECT @column\nFROM publicdata.samples.wikipedia\nWHERE endpoint=@endpoint\"\"\")\n\n    transformation_config = {\n      'query': 'foo_query'\n    }\n    output_config = {\n      'table': 'foo_table_%(_ts_month)s',\n      'mode': 'foo_mode'\n    }\n    parameters_config = [\n      {\n        'type': 'STRING',\n        'name': 'endpoint',\n        'value': 'Interact2'\n      },\n      {\n        'type': 'INTEGER',\n        'name': 'column',\n        'value': '1234'\n      }\n    ]\n\n    # Empty input config\n    actual_execute_config = bq._get_execute_parameters('foo_load_task', {}, transformation_config,\n                                                       output_config, parameters_config)\n    expected_execute_config = {\n      'type': 'pydatalab.bq.execute',\n      'up_stream': ['foo_load_task'],\n      'sql': 'SELECT @column\\nFROM publicdata.samples.wikipedia\\nWHERE endpoint=@endpoint',\n      'table': 'foo_table_%(_ts_month)s',\n      'mode': 'foo_mode',\n    }\n    self.assertExecuteConfigEquals(actual_execute_config, expected_execute_config,\n                                   parameters_config)\n\n    # Empty input and parameters config\n    actual_execute_config = bq._get_execute_parameters('foo_load_task', {}, transformation_config,\n                                                       output_config, None)\n    expected_execute_config = {\n      'type': 'pydatalab.bq.execute',\n      'up_stream': ['foo_load_task'],\n      'sql': 'SELECT @column\\nFROM publicdata.samples.wikipedia\\nWHERE endpoint=@endpoint',\n      'table': 'foo_table_%(_ts_month)s',\n      'mode': 'foo_mode',\n    }\n    self.assertExecuteConfigEquals(actual_execute_config, expected_execute_config,\n                                   None)\n\n    # Empty input and empty output configs\n    actual_execute_config = bq._get_execute_parameters('foo_load_task', {}, transformation_config,\n                                                       {}, parameters_config)\n    expected_execute_config = {\n      'type': 'pydatalab.bq.execute',\n      'up_stream': ['foo_load_task'],\n      'sql': 'SELECT @column\\nFROM publicdata.samples.wikipedia\\nWHERE endpoint=@endpoint',\n    }\n    self.assertExecuteConfigEquals(actual_execute_config, expected_execute_config,\n                                   parameters_config)\n\n    # Empty output config. Expected config is same as output with empty input and empty output.\n    actual_execute_config = bq._get_execute_parameters('foo_load_task', TestCases.test_input_config,\n                                                       transformation_config, {}, parameters_config)\n    expected_execute_config = {\n      'type': 'pydatalab.bq.execute',\n      'up_stream': ['foo_load_task'],\n      'sql': \"\"\"WITH input AS (\n  SELECT * FROM `test_table`\n)\n\nSELECT @column\nFROM publicdata.samples.wikipedia\nWHERE endpoint=@endpoint\"\"\",\n    }\n    self.assertExecuteConfigEquals(actual_execute_config, expected_execute_config,\n                                   parameters_config)\n\n    # With no table, and implicit data_source\n    input_config = TestCases.test_input_config.copy()\n    del input_config['table']\n    actual_execute_config = bq._get_execute_parameters('foo_load_task', input_config,\n                                                       transformation_config, {}, parameters_config)\n    expected_execute_config = {\n      'type': 'pydatalab.bq.execute',\n      'up_stream': ['foo_load_task'],\n      'sql': 'SELECT @column\\nFROM publicdata.samples.wikipedia\\nWHERE endpoint=@endpoint',\n      'data_source': 'input',\n      'path': 'test_path_%(_ts_month)s',\n      'schema': 'test_schema',\n      'source_format': 'csv',\n      'csv_options': {'delimiter': ';', 'quote': '\"', 'skip': 9, 'strict': False},\n    }\n    self.assertExecuteConfigEquals(actual_execute_config, expected_execute_config,\n                                   parameters_config)\n\n    # With no table, and explicit data_source\n    input_config['data_source'] = 'foo_data_source'\n    actual_execute_config = bq._get_execute_parameters('foo_load_task', input_config,\n                                                       transformation_config, {}, parameters_config)\n    expected_execute_config = {\n      'type': 'pydatalab.bq.execute',\n      'up_stream': ['foo_load_task'],\n      'sql': 'SELECT @column\\nFROM publicdata.samples.wikipedia\\nWHERE endpoint=@endpoint',\n      'data_source': 'foo_data_source',\n      'path': 'test_path_%(_ts_month)s',\n      'schema': 'test_schema',\n      'source_format': 'csv',\n      'csv_options': {'delimiter': ';', 'quote': '\"', 'skip': 9, 'strict': False},\n    }\n    self.assertExecuteConfigEquals(actual_execute_config, expected_execute_config,\n                                   parameters_config)\n\n    # With table and implicit sub-query\n    mock_notebook_item.return_value = google.datalab.bigquery.Query(\"\"\"SELECT @column\nFROM input\nWHERE endpoint=@endpoint\"\"\")\n    input_config = {\n      'path': 'test_path_%(_ds)s',\n      'table': 'test_table_%(_ds)s',\n    }\n    actual_execute_config = bq._get_execute_parameters(None, input_config, transformation_config,\n                                                       {}, parameters_config)\n    expected_execute_config = {\n      'type': 'pydatalab.bq.execute',\n      'sql': \"\"\"WITH input AS (\n  SELECT * FROM `test_table_{{ ds }}`\n)\n\nSELECT @column\nFROM input\nWHERE endpoint=@endpoint\"\"\"\n    }\n    self.assertExecuteConfigEquals(actual_execute_config, expected_execute_config,\n                                   parameters_config)\n\n  def assertExecuteConfigEquals(self, actual_execute_config, expected_execute_config,\n                                parameters_config):\n    actual_parameters = actual_execute_config['parameters'] if actual_execute_config else []\n    self.compare_parameters(actual_parameters, parameters_config)\n    if actual_execute_config:\n      del actual_execute_config['parameters']\n    self.assertDictEqual(actual_execute_config, expected_execute_config)\n\n  def compare_parameters(self, actual_parameters, user_parameters):\n    actual_paramaters_dict = user_parameters_dict = {}\n    if actual_parameters:\n      actual_paramaters_dict = {item['name']: (item['value'], item['type'])\n                                for item in actual_parameters}\n    if user_parameters:\n      user_parameters_dict = {item['name']: (item['value'], item['type'])\n                              for item in user_parameters}\n    self.assertDictEqual(actual_paramaters_dict, user_parameters_dict)\n\n  @mock.patch('google.datalab.contrib.pipeline.composer._api.Api.get_environment_details')\n  @mock.patch('google.datalab.Context.default')\n  @mock.patch('google.datalab.utils.commands.notebook_environment')\n  @mock.patch('google.datalab.utils.commands.get_notebook_item')\n  @mock.patch('google.datalab.bigquery.Table.exists')\n  @mock.patch('google.datalab.bigquery.commands._bigquery._get_table')\n  @mock.patch('google.datalab.storage.Bucket')\n  def test_pipeline_cell_golden(self, mock_bucket_class, mock_get_table, mock_table_exists,\n                                mock_notebook_item, mock_environment, mock_default_context,\n                                mock_composer_env):\n    import google.datalab.contrib.pipeline.airflow\n    table = google.datalab.bigquery.Table('project.test.table')\n    mock_get_table.return_value = table\n    mock_table_exists.return_value = True\n    context = TestCases._create_context()\n    mock_default_context.return_value = context\n    mock_composer_env.return_value = {\n      'config': {'gcsDagLocation': 'gs://foo_bucket/dags'}\n    }\n    env = {\n      'endpoint': 'Interact2',\n      'job_id': '1234',\n      'input_table_format': 'cloud-datalab-samples.httplogs.logs_%(_ds_nodash)s',\n      'output_table_format': 'cloud-datalab-samples.endpoints.logs_%(_ds_nodash)s'\n    }\n    mock_notebook_item.return_value = google.datalab.bigquery.Query(\n        'SELECT @column FROM input where endpoint=@endpoint')\n\n    mock_environment.return_value = env\n    name = 'bq_pipeline_test'\n    args = {'name': name, 'environment': 'foo_environment',\n            'location': 'foo_location', 'gcs_dag_bucket': 'foo_bucket',\n            'gcs_dag_file_path': 'foo_file_path', 'debug': True}\n    cell_body = \"\"\"\n            emails: foo1@test.com,foo2@test.com\n            schedule:\n                start: 2009-05-05T22:28:15Z\n                end: 2009-05-06T22:28:15Z\n                interval: '@hourly'\n            input:\n                path: gs://bucket/cloud-datalab-samples-httplogs_%(_ds_nodash)s\n                table: $input_table_format\n                csv:\n                  header: True\n                  strict: False\n                  quote: '\"'\n                  skip: 5\n                  delimiter: ','\n                schema:\n                  - name: col1\n                    type: int64\n                    mode: NULLABLE\n                    description: description1\n                  - name: col2\n                    type: STRING\n                    mode: required\n                    description: description1\n            transformation:\n                query: foo_query\n            output:\n                path: gs://bucket/cloud-datalab-samples-endpoints_%(_ds_nodash)s.csv\n                table: $output_table_format\n            parameters:\n                - name: endpoint\n                  type: STRING\n                  value: $endpoint\n                - name: column\n                  type: INTEGER\n                  value: $job_id\n    \"\"\"\n\n    output = google.datalab.bigquery.commands._bigquery._pipeline_cell(args, cell_body)\n\n    error_message = (\"Airflow pipeline successfully deployed! View dashboard for more details.\\n\"\n                     \"Composer pipeline successfully deployed! View dashboard for more details.\\n\")\n    airflow_spec_pattern = \"\"\"\nimport datetime\nfrom airflow import DAG\nfrom airflow.operators.bash_operator import BashOperator\nfrom airflow.contrib.operators.bigquery_operator import BigQueryOperator\nfrom airflow.contrib.operators.bigquery_table_delete_operator import BigQueryTableDeleteOperator\nfrom airflow.contrib.operators.bigquery_to_bigquery import BigQueryToBigQueryOperator\nfrom airflow.contrib.operators.bigquery_to_gcs import BigQueryToCloudStorageOperator\nfrom airflow.contrib.operators.gcs_to_bq import GoogleCloudStorageToBigQueryOperator\nfrom google.datalab.contrib.bigquery.operators._bq_load_operator import LoadOperator\nfrom google.datalab.contrib.bigquery.operators._bq_execute_operator import ExecuteOperator\nfrom google.datalab.contrib.bigquery.operators._bq_extract_operator import ExtractOperator\nfrom datetime import timedelta\n\ndefault_args = {\n    'owner': 'Google Cloud Datalab',\n    'email': \\['foo1@test.com', 'foo2@test.com'\\],\n    'start_date': datetime.datetime.strptime\\('2009-05-05T22:28:15', '%Y-%m-%dT%H:%M:%S'\\),\n    'end_date': datetime.datetime.strptime\\('2009-05-06T22:28:15', '%Y-%m-%dT%H:%M:%S'\\),\n}\n\ndag = DAG\\(dag_id='bq_pipeline_test', schedule_interval='@hourly', catchup=False, default_args=default_args\\)\n\nbq_pipeline_execute_task = ExecuteOperator\\(task_id='bq_pipeline_execute_task_id', parameters=(.*), sql=\\\"\\\"\\\"WITH input AS \\(\n  SELECT \\* FROM `cloud-datalab-samples\\.httplogs\\.logs_{{ ds_nodash }}`\n\\)\n\nSELECT @column FROM input where endpoint=@endpoint\\\"\\\"\\\", table=\\\"\\\"\\\"cloud-datalab-samples\\.endpoints\\.logs_{{ ds_nodash }}\\\"\\\"\\\", dag=dag\\)\nbq_pipeline_extract_task = ExtractOperator\\(task_id='bq_pipeline_extract_task_id', path=\\\"\\\"\\\"gs://bucket/cloud-datalab-samples-endpoints_{{ ds_nodash }}\\.csv\\\"\\\"\\\", table=\\\"\\\"\\\"cloud-datalab-samples\\.endpoints\\.logs_{{ ds_nodash }}\\\"\\\"\\\", dag=dag\\).*\nbq_pipeline_load_task = LoadOperator\\(task_id='bq_pipeline_load_task_id', csv_options=(.*), path=\\\"\\\"\\\"gs://bucket/cloud-datalab-samples-httplogs_{{ ds_nodash }}\\\"\\\"\\\", schema=(.*), table=\\\"\\\"\\\"cloud-datalab-samples\\.httplogs\\.logs_{{ ds_nodash }}\\\"\\\"\\\", dag=dag\\).*\nbq_pipeline_execute_task.set_upstream\\(bq_pipeline_load_task\\)\nbq_pipeline_extract_task.set_upstream\\(bq_pipeline_execute_task\\)\n\"\"\"  # noqa\n\n    pattern = re.compile(error_message + '\\n\\n' + airflow_spec_pattern)\n\n    self.assertIsNotNone(pattern.match(output))\n\n    # String that follows the \"parameters=\", for the execute operator.\n    actual_parameter_dict_str = pattern.match(output).group(1)\n    self.assertIn(\"'type': 'STRING'\", actual_parameter_dict_str)\n    self.assertIn(\"'name': 'endpoint'\", actual_parameter_dict_str)\n    self.assertIn(\"'value': 'Interact2'\", actual_parameter_dict_str)\n    self.assertIn(\"'type': 'INTEGER'\", actual_parameter_dict_str)\n    self.assertIn(\"'name': 'column'\", actual_parameter_dict_str)\n    self.assertIn(\"'value': '1234'\", actual_parameter_dict_str)\n\n    # String that follows the \"csv_options=\", for the load operator.\n    actual_csv_options_dict_str = pattern.match(output).group(2)\n    self.assertIn(\"'header': True\", actual_csv_options_dict_str)\n    self.assertIn(\"'delimiter': ','\", actual_csv_options_dict_str)\n    self.assertIn(\"'skip': 5\", actual_csv_options_dict_str)\n    self.assertIn(\"'strict': False\", actual_csv_options_dict_str)\n    self.assertIn(\"'quote': '\\\"'\", actual_csv_options_dict_str)\n\n    # String that follows the \"schema=\", i.e. the list of dicts.\n    actual_schema_str = pattern.match(output).group(3)\n    self.assertIn(\"'type': 'int64'\", actual_schema_str)\n    self.assertIn(\"'mode': 'NULLABLE'\", actual_schema_str)\n    self.assertIn(\"'name': 'col1'\", actual_schema_str)\n    self.assertIn(\"'description': 'description1'\", actual_schema_str)\n    self.assertIn(\"'type': 'STRING'\", actual_schema_str)\n    self.assertIn(\"'mode': 'required'\", actual_schema_str)\n    self.assertIn(\"'name': 'col2'\", actual_schema_str)\n    self.assertIn(\"'description': 'description1'\", actual_schema_str)\n\n    import google.datalab.utils as utils\n    cell_body_dict = utils.commands.parse_config(cell_body, utils.commands.notebook_environment())\n    expected_airflow_spec = \\\n        google.datalab.contrib.bigquery.commands._bigquery.get_airflow_spec_from_config(\n          name, cell_body_dict)\n\n    mock_bucket_class.assert_called_with('foo_bucket')\n    mock_bucket_class.return_value.object.assert_called_with('dags/bq_pipeline_test.py')\n    mock_bucket_class.return_value.object.return_value.write_stream.assert_called_with(\n      expected_airflow_spec, 'text/plain')\n"
  },
  {
    "path": "tests/bigquery/query_tests.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom builtins import str\nimport datetime\nimport mock\nimport unittest\n\nimport google.auth\nimport google.datalab\nimport google.datalab.bigquery\n\n\nclass TestCases(unittest.TestCase):\n\n  def test_parameter_validation(self):\n    sql = 'SELECT * FROM table'\n    with self.assertRaises(Exception):\n      TestCases._create_query(sql, subqueries=['subquery'])\n    sq = TestCases._create_query()\n    env = {'subquery': sq}\n    q = TestCases._create_query(sql, env=env, subqueries=['subquery'])\n    self.assertIsNotNone(q)\n    self.assertEqual(q.subqueries, {'subquery': sq})\n    self.assertEqual(q._sql, sql)\n\n    with self.assertRaises(Exception):\n      TestCases._create_query(sql, udfs=['udf'])\n    udf = TestCases._create_udf('test_udf', 'code', 'TYPE')\n    env = {'testudf': udf}\n    q = TestCases._create_query(sql, env=env, udfs=['testudf'])\n    self.assertIsNotNone(q)\n    self.assertEqual(q.udfs, {'testudf': udf})\n    self.assertEqual(q._sql, sql)\n\n    with self.assertRaises(Exception):\n      TestCases._create_query(sql, data_sources=['test_datasource'])\n    test_datasource = TestCases._create_data_source('gs://test/path')\n    env = {'test_datasource': test_datasource}\n    q = TestCases._create_query(sql, env=env, data_sources=['test_datasource'])\n    self.assertIsNotNone(q)\n    self.assertEqual(q.data_sources, {'test_datasource': test_datasource})\n    self.assertEqual(q._sql, sql)\n\n  def test_query_with_udf_object(self):\n    udf = TestCases._create_udf('test_udf', 'udf body', 'TYPE')\n    q = TestCases._create_query('SELECT * FROM table', udfs={'test_udf': udf})\n    self.assertIn('udf body', q.sql)\n\n  @mock.patch('google.datalab.bigquery._api.Api.tabledata_list')\n  @mock.patch('google.datalab.bigquery._api.Api.jobs_insert_query')\n  @mock.patch('google.datalab.bigquery._api.Api.jobs_query_results')\n  @mock.patch('google.datalab.bigquery._api.Api.jobs_get')\n  @mock.patch('google.datalab.bigquery._api.Api.tables_get')\n  def test_single_result_query(self, mock_api_tables_get, mock_api_jobs_get,\n                               mock_api_jobs_query_results, mock_api_insert_query,\n                               mock_api_tabledata_list):\n    mock_api_tables_get.return_value = TestCases._create_tables_get_result()\n    mock_api_jobs_get.return_value = {'status': {'state': 'DONE'}}\n    mock_api_jobs_query_results.return_value = {'jobComplete': True}\n    mock_api_insert_query.return_value = TestCases._create_insert_done_result()\n    mock_api_tabledata_list.return_value = TestCases._create_single_row_result()\n\n    sql = 'SELECT field1 FROM [table] LIMIT 1'\n    q = TestCases._create_query(sql)\n    context = TestCases._create_context()\n    results = q.execute(context=context).result()\n\n    self.assertEqual(sql, results.sql)\n    self.assertEqual('(%s)' % sql, q._repr_sql_())\n    self.assertEqual(1, results.length)\n    first_result = results[0]\n    self.assertEqual('value1', first_result['field1'])\n\n  @mock.patch('google.datalab.bigquery._api.Api.jobs_insert_query')\n  @mock.patch('google.datalab.bigquery._api.Api.jobs_query_results')\n  @mock.patch('google.datalab.bigquery._api.Api.jobs_get')\n  @mock.patch('google.datalab.bigquery._api.Api.tables_get')\n  def test_empty_result_query(self, mock_api_tables_get, mock_api_jobs_get,\n                              mock_api_jobs_query_results, mock_api_insert_query):\n    mock_api_tables_get.return_value = TestCases._create_tables_get_result(0)\n    mock_api_jobs_get.return_value = {'status': {'state': 'DONE'}}\n    mock_api_jobs_query_results.return_value = {'jobComplete': True}\n    mock_api_insert_query.return_value = TestCases._create_insert_done_result()\n\n    q = TestCases._create_query()\n    context = TestCases._create_context()\n    results = q.execute(context=context).result()\n\n    self.assertEqual(0, results.length)\n\n  @mock.patch('google.datalab.bigquery._api.Api.jobs_insert_query')\n  @mock.patch('google.datalab.bigquery._api.Api.jobs_query_results')\n  @mock.patch('google.datalab.bigquery._api.Api.jobs_get')\n  @mock.patch('google.datalab.bigquery._api.Api.tables_get')\n  def test_incomplete_result_query(self,\n                                   mock_api_tables_get,\n                                   mock_api_jobs_get,\n                                   mock_api_jobs_query_results,\n                                   mock_api_insert_query):\n    mock_api_tables_get.return_value = TestCases._create_tables_get_result()\n    mock_api_jobs_get.return_value = {'status': {'state': 'DONE'}}\n    mock_api_jobs_query_results.return_value = {'jobComplete': True}\n    mock_api_insert_query.return_value = TestCases._create_incomplete_result()\n\n    q = TestCases._create_query()\n    context = TestCases._create_context()\n    results = q.execute(context=context).result()\n\n    self.assertEqual(1, results.length)\n    self.assertEqual('test_job', results.job_id)\n\n  @mock.patch('google.datalab.bigquery._api.Api.jobs_insert_query')\n  def test_malformed_response_raises_exception(self, mock_api_insert_query):\n    mock_api_insert_query.return_value = {}\n\n    q = TestCases._create_query()\n\n    with self.assertRaises(Exception) as error:\n      context = TestCases._create_context()\n      q.execute(context=context).result()\n    self.assertEqual('Unexpected response from server', str(error.exception))\n\n  def test_nested_subquery_expansion(self):\n    # test expanding subquery and udf validation\n    with self.assertRaises(Exception):\n      TestCases._create_query('SELECT * FROM subquery', subqueries=['subquery'])\n\n    with self.assertRaises(Exception):\n      TestCases._create_query('SELECT test_udf(field1) FROM test_table', udfs=['test_udf'])\n\n    env = {}\n\n    # test direct subquery expansion\n    q1 = TestCases._create_query('SELECT * FROM test_table', name='q1', env=env)\n    q2 = TestCases._create_query('SELECT * FROM q1', name='q2', subqueries=['q1'], env=env)\n    self.assertEqual('''\\\nWITH q1 AS (\n  SELECT * FROM test_table\n)\n\nSELECT * FROM q1''', q2.sql)\n\n    # test recursive, second level subquery expansion\n    q3 = TestCases._create_query('SELECT * FROM q2', name='q3', subqueries=['q2'], env=env)\n    # subquery listing order is random, try both possibilities\n    expected_sql1 = '''\\\nWITH q1 AS (\n  %s\n),\nq2 AS (\n  %s\n)\n\n%s''' % (q1._sql, q2._sql, q3._sql)\n    expected_sql2 = '''\\\nWITH q2 AS (\n  %s\n),\nq1 AS (\n  %s\n)\n\n%s''' % (q2._sql, q1._sql, q3._sql)\n\n    self.assertTrue((expected_sql1 == q3.sql) or (expected_sql2 == q3.sql))\n\n  # @mock.patch('google.datalab.bigquery._api.Api.jobs_insert_query')\n  def test_subquery_expansion_order(self):\n    env = {}\n    TestCases._create_query('SELECT * FROM test_table', name='snps', env=env)\n    TestCases._create_query('SELECT * FROM snps', subqueries=['snps'], name='windows', env=env)\n    titv = TestCases._create_query('SELECT * FROM snps, windows', subqueries=['snps', 'windows'],\n                                   env=env)\n\n    # make sure snps appears before windows in the expanded sql of titv\n    snps_pos, windows_pos = titv.sql.find('snps AS'), titv.sql.find('windows AS')\n    self.assertNotEqual(snps_pos, -1, 'Could not find snps definition in expanded sql')\n    self.assertNotEqual(windows_pos, -1, 'Could not find windows definition in expanded sql')\n    self.assertLess(snps_pos, windows_pos)\n\n    # reverse the order they're referenced in titv, and make sure snps still appears before windows\n    titv = TestCases._create_query('SELECT * FROM snps, windows', subqueries=['windows', 'snps'],\n                                   env=env)\n    snps_pos, windows_pos = titv.sql.find('snps AS'), titv.sql.find('windows AS')\n    self.assertNotEqual(snps_pos, -1, 'Could not find snps definition in expanded sql')\n    self.assertNotEqual(windows_pos, -1, 'Could not find windows definition in expanded sql')\n    self.assertLess(snps_pos, windows_pos)\n\n  @staticmethod\n  def _create_query(sql='SELECT * ...', name=None, env=None, udfs=None, data_sources=None,\n                    subqueries=None):\n    if env is None:\n      env = {}\n    q = google.datalab.bigquery.Query(sql, env=env, udfs=udfs, data_sources=data_sources,\n                                      subqueries=subqueries)\n    if name:\n      env[name] = q\n    return q\n\n  @staticmethod\n  def _create_udf(name, code, return_type):\n    return google.datalab.bigquery.UDF(name, code, return_type)\n\n  @staticmethod\n  def _create_data_source(source):\n    return google.datalab.bigquery.ExternalDataSource(source=source)\n\n  @staticmethod\n  def _create_context():\n    project_id = 'test'\n    creds = mock.Mock(spec=google.auth.credentials.Credentials)\n    return google.datalab.Context(project_id, creds)\n\n  @staticmethod\n  def _create_insert_done_result():\n    # pylint: disable=g-continuation-in-parens-misaligned\n    return {\n      'jobReference': {\n        'jobId': 'test_job'\n      },\n      'configuration': {\n        'query': {\n          'destinationTable': {\n            'projectId': 'project',\n            'datasetId': 'dataset',\n            'tableId': 'table'\n          }\n        }\n      },\n      'jobComplete': True,\n    }\n\n  @staticmethod\n  def _create_single_row_result():\n    # pylint: disable=g-continuation-in-parens-misaligned\n    return {\n      'totalRows': 1,\n      'rows': [\n        {'f': [{'v': 'value1'}]}\n      ]\n    }\n\n  @staticmethod\n  def _create_empty_result():\n    # pylint: disable=g-continuation-in-parens-misaligned\n    return {\n      'totalRows': 0\n    }\n\n  @staticmethod\n  def _create_incomplete_result():\n    # pylint: disable=g-continuation-in-parens-misaligned\n    return {\n      'jobReference': {\n        'jobId': 'test_job'\n      },\n      'configuration': {\n        'query': {\n          'destinationTable': {\n            'projectId': 'project',\n            'datasetId': 'dataset',\n            'tableId': 'table'\n          }\n        }\n      },\n      'jobComplete': False\n    }\n\n  @staticmethod\n  def _create_page_result(page_token=None):\n    # pylint: disable=g-continuation-in-parens-misaligned\n    return {\n      'totalRows': 2,\n      'rows': [\n        {'f': [{'v': 'value1'}]}\n      ],\n      'pageToken': page_token\n    }\n\n  @staticmethod\n  def _create_tables_get_result(num_rows=1, schema=None):\n    if schema is None:\n      schema = [{'name': 'field1', 'type': 'string'}]\n    return {\n      'numRows': num_rows,\n      'schema': {\n        'fields': schema\n      },\n    }\n\n  def test_merged_parameters(self):\n    parameters = [\n        {'type': 'foo1', 'name': 'foo1', 'value': 'foo1'},\n        {'type': 'foo2', 'name': 'foo2', 'value': 'foo2'},\n        {'type': 'foo3', 'name': '_ds', 'value': 'foo3'},\n    ]\n    merged_parameters = google.datalab.bigquery.Query.merge_parameters(\n      parameters, date_time=datetime.datetime.now(), macros=True, types_and_values=False)\n    expected = {\n      'foo1': 'foo1',\n      'foo2': 'foo2',\n      '_ds': 'foo3',\n      '_ts': '{{ ts }}',\n      '_ds_nodash': '{{ ds_nodash }}',\n      '_ts_nodash': '{{ ts_nodash }}',\n      '_ts_year': \"\"\"{{ '{:04d}'.format(execution_date.year) }}\"\"\",\n      '_ts_month': \"\"\"{{ '{:02d}'.format(execution_date.month) }}\"\"\",\n      '_ts_day': \"\"\"{{ '{:02d}'.format(execution_date.day) }}\"\"\",\n      '_ts_hour': \"\"\"{{ '{:02d}'.format(execution_date.hour) }}\"\"\",\n      '_ts_minute': \"\"\"{{ '{:02d}'.format(execution_date.minute) }}\"\"\",\n      '_ts_second': \"\"\"{{ '{:02d}'.format(execution_date.second) }}\"\"\",\n    }\n    self.assertDictEqual(merged_parameters, expected)\n\n    date_time = datetime.datetime.now()\n    day = date_time.date()\n\n    merged_parameters = google.datalab.bigquery.Query.merge_parameters(\n      parameters, date_time=date_time, macros=False, types_and_values=False)\n    expected = {\n      u'_ts_nodash': date_time.strftime('%Y%m%d%H%M%S%f'),\n      u'_ts_second': date_time.strftime('%S'),\n      u'_ts_day': day.strftime('%d'),\n      u'_ts_minute': date_time.strftime('%M'),\n      u'_ts': date_time.isoformat(),\n      u'_ts_hour': date_time.strftime('%H'),\n      u'_ts_month': day.strftime('%m'),\n      u'_ds_nodash': day.strftime('%Y%m%d'),\n      u'_ds': 'foo3',\n      u'_ts_year': day.strftime('%Y'),\n      u'foo1': 'foo1',\n      u'foo2': 'foo2'\n    }\n    self.assertDictEqual(merged_parameters, expected)\n\n    merged_parameters = google.datalab.bigquery.Query.merge_parameters(\n      parameters, date_time=date_time, macros=False, types_and_values=True)\n    expected = {\n      u'_ts_nodash': {u'type': u'STRING', u'value': date_time.strftime('%Y%m%d%H%M%S%f')},\n      u'_ts_second': {u'type': u'STRING', u'value': date_time.strftime('%S')},\n      u'_ts_day': {u'type': u'STRING', u'value': day.strftime('%d')},\n      u'_ts_minute': {u'type': u'STRING', u'value': date_time.strftime('%M')},\n      u'_ts': {u'type': u'STRING', u'value': date_time.isoformat()},\n      u'_ts_hour': {u'type': u'STRING', u'value': date_time.strftime('%H')},\n      u'_ts_month': {u'type': u'STRING', u'value': day.strftime('%m')},\n      u'_ds_nodash': {u'type': u'STRING', u'value': day.strftime('%Y%m%d')},\n      u'_ds': {u'type': u'foo3', u'value': 'foo3'},\n      u'_ts_year': {u'type': u'STRING', u'value': day.strftime('%Y')},\n      u'foo1': {u'type': u'foo1', u'value': u'foo1'},\n      u'foo2': {u'type': u'foo2', u'value': u'foo2'}\n    }\n    self.assertDictEqual(merged_parameters, expected)\n\n  def test_resolve_parameters(self):\n    date_time = datetime.datetime.now()\n    day = date_time.date()\n    day_string = day.isoformat()\n    self.assertEqual(google.datalab.bigquery.Query.resolve_parameters('foo%(_ds)s', []),\n                     'foo{0}'.format(day_string))\n    self.assertListEqual(google.datalab.bigquery.Query.resolve_parameters(\n      ['foo%(_ds)s', 'bar%(_ds)s'], []), ['foo{0}'.format(day_string), 'bar{0}'.format(day_string)])\n    self.assertDictEqual(google.datalab.bigquery.Query.resolve_parameters(\n      {'key%(_ds)s': 'value%(_ds)s'}, []),\n      {'key{0}'.format(day_string): 'value{0}'.format(day_string)})\n    self.assertDictEqual(google.datalab.bigquery.Query.resolve_parameters(\n      {'key%(_ds)s': {'key': 'value%(_ds)s'}}, []),\n      {'key{0}'.format(day_string): {'key': 'value{0}'.format(day_string)}})\n    params = [{'name': 'custom_key', 'value': 'custom_value'}]\n    self.assertDictEqual(google.datalab.bigquery.Query.resolve_parameters(\n      {'key%(custom_key)s': 'value%(custom_key)s'}, params),\n      {'keycustom_value': 'valuecustom_value'})\n    params = [{'name': '_ds', 'value': 'custom_value'}]\n    self.assertDictEqual(google.datalab.bigquery.Query.resolve_parameters(\n      {'key%(_ds)s': 'value%(_ds)s'}, params),\n      {'keycustom_value': 'valuecustom_value'})\n"
  },
  {
    "path": "tests/bigquery/sampling_tests.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nimport unittest\nfrom google.datalab.bigquery import Sampling\n\n\nclass TestCases(unittest.TestCase):\n\n  BASE_SQL = '[<q>]'\n\n  def test_default(self):\n    expected_sql = 'SELECT * FROM (%s) LIMIT 5' % TestCases.BASE_SQL\n    self._apply_sampling(Sampling.default(), expected_sql)\n\n  def test_default_custom_count(self):\n    expected_sql = 'SELECT * FROM (%s) LIMIT 20' % TestCases.BASE_SQL\n    self._apply_sampling(Sampling.default(count=20), expected_sql)\n\n  def test_default_custom_fields(self):\n    expected_sql = 'SELECT f1,f2 FROM (%s) LIMIT 5' % TestCases.BASE_SQL\n    self._apply_sampling(Sampling.default(fields=['f1', 'f2']), expected_sql)\n\n  def test_default_all_fields(self):\n    expected_sql = 'SELECT * FROM (%s) LIMIT 5' % TestCases.BASE_SQL\n    self._apply_sampling(Sampling.default(fields=[]), expected_sql)\n\n  def test_hashed(self):\n    expected_sql = 'SELECT * FROM (%s) ' \\\n                   'WHERE MOD(ABS(FARM_FINGERPRINT(CAST(f1 AS STRING))), 100) < 5' \\\n                   % TestCases.BASE_SQL\n    self._apply_sampling(Sampling.hashed('f1', 5), expected_sql)\n\n  def test_hashed_and_limited(self):\n    expected_sql = 'SELECT * FROM (%s) ' \\\n                   'WHERE MOD(ABS(FARM_FINGERPRINT(CAST(f1 AS STRING))), 100) < 5 LIMIT 100' \\\n                   % TestCases.BASE_SQL\n    self._apply_sampling(Sampling.hashed('f1', 5, count=100), expected_sql)\n\n  def test_hashed_with_fields(self):\n    expected_sql = 'SELECT f1 FROM (%s) ' \\\n                   'WHERE MOD(ABS(FARM_FINGERPRINT(CAST(f1 AS STRING))), 100) < 5' \\\n                   % TestCases.BASE_SQL\n    self._apply_sampling(Sampling.hashed('f1', 5, fields=['f1']), expected_sql)\n\n  def test_sorted_ascending(self):\n    expected_sql = 'SELECT * FROM (%s) ORDER BY f1 LIMIT 5' % TestCases.BASE_SQL\n    self._apply_sampling(Sampling.sorted('f1'), expected_sql)\n\n  def test_sorted_descending(self):\n    expected_sql = 'SELECT * FROM (%s) ORDER BY f1 DESC LIMIT 5' % TestCases.BASE_SQL\n    self._apply_sampling(Sampling.sorted('f1', ascending=False), expected_sql)\n\n  def test_sorted_with_fields(self):\n    expected_sql = 'SELECT f1,f2 FROM (%s) ORDER BY f1 LIMIT 5' % TestCases.BASE_SQL\n    self._apply_sampling(Sampling.sorted('f1', fields=['f1', 'f2']), expected_sql)\n\n  def _apply_sampling(self, sampling, expected_query):\n    sampled_query = sampling(TestCases.BASE_SQL)\n    self.assertEqual(sampled_query, expected_query)\n"
  },
  {
    "path": "tests/bigquery/schema_tests.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nimport collections\nimport pandas\nimport sys\nimport unittest\n\nimport google.datalab.bigquery\nimport google.datalab.utils\n\n\nclass TestCases(unittest.TestCase):\n\n  def test_schema_from_dataframe(self):\n    df = TestCases._create_data_frame()\n    result = google.datalab.bigquery.Schema.from_data(df)\n    self.assertEqual(google.datalab.bigquery.Schema.from_data(TestCases._create_inferred_schema()),\n                     result)\n\n  def test_schema_from_data(self):\n    variant1 = [\n      3,\n      2.0,\n      True,\n      ['cow', 'horse', [0, []]]\n    ]\n    variant2 = collections.OrderedDict()\n    variant2['Column1'] = 3\n    variant2['Column2'] = 2.0\n    variant2['Column3'] = True\n    variant2['Column4'] = collections.OrderedDict()\n    variant2['Column4']['Column1'] = 'cow'\n    variant2['Column4']['Column2'] = 'horse'\n    variant2['Column4']['Column3'] = collections.OrderedDict()\n    variant2['Column4']['Column3']['Column1'] = 0\n    variant2['Column4']['Column3']['Column2'] = collections.OrderedDict()\n\n    master = [\n      {'name': 'Column1', 'type': 'INTEGER'},\n      {'name': 'Column2', 'type': 'FLOAT'},\n      {'name': 'Column3', 'type': 'BOOLEAN'},\n      {'name': 'Column4', 'type': 'RECORD', 'fields': [\n          {'name': 'Column1', 'type': 'STRING'},\n          {'name': 'Column2', 'type': 'STRING'},\n          {'name': 'Column3', 'type': 'RECORD', 'fields': [\n              {'name': 'Column1', 'type': 'INTEGER'},\n              {'name': 'Column2', 'type': 'RECORD', 'fields': []}\n          ]}\n      ]}\n    ]\n\n    schema_master = google.datalab.bigquery.Schema(master)\n\n    with self.assertRaises(Exception) as error1:\n      google.datalab.bigquery.Schema.from_data(variant1)\n    if sys.version_info[0] == 3:\n      self.assertEquals('Cannot create a schema from heterogeneous list [3, 2.0, True, ' +\n                        '[\\'cow\\', \\'horse\\', [0, []]]]; perhaps you meant to use ' +\n                        'Schema.from_record?', str(error1.exception))\n    else:\n      self.assertEquals('Cannot create a schema from heterogeneous list [3, 2.0, True, ' +\n                        '[u\\'cow\\', u\\'horse\\', [0, []]]]; perhaps you meant to use ' +\n                        'Schema.from_record?', str(error1.exception))\n    schema3 = google.datalab.bigquery.Schema.from_data([variant1])\n    schema4 = google.datalab.bigquery.Schema.from_data([variant2])\n    schema5 = google.datalab.bigquery.Schema.from_data(master)\n    schema6 = google.datalab.bigquery.Schema.from_record(variant1)\n    schema7 = google.datalab.bigquery.Schema.from_record(variant2)\n\n    self.assertEquals(schema_master, schema3, 'schema inferred from list of lists with from_data')\n    self.assertEquals(schema_master, schema4, 'schema inferred from list of dicts with from_data')\n    self.assertEquals(schema_master, schema5, 'schema inferred from BQ schema list with from_data')\n    self.assertEquals(schema_master, schema6, 'schema inferred from list with from_record')\n    self.assertEquals(schema_master, schema7, 'schema inferred from dict with from_record')\n\n  @staticmethod\n  def _create_data_frame():\n    data = {\n      'some': [\n        0, 1, 2, 3\n      ],\n      'column': [\n        'r0', 'r1', 'r2', 'r3'\n      ],\n      'headers': [\n        10.0, 10.0, 10.0, 10.0\n      ]\n    }\n    return pandas.DataFrame(data)\n\n  @staticmethod\n  def _create_inferred_schema(extra_field=None):\n    schema = [\n      {'name': 'some', 'type': 'INTEGER'},\n      {'name': 'column', 'type': 'STRING'},\n      {'name': 'headers', 'type': 'FLOAT'},\n    ]\n    if extra_field:\n      schema.append({'name': extra_field, 'type': 'INTEGER'})\n    return schema\n"
  },
  {
    "path": "tests/bigquery/table_tests.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom builtins import str\nfrom builtins import object\nimport calendar\nimport datetime as dt\nimport mock\nimport pandas\nimport unittest\n\nimport google.auth\nimport google.datalab\nimport google.datalab.bigquery\nimport google.datalab.utils\n\n\nclass TestCases(unittest.TestCase):\n\n  def _check_name_parts(self, table):\n    parsed_name = table._name_parts\n    self.assertEqual('test', parsed_name[0])\n    self.assertEqual('requestlogs', parsed_name[1])\n    self.assertEqual('today', parsed_name[2])\n    self.assertEqual('', parsed_name[3])\n    self.assertEqual('`test.requestlogs.today`', table._repr_sql_())\n\n  def test_api_paths(self):\n    name = google.datalab.bigquery._utils.TableName('a', 'b', 'c', 'd')\n    self.assertEqual('/projects/a/datasets/b/tables/cd',\n                     google.datalab.bigquery._api.Api._TABLES_PATH % name)\n    self.assertEqual('/projects/a/datasets/b/tables/cd/data',\n                     google.datalab.bigquery._api.Api._TABLEDATA_PATH % name)\n    name = google.datalab.bigquery._utils.DatasetName('a', 'b')\n    self.assertEqual('/projects/a/datasets/b',\n                     google.datalab.bigquery._api.Api._DATASETS_PATH % name)\n\n  def test_parse_full_name(self):\n    table = TestCases._create_table('test.requestlogs.today')\n    self._check_name_parts(table)\n\n  def test_parse_local_name(self):\n    table = TestCases._create_table('requestlogs.today')\n    self._check_name_parts(table)\n\n  def test_parse_dict_full_name(self):\n    table = TestCases._create_table({'project_id': 'test',\n                                     'dataset_id': 'requestlogs',\n                                     'table_id': 'today'})\n    self._check_name_parts(table)\n\n  def test_parse_dict_local_name(self):\n    table = TestCases._create_table({'dataset_id': 'requestlogs', 'table_id': 'today'})\n    self._check_name_parts(table)\n\n  def test_parse_named_tuple_name(self):\n    table = TestCases._create_table(google.datalab.bigquery._utils.TableName('test', 'requestlogs',\n                                                                             'today', ''))\n    self._check_name_parts(table)\n\n  def test_parse_tuple_full_name(self):\n    table = TestCases._create_table(('test', 'requestlogs', 'today'))\n    self._check_name_parts(table)\n\n  def test_parse_tuple_local(self):\n    table = TestCases._create_table(('requestlogs', 'today'))\n    self._check_name_parts(table)\n\n  def test_parse_array_full_name(self):\n    table = TestCases._create_table(['test', 'requestlogs', 'today'])\n    self._check_name_parts(table)\n\n  def test_parse_array_local(self):\n    table = TestCases._create_table(['requestlogs', 'today'])\n    self._check_name_parts(table)\n\n  def test_parse_invalid_name(self):\n    with self.assertRaises(Exception):\n      TestCases._create_table('today@')\n\n  @mock.patch('google.datalab.bigquery._api.Api.tables_get')\n  def test_table_metadata(self, mock_api_tables_get):\n    name = 'test.requestlogs.today'\n    ts = dt.datetime.utcnow()\n\n    mock_api_tables_get.return_value = TestCases._create_table_info_result(ts=ts)\n    t = TestCases._create_table(name)\n\n    metadata = t.metadata\n\n    self.assertEqual('Logs', metadata.friendly_name)\n    self.assertEqual(2, metadata.rows)\n    self.assertEqual(2, metadata.rows)\n    self.assertTrue(abs((metadata.created_on - ts).total_seconds()) <= 1)\n    self.assertEqual(None, metadata.expires_on)\n\n  @mock.patch('google.datalab.bigquery._api.Api.tables_get')\n  def test_table_schema(self, mock_api_tables):\n    mock_api_tables.return_value = TestCases._create_table_info_result()\n\n    t = TestCases._create_table('test.requestlogs.today')\n    schema = t.schema\n\n    self.assertEqual(2, len(schema))\n    self.assertEqual('name', schema[0].name)\n\n  @mock.patch('google.datalab.bigquery._api.Api.tables_get')\n  def test_table_schema_nested(self, mock_api_tables):\n    mock_api_tables.return_value = TestCases._create_table_info_nested_schema_result()\n\n    t = TestCases._create_table('test.requestlogs.today')\n    schema = t.schema\n\n    self.assertEqual(4, len(schema))\n    self.assertEqual('name', schema[0].name)\n    self.assertEqual('val', schema[1].name)\n    self.assertEqual('more', schema[2].name)\n    self.assertEqual('more.xyz', schema[3].name)\n\n    self.assertIsNone(schema['value'])\n    self.assertIsNotNone(schema['val'])\n\n  @mock.patch('google.datalab.bigquery._api.Api.tables_get')\n  def test_malformed_response_raises_exception(self, mock_api_tables_get):\n    mock_api_tables_get.return_value = {}\n\n    t = TestCases._create_table('test.requestlogs.today')\n\n    with self.assertRaises(Exception) as error:\n      t.schema\n    self.assertEqual('Unexpected table response: missing schema', str(error.exception))\n\n  @mock.patch('google.datalab.bigquery._api.Api.tables_list')\n  @mock.patch('google.datalab.bigquery._api.Api.datasets_get')\n  def test_dataset_list(self, mock_api_datasets_get, mock_api_tables_list):\n    mock_api_datasets_get.return_value = None\n    mock_api_tables_list.return_value = TestCases._create_table_list_result()\n\n    ds = google.datalab.bigquery.Dataset('testds', context=TestCases._create_context())\n\n    tables = []\n    for table in ds:\n      tables.append(table)\n    self.assertEqual(2, len(tables))\n    self.assertEqual('`test.testds.testTable1`', tables[0]._repr_sql_())\n    self.assertEqual('`test.testds.testTable2`', tables[1]._repr_sql_())\n\n  @mock.patch('google.datalab.bigquery._api.Api.tables_list')\n  @mock.patch('google.datalab.bigquery._api.Api.datasets_get')\n  def test_table_list(self, mock_api_datasets_get, mock_api_tables_list):\n    mock_api_datasets_get.return_value = None\n    mock_api_tables_list.return_value = TestCases._create_table_list_result()\n\n    ds = google.datalab.bigquery.Dataset('testds', context=TestCases._create_context())\n\n    tables = []\n    for table in ds.tables():\n      tables.append(table)\n    self.assertEqual(2, len(tables))\n    self.assertEqual('`test.testds.testTable1`', tables[0]._repr_sql_())\n    self.assertEqual('`test.testds.testTable2`', tables[1]._repr_sql_())\n\n  @mock.patch('google.datalab.bigquery._api.Api.tables_list')\n  @mock.patch('google.datalab.bigquery._api.Api.datasets_get')\n  def test_view_list(self, mock_api_datasets_get, mock_api_tables_list):\n    mock_api_datasets_get.return_value = None\n    mock_api_tables_list.return_value = TestCases._create_table_list_result()\n\n    ds = google.datalab.bigquery.Dataset('testds', context=TestCases._create_context())\n\n    views = []\n    for view in ds.views():\n      views.append(view)\n    self.assertEqual(1, len(views))\n    self.assertEqual('`test.testds.testView1`', views[0]._repr_sql_())\n\n  @mock.patch('google.datalab.bigquery._api.Api.tables_list')\n  @mock.patch('google.datalab.bigquery._api.Api.datasets_get')\n  def test_table_list_empty(self, mock_api_datasets_get, mock_api_tables_list):\n    mock_api_datasets_get.return_value = None\n    mock_api_tables_list.return_value = TestCases._create_table_list_empty_result()\n\n    ds = google.datalab.bigquery.Dataset('testds', context=TestCases._create_context())\n\n    tables = []\n    for table in ds:\n      tables.append(table)\n\n    self.assertEqual(0, len(tables))\n\n  @mock.patch('google.datalab.bigquery._api.Api.tables_get')\n  def test_table_exists(self, mock_api_tables_get):\n    mock_api_tables_get.return_value = None\n    tbl = google.datalab.bigquery.Table('testds.testTable0', context=TestCases._create_context())\n    self.assertTrue(tbl.exists())\n\n    mock_api_tables_get.side_effect = google.datalab.utils.RequestException(404, 'failed')\n    self.assertFalse(tbl.exists())\n\n  @mock.patch('google.datalab.bigquery._api.Api.tables_insert')\n  @mock.patch('google.datalab.bigquery._api.Api.tables_list')\n  @mock.patch('google.datalab.bigquery._api.Api.datasets_get')\n  def test_tables_create(self,\n                         mock_api_datasets_get,\n                         mock_api_tables_list,\n                         mock_api_tables_insert):\n    mock_api_datasets_get.return_value = None\n    mock_api_tables_list.return_value = []\n    schema = TestCases._create_inferred_schema()\n\n    mock_api_tables_insert.return_value = {}\n    with self.assertRaises(Exception) as error:\n      TestCases._create_table_with_schema(schema)\n    self.assertEqual('Table test.testds.testTable0 could not be created as it already exists',\n                     str(error.exception))\n\n    mock_api_tables_insert.return_value = {'selfLink': 'http://foo'}\n    self.assertIsNotNone(TestCases._create_table_with_schema(schema), 'Expected a table')\n\n  @mock.patch('uuid.uuid4')\n  @mock.patch('time.sleep')\n  @mock.patch('google.datalab.bigquery._api.Api.tables_list')\n  @mock.patch('google.datalab.bigquery._api.Api.tables_insert')\n  @mock.patch('google.datalab.bigquery._api.Api.tables_get')\n  @mock.patch('google.datalab.bigquery._api.Api.tabledata_insert_all')\n  @mock.patch('google.datalab.bigquery._api.Api.datasets_get')\n  def test_insert_no_table(self,\n                           mock_api_datasets_get,\n                           mock_api_tabledata_insert_all,\n                           mock_api_tables_get,\n                           mock_api_tables_insert,\n                           mock_api_tables_list,\n                           mock_time_sleep,\n                           mock_uuid):\n    mock_uuid.return_value = TestCases._create_uuid()\n    mock_time_sleep.return_value = None\n    mock_api_tables_list.return_value = []\n    mock_api_tables_insert.return_value = {'selfLink': 'http://foo'}\n    mock_api_tables_get.side_effect = google.datalab.utils.RequestException(404, 'failed')\n    mock_api_tabledata_insert_all.return_value = {}\n    mock_api_datasets_get.return_value = None\n\n    table = TestCases._create_table_with_schema(TestCases._create_inferred_schema())\n    df = TestCases._create_data_frame()\n\n    with self.assertRaises(Exception) as error:\n      table.insert(df)\n    self.assertEqual('Table %s does not exist.' % table._full_name, str(error.exception))\n\n  @mock.patch('uuid.uuid4')\n  @mock.patch('time.sleep')\n  @mock.patch('google.datalab.bigquery._api.Api.datasets_get')\n  @mock.patch('google.datalab.bigquery._api.Api.tables_list')\n  @mock.patch('google.datalab.bigquery._api.Api.tables_insert')\n  @mock.patch('google.datalab.bigquery._api.Api.tables_get')\n  @mock.patch('google.datalab.bigquery._api.Api.tabledata_insert_all')\n  def test_insert_missing_field(self,\n                                mock_api_tabledata_insert_all,\n                                mock_api_tables_get,\n                                mock_api_tables_insert,\n                                mock_api_tables_list,\n                                mock_api_datasets_get,\n                                mock_time_sleep,\n                                mock_uuid,):\n    # Truncate the schema used when creating the table so we have an unmatched column in insert.\n    schema = TestCases._create_inferred_schema()[:2]\n\n    mock_uuid.return_value = TestCases._create_uuid()\n    mock_time_sleep.return_value = None\n    mock_api_datasets_get.return_value = None\n    mock_api_tables_insert.return_value = {'selfLink': 'http://foo'}\n    mock_api_tables_list.return_value = []\n    mock_api_tables_get.return_value = {'schema': {'fields': schema}}\n    mock_api_tabledata_insert_all.return_value = {}\n\n    table = TestCases._create_table_with_schema(schema)\n    df = TestCases._create_data_frame()\n\n    with self.assertRaises(Exception) as error:\n      table.insert(df)\n    self.assertEqual('Table does not contain field headers', str(error.exception))\n\n  @mock.patch('uuid.uuid4')\n  @mock.patch('time.sleep')\n  @mock.patch('google.datalab.bigquery._api.Api.tables_list')\n  @mock.patch('google.datalab.bigquery._api.Api.tables_insert')\n  @mock.patch('google.datalab.bigquery._api.Api.tables_get')\n  @mock.patch('google.datalab.bigquery._api.Api.tabledata_insert_all')\n  @mock.patch('google.datalab.bigquery._api.Api.datasets_get')\n  def test_insert_mismatched_schema(self,\n                                    mock_api_datasets_get,\n                                    mock_api_tabledata_insert_all,\n                                    mock_api_tables_get,\n                                    mock_api_tables_insert,\n                                    mock_api_tables_list,\n                                    mock_time_sleep,\n                                    mock_uuid):\n    # Change the schema used when creating the table so we get a mismatch when inserting.\n    schema = TestCases._create_inferred_schema()\n    schema[2]['type'] = 'STRING'\n\n    mock_uuid.return_value = TestCases._create_uuid()\n    mock_time_sleep.return_value = None\n    mock_api_tables_list.return_value = []\n    mock_api_tables_insert.return_value = {'selfLink': 'http://foo'}\n    mock_api_tables_get.return_value = {'schema': {'fields': schema}}\n    mock_api_tabledata_insert_all.return_value = {}\n    mock_api_datasets_get.return_value = None\n\n    table = TestCases._create_table_with_schema(schema)\n    df = TestCases._create_data_frame()\n\n    with self.assertRaises(Exception) as error:\n      table.insert(df)\n    self.assertEqual('Field headers in data has type FLOAT but in table has type STRING',\n                     str(error.exception))\n\n  @mock.patch('uuid.uuid4')\n  @mock.patch('time.sleep')\n  @mock.patch('google.datalab.bigquery._api.Api.datasets_get')\n  @mock.patch('google.datalab.bigquery._api.Api.tables_list')\n  @mock.patch('google.datalab.bigquery._api.Api.tables_insert')\n  @mock.patch('google.datalab.bigquery._api.Api.tables_get')\n  @mock.patch('google.datalab.bigquery._api.Api.tabledata_insert_all')\n  def test_insert_dataframe(self,\n                            mock_api_tabledata_insert_all,\n                            mock_api_tables_get,\n                            mock_api_tables_insert,\n                            mock_api_tables_list,\n                            mock_api_datasets_get,\n                            mock_time_sleep, mock_uuid):\n    schema = TestCases._create_inferred_schema()\n\n    mock_uuid.return_value = TestCases._create_uuid()\n    mock_time_sleep.return_value = None\n    mock_api_datasets_get.return_value = True\n    mock_api_tables_list.return_value = []\n    mock_api_tables_insert.return_value = {'selfLink': 'http://foo'}\n    mock_api_tables_get.return_value = {'schema': {'fields': schema}}\n    mock_api_tabledata_insert_all.return_value = {}\n\n    table = TestCases._create_table_with_schema(schema)\n    df = TestCases._create_data_frame()\n\n    result = table.insert(df)\n    self.assertIsNotNone(result, \"insert_all should return the table object\")\n    mock_api_tabledata_insert_all.assert_called_with(('test', 'testds', 'testTable0', ''), [\n      {'insertId': '#0', 'json': {u'column': 'r0', u'headers': 10.0, u'some': 0}},\n      {'insertId': '#1', 'json': {u'column': 'r1', u'headers': 10.0, u'some': 1}},\n      {'insertId': '#2', 'json': {u'column': 'r2', u'headers': 10.0, u'some': 2}},\n      {'insertId': '#3', 'json': {u'column': 'r3', u'headers': 10.0, u'some': 3}}\n    ])\n\n  @mock.patch('uuid.uuid4')\n  @mock.patch('time.sleep')\n  @mock.patch('google.datalab.bigquery._api.Api.datasets_get')\n  @mock.patch('google.datalab.bigquery._api.Api.tables_list')\n  @mock.patch('google.datalab.bigquery._api.Api.tables_insert')\n  @mock.patch('google.datalab.bigquery._api.Api.tables_get')\n  @mock.patch('google.datalab.bigquery._api.Api.tabledata_insert_all')\n  def test_insert_dictlist(self,\n                           mock_api_tabledata_insert_all,\n                           mock_api_tables_get,\n                           mock_api_tables_insert,\n                           mock_api_tables_list,\n                           mock_api_datasets_get,\n                           mock_time_sleep, mock_uuid):\n    schema = TestCases._create_inferred_schema()\n\n    mock_uuid.return_value = TestCases._create_uuid()\n    mock_time_sleep.return_value = None\n    mock_api_datasets_get.return_value = True\n    mock_api_tables_list.return_value = []\n    mock_api_tables_insert.return_value = {'selfLink': 'http://foo'}\n    mock_api_tables_get.return_value = {'schema': {'fields': schema}}\n    mock_api_tabledata_insert_all.return_value = {}\n\n    table = TestCases._create_table_with_schema(schema)\n\n    result = table.insert([\n      {u'column': 'r0', u'headers': 10.0, u'some': 0},\n      {u'column': 'r1', u'headers': 10.0, u'some': 1},\n      {u'column': 'r2', u'headers': 10.0, u'some': 2},\n      {u'column': 'r3', u'headers': 10.0, u'some': 3}\n    ])\n    self.assertIsNotNone(result, \"insert_all should return the table object\")\n    mock_api_tabledata_insert_all.assert_called_with(('test', 'testds', 'testTable0', ''), [\n      {'insertId': '#0', 'json': {u'column': 'r0', u'headers': 10.0, u'some': 0}},\n      {'insertId': '#1', 'json': {u'column': 'r1', u'headers': 10.0, u'some': 1}},\n      {'insertId': '#2', 'json': {u'column': 'r2', u'headers': 10.0, u'some': 2}},\n      {'insertId': '#3', 'json': {u'column': 'r3', u'headers': 10.0, u'some': 3}}\n    ])\n\n  @mock.patch('uuid.uuid4')\n  @mock.patch('time.sleep')\n  @mock.patch('google.datalab.bigquery._api.Api.datasets_get')\n  @mock.patch('google.datalab.bigquery._api.Api.tables_list')\n  @mock.patch('google.datalab.bigquery._api.Api.tables_insert')\n  @mock.patch('google.datalab.bigquery._api.Api.tables_get')\n  @mock.patch('google.datalab.bigquery._api.Api.tabledata_insert_all')\n  def test_insert_dictlist_index(self,\n                                 mock_api_tabledata_insert_all,\n                                 mock_api_tables_get,\n                                 mock_api_tables_insert,\n                                 mock_api_tables_list,\n                                 mock_api_datasets_get,\n                                 mock_time_sleep, mock_uuid):\n    schema = TestCases._create_inferred_schema('Index')\n\n    mock_uuid.return_value = TestCases._create_uuid()\n    mock_time_sleep.return_value = None\n    mock_api_datasets_get.return_value = True\n    mock_api_tables_list.return_value = []\n    mock_api_tables_insert.return_value = {'selfLink': 'http://foo'}\n    mock_api_tables_get.return_value = {'schema': {'fields': schema}}\n    mock_api_tabledata_insert_all.return_value = {}\n\n    table = TestCases._create_table_with_schema(schema)\n\n    result = table.insert([\n      {u'column': 'r0', u'headers': 10.0, u'some': 0},\n      {u'column': 'r1', u'headers': 10.0, u'some': 1},\n      {u'column': 'r2', u'headers': 10.0, u'some': 2},\n      {u'column': 'r3', u'headers': 10.0, u'some': 3}\n    ], include_index=True)\n    self.assertIsNotNone(result, \"insert_all should return the table object\")\n    mock_api_tabledata_insert_all.assert_called_with(('test', 'testds', 'testTable0', ''), [\n      {'insertId': '#0', 'json': {u'column': 'r0', u'headers': 10.0, u'some': 0, 'Index': 0}},\n      {'insertId': '#1', 'json': {u'column': 'r1', u'headers': 10.0, u'some': 1, 'Index': 1}},\n      {'insertId': '#2', 'json': {u'column': 'r2', u'headers': 10.0, u'some': 2, 'Index': 2}},\n      {'insertId': '#3', 'json': {u'column': 'r3', u'headers': 10.0, u'some': 3, 'Index': 3}}\n    ])\n\n  @mock.patch('uuid.uuid4')\n  @mock.patch('time.sleep')\n  @mock.patch('google.datalab.bigquery._api.Api.datasets_get')\n  @mock.patch('google.datalab.bigquery._api.Api.tables_list')\n  @mock.patch('google.datalab.bigquery._api.Api.tables_insert')\n  @mock.patch('google.datalab.bigquery._api.Api.tables_get')\n  @mock.patch('google.datalab.bigquery._api.Api.tabledata_insert_all')\n  def test_insert_dictlist_named_index(self,\n                                       mock_api_tabledata_insert_all,\n                                       mock_api_tables_get,\n                                       mock_api_tables_insert,\n                                       mock_api_tables_list,\n                                       mock_api_datasets_get,\n                                       mock_time_sleep, mock_uuid):\n    schema = TestCases._create_inferred_schema('Row')\n\n    mock_uuid.return_value = TestCases._create_uuid()\n    mock_time_sleep.return_value = None\n    mock_api_datasets_get.return_value = True\n    mock_api_tables_list.return_value = []\n    mock_api_tables_insert.return_value = {'selfLink': 'http://foo'}\n    mock_api_tables_get.return_value = {'schema': {'fields': schema}}\n    mock_api_tabledata_insert_all.return_value = {}\n\n    table = TestCases._create_table_with_schema(schema)\n\n    result = table.insert([\n        {u'column': 'r0', u'headers': 10.0, u'some': 0},\n        {u'column': 'r1', u'headers': 10.0, u'some': 1},\n        {u'column': 'r2', u'headers': 10.0, u'some': 2},\n        {u'column': 'r3', u'headers': 10.0, u'some': 3}\n    ], include_index=True, index_name='Row')\n    self.assertIsNotNone(result, \"insert_all should return the table object\")\n    mock_api_tabledata_insert_all.assert_called_with(('test', 'testds', 'testTable0', ''), [\n      {'insertId': '#0', 'json': {u'column': 'r0', u'headers': 10.0, u'some': 0, 'Row': 0}},\n      {'insertId': '#1', 'json': {u'column': 'r1', u'headers': 10.0, u'some': 1, 'Row': 1}},\n      {'insertId': '#2', 'json': {u'column': 'r2', u'headers': 10.0, u'some': 2, 'Row': 2}},\n      {'insertId': '#3', 'json': {u'column': 'r3', u'headers': 10.0, u'some': 3, 'Row': 3}}\n    ])\n\n  @mock.patch('google.datalab.bigquery._api.Api.tables_get')\n  @mock.patch('google.datalab.bigquery._api.Api.jobs_insert_load')\n  @mock.patch('google.datalab.bigquery._api.Api.jobs_get')\n  def test_table_load(self, mock_api_jobs_get, mock_api_jobs_insert_load, mock_api_tables_get):\n    schema = TestCases._create_inferred_schema('Row')\n    mock_api_jobs_get.return_value = {'status': {'state': 'DONE'}}\n    mock_api_jobs_insert_load.return_value = None\n    mock_api_tables_get.return_value = {'schema': {'fields': schema}}\n    tbl = google.datalab.bigquery.Table('testds.testTable0', context=TestCases._create_context())\n    job = tbl.load('gs://foo')\n    self.assertIsNone(job)\n    mock_api_jobs_insert_load.return_value = {'jobReference': {'jobId': 'bar'}}\n    job = tbl.load('gs://foo')\n    self.assertEquals('bar', job.id)\n\n  @mock.patch('google.datalab.bigquery._api.Api.table_extract')\n  @mock.patch('google.datalab.bigquery._api.Api.jobs_get')\n  @mock.patch('google.datalab.bigquery._api.Api.tables_get')\n  def test_table_extract(self, mock_api_tables_get, mock_api_jobs_get, mock_api_table_extract):\n    mock_api_tables_get.return_value = {}\n    mock_api_jobs_get.return_value = {'status': {'state': 'DONE'}}\n    mock_api_table_extract.return_value = None\n\n    tbl = google.datalab.bigquery.Table('testds.testTable0', context=self._create_context())\n    tbl._api.table_extract = mock.Mock(return_value={'jobReference': {'jobId': 'bar'}})\n\n    job = tbl.extract('gs://foo')\n    tbl._api.table_extract.assert_called_with(tbl.name, 'gs://foo', 'CSV', False, ',', True)\n    self.assertEquals('bar', job.id)\n\n    tbl.extract('gs://foo', format='json')\n    tbl._api.table_extract.assert_called_with(tbl.name, 'gs://foo', 'NEWLINE_DELIMITED_JSON',\n                                              False, None, True)\n\n    tbl.extract('gs://foo', format='avro')\n    tbl._api.table_extract.assert_called_with(tbl.name, 'gs://foo', 'AVRO', False, None, True)\n\n  @mock.patch('google.datalab.bigquery._api.Api.tabledata_list')\n  @mock.patch('google.datalab.bigquery._api.Api.tables_get')\n  def test_table_to_dataframe(self, mock_api_tables_get, mock_api_tabledata_list):\n    schema = self._create_inferred_schema()\n    mock_api_tables_get.return_value = {'schema': {'fields': schema}}\n    mock_api_tabledata_list.return_value = {\n      'rows': [\n          {'f': [{'v': 1}, {'v': 'foo'}, {'v': 3.1415}]},\n          {'f': [{'v': 2}, {'v': 'bar'}, {'v': 0.5}]},\n      ]\n    }\n    tbl = google.datalab.bigquery.Table('testds.testTable0', context=TestCases._create_context())\n    df = tbl.to_dataframe()\n    self.assertEquals(2, len(df))\n    self.assertEquals(1, df['some'][0])\n    self.assertEquals(2, df['some'][1])\n    self.assertEquals('foo', df['column'][0])\n    self.assertEquals('bar', df['column'][1])\n    self.assertEquals(3.1415, df['headers'][0])\n    self.assertEquals(0.5, df['headers'][1])\n\n  def test_encode_dict_as_row_datetime(self):\n    when = dt.datetime(2001, 2, 3, 4, 5, 6, 7)\n    row = google.datalab.bigquery.Table._encode_dict_as_row({'fo@o': 'b@r', 'b+ar': when}, {})\n    self.assertEqual({'foo': 'b@r', 'bar': '2001-02-03T04:05:06.000007'}, row)\n\n  def test_encode_dict_as_row_date(self):\n    when = dt.date(2001, 2, 3)\n    row = google.datalab.bigquery.Table._encode_dict_as_row({'fo@o': 'b@r', 'b+ar': when}, {})\n    self.assertEqual({'foo': 'b@r', 'bar': '2001-02-03'}, row)\n\n  def test_encode_dict_as_row_time(self):\n    when = dt.time(1, 2, 3, 4)\n    row = google.datalab.bigquery.Table._encode_dict_as_row({'fo@o': 'b@r', 'b+ar': when}, {})\n    self.assertEqual({'foo': 'b@r', 'bar': '01:02:03.000004'}, row)\n\n  def test_decorators(self):\n    tbl = google.datalab.bigquery.Table('testds.testTable0', context=TestCases._create_context())\n    tbl2 = tbl.snapshot(dt.timedelta(hours=-1))\n    self.assertEquals('`test.testds.testTable0@-3600000`', tbl2._repr_sql_())\n\n    with self.assertRaises(Exception) as error:\n      tbl2 = tbl2.snapshot(dt.timedelta(hours=-2))\n    self.assertEqual('Cannot use snapshot() on an already decorated table',\n                     str(error.exception))\n\n    with self.assertRaises(Exception) as error:\n      tbl2.window(dt.timedelta(hours=-2), 0)\n    self.assertEqual('Cannot use window() on an already decorated table',\n                     str(error.exception))\n\n    with self.assertRaises(Exception) as error:\n      tbl.snapshot(dt.timedelta(days=-8))\n    self.assertEqual(\n        'Invalid snapshot relative when argument: must be within 7 days: -8 days, 0:00:00',\n        str(error.exception))\n\n    with self.assertRaises(Exception) as error:\n      tbl.snapshot(dt.timedelta(days=-8))\n    self.assertEqual(\n        'Invalid snapshot relative when argument: must be within 7 days: -8 days, 0:00:00',\n        str(error.exception))\n\n    tbl2 = tbl.snapshot(dt.timedelta(days=-1))\n    self.assertEquals('`test.testds.testTable0@-86400000`', tbl2._repr_sql_())\n\n    with self.assertRaises(Exception) as error:\n      tbl.snapshot(dt.timedelta(days=1))\n    self.assertEqual('Invalid snapshot relative when argument: 1 day, 0:00:00',\n                     str(error.exception))\n\n    with self.assertRaises(Exception) as error:\n      tbl2 = tbl.snapshot(1000)\n    self.assertEqual('Invalid snapshot when argument type: 1000',\n                     str(error.exception))\n\n    self.assertEquals('`test.testds.testTable0@-86400000`', tbl2._repr_sql_())\n\n    when = dt.datetime.utcnow() + dt.timedelta(1)\n    with self.assertRaises(Exception) as error:\n      tbl.snapshot(when)\n    self.assertEqual('Invalid snapshot absolute when argument: %s' % when,\n                     str(error.exception))\n\n    when = dt.datetime.utcnow() - dt.timedelta(8)\n    with self.assertRaises(Exception) as error:\n      tbl.snapshot(when)\n    self.assertEqual('Invalid snapshot absolute when argument: %s' % when,\n                     str(error.exception))\n\n  def test_window_decorators(self):\n    # The at test above already tests many of the conversion cases. The extra things we\n    # have to test are that we can use two values, we get a meaningful default for the second\n    # if we pass None, and that the first time comes before the second.\n    tbl = google.datalab.bigquery.Table('testds.testTable0', context=TestCases._create_context())\n\n    tbl2 = tbl.window(dt.timedelta(hours=-1))\n    self.assertEquals('`test.testds.testTable0@-3600000-0`', tbl2._repr_sql_())\n\n    with self.assertRaises(Exception) as error:\n      tbl2 = tbl2.window(-400000, 0)\n    self.assertEqual('Cannot use window() on an already decorated table',\n                     str(error.exception))\n\n    with self.assertRaises(Exception) as error:\n      tbl2.snapshot(-400000)\n    self.assertEqual('Cannot use snapshot() on an already decorated table',\n                     str(error.exception))\n\n    with self.assertRaises(Exception) as error:\n      tbl.window(dt.timedelta(0), dt.timedelta(hours=-1))\n    self.assertEqual(\n        'window: Between arguments: begin must be before end: 0:00:00, -1 day, 23:00:00',\n        str(error.exception))\n\n  @mock.patch('google.datalab.bigquery._api.Api.tables_get')\n  @mock.patch('google.datalab.bigquery._api.Api.table_update')\n  def test_table_update(self, mock_api_table_update, mock_api_tables_get):\n    schema = self._create_inferred_schema()\n    info = {'schema': {'fields': schema}, 'friendlyName': 'casper',\n            'description': 'ghostly logs',\n            'expirationTime': calendar.timegm(dt.datetime(2020, 1, 1).utctimetuple()) * 1000}\n    mock_api_tables_get.return_value = info\n    tbl = google.datalab.bigquery.Table('testds.testTable0', context=TestCases._create_context())\n    new_name = 'aziraphale'\n    new_description = 'demon duties'\n    new_schema = [{'name': 'injected', 'type': 'FLOAT'}]\n    new_schema.extend(schema)\n    new_expiry = dt.datetime(2030, 1, 1)\n    tbl.update(new_name, new_description, new_expiry, new_schema)\n    name, info = mock_api_table_update.call_args[0]\n    self.assertEqual(tbl.name, name)\n    self.assertEqual(new_name, tbl.metadata.friendly_name)\n    self.assertEqual(new_description, tbl.metadata.description)\n    self.assertEqual(new_expiry, tbl.metadata.expires_on)\n    self.assertEqual(len(new_schema), len(tbl.schema))\n\n  def test_table_to_query(self):\n    tbl = google.datalab.bigquery.Table('testds.testTable0', context=TestCases._create_context())\n    q = google.datalab.bigquery.Query.from_table(tbl)\n    self.assertEqual('SELECT * FROM `test.testds.testTable0`', q.sql)\n    q = google.datalab.bigquery.Query.from_table(tbl, fields='foo, bar')\n    self.assertEqual('SELECT foo, bar FROM `test.testds.testTable0`', q.sql)\n    q = google.datalab.bigquery.Query.from_table(tbl, fields=['bar', 'foo'])\n    self.assertEqual('SELECT bar,foo FROM `test.testds.testTable0`', q.sql)\n\n  @mock.patch('google.datalab.bigquery._api.Api.tables_get')\n  def test_row_fetcher(self, mock_api_tables_get):\n    schema = self._create_inferred_schema()\n    mock_api_tables_get.return_value = {'schema': {'fields': schema}}\n\n    dummy_row = {'f': [{'v': 1}, {'v': 'foo'}, {'v': 3.1415}]}\n    results = {\n      'rows': [dummy_row] * 10,\n      'pageToken': None\n    }\n    tbl = TestCases._create_table('test.table')\n    tbl._api.tabledata_list = mock.Mock(return_value=results)\n\n    # using Table.to_dataframe should use large pages to reduce traffic\n    tbl.to_dataframe()\n    tbl._api.tabledata_list.assert_called_with(tbl.name, max_results=100000, start_index=0)\n\n    # using Table.range or iterator should use smaller pages to reduce latency\n    list(tbl.range(start_row=0))\n    tbl._api.tabledata_list.assert_called_with(tbl.name, max_results=1024, start_index=0)\n\n    tbl[0]\n    tbl._api.tabledata_list.assert_called_with(tbl.name, max_results=1024, start_index=0)\n\n  @staticmethod\n  def _create_context():\n    project_id = 'test'\n    creds = mock.Mock(spec=google.auth.credentials.Credentials)\n    return google.datalab.Context(project_id, creds)\n\n  @staticmethod\n  def _create_table(name):\n    return google.datalab.bigquery.Table(name, TestCases._create_context())\n\n  @staticmethod\n  def _create_table_info_result(ts=None):\n    if ts is None:\n      ts = dt.datetime.utcnow()\n    epoch = dt.datetime.utcfromtimestamp(0)\n    timestamp = (ts - epoch).total_seconds() * 1000\n\n    return {\n      'description': 'Daily Logs Table',\n      'friendlyName': 'Logs',\n      'numBytes': 1000,\n      'numRows': 2,\n      'creationTime': timestamp,\n      'lastModifiedTime': timestamp,\n      'schema': {\n        'fields': [\n          {'name': 'name', 'type': 'STRING', 'mode': 'NULLABLE'},\n          {'name': 'val', 'type': 'INTEGER', 'mode': 'NULLABLE'}\n        ]\n       }\n    }\n\n  @staticmethod\n  def _create_table_info_nested_schema_result(ts=None):\n    if ts is None:\n      ts = dt.datetime.utcnow()\n    epoch = dt.datetime.utcfromtimestamp(0)\n    timestamp = (ts - epoch).total_seconds() * 1000\n\n    return {\n      'description': 'Daily Logs Table',\n      'friendlyName': 'Logs',\n      'numBytes': 1000,\n      'numRows': 2,\n      'creationTime': timestamp,\n      'lastModifiedTime': timestamp,\n      'schema': {\n        'fields': [\n          {'name': 'name', 'type': 'STRING', 'mode': 'NULLABLE'},\n          {'name': 'val', 'type': 'INTEGER', 'mode': 'NULLABLE'},\n          {'name': 'more', 'type': 'RECORD', 'mode': 'REPEATED',\n           'fields': [\n              {'name': 'xyz', 'type': 'INTEGER', 'mode': 'NULLABLE'}\n            ]\n           }\n        ]\n      }\n    }\n\n  @staticmethod\n  def _create_dataset(dataset_id):\n    return google.datalab.bigquery.Dataset(dataset_id, context=TestCases._create_context())\n\n  @staticmethod\n  def _create_table_list_result():\n    return {\n      'tables': [\n        {\n          'type': 'TABLE',\n          'tableReference': {'projectId': 'test', 'datasetId': 'testds', 'tableId': 'testTable1'}\n        },\n        {\n          'type': 'VIEW',\n          'tableReference': {'projectId': 'test', 'datasetId': 'testds', 'tableId': 'testView1'}\n        },\n        {\n          'type': 'TABLE',\n          'tableReference': {'projectId': 'test', 'datasetId': 'testds', 'tableId': 'testTable2'}\n        }\n       ]\n    }\n\n  @staticmethod\n  def _create_table_list_empty_result():\n    return {\n      'tables': []\n    }\n\n  @staticmethod\n  def _create_data_frame():\n    data = {\n      'some': [\n        0, 1, 2, 3\n      ],\n      'column': [\n        'r0', 'r1', 'r2', 'r3'\n      ],\n      'headers': [\n        10.0, 10.0, 10.0, 10.0\n      ]\n    }\n    return pandas.DataFrame(data)\n\n  @staticmethod\n  def _create_inferred_schema(extra_field=None):\n    schema = [\n      {'name': 'some', 'type': 'INTEGER'},\n      {'name': 'column', 'type': 'STRING'},\n      {'name': 'headers', 'type': 'FLOAT'},\n    ]\n    if extra_field:\n      schema.append({'name': extra_field, 'type': 'INTEGER'})\n    return schema\n\n  @staticmethod\n  def _create_table_with_schema(schema, name='test.testds.testTable0'):\n    return google.datalab.bigquery.Table(name, TestCases._create_context()).create(schema)\n\n  class _uuid(object):\n    @property\n    def hex(self):\n      return '#'\n\n  @staticmethod\n  def _create_uuid():\n    return TestCases._uuid()\n"
  },
  {
    "path": "tests/bigquery/udf_tests.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nimport unittest\n\nimport google.datalab\nimport google.datalab.bigquery\n\n\nclass TestCases(unittest.TestCase):\n\n  def _create_udf(self, name='test_udf', code='console.log(\"test\");', return_type='integer',\n                  params=None, language='js', imports=None):\n    if params is None:\n      params = [('test_param', 'integer')]\n    if code is None:\n      code = 'test code;'\n    if imports is None:\n      imports = ['gcs://mylib']\n    return google.datalab.bigquery.UDF(name, code, return_type, params, language, imports)\n\n  def test_building_udf(self):\n    code = 'console.log(\"test\");'\n    imports = ['gcs://test_lib']\n    udf = self._create_udf(code=code, imports=imports)\n\n    expected_sql = '''\\\nCREATE TEMPORARY FUNCTION test_udf (test_param integer)\nRETURNS integer\nLANGUAGE js\nAS \"\"\"\nconsole.log(\"test\");\n\"\"\"\nOPTIONS (\nlibrary=\"gcs://test_lib\"\n);\\\n'''\n    self.assertEqual(udf.name, 'test_udf')\n    self.assertEqual(udf.code, code)\n    self.assertEqual(udf.imports, imports)\n\n    self.assertEqual(udf._language, 'js')\n    self.assertEqual(udf._repr_sql_(), udf._expanded_sql())\n    self.assertEqual(udf.__repr__(), 'BigQuery UDF - code:\\n%s' % udf._code)\n    self.assertEqual(udf._expanded_sql(), expected_sql)\n\n  def test_udf_bad_return_type(self):\n    with self.assertRaisesRegexp(TypeError, 'Argument return_type should be a string'):\n      self._create_udf(return_type=['integer'])\n\n  def test_udf_bad_params(self):\n    with self.assertRaisesRegexp(TypeError, 'Argument params should be a list'):\n      self._create_udf(params={'param1': 'param2'})\n\n  def test_udf_params_order(self):\n    udf = self._create_udf(params=[('param1', 'int'), ('param2', 'string'), ('param3', 'array')])\n    self.assertIn('param1 int,param2 string,param3 array', udf._expanded_sql())\n\n  def test_udf_bad_imports(self):\n    with self.assertRaisesRegexp(TypeError, 'Argument imports should be a list'):\n      self._create_udf(imports='gcs://mylib')\n\n  def test_udf_imports_non_js(self):\n    with self.assertRaisesRegexp(Exception, 'Imports are available for Javascript'):\n      self._create_udf(language='sql')\n\n  def test_query_with_udf(self):\n    code = 'console.log(\"test\");'\n    return_type = 'integer'\n    params = [('test_param', 'integer')]\n    language = 'js'\n    imports = ''\n    udf = google.datalab.bigquery.UDF('test_udf', code, return_type, params, language, imports)\n    sql = 'SELECT test_udf(col) FROM mytable'\n    expected_sql = '''\\\nCREATE TEMPORARY FUNCTION test_udf (test_param integer)\nRETURNS integer\nLANGUAGE js\nAS \"\"\"\nconsole.log(\"test\");\n\"\"\"\nOPTIONS (\n\n);\nSELECT test_udf(col) FROM mytable\\\n'''\n    query = google.datalab.bigquery.Query(sql, udfs={'udf': udf})\n    self.assertEquals(query.sql, expected_sql)\n\n    # Alternate form of passing the udf using notebook environment\n    query = google.datalab.bigquery.Query(sql, udfs=['udf'], env={'udf': udf})\n    self.assertEquals(query.sql, expected_sql)\n\n  def test_query_with_sql_udf(self):\n    code = 'test_param + 1'\n    return_type = 'INT64'\n    params = [('test_param', 'INT64')]\n    language = 'sql'\n    imports = ''\n    udf = google.datalab.bigquery.UDF('test_udf', code, return_type, params, language, imports)\n    sql = 'SELECT test_udf(col) FROM mytable'\n    expected_sql = '''\\\nCREATE TEMPORARY FUNCTION test_udf (test_param INT64)\nRETURNS INT64\nAS (\ntest_param + 1\n);\nSELECT test_udf(col) FROM mytable\\\n'''\n    query = google.datalab.bigquery.Query(sql, udfs={'udf': udf})\n    self.assertEquals(query.sql, expected_sql)\n\n    # Alternate form of passing the udf using notebook environment\n    query = google.datalab.bigquery.Query(sql, udfs=['udf'], env={'udf': udf})\n    self.assertEquals(query.sql, expected_sql)\n"
  },
  {
    "path": "tests/bigquery/view_tests.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nimport mock\nimport unittest\n\nimport google.auth\nimport google.datalab\nimport google.datalab.bigquery\n\n\nclass TestCases(unittest.TestCase):\n\n  def test_view_repr_sql(self):\n    name = 'test.testds.testView0'\n    view = google.datalab.bigquery.View(name, TestCases._create_context())\n    self.assertEqual('`%s`' % name, view._repr_sql_())\n\n  @mock.patch('google.datalab.bigquery._api.Api.tables_insert')\n  @mock.patch('google.datalab.bigquery._api.Api.tables_get')\n  @mock.patch('google.datalab.bigquery._api.Api.tables_list')\n  @mock.patch('google.datalab.bigquery._api.Api.datasets_get')\n  def test_view_create(self,\n                       mock_api_datasets_get,\n                       mock_api_tables_list,\n                       mock_api_tables_get,\n                       mock_api_tables_insert):\n    mock_api_datasets_get.return_value = None\n    mock_api_tables_list.return_value = []\n    mock_api_tables_get.return_value = None\n    mock_api_tables_insert.return_value = TestCases._create_tables_insert_success_result()\n\n    name = 'test.testds.testView0'\n    sql = 'select * from test.testds.testTable0'\n    view = google.datalab.bigquery.View(name, TestCases._create_context())\n    result = view.create(sql)\n    self.assertTrue(view.exists())\n    self.assertEqual('`%s`' % name, view._repr_sql_())\n    self.assertIsNotNone(result, 'Expected a view')\n\n  @mock.patch('google.datalab.bigquery._api.Api.tables_insert')\n  @mock.patch('google.datalab.bigquery._api.Api.tabledata_list')\n  @mock.patch('google.datalab.bigquery._api.Api.jobs_insert_query')\n  @mock.patch('google.datalab.bigquery._api.Api.jobs_query_results')\n  @mock.patch('google.datalab.bigquery._api.Api.jobs_get')\n  @mock.patch('google.datalab.bigquery._api.Api.tables_get')\n  def test_view_result(self, mock_api_tables_get, mock_api_jobs_get, mock_api_jobs_query_results,\n                       mock_api_insert_query, mock_api_tabledata_list, mock_api_tables_insert):\n\n    mock_api_insert_query.return_value = TestCases._create_insert_done_result()\n    mock_api_tables_insert.return_value = TestCases._create_tables_insert_success_result()\n    mock_api_jobs_query_results.return_value = {'jobComplete': True}\n    mock_api_tables_get.return_value = TestCases._create_tables_get_result()\n    mock_api_jobs_get.return_value = {'status': {'state': 'DONE'}}\n    mock_api_tabledata_list.return_value = TestCases._create_single_row_result()\n\n    name = 'test.testds.testView0'\n    sql = 'select * from test.testds.testTable0'\n    context = TestCases._create_context()\n    view = google.datalab.bigquery.View(name, context)\n    view.create(sql)\n    q = google.datalab.bigquery.Query.from_view(view)\n    results = q.execute(context=context).result()\n\n    self.assertEqual(1, results.length)\n    first_result = results[0]\n    self.assertEqual('value1', first_result['field1'])\n\n  @mock.patch('google.datalab.bigquery._api.Api.tables_insert')\n  @mock.patch('google.datalab.bigquery._api.Api.tables_get')\n  @mock.patch('google.datalab.bigquery._api.Api.table_update')\n  @mock.patch('google.datalab.Context.default')\n  def test_view_update(self, mock_context_default, mock_api_table_update,\n                       mock_api_tables_get, mock_api_tables_insert):\n    mock_api_tables_insert.return_value = TestCases._create_tables_insert_success_result()\n    mock_context_default.return_value = TestCases._create_context()\n    mock_api_table_update.return_value = None\n    friendly_name = 'casper'\n    description = 'ghostly logs'\n    sql = 'select * from `test.testds.testTable0`'\n    info = {'friendlyName': friendly_name,\n            'description': description,\n            'view': {'query': sql}}\n    mock_api_tables_get.return_value = info\n    name = 'test.testds.testView0'\n    view = google.datalab.bigquery.View(name, TestCases._create_context())\n    view.create(sql)\n    self.assertEqual(friendly_name, view.friendly_name)\n    self.assertEqual(description, view.description)\n    self.assertEqual(sql, view.query.sql)\n\n    new_friendly_name = 'aziraphale'\n    new_description = 'demon duties'\n    new_query = 'SELECT 3 AS x'\n    view.update(new_friendly_name, new_description, new_query)\n\n    self.assertEqual(new_friendly_name, view.friendly_name)\n    self.assertEqual(new_description, view.description)\n    self.assertEqual(new_query, view.query.sql)\n\n  @staticmethod\n  def _create_tables_insert_success_result():\n    return {'selfLink': 'http://foo'}\n\n  @staticmethod\n  def _create_insert_done_result():\n    # pylint: disable=g-continuation-in-parens-misaligned\n    return {\n      'jobReference': {\n        'jobId': 'test_job'\n      },\n      'configuration': {\n        'query': {\n          'destinationTable': {\n            'projectId': 'project',\n            'datasetId': 'dataset',\n            'tableId': 'table'\n          }\n        }\n      },\n      'jobComplete': True,\n    }\n\n  @staticmethod\n  def _create_tables_get_result(num_rows=1, schema=None):\n    if not schema:\n      schema = [{'name': 'field1', 'type': 'string'}]\n    return {\n      'numRows': num_rows,\n      'schema': {\n        'fields': schema\n      },\n    }\n\n  @staticmethod\n  def _create_single_row_result():\n    # pylint: disable=g-continuation-in-parens-misaligned\n    return {\n      'totalRows': 1,\n      'rows': [\n        {'f': [{'v': 'value1'}]}\n      ]\n    }\n\n  @staticmethod\n  def _create_context():\n    project_id = 'test'\n    creds = mock.Mock(spec=google.auth.credentials.Credentials)\n    return google.datalab.Context(project_id, creds)\n"
  },
  {
    "path": "tests/context_tests.py",
    "content": "# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nimport unittest\nimport mock\n\nfrom google.datalab import Context\nfrom google.datalab.utils import _utils as du\n\n\nclass TestCases(unittest.TestCase):\n\n  def test_credentials(self):\n    dummy_creds = {}\n    c = Context('test_project', credentials=dummy_creds)\n\n    self.assertEqual(c.credentials, dummy_creds)\n\n    dummy_creds = {'test': 'test'}\n    c.set_credentials(dummy_creds)\n    self.assertEqual(c.credentials, dummy_creds)\n\n  def test_config(self):\n    dummy_config = {}\n    c = Context('test_project', credentials=None, config=dummy_config)\n\n    self.assertEqual(c.config, dummy_config)\n\n    dummy_config = {'test': 'test'}\n    c.set_config(dummy_config)\n    self.assertEqual(c.config, dummy_config)\n\n    c = Context('test_project', None, None)\n    self.assertEqual(c.config, Context._get_default_config())\n\n  def test_project(self):\n    dummy_project = 'test_project'\n    c = Context(dummy_project, credentials=None, config=None)\n\n    self.assertEqual(c.project_id, dummy_project)\n\n    dummy_project = 'test_project2'\n    c.set_project_id(dummy_project)\n    self.assertEqual(c.project_id, dummy_project)\n\n    c = Context(None, None, None)\n    with self.assertRaises(Exception):\n      print(c.project_id)\n\n  @mock.patch('google.datalab.utils._utils.get_credentials')\n  @mock.patch('google.datalab.utils._utils.get_default_project_id')\n  @mock.patch('google.datalab.utils._utils.save_project_id')\n  def test_default_project(self, mock_save_project_id, mock_get_default_project_id,\n                           mock_get_credentials):\n    # verify setting the project on a default Context object sets\n    # the global default project\n\n    global default_project\n    default_project = ''\n\n    def save_project(project=None):\n      global default_project\n      default_project = project\n\n    def get_project():\n      global default_project\n      return default_project\n\n    mock_save_project_id.side_effect = save_project\n    mock_get_default_project_id.side_effect = get_project\n    mock_get_credentials.return_value = ''\n\n    c = Context.default()\n    dummy_project = 'test_project3'\n    c.set_project_id(dummy_project)\n    self.assertEqual(du.get_default_project_id(), dummy_project)\n\n  @mock.patch('google.datalab.utils._utils.get_credentials')\n  def test_is_signed_in(self, mock_get_credentials):\n    mock_get_credentials.side_effect = Exception('No creds!')\n    self.assertFalse(Context._is_signed_in())\n\n    mock_get_credentials.return_value = {}\n    mock_get_credentials.side_effect = None\n    self.assertTrue(Context._is_signed_in())\n\n  @mock.patch('google.datalab.utils._utils.get_credentials')\n  @mock.patch('google.datalab.utils._utils.get_default_project_id')\n  @mock.patch('google.datalab.utils._utils.save_project_id')\n  def test_default_context(self, mock_save_project_id, mock_get_default_project_id,\n                           mock_get_credentials):\n\n    mock_get_default_project_id.return_value = 'default_project'\n    mock_get_credentials.return_value = ''\n\n    c = Context.default()\n    default_project = c.project_id\n    self.assertEqual(default_project, 'default_project')\n\n    # deliberately change the default project and make sure it's reset\n    c.set_project_id('test_project4')\n\n    self.assertEqual(Context.default().project_id, 'default_project')\n"
  },
  {
    "path": "tests/integration/storage_test.py",
    "content": "\"\"\"Integration tests for google.datalab.storage.\"\"\"\n\nfrom __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport logging\nimport random\nimport string\nimport unittest\n\nimport google.datalab\nfrom google.datalab import storage\n\n\nclass StorageTest(unittest.TestCase):\n\n  def setUp(self):\n    self._context = google.datalab.Context.default()\n    logging.info('Using project: %s', self._context.project_id)\n\n    suffix = ''.join(random.choice(string.lowercase) for _ in range(8))\n    self._test_bucket_name = '{}-{}'.format(self._context.project_id, suffix)\n    logging.info('test bucket: %s', self._test_bucket_name)\n\n  def test_object_deletion_consistency(self):\n    b = storage.Bucket(self._test_bucket_name, context=self._context)\n    b.create()\n    o = b.object('sample')\n    o.write_stream('contents', 'text/plain')\n    o.delete()\n    b.delete()\n\n\nif __name__ == '__main__':\n  logging.basicConfig(level=logging.INFO)\n  unittest.main()\n"
  },
  {
    "path": "tests/kernel/__init__.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n"
  },
  {
    "path": "tests/kernel/bigquery_tests.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nimport json\nimport mock\nimport pandas\nimport six\nimport unittest\n\nfrom datetime import datetime\n\nimport google\nimport google.auth\nimport google.datalab  # noqa\nimport google.datalab.bigquery as bq\nimport google.datalab.bigquery.commands\nimport google.datalab.storage\nimport google.datalab.utils.commands  # noqa\n# import Python so we can mock the parts we need to here.\nimport IPython\nimport IPython.core.magic\n\n\ndef noop_decorator(func):\n  return func\n\n\nIPython.core.magic.register_line_cell_magic = noop_decorator\nIPython.core.magic.register_line_magic = noop_decorator\nIPython.core.magic.register_cell_magic = noop_decorator\nIPython.get_ipython = mock.Mock()\n\n\nclass TestCases(unittest.TestCase):\n\n  def test_table_schema(self):\n    import jsonschema\n    good_schemas = [\n      {\n        'schema': [\n          {'name': 'col1', 'type': 'int64', 'mode': 'NULLABLE', 'description': 'description1'},\n          {'name': 'col1', 'type': 'STRING', 'mode': 'required', 'description': 'description1'}\n        ]\n      },\n      {\n        'schema': [\n          {'name': 'col1', 'type': 'record', 'mode': 'repeated', 'description': 'description1',\n           'fields': [\n             {'name': 'field1', 'type': 'int64'},\n             {'name': 'field2', 'type': 'int64'},\n             {'name': 'field3', 'type': 'record',\n              'fields': [\n                {'name': 'nestedField1', 'type': 'STRING'},\n                {'name': 'nestedField2', 'type': 'STRING'}\n              ]}\n           ]}\n        ]\n      }\n    ]\n\n    bad_schemas = [\n      {\n        # Bad type.\n        'schema': [\n          {'name': 'col1', 'type': 'badtype'}\n        ]\n      },\n      {\n        # Bad type. Strictly upper and lower case are supported.\n        'schema': [\n          {'name': 'col1', 'type': 'stRING'}\n        ]\n      },\n      {\n        # Missing name.\n        'schema': [\n          {'type': 'string'}\n        ]\n      },\n      {\n        # Missing type.\n        'schema': [\n          {'name': 'col1'}\n        ]\n      },\n      {\n        # Fields should be an array.\n        'schema': [\n          {'name': 'col1', 'type': 'string', 'fields': 'badfields'}\n        ]\n      }\n    ]\n\n    for s in good_schemas:\n      record = google.datalab.utils.commands.parse_config(json.dumps(s), {})\n      jsonschema.validate(record,\n                          bq.commands._bigquery.BigQuerySchema.TABLE_SCHEMA_SCHEMA)\n\n    for s in bad_schemas:\n      record = google.datalab.utils.commands.parse_config(json.dumps(s), {})\n      with self.assertRaises(Exception):\n        jsonschema.validate(record, bq.commands._bigquery.table_schema_schema)\n\n  @mock.patch('google.datalab.utils.commands.notebook_environment')\n  @mock.patch('google.datalab.Context.default')\n  def test_udf_cell(self, mock_default_context, mock_notebook_environment):\n    env = {}\n    mock_default_context.return_value = TestCases._create_context()\n    mock_notebook_environment.return_value = env\n\n    # no cell body\n    with self.assertRaisesRegexp(Exception, 'UDF return type must be defined'):\n      bq.commands._bigquery._udf_cell({'name': 'test_udf', 'language': 'js'}, '')\n\n    # no name\n    with self.assertRaisesRegexp(Exception, 'Declaration must be of the form %%bq udf --name'):\n      bq.commands._bigquery._udf_cell({'name': None, 'language': 'js'}, 'test_cell_body')\n\n    # no return type\n    cell_body = \"\"\"\n    // @param word STRING\n    // @param corpus STRING\n    re = new RegExp(word, 'g');\n    return corpus.match(re || []).length;\n    \"\"\"\n    with self.assertRaisesRegexp(Exception, 'UDF return type must be defined'):\n      bq.commands._bigquery._udf_cell({'name': 'count_occurrences', 'language': 'js'}, cell_body)\n\n    # too many return statements\n    cell_body = \"\"\"\n    // @param word STRING\n    // @param corpus STRING\n    // @returns INTEGER\n    // @returns STRING\n    re = new RegExp(word, 'g');\n    return corpus.match(re || []).length;\n    \"\"\"\n    with self.assertRaisesRegexp(Exception, 'Found more than one return'):\n      bq.commands._bigquery._udf_cell({'name': 'count_occurrences', 'language': 'js'}, cell_body)\n\n    cell_body = \"\"\"\n    // @param word STRING\n    // @param corpus STRING\n    // @returns INTEGER\n    re = new RegExp(word, 'g');\n    return corpus.match(re || []).length;\n    \"\"\"\n    bq.commands._bigquery._udf_cell({'name': 'count_occurrences', 'language': 'js'}, cell_body)\n    udf = env['count_occurrences']\n    self.assertIsNotNone(udf)\n    self.assertEquals('count_occurrences', udf._name)\n    self.assertEquals('js', udf._language)\n    self.assertEquals('INTEGER', udf._return_type)\n    self.assertEquals([('word', 'STRING'), ('corpus', 'STRING')], udf._params)\n    self.assertEquals([], udf._imports)\n\n    # param types with spaces (regression for pull request 373)\n    cell_body = \"\"\"\n    // @param test_param ARRAY<STRUCT<index INT64, value STRING>>\n    // @returns INTEGER\n    \"\"\"\n    bq.commands._bigquery._udf_cell({'name': 'count_occurrences', 'language': 'js'}, cell_body)\n    udf = env['count_occurrences']\n    self.assertIsNotNone(udf)\n    self.assertEquals([('test_param', 'ARRAY<STRUCT<index INT64, value STRING>>')], udf._params)\n\n  @mock.patch('google.datalab.utils.commands.notebook_environment')\n  def test_datasource_cell(self, mock_notebook_env):\n    env = {}\n    mock_notebook_env.return_value = env\n    args = {'name': 'test_ds', 'paths': 'test_path', 'format': None, 'compressed': None}\n    cell_body = {\n      'schema': [\n        {'name': 'col1', 'type': 'int64', 'mode': 'NULLABLE', 'description': 'description1'},\n        {'name': 'col1', 'type': 'STRING', 'mode': 'required', 'description': 'description1'}\n      ]\n    }\n    bq.commands._bigquery._datasource_cell(args, json.dumps(cell_body))\n    self.assertIsInstance(env['test_ds'], bq.ExternalDataSource)\n    self.assertEqual(env['test_ds']._source, ['test_path'])\n    self.assertEqual(env['test_ds']._source_format, 'csv')\n\n  @mock.patch('google.datalab.bigquery.Query.execute')\n  @mock.patch('google.datalab.utils.commands.notebook_environment')\n  @mock.patch('google.datalab.Context.default')\n  def test_query_cell(self, mock_default_context, mock_notebook_environment, mock_query_execute):\n    env = {}\n    mock_default_context.return_value = TestCases._create_context()\n    mock_notebook_environment.return_value = env\n    IPython.get_ipython().user_ns = env\n\n    # test query creation\n    q1_body = 'SELECT * FROM test_table'\n\n    # no query name specified. should execute\n    bq.commands._bigquery._query_cell(\n      {'name': None, 'udfs': None, 'datasources': None, 'subqueries': None}, q1_body)\n    mock_query_execute.assert_called_with()\n\n    # test query creation\n    bq.commands._bigquery._query_cell(\n      {'name': 'q1', 'udfs': None, 'datasources': None, 'subqueries': None}, q1_body)\n    mock_query_execute.assert_called_with()\n\n    q1 = env['q1']\n    self.assertIsNotNone(q1)\n    self.assertEqual(q1.udfs, {})\n    self.assertEqual(q1.subqueries, {})\n    self.assertEqual(q1_body, q1._sql)\n    self.assertEqual(q1_body, q1.sql)\n\n    # test subquery reference and expansion\n    q2_body = 'SELECT * FROM q1'\n    bq.commands._bigquery._query_cell(\n      {'name': 'q2', 'udfs': None, 'datasources': None, 'subqueries': ['q1']}, q2_body)\n    q2 = env['q2']\n    self.assertIsNotNone(q2)\n    self.assertEqual(q2.udfs, {})\n    self.assertEqual({'q1': q1}, q2.subqueries)\n    expected_sql = '''\\\nWITH q1 AS (\n  %s\n)\n\n%s''' % (q1_body, q2_body)\n    self.assertEqual(q2_body, q2._sql)\n    self.assertEqual(expected_sql, q2.sql)\n\n  @mock.patch('google.datalab.Context.default')\n  @mock.patch('google.datalab.bigquery.Query.execute')\n  @mock.patch('google.datalab.utils.commands.get_notebook_item')\n  def test_execute_cell(self, mock_get_notebook_item, mock_query_execute, mock_default_context):\n    args = {'query': 'test_query', 'verbose': None, 'to_dataframe': None, 'table': None,\n            'dataframe_start_row': None, 'dataframe_max_rows': None, 'nocache': None,\n            'mode': None, 'large': None}\n    cell_body = ''\n    mock_get_notebook_item.return_value = bq.Query('test_sql')\n    bq.commands._bigquery._execute_cell(args, cell_body)\n\n    args['to_dataframe'] = True\n    bq.commands._bigquery._execute_cell(args, cell_body)\n\n    # test --verbose\n    args['verbose'] = True\n    with mock.patch('sys.stdout', new=six.StringIO()) as mocked_stdout:\n      bq.commands._bigquery._execute_cell(args, cell_body)\n    self.assertEqual(mocked_stdout.getvalue(), 'test_sql\\n')\n    args['verbose'] = False\n\n  @staticmethod\n  def _create_context():\n    project_id = 'test'\n    creds = mock.Mock(spec=google.auth.credentials.Credentials)\n    return google.datalab.Context(project_id, creds)\n\n  @mock.patch('google.datalab.bigquery.commands._bigquery._get_table')\n  @mock.patch('google.datalab.bigquery.Query.execute')\n  @mock.patch('google.datalab.Context.default')\n  @mock.patch('google.datalab.utils.commands.get_notebook_item')\n  def test_sample_cell(self, mock_get_notebook_item, mock_context_default,\n                       mock_query_execute, mock_get_table):\n    args = {'query': None, 'table': None, 'view': None, 'fields': None,\n            'count': 5, 'percent': 1, 'key_field': None, 'order': None,\n            'profile': None, 'verbose': None, 'method': 'limit'}\n    cell_body = ''\n    with self.assertRaises(Exception):\n      bq.commands._bigquery._sample_cell(args, cell_body)\n\n    args['query'] = 'test_query'\n    mock_get_notebook_item.return_value = None\n    with self.assertRaises(Exception):\n      bq.commands._bigquery._sample_cell(args, cell_body)\n\n    # query passed, no other parameters\n    mock_get_notebook_item.return_value = bq.Query('test_sql')\n    bq.commands._bigquery._sample_cell(args, cell_body)\n    call_args = mock_query_execute.call_args[0]\n    call_kwargs = mock_query_execute.call_args[1]\n    self.assertEqual(call_args[0]._output_type, 'table')\n    self.assertEqual(call_kwargs['sampling']('test_sql'),\n                     bq._sampling.Sampling.default()('test_sql'))\n\n    # test --profile\n    args['profile'] = True\n    mock_query_execute.return_value.result = lambda: pandas.DataFrame({'c': 'v'}, index=['c'])\n    bq.commands._bigquery._sample_cell(args, cell_body)\n    call_args = mock_query_execute.call_args[0]\n    self.assertEqual(call_args[0]._output_type, 'dataframe')\n\n    # test --verbose\n    args['verbose'] = True\n    with mock.patch('sys.stdout', new=six.StringIO()) as mocked_stdout:\n      bq.commands._bigquery._sample_cell(args, cell_body)\n    self.assertEqual(mocked_stdout.getvalue(), 'test_sql\\n')\n    args['verbose'] = False\n\n    # bad query\n    mock_get_notebook_item.return_value = None\n    with self.assertRaises(Exception):\n      bq.commands._bigquery._sample_cell(args, cell_body)\n\n    # table passed\n    args['query'] = None\n    args['table'] = 'test.table'\n    mock_get_notebook_item.return_value = bq.Table('test.table')\n    bq.commands._bigquery._sample_cell(args, cell_body)\n\n    # bad table\n    mock_get_table.return_value = None\n    with self.assertRaises(Exception):\n      bq.commands._bigquery._sample_cell(args, cell_body)\n\n    # view passed\n    args['table'] = None\n    args['view'] = 'test_view'\n    mock_get_notebook_item.return_value = bq.View('test.view')\n    bq.commands._bigquery._sample_cell(args, cell_body)\n\n    # bad view\n    mock_get_notebook_item.return_value = None\n    with self.assertRaises(Exception):\n      bq.commands._bigquery._sample_cell(args, cell_body)\n\n  @mock.patch('google.datalab.bigquery.Query.dry_run')\n  @mock.patch('google.datalab.Context.default')\n  @mock.patch('google.datalab.bigquery.commands._bigquery._get_query_argument')\n  def test_dry_run_cell(self, mock_get_query_argument, mock_context_default, mock_dry_run):\n    args = {'query': 'test_query'}\n    cell_body = ''\n    mock_get_query_argument.return_value = bq.Query('test_sql')\n\n    # test --verbose\n    args['verbose'] = True\n    with mock.patch('sys.stdout', new=six.StringIO()) as mocked_stdout:\n      bq.commands._bigquery._dryrun_cell(args, cell_body)\n    self.assertEqual(mocked_stdout.getvalue(), 'test_sql\\n')\n    args['verbose'] = False\n\n  @mock.patch('google.datalab.Context.default')\n  @mock.patch('google.datalab.utils._utils.get_credentials')\n  @mock.patch('google.datalab.bigquery.Table.exists')\n  @mock.patch('google.datalab.utils.commands.get_notebook_item')\n  def test_get_table(self, mock_get_notebook_item, mock_table_exists, mock_get_credentials,\n                     mock_default_context):\n    # test bad name\n    mock_get_notebook_item.return_value = None\n    mock_table_exists.return_value = False\n    t = bq.commands._bigquery._get_table('bad.name')\n    self.assertIsNone(t)\n\n    # test good table name\n    test_table_name = 'testproject.test.table'\n    mock_get_notebook_item.return_value = bq.Table(test_table_name)\n    t = bq.commands._bigquery._get_table(test_table_name)\n    self.assertEqual(t.full_name, test_table_name)\n\n    # test table name reference\n    mock_get_notebook_item.return_value = test_table_name\n    mock_table_exists.return_value = True\n    t = bq.commands._bigquery._get_table(test_table_name)\n    self.assertEqual(t.full_name, test_table_name)\n\n    self.assertIn(test_table_name, bq.commands._bigquery._existing_table_cache)\n\n  @mock.patch('google.datalab.Context.default')\n  @mock.patch('google.datalab.bigquery.Datasets')\n  @mock.patch('google.datalab.bigquery.commands._bigquery._render_list')\n  def test_dataset_line_list(self, mock_render_list, mock_datasets, mock_default_context):\n    args = {'command': 'list', 'filter': None, 'project': None}\n    datasets = ['ds1', 'ds2', 'ds11']\n    mock_datasets.return_value = iter(datasets)\n    bq.commands._bigquery._dataset_line(args)\n    mock_render_list.assert_called_with(datasets)\n\n  @mock.patch('google.datalab.Context.default')\n  @mock.patch('google.datalab.bigquery.Datasets')\n  @mock.patch('google.datalab.bigquery.commands._bigquery._render_list')\n  def test_dataset_line_list_asterisk(self, mock_render_list, mock_datasets,\n                                      mock_default_context):\n    args = {'command': 'list', 'filter': '*', 'project': None}\n    datasets = ['ds1', 'ds2', 'ds11']\n    mock_datasets.return_value = iter(datasets)\n    bq.commands._bigquery._dataset_line(args)\n    mock_render_list.assert_called_with(datasets)\n\n  @mock.patch('google.datalab.Context.default')\n  @mock.patch('google.datalab.bigquery.Datasets')\n  @mock.patch('google.datalab.bigquery.commands._bigquery._render_list')\n  def test_dataset_line_list_substr_filter(self, mock_render_list, mock_datasets,\n                                           mock_default_context):\n    args = {'command': 'list', 'filter': 'ds1*', 'project': None}\n    datasets = ['ds1', 'ds2', 'ds11']\n    mock_datasets.return_value = iter(datasets)\n    bq.commands._bigquery._dataset_line(args)\n    mock_render_list.assert_called_with(['ds1', 'ds11'])\n\n  @mock.patch('google.datalab.Context.default')\n  @mock.patch('google.datalab.bigquery.Datasets')\n  @mock.patch('google.datalab.bigquery.commands._bigquery._render_list')\n  def test_dataset_line_list_exact_filter(self, mock_render_list, mock_datasets,\n                                          mock_default_context):\n    args = {'command': 'list', 'filter': 'ds1', 'project': None}\n    datasets = ['ds1', 'ds2', 'ds11']\n    mock_datasets.return_value = iter(datasets)\n    bq.commands._bigquery._dataset_line(args)\n    mock_render_list.assert_called_with(['ds1'])\n\n  @mock.patch('google.datalab.Context.default')\n  @mock.patch('google.datalab.bigquery.Datasets')\n  @mock.patch('google.datalab.bigquery.commands._bigquery._render_list')\n  def test_dataset_line_list_project(self, mock_render_list, mock_datasets, mock_default_context):\n    args = {'command': 'list', 'filter': None, 'project': 'testproject'}\n    mock_default_context.return_value = self._create_context()\n    bq.commands._bigquery._dataset_line(args)\n    self.assertEqual(mock_datasets.call_args[0][0].project_id, 'testproject')\n\n  @mock.patch('google.datalab.Context.default')\n  @mock.patch('google.datalab.bigquery.Dataset')\n  def test_dataset_line_create(self, mock_dataset, mock_default_context):\n    args = {'command': 'create', 'name': 'dataset-name', 'friendly': 'test-name'}\n    bq.commands._bigquery._dataset_line(args)\n    mock_dataset.assert_called_with('dataset-name')\n    mock_dataset.return_value.create.assert_called_with(friendly_name='test-name')\n\n    mock_dataset.side_effect = Exception('error')\n    with mock.patch('sys.stdout', new=six.StringIO()) as mocked_stdout:\n      bq.commands._bigquery._dataset_line(args)\n    self.assertIn('Failed to create dataset dataset-name', mocked_stdout.getvalue())\n\n  @mock.patch('google.datalab.Context.default')\n  @mock.patch('google.datalab.bigquery.Dataset')\n  def test_dataset_line_delete(self, mock_dataset, mock_default_context):\n    args = {'command': 'delete', 'name': 'dataset-name'}\n    bq.commands._bigquery._dataset_line(args)\n    mock_dataset.assert_called_with('dataset-name')\n    mock_dataset.return_value.delete.assert_called_with()\n\n    mock_dataset.side_effect = Exception('error')\n    with mock.patch('sys.stdout', new=six.StringIO()) as mocked_stdout:\n      bq.commands._bigquery._dataset_line(args)\n    self.assertIn('Failed to delete dataset dataset-name', mocked_stdout.getvalue())\n\n  @mock.patch('google.datalab.Context.default')\n  @mock.patch('google.datalab.bigquery.Datasets')\n  def test_table_cell_list(self, mock_datasets, mock_default_context):\n    args = {'command': 'list', 'filter': None, 'dataset': None, 'project': None}\n    tables = [bq.Table('project.test.' + name) for name in ['t1', 't2', 't3']]\n    ds1 = mock.MagicMock()\n    ds1.__iter__.return_value = iter([tables[0], tables[1]])\n    ds2 = mock.MagicMock()\n    ds2.__iter__.return_value = iter([tables[2]])\n    mock_datasets.return_value = iter([ds1, ds2])\n    self.assertEqual(\n        bq.commands._bigquery._table_cell(args, None),\n        '<ul><li>project.test.t1</li><li>project.test.t2</li><li>project.test.t3</li></ul>')\n\n  @mock.patch('google.datalab.Context.default')\n  @mock.patch('google.datalab.bigquery.Datasets')\n  def test_table_cell_list_asterisk(self, mock_datasets, mock_default_context):\n    args = {'command': 'list', 'filter': '*', 'dataset': None, 'project': None}\n    tables = [bq.Table('project.test.' + name) for name in ['t1', 't2', 't3']]\n    ds1 = mock.MagicMock()\n    ds1.__iter__.return_value = iter([tables[0], tables[1]])\n    ds2 = mock.MagicMock()\n    ds2.__iter__.return_value = iter([tables[2]])\n    mock_datasets.return_value = iter([ds1, ds2])\n    self.assertEqual(\n        bq.commands._bigquery._table_cell(args, None),\n        '<ul><li>project.test.t1</li><li>project.test.t2</li><li>project.test.t3</li></ul>')\n\n  @mock.patch('google.datalab.Context.default')\n  @mock.patch('google.datalab.bigquery.Datasets')\n  def test_table_cell_list_substr_filter(self, mock_datasets, mock_default_context):\n    args = {'command': 'list', 'filter': '*t1*', 'dataset': None, 'project': None}\n    tables = [bq.Table('project.test.' + name) for name in ['t1', 't2', 't11']]\n    ds1 = mock.MagicMock()\n    ds1.__iter__.return_value = iter([tables[0], tables[1]])\n    ds2 = mock.MagicMock()\n    ds2.__iter__.return_value = iter([tables[2]])\n    mock_datasets.return_value = iter([ds1, ds2])\n    self.assertEqual(\n        bq.commands._bigquery._table_cell(args, None),\n        '<ul><li>project.test.t1</li><li>project.test.t11</li></ul>')\n\n  @mock.patch('google.datalab.Context.default')\n  @mock.patch('google.datalab.bigquery.Datasets')\n  def test_table_cell_list_bad_filter(self, mock_datasets, mock_default_context):\n    args = {'command': 'list', 'filter': 't7', 'dataset': None, 'project': None}\n    tables = [bq.Table('project.test.' + name) for name in ['t1', 't2', 't11']]\n    ds1 = mock.MagicMock()\n    ds1.__iter__.return_value = iter([tables[0], tables[1]])\n    ds2 = mock.MagicMock()\n    ds2.__iter__.return_value = iter([tables[2]])\n    mock_datasets.return_value = iter([ds1, ds2])\n    self.assertEqual(\n        bq.commands._bigquery._table_cell(args, None),\n        '<pre>&lt;empty&gt;</pre>')\n\n  @mock.patch('google.datalab.Context.default')\n  @mock.patch('google.datalab.bigquery.Dataset')\n  def test_table_cell_list_dataset(self, mock_dataset, mock_default_context):\n    args = {'command': 'list', 'filter': '', 'dataset': 'test-dataset', 'project': None}\n    tables = [bq.Table('project.test.' + name) for name in ['t1', 't2']]\n    mock_dataset.return_value = iter(tables)\n    self.assertEqual(\n        bq.commands._bigquery._table_cell(args, None),\n        '<ul><li>project.test.t1</li><li>project.test.t2</li></ul>')\n\n  @mock.patch('google.datalab.Context.default')\n  @mock.patch('google.datalab.bigquery.Datasets')\n  def test_table_cell_list_project(self, mock_datasets, mock_default_context):\n    args = {'command': 'list', 'filter': '', 'dataset': None, 'project': 'test-project'}\n    tables = [bq.Table('project.test.' + name) for name in ['t1', 't2', 't3']]\n    ds1 = mock.MagicMock()\n    ds1.__iter__.return_value = iter([tables[0], tables[1]])\n    ds2 = mock.MagicMock()\n    ds2.__iter__.return_value = iter([tables[2]])\n    mock_datasets.return_value = iter([ds1, ds2])\n    self.assertEqual(\n        bq.commands._bigquery._table_cell(args, None),\n        '<ul><li>project.test.t1</li><li>project.test.t2</li><li>project.test.t3</li></ul>')\n\n  @mock.patch('google.datalab.Context.default')\n  @mock.patch('google.datalab.bigquery.Dataset')\n  def test_table_cell_list_dataset_project(self, mock_dataset, mock_default_context):\n    args = {'command': 'list', 'filter': '', 'dataset': 'test-dataset', 'project': 'test-project'}\n    tables = [bq.Table('project.test.' + name) for name in ['t1', 't2']]\n    mock_dataset.return_value = iter(tables)\n    self.assertEqual(\n        bq.commands._bigquery._table_cell(args, None),\n        '<ul><li>project.test.t1</li><li>project.test.t2</li></ul>')\n    call_args = mock_dataset.call_args[0]\n    self.assertEqual(call_args[0], 'test-dataset')\n    self.assertEqual(call_args[1].project_id, 'test-project')\n\n  @mock.patch('google.datalab.Context.default')\n  @mock.patch('google.datalab.bigquery.Table')\n  def test_table_cell_create_bad_params(self, mock_table, mock_default_context):\n    args = {'command': 'create', 'name': 'test-table', 'overwrite': None}\n    with mock.patch('sys.stdout', new=six.StringIO()) as mocked_stdout:\n      bq.commands._bigquery._table_cell(args, None)\n    self.assertIn('Failed to create test-table: no schema', mocked_stdout.getvalue())\n\n    mock_table.side_effect = Exception\n    with mock.patch('sys.stdout', new=six.StringIO()) as mocked_stdout:\n      bq.commands._bigquery._table_cell(args, json.dumps({}))\n    self.assertIn('\\'schema\\' is a required property', mocked_stdout.getvalue())\n\n  @mock.patch('google.datalab.Context.default')\n  @mock.patch('google.datalab.bigquery.Table')\n  def test_table_cell_create(self, mock_table, mock_default_context):\n    args = {'command': 'create', 'name': 'test-table', 'overwrite': None}\n    cell_body = {\n      'schema': [\n        {'name': 'col1', 'type': 'int64', 'mode': 'NULLABLE', 'description': 'description1'},\n        {'name': 'col1', 'type': 'STRING', 'mode': 'required', 'description': 'description1'}\n      ]\n    }\n    bq.commands._bigquery._table_cell(args, json.dumps(cell_body))\n    call_kwargs = mock_table.return_value.create.call_args[1]\n    self.assertEqual(None, call_kwargs['overwrite'])\n    self.assertEqual(bq.Schema(cell_body['schema']), call_kwargs['schema'])\n\n  @mock.patch('google.datalab.Context.default')\n  @mock.patch('google.datalab.bigquery.commands._bigquery._get_table')\n  def test_table_cell_describe(self, mock_get_table, mock_default_context):\n    args = {'command': 'describe', 'name': 'test-table', 'overwrite': None}\n    mock_get_table.return_value = None\n    with self.assertRaisesRegexp(Exception, 'Could not find table'):\n      bq.commands._bigquery._table_cell(args, None)\n\n    mock_get_table.return_value = bq.Table('project.test.table')\n    schema = bq.Schema([{\n      'name': 'col1',\n      'type': 'string'\n    }])\n    mock_get_table.return_value._schema = schema\n    rendered = bq.commands._bigquery._table_cell(args, None)\n    expected_html1 = 'bq.renderSchema(dom, [{\"type\": \"string\", \"name\": \"col1\"}]);'\n    expected_html2 = 'bq.renderSchema(dom, [{\"name\": \"col1\", \"type\": \"string\"}]);'\n    self.assertTrue(expected_html1 in rendered or expected_html2 in rendered)\n\n  @mock.patch('google.datalab.Context.default')\n  @mock.patch('google.datalab.bigquery.Table')\n  def test_table_cell_delete(self, mock_table, mock_default_context):\n    args = {'command': 'delete', 'name': 'test-table'}\n    mock_table.return_value.delete.side_effect = Exception\n    with mock.patch('sys.stdout', new=six.StringIO()) as mocked_stdout:\n      bq.commands._bigquery._table_cell(args, None)\n    self.assertIn('Failed to delete table test-table', mocked_stdout.getvalue())\n\n  @mock.patch('google.datalab.Context.default')\n  @mock.patch('google.datalab.bigquery.commands._bigquery._get_table')\n  def test_table_cell_view(self, mock_get_table, mock_default_context):\n    args = {'command': 'view', 'name': 'test-table'}\n    table = bq.Table('project.test.table')\n    mock_get_table.return_value = None\n    with self.assertRaisesRegexp(Exception, 'Could not find table test-table'):\n      bq.commands._bigquery._table_cell(args, None)\n\n    mock_get_table.return_value = table\n    self.assertEqual(table, bq.commands._bigquery._table_cell(args, None))\n\n  @mock.patch('google.datalab.Context.default')\n  @mock.patch('google.datalab.bigquery.Query.execute')\n  @mock.patch('google.datalab.utils.commands.get_notebook_item')\n  def test_extract_cell_query(self, mock_get_notebook_item, mock_query_execute,\n                              mock_default_context):\n    args = {'table': None, 'view': None, 'query': None, 'path': None, 'format': None,\n            'delimiter': None, 'header': None, 'compress': None, 'nocache': None}\n    with self.assertRaisesRegexp(Exception, 'A query, table, or view is needed'):\n      bq.commands._bigquery._extract_cell(args, None)\n\n    args['query'] = 'test-query'\n    mock_get_notebook_item.return_value = None\n    with self.assertRaisesRegexp(Exception, 'Could not find query test-query'):\n      bq.commands._bigquery._extract_cell(args, None)\n\n    mock_get_notebook_item.return_value = bq.Query('sql')\n    mock_query_execute.return_value.failed = True\n    mock_query_execute.return_value.fatal_error = 'test-error'\n    with self.assertRaisesRegexp(Exception, 'Extract failed: test-error'):\n      bq.commands._bigquery._extract_cell(args, None)\n\n    mock_query_execute.return_value.failed = False\n    mock_query_execute.return_value.errors = 'test-errors'\n    with self.assertRaisesRegexp(Exception, 'Extract completed with errors: test-errors'):\n      bq.commands._bigquery._extract_cell(args, None)\n\n    mock_query_execute.return_value.errors = None\n    mock_query_execute.return_value.result = lambda: 'results'\n    self.assertEqual(bq.commands._bigquery._extract_cell(args, None),\n                     'results')\n\n    cell_body = {\n      'parameters': [\n          {'name': 'arg1', 'type': 'INT64', 'value': 5}\n      ]\n    }\n    bq.commands._bigquery._extract_cell(args, json.dumps(cell_body))\n    mock_get_notebook_item.assert_called_with('test-query')\n    call_args = mock_query_execute.call_args[1]\n\n    found_item = False\n    for item in call_args['query_params']:\n      if item['name'] == 'arg1':\n        found_item = True\n        self.assertDictEqual(item, {\n          'parameterValue': {'value': 5},\n          'name': 'arg1',\n          'parameterType': {'type': 'INT64'}\n        })\n    self.assertTrue(found_item)\n\n  @mock.patch('google.datalab.bigquery.Table.extract')\n  @mock.patch('google.datalab.bigquery.commands._bigquery._get_table')\n  @mock.patch('google.datalab.utils.commands.get_notebook_item')\n  def test_extract_cell_table(self, mock_get_notebook_item, mock_get_table, mock_table_extract):\n    args = {'table': 'test-table', 'path': 'test-path', 'format': 'json', 'delimiter': None,\n            'header': None, 'compress': None, 'nocache': None}\n    mock_get_table.return_value = None\n    with self.assertRaisesRegexp(Exception, 'Could not find table test-table'):\n      bq.commands._bigquery._extract_cell(args, None)\n\n    mock_get_table.return_value = bq.Table('project.test.table', self._create_context())\n    mock_table_extract.return_value.result = lambda: 'test-results'\n    mock_table_extract.return_value.failed = False\n    mock_table_extract.return_value.errors = None\n    self.assertEqual(bq.commands._bigquery._extract_cell(args, None),\n                     'test-results')\n    mock_table_extract.assert_called_with('test-path', format='json', csv_delimiter=None,\n                                          csv_header=None, compress=None)\n\n  @mock.patch('google.datalab.Context.default')\n  @mock.patch('google.datalab.bigquery.Query.execute')\n  @mock.patch('google.datalab.utils.commands.get_notebook_item')\n  def test_extract_cell_view(self, mock_get_notebook_item, mock_query_execute,\n                             mock_default_context):\n    args = {'view': 'test-view', 'table': None, 'query': None, 'path': 'test-path',\n            'format': None, 'delimiter': None, 'header': None, 'compress': None, 'nocache': None}\n    mock_get_notebook_item.return_value = None\n    with self.assertRaisesRegexp(Exception, 'Could not find view test-view'):\n      bq.commands._bigquery._extract_cell(args, None)\n\n    mock_get_notebook_item.return_value = bq.View('project.test.view', self._create_context())\n    mock_query_execute.return_value.result = lambda: 'test-results'\n    mock_query_execute.return_value.failed = False\n    mock_query_execute.return_value.errors = None\n    self.assertEqual(bq.commands._bigquery._extract_cell(args, None),\n                     'test-results')\n    mock_get_notebook_item.assert_called_with('test-view')\n\n  @mock.patch('google.datalab.Context.default')\n  @mock.patch('google.datalab.bigquery.Table.create')\n  @mock.patch('google.datalab.bigquery.Table.exists')\n  @mock.patch('google.datalab.bigquery.Table.load')\n  @mock.patch('google.datalab.bigquery.commands._bigquery._get_table')\n  def test_load_cell(self, mock_get_table, mock_table_load, mock_table_exists,\n                     mock_table_create, mock_default_context):\n\n    args = {'table': 'project.test.table', 'mode': 'create', 'path': 'test/path_%(_ds)s',\n            'skip': None, 'csv': None, 'delimiter': None, 'format': 'csv', 'strict': None,\n            'quote': None}\n    context = self._create_context()\n    mock_get_table.return_value = bq.Table('project.test.table')\n    job = bq._query_job.QueryJob('test_id', 'project.test.table', 'test_sql', context)\n\n    mock_table_exists.return_value = True\n    with self.assertRaisesRegexp(Exception, 'already exists; use \"append\" or \"overwrite\" as mode.'):\n      bq.commands._bigquery._load_cell(args, None)\n\n    mock_table_exists.return_value = False\n    with self.assertRaisesRegexp(Exception, 'Table does not exist, and no schema specified'):\n      bq.commands._bigquery._load_cell(args, None)\n\n    cell_body = {\n      'schema': [\n        {'name': 'col1', 'type': 'int64', 'mode': 'NULLABLE', 'description': 'description1'},\n        {'name': 'col1', 'type': 'STRING', 'mode': 'required', 'description': 'description1'}\n      ],\n      'parameters': [\n        {'name': 'custom', 'type': 'FLOAT', 'value': 4.23}\n      ]\n    }\n\n    mock_table_load.return_value = job\n    job._is_complete = True\n    job._fatal_error = 'fatal error'\n    with self.assertRaisesRegexp(Exception, 'Load failed: fatal error'):\n      bq.commands._bigquery._load_cell(args, json.dumps(cell_body))\n\n    job._fatal_error = None\n    job._errors = 'error'\n    with self.assertRaisesRegexp(Exception, 'Load completed with errors: error'):\n      bq.commands._bigquery._load_cell(args, json.dumps(cell_body))\n\n    job._errors = None\n    bq.commands._bigquery._load_cell(args, json.dumps(cell_body))\n    today = datetime.now().date().isoformat()\n    mock_table_load.assert_called_with('test/path_{0}'.format(today), mode='create',\n                                       source_format='csv',\n                                       csv_options=mock.ANY, ignore_unknown_values=True)\n\n    mock_get_table.return_value = None\n    mock_table_exists.return_value = True\n    args['mode'] = 'append'\n    args['format'] = 'csv'\n\n    bq.commands._bigquery._load_cell(args, None)\n    mock_table_load.assert_called_with('test/path_{0}'.format(today), mode='append',\n                                       source_format='csv', csv_options=mock.ANY,\n                                       ignore_unknown_values=True)\n\n  @mock.patch('google.datalab.Context.default')\n  @mock.patch('google.datalab.storage.Bucket')\n  @mock.patch('google.datalab.utils.commands.get_notebook_item')\n  @mock.patch('google.datalab.utils.commands.notebook_environment')\n  def test_pipeline_cell(self, mock_env, mock_get_notebook_item, mock_bucket_class,\n                         mock_default_context):\n    context = TestCases._create_context()\n    mock_default_context.return_value = context\n    mock_bucket_class.return_value = mock.Mock()\n    mock_get_notebook_item.return_value = bq.Query(\n        'SELECT * FROM publicdata.samples.wikipedia LIMIT 5')\n    small_cell_body = \"\"\"\n            emails: foo1@test.com\n            schedule:\n                start: 2009-05-05T22:28:15Z\n                end: 2009-05-06T22:28:15Z\n                interval: '@hourly'\n            input:\n                table: project.test.table\n            transformation:\n                query: foo_query\n            output:\n                table: project.test.table\n       \"\"\"\n    args = {'name': 'bq_pipeline_test', 'gcs_dag_bucket': 'foo_bucket', 'gcs_dag_folder': 'dags'}\n    actual = bq.commands._bigquery._pipeline_cell(args, small_cell_body)\n    self.assertIn(\"successfully deployed\", actual)\n    self.assertNotIn(\"'email': ['foo1@test.com']\", actual)\n\n    args['debug'] = True\n    actual = bq.commands._bigquery._pipeline_cell(args, small_cell_body)\n    self.assertIn(\"successfully deployed\", actual)\n    self.assertIn(\"'email': ['foo1@test.com']\", actual)\n\n  @mock.patch('google.datalab.utils.commands._html.Html.next_id')\n  @mock.patch('google.datalab.utils.commands._html.HtmlBuilder.render_chart_data')\n  @mock.patch('google.datalab.bigquery._api.Api.tables_get')\n  @mock.patch('google.datalab.utils.commands.get_data')\n  @mock.patch('google.datalab.utils.commands.get_field_list')\n  @mock.patch('google.datalab.bigquery.Table.exists')\n  def test_table_viewer(self, mock_table_exists, mock_get_field_list, mock_get_data,\n                        mock_tables_get, mock_render_chart_data, mock_next_id):\n    test_table = bq.Table('testproject.test.table', self._create_context())\n\n    mock_table_exists.return_value = False\n    with self.assertRaisesRegexp(Exception, 'does not exist'):\n      bq.commands._bigquery._table_viewer(test_table)\n\n    mock_table_exists.return_value = True\n    mock_get_field_list.return_value = ['col1']\n    mock_get_data.return_value = ({'cols': ['col1'], 'rows': ['val1']}, 1)\n    mock_render_chart_data.return_value = 'test_chart_data'\n    mock_next_id.return_value = 'test_id'\n    viewer = bq.commands._bigquery._table_viewer(test_table)\n\n    mock_table_exists.assert_called()\n    mock_get_field_list.assert_called()\n    mock_render_chart_data.assert_called()\n\n    expected_html_header = '''\n    <div class=\"bqtv\" id=\"test_id\">test_chart_data</div>\n    <br />(testproject.test.table)<br />\n    '''\n    self.assertIn(expected_html_header, viewer)\n\n  @mock.patch('google.datalab.bigquery._query_stats.QueryStats._size_formatter')\n  @mock.patch('google.datalab.bigquery.Table.job')\n  @mock.patch('google.datalab.utils.commands._html.Html.next_id')\n  @mock.patch('google.datalab.utils.commands._html.HtmlBuilder.render_chart_data')\n  @mock.patch('google.datalab.bigquery._api.Api.tables_get')\n  @mock.patch('google.datalab.utils.commands.get_data')\n  @mock.patch('google.datalab.utils.commands.get_field_list')\n  @mock.patch('google.datalab.bigquery.Table.exists')\n  def test_query_results_table_viewer(self, mock_table_exists, mock_get_field_list, mock_get_data,\n                                      mock_tables_get, mock_render_chart_data, mock_next_id,\n                                      mock_table_job, mock_size_formatter):\n    context = self._create_context()\n    table_name = 'testproject.test.table'\n    job = bq._query_job.QueryJob('test_id', table_name, 'test_sql', context)\n    job._start_time, job._end_time = datetime(2017, 1, 1, 1, 1), datetime(2017, 1, 1, 1, 2)\n    test_table = bq.QueryResultsTable(table_name, context, job)\n\n    mock_table_exists.return_value = True\n    mock_get_field_list.return_value = ['col1']\n    mock_get_data.return_value = ({'cols': ['col1'], 'rows': ['val1']}, 1)\n    mock_next_id.return_value = 'test_id'\n    mock_size_formatter.return_value = '10MB'\n    mock_render_chart_data.return_value = 'test_chart_data'\n\n    viewer = bq.commands._bigquery._table_viewer(test_table)\n\n    mock_table_exists.assert_called()\n    mock_get_field_list.assert_called()\n    mock_render_chart_data.assert_called()\n\n    expected_html_header = '''\n    <div class=\"bqtv\" id=\"test_id\">test_chart_data</div>\n    <br />(time: 60.0s, 10MB processed, job: test_id)<br />\n    '''\n    self.assertIn(expected_html_header, viewer)\n\n    job._cache_hit = True\n\n    viewer = bq.commands._bigquery._table_viewer(test_table)\n\n    expected_html_header = '''\n    <div class=\"bqtv\" id=\"test_id\">test_chart_data</div>\n    <br />(time: 60.0s, cached, job: test_id)<br />\n    '''\n    self.assertIn(expected_html_header, viewer)\n\n    mock_get_data.return_value = ({'rows': []}, -1)\n    viewer = bq.commands._bigquery._table_viewer(test_table)\n    expected_html_header = 'pageSize: 25,'\n    self.assertIn(expected_html_header, viewer)\n\n    mock_get_data.return_value = ({'rows': ['val'] * 5}, -1)\n    viewer = bq.commands._bigquery._table_viewer(test_table, rows_per_page=10)\n    expected_html_header = 'pageSize: 10,'\n    self.assertIn(expected_html_header, viewer)\n    expected_html_footer = '''\n            {source_index: 0, fields: 'col1'},\n            0,\n            5);\n    '''\n    self.assertIn(expected_html_footer, viewer)\n\n  @mock.patch('google.datalab.utils._utils.get_credentials')\n  @mock.patch('google.datalab.utils._utils.get_default_project_id')\n  @mock.patch('google.datalab.utils._utils.save_project_id')\n  def test_args_to_context(self, mock_save_project, mock_get_default_project, mock_get_credentials):\n    mock_get_credentials.return_value = 'test_creds'\n    mock_get_default_project.return_value = 'testproject'\n\n    args = {'billing': 'billing_value'}\n    default_context = google.datalab.Context.default()\n    c = google.datalab.utils._utils._construct_context_for_args(args)\n\n    # make sure it's not the same object\n    self.assertNotEqual(c, default_context)\n    self.assertEqual(c.project_id, default_context.project_id)\n    self.assertEqual(c.credentials, default_context.credentials)\n\n    # make sure the right config object was passed\n    self.assertEqual(c.config, {'bigquery_billing_tier': 'billing_value'})\n\n    default_context.config['test_prop'] = 'test_val'\n    c = google.datalab.utils._utils._construct_context_for_args(args)\n    # make sure other properties in default context were copied\n    self.assertEqual(c.config, {'bigquery_billing_tier': 'billing_value', 'test_prop': 'test_val'})\n\n  @mock.patch('google.datalab.utils.commands.get_notebook_item')\n  def test_get_query_argument(self, mock_get_notebook_item):\n    args = {}\n    cell = None\n    env = {}\n    # an Exception should be raised if no query is specified by name or body\n    with self.assertRaises(Exception):\n      bq.commands._bigquery._get_query_argument(args, cell, env)\n\n    # specify query name, no cell body\n    args = {'query': 'test_query'}\n    mock_get_notebook_item.return_value = bq.Query('test_sql')\n    q = bq.commands._bigquery._get_query_argument(args, cell, env)\n    self.assertEqual(q.sql, 'test_sql')\n\n    # specify query in cell body, no name\n    args = {}\n    cell = 'test_sql2'\n    q = bq.commands._bigquery._get_query_argument(args, cell, env)\n    self.assertEqual(q.sql, 'test_sql2')\n\n    # specify query by bad name\n    args = {'query': 'test_query'}\n    mock_get_notebook_item.return_value = None\n    with self.assertRaises(Exception):\n      bq.commands._bigquery._get_query_argument(args, cell, env)\n\n  def test_get_query_parameters(self):\n    args = {'query': None}\n    cell_body = ''\n    now = datetime.now()\n    with self.assertRaises(Exception):\n      bq.commands._bigquery.get_query_parameters(args, json.dumps(cell_body))\n\n    args['query'] = 'test_sql'\n    params = bq.commands._bigquery.get_query_parameters(args, json.dumps(cell_body), date_time=now)\n\n    # We push the params into a dict so that it's easier to compare\n    params_dict = {\n      item['name']: {\n        'type': item['parameterType']['type'],\n        'value': item['parameterValue']['value']\n      } for item in params\n    }\n\n    today = now.date()\n    default_query_parameters = {\n      # the datetime formatted as YYYY-MM-DD\n      '_ds': {'type': 'STRING', 'value': today.isoformat()},\n      # the full ISO-formatted timestamp YYYY-MM-DDTHH:MM:SS.mmmmmm\n      '_ts': {'type': 'STRING', 'value': now.isoformat()},\n      # the datetime formatted as YYYYMMDD (i.e. YYYY-MM-DD with 'no dashes')\n      '_ds_nodash': {'type': 'STRING', 'value': today.strftime('%Y%m%d')},\n      # the timestamp formatted as YYYYMMDDTHHMMSSmmmmmm (i.e full ISO-formatted timestamp\n      # YYYY-MM-DDTHH:MM:SS.mmmmmm with no dashes or colons).\n      '_ts_nodash': {'type': 'STRING', 'value': now.strftime('%Y%m%d%H%M%S%f')},\n      '_ts_year': {'type': 'STRING', 'value': today.strftime('%Y')},\n      '_ts_month': {'type': 'STRING', 'value': today.strftime('%m')},\n      '_ts_day': {'type': 'STRING', 'value': today.strftime('%d')},\n      '_ts_hour': {'type': 'STRING', 'value': now.strftime('%H')},\n      '_ts_minute': {'type': 'STRING', 'value': now.strftime('%M')},\n      '_ts_second': {'type': 'STRING', 'value': now.strftime('%S')},\n    }\n    self.assertDictEqual(params_dict, default_query_parameters)\n\n    cell_body = {\n      'parameters': [\n          {'name': 'arg1', 'type': 'INT64', 'value': 5},\n          {'name': 'arg2', 'type': 'string', 'value': 'val2'},\n          {'name': 'arg3', 'type': 'date', 'value': 'val3'}\n      ]\n    }\n    params = bq.commands._bigquery.get_query_parameters(args, json.dumps(cell_body), date_time=now)\n    # We push the params into a dict so that it's easier to compare\n    params_dict = {\n      item['name']: {\n        'type': item['parameterType']['type'],\n        'value': item['parameterValue']['value']\n      } for item in params\n    }\n    cell_body_params_dict = {\n      item['name']: {\n        'type': item['type'],\n        'value': item['value']\n      } for item in cell_body['parameters']\n    }\n    default_query_parameters.update(cell_body_params_dict)\n    self.assertDictEqual(params_dict, default_query_parameters)\n"
  },
  {
    "path": "tests/kernel/chart_data_tests.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nimport json\nimport mock\nimport unittest\n\n# import Python so we can mock the parts we need to here.\nimport IPython.core.display\nimport IPython.core.magic\n\n\ndef noop_decorator(func):\n  return func\n\n\nIPython.core.magic.register_line_cell_magic = noop_decorator\nIPython.core.magic.register_line_magic = noop_decorator\nIPython.core.magic.register_cell_magic = noop_decorator\nIPython.core.display.HTML = lambda x: x\nIPython.core.display.JSON = lambda x: x\n\n\nimport google.datalab.utils.commands  # noqa\n\n\nclass TestCases(unittest.TestCase):\n\n  @mock.patch('google.datalab.utils.get_item')\n  def test_get_chart_data(self, mock_get_item):\n    IPython.get_ipython().user_ns = {}\n    t = [\n        {'country': 'US', 'quantity': 100},\n        {'country': 'ZA', 'quantity': 50},\n        {'country': 'UK', 'quantity': 75},\n        {'country': 'AU', 'quantity': 25}\n    ]\n    mock_get_item.return_value = t\n    ds = google.datalab.utils.commands.get_data_source_index('t')\n    data = google.datalab.utils.commands._chart_data._get_chart_data('', json.dumps({\n      'source_index': ds,\n      'fields': 'country',\n      'first': 1,\n      'count': 1\n    }))\n    self.assertEquals({\"data\": {\"rows\": [{\"c\": [{\"v\": \"ZA\"}]}],\n                                \"cols\": [{\"type\": \"string\", \"id\": \"country\", \"label\": \"country\"}]},\n                       \"refresh_interval\": 0, \"options\": {}}, data)\n\n    data = google.datalab.utils.commands._chart_data._get_chart_data('', json.dumps({\n      'source_index': ds,\n      'fields': 'country',\n      'first': 6,\n      'count': 1\n    }))\n    self.assertEquals({\"data\": {\"rows\": [], \"cols\": [{\"type\": \"string\", \"id\": \"country\",\n                                                      \"label\": \"country\"}]},\n                       \"refresh_interval\": 0, \"options\": {}}, data)\n\n    data = google.datalab.utils.commands._chart_data._get_chart_data('', json.dumps({\n      'source_index': ds,\n      'fields': 'country',\n      'first': 2,\n      'count': 0\n    }))\n    self.assertEquals({\"data\": {\"rows\": [], \"cols\": [{\"type\": \"string\", \"id\": \"country\",\n                                                      \"label\": \"country\"}]},\n                       \"refresh_interval\": 0, \"options\": {}}, data)\n"
  },
  {
    "path": "tests/kernel/chart_tests.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nimport unittest\n\n# import Python so we can mock the parts we need to here.\nimport IPython.core.display\nimport IPython.core.magic\n\n\ndef noop_decorator(func):\n  return func\n\n\nIPython.core.magic.register_line_cell_magic = noop_decorator\nIPython.core.magic.register_line_magic = noop_decorator\nIPython.core.magic.register_cell_magic = noop_decorator\nIPython.core.display.HTML = lambda x: x\nIPython.core.display.JSON = lambda x: x\n\n\nimport google.datalab.utils.commands  # noqa\n\n\nclass TestCases(unittest.TestCase):\n\n  def test_chart_cell(self):\n    t = [{'country': 'US', 'quantity': 100}, {'country': 'ZA', 'quantity': 50}]\n    IPython.get_ipython().user_ns = {}\n    chart = google.datalab.utils.commands._chart._chart_cell({'chart': 'geo', 'data': t,\n                                                              'fields': None}, '')\n    self.assertTrue(chart.find('charts.render(') > 0)\n    self.assertTrue(chart.find('\\'geo\\'') > 0)\n    self.assertTrue(chart.find('\"fields\": \"*\"') > 0)\n    self.assertTrue(chart.find('{\"c\": [{\"v\": \"US\"}, {\"v\": 100}]}') > 0 or\n                    chart.find('{\"c\": [{\"v\": 100}, {\"v\": \"US\"}]}') > 0)\n    self.assertTrue(chart.find('{\"c\": [{\"v\": \"ZA\"}, {\"v\": 50}]}') > 0 or\n                    chart.find('{\"c\": [{\"v\": 50}, {\"v\": \"ZA\"}]}') > 0)\n\n  def test_chart_magic(self):\n    # TODO(gram): complete this test\n    pass\n"
  },
  {
    "path": "tests/kernel/html_tests.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nimport mock\nimport unittest\n\n# import Python so we can mock the parts we need to here.\nimport IPython\nimport IPython.core.magic\n\nimport google.datalab\n\n\ndef noop_decorator(func):\n  return func\n\n\nIPython.core.magic.register_line_cell_magic = noop_decorator\nIPython.core.magic.register_line_magic = noop_decorator\nIPython.core.magic.register_cell_magic = noop_decorator\nIPython.get_ipython = mock.Mock()\n\n\nclass TestCases(unittest.TestCase):\n\n  def test_render_table(self):\n    builder = google.datalab.utils.commands.HtmlBuilder()\n    builder._render_objects({\n        'cols': [\n         {'label': 'col1'},\n         {'label': 'col2'},\n        ],\n        'rows': [\n          {'c': [\n            {'v': 'val1'},\n            {'v': 'val2'}\n          ]},\n          {'c': [\n            {'v': 'val3'},\n            {'v': 'val4'}\n          ]}\n        ]\n      }, ['col1', 'col2'], 'chartdata')\n    expected_html = ''.join('''\n    <table>\n      <tr>\n        <th>col1</th>\n        <th>col2</th>\n      </tr>\n      <tr>\n        <td>val1</td>\n        <td>val2</td>\n      </tr>\n      <tr>\n        <td>val3</td>\n        <td>val4</td>\n      </tr>\n    </table>\n'''.split())\n    self.assertEqual(builder._to_html(), expected_html)\n\n  def test_render_text(self):\n    # TODO(gram): complete this test\n    pass\n"
  },
  {
    "path": "tests/kernel/pipeline_tests.py",
    "content": "# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\n\nimport unittest\n\n# import Python so we can mock the parts we need to here.\nimport IPython\nimport IPython.core.magic\nimport mock\n\nimport google.auth\nimport google.datalab.contrib.pipeline.commands._pipeline\n\n\ndef noop_decorator(func):\n  return func\n\n\nIPython.core.magic.register_line_cell_magic = noop_decorator\nIPython.core.magic.register_line_magic = noop_decorator\nIPython.core.magic.register_cell_magic = noop_decorator\nIPython.get_ipython = mock.Mock()\n\n\nclass TestCases(unittest.TestCase):\n\n  # test pipeline creation\n  sample_cell_body = \"\"\"\nschedule:\n  start: 2009-05-05T22:28:15Z\n  end: 2009-05-06T22:28:15Z\n  interval: '@hourly'\ntasks:\n  print_pdt_date:\n    type: bash\n    bash_command: date\n  print_utc_date:\n    type: bash\n    bash_command: date -u\n    up_stream:\n      - print_pdt_date\n\"\"\"\n\n  @staticmethod\n  def _create_context():\n    project_id = 'test'\n    creds = mock.Mock(spec=google.auth.credentials.Credentials)\n    return google.datalab.Context(project_id, creds)\n\n  @mock.patch('google.datalab.utils.commands.notebook_environment')\n  @mock.patch('google.datalab.Context.default')\n  def test_create_cell_no_name(self, mock_default_context, mock_notebook_environment):\n    env = {}\n    mock_default_context.return_value = TestCases._create_context()\n    mock_notebook_environment.return_value = env\n    IPython.get_ipython().user_ns = env\n\n    # test pipeline creation\n    p_body = 'foo'\n\n    # no pipeline name specified. should execute\n    with self.assertRaises(Exception):\n      google.datalab.contrib.pipeline.commands._pipeline._create_cell({'name': None},\n                                                                      p_body)\n\n  @mock.patch('google.datalab.utils.commands.notebook_environment')\n  @mock.patch('google.datalab.Context.default')\n  def test_create_cell_debug(self, mock_default_context, mock_notebook_environment):\n    env = {}\n    mock_default_context.return_value = TestCases._create_context()\n    mock_notebook_environment.return_value = env\n    IPython.get_ipython().user_ns = env\n\n    # cell output is empty when debug is True\n    output = google.datalab.contrib.pipeline.commands._pipeline._create_cell(\n        {'name': 'foo_pipeline', 'debug': True}, self.sample_cell_body)\n    self.assertTrue(len(output) > 0)\n\n    output = google.datalab.contrib.pipeline.commands._pipeline._create_cell(\n        {'name': 'foo_pipeline', 'debug': False}, self.sample_cell_body)\n    self.assertTrue(output is None)\n\n    output = google.datalab.contrib.pipeline.commands._pipeline._create_cell(\n        {'name': 'foo_pipeline'}, self.sample_cell_body)\n    self.assertTrue(output is None)\n\n  @mock.patch('google.datalab.utils.commands.notebook_environment')\n  @mock.patch('google.datalab.Context.default')\n  def test_create_cell_golden(self, mock_default_context, mock_notebook_environment):\n    # This import is required by the test to run successfully because we dynamically check the\n    # imports to instantiate the class-type.\n    from airflow.operators.bash_operator import BashOperator  # noqa\n\n    mock_default_context.return_value = TestCases._create_context()\n    env = {}\n    env['foo_query'] = google.datalab.bigquery.Query(\n        'SELECT * FROM publicdata.samples.wikipedia LIMIT 5')\n    mock_notebook_environment.return_value = env\n    # TODO(rajivpb): Possibly not necessary\n    IPython.get_ipython().user_ns = env\n\n    # test pipeline creation\n    p_body = \"\"\"\nemails: foo1@test.com,foo2@test.com\nschedule:\n  start: 2009-05-05T22:28:15Z\n  end: 2009-05-06T22:28:15Z\n  interval: '@hourly'\ntasks:\n  foo_task_1:\n    type: BigQuery\n    query: $foo_query\n  foo_task_2:\n    type: Bash\n    bash_command: date\n  foo_task_3:\n    type: Bash\n    bash_command: date -u\n    up_stream:\n      - print_pdt_date\n\"\"\"\n\n    spec = google.datalab.contrib.pipeline.commands._pipeline._create_cell(\n      {'name': 'p1', 'debug': True}, p_body)\n    self.assertEqual(spec, \"\"\"\nimport datetime\nfrom airflow import DAG\nfrom airflow.operators.bash_operator import BashOperator\nfrom airflow.contrib.operators.bigquery_operator import BigQueryOperator\nfrom airflow.contrib.operators.bigquery_table_delete_operator import BigQueryTableDeleteOperator\nfrom airflow.contrib.operators.bigquery_to_bigquery import BigQueryToBigQueryOperator\nfrom airflow.contrib.operators.bigquery_to_gcs import BigQueryToCloudStorageOperator\nfrom airflow.contrib.operators.gcs_to_bq import GoogleCloudStorageToBigQueryOperator\nfrom google.datalab.contrib.bigquery.operators._bq_load_operator import LoadOperator\nfrom google.datalab.contrib.bigquery.operators._bq_execute_operator import ExecuteOperator\nfrom google.datalab.contrib.bigquery.operators._bq_extract_operator import ExtractOperator\nfrom datetime import timedelta\n\ndefault_args = {\n    'owner': 'Google Cloud Datalab',\n    'email': ['foo1@test.com', 'foo2@test.com'],\n    'start_date': datetime.datetime.strptime('2009-05-05T22:28:15', '%Y-%m-%dT%H:%M:%S'),\n    'end_date': datetime.datetime.strptime('2009-05-06T22:28:15', '%Y-%m-%dT%H:%M:%S'),\n}\n\ndag = DAG(dag_id='p1', schedule_interval='@hourly', catchup=False, default_args=default_args)\n\nfoo_task_1 = BigQueryOperator(task_id='foo_task_1_id', bql=\\\"\\\"\\\"SELECT * FROM publicdata.samples.wikipedia LIMIT 5\\\"\\\"\\\", use_legacy_sql=False, dag=dag)\nfoo_task_2 = BashOperator(task_id='foo_task_2_id', bash_command=\\\"\\\"\\\"date\\\"\\\"\\\", dag=dag)\nfoo_task_3 = BashOperator(task_id='foo_task_3_id', bash_command=\\\"\\\"\\\"date -u\\\"\\\"\\\", dag=dag)\nfoo_task_3.set_upstream(print_pdt_date)\n\"\"\"  # noqa\n                     )\n"
  },
  {
    "path": "tests/kernel/storage_tests.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nimport mock\nimport unittest\n\n# import Python so we can mock the parts we need to here.\nimport IPython\nimport IPython.core.magic\n\nimport google.auth\n\n\ndef noop_decorator(func):\n  return func\n\n\nIPython.core.magic.register_line_cell_magic = noop_decorator\nIPython.core.magic.register_line_magic = noop_decorator\nIPython.core.magic.register_cell_magic = noop_decorator\nIPython.get_ipython = mock.Mock()\n\n\nimport google.datalab  # noqa\nimport google.datalab.storage  # noqa\nimport google.datalab.storage.commands  # noqa\n\n\nclass TestCases(unittest.TestCase):\n\n  @mock.patch('google.datalab.storage._object.Object.exists', autospec=True)\n  @mock.patch('google.datalab.storage._bucket.Bucket.objects', autospec=True)\n  @mock.patch('google.datalab.storage._api.Api.objects_get', autospec=True)\n  @mock.patch('google.datalab.Context.default')\n  def test_expand_list(self, mock_context_default, mock_api_objects_get, mock_bucket_objects,\n                       mock_object_exists):\n    context = TestCases._create_context()\n    mock_context_default.return_value = context\n\n    # Mock API for testing for object existence. Fail if called with name that includes wild char.\n    def object_exists_side_effect(*args, **kwargs):\n      return args[0].key.find('*') < 0\n\n    mock_object_exists.side_effect = object_exists_side_effect\n\n    # Mock API for getting objects in a bucket.\n    mock_bucket_objects.side_effect = TestCases._mock_bucket_objects_return(context)\n\n    # Mock API for getting object metadata.\n    mock_api_objects_get.side_effect = TestCases._mock_api_objects_get()\n\n    objects = google.datalab.storage.commands._storage._expand_list(None)\n    self.assertEqual([], objects)\n\n    objects = google.datalab.storage.commands._storage._expand_list([])\n    self.assertEqual([], objects)\n\n    objects = google.datalab.storage.commands._storage._expand_list('gs://bar/o*')\n    self.assertEqual(['gs://bar/object1', 'gs://bar/object3'], objects)\n\n    objects = google.datalab.storage.commands._storage._expand_list(['gs://foo', 'gs://bar'])\n    self.assertEqual(['gs://foo', 'gs://bar'], objects)\n\n    objects = google.datalab.storage.commands._storage._expand_list(['gs://foo/*', 'gs://bar'])\n    self.assertEqual(['gs://foo/object1', 'gs://foo/object2', 'gs://foo/object3', 'gs://bar'],\n                     objects)\n\n    objects = google.datalab.storage.commands._storage._expand_list(['gs://bar/o*'])\n    self.assertEqual(['gs://bar/object1', 'gs://bar/object3'], objects)\n\n    objects = google.datalab.storage.commands._storage._expand_list(['gs://bar/i*'])\n    # Note - if no match we return the pattern.\n    self.assertEqual(['gs://bar/i*'], objects)\n\n    objects = google.datalab.storage.commands._storage._expand_list(['gs://baz'])\n    self.assertEqual(['gs://baz'], objects)\n\n    objects = google.datalab.storage.commands._storage._expand_list(['gs://baz/*'])\n    self.assertEqual(['gs://baz/*'], objects)\n\n    objects = google.datalab.storage.commands._storage._expand_list(['gs://foo/o*3'])\n    self.assertEqual(['gs://foo/object3'], objects)\n\n  @mock.patch('google.datalab.storage._object.Object.copy_to', autospec=True)\n  @mock.patch('google.datalab.storage._bucket.Bucket.objects', autospec=True)\n  @mock.patch('google.datalab.storage._api.Api.objects_get', autospec=True)\n  @mock.patch('google.datalab.Context.default')\n  def test_gcs_copy(self, mock_context_default, mock_api_objects_get, mock_bucket_objects,\n                    mock_gcs_object_copy_to):\n    context = TestCases._create_context()\n    mock_context_default.return_value = context\n    # Mock API for getting objects in a bucket.\n    mock_bucket_objects.side_effect = TestCases._mock_bucket_objects_return(context)\n    # Mock API for getting object metadata.\n    mock_api_objects_get.side_effect = TestCases._mock_api_objects_get()\n\n    google.datalab.storage.commands._storage._gcs_copy({\n      'source': ['gs://foo/object1'],\n      'destination': 'gs://foo/bar1'\n    }, None)\n\n    mock_gcs_object_copy_to.assert_called_with(mock.ANY, 'bar1', bucket='foo')\n    self.assertEquals('object1', mock_gcs_object_copy_to.call_args[0][0].key)\n    self.assertEquals('foo', mock_gcs_object_copy_to.call_args[0][0]._bucket)\n\n    with self.assertRaises(Exception) as error:\n      google.datalab.storage.commands._storage._gcs_copy({\n        'source': ['gs://foo/object*'],\n        'destination': 'gs://foo/bar1'\n      }, None)\n    self.assertEqual('More than one source but target gs://foo/bar1 is not a bucket',\n                     str(error.exception))\n\n  @mock.patch('google.datalab.storage.commands._storage._gcs_copy', autospec=True)\n  def test_gcs_copy_magic(self, mock_gcs_copy):\n    google.datalab.storage.commands._storage.gcs('copy --source gs://foo/object1 '\n                                                 '--destination gs://foo/bar1')\n    mock_gcs_copy.assert_called_with({\n        'source': ['gs://foo/object1'],\n        'destination': 'gs://foo/bar1',\n        'func': google.datalab.storage.commands._storage._gcs_copy\n      }, None)\n\n  @mock.patch('google.datalab.storage._api.Api.buckets_insert', autospec=True)\n  @mock.patch('google.datalab.Context.default')\n  def test_gcs_create(self, mock_context_default, mock_api_buckets_insert):\n    context = TestCases._create_context()\n    mock_context_default.return_value = context\n\n    errs = google.datalab.storage.commands._storage._gcs_create({\n      'project': 'test',\n      'bucket': [\n        'gs://baz'\n      ]\n    }, None)\n    self.assertEqual(None, errs)\n    mock_api_buckets_insert.assert_called_with(mock.ANY, 'baz', project_id='test')\n\n    with self.assertRaises(Exception) as error:\n      google.datalab.storage.commands._storage._gcs_create({\n        'project': 'test',\n        'bucket': [\n          'gs://foo/bar'\n        ]\n      }, None)\n    self.assertEqual(\"Couldn't create gs://foo/bar: Invalid bucket name gs://foo/bar\",\n                     str(error.exception))\n\n  @mock.patch('google.datalab.storage._api.Api.objects_list', autospec=True)\n  @mock.patch('google.datalab.storage._api.Api.buckets_get', autospec=True)\n  @mock.patch('google.datalab.storage._api.Api.objects_get', autospec=True)\n  @mock.patch('google.datalab.storage._bucket.Bucket.objects', autospec=True)\n  @mock.patch('google.datalab.storage._api.Api.objects_delete', autospec=True)\n  @mock.patch('google.datalab.storage._api.Api.buckets_delete', autospec=True)\n  @mock.patch('google.datalab.Context.default')\n  def test_gcs_delete(self, mock_context_default, mock_api_bucket_delete,\n                      mock_api_objects_delete, mock_bucket_objects, mock_api_objects_get,\n                      mock_api_buckets_get, mock_api_objects_list):\n    context = TestCases._create_context()\n    mock_context_default.return_value = context\n    # Mock API for getting objects in a bucket.\n    mock_bucket_objects.side_effect = TestCases._mock_bucket_objects_return(context)\n    # Mock API for getting object metadata.\n    mock_api_objects_get.side_effect = TestCases._mock_api_objects_get()\n    mock_api_buckets_get.side_effect = TestCases._mock_api_buckets_get()\n    # Mock API for listing objects in a bucket.\n    mock_api_objects_list.side_effect = {}\n\n    with self.assertRaises(Exception) as error:\n      google.datalab.storage.commands._storage._gcs_delete({\n        'bucket': [\n          'gs://bar',\n          'gs://baz'\n        ],\n        'object': [\n          'gs://foo/object1',\n          'gs://baz/object1',\n        ]\n      }, None)\n    self.assertEqual('gs://baz does not exist\\ngs://baz/object1 does not exist',\n                     str(error.exception))\n    mock_api_bucket_delete.assert_called_with(mock.ANY, 'bar')\n    mock_api_objects_delete.assert_called_with(mock.ANY, 'foo', 'object1')\n\n  @mock.patch('google.datalab.Context.default')\n  def test_gcs_view(self, mock_context_default):\n    context = TestCases._create_context()\n    mock_context_default.return_value = context\n    # TODO(gram): complete this test\n\n  @mock.patch('google.datalab.Context.default')\n  def test_gcs_write(self, mock_context_default):\n    context = TestCases._create_context()\n    mock_context_default.return_value = context\n    # TODO(gram): complete this test\n\n  @staticmethod\n  def _create_context():\n    project_id = 'test'\n    creds = mock.Mock(spec=google.auth.credentials.Credentials)\n    return google.datalab.Context(project_id, creds)\n\n  @staticmethod\n  def _mock_bucket_objects_return(context):\n    # Mock API for getting objects in a bucket.\n    def bucket_objects_side_effect(*args, **kwargs):\n      bucket = args[0].name  # self\n      if bucket == 'foo':\n        return [\n          google.datalab.storage._object.Object(bucket, 'object1', context=context),\n          google.datalab.storage._object.Object(bucket, 'object2', context=context),\n          google.datalab.storage._object.Object(bucket, 'object3', context=context),\n        ]\n      elif bucket == 'bar':\n        return [\n          google.datalab.storage._object.Object(bucket, 'object1', context=context),\n          google.datalab.storage._object.Object(bucket, 'object3', context=context),\n        ]\n      else:\n        return []\n    return bucket_objects_side_effect\n\n  @staticmethod\n  def _mock_api_objects_get():\n    # Mock API for getting object metadata.\n    def api_objects_get_side_effect(*args, **kwargs):\n      if args[1].find('baz') >= 0:\n        return None\n      key = args[2]\n      if key.find('*') >= 0:\n        return None\n      return {'name': key}\n    return api_objects_get_side_effect\n\n  @staticmethod\n  def _mock_api_buckets_get():\n    # Mock API for getting bucket metadata.\n    def api_buckets_get_side_effect(*args, **kwargs):\n      key = args[1]\n      if key.find('*') >= 0 or key.find('baz') >= 0:\n        return None\n      return {'name': key}\n    return api_buckets_get_side_effect\n"
  },
  {
    "path": "tests/kernel/utils_tests.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nfrom builtins import range\nimport datetime as dt\nimport collections\nimport mock\nimport pandas\nimport unittest\n\n# import Python so we can mock the parts we need to here.\nimport IPython\nimport IPython.core.magic\n\nimport google.auth\n\n\nIPython.core.magic.register_line_cell_magic = mock.Mock()\nIPython.core.magic.register_line_magic = mock.Mock()\nIPython.core.magic.register_cell_magic = mock.Mock()\nIPython.get_ipython = mock.Mock()\n\n\nimport google.datalab  # noqa\nimport google.datalab.bigquery  # noqa\nimport google.datalab.utils.commands._utils as _utils # noqa\n\n\nclass TestCases(unittest.TestCase):\n\n  @staticmethod\n  def _get_expected_cols():\n    cols = [\n      {'type': 'number', 'id': 'Column1', 'label': 'Column1'},\n      {'type': 'number', 'id': 'Column2', 'label': 'Column2'},\n      {'type': 'string', 'id': 'Column3', 'label': 'Column3'},\n      {'type': 'boolean', 'id': 'Column4', 'label': 'Column4'},\n      {'type': 'number', 'id': 'Column5', 'label': 'Column5'},\n      {'type': 'timestamp', 'id': 'Column6', 'label': 'Column6'}\n    ]\n    return cols\n\n  @staticmethod\n  def _timestamp(d):\n    return (d - dt.datetime(1970, 1, 1)).total_seconds()\n\n  @staticmethod\n  def _get_raw_rows():\n    rows = [\n      {'f': [\n        {'v': 1}, {'v': 2}, {'v': '3'}, {'v': 'true'}, {'v': 0.0},\n        {'v': TestCases._timestamp(dt.datetime(2000, 1, 1))}\n      ]},\n      {'f': [\n        {'v': 11}, {'v': 12}, {'v': '13'}, {'v': 'false'}, {'v': 0.2},\n        {'v': TestCases._timestamp(dt.datetime(2000, 1, 2))}\n      ]},\n      {'f': [\n        {'v': 21}, {'v': 22}, {'v': '23'}, {'v': 'true'}, {'v': 0.3},\n        {'v': TestCases._timestamp(dt.datetime(2000, 1, 3))}\n      ]},\n      {'f': [\n        {'v': 31}, {'v': 32}, {'v': '33'}, {'v': 'false'}, {'v': 0.4},\n        {'v': TestCases._timestamp(dt.datetime(2000, 1, 4))}\n      ]},\n      {'f': [\n        {'v': 41}, {'v': 42}, {'v': '43'}, {'v': 'true'}, {'v': 0.5},\n        {'v': TestCases._timestamp(dt.datetime(2000, 1, 5))}\n      ]},\n      {'f': [\n        {'v': 51}, {'v': 52}, {'v': '53'}, {'v': 'true'}, {'v': 0.6},\n        {'v': TestCases._timestamp(dt.datetime(2000, 1, 6))}\n      ]}\n    ]\n    return rows\n\n  @staticmethod\n  def _get_expected_rows():\n    rows = [\n      {'c': [\n        {'v': 1}, {'v': 2}, {'v': '3'}, {'v': True}, {'v': 0.0}, {'v': dt.datetime(2000, 1, 1)}\n      ]},\n      {'c': [\n        {'v': 11}, {'v': 12}, {'v': '13'}, {'v': False}, {'v': 0.2}, {'v': dt.datetime(2000, 1, 2)}\n      ]},\n      {'c': [\n        {'v': 21}, {'v': 22}, {'v': '23'}, {'v': True}, {'v': 0.3}, {'v': dt.datetime(2000, 1, 3)}\n      ]},\n      {'c': [\n        {'v': 31}, {'v': 32}, {'v': '33'}, {'v': False}, {'v': 0.4}, {'v': dt.datetime(2000, 1, 4)}\n      ]},\n      {'c': [\n        {'v': 41}, {'v': 42}, {'v': '43'}, {'v': True}, {'v': 0.5}, {'v': dt.datetime(2000, 1, 5)}\n      ]},\n      {'c': [\n        {'v': 51}, {'v': 52}, {'v': '53'}, {'v': True}, {'v': 0.6}, {'v': dt.datetime(2000, 1, 6)}\n      ]}\n    ]\n    return rows\n\n  @staticmethod\n  def _get_test_data_as_list_of_dicts():\n    test_data = [\n      {'Column1': 1, 'Column2': 2, 'Column3': '3',\n       'Column4': True, 'Column5': 0.0, 'Column6': dt.datetime(2000, 1, 1)},\n      {'Column1': 11, 'Column2': 12, 'Column3': '13',\n       'Column4': False, 'Column5': 0.2, 'Column6': dt.datetime(2000, 1, 2)},\n      {'Column1': 21, 'Column2': 22, 'Column3': '23',\n       'Column4': True, 'Column5': 0.3, 'Column6': dt.datetime(2000, 1, 3)},\n      {'Column1': 31, 'Column2': 32, 'Column3': '33',\n       'Column4': False, 'Column5': 0.4, 'Column6': dt.datetime(2000, 1, 4)},\n      {'Column1': 41, 'Column2': 42, 'Column3': '43',\n       'Column4': True, 'Column5': 0.5, 'Column6': dt.datetime(2000, 1, 5)},\n      {'Column1': 51, 'Column2': 52, 'Column3': '53',\n       'Column4': True, 'Column5': 0.6, 'Column6': dt.datetime(2000, 1, 6)}\n    ]\n    # Use OrderedDicts to make testing the result easier.\n    for i in range(0, len(test_data)):\n      test_data[i] = collections.OrderedDict(sorted(list(test_data[i].items()), key=lambda t: t[0]))\n\n    return test_data\n\n  def test_get_data_from_list_of_dicts(self):\n    self._test_get_data(TestCases._get_test_data_as_list_of_dicts(), TestCases._get_expected_cols(),\n                        TestCases._get_expected_rows(), 6,\n                        _utils._get_data_from_list_of_dicts)\n    self._test_get_data(TestCases._get_test_data_as_list_of_dicts(), TestCases._get_expected_cols(),\n                        TestCases._get_expected_rows(), 6,\n                        _utils.get_data)\n\n  def test_get_data_from_list_of_lists(self):\n    test_data = [\n      [1, 2, '3', True, 0.0, dt.datetime(2000, 1, 1)],\n      [11, 12, '13', False, 0.2, dt.datetime(2000, 1, 2)],\n      [21, 22, '23', True, 0.3, dt.datetime(2000, 1, 3)],\n      [31, 32, '33', False, 0.4, dt.datetime(2000, 1, 4)],\n      [41, 42, '43', True, 0.5, dt.datetime(2000, 1, 5)],\n      [51, 52, '53', True, 0.6, dt.datetime(2000, 1, 6)],\n    ]\n\n    self._test_get_data(test_data, TestCases._get_expected_cols(), TestCases._get_expected_rows(),\n                        6, _utils._get_data_from_list_of_lists)\n    self._test_get_data(test_data, TestCases._get_expected_cols(), TestCases._get_expected_rows(),\n                        6, _utils.get_data)\n\n  def test_get_data_from_dataframe(self):\n    df = pandas.DataFrame(self._get_test_data_as_list_of_dicts())\n    self._test_get_data(df, TestCases._get_expected_cols(), TestCases._get_expected_rows(), 6,\n                        _utils._get_data_from_dataframe)\n    self._test_get_data(df, TestCases._get_expected_cols(), TestCases._get_expected_rows(), 6,\n                        _utils.get_data)\n\n  @mock.patch('google.datalab.bigquery._api.Api.tabledata_list')\n  @mock.patch('google.datalab.bigquery._table.Table.exists')\n  @mock.patch('google.datalab.bigquery._api.Api.tables_get')\n  @mock.patch('google.datalab.Context.default')\n  def test_get_data_from_table(self, mock_context_default, mock_api_tables_get,\n                               mock_table_exists, mock_api_tabledata_list):\n    data = TestCases._get_expected_rows()\n    mock_context_default.return_value = TestCases._create_context()\n    mock_api_tables_get.return_value = {\n      'numRows': len(data),\n      'schema': {\n        'fields': [\n          {'name': 'Column1', 'type': 'INTEGER'},\n          {'name': 'Column2', 'type': 'INTEGER'},\n          {'name': 'Column3', 'type': 'STRING'},\n          {'name': 'Column4', 'type': 'BOOLEAN'},\n          {'name': 'Column5', 'type': 'FLOAT'},\n          {'name': 'Column6', 'type': 'TIMESTAMP'}\n        ]\n      }\n    }\n    mock_table_exists.return_value = True\n    raw_data = self._get_raw_rows()\n\n    def tabledata_list(*args, **kwargs):\n      start_index = kwargs['start_index']\n      max_results = kwargs['max_results']\n      if max_results < 0:\n        max_results = len(data)\n      return {'rows': raw_data[start_index:start_index + max_results]}\n\n    mock_api_tabledata_list.side_effect = tabledata_list\n    t = google.datalab.bigquery.Table('foo.bar')\n    self._test_get_data(t, TestCases._get_expected_cols(), TestCases._get_expected_rows(), 6,\n                        _utils._get_data_from_table)\n    self._test_get_data(t, TestCases._get_expected_cols(), TestCases._get_expected_rows(), 6,\n                        _utils.get_data)\n\n  def test_get_data_from_empty_list(self):\n    self._test_get_data([], [], [], 0, _utils.get_data)\n\n  def test_get_data_from_malformed_list(self):\n    with self.assertRaises(Exception) as error:\n      self._test_get_data(['foo', 'bar'], [], [], 0, _utils.get_data)\n    self.assertEquals('To get tabular data from a list it must contain dictionaries or lists.',\n                      str(error.exception))\n\n  def _test_get_data(self, test_data, cols, rows, expected_count, fn):\n    self.maxDiff = None\n    data, count = fn(test_data)\n    self.assertEquals(expected_count, count)\n    self.assertEquals({'cols': cols, 'rows': rows}, data)\n\n    # Test first_row. Note that count must be set in this case so we use a value greater than the\n    # data set size.\n    for first in range(0, 6):\n      data, count = fn(test_data, first_row=first, count=10)\n      self.assertEquals(expected_count, count)\n      self.assertEquals({'cols': cols, 'rows': rows[first:]}, data)\n\n    # Test first_row + count\n    for first in range(0, 6):\n      data, count = fn(test_data, first_row=first, count=2)\n      self.assertEquals(expected_count, count)\n      self.assertEquals({'cols': cols, 'rows': rows[first:first + 2]}, data)\n\n    # Test subsets of columns\n\n    # No columns\n    data, count = fn(test_data, fields=[])\n    self.assertEquals({'cols': [], 'rows': [{'c': []}] * expected_count}, data)\n\n    # Single column\n    data, count = fn(test_data, fields=['Column3'])\n\n    if expected_count == 0:\n      return\n\n    self.assertEquals({'cols': [cols[2]], 'rows': [{'c': [row['c'][2]]} for row in rows]}, data)\n\n    # Multi-columns\n    data, count = fn(test_data, fields=['Column1', 'Column3', 'Column6'])\n    self.assertEquals({'cols': [cols[0], cols[2], cols[5]],\n                       'rows': [{'c': [row['c'][0], row['c'][2], row['c'][5]]} for row in rows]},\n                      data)\n\n    # Switch order\n    data, count = fn(test_data, fields=['Column3', 'Column1'])\n    self.assertEquals({'cols': [cols[2], cols[0]],\n                       'rows': [{'c': [row['c'][2], row['c'][0]]} for row in rows]}, data)\n\n    # Select all\n    data, count = fn(test_data,\n                     fields=['Column1', 'Column2', 'Column3', 'Column4', 'Column5', 'Column6'])\n    self.assertEquals({'cols': cols, 'rows': rows}, data)\n\n  def test_expand_var(self):\n    env = {'var': 'test-var-value'}\n    resolved = _utils.expand_var('$var', env)\n    self.assertEqual(resolved, env['var'])\n\n    resolved = _utils.expand_var('', env)\n    self.assertEqual(resolved, '')\n\n    with self.assertRaisesRegexp(Exception, 'Cannot expand variable'):\n      _utils.expand_var('$badname', env)\n\n  def test_replace_vars(self):\n    config = {'var': '$value'}\n    env = {'value': 5}\n    _utils.replace_vars(config, env)\n    self.assertEqual(config, {'var': 5})\n\n    config = ['$value']\n    _utils.replace_vars(config, env)\n    self.assertEqual(config, [5])\n\n    config = ({'var1': '$value1'}, ['$value2'])\n    env = {'value1': 5, 'value2': 'stringvalue'}\n    _utils.replace_vars(config, env)\n    self.assertEqual(config, ({'var1': 5}, ['stringvalue']))\n\n  def test_validate_config(self):\n    with self.assertRaisesRegexp(Exception, 'config is not dict type'):\n      _utils.validate_config([], [])\n\n    config = {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'}\n    _utils.validate_config(config, ['key1', 'key2'], ['key3'])\n    _utils.validate_config(config, [], ['key1', 'key2', 'key3'])\n    _utils.validate_config(config, ['key1', 'key2', 'key3'])\n\n    with self.assertRaisesRegexp(Exception, 'Invalid config with unexpected keys'):\n      _utils.validate_config(config, ['key1', 'key2'])\n\n    with self.assertRaisesRegexp(Exception, 'Invalid config with missing keys'):\n      _utils.validate_config(config, ['key1', 'key2', 'key3', 'key4'])\n\n  def test_validate_config_must_have(self):\n    config = {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'}\n\n    _utils.validate_config_must_have(config, ['key1', 'key2'])\n\n    with self.assertRaisesRegexp(Exception, 'Invalid config with missing keys'):\n      _utils.validate_config_must_have(config, ['key1', 'key4'])\n\n  def test_validate_config_has_one_of(self):\n    config = {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'}\n\n    _utils.validate_config_has_one_of(config, ['key1'])\n\n    with self.assertRaisesRegexp(Exception, 'Only one of the values'):\n      _utils.validate_config_has_one_of(config, ['key1', 'key2', 'key3'])\n\n    with self.assertRaisesRegexp(Exception, 'One of the values in'):\n      _utils.validate_config_has_one_of(config, ['key4', 'key5'])\n\n  def test_validate_config_value(self):\n    _utils.validate_config_value('val', ['val', 'val1', 'val2'])\n\n    with self.assertRaisesRegexp(Exception, 'Invalid config value'):\n      _utils.validate_config_value('val', ['val0', 'val1', 'val2'])\n\n  def test_validate_gcs_path(self):\n    _utils.validate_gcs_path('gs://testbucket/path/to/object', False)\n\n    with self.assertRaisesRegexp(Exception, 'Invalid GCS path'):\n      _utils.validate_gcs_path('path/to/object', False)\n\n    _utils.validate_gcs_path('gs://path', False)\n\n    with self.assertRaisesRegexp(Exception, 'It appears the GCS path \"gs://path\" is a bucket'):\n      _utils.validate_gcs_path('gs://path', True)\n\n  def test_parse_control_options_badtype(self):\n    control = {'label': None, 'type': 'badtype'}\n    with self.assertRaisesRegexp(Exception, 'Unknown control type badtype'):\n      _utils.parse_control_options({'test-control': control})\n\n  def test_parse_control_options_set(self):\n    control = {'label': None, 'choices': ['v1', 'v2'], 'min': 0, 'max': 10, 'step': 2}\n    defaults = {'test-control': ['value1', 'value2']}\n\n    control_html = _utils.parse_control_options({'test-control': control}, defaults)\n    self.assertIn('class=\"gchart-control\"', control_html[0])\n    self.assertIn('<input type=\"checkbox\"', control_html[0])\n    self.assertIn('value=\"v1\"', control_html[0])\n    self.assertIn('value=\"v2\"', control_html[0])\n    self.assertEqual(control_html[1], {'test-control': ['value1', 'value2']})\n\n    control['choices'] = []\n    with self.assertRaisesRegexp(Exception, 'set control must specify a nonempty set'):\n      _utils.parse_control_options({'test-control': control}, defaults)\n\n    # make sure value is picked from set of choices if not specified in any way\n    control['type'] = 'set'\n    control['choices'] = ['v1', 'v2']\n    _utils.parse_control_options({'test-control': control})\n\n  def test_parse_control_options_picker(self):\n    control = {'label': None, 'type': 'picker', 'choices': ['v1', 'v2'],\n               'min': 0, 'max': 10, 'step': 2}\n    defaults = {'test-control': ['value1', 'value2']}\n\n    control_html = _utils.parse_control_options({'test-control': control}, defaults)\n    self.assertIn('class=\"gchart-control\"', control_html[0])\n    self.assertIn('<select', control_html[0])\n    self.assertIn('<option value=\"v1\"', control_html[0])\n    self.assertIn('<option value=\"v2\"', control_html[0])\n    self.assertEqual(control_html[1], {'test-control': ['value1', 'value2']})\n\n    control['choices'] = []\n    with self.assertRaisesRegexp(Exception, 'picker control must specify a nonempty set'):\n      _utils.parse_control_options({'test-control': control}, defaults)\n\n    # make sure value is picked from set of choices if not specified in any way\n    control['type'] = 'picker'\n    control['choices'] = ['v1', 'v2']\n    _utils.parse_control_options({'test-control': control})\n\n  def test_parse_control_options_textbox(self):\n    control = {'label': None, 'value': 'test-value', 'type': 'textbox',\n               'choices': None, 'min': 0, 'max': 10, 'step': 2}\n    defaults = {'test-control': None}\n\n    control_html = _utils.parse_control_options({'test-control': control}, defaults)\n    self.assertIn('class=\"gchart-control\"', control_html[0])\n    self.assertIn('<input type=\"text\"', control_html[0])\n    self.assertIn('value=\"test-value\"', control_html[0])\n    self.assertEqual(control_html[1], {'test-control': 'test-value'})\n\n    control['value'] = None\n    control_html = _utils.parse_control_options({'test-control': control})\n    self.assertIn('value=\"\"', control_html[0])\n\n  def test_parse_control_options_slider(self):\n    control = {'label': None, 'value': 5, 'type': 'slider',\n               'choices': None, 'min': 0, 'max': 10, 'step': 2}\n    control_html = _utils.parse_control_options({'test-control': control})\n    self.assertIn('class=\"gchart-slider_value\"', control_html[0])\n    self.assertIn('<input type=\"range\"', control_html[0])\n    self.assertIn('value=\"5\"', control_html[0])\n    self.assertIn('min=\"0\" max=\"10\" step=\"2\"', control_html[0])\n    self.assertEqual(control_html[1], {'test-control': 5})\n\n    control['min'] = None\n    with self.assertRaisesRegexp(Exception, 'slider control must specify a min and max'):\n      _utils.parse_control_options({'test-control': control})\n\n    control['min'] = 20\n    with self.assertRaisesRegexp(Exception,\n                                 'slider control must specify a min value less than max value'):\n      _utils.parse_control_options({'test-control': control})\n\n    control['min'] = 7\n    control['value'] = None\n    control_html = _utils.parse_control_options({'test-control': control})\n    self.assertIn('value=\"7\"', control_html[0])\n\n  def test_parse_control_options_checkbox(self):\n    control_html = _utils.parse_control_options({'test-control': {'type': 'checkbox'}})\n    self.assertIn('<input type=\"checkbox\"', control_html[0])\n\n  @staticmethod\n  def _create_api():\n    context = TestCases._create_context()\n    return google.datalab.bigquery._api.Api(context.credentials, context.project_id)\n\n  @staticmethod\n  def _create_context():\n    project_id = 'test'\n    creds = mock.Mock(spec=google.auth.credentials.Credentials)\n    return google.datalab.Context(project_id, creds)\n"
  },
  {
    "path": "tests/main.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nimport argparse\nimport sys\nimport unittest\n\n# For these tests to work locally, install the package with \"pip install -e .\"\n# from the parent folder and run \"python tests/main.py\"\n\nimport context_tests\nimport bigquery.api_tests\nimport bigquery.dataset_tests\nimport bigquery.external_data_source_tests\nimport bigquery.jobs_tests\nimport bigquery.operator_tests\nimport bigquery.parser_tests\nimport bigquery.pipeline_tests\nimport bigquery.query_tests\nimport bigquery.sampling_tests\nimport bigquery.schema_tests\nimport bigquery.table_tests\nimport bigquery.udf_tests\nimport bigquery.view_tests\nimport kernel.bigquery_tests\nimport kernel.chart_data_tests\nimport kernel.chart_tests\nimport kernel.html_tests\nimport kernel.pipeline_tests\nimport kernel.storage_tests\nimport kernel.utils_tests\nimport ml.confusion_matrix_tests\nimport ml.dataset_tests\nimport ml.facets_tests\nimport ml.metrics_tests\nimport ml.summary_tests\nimport ml.tensorboard_tests\nimport ml_workbench.all_tests\nimport mltoolbox_structured_data.dl_interface_tests\nimport mltoolbox_structured_data.sd_e2e_tests\nimport mltoolbox_structured_data.traininglib_tests\nimport mlworkbench_magic.archive_tests\nimport mlworkbench_magic.explainer_tests\nimport mlworkbench_magic.local_predict_tests\nimport mlworkbench_magic.ml_tests\nimport mlworkbench_magic.shell_process_tests\nimport pipeline.airflow_tests\nimport pipeline.composer_tests\nimport pipeline.composer_api_tests\nimport pipeline.pipeline_tests\nimport stackdriver.commands.monitoring_tests\nimport stackdriver.monitoring.group_tests\nimport stackdriver.monitoring.metric_tests\nimport stackdriver.monitoring.resource_tests\nimport stackdriver.monitoring.query_metadata_tests\nimport stackdriver.monitoring.query_tests\nimport stackdriver.monitoring.utils_tests\nimport storage.api_tests\nimport storage.bucket_tests\nimport storage.object_tests\nimport _util.commands_tests\nimport _util.feature_statistics_generator_test\nimport _util.generic_feature_statistics_generator_test\nimport _util.http_tests\nimport _util.lru_cache_tests\nimport _util.util_tests\n\n\n_UNIT_TEST_MODULES = [\n    context_tests,\n    bigquery.api_tests,\n    bigquery.dataset_tests,\n    # bigquery.external_data_source_tests, # TODO: enable external data source tests\n    bigquery.jobs_tests,\n    bigquery.operator_tests,\n    bigquery.parser_tests,\n    bigquery.pipeline_tests,\n    bigquery.query_tests,\n    bigquery.sampling_tests,\n    bigquery.schema_tests,\n    bigquery.table_tests,\n    bigquery.udf_tests,\n    bigquery.view_tests,\n    bigquery.sampling_tests,\n    kernel.bigquery_tests,\n    kernel.chart_data_tests,\n    kernel.chart_tests,\n    kernel.html_tests,\n    kernel.pipeline_tests,\n    kernel.storage_tests,\n    kernel.utils_tests,\n    ml.confusion_matrix_tests,\n    ml.dataset_tests,\n    ml.facets_tests,\n    ml.metrics_tests,\n    ml.summary_tests,\n    mlworkbench_magic.ml_tests,\n    pipeline.composer_api_tests,\n    pipeline.composer_tests,\n    pipeline.airflow_tests,\n    pipeline.pipeline_tests,\n    stackdriver.commands.monitoring_tests,\n    stackdriver.monitoring.group_tests,\n    stackdriver.monitoring.metric_tests,\n    stackdriver.monitoring.resource_tests,\n    stackdriver.monitoring.query_metadata_tests,\n    stackdriver.monitoring.query_tests,\n    stackdriver.monitoring.utils_tests,\n    storage.api_tests,\n    storage.bucket_tests,\n    storage.object_tests,\n    _util.commands_tests,\n    _util.feature_statistics_generator_test,\n    _util.generic_feature_statistics_generator_test,\n    _util.http_tests,\n    _util.lru_cache_tests,\n    _util.util_tests\n]\n\n\n_INTEGRATION_TEST_MODULES = [\n    ml.tensorboard_tests,\n    ml_workbench.all_tests,\n    mltoolbox_structured_data.dl_interface_tests,\n    mltoolbox_structured_data.sd_e2e_tests,  # Not everything runs in Python 3.\n    mltoolbox_structured_data.traininglib_tests,\n    mlworkbench_magic.local_predict_tests,\n    mlworkbench_magic.explainer_tests,\n    # TODO: the test fails in travis only. Need to investigate.\n    # mlworkbench_magic.shell_process_tests,\n    mlworkbench_magic.archive_tests,\n]\n\n\ndef parse_arguments(argv):\n  \"\"\"Parse command line arguments.\n\n  Args:\n    argv: list of command line arguments, including program name.\n\n  Returns:\n    An argparse Namespace object.\n\n  Raises:\n    ValueError: for bad parameters\n  \"\"\"\n  parser = argparse.ArgumentParser()\n  parser.add_argument('--unittestonly',\n                      action='store_true',\n                      help='Only run unit tests (no integration tests).')\n  args = parser.parse_args(args=argv[1:])\n  return args\n\n\nif __name__ == '__main__':\n  args = parse_arguments(sys.argv)\n  suite = unittest.TestSuite()\n  for m in _UNIT_TEST_MODULES:\n    suite.addTests(unittest.defaultTestLoader.loadTestsFromModule(m))\n  if not args.unittestonly:\n    for m in _INTEGRATION_TEST_MODULES:\n      suite.addTests(unittest.defaultTestLoader.loadTestsFromModule(m))\n\n  runner = unittest.TextTestRunner()\n  result = runner.run(suite)\n\n  sys.exit(len(result.errors) + len(result.failures))\n"
  },
  {
    "path": "tests/ml/__init__.py",
    "content": ""
  },
  {
    "path": "tests/ml/confusion_matrix_tests.py",
    "content": "# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nimport unittest\n\nimport csv\nimport os\nimport random\nimport shutil\nimport tempfile\n\nfrom google.datalab.ml import ConfusionMatrix\n\n\nclass TestConfusionMatrix(unittest.TestCase):\n  \"\"\"google.datalab.ml.ConfusionMatrix Tests\"\"\"\n\n  def setUp(self):\n    self._test_dir = tempfile.mkdtemp()\n\n  def tearDown(self):\n    shutil.rmtree(self._test_dir)\n\n  def test_from_csv(self):\n    \"\"\"test ConfusionMatrix's from_csv().\"\"\"\n\n    counts = self._create_csv_files(['1.csv', '2.csv'], 50)\n    cm = ConfusionMatrix.from_csv(os.path.join(self._test_dir, '*.csv'),\n                                  headers=['target', 'predicted', ''])\n    df = cm.to_dataframe()\n    dict_from_df = {}\n    for index, row in df.iterrows():\n      dict_from_df[(row['target'], row['predicted'])] = row['count']\n    self.assertEqual(counts, dict_from_df)\n\n  def _create_csv_files(self, filenames, num_lines):\n    \"\"\"Makes csv data files.\"\"\"\n\n    counts = {\n        ('red', 'red'): 0,\n        ('red', 'blue'): 0,\n        ('red', 'green'): 0,\n        ('blue', 'red'): 0,\n        ('blue', 'blue'): 0,\n        ('blue', 'green'): 0,\n        ('green', 'red'): 0,\n        ('green', 'blue'): 0,\n        ('green', 'green'): 0\n    }\n    index = 0\n    for filename in filenames:\n      full_file_name = os.path.join(self._test_dir, filename)\n      with open(full_file_name, 'w') as f:\n        writer = csv.writer(f)\n        for r in range(num_lines):\n          target = random.choice(['red', 'blue', 'green'])\n          predicted = random.choice(['red', 'blue', 'green'])\n          counts[(target, predicted)] += 1\n          index += 1\n          writer.writerow([target, predicted, index])\n\n    return counts\n"
  },
  {
    "path": "tests/ml/dataset_tests.py",
    "content": "# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nimport unittest\n\nimport csv\nimport os\nimport pandas as pd\nimport random\nimport shutil\nimport tempfile\n\nimport google.datalab\nfrom google.datalab.ml import CsvDataSet, BigQueryDataSet, TransformedDataSet\n\n\nclass TestCsvDataSet(unittest.TestCase):\n\n  def test_schema(self):\n    json_schema = TestCsvDataSet._create_json_schema()\n\n    # CsvDataSet can take a json schema, a Schema object, or a string\n    ds = CsvDataSet(file_pattern='some/file', schema=json_schema)\n    self.assertEqual(json_schema, ds.schema)\n\n    schema_obj = google.datalab.bigquery.Schema(json_schema)\n    ds = CsvDataSet(file_pattern='some/file', schema=schema_obj)\n    self.assertEqual(json_schema, ds.schema)\n\n    schema_str = 'id: INTEGER, field1: STRING, field2: INTEGER'\n    ds = CsvDataSet(file_pattern='some/file', schema=schema_str)\n    self.assertEqual(json_schema, ds.schema)\n\n  def test_sample_and_size(self):\n    tmp_dir = tempfile.mkdtemp()\n    try:\n      json_schema = TestCsvDataSet._create_json_schema()\n      all_rows = TestCsvDataSet._create_csv_files(tmp_dir, 'data', 3, 30)\n      ds = CsvDataSet(file_pattern=os.path.join(tmp_dir, 'data*'), schema=json_schema)\n      self.assertEqual(90, ds.size)\n\n      df = ds.sample(5)\n      self.assertEqual(5, len(df))\n      self.assertTrue(isinstance(df, pd.DataFrame))\n      self.assertEqual(5, len(set(df['id'].tolist())))  # 5 unique rows.\n\n      # check the 5 samples below to the csv files by checking they are in\n      # all_rows\n      for _, row in df.iterrows():\n        row_index = row['id']\n        self.assertEqual(all_rows.iloc[row_index]['field1'], row['field1'])\n        self.assertEqual(all_rows.iloc[row_index]['field2'], row['field2'])\n\n      df = ds.sample(3 * 5)\n      self.assertEqual(3 * 5, len(df))\n      self.assertTrue(isinstance(df, pd.DataFrame))\n      self.assertEqual(3 * 5, len(set(df['id'].tolist())))  # 15 unique rows.\n\n      with self.assertRaises(ValueError):\n        df = ds.sample(3 * 50 + 1)  # sample is larger than data size\n    finally:\n      shutil.rmtree(tmp_dir)\n\n  @staticmethod\n  def _create_csv_files(folder, filename, num_files, num_lines):\n    \"\"\"Makes csv data files.\n\n    Makes files in the from:\n      folder/filename1.csv,\n      folder/filename2.csv,\n      ...\n      folder/filename{num_files}.csv\n\n    Each file will have 5 random csv rows.\n\n    Args:\n      folder: output folder\n      filename: filename prefix\n      num_files: how many files to make\n      num_lines: how many lines each file includes\n\n    Returns:\n      A pandas dataframe containing all the csv rows where the id is the index\n          row.\n    \"\"\"\n    ex_id = 0\n    dfs = []\n    for i in range(1, num_files + 1):\n      full_file_name = os.path.join(folder, filename + str(i) + '.csv')\n      with open(full_file_name, 'w') as f:\n        writer = csv.writer(f)\n        for r in range(num_lines):\n          writer.writerow([ex_id,\n                           random.choice(['red', 'blue', 'green']),\n                           random.randint(0, 100)])\n          ex_id += 1\n      dfs.append(pd.read_csv(\n          full_file_name,\n          names=['id', 'field1', 'field2'],\n          index_col='id',\n          header=None))\n    return pd.concat(dfs, axis=0, ignore_index=False)\n\n  @staticmethod\n  def _create_json_schema():\n    return [{'name': 'id', 'type': 'INTEGER'},      # unique id\n            {'name': 'field1', 'type': 'STRING'},   # random string\n            {'name': 'field2', 'type': 'INTEGER'}]  # random int\n\n\nclass TestBigQueryDataSet(unittest.TestCase):\n\n  def test_basics(self):\n    # Just run the init function. Expand when we have credentials in tests\n    BigQueryDataSet(table='a.b')\n    BigQueryDataSet(sql='SELECT * FROM myds.mytable')\n\n\nclass TestTransformedDataSet(unittest.TestCase):\n\n  def test_basics(self):\n    # Just run the init function.\n    TransformedDataSet('a*.gz')\n    TransformedDataSet(['a.gz', 'b.gz'])\n"
  },
  {
    "path": "tests/ml/facets_tests.py",
    "content": "# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nimport unittest\n\nimport pandas as pd\n\nfrom google.datalab.ml import FacetsOverview, FacetsDiveview\n\n\nclass TestFacets(unittest.TestCase):\n  \"\"\"Tests facets visualization components.\"\"\"\n\n  def _create_test_data(self):\n    data1 = [\n      {'num1': 1.2, 'weekday': 'Monday', 'occupation': 'software engineer'},\n      {'num1': 3.2, 'weekday': 'Tuesday', 'occupation': 'medical doctor'},\n    ]\n\n    data2 = [\n      {'num1': -2.8, 'weekday': 'Friday', 'occupation': 'musician'},\n    ]\n\n    data1 = pd.DataFrame(data1)\n    data2 = pd.DataFrame(data2)\n    return data1, data2\n\n  def test_overview_plot(self):\n    \"\"\"Tests overview.\"\"\"\n\n    data1, data2 = self._create_test_data()\n    output = FacetsOverview().plot({'data1': data1, 'data2': data2})\n    # Output is an html. Ideally we can parse the html and verify nodes, but since the html\n    # is output by a polymer component which is tested separately, we just verify\n    # minumum keywords.\n    self.assertIn(\"facets-overview\", output)\n    self.assertIn(\"<script>\", output)\n\n  def test_dive_plot(self):\n    \"\"\"Tests diveview.\"\"\"\n\n    data1, _ = self._create_test_data()\n    output = FacetsDiveview().plot(data1)\n\n    # Output is an html. Ideally we can parse the html and verify nodes, but since the html\n    # is output by a polymer component which is tested separately, we just verify\n    # minumum keywords.\n    self.assertIn(\"facets-dive\", output)\n    self.assertIn(\"<script>\", output)\n"
  },
  {
    "path": "tests/ml/metrics_tests.py",
    "content": "# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nimport unittest\n\nimport csv\nimport os\nimport random\nimport shutil\nimport tempfile\n\nfrom google.datalab.ml import Metrics\n\n\nclass TestMetrics(unittest.TestCase):\n  \"\"\"google.datalab.ml.Metrics Tests.\"\"\"\n\n  def setUp(self):\n    self._test_dir = tempfile.mkdtemp()\n\n  def tearDown(self):\n    shutil.rmtree(self._test_dir)\n\n  def test_accuracy(self):\n    \"\"\"test Metrics's accuracy().\"\"\"\n\n    dict_counts, dict_accuracy = self._create_classification_csv_files(\n        ['classification1.csv', 'classification2.csv'], 50)\n    metrics = Metrics.from_csv(os.path.join(self._test_dir, 'classification?.csv'),\n                               headers=['target', 'predicted', ''])\n    accuracy = metrics.accuracy()\n    dict_counts_from_results, dict_accuracy_from_results = {}, {}\n    for index, row in accuracy.iterrows():\n      dict_counts_from_results[row['target']] = row['count']\n      dict_accuracy_from_results[row['target']] = row['accuracy']\n\n    self.assertEqual(dict_counts, dict_counts_from_results)\n    self.assertEqual(dict_accuracy, dict_accuracy_from_results)\n\n  def test_precision_recall(self):\n    \"\"\"test Metrics's accuracy().\"\"\"\n\n    self._create_classification_csv_files_with_probs('color.csv', 500)\n    metrics = Metrics.from_csv(os.path.join(self._test_dir, 'color.csv'),\n                               headers=['target', 'blue', 'key'])\n    pr = metrics.precision_recall(10, 'blue')\n    self.assertEqual(10, len(pr))\n    # When threshold = 0.0 recall should be 1.0\n    self.assertAlmostEqual(1.0, pr[pr['threshold'] == 0.0]['recall'][0])\n    # Recall values should be desc ordered.\n    for i in range(9):\n      self.assertAlmostEqual(float(i) / 10, pr['threshold'][i])\n      self.assertGreater(pr['recall'][i], pr['recall'][i + 1])\n\n  def test_roc(self):\n    \"\"\"test Metrics's roc().\"\"\"\n\n    self._create_classification_csv_files_with_probs('color.csv', 500)\n    metrics = Metrics.from_csv(os.path.join(self._test_dir, 'color.csv'),\n                               headers=['target', 'blue', 'key'])\n    roc = metrics.roc(10, 'blue')\n    # note that roc includes both threshold 0.0 and 1.0.\n    self.assertEqual(11, len(roc))\n\n    # When threshold = 0.0 fpr and tpr should be 1.0\n    self.assertAlmostEqual(1.0, roc[roc['threshold'] == 0.0]['fpr'][0])\n    self.assertAlmostEqual(1.0, roc[roc['threshold'] == 0.0]['tpr'][0])\n\n    # When threshold = 1.0 fpr and tpr should be 0.0\n    self.assertAlmostEqual(0.0, roc[roc['threshold'] == 1.0]['fpr'][10])\n    self.assertAlmostEqual(0.0, roc[roc['threshold'] == 1.0]['tpr'][10])\n\n  def test_rmse(self):\n    \"\"\"test Metrics's accuracy().\"\"\"\n\n    truth = self._create_regression_csv_file()\n    metrics = Metrics.from_csv(os.path.join(self._test_dir, 'regression.csv'),\n                               headers=['key', 'target', 'predicted'])\n    rmse = metrics.rmse()\n    self.assertEqual(truth['rmse'], rmse)\n\n  def test_mae(self):\n    \"\"\"test Metrics's accuracy().\"\"\"\n\n    truth = self._create_regression_csv_file()\n    metrics = Metrics.from_csv(os.path.join(self._test_dir, 'regression.csv'),\n                               headers=['key', 'target', 'predicted'])\n    mae = metrics.mae()\n    self.assertEqual(truth['mae'], mae)\n\n  def test_percentile(self):\n    \"\"\"test Metrics's accuracy().\"\"\"\n\n    truth = self._create_regression_csv_file()\n    metrics = Metrics.from_csv(os.path.join(self._test_dir, 'regression.csv'),\n                               headers=['key', 'target', 'predicted'])\n    percentile50 = metrics.percentile_nearest(50)\n    self.assertEqual(truth['percentile50'], percentile50)\n    percentile90 = metrics.percentile_nearest(90)\n    self.assertEqual(truth['percentile90'], percentile90)\n\n  def _create_classification_csv_files(self, filenames, num_lines):\n    \"\"\"Makes classification csv data files.\"\"\"\n\n    dict_counts = {\n        'red': 0,\n        'blue': 0,\n        'green': 0,\n        '_all': 0,\n    }\n    dict_correct_counts = {\n        'red': 0,\n        'blue': 0,\n        'green': 0,\n        '_all': 0,\n    }\n    index = 0\n    for filename in filenames:\n      full_file_name = os.path.join(self._test_dir, filename)\n      with open(full_file_name, 'w') as f:\n        writer = csv.writer(f)\n        for r in range(num_lines):\n          target = random.choice(['red', 'blue', 'green'])\n          predicted = random.choice(['red', 'blue', 'green'])\n          dict_counts[target] += 1\n          dict_counts['_all'] += 1\n          if target == predicted:\n            dict_correct_counts[target] += 1\n            dict_correct_counts['_all'] += 1\n          index += 1\n          writer.writerow([target, predicted, index])\n\n    dict_accuracy = {\n        'red': float(dict_correct_counts['red']) / dict_counts['red'],\n        'blue': float(dict_correct_counts['blue']) / dict_counts['blue'],\n        'green': float(dict_correct_counts['green']) / dict_counts['green'],\n        '_all': float(dict_correct_counts['_all']) / dict_counts['_all'],\n    }\n    return dict_counts, dict_accuracy\n\n  def _create_classification_csv_files_with_probs(self, filename, num_lines):\n    \"\"\"Makes classification csv data files.\"\"\"\n\n    index = 0\n    full_file_name = os.path.join(self._test_dir, filename)\n    with open(full_file_name, 'w') as f:\n      writer = csv.writer(f)\n      for r in range(num_lines):\n        target = random.choice(['red', 'blue', 'green'])\n        prob = random.uniform(0, 1)\n        writer.writerow([target, prob, index])\n\n  def _create_regression_csv_file(self):\n    \"\"\"Makes a single regression csv data file.\"\"\"\n\n    full_file_name = os.path.join(self._test_dir, 'regression.csv')\n    with open(full_file_name, 'w') as f:\n      writer = csv.writer(f)\n      writer.writerow([1, 12.4, 15.4])\n      writer.writerow([2, 20.1, 16.1])\n      writer.writerow([3, 10.0, 10.0])\n      writer.writerow([4, 0, 0])\n\n    # rmse = sqrt(((12.4-15.4)^2 + (20.1-16.1)^2 + 0 + 0) / 4) = 2.5\n    # mae = ((15.4-12.4) + (20.1-16.1) + 0 + 0) / 4 = 1.75\n    return {'rmse': 2.5, 'mae': 1.75, 'percentile50': 3.0, 'percentile90': 4.0}\n"
  },
  {
    "path": "tests/ml/summary_tests.py",
    "content": "# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nimport unittest\n\nimport os\nimport pandas as pd\nimport shutil\nimport tensorflow as tf\nimport tempfile\n\nfrom google.datalab.ml import Summary\n\n\nclass TestSummary(unittest.TestCase):\n  \"\"\"Tests google.datalab.ml.Summary class.\"\"\"\n\n  def setUp(self):\n    self._test_dir = tempfile.mkdtemp()\n    self._create_events()\n\n  def tearDown(self):\n    shutil.rmtree(self._test_dir)\n\n  def _create_events(self):\n    # This is for suppressing TF warnings in the unit-test output of the form \"The TensorFlow\n    # library wasn't compiled to use SSE4.2/AVX instructions...\"\n    # TODO(rajivpb): Remove if this is no longer necessary.\n    os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'\n    with tf.Session(graph=tf.Graph()) as sess:\n      del os.environ['TF_CPP_MIN_LOG_LEVEL']\n      # Just making sure that this is unset so that os.environ is as before\n      self.assertIsNone(os.environ.get('TF_CPP_MIN_LOG_LEVEL'))\n      train_num = tf.placeholder(dtype=tf.float32, shape=[])\n      eval_num1 = tf.multiply(train_num, 2)\n      eval_num2 = tf.add(eval_num1, 10)\n      train_summary = tf.summary.scalar('train_num', train_num)\n      eval_summary1 = tf.summary.scalar('eval_num1', eval_num1)\n      eval_summary2 = tf.summary.scalar('eval_num2', eval_num2)\n      train_writer = tf.summary.FileWriter(os.path.join(self._test_dir, 'train'), sess.graph)\n      eval_writer = tf.summary.FileWriter(os.path.join(self._test_dir, 'train', 'eval'), sess.graph)\n      for i in range(10):\n        t, evr1, evr2 = sess.run(\n            [train_summary, eval_summary1, eval_summary2], feed_dict={train_num: i + 1})\n        train_writer.add_summary(t, i)\n        eval_writer.add_summary(t, i)\n        eval_writer.add_summary(evr1, i)\n        eval_writer.add_summary(evr2, i)\n      train_writer.close()\n      eval_writer.close()\n\n  def test_list_events(self):\n    \"\"\"Tests list_events().\"\"\"\n\n    train_dir = os.path.join(self._test_dir, 'train')\n    eval_dir = os.path.join(self._test_dir, 'train', 'eval')\n    summary = Summary(train_dir)\n    events_dict = summary.list_events()\n    expected_events_dict = {\n      'train_num': {train_dir, eval_dir},\n      'eval_num1': {eval_dir},\n      'eval_num2': {eval_dir},\n    }\n\n    self.assertEqual(expected_events_dict, events_dict)\n\n  def test_get_events(self):\n    \"\"\"Tests get_events().\"\"\"\n\n    train_dir = os.path.join(self._test_dir, 'train')\n    eval_dir = os.path.join(self._test_dir, 'train', 'eval')\n    summary = Summary(train_dir)\n    events_list = summary.get_events(['train_num', 'eval_num1'])\n\n    self.assertEqual(set(events_list[0].keys()), {train_dir, eval_dir})\n    self.assertEqual(set(events_list[1].keys()), {eval_dir})\n\n    df = events_list[0][train_dir]\n    self.assertEqual(list(range(0, 10)), df['step'].tolist())\n    self.assertEqual(list(range(1, 11)), df['value'].tolist())\n    self.assertIsInstance(df['time'][0], pd.Timestamp)\n\n    df = events_list[1][eval_dir]\n    self.assertEqual(list(range(0, 10)), df['step'].tolist())\n    self.assertEqual(list(range(2, 22, 2)), df['value'].tolist())\n\n  def test_plot_events(self):\n    \"\"\"Tests plot_events().\"\"\"\n\n    train_dir = os.path.join(self._test_dir, 'train')\n    summary = Summary(train_dir)\n    # Call the function and make sure no exception.\n    summary.plot('eval_num2')\n    summary.plot(['train_num', 'eval_num2', 'eval_num2'])\n"
  },
  {
    "path": "tests/ml/tensorboard_tests.py",
    "content": "# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nimport unittest\n\n\nfrom google.datalab.ml import TensorBoard\n\n\nclass TestTensorboard(unittest.TestCase):\n  def test_tensorboard(self):\n    df = TensorBoard.list()\n    if not df.empty:\n      for pid in df['pid']:\n        TensorBoard.stop(int(pid))\n\n    TensorBoard.start('./a')\n    TensorBoard.start('./b')\n    df = TensorBoard.list()\n    self.assertEqual(2, len(df))\n    self.assertEqual(set(df['logdir']), {'./a', './b'})\n    for pid in df['pid']:\n      TensorBoard.stop(pid)\n\n    # It seems on travis psutil.kill doesn't work. The following passes\n    # on my workstation but not travis. Disable for now.\n    # df = TensorBoard.list()\n    # self.assertTrue(df.empty)\n"
  },
  {
    "path": "tests/ml_workbench/__init__.py",
    "content": ""
  },
  {
    "path": "tests/ml_workbench/all_tests.py",
    "content": "# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\"\"\"Test the code_free_ml package\n\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import print_function\n\nimport os\nimport subprocess\nimport six\nimport unittest\n\n\nclass RunTestScript(unittest.TestCase):\n  \"\"\"Makes a subprocess call to the test script.\n\n  Note that we cannot simply install the mltoolbox package and run each step\n  as it is designed to run as a sample/script, not as a module.\n  \"\"\"\n  def __init__(self, *args, **kwargs):\n    super(RunTestScript, self).__init__(*args, **kwargs)\n\n    # Path to the test script.\n    self._root_paths = [\n        os.path.abspath(os.path.join(os.path.dirname(__file__),\n                        '..', '..', 'solutionbox', 'ml_workbench', 'test_tensorflow')),\n        os.path.abspath(os.path.join(os.path.dirname(__file__),\n                        '..', '..', 'solutionbox', 'ml_workbench', 'test_xgboost')),\n    ]\n\n  @unittest.skipIf(not six.PY2, 'Python 2 is required')\n  def test_local(self):\n    \"\"\"Run some of the code_free_ml tests.\n\n    Tests that use GCS services like GCS or BigQuery are not ran.\n    \"\"\"\n    for root_path in self._root_paths:\n      cmd = 'bash %s' % os.path.join(root_path, 'run_all.sh')\n      subprocess.check_call(cmd, cwd=root_path, shell=True)\n"
  },
  {
    "path": "tests/mltoolbox_structured_data/__init__.py",
    "content": "# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n"
  },
  {
    "path": "tests/mltoolbox_structured_data/dl_interface_tests.py",
    "content": "# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\"\"\"Test the datalab interface functions.\n\nNote that the calls to do analysis, training, and prediction are all mocked.\n\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import print_function\n\nimport os\nimport sys\n\n# Set up the path so that we can import local packages.\nsys.path.append(\n    os.path.abspath(os.path.join(os.path.dirname(__file__),\n                    '../../solutionbox/structured_data/')))  # noqa\n\nfrom test_mltoolbox.test_package_functions import *  # noqa\n"
  },
  {
    "path": "tests/mltoolbox_structured_data/sd_e2e_tests.py",
    "content": "# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\"\"\"Test the structured data package e2e locally.\n\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import print_function\n\nimport logging\nimport os\nimport six\nimport sys\nimport unittest\n\n# Set up the path so that we can import local packages.\nsys.path.append(\n    os.path.abspath(os.path.join(os.path.dirname(__file__),\n                    '../../solutionbox/structured_data/')))\n\nimport test_mltoolbox.test_datalab_e2e as e2e  # noqa\n\n\n@unittest.skipIf(not six.PY2, 'Python 2 is required')\nclass TestLinearRegression(e2e.TestLinearRegression):\n  \"\"\"Test linear regression works e2e locally.\n  \"\"\"\n  def __init__(self, *args, **kwargs):\n    super(TestLinearRegression, self).__init__(*args, **kwargs)\n\n    # Don't print debugging info\n    self._logger.setLevel(logging.INFO)\n"
  },
  {
    "path": "tests/mltoolbox_structured_data/traininglib_tests.py",
    "content": "# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\nfrom __future__ import absolute_import\n\nimport logging\nimport os\nimport six\nimport sys\nimport unittest\n\n# Set up the path so that we can import local packages.\nsys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__),\n                                             '../../solutionbox/structured_data/')))  # noqa\n\nimport test_mltoolbox.test_sd_trainer as sdtraining\n\n\n@unittest.skipIf(not six.PY2, 'Python 2 is required')\nclass TestCoreTrainingLib(sdtraining.TestTrainer):\n  \"\"\"Wraps the training tests in the structured data package.\n\n  Four problems/models are built:\n    regression + dnn model\n    regression + linear model\n    classification + dnn model\n    classification + linear model\n\n  These tests take about 30 seconds to run.\n  \"\"\"\n\n  def __init__(self, *args, **kwargs):\n    super(TestCoreTrainingLib, self).__init__(*args, **kwargs)\n\n    # Test that training works, not that the model is good.\n    self._max_steps = 50\n    self._check_model_fit = False\n\n    # Don't print debugging info as no other test does.\n    self._logger.setLevel(logging.INFO)\n"
  },
  {
    "path": "tests/mlworkbench_magic/__init__.py",
    "content": "# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n"
  },
  {
    "path": "tests/mlworkbench_magic/archive_tests.py",
    "content": "# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Test MLToolbox Magic's archive functions.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import print_function\n\n\nimport os\nimport shutil\nimport subprocess\nimport tempfile\nimport unittest\n\nimport google.datalab.contrib.mlworkbench._archive as _archive\n\n\nclass TestArchive(unittest.TestCase):\n  \"\"\"Tests for untar-ing files\"\"\"\n\n  def setUp(self):\n    self._root_folder = tempfile.mkdtemp()\n\n    # Make two files to tar/compress\n    self._src_folder = tempfile.mkdtemp(dir=self._root_folder)\n    self._filename1 = 'file1.txt'\n    self._filename2 = 'file2.txt'\n    with open(os.path.join(self._src_folder, self._filename1), 'w') as f:\n      f.write('This is file 1')\n    with open(os.path.join(self._src_folder, self._filename2), 'w') as f:\n      f.write('and this is file 2')\n\n  def tearDown(self):\n    shutil.rmtree(self._root_folder)\n\n  def test_extract_archive_targz(self):\n    \"\"\"Tests extracting tar.gz files.\"\"\"\n\n    # Make a tar.gz file\n    archive_path = os.path.join(self._root_folder, 'test.tar.gz')\n    cmd = ['tar', '-czf', archive_path, '-C', self._src_folder, self._filename1, self._filename2]\n    subprocess.check_call(cmd)\n\n    # Undo it\n    dest = os.path.join(self._root_folder, 'output')\n    _archive.extract_archive(archive_path, dest)\n\n    expected_file1 = os.path.join(dest, self._filename1)\n    expected_file2 = os.path.join(dest, self._filename2)\n    self.assertTrue(os.path.isfile(expected_file1))\n    self.assertTrue(os.path.isfile(expected_file2))\n\n    with open(expected_file2, 'r') as f:\n      file_contents = f.read()\n    self.assertTrue(file_contents, 'and this is file2')\n\n  def test_extract_archive_tar(self):\n    \"\"\"Tests extracting tar.gz files.\"\"\"\n\n    # Make a tar.gz file\n    archive_path = os.path.join(self._root_folder, 'test.tar')\n    cmd = ['tar', '-cf', archive_path, '-C', self._src_folder, self._filename1, self._filename2]\n    subprocess.check_call(cmd)\n\n    # Undo it\n    dest = os.path.join(self._root_folder, 'output')\n    _archive.extract_archive(archive_path, dest)\n\n    expected_file1 = os.path.join(dest, self._filename1)\n    expected_file2 = os.path.join(dest, self._filename2)\n    self.assertTrue(os.path.isfile(expected_file1))\n    self.assertTrue(os.path.isfile(expected_file2))\n\n    with open(expected_file2, 'r') as f:\n      file_contents = f.read()\n    self.assertTrue(file_contents, 'and this is file2')\n\n\nif __name__ == '__main__':\n    unittest.main()\n"
  },
  {
    "path": "tests/mlworkbench_magic/explainer_tests.py",
    "content": "# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\"\"\"Integration Tests of PredictionExplainer.\"\"\"\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nimport unittest\nfrom PIL import Image\nimport logging\nimport mock\nimport numpy as np\nimport os\nimport pandas as pd\nimport shutil\nimport six\nfrom six.moves.urllib.request import urlopen\nimport tempfile\nimport sys\n\n\n# import Python so we can mock the parts we need to here.\nimport IPython.core.display\nimport IPython.core.magic\n\nfrom google.datalab.contrib.mlworkbench import PredictionExplainer\n\n\ndef noop_decorator(func):\n  return func\n\n\nIPython.core.magic.register_line_cell_magic = noop_decorator\nIPython.core.magic.register_line_magic = noop_decorator\nIPython.core.magic.register_cell_magic = noop_decorator\nIPython.core.display.HTML = lambda x: x\nIPython.core.display.JSON = lambda x: x\nIPython.get_ipython = mock.Mock()\nIPython.get_ipython().user_ns = {}\n\nimport google.datalab.contrib.mlworkbench.commands._ml as mlmagic  # noqa\n\n\nclass TestMLExplainer(unittest.TestCase):\n  \"\"\"Integration tests of PredictionExplainer\"\"\"\n\n  def setUp(self):\n    self._logger = logging.getLogger('TestExplainerLogger')\n    self._logger.setLevel(logging.DEBUG)\n    if not self._logger.handlers:\n      self._logger.addHandler(logging.StreamHandler(stream=sys.stdout))\n\n    self._code_path = mlmagic.DEFAULT_PACKAGE_PATH\n    mlmagic.DEFAULT_PACKAGE_PATH = os.path.abspath(\n        os.path.join(os.path.dirname(__file__), '../../solutionbox/ml_workbench/tensorflow'))\n    self._test_dir = tempfile.mkdtemp()\n\n  def tearDown(self):\n    mlmagic.DEFAULT_PACKAGE_PATH = self._code_path\n    shutil.rmtree(self._test_dir)\n\n  def _create_tabular_test_data(self):\n    \"\"\"Create tabular model with text.\"\"\"\n\n    test_data = \"\"\"1,5.0,monday,word1 word2 word3,true\n    2,3.2,tuesday,word1 word3,true\n    3,-1.1,friday,word1,false\"\"\"\n    train_csv = os.path.join(self._test_dir, 'train.csv')\n    with open(train_csv, 'w') as f:\n      f.write(test_data)\n\n    df = pd.read_csv(train_csv, names=['key', 'num', 'weekday', 'garbage', 'target'])\n    analyze_dir = os.path.join(self._test_dir, 'analysistab')\n    train_dir = os.path.join(self._test_dir, 'traintab')\n\n    mlmagic.ml(\n        line='dataset create',\n        cell=\"\"\"\\\n            format: csv\n            name: mytabular\n            schema:\n                - name: key\n                  type: INTEGER\n                - name: num\n                  type: FLOAT\n                - name: weekday\n                  type: STRING\n                - name: garbage\n                  type: STRING\n                - name: target\n                  type: STRING\n            train: %s\n            eval: %s\"\"\" % (train_csv, train_csv))\n\n    mlmagic.ml(\n        line='analyze',\n        cell=\"\"\"\\\n            output: %s\n            data: mytabular\n            features:\n              key:\n                transform: key\n              num:\n                transform: scale\n              weekday:\n                transform: one_hot\n              garbage:\n                transform: bag_of_words\n              target:\n                transform: target\"\"\" % (analyze_dir))\n\n    mlmagic.ml(\n        line='train',\n        cell=\"\"\"\\\n            output: %s\n            analysis: %s\n            data: mytabular\n            notb: true\n            model_args:\n              model: linear_classification\n              top-n: 0\n              max-steps: 300\"\"\" % (train_dir, analyze_dir))\n    return df\n\n  def _create_text_test_data(self):\n    \"\"\"Create text model.\"\"\"\n\n    test_data = \"\"\"1,sour green round,lime\n    2,melon green long,cucumber\n    3,sweet round red,apple\"\"\"\n    train_csv = os.path.join(self._test_dir, 'train.csv')\n    with open(train_csv, 'w') as f:\n      f.write(test_data)\n\n    analyze_dir = os.path.join(self._test_dir, 'analysistxt')\n    train_dir = os.path.join(self._test_dir, 'traintxt')\n\n    mlmagic.ml(\n        line='dataset create',\n        cell=\"\"\"\\\n            format: csv\n            name: mytext\n            schema:\n                - name: key\n                  type: INTEGER\n                - name: text\n                  type: STRING\n                - name: target\n                  type: STRING\n            train: %s\n            eval: %s\"\"\" % (train_csv, train_csv))\n\n    mlmagic.ml(\n        line='analyze',\n        cell=\"\"\"\\\n            output: %s\n            data: mytext\n            features:\n              key:\n                transform: key\n              text:\n                transform: bag_of_words\n              target:\n                transform: target\"\"\" % (analyze_dir))\n\n    mlmagic.ml(\n        line='train',\n        cell=\"\"\"\\\n            output: %s\n            analysis: %s\n            data: mytext\n            notb: true\n            model_args:\n              model: linear_classification\n              top-n: 0\n              max-steps: 300\"\"\" % (train_dir, analyze_dir))\n\n  def _create_image_test_data(self):\n    image_path1 = os.path.join(self._test_dir, 'img1.jpg')\n    image_path2 = os.path.join(self._test_dir, 'img2.jpg')\n    image_path3 = os.path.join(self._test_dir, 'img3.jpg')\n    Image.new('RGB', size=(128, 128), color=(155, 211, 64)).save(image_path1, \"JPEG\")\n    Image.new('RGB', size=(64, 64), color=(111, 21, 86)).save(image_path2, \"JPEG\")\n    Image.new('RGB', size=(16, 16), color=(255, 21, 1)).save(image_path3, \"JPEG\")\n    test_data = \"\"\"1,1.2,word1 word2,%s,true\n2,3.2,word2 word3,%s,false\n5,-2.1,word3 word4,%s,true\"\"\" % (image_path1, image_path2, image_path3)\n\n    train_csv = os.path.join(self._test_dir, 'train.csv')\n    with open(train_csv, 'w') as f:\n      f.write(test_data)\n\n    analyze_dir = os.path.join(self._test_dir, 'analysisimg')\n    transform_dir = os.path.join(self._test_dir, 'transformimg')\n    train_dir = os.path.join(self._test_dir, 'trainimg')\n\n    # Download inception checkpoint. Note that gs url doesn't work because\n    # we may not have gcloud signed in when running the test.\n    url = ('https://storage.googleapis.com/cloud-ml-data/img/' +\n           'flower_photos/inception_v3_2016_08_28.ckpt')\n    checkpoint_path = os.path.join(self._test_dir, \"checkpoint\")\n    response = urlopen(url)\n    with open(checkpoint_path, 'wb') as f:\n      f.write(response.read())\n\n    mlmagic.ml(\n        line='dataset create',\n        cell=\"\"\"\\\n            format: csv\n            name: myds\n            schema:\n              - name: key\n                type: INTEGER\n              - name: num\n                type: FLOAT\n              - name: text\n                type: STRING\n              - name: img_url\n                type: STRING\n              - name: target\n                type: STRING\n            train: %s\n            eval: %s\"\"\" % (train_csv, train_csv))\n\n    mlmagic.ml(\n        line='analyze',\n        cell=\"\"\"\\\n            output: %s\n            data: myds\n            features:\n              key:\n                transform: key\n              num:\n                transform: scale\n              text:\n                transform: bag_of_words\n              img_url:\n                transform: image_to_vec\n                checkpoint: %s\n              target:\n                transform: target\"\"\" % (analyze_dir, checkpoint_path))\n\n    mlmagic.ml(\n        line='transform',\n        cell=\"\"\"\\\n            output: %s\n            analysis: %s\n            data: myds\"\"\" % (transform_dir, analyze_dir))\n\n    mlmagic.ml(\n        line='dataset create',\n        cell=\"\"\"\\\n            format: transformed\n            name: transformed_ds\n            train: %s/train-*\n            eval: %s/eval-*\"\"\" % (transform_dir, transform_dir))\n\n    mlmagic.ml(\n        line='train',\n        cell=\"\"\"\\\n            output: %s\n            analysis: %s\n            data: transformed_ds\n            notb: true\n            model_args:\n              model: linear_classification\n              top-n: 0\n              max-steps: 200\"\"\" % (train_dir, analyze_dir))\n\n  @unittest.skipIf(not six.PY2, 'Integration test that invokes mlworkbench with DataFlow.')\n  def test_text_explainer(self):\n    \"\"\"Test text explainer.\"\"\"\n\n    self._logger.debug('Starting text explainer test.')\n    self._create_text_test_data()\n    explainer = PredictionExplainer(os.path.join(self._test_dir, 'traintxt', 'model'))\n    exp_instance = explainer.explain_text(['apple', 'lime', 'cucumber'], '4,green long')\n    apple = exp_instance.as_list(label=0)\n    self.assertEqual(len(apple), 2)\n    for word, score in apple:\n      # \"green\" and \"long\" are both negative to \"apple\"\n      self.assertLess(score, 0.0)\n\n    cucumber = exp_instance.as_list(label=2)\n    self.assertEqual(len(cucumber), 2)\n    for word, score in cucumber:\n      # \"green\" and \"long\" are both positive to \"cucumber\"\n      self.assertGreater(score, 0.0)\n\n  @unittest.skipIf(not six.PY2, 'Integration test that invokes mlworkbench with DataFlow.')\n  def test_image_explainer(self):\n    \"\"\"Test image explainer.\"\"\"\n\n    self._logger.debug('Starting image explainer test.')\n    self._create_image_test_data()\n    explainer = PredictionExplainer(os.path.join(self._test_dir, 'trainimg', 'model'))\n    exp_instance = explainer.explain_image(\n        ['true', 'false'],\n        '4,2.0,word2 word1,%s' % os.path.join(self._test_dir, 'img1.jpg'),\n        num_samples=50)\n\n    for i in range(2):\n      image, mask = exp_instance.get_image_and_mask(i, positive_only=False, num_features=3)\n      # image's dimension is length*width*channel\n      self.assertEqual(len(np.asarray(image).shape), 3)\n      # mask's dimension is length*width\n      self.assertEqual(len(np.asarray(mask).shape), 2)\n\n  @unittest.skipIf(not six.PY2, 'Integration test that invokes mlworkbench with DataFlow.')\n  def test_image_prober(self):\n    \"\"\"Test image explainer.\"\"\"\n\n    self._logger.debug('Starting image prober test.')\n    self._create_image_test_data()\n    explainer = PredictionExplainer(os.path.join(self._test_dir, 'trainimg', 'model'))\n    raw_image, grads_vizs = explainer.probe_image(\n        ['true', 'false'],\n        '4,2.0,word2 word1,%s' % os.path.join(self._test_dir, 'img1.jpg'),\n        num_scaled_images=5,\n        top_percent=20)\n    self.assertEqual((299, 299, 3), np.asarray(raw_image).shape)\n\n    for im in grads_vizs:\n      self.assertEqual((299, 299, 3), np.asarray(im).shape)\n      arr = np.asarray(im)\n      arr = arr.reshape(-1)\n      self.assertGreater(float((arr == 0).sum()) / len(arr), 0.79)\n\n  @unittest.skipIf(not six.PY2, 'Integration test that invokes mlworkbench with DataFlow.')\n  def test_tabular_explainer(self):\n    \"\"\"Test tabular explainer.\"\"\"\n\n    self._logger.debug('Starting tabular explainer test.')\n    train_df = self._create_tabular_test_data()\n\n    explainer = PredictionExplainer(os.path.join(self._test_dir, 'traintab', 'model'))\n    exp_instance = explainer.explain_tabular(train_df, ['true', 'false'], '8,-1.0,tuesday,word3',\n                                             num_features=5)\n    for i in range(2):\n      label_data = exp_instance.as_list(label=i)\n      # There should be 2 entries. One for categorical (\"weekday\") and one for numeric (\"num\")\n      # label_data should look like:\n      #    [\n      #      (\"weekday=tuesday\", 0.02),\n      #      (\"num > 1.0\", 0.03),\n      #    ]\n      self.assertEqual(2, len(label_data))\n      keys = [x[0] for x in label_data]\n      self.assertIn('weekday=tuesday', keys)\n      keys.remove('weekday=tuesday')\n      self.assertTrue('num' in keys[0])\n"
  },
  {
    "path": "tests/mlworkbench_magic/local_predict_tests.py",
    "content": "# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Test MLWorkbench local predict\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import print_function\n\n\nimport base64\nimport csv\nfrom io import BytesIO\nimport json\nimport logging\nimport os\nimport pandas as pd\nfrom PIL import Image\nimport shutil\nimport six\nimport sys\nimport tempfile\nimport tensorflow as tf\nfrom tensorflow.python.saved_model import signature_constants\nimport unittest\n\n\nimport google.datalab.contrib.mlworkbench as mlw\n\n\nclass TestLocalPredictions(unittest.TestCase):\n  \"\"\"Tests for checking the format between the schema and features files.\"\"\"\n\n  def setUp(self):\n    self._logger = logging.getLogger('TestStructuredDataLogger')\n    self._logger.setLevel(logging.DEBUG)\n    if not self._logger.handlers:\n      self._logger.addHandler(logging.StreamHandler(stream=sys.stdout))\n\n    self._test_dir = tempfile.mkdtemp()\n\n  def tearDown(self):\n    shutil.rmtree(self._test_dir)\n\n  def _create_model(self, dir_name):\n    \"\"\"Create a simple model that takes 'key', 'num1', 'text1', 'img_url1' input.\"\"\"\n\n    def _decode_jpg(image):\n      img_buf = BytesIO()\n      Image.new('RGB', (16, 16)).save(img_buf, 'jpeg')\n      default_image_string = base64.urlsafe_b64encode(img_buf.getvalue())\n      image = tf.where(tf.equal(image, ''), default_image_string, image)\n      image = tf.decode_base64(image)\n      image = tf.image.decode_jpeg(image, channels=3)\n      image = tf.reshape(image, [-1])\n      image = tf.reduce_max(image)\n      return image\n\n    model_dir = tempfile.mkdtemp()\n    with tf.Session(graph=tf.Graph()) as sess:\n      record_defaults = [\n          tf.constant([0], dtype=tf.int64),\n          tf.constant([0.0], dtype=tf.float32),\n          tf.constant([''], dtype=tf.string),\n          tf.constant([''], dtype=tf.string),\n      ]\n      placeholder = tf.placeholder(dtype=tf.string, shape=(None,), name='csv_input_placeholder')\n      key_tensor, num_tensor, text_tensor, img_tensor = tf.decode_csv(placeholder, record_defaults)\n      text_tensor = tf.string_to_number(text_tensor, tf.float32)\n      img_tensor = tf.map_fn(_decode_jpg, img_tensor, back_prop=False, dtype=tf.uint8)\n      img_tensor = tf.cast(img_tensor, tf.float32)\n      stacked = tf.stack([num_tensor, text_tensor, img_tensor])\n      min_tensor = tf.reduce_min(stacked, axis=0)\n      max_tensor = tf.reduce_max(stacked, axis=0)\n\n      predict_input_tensor = tf.saved_model.utils.build_tensor_info(placeholder)\n      predict_signature_inputs = {\"input\": predict_input_tensor}\n      predict_output_tensor1 = tf.saved_model.utils.build_tensor_info(min_tensor)\n      predict_output_tensor2 = tf.saved_model.utils.build_tensor_info(max_tensor)\n      predict_key_tensor = tf.saved_model.utils.build_tensor_info(key_tensor)\n      predict_signature_outputs = {\n        'key': predict_key_tensor,\n        'var1': predict_output_tensor1,\n        'var2': predict_output_tensor2\n      }\n      predict_signature_def = (\n          tf.saved_model.signature_def_utils.build_signature_def(\n              predict_signature_inputs, predict_signature_outputs,\n              tf.saved_model.signature_constants.PREDICT_METHOD_NAME\n          )\n      )\n      signature_def_map = {\n          signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY: predict_signature_def\n      }\n      model_dir = os.path.join(self._test_dir, dir_name)\n      builder = tf.saved_model.builder.SavedModelBuilder(model_dir)\n      builder.add_meta_graph_and_variables(\n          sess, [tf.saved_model.tag_constants.SERVING],\n          signature_def_map=signature_def_map)\n      builder.save(False)\n\n    return model_dir\n\n  def _create_test_data(self, embedding_images=False, missing_values=False, csv_data=False):\n    image_path1 = os.path.join(self._test_dir, 'img1.jpg')\n    image_path2 = os.path.join(self._test_dir, 'img2.jpg')\n    image_path3 = os.path.join(self._test_dir, 'img3.jpg')\n    Image.new('RGB', size=(128, 128), color=(155, 211, 64)).save(image_path1, \"JPEG\")\n    Image.new('RGB', size=(64, 64), color=(111, 21, 86)).save(image_path2, \"JPEG\")\n    Image.new('RGB', size=(16, 16), color=(255, 21, 1)).save(image_path3, \"JPEG\")\n\n    data = [\n        {'key': 1, 'num1': 4.1, 'text1': '32', 'img_url1': image_path1},\n        {'key': 2, 'num1': 5.2, 'text1': '18', 'img_url1': image_path2},\n        {'key': 5, 'num1': -12.0, 'text1': '22', 'img_url1': image_path3},\n    ]\n    if embedding_images:\n      for d in data:\n        with open(d['img_url1'], 'rb') as f:\n          d['img_url1'] = base64.urlsafe_b64encode(f.read()).decode('ascii')\n\n    if missing_values:\n      del data[0]['num1']\n      del data[1]['img_url1']\n\n    if csv_data:\n      csv_lines = []\n      for d in data:\n        buf = six.StringIO()\n        writer = csv.DictWriter(buf, fieldnames=['key', 'num1', 'text1', 'img_url1'])\n        writer.writerow(d)\n        csv_lines.append(buf.getvalue().rstrip())\n      data = csv_lines\n\n    return data\n\n  def _validate_results(self, df, with_source, show_image):\n    expected_columns = set(['key', 'var1', 'var2'])\n    if with_source:\n      expected_columns = expected_columns.union(['num1', 'text1', 'img_url1'])\n      if show_image:\n        expected_columns.add('img_url1_image')\n    self.assertEqual(expected_columns, set(df.columns))\n    self.assertEqual([1, 2, 5], df['key'].tolist())\n    self.assertEqual(3, len(df.index))\n\n  def test_predict(self):\n    \"\"\" Test prediction on a model which accepts CSV lines \"int64,float32,text,image_url\".\n    \"\"\"\n\n    model_dir = self._create_model('model1')\n    headers = ['key', 'num1', 'text1', 'img_url1']\n\n    # Test data being list of dict and list of csvlines, with and without missing values,\n    # show or not show images.\n    for missing_values in [True, False]:\n      for csv_data in [True, False]:\n        for with_source in [True, False]:\n          for show_image in [True, False]:\n            self._logger.debug('LocalPredict: ' +\n                               'missing_values=%s, csv_data=%s, with_source=%s, show_image=%s' %\n                               (missing_values, csv_data, with_source, show_image))\n          test_data = self._create_test_data(False, missing_values, csv_data)\n          df = mlw.get_prediction_results(\n              model_dir, test_data, headers, img_cols=['img_url1'], with_source=with_source,\n              show_image=show_image)\n          self._validate_results(df, with_source, show_image)\n\n    # Test data being dataframes, with and without missing values, and embedded images.\n    for missing_values in [True, False]:\n      self._logger.debug('LocalPredict: ' +\n                         'missing_values=%s, DataFrame' % missing_values)\n      test_data = self._create_test_data(True, missing_values, csv_data=False)\n      df_s = pd.DataFrame(test_data).fillna('')\n      df = mlw.get_prediction_results(model_dir, df_s, headers,\n                                      with_source=True, show_image=False)\n      self._validate_results(df, True, False)\n\n  def test_get_probs_for_labels(self):\n    \"\"\"Test get_probs_for_labels when top-n is set to non-zero (default).\"\"\"\n\n    prediction_data = [\n      {'predicted': 'daisy', 'probability': 0.8,\n       'predicted_2': 'rose', 'probability_2': 0.1,\n       'predicted_3': 'sunflower', 'probability_3': 0.05},\n      {'predicted': 'sunflower', 'probability': 0.9,\n       'predicted_2': 'daisy', 'probability_2': 0.01,\n       'predicted_3': 'rose', 'probability_3': 0.02},\n    ]\n    labels = ['daisy', 'rose', 'sunflower']\n    probs = mlw.get_probs_for_labels(labels, pd.DataFrame(prediction_data))\n    expected_probs = [\n      [0.8, 0.1, 0.05],\n      [0.01, 0.02, 0.9],\n    ]\n    self.assertEqual(expected_probs, probs)\n\n  def test_get_probs_for_labels_topn_0(self):\n    \"\"\"Test get_probs_for_labels when top-n is set to zero.\"\"\"\n\n    prediction_data = [\n      {'predicted': 'daisy', 'daisy': 0.8, 'rose': 0.1, 'sunflower': 0.05},\n      {'predicted': 'sunflower', 'sunflower': 0.9, 'daisy': 0.01, 'rose': 0.02}\n    ]\n    labels = ['daisy', 'rose', 'sunflower']\n    probs = mlw.get_probs_for_labels(labels, pd.DataFrame(prediction_data))\n    expected_probs = [\n      [0.8, 0.1, 0.05],\n      [0.01, 0.02, 0.9],\n    ]\n    self.assertEqual(expected_probs, probs)\n\n  def _validate_schema_file(self, output_dir):\n    with open(os.path.join(output_dir, 'predict_results_schema.json'), 'r') as f:\n      schema = json.loads(f.read())\n\n    expected_schema = [\n        {\"type\": \"INTEGER\", \"name\": \"key\"},\n        {\"type\": \"FLOAT\", \"name\": \"var1\"},\n        {\"type\": \"FLOAT\", \"name\": \"var2\"}\n    ]\n    self.assertEqual(expected_schema, schema)\n\n  def test_batch_predict(self):\n    \"\"\" Test batch prediction on a model which accepts CSV lines \"int64,float32,text,image_url\".\n    \"\"\"\n\n    self._logger.debug('Starting Local Batch Predict')\n    model_dir = self._create_model('model2')\n    test_data = self._create_test_data(embedding_images=True, missing_values=True, csv_data=True)\n    prediction_source = os.path.join(self._test_dir, 'prediction.csv')\n    output_dir = os.path.join(self._test_dir, 'prediction_output')\n    with open(prediction_source, 'w') as f:\n      f.write('\\n'.join(test_data))\n\n    # Test prediction output as csv file.\n    mlw.local_batch_predict(model_dir, prediction_source, output_dir, 'csv', batch_size=2)\n    self._validate_schema_file(output_dir)\n\n    prediction_results_file = os.path.join(output_dir, 'predict_results_prediction.csv')\n    df = pd.read_csv(prediction_results_file, header=None, names=['key', 'var1', 'var2'])\n    self.assertEqual(3, len(df.index))\n    self.assertEqual([1, 2, 5], list(df['key']))\n\n    # Test prediction output as json file.\n    mlw.local_batch_predict(model_dir, prediction_source, output_dir, 'json', batch_size=1)\n    self._validate_schema_file(output_dir)\n\n    prediction_results_file = os.path.join(output_dir, 'predict_results_prediction.json')\n    results = []\n    with open(prediction_results_file, 'r') as f:\n      for l in f:\n        results.append(json.loads(l))\n\n    self.assertEqual(3, len(results))\n    self.assertEqual([1, 2, 5], [x['key'] for x in results])\n\n\nif __name__ == '__main__':\n    unittest.main()\n"
  },
  {
    "path": "tests/mlworkbench_magic/ml_tests.py",
    "content": "# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\"\"\"Tests the \\%\\%ml magics functions without runing any jobs.\"\"\"\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nimport unittest\nimport mock\nimport os\n\n\n# import Python so we can mock the parts we need to here.\nimport IPython.core.display\nimport IPython.core.magic\n\n\ndef noop_decorator(func):\n  return func\n\n\nIPython.core.magic.register_line_cell_magic = noop_decorator\nIPython.core.magic.register_line_magic = noop_decorator\nIPython.core.magic.register_cell_magic = noop_decorator\nIPython.core.display.HTML = lambda x: x\nIPython.core.display.JSON = lambda x: x\nIPython.get_ipython = mock.Mock()\nIPython.get_ipython().user_ns = {}\n\nimport google.datalab.contrib.mlworkbench.commands._ml as mlmagic  # noqa\n\n\ndef find_key_value(arg_list, key, value):\n  \"\"\"Checks '--key value' is in arg_list.\"\"\"\n  for i in range(len(arg_list)):\n    if arg_list[i] == key and arg_list[i + 1] == value:\n      return True\n  return False\n\n\ndef find_key_endswith(arg_list, key, value):\n  \"\"\"Checks '--key prefix_<value>' is in arg_list.\"\"\"\n  for i in range(len(arg_list)):\n    if arg_list[i] == key and arg_list[i + 1].endswith(value):\n      return True\n  return False\n\n\ndef find_startswith_endswith(arg_list, key, value):\n  \"\"\"Checks '--<key>anything<value>' is in arg_list.\"\"\"\n  for i in range(len(arg_list)):\n    if arg_list[i].startswith(key) and arg_list[i].endswith(value):\n      return True\n  return False\n\n\nclass TestMLMagic(unittest.TestCase):\n\n  @mock.patch('google.datalab.contrib.mlworkbench._shell_process.run_and_monitor')\n  @mock.patch('subprocess.Popen')  # Because of the trainer help menu\n  def test_analyze_csv_local(self, popen_mock, run_and_monitor_mock):\n    mlmagic.ml(\n      line='dataset create',\n      cell=\"\"\"\\\n          format: csv\n          train: ./taxi/train.csv\n          eval: ./taxi/eval.csv\n          name: taxi_data\n          schema:\n              - name: unique_key\n                type: STRING\n              - name: fare\n                type: FLOAT\"\"\"\n    )\n    mlmagic.ml(\n        line='analyze',\n        cell=\"\"\"\\\n            output: my_out_dir\n            data: taxi_data\n            features: dummy_features\"\"\")\n    cmd_list = run_and_monitor_mock.call_args[0][0]\n    # cmd_list = [u'python', u'analyze.py', u'--output', 'path/my_out_dir',\n    #   u'--csv=path/file*.csv', u'--schema', u'/path/schema.json',\n    #   u'--features', u'path/features.json']\n\n    self.assertEqual('python', cmd_list[0])\n    self.assertEqual('analyze.py', cmd_list[1])\n    self.assertIn('--schema', cmd_list)\n    self.assertIn('--features', cmd_list)\n    self.assertTrue(find_key_endswith(cmd_list, '--output', 'my_out_dir'))\n    self.assertTrue(find_startswith_endswith(cmd_list, '--csv=', 'train.csv'))\n\n  @mock.patch('google.datalab.contrib.mlworkbench._shell_process.run_and_monitor')\n  @mock.patch('subprocess.Popen')  # Because of the trainer help menu\n  def test_transform_csv(self, popen_mock, run_and_monitor_mock):\n    mlmagic.ml(\n      line='dataset create',\n      cell=\"\"\"\\\n          format: csv\n          train: ./taxi/train.csv\n          eval: ./taxi/eval.csv\n          name: taxi_data\n          schema:\n              - name: unique_key\n                type: STRING\n              - name: fare\n                type: FLOAT\"\"\"\n    )\n    mlmagic.ml(\n        line='transform --shuffle --cloud',\n        cell=\"\"\"\\\n            output: my_out_dir\n            analysis: my_analyze_dir\n            batch_size: 123\n            data: taxi_data\n            cloud_config:\n              project_id: my_id\n              num_workers: 987\n              worker_machine_type: BLUE\n              job_name: RED\"\"\")\n    cmd_list = run_and_monitor_mock.call_args[0][0]\n    # cmd_list = [u'python', u'transform.py', u'--output', 'path/my_out_dir',\n    #   u'--analysis', 'path/my_analyze_dir', u'--prefix', 'my_prefix',\n    #   u'--shuffle', u'--batch-size', '100', u'--csv=/path/file*.csv'\n    #   ...\n    self.assertEqual('python', cmd_list[0])\n    self.assertEqual('transform.py', cmd_list[1])\n    self.assertIn('--shuffle', cmd_list)\n\n    self.assertTrue(find_key_endswith(cmd_list, '--output', 'my_out_dir'))\n    self.assertTrue(find_key_endswith(cmd_list, '--analysis', 'my_analyze_dir'))\n    self.assertTrue(find_key_value(cmd_list, '--prefix', 'train') or\n                    find_key_value(cmd_list, '--prefix', 'eval'))\n    self.assertTrue(find_key_value(cmd_list, '--batch-size', '123'))\n    self.assertTrue(find_startswith_endswith(cmd_list, '--csv=', 'train.csv') or\n                    find_startswith_endswith(cmd_list, '--csv=', 'eval.csv'))\n    self.assertTrue(find_key_value(cmd_list, '--project-id', 'my_id'))\n    self.assertTrue(find_key_value(cmd_list, '--num-workers', '987'))\n    self.assertTrue(find_key_value(cmd_list, '--worker-machine-type', 'BLUE'))\n    self.assertTrue(find_key_value(cmd_list, '--job-name', 'RED'))\n\n  @mock.patch('google.datalab.contrib.mlworkbench.commands._ml._show_job_link')\n  @mock.patch('google.datalab.ml.package_and_copy')\n  @mock.patch('google.datalab.ml.Job.submit_training')\n  @mock.patch('subprocess.Popen')  # Because of the trainer help menu\n  def test_train_csv(self, popen_mock, submit_training_mock,\n                     package_and_copy_mock, _show_job_link_mock):\n    mlmagic.ml(\n      line='dataset create',\n      cell=\"\"\"\\\n          format: transformed\n          train: ./taxi/train_tfrecord.tar.gz\n          eval: ./taxi/eval_tfrecord.tar.gz\n          name: taxi_data_transformed\"\"\"\n    )\n    mlmagic.ml(\n        line='train --cloud',\n        cell=\"\"\"\\\n            output: gs://my_out_dir\n            analysis: my_analyze_dir\n            data: $taxi_data_transformed\n            model_args:\n              key: value\n            cloud_config:\n              job_name: job1\n              project_id: id\"\"\")\n    job_request = submit_training_mock.call_args[0][0]\n\n    cmd_list = job_request['args']\n\n    self.assertEqual(job_request['project_id'], 'id')\n    self.assertEqual(job_request['job_dir'], 'gs://my_out_dir')\n    self.assertEqual(job_request['python_module'], 'trainer.task')\n    self.assertEqual(job_request['package_uris'], ['gs://my_out_dir/staging/trainer.tar.gz'])\n\n    self.assertTrue(find_key_value(cmd_list, '--job-dir', 'gs://my_out_dir'))\n    self.assertTrue(find_key_endswith(cmd_list, '--analysis', 'my_analyze_dir'))\n    self.assertTrue(find_startswith_endswith(cmd_list, '--train=', 'train_tfrecord.tar.gz'))\n    self.assertTrue(find_startswith_endswith(cmd_list, '--eval=', 'eval_tfrecord.tar.gz'))\n    self.assertTrue(find_key_value(cmd_list, '--key', 'value'))\n\n  @mock.patch('google.datalab.contrib.mlworkbench.commands._ml._show_job_link')\n  @mock.patch('google.datalab.Context.default')\n  @mock.patch('google.datalab.ml.Job.submit_batch_prediction')\n  @mock.patch('subprocess.Popen')  # Because of the trainer help menu\n  def test_batch_predict_csv(self, popen_mock, submit_batch_prediction_mock,\n                             default_mock, _show_job_link_mock):\n    default_mock.return_value = mock.Mock(project_id='my_project_id')\n\n    mlmagic.ml(\n        line='batch_predict --cloud',\n        cell=\"\"\"\\\n            model: my_model.my_version\n            output: gs://output\n            format: json\n            batch_size: 10\n            data:\n              csv: %s\"\"\" % os.path.abspath(__file__))\n\n    job_args = submit_batch_prediction_mock.call_args[0][0]\n\n    self.assertEqual(job_args['input_paths'], [os.path.abspath(__file__)])\n    self.assertEqual(\n        job_args['version_name'],\n        'projects/my_project_id/models/my_model/versions/my_version')\n    self.assertEqual(job_args['output_path'], 'gs://output')\n    self.assertEqual(job_args['data_format'], 'TEXT')\n"
  },
  {
    "path": "tests/mlworkbench_magic/shell_process_tests.py",
    "content": "# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\n\"\"\"Test MLWorkbench shell process monitor\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import print_function\n\nimport logging\nimport os\nimport psutil\nimport six\nimport subprocess\nimport sys\nimport threading\nimport time\nimport unittest\n\nimport google.datalab.contrib.mlworkbench._shell_process as _shell_process\n\n\nclass TestShellProcess(unittest.TestCase):\n  \"\"\"Tests for process managements used in MLWorkbench magics.\"\"\"\n\n  def setUp(self):\n    self._logger = logging.getLogger('TestStructuredDataLogger')\n    self._logger.setLevel(logging.DEBUG)\n    if not self._logger.handlers:\n      self._logger.addHandler(logging.StreamHandler(stream=sys.stdout))\n\n  def test_process(self):\n    \"\"\" Test starting a process and have it depend on another process.\n\n    Steps:\n      1: process_to_wait is created with 10 seconds to live. It is assumed this\n         test will finish before then.\n      2: _shell_process.run_and_monitor() creates a worker process and a monitor\n         process.\n      3: The worker process prints \"exclude message\", \"include message1\".\n      4: This test wakes up from 1 sec sleep, kills process_to_wait.\n      5: The monitor process seeks process_to_wait is dead, and kills the worker.\n         Monitor process also ends after killing the worker.\n      6: This test wakes up from 1 sec sleep and checks the worker is dead. Also\n         checks the stdout message of the worker process is captured and filtered.\n    \"\"\"\n\n    # The process will do time.sleep(10) but it will be killed much earlier.\n    process_to_wait_args = ['python', '-c', 'import time; time.sleep(10)']\n    process_to_wait = subprocess.Popen(process_to_wait_args, env=os.environ)\n    self.assertIsNone(process_to_wait.poll())\n    self._logger.debug('TestProcess: Started a process %d which will be waited on.' %\n                       process_to_wait.pid)\n\n    # The worker process prints out 3 messages. \"exclude message\" should be filtered out.\n    # \"include message1\" should be redirected to stdout. \"include message2\" should not\n    # get a chance to output because the worker process should have been killed by\n    # monitor process by then.\n    worker_process_args = [\n        'python',\n        '-c',\n        'import time;import sys;print(\\'exclude message\\');print(\\'include message1\\');' +\n        'sys.stdout.flush();time.sleep(3);print(\\'include message2\\');sys.stdout.flush()'\n    ]\n\n    old_stdout = sys.stdout\n    buf = six.StringIO()\n    sys.stdout = buf\n    t = threading.Thread(target=_shell_process.run_and_monitor,\n                         args=(worker_process_args,\n                               process_to_wait.pid, lambda x: x.startswith('include')))\n    t.start()\n    time.sleep(1)\n\n    # The worker process should have been started by _shell_process.run_and_monitor.\n    # But because the process id is not available outside the function, we need to search\n    # all processes to find the one that has matching args.\n    process_to_monitor = None\n    for proc in psutil.process_iter():\n      if proc.is_running() and proc.cmdline() == worker_process_args:\n        process_to_monitor = proc\n        break\n\n    self.assertIsNotNone(process_to_monitor)\n    self._logger.debug('TestProcess: Started a worker process %d to be monitored on.' %\n                       process_to_monitor.pid)\n\n    self._logger.debug('TestProcess: killing process %d' % process_to_wait.pid)\n    process_to_wait.kill()\n    process_to_wait.wait()\n    time.sleep(1)\n    self.assertFalse(process_to_monitor.is_running())\n    self._logger.debug('TestProcess: process %d being monitored ' % process_to_monitor.pid +\n                       'was also killed successfully after waiting process was killed.')\n    sys.stdout = old_stdout\n\n    # Make sure stdout filter works.\n    self.assertEqual('include message1', buf.getvalue().rstrip())\n\n\nif __name__ == '__main__':\n    unittest.main()\n"
  },
  {
    "path": "tests/pipeline/__init__.py",
    "content": "# Copyright 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n"
  },
  {
    "path": "tests/pipeline/airflow_tests.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nimport google\nimport google.auth\nimport unittest\nimport mock\n\nfrom google.datalab.contrib.pipeline.airflow._airflow import Airflow\n\n\nclass TestCases(unittest.TestCase):\n\n  @staticmethod\n  def _create_context():\n      project_id = 'test'\n      creds = mock.Mock(spec=google.auth.credentials.Credentials)\n      return google.datalab.Context(project_id, creds)\n\n  @mock.patch('google.datalab.Context.default')\n  @mock.patch('google.datalab.storage.Bucket')\n  def test_deploy(self, mock_bucket_class, mock_default_context):\n      context = TestCases._create_context()\n      mock_default_context.return_value = context\n\n      # Happy path\n      test_airflow = Airflow('foo_bucket', 'foo_path')\n      test_airflow.deploy('foo_name', 'foo_dag_string')\n      mock_bucket_class.assert_called_with('foo_bucket')\n      mock_bucket_class.return_value.object.assert_called_with('foo_path/foo_name.py')\n      mock_bucket_class.return_value.object.return_value.write_stream.assert_called_with(\n          'foo_dag_string', 'text/plain')\n\n      # Only bucket\n      test_airflow = Airflow('foo_bucket')\n      test_airflow.deploy('foo_name', 'foo_dag_string')\n      mock_bucket_class.assert_called_with('foo_bucket')\n      mock_bucket_class.return_value.object.assert_called_with('foo_name.py')\n      mock_bucket_class.return_value.object.return_value.write_stream.assert_called_with(\n          'foo_dag_string', 'text/plain')\n\n      # Only bucket with path as '/'\n      test_airflow = Airflow('foo_bucket', '/')\n      test_airflow.deploy('foo_name', 'foo_dag_string')\n      mock_bucket_class.assert_called_with('foo_bucket')\n      mock_bucket_class.return_value.object.assert_called_with('/foo_name.py')\n      mock_bucket_class.return_value.object.return_value.write_stream.assert_called_with(\n          'foo_dag_string', 'text/plain')\n\n      # GCS dag location has additional parts\n      test_airflow = Airflow('foo_bucket', 'foo_path1/foo_path2')\n      test_airflow.deploy('foo_name', 'foo_dag_string')\n      mock_bucket_class.assert_called_with('foo_bucket')\n      mock_bucket_class.return_value.object.assert_called_with('foo_path1/foo_path2/foo_name.py')\n      mock_bucket_class.return_value.object.return_value.write_stream.assert_called_with(\n          'foo_dag_string', 'text/plain')\n"
  },
  {
    "path": "tests/pipeline/composer_api_tests.py",
    "content": "# Copyright 2018 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nimport unittest\nimport mock\n\nimport google.auth\nimport google.datalab.utils\nfrom google.datalab.contrib.pipeline.composer._api import Api\n\n\nclass TestCases(unittest.TestCase):\n\n  TEST_PROJECT_ID = 'test_project'\n\n  def validate(self, mock_http_request, expected_url, expected_args=None, expected_data=None,\n               expected_headers=None, expected_method=None):\n    url = mock_http_request.call_args[0][0]\n    kwargs = mock_http_request.call_args[1]\n    self.assertEquals(expected_url, url)\n    if expected_args is not None:\n      self.assertEquals(expected_args, kwargs['args'])\n    else:\n      self.assertNotIn('args', kwargs)\n    if expected_data is not None:\n      self.assertEquals(expected_data, kwargs['data'])\n    else:\n      self.assertNotIn('data', kwargs)\n    if expected_headers is not None:\n      self.assertEquals(expected_headers, kwargs['headers'])\n    else:\n      self.assertNotIn('headers', kwargs)\n    if expected_method is not None:\n      self.assertEquals(expected_method, kwargs['method'])\n    else:\n      self.assertNotIn('method', kwargs)\n\n  @mock.patch('google.datalab.Context.default')\n  @mock.patch('google.datalab.utils.Http.request')\n  def test_environment_details_get(self, mock_http_request, mock_context_default):\n    mock_context_default.return_value = TestCases._create_context()\n    Api.get_environment_details('ZONE', 'ENVIRONMENT')\n    self.validate(mock_http_request,\n                  'https://composer.googleapis.com/v1alpha1/projects/test_project/locations/ZONE/'\n                  'environments/ENVIRONMENT')\n\n  @staticmethod\n  def _create_context():\n    project_id = TestCases.TEST_PROJECT_ID\n    creds = mock.Mock(spec=google.auth.credentials.Credentials)\n    return google.datalab.Context(project_id, creds)\n"
  },
  {
    "path": "tests/pipeline/composer_tests.py",
    "content": "# Copyright 2018 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nimport unittest\nimport mock\n\nfrom google.datalab.contrib.pipeline.composer._composer import Composer\n\n\nclass TestCases(unittest.TestCase):\n\n  @mock.patch('google.datalab.Context.default')\n  @mock.patch('google.datalab.storage.Bucket')\n  @mock.patch('google.datalab.contrib.pipeline.composer._api.Api.get_environment_details')\n  def test_deploy(self, mock_environment_details, mock_bucket_class, mock_default_context):\n      # Happy path\n      mock_environment_details.return_value = {\n        'config': {\n          'gcsDagLocation': 'gs://foo_bucket/dags'\n        }\n      }\n      test_composer = Composer('foo_zone', 'foo_environment')\n      test_composer.deploy('foo_name', 'foo_dag_string')\n      mock_bucket_class.assert_called_with('foo_bucket')\n      mock_bucket_class.return_value.object.assert_called_with('dags/foo_name.py')\n      mock_bucket_class.return_value.object.return_value.write_stream.assert_called_with(\n          'foo_dag_string', 'text/plain')\n\n      # Only bucket with no path\n      mock_environment_details.return_value = {\n        'config': {\n          'gcsDagLocation': 'gs://foo_bucket'\n        }\n      }\n      test_composer = Composer('foo_zone', 'foo_environment')\n      test_composer.deploy('foo_name', 'foo_dag_string')\n      mock_bucket_class.assert_called_with('foo_bucket')\n      mock_bucket_class.return_value.object.assert_called_with('foo_name.py')\n      mock_bucket_class.return_value.object.return_value.write_stream.assert_called_with(\n          'foo_dag_string', 'text/plain')\n\n      # GCS dag location has additional parts\n      mock_environment_details.return_value = {\n        'config': {\n          'gcsDagLocation': 'gs://foo_bucket/foo_random/dags'\n        }\n      }\n      test_composer = Composer('foo_zone', 'foo_environment')\n      test_composer.deploy('foo_name', 'foo_dag_string')\n      mock_bucket_class.assert_called_with('foo_bucket')\n      mock_bucket_class.return_value.object.assert_called_with('foo_random/dags/foo_name.py')\n      mock_bucket_class.return_value.object.return_value.write_stream.assert_called_with(\n          'foo_dag_string', 'text/plain')\n\n  @mock.patch('google.datalab.contrib.pipeline.composer._api.Api.get_environment_details')\n  def test_gcs_dag_location(self, mock_environment_details):\n      # Composer returns good result\n      mock_environment_details.return_value = {\n        'config': {\n          'gcsDagLocation': 'gs://foo_bucket/dags'\n        }\n      }\n      test_composer = Composer('foo_zone', 'foo_environment')\n      self.assertEqual('gs://foo_bucket/dags/', test_composer.gcs_dag_location)\n\n      mock_environment_details.return_value = {\n        'config': {\n          'gcsDagLocation': 'gs://foo_bucket'  # only bucket\n        }\n      }\n      test_composer = Composer('foo_zone', 'foo_environment')\n      self.assertEqual('gs://foo_bucket/', test_composer.gcs_dag_location)\n\n      mock_environment_details.return_value = {\n        'config': {\n          'gcsDagLocation': 'gs://foo_bucket/'  # with trailing slash\n        }\n      }\n      test_composer = Composer('foo_zone', 'foo_environment')\n      self.assertEqual('gs://foo_bucket/', test_composer.gcs_dag_location)\n\n      # Composer returns empty result\n      mock_environment_details.return_value = {}\n      test_composer = Composer('foo_zone', 'foo_environment')\n      with self.assertRaisesRegexp(\n              ValueError, 'Dag location unavailable from Composer environment foo_environment'):\n        test_composer.gcs_dag_location\n\n      # Composer returns empty result\n      mock_environment_details.return_value = {\n        'config': {}\n      }\n      test_composer = Composer('foo_zone', 'foo_environment')\n      with self.assertRaisesRegexp(\n              ValueError, 'Dag location unavailable from Composer environment foo_environment'):\n        test_composer.gcs_dag_location\n\n      # Composer returns None result\n      mock_environment_details.return_value = {\n        'config': {\n          'gcsDagLocation': None\n        }\n      }\n      test_composer = Composer('foo_zone', 'foo_environment')\n      with self.assertRaisesRegexp(\n              ValueError,\n              'Dag location None from Composer environment foo_environment is in incorrect format'):\n        test_composer.gcs_dag_location\n\n      # Composer returns incorrect formats\n      mock_environment_details.return_value = {\n        'config': {\n          'gcsDagLocation': 'gs:/foo_bucket'\n        }\n      }\n      test_composer = Composer('foo_zone', 'foo_environment')\n      with self.assertRaisesRegexp(\n              ValueError,\n              ('Dag location gs:/foo_bucket from Composer environment foo_environment is in'\n               ' incorrect format')):\n        test_composer.gcs_dag_location\n\n      mock_environment_details.return_value = {\n        'config': {\n          'gcsDagLocation': 'as://foo_bucket'\n        }\n      }\n      test_composer = Composer('foo_zone', 'foo_environment')\n      with self.assertRaisesRegexp(\n              ValueError,\n              ('Dag location as://foo_bucket from Composer environment foo_environment is in'\n               ' incorrect format')):\n        test_composer.gcs_dag_location\n"
  },
  {
    "path": "tests/pipeline/pipeline_tests.py",
    "content": "# Copyright 2017 Google Inc. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\"\"\"Tests for google3.third_party.py.google.datalab.utils._file.\"\"\"\n\nimport datetime\nimport mock\nimport re\nimport unittest\nimport yaml\n\nimport google.auth\nimport google.datalab\nimport google.datalab.bigquery as bq\nimport google.datalab.contrib.pipeline._pipeline as pipeline\n\nimport google.auth\n\n\nclass PipelineTest(unittest.TestCase):\n\n  _test_pipeline_yaml_spec = \"\"\"\nemails: foo1@test.com,foo2@test.com\nschedule:\n  start: 2009-05-05T22:28:15Z\n  end: 2009-05-06T22:28:15Z\n  interval: '0-59 * * * *'\ntasks:\n  current_timestamp:\n    type: bq.execute\n    query: $foo_query\n    use_legacy_sql: False\n  tomorrows_timestamp:\n    type: bq.execute\n    query: $foo_query\n    use_legacy_sql: False\n    up_stream:\n      - current_timestamp\n\"\"\"\n\n  @staticmethod\n  def _create_context():\n    project_id = 'project'\n    creds = mock.Mock(spec=google.auth.credentials.Credentials)\n    return google.datalab.Context(project_id, creds)\n\n  def test_get_dependency_definition_single(self):\n    dependencies = pipeline.PipelineGenerator._get_dependency_definition('t2', ['t1'])\n    self.assertEqual(dependencies, 't2.set_upstream(t1)\\n')\n\n  def test_get_dependency_definition_multiple(self):\n    dependencies = pipeline.PipelineGenerator._get_dependency_definition('t2', ['t1', 't3'])\n    self.assertEqual(dependencies, 't2.set_upstream(t1)\\nt2.set_upstream(t3)\\n')\n\n  def test_get_bash_operator_definition(self):\n    task_id = 'print_pdt_date'\n    task_details = {}\n    task_details['type'] = 'Bash'\n    task_details['bash_command'] = 'date'\n\n    operator_def = pipeline.PipelineGenerator._get_operator_definition(task_id, task_details, None)\n    self.assertEqual(operator_def, \"\"\"print_pdt_date = BashOperator(task_id=\\'print_pdt_date_id\\', bash_command=\\\"\\\"\\\"date\\\"\\\"\\\", dag=dag)\n\"\"\")  # noqa\n\n  def test_get_bash_operator_definition_with_templates(self):\n    task_id = 'print_pdt_date'\n    task_details = {}\n    task_details['type'] = 'Bash'\n    task_details['output_encoding'] = 'utf-8'\n    task_details['bash_command'] = 'date_%(_ds)s'\n    operator_def = pipeline.PipelineGenerator._get_operator_definition(task_id, task_details, None)\n    self.assertEqual(operator_def, \"\"\"print_pdt_date = BashOperator(task_id=\\'print_pdt_date_id\\', bash_command=\\\"\\\"\\\"date_{{ ds }}\\\"\\\"\\\", output_encoding=\\\"\\\"\\\"utf-8\\\"\\\"\\\", dag=dag)\n\"\"\")  # noqa\n\n    # Airflow macros should get replaced in templated fields\n    task_details['bash_command'] = 'date_%(_ds)s'\n    operator_def = pipeline.PipelineGenerator._get_operator_definition(task_id, task_details, None)\n    self.assertEqual(operator_def, \"\"\"print_pdt_date = BashOperator(task_id=\\'print_pdt_date_id\\', bash_command=\\\"\\\"\\\"date_{{ ds }}\\\"\\\"\\\", output_encoding=\\\"\\\"\\\"utf-8\\\"\\\"\\\", dag=dag)\n\"\"\")  # noqa\n\n    # Airflow macros should not get replaced in non-templated fields\n    task_details['bash_command'] = 'date'\n    task_details['output_encoding'] = 'foo_%(_ds)s'\n    operator_def = pipeline.PipelineGenerator._get_operator_definition(task_id, task_details, None)\n    self.assertEqual(operator_def, \"\"\"print_pdt_date = BashOperator(task_id=\\'print_pdt_date_id\\', bash_command=\\\"\\\"\\\"date\\\"\\\"\\\", output_encoding=\\\"\\\"\\\"foo_%(_ds)s\\\"\\\"\\\", dag=dag)\n\"\"\")  # noqa\n\n    # User-defined modifiers should get replaced in templated fields\n    task_details['bash_command'] = 'date_%(foo_key)s'\n    operator_def = pipeline.PipelineGenerator._get_operator_definition(\n      task_id, task_details, [{'name': 'foo_key', 'value': 'foo_value', 'type': 'STRING'}])\n    self.assertEqual(operator_def, \"\"\"print_pdt_date = BashOperator(task_id=\\'print_pdt_date_id\\', bash_command=\\\"\\\"\\\"date_foo_value\\\"\\\"\\\", output_encoding=\\\"\\\"\\\"foo_%(_ds)s\\\"\\\"\\\", dag=dag)\n\"\"\")  # noqa\n\n    # User-defined modifiers should take precedence over the built-in airflow macros\n    task_details['bash_command'] = 'date_%(_ds)s'\n    operator_def = pipeline.PipelineGenerator._get_operator_definition(\n      task_id, task_details, [{'name': '_ds', 'value': 'user_value', 'type': 'STRING'}])\n    self.assertEqual(operator_def, \"\"\"print_pdt_date = BashOperator(task_id=\\'print_pdt_date_id\\', bash_command=\\\"\\\"\\\"date_user_value\\\"\\\"\\\", output_encoding=\\\"\\\"\\\"foo_%(_ds)s\\\"\\\"\\\", dag=dag)\n\"\"\")  # noqa\n\n  @mock.patch('google.datalab.bigquery.commands._bigquery._get_table')\n  def test_get_bq_execute_operator_definition(self, mock_table):\n    mock_table.return_value = bq.Table(\n        'foo_project.foo_dataset.foo_table',\n        context=PipelineTest._create_context())\n    task_id = 'foo'\n    task_details = {}\n    task_details['type'] = 'BigQuery'\n\n    # Adding newlines to the query to mimic actual usage of %%bq query ...\n    task_details['query'] = google.datalab.bigquery.Query(\"\"\"SELECT *\nFROM publicdata.samples.wikipedia\nLIMIT 5\"\"\")\n    operator_def = pipeline.PipelineGenerator._get_operator_definition(task_id, task_details, None)\n    self.assertEqual(operator_def, \"\"\"foo = BigQueryOperator(task_id='foo_id', bql=\\\"\\\"\\\"SELECT *\\nFROM publicdata.samples.wikipedia\\nLIMIT 5\\\"\\\"\\\", use_legacy_sql=False, dag=dag)\n\"\"\")  # noqa\n\n  @mock.patch('google.datalab.bigquery.commands._bigquery._get_table')\n  def test_get_bq_extract_operator_definition(self, mock_table):\n    mock_table.return_value = bq.Table(\n        'foo_project.foo_dataset.foo_table',\n        context=PipelineTest._create_context())\n    task_id = 'foo'\n    task_details = {}\n    task_details['type'] = 'BigQueryToCloudStorage'\n    task_details['table'] = 'foo_project.foo_dataset.foo_table'\n    task_details['path'] = 'foo_path'\n    task_details['format'] = 'csv'\n    task_details['delimiter'] = '$'\n    task_details['header'] = False\n    task_details['compress'] = True\n    operator_def = pipeline.PipelineGenerator._get_operator_definition(task_id, task_details, None)\n    self.assertEqual(operator_def, \"\"\"foo = BigQueryToCloudStorageOperator(task_id='foo_id', compression=\\\"\\\"\\\"GZIP\\\"\\\"\\\", destination_cloud_storage_uris=[\\'foo_path\\'], export_format=\\\"\\\"\\\"CSV\\\"\\\"\\\", field_delimiter=\\\"\\\"\\\"$\\\"\\\"\\\", print_header=False, source_project_dataset_table=\\\"\\\"\\\"foo_project.foo_dataset.foo_table\\\"\\\"\\\", dag=dag)\n\"\"\")  # noqa\n\n    task_details['format'] = 'json'\n    operator_def = pipeline.PipelineGenerator._get_operator_definition(task_id, task_details, None)\n    self.assertEqual(operator_def, \"\"\"foo = BigQueryToCloudStorageOperator(task_id='foo_id', compression=\\\"\\\"\\\"GZIP\\\"\\\"\\\", destination_cloud_storage_uris=[\\'foo_path\\'], export_format=\\\"\\\"\\\"NEWLINE_DELIMITED_JSON\\\"\\\"\\\", field_delimiter=\\\"\\\"\\\"$\\\"\\\"\\\", print_header=False, source_project_dataset_table=\\\"\\\"\\\"foo_project.foo_dataset.foo_table\\\"\\\"\\\", dag=dag)\n\"\"\")  # noqa\n\n  @mock.patch('google.datalab.bigquery.commands._bigquery._get_table')\n  def test_get_bq_load_operator_definition(self, mock_table):\n    mock_table.return_value = bq.Table(\n        'foo_project.foo_dataset.foo_table',\n        context=PipelineTest._create_context())\n    task_id = 'foo'\n    task_details = {}\n    task_details['type'] = 'GoogleCloudStorageToBigQuery'\n    task_details['table'] = 'foo_project.foo_dataset.foo_table'\n    task_details['path'] = 'gs://foo_bucket/foo_file.csv'\n    task_details['format'] = 'csv'\n    task_details['delimiter'] = '$'\n    task_details['skip'] = False\n    operator_def = pipeline.PipelineGenerator._get_operator_definition(task_id, task_details, None)\n    self.assertEqual(operator_def, \"\"\"foo = GoogleCloudStorageToBigQueryOperator(task_id='foo_id', bucket=\\\"\\\"\\\"foo_bucket\\\"\\\"\\\", destination_project_dataset_table=\\\"\\\"\\\"foo_project.foo_dataset.foo_table\\\"\\\"\\\", export_format=\\\"\\\"\\\"CSV\\\"\\\"\\\", field_delimiter=\\\"\\\"\\\"$\\\"\\\"\\\", skip_leading_rows=False, source_objects=\\\"\\\"\\\"foo_file.csv\\\"\\\"\\\", dag=dag)\n\"\"\")  # noqa\n\n    task_details['format'] = 'json'\n    operator_def = pipeline.PipelineGenerator._get_operator_definition(task_id, task_details, None)\n    self.assertEqual(operator_def, \"\"\"foo = GoogleCloudStorageToBigQueryOperator(task_id='foo_id', bucket=\\\"\\\"\\\"foo_bucket\\\"\\\"\\\", destination_project_dataset_table=\\\"\\\"\\\"foo_project.foo_dataset.foo_table\\\"\\\"\\\", export_format=\\\"\\\"\\\"NEWLINE_DELIMITED_JSON\\\"\\\"\\\", field_delimiter=\\\"\\\"\\\"$\\\"\\\"\\\", skip_leading_rows=False, source_objects=\\\"\\\"\\\"foo_file.csv\\\"\\\"\\\", dag=dag)\n\"\"\")  # noqa\n\n  def test_get_pydatalab_bq_load_operator_definition(self):\n    task_id = 'bq_pipeline_load_task'\n    task_details = {}\n    task_details['type'] = 'pydatalab.bq.load'\n    task_details['delimiter'] = ','\n    task_details['format'] = 'csv'\n    task_details['mode'] = 'create'\n    task_details['path'] = 'test/path'\n    task_details['quote'] = '\"'\n    schema = [\n      {\n        'mode': 'NULLABLE',\n        'type': 'int64',\n        'description': 'description1',\n        'name': 'col1',\n      },\n      {\n        'mode': 'required',\n        'type': 'STRING',\n        'description': 'description1',\n        'name': 'col2',\n      }\n    ]\n    task_details['schema'] = schema\n    task_details['skip'] = 0\n    task_details['strict'] = True\n    task_details['table'] = 'project.test.table'\n\n    actual = pipeline.PipelineGenerator._get_operator_definition(task_id, task_details, None)\n    pattern = re.compile(\"\"\"bq_pipeline_load_task = LoadOperator\\(task_id='bq_pipeline_load_task_id', delimiter=\\\"\\\"\\\",\\\"\\\"\\\", format=\\\"\\\"\\\"csv\\\"\\\"\\\", mode=\\\"\\\"\\\"create\\\"\\\"\\\", path=\\\"\\\"\\\"test/path\\\"\\\"\\\", quote=\\\"\\\"\\\"\"\\\"\\\"\\\", schema=(.*), skip=0, strict=True, table=\\\"\\\"\\\"project.test.table\\\"\\\"\\\", dag=dag\\)\"\"\")  # noqa\n    # group(1) has the string that follows the \"schema=\", i.e. the list of dicts.\n    # Since we're comparing string literals of dicts that have the items re-ordered, we just sort\n    # the string. This is a loose check.\n    sorted_string_of_actual_schema = ''.join(sorted(pattern.match(actual).group(1)))\n    sorted_string_of_expected_schema = ''.join(sorted(str(schema)))\n    self.assertEqual(sorted_string_of_actual_schema, sorted_string_of_expected_schema)\n\n  def test_get_pydatalab_bq_execute_operator_definition(self):\n    task_id = 'bq_pipeline_execute_task'\n    task_details = {}\n    task_details['type'] = 'pydatalab.bq.execute'\n    task_details['large'] = True\n    task_details['mode'] = 'create'\n    task_details['sql'] = 'foo_query'\n    task_details['table'] = 'project.test.table'\n    actual = pipeline.PipelineGenerator._get_operator_definition(task_id, task_details, None)\n    expected = \"\"\"bq_pipeline_execute_task = ExecuteOperator(task_id='bq_pipeline_execute_task_id', large=True, mode=\\\"\\\"\\\"create\\\"\\\"\\\", sql=\\\"\\\"\\\"foo_query\\\"\\\"\\\", table=\\\"\\\"\\\"project.test.table\\\"\\\"\\\", dag=dag)\n\"\"\"  # noqa\n    self.assertEqual(actual, expected)\n\n  def test_get_pydatalab_bq_extract_operator_definition(self):\n    task_id = 'bq_pipeline_extract_task'\n    task_details = {}\n    task_details['type'] = 'pydatalab.bq.extract'\n    task_details['billing'] = 'foo'\n    task_details['compress'] = True\n    task_details['delimiter'] = ','\n    task_details['format'] = 'csv'\n    task_details['header'] = True\n    task_details['path'] = 'test/path'\n\n    actual = pipeline.PipelineGenerator._get_operator_definition(task_id, task_details, None)\n    expected = \"\"\"bq_pipeline_extract_task = ExtractOperator(task_id='bq_pipeline_extract_task_id', billing=\\\"\\\"\\\"foo\\\"\\\"\\\", compress=True, delimiter=\\\"\\\"\\\",\\\"\\\"\\\", format=\\\"\\\"\\\"csv\\\"\\\"\\\", header=True, path=\\\"\\\"\\\"test/path\\\"\\\"\\\", dag=dag)\n\"\"\"  # noqa\n    self.assertEqual(actual, expected)\n\n  def test_get_unknown_operator_definition(self):\n    task_id = 'id'\n    task_details = {}\n    task_details['type'] = 'Unknown'\n    task_details['foo'] = 'bar'\n    task_details['bar_typed'] = False\n    operator_def = pipeline.PipelineGenerator._get_operator_definition(task_id, task_details, None)\n    self.assertEqual(operator_def,\n                     'id = UnknownOperator(''task_id=\\'id_id\\', ' +\n                     'bar_typed=False, foo=\"\"\"bar\"\"\", dag=dag)\\n')\n\n  def test_get_random_operator_class_name(self):\n    self.assertEqual(pipeline.PipelineGenerator._get_operator_class_name('Unknown'),\n                     ('UnknownOperator', 'google.datalab.contrib.pipeline._pipeline'))\n\n  def test_get_dag_definition(self):\n    self.assertEqual(pipeline.PipelineGenerator._get_dag_definition('foo', 'bar', ),\n                     'dag = DAG(dag_id=\\'foo\\', schedule_interval=\\'bar\\', '\n                     'catchup=False, default_args=default_args)\\n\\n')\n\n    self.assertEqual(pipeline.PipelineGenerator._get_dag_definition('foo', 'bar', True),\n                     'dag = DAG(dag_id=\\'foo\\', schedule_interval=\\'bar\\', '\n                     'catchup=True, default_args=default_args)\\n\\n')\n\n  def test_get_datetime_expr(self):\n    dag_dict = yaml.load(PipelineTest._test_pipeline_yaml_spec)\n    start = dag_dict.get('schedule').get('start')\n    datetime_expr = pipeline.PipelineGenerator._get_datetime_expr_str(start)\n\n    self.assertEqual(datetime_expr,\n                     'datetime.datetime.strptime(\\'2009-05-05T22:28:15\\', \\'%Y-%m-%dT%H:%M:%S\\')')\n    self.assertEqual(eval(datetime_expr), datetime.datetime(2009, 5, 5, 22, 28, 15))\n\n  def test_get_default_args(self):\n    actual = pipeline.PipelineGenerator._get_default_args({}, None)\n    self.assertIn(\"'end_date': None\", actual)\n    self.assertIn(\"'start_date': datetime.datetime.strptime(\", actual)\n    self.assertIn(\"'email': []\", actual)\n    self.assertIn(\"'owner': 'Google Cloud Datalab'\", actual)\n\n    dag_dict = yaml.load(PipelineTest._test_pipeline_yaml_spec)\n    dag_dict['schedule']['retries'] = 5\n    dag_dict['schedule']['email_on_retry'] = False\n    dag_dict['schedule']['email_on_failure'] = False\n    dag_dict['schedule']['retry_exponential_backoff'] = False\n    dag_dict['schedule']['retry_delay_seconds'] = 10\n    dag_dict['schedule']['max_retry_delay_seconds'] = 15\n    actual = pipeline.PipelineGenerator._get_default_args(dag_dict.get('schedule'),\n                                                          dag_dict.get('emails'))\n    self.assertIn(\n      \"'end_date': datetime.datetime.strptime('2009-05-06T22:28:15', '%Y-%m-%dT%H:%M:%S')\",\n      actual)\n    self.assertIn(\n      \"'start_date': datetime.datetime.strptime('2009-05-05T22:28:15', '%Y-%m-%dT%H:%M:%S')\",\n      actual)\n    self.assertIn(\"'email': ['foo1@test.com', 'foo2@test.com']\", actual)\n    self.assertIn(\"'owner': 'Google Cloud Datalab'\", actual)\n    self.assertIn(\"'retries': 5\", actual)\n    self.assertIn(\"'email_on_retry': False\", actual)\n    self.assertIn(\"'email_on_failure': False\", actual)\n    self.assertIn(\"'retry_exponential_backoff': False\", actual)\n    self.assertIn(\"'retry_delay': timedelta(seconds=10)\", actual)\n    self.assertIn(\"'max_retry_delay': timedelta(seconds=15)\", actual)\n\n  def test_get_airflow_spec_with_default_schedule(self):\n    dag_dict = yaml.load(PipelineTest._test_pipeline_yaml_spec)\n    # We delete the schedule spec to test with defaults\n    del dag_dict['schedule']\n\n    actual = pipeline.PipelineGenerator.generate_airflow_spec('foo_name', dag_dict)\n    self.assertIn('import datetime', actual)\n    self.assertIn(\"'email': ['foo1@test.com', 'foo2@test.com']\", actual)\n    self.assertIn(\"schedule_interval='@once'\", actual)\n    self.assertIn('current_timestamp_id', actual)\n    self.assertIn('tomorrows_timestamp_id', actual)\n    self.assertIn('tomorrows_timestamp.set_upstream(current_timestamp)', actual)\n\n\nif __name__ == '__main__':\n  unittest.main()\n"
  },
  {
    "path": "tests/stackdriver/__init__.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n"
  },
  {
    "path": "tests/stackdriver/commands/__init__.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n"
  },
  {
    "path": "tests/stackdriver/commands/monitoring_tests.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nimport mock\nimport unittest\n\nimport pandas\n\nimport google.auth\nimport google.datalab\nimport google.datalab.stackdriver.commands._monitoring as monitoring_commands\n\nDEFAULT_PROJECT = 'test'\nPROJECT = 'my-project'\n\n\nclass TestCases(unittest.TestCase):\n  def setUp(self):\n    self.context = self._create_context(DEFAULT_PROJECT)\n\n  @mock.patch('google.datalab.Context.default')\n  def test_make_context(self, mock_context_default):\n    mock_context_default.return_value = self.context\n    new_context = monitoring_commands._make_context(PROJECT)\n    self.assertEqual(new_context.project_id, PROJECT)\n    self.assertEqual(new_context.credentials, self.context.credentials)\n\n  @mock.patch('google.datalab.Context.default')\n  def test_make_context_empty_project(self, mock_context_default):\n    mock_context_default.return_value = self.context\n    new_context = monitoring_commands._make_context('')\n    self.assertEqual(new_context.project_id, DEFAULT_PROJECT)\n    self.assertEqual(new_context.credentials, self.context.credentials)\n\n  @mock.patch('google.datalab.Context.default')\n  @mock.patch('google.datalab.stackdriver.commands._monitoring._render_dataframe')\n  @mock.patch('google.datalab.stackdriver.monitoring.MetricDescriptors')\n  def test_monitoring_metrics_list(self, mock_metric_descriptors, mock_render_dataframe,\n                                   mock_context_default):\n    METRIC_TYPES = ['compute.googleapis.com/instances/cpu/utilization',\n                    'compute.googleapis.com/instances/cpu/usage_time']\n    DATAFRAME = pandas.DataFrame(METRIC_TYPES, columns=['Metric type'])\n    PATTERN = 'compute*cpu*'\n\n    mock_context_default.return_value = self.context\n    mock_metric_class = mock_metric_descriptors.return_value\n    mock_metric_class.as_dataframe.return_value = DATAFRAME\n\n    monitoring_commands._monitoring_metrics_list(\n        {'project': PROJECT, 'type': PATTERN}, None)\n\n    mock_metric_descriptors.assert_called_once()\n    mock_metric_class.as_dataframe.assert_called_once_with(pattern=PATTERN)\n    mock_render_dataframe.assert_called_once_with(DATAFRAME)\n\n  @mock.patch('google.datalab.Context.default')\n  @mock.patch('google.datalab.stackdriver.commands._monitoring._render_dataframe')\n  @mock.patch('google.datalab.stackdriver.monitoring.ResourceDescriptors')\n  def test_monitoring_resource_types_list(self, mock_resource_descriptors, mock_render_dataframe,\n                                          mock_context_default):\n    RESOURCE_TYPES = ['gce_instance', 'aws_ec2_instance']\n    DATAFRAME = pandas.DataFrame(RESOURCE_TYPES, columns=['Resource type'])\n    PATTERN = '*instance*'\n\n    mock_context_default.return_value = self.context\n    mock_resource_class = mock_resource_descriptors.return_value\n    mock_resource_class.as_dataframe.return_value = DATAFRAME\n\n    monitoring_commands._monitoring_resource_types_list(\n        {'project': PROJECT, 'type': PATTERN}, None)\n\n    mock_resource_descriptors.assert_called_once()\n    mock_resource_class.as_dataframe.assert_called_once_with(pattern=PATTERN)\n    mock_render_dataframe.assert_called_once_with(DATAFRAME)\n\n  @mock.patch('google.datalab.Context.default')\n  @mock.patch('google.datalab.stackdriver.commands._monitoring._render_dataframe')\n  @mock.patch('google.datalab.stackdriver.monitoring.Groups')\n  def test_monitoring_groups_list(self, mock_groups, mock_render_dataframe,\n                                  mock_context_default):\n    GROUP_IDS = ['GROUP-205', 'GROUP-101']\n    DATAFRAME = pandas.DataFrame(GROUP_IDS, columns=['Group ID'])\n    PATTERN = 'GROUP-*'\n\n    mock_context_default.return_value = self.context\n    mock_group_class = mock_groups.return_value\n    mock_group_class.as_dataframe.return_value = DATAFRAME\n\n    monitoring_commands._monitoring_groups_list(\n        {'project': PROJECT, 'name': PATTERN}, None)\n\n    mock_groups.assert_called_once()\n    mock_group_class.as_dataframe.assert_called_once_with(pattern=PATTERN)\n    mock_render_dataframe.assert_called_once_with(DATAFRAME)\n\n  @staticmethod\n  def _create_context(project_id):\n    creds = mock.Mock(spec=google.auth.credentials.Credentials)\n    return google.datalab.Context(project_id, creds)\n"
  },
  {
    "path": "tests/stackdriver/monitoring/__init__.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n"
  },
  {
    "path": "tests/stackdriver/monitoring/group_tests.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\n\nimport mock\nimport unittest\n\nimport google.cloud.monitoring_v3\n\nimport google.auth\nimport google.datalab\nimport google.datalab.stackdriver.monitoring as gcm\n\nDEFAULT_PROJECT = 'test'\nPROJECT = 'my-project'\nGROUP_IDS = ['GROUP-205', 'GROUP-101']\nPARENT_IDS = ['', GROUP_IDS[0]]\nDISPLAY_NAMES = ['All Instances', 'GCE Instances']\nPARENT_DISPLAY_NAMES = ['', DISPLAY_NAMES[0]]\nFILTER_STRINGS = ['resource.type = ends_with(\"instance\")',\n                  'resource.type = \"gce_instance\"']\nIS_CLUSTERS = [False, True]\n\n\nclass TestCases(unittest.TestCase):\n\n  def setUp(self):\n    self.context = self._create_context(DEFAULT_PROJECT)\n    self.groups = gcm.Groups(context=self.context)\n\n  @mock.patch('google.datalab.Context.default')\n  def test_constructor_minimal(self, mock_context_default):\n    mock_context_default.return_value = self.context\n\n    groups = gcm.Groups()\n\n    self.assertIs(groups._context, self.context)\n    self.assertIsNone(groups._group_dict)\n\n    self.assertEqual(groups._client.project, DEFAULT_PROJECT)\n\n  def test_constructor_maximal(self):\n    context = self._create_context(PROJECT)\n    groups = gcm.Groups(context)\n    self.assertIs(groups._context, context)\n    self.assertIsNone(groups._group_dict)\n    self.assertEqual(groups._client.project, PROJECT)\n\n  @mock.patch('google.cloud.monitoring_v3.GroupServiceClient.list_groups')\n  def test_list(self, mock_api_list_groups):\n    mock_api_list_groups.return_value = self._list_groups_get_result(\n        context=self.context)\n\n    group_list = self.groups.list()\n\n    mock_api_list_groups.assert_called_once_with(DEFAULT_PROJECT)\n    self.assertEqual(len(group_list), 2)\n    self.assertEqual(group_list[0].name, GROUP_IDS[0])\n    self.assertEqual(group_list[1].name, GROUP_IDS[1])\n\n  @mock.patch('google.cloud.monitoring_v3.GroupServiceClient.list_groups')\n  def test_list_w_pattern_match(self, mock_api_list_groups):\n    mock_api_list_groups.return_value = self._list_groups_get_result(\n        context=self.context)\n\n    group_list = self.groups.list(pattern='GCE*')\n\n    mock_api_list_groups.assert_called_once_with(DEFAULT_PROJECT)\n    self.assertEqual(len(group_list), 1)\n    self.assertEqual(group_list[0].name, GROUP_IDS[1])\n\n  @mock.patch('google.cloud.monitoring_v3.GroupServiceClient.list_groups')\n  def test_list_caching(self, mock_gcloud_list_groups):\n    mock_gcloud_list_groups.return_value = self._list_groups_get_result(\n        context=self.context)\n\n    actual_list1 = self.groups.list()\n    actual_list2 = self.groups.list()\n\n    mock_gcloud_list_groups.assert_called_once_with(DEFAULT_PROJECT)\n    self.assertEqual(actual_list1, actual_list2)\n\n  @mock.patch('google.cloud.monitoring_v3.GroupServiceClient.list_groups')\n  def test_as_dataframe(self, mock_gcloud_list_groups):\n    mock_gcloud_list_groups.return_value = self._list_groups_get_result(\n        context=self.context)\n    dataframe = self.groups.as_dataframe()\n    mock_gcloud_list_groups.assert_called_once_with(DEFAULT_PROJECT)\n\n    expected_headers = list(gcm.Groups._DISPLAY_HEADERS)\n    self.assertEqual(dataframe.columns.tolist(), expected_headers)\n    self.assertEqual(dataframe.columns.names, [None])\n\n    self.assertEqual(dataframe.index.tolist(), list(range(len(GROUP_IDS))))\n    self.assertEqual(dataframe.index.names, [None])\n\n    expected_values = [list(row) for row in\n                       zip(GROUP_IDS, DISPLAY_NAMES, PARENT_IDS,\n                           PARENT_DISPLAY_NAMES, IS_CLUSTERS, FILTER_STRINGS)]\n    self.assertEqual(dataframe.values.tolist(), expected_values)\n\n  @mock.patch('google.cloud.monitoring_v3.GroupServiceClient.list_groups')\n  def test_as_dataframe_w_all_args(self, mock_gcloud_list_groups):\n    mock_gcloud_list_groups.return_value = self._list_groups_get_result(\n        context=self.context)\n    dataframe = self.groups.as_dataframe(pattern='*Instance*', max_rows=1)\n    mock_gcloud_list_groups.assert_called_once_with(DEFAULT_PROJECT)\n\n    expected_headers = list(gcm.Groups._DISPLAY_HEADERS)\n    self.assertEqual(dataframe.columns.tolist(), expected_headers)\n    self.assertEqual(dataframe.index.tolist(), [0])\n    self.assertEqual(dataframe.iloc[0, 0], GROUP_IDS[0])\n\n  @staticmethod\n  def _create_context(project_id):\n    creds = mock.Mock(spec=google.auth.credentials.Credentials)\n    return google.datalab.Context(project_id, creds)\n\n  @staticmethod\n  def _list_groups_get_result(context):\n    groups = []\n    for group_id, parent_id, display_name, filter_string, is_cluster in \\\n            zip(GROUP_IDS, PARENT_IDS, DISPLAY_NAMES, FILTER_STRINGS, IS_CLUSTERS):\n      group = google.cloud.monitoring_v3.types.Group(\n          name=group_id, display_name=display_name,\n          parent_name=parent_id, filter=filter_string,\n          is_cluster=is_cluster)\n      groups.append(group)\n\n    return groups\n"
  },
  {
    "path": "tests/stackdriver/monitoring/metric_tests.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\n\nimport mock\nimport unittest\n\nimport google.cloud.monitoring_v3\n\nimport google.auth\nimport google.datalab\nimport google.datalab.stackdriver.monitoring as gcm\n\nDEFAULT_PROJECT = 'test'\nPROJECT = 'my-project'\nMETRIC_TYPES = ['compute.googleapis.com/instances/cpu/utilization',\n                'compute.googleapis.com/instances/cpu/usage_time']\nDISPLAY_NAMES = ['CPU Utilization', 'CPU Usage']\nMETRIC_KIND = 'GAUGE'\nVALUE_TYPE = 'DOUBLE'\nUNIT = '1'\nLABELS = [dict(key='instance_name', value_type='STRING',\n               description='VM instance'),\n          dict(key='device_name', value_type='STRING',\n               description='Device name')]\nFILTER_STRING = 'metric.type:\"cpu\"'\nTYPE_PREFIX = 'compute'\n\n\nclass TestCases(unittest.TestCase):\n\n  def setUp(self):\n    self.context = self._create_context(DEFAULT_PROJECT)\n    self.descriptors = gcm.MetricDescriptors(context=self.context)\n\n  @mock.patch('google.datalab.Context.default')\n  def test_constructor_minimal(self, mock_context_default):\n    mock_context_default.return_value = self.context\n\n    descriptors = gcm.MetricDescriptors()\n\n    self.assertEqual(descriptors._client.project, DEFAULT_PROJECT)\n\n    self.assertIsNone(descriptors._filter_string)\n    self.assertIsNone(descriptors._type_prefix)\n    self.assertIsNone(descriptors._descriptors)\n\n  def test_constructor_maximal(self):\n    context = self._create_context(PROJECT)\n    descriptors = gcm.MetricDescriptors(\n        filter_string=FILTER_STRING, type_prefix=TYPE_PREFIX,\n        context=context)\n\n    self.assertEqual(descriptors._client.project, PROJECT)\n\n    self.assertEqual(descriptors._filter_string, FILTER_STRING)\n    self.assertEqual(descriptors._type_prefix, TYPE_PREFIX)\n    self.assertIsNone(descriptors._descriptors)\n\n  @mock.patch('google.cloud.monitoring_v3.MetricServiceClient.list_metric_descriptors')\n  def test_list(self, mock_gcloud_list_descriptors):\n    mock_gcloud_list_descriptors.return_value = self._list_metrics_get_result(\n        context=self.context)\n\n    metric_descriptor_list = self.descriptors.list()\n\n    mock_gcloud_list_descriptors.assert_called_once_with(\n        DEFAULT_PROJECT, filter_='')\n    self.assertEqual(len(metric_descriptor_list), 2)\n    self.assertEqual(metric_descriptor_list[0].type, METRIC_TYPES[0])\n    self.assertEqual(metric_descriptor_list[1].type, METRIC_TYPES[1])\n\n  @mock.patch('google.cloud.monitoring_v3.MetricServiceClient.list_metric_descriptors')\n  def test_list_w_api_filter(self, mock_gcloud_list_descriptors):\n    mock_gcloud_list_descriptors.return_value = self._list_metrics_get_result(\n        context=self.context)\n\n    descriptors = gcm.MetricDescriptors(\n        filter_string=FILTER_STRING, type_prefix=TYPE_PREFIX,\n        context=self.context)\n    metric_descriptor_list = descriptors.list()\n\n    expected_filter = '{} AND metric.type = starts_with(\"{}\")'.format(\n        FILTER_STRING, TYPE_PREFIX)\n\n    mock_gcloud_list_descriptors.assert_called_once_with(\n        DEFAULT_PROJECT, filter_=expected_filter)\n    self.assertEqual(len(metric_descriptor_list), 2)\n    self.assertEqual(metric_descriptor_list[0].type, METRIC_TYPES[0])\n    self.assertEqual(metric_descriptor_list[1].type, METRIC_TYPES[1])\n\n  @mock.patch('google.cloud.monitoring_v3.MetricServiceClient.list_metric_descriptors')\n  def test_list_w_pattern_match(self, mock_gcloud_list_descriptors):\n    mock_gcloud_list_descriptors.return_value = self._list_metrics_get_result(\n        context=self.context)\n\n    metric_descriptor_list = self.descriptors.list(pattern='*usage_time')\n\n    mock_gcloud_list_descriptors.assert_called_once_with(\n        DEFAULT_PROJECT, filter_='')\n    self.assertEqual(len(metric_descriptor_list), 1)\n    self.assertEqual(metric_descriptor_list[0].type, METRIC_TYPES[1])\n\n  @mock.patch('google.cloud.monitoring_v3.MetricServiceClient.list_metric_descriptors')\n  def test_list_caching(self, mock_gcloud_list_descriptors):\n    mock_gcloud_list_descriptors.return_value = self._list_metrics_get_result(\n        context=self.context)\n\n    actual_list1 = self.descriptors.list()\n    actual_list2 = self.descriptors.list()\n\n    mock_gcloud_list_descriptors.assert_called_once_with(\n        DEFAULT_PROJECT, filter_='')\n    self.assertEqual(actual_list1, actual_list2)\n\n  @mock.patch('google.datalab.stackdriver.monitoring.MetricDescriptors.list')\n  def test_as_dataframe(self, mock_datalab_list_descriptors):\n    mock_datalab_list_descriptors.return_value = self._list_metrics_get_result(\n        context=self.context)\n    dataframe = self.descriptors.as_dataframe()\n    mock_datalab_list_descriptors.assert_called_once_with('*')\n\n    expected_headers = list(gcm.MetricDescriptors._DISPLAY_HEADERS)\n    self.assertEqual(dataframe.columns.tolist(), expected_headers)\n    self.assertEqual(dataframe.columns.names, [None])\n\n    self.assertEqual(dataframe.index.tolist(), list(range(len(METRIC_TYPES))))\n    self.assertEqual(dataframe.index.names, [None])\n\n    expected_labels = 'instance_name, device_name'\n    expected_values = [\n        [metric_type, display_name, METRIC_KIND, VALUE_TYPE, UNIT,\n         expected_labels]\n        for metric_type, display_name in zip(METRIC_TYPES, DISPLAY_NAMES)]\n    self.assertEqual(dataframe.values.tolist(), expected_values)\n\n  @mock.patch('google.datalab.stackdriver.monitoring.MetricDescriptors.list')\n  def test_as_dataframe_w_all_args(self, mock_datalab_list_descriptors):\n    mock_datalab_list_descriptors.return_value = self._list_metrics_get_result(\n        context=self.context)\n    dataframe = self.descriptors.as_dataframe(pattern='*cpu*', max_rows=1)\n    mock_datalab_list_descriptors.assert_called_once_with('*cpu*')\n\n    expected_headers = list(gcm.MetricDescriptors._DISPLAY_HEADERS)\n    self.assertEqual(dataframe.columns.tolist(), expected_headers)\n    self.assertEqual(dataframe.index.tolist(), [0])\n    self.assertEqual(dataframe.iloc[0, 0], METRIC_TYPES[0])\n\n  @staticmethod\n  def _create_context(project_id):\n    creds = mock.Mock(spec=google.auth.credentials.Credentials)\n    return google.datalab.Context(project_id, creds)\n\n  @staticmethod\n  def _list_metrics_get_result(context):\n    all_labels = [google.cloud.monitoring_v3.types.LabelDescriptor(**labels)\n                  for labels in LABELS]\n    descriptors = [\n        google.cloud.monitoring_v3.types.MetricDescriptor(\n            type=metric_type, metric_kind=METRIC_KIND, value_type=VALUE_TYPE,\n            unit=UNIT, display_name=display_name, labels=all_labels,\n        )\n        for metric_type, display_name in zip(METRIC_TYPES, DISPLAY_NAMES)]\n    return descriptors\n"
  },
  {
    "path": "tests/stackdriver/monitoring/query_metadata_tests.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nimport mock\nimport unittest\n\nfrom google.cloud.monitoring_v3.types import Metric\nfrom google.cloud.monitoring_v3.types import MonitoredResource\nfrom google.cloud.monitoring_v3.types import TimeSeries\n\nimport google.auth\nimport google.datalab\nimport google.datalab.stackdriver.monitoring as gcm\n\n\nPROJECT = 'my-project'\n\nMETRIC_TYPE = 'compute.googleapis.com/instance/cpu/utilization'\nRESOURCE_TYPE = 'gce_instance'\nINSTANCE_NAMES = ['instance-1', 'instance-2']\nINSTANCE_ZONES = ['us-east1-a', 'us-east1-b']\nINSTANCE_IDS = ['1234567890123456789', '9876543210987654321']\n\n\nclass TestCases(unittest.TestCase):\n\n  def setUp(self):\n    creds = mock.Mock(spec=google.auth.credentials.Credentials)\n    context = google.datalab.Context(PROJECT, creds)\n    self.query = gcm.Query(METRIC_TYPE, context=context)\n\n  @mock.patch('google.datalab.stackdriver.monitoring.Query.iter')\n  def test_constructor(self, mock_query_iter):\n    time_series_iterable = list(self._query_iter_get_result())\n    mock_query_iter.return_value = self._query_iter_get_result()\n\n    query_metadata = gcm.QueryMetadata(self.query)\n\n    mock_query_iter.assert_called_once_with(headers_only=True)\n    self.assertEqual(query_metadata.metric_type, METRIC_TYPE)\n    self.assertEqual(query_metadata.resource_types, set([RESOURCE_TYPE]))\n    self.assertEqual(query_metadata._timeseries_list, time_series_iterable)\n\n  @mock.patch('google.datalab.stackdriver.monitoring.Query.iter')\n  def test_iteration(self, mock_query_iter):\n    time_series_iterable = list(self._query_iter_get_result())\n    mock_query_iter.return_value = self._query_iter_get_result()\n\n    query_metadata = gcm.QueryMetadata(self.query)\n    response = list(query_metadata)\n\n    self.assertEqual(len(response), len(time_series_iterable))\n    self.assertEqual(response, time_series_iterable)\n\n  @mock.patch('google.datalab.stackdriver.monitoring.Query.iter')\n  def test_as_dataframe(self, mock_query_iter):\n    mock_query_iter.return_value = self._query_iter_get_result()\n\n    query_metadata = gcm.QueryMetadata(self.query)\n    dataframe = query_metadata.as_dataframe()\n\n    NUM_INSTANCES = len(INSTANCE_IDS)\n\n    self.assertEqual(dataframe.shape, (NUM_INSTANCES, 5))\n\n    expected_values = [\n        [RESOURCE_TYPE, PROJECT, zone, instance_id, instance_name]\n        for zone, instance_id, instance_name\n        in zip(INSTANCE_ZONES, INSTANCE_IDS, INSTANCE_NAMES)]\n    self.assertEqual(dataframe.values.tolist(), expected_values)\n\n    expected_headers = [\n        ('resource.type', ''),\n        ('resource.labels', 'project_id'),\n        ('resource.labels', 'zone'),\n        ('resource.labels', 'instance_id'),\n        ('metric.labels', 'instance_name')\n    ]\n    self.assertEqual(dataframe.columns.tolist(), expected_headers)\n    self.assertEqual(dataframe.columns.names, [None, None])\n\n    self.assertEqual(dataframe.index.tolist(), list(range(NUM_INSTANCES)))\n    self.assertEqual(dataframe.index.names, [None])\n\n  @mock.patch('google.datalab.stackdriver.monitoring.Query.iter')\n  def test_as_dataframe_w_max_rows(self, mock_query_iter):\n    mock_query_iter.return_value = self._query_iter_get_result()\n\n    MAX_ROWS = 1\n    query_metadata = gcm.QueryMetadata(self.query)\n    dataframe = query_metadata.as_dataframe(max_rows=MAX_ROWS)\n\n    self.assertEqual(dataframe.shape, (MAX_ROWS, 5))\n\n    expected_values = [\n        [RESOURCE_TYPE, PROJECT, INSTANCE_ZONES[0], INSTANCE_IDS[0],\n         INSTANCE_NAMES[0]],\n    ]\n    self.assertEqual(dataframe.values.tolist(), expected_values)\n\n    expected_headers = [\n        ('resource.type', ''),\n        ('resource.labels', 'project_id'),\n        ('resource.labels', 'zone'),\n        ('resource.labels', 'instance_id'),\n        ('metric.labels', 'instance_name')\n    ]\n    self.assertEqual(dataframe.columns.tolist(), expected_headers)\n    self.assertEqual(dataframe.columns.names, [None, None])\n\n    self.assertEqual(dataframe.index.tolist(), list(range(MAX_ROWS)))\n    self.assertEqual(dataframe.index.names, [None])\n\n  @mock.patch('google.datalab.stackdriver.monitoring.Query.iter')\n  def test_as_dataframe_w_no_data(self, mock_query_iter):\n    query_metadata = gcm.QueryMetadata(self.query)\n    dataframe = query_metadata.as_dataframe()\n\n    self.assertEqual(dataframe.shape, (0, 0))\n    self.assertIsNone(dataframe.columns.name)\n    self.assertIsNone(dataframe.index.name)\n\n  @staticmethod\n  def _query_iter_get_result():\n    METRIC_LABELS = list({'instance_name': name} for name in INSTANCE_NAMES)\n    RESOURCE_LABELS = list({\n        'project_id': PROJECT,\n        'zone': zone,\n        'instance_id': instance_id,\n    } for zone, instance_id in zip(INSTANCE_ZONES, INSTANCE_IDS))\n\n    for metric_labels, resource_labels in zip(METRIC_LABELS, RESOURCE_LABELS):\n      yield TimeSeries(\n        metric=Metric(type=METRIC_TYPE, labels=metric_labels),\n        resource=MonitoredResource(type=RESOURCE_TYPE, labels=resource_labels),\n        metric_kind='GAUGE',\n        value_type='DOUBLE',\n        points=[],\n      )\n"
  },
  {
    "path": "tests/stackdriver/monitoring/query_tests.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nimport datetime\nimport mock\nimport unittest\n\nfrom google.cloud.monitoring_v3.query import Query as BaseQuery\n\nimport google.auth\nimport google.datalab\nimport google.datalab.stackdriver.monitoring as gcm\n\n\nPROJECT = 'my-project'\nMETRIC_TYPE = 'compute.googleapis.com/instance/cpu/utilization'\nRESOURCE_TYPE = 'gce_instance'\nINSTANCE_NAMES = ['instance-1', 'instance-2']\nINSTANCE_ZONES = ['us-east1-a', 'us-east1-b']\nINSTANCE_IDS = ['1234567890123456789', '9876543210987654321']\n\n\nclass TestCases(unittest.TestCase):\n\n  def setUp(self):\n    creds = mock.Mock(spec=google.auth.credentials.Credentials)\n    self.context = google.datalab.Context(PROJECT, creds)\n\n  @mock.patch('google.datalab.Context.default')\n  def test_constructor_minimal(self, mock_context_default):\n    mock_context_default.return_value = self.context\n\n    query = gcm.Query()\n\n    self.assertEqual(query._filter.metric_type, BaseQuery.DEFAULT_METRIC_TYPE)\n\n    self.assertIsNone(query._start_time)\n    self.assertIsNone(query._end_time)\n\n    self.assertEqual(query._per_series_aligner, 0)\n    self.assertEqual(query._alignment_period_seconds, 0)\n    self.assertEqual(query._cross_series_reducer, 0)\n    self.assertEqual(query._group_by_fields, ())\n\n  def test_constructor_maximal(self):\n    UPTIME_METRIC = 'compute.googleapis.com/instance/uptime'\n    T1 = datetime.datetime(2016, 4, 7, 2, 30, 30)\n    DAYS, HOURS, MINUTES = 1, 2, 3\n    T0 = T1 - datetime.timedelta(days=DAYS, hours=HOURS, minutes=MINUTES)\n\n    query = gcm.Query(UPTIME_METRIC,\n                      end_time=T1, days=DAYS, hours=HOURS, minutes=MINUTES,\n                      context=self.context)\n\n    self.assertEqual(query._filter.metric_type, UPTIME_METRIC)\n\n    self.assertEqual(query._start_time, T0)\n    self.assertEqual(query._end_time, T1)\n\n    self.assertEqual(query._per_series_aligner, 0)\n    self.assertEqual(query._alignment_period_seconds, 0)\n    self.assertEqual(query._cross_series_reducer, 0)\n    self.assertEqual(query._group_by_fields, ())\n\n  @mock.patch('google.datalab.stackdriver.monitoring.Query.iter')\n  def test_metadata(self, mock_query_iter):\n    query = gcm.Query(METRIC_TYPE, hours=1, context=self.context)\n    query_metadata = query.metadata()\n\n    mock_query_iter.assert_called_once_with(headers_only=True)\n    self.assertIsInstance(query_metadata, gcm.QueryMetadata)\n    self.assertEqual(query_metadata.metric_type, METRIC_TYPE)\n"
  },
  {
    "path": "tests/stackdriver/monitoring/resource_tests.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nimport mock\nimport unittest\n\nimport google.cloud.monitoring_v3\n\nimport google.auth\nimport google.datalab\nimport google.datalab.stackdriver.monitoring as gcm\n\nDEFAULT_PROJECT = 'test'\nPROJECT = 'my-project'\nRESOURCE_TYPES = ['gce_instance', 'aws_ec2_instance']\nDISPLAY_NAMES = ['GCE VM Instance', 'Amazon EC2 Instance']\n\nLABELS = [dict(key='instance_id', value_type='STRING',\n               description='VM instance ID'),\n          dict(key='project_id', value_type='STRING',\n               description='Project ID')]\nFILTER_STRING = 'resource.type = ends_with(\"instance\")'\n\n\nclass TestCases(unittest.TestCase):\n\n  def setUp(self):\n    self.context = self._create_context(DEFAULT_PROJECT)\n    self.descriptors = gcm.ResourceDescriptors(context=self.context)\n\n  @mock.patch('google.datalab.Context.default')\n  def test_constructor_minimal(self, mock_context_default):\n    mock_context_default.return_value = self.context\n    descriptors = gcm.ResourceDescriptors()\n    self.assertEqual(descriptors._client.project, DEFAULT_PROJECT)\n    self.assertIsNone(descriptors._filter_string)\n    self.assertIsNone(descriptors._descriptors)\n\n  def test_constructor_maximal(self):\n    context = self._create_context(PROJECT)\n    descriptors = gcm.ResourceDescriptors(\n        filter_string=FILTER_STRING, context=context)\n    self.assertEqual(descriptors._client.project, PROJECT)\n\n    self.assertEqual(descriptors._filter_string, FILTER_STRING)\n    self.assertIsNone(descriptors._descriptors)\n\n  @mock.patch('google.cloud.monitoring_v3.MetricServiceClient.list_monitored_resource_descriptors')\n  def test_list(self, mock_api_list_descriptors):\n    mock_api_list_descriptors.return_value = self._list_resources_get_result()\n\n    resource_descriptor_list = self.descriptors.list()\n\n    mock_api_list_descriptors.assert_called_once_with(\n        DEFAULT_PROJECT, filter_=None)\n    self.assertEqual(len(resource_descriptor_list), 2)\n    self.assertEqual(resource_descriptor_list[0].type, RESOURCE_TYPES[0])\n    self.assertEqual(resource_descriptor_list[1].type, RESOURCE_TYPES[1])\n\n  @mock.patch('google.cloud.monitoring_v3.MetricServiceClient.list_monitored_resource_descriptors')\n  def test_list_w_api_filter(self, mock_api_list_descriptors):\n    mock_api_list_descriptors.return_value = self._list_resources_get_result()\n\n    descriptors = gcm.ResourceDescriptors(\n        filter_string=FILTER_STRING, context=self.context)\n    resource_descriptor_list = descriptors.list()\n\n    mock_api_list_descriptors.assert_called_once_with(\n        DEFAULT_PROJECT, filter_=FILTER_STRING)\n    self.assertEqual(len(resource_descriptor_list), 2)\n    self.assertEqual(resource_descriptor_list[0].type, RESOURCE_TYPES[0])\n    self.assertEqual(resource_descriptor_list[1].type, RESOURCE_TYPES[1])\n\n  @mock.patch('google.cloud.monitoring_v3.MetricServiceClient.list_monitored_resource_descriptors')\n  def test_list_w_pattern_match(self, mock_api_list_descriptors):\n    mock_api_list_descriptors.return_value = self._list_resources_get_result()\n\n    resource_descriptor_list = self.descriptors.list(pattern='*ec2*')\n\n    mock_api_list_descriptors.assert_called_once_with(\n        DEFAULT_PROJECT, filter_=None)\n    self.assertEqual(len(resource_descriptor_list), 1)\n    self.assertEqual(resource_descriptor_list[0].type, RESOURCE_TYPES[1])\n\n  @mock.patch('google.cloud.monitoring_v3.MetricServiceClient.list_monitored_resource_descriptors')\n  def test_list_caching(self, mock_gcloud_list_descriptors):\n    mock_gcloud_list_descriptors.return_value = (\n        self._list_resources_get_result())\n\n    actual_list1 = self.descriptors.list()\n    actual_list2 = self.descriptors.list()\n\n    mock_gcloud_list_descriptors.assert_called_once_with(\n        DEFAULT_PROJECT, filter_=None)\n    self.assertEqual(actual_list1, actual_list2)\n\n  @mock.patch('google.cloud.monitoring_v3.MetricServiceClient.list_monitored_resource_descriptors')\n  def test_as_dataframe(self, mock_datalab_list_descriptors):\n    mock_datalab_list_descriptors.return_value = (\n        self._list_resources_get_result())\n    dataframe = self.descriptors.as_dataframe()\n    mock_datalab_list_descriptors.assert_called_once_with(\n        DEFAULT_PROJECT, filter_=None)\n\n    expected_headers = list(gcm.ResourceDescriptors._DISPLAY_HEADERS)\n    self.assertEqual(dataframe.columns.tolist(), expected_headers)\n    self.assertEqual(dataframe.columns.names, [None])\n\n    self.assertEqual(dataframe.index.tolist(), list(range(len(RESOURCE_TYPES))))\n    self.assertEqual(dataframe.index.names, [None])\n\n    expected_labels = 'instance_id, project_id'\n    expected_values = [\n        [resource_type, display_name, expected_labels]\n        for resource_type, display_name in zip(RESOURCE_TYPES, DISPLAY_NAMES)]\n    self.assertEqual(dataframe.values.tolist(), expected_values)\n\n  @mock.patch('google.cloud.monitoring_v3.MetricServiceClient.list_monitored_resource_descriptors')\n  def test_as_dataframe_w_all_args(self, mock_datalab_list_descriptors):\n    mock_datalab_list_descriptors.return_value = (\n        self._list_resources_get_result())\n    dataframe = self.descriptors.as_dataframe(pattern='*instance*', max_rows=1)\n    mock_datalab_list_descriptors.assert_called_once_with(\n        DEFAULT_PROJECT, filter_=None)\n\n    expected_headers = list(gcm.ResourceDescriptors._DISPLAY_HEADERS)\n    self.assertEqual(dataframe.columns.tolist(), expected_headers)\n    self.assertEqual(dataframe.index.tolist(), [0])\n    self.assertEqual(dataframe.iloc[0, 0], RESOURCE_TYPES[0])\n\n  @staticmethod\n  def _create_context(project_id):\n    creds = mock.Mock(spec=google.auth.credentials.Credentials)\n    return google.datalab.Context(project_id, creds)\n\n  @staticmethod\n  def _list_resources_get_result():\n    all_labels = [google.cloud.monitoring_v3.types.LabelDescriptor(**labels)\n                  for labels in LABELS]\n    descriptors = [\n        google.cloud.monitoring_v3.types.MonitoredResourceDescriptor(\n            name=None, type=resource_type, display_name=display_name,\n            description=None, labels=all_labels,\n        )\n        for resource_type, display_name in zip(RESOURCE_TYPES, DISPLAY_NAMES)]\n    return descriptors\n"
  },
  {
    "path": "tests/stackdriver/monitoring/utils_tests.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nimport mock\nimport unittest\n\nimport google.auth\nimport google.datalab\nimport google.datalab.stackdriver.monitoring as gcm\n\n\nclass TestCases(unittest.TestCase):\n\n  def test_make_client(self):\n    context = self._create_context()\n    client = gcm._utils.make_client(context)\n\n    self.assertEqual(client.project, context.project_id)\n\n  @mock.patch('google.datalab.Context.default')\n  def test_make_client_w_defaults(self, mock_context_default):\n    default_context = self._create_context()\n    mock_context_default.return_value = default_context\n    client = gcm._utils.make_client()\n\n    self.assertEqual(client.project, default_context.project_id)\n\n  @staticmethod\n  def _create_context():\n    creds = mock.Mock(spec=google.auth.credentials.Credentials)\n    return google.datalab.Context('test_project', creds)\n"
  },
  {
    "path": "tests/storage/__init__.py",
    "content": "# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n"
  },
  {
    "path": "tests/storage/api_tests.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nimport unittest\nimport mock\n\nimport google.auth\nimport google.datalab\nfrom google.datalab.storage._api import Api\n\n\nclass TestCases(unittest.TestCase):\n\n  def validate(self, mock_http_request, expected_url, expected_args=None, expected_data=None,\n               expected_headers=None, expected_method=None):\n    url = mock_http_request.call_args[0][0]\n    kwargs = mock_http_request.call_args[1]\n    self.assertEquals(expected_url, url)\n    if expected_args is not None:\n      self.assertEquals(expected_args, kwargs['args'])\n    if expected_data is not None:\n      self.assertEquals(expected_data, kwargs['data'])\n    if expected_headers is not None:\n      self.assertEquals(expected_headers, kwargs['headers'])\n    if expected_method is not None:\n      self.assertEquals(expected_method, kwargs['method'])\n\n  @mock.patch('google.datalab.utils.Http.request')\n  def test_buckets_insert(self, mock_http_request):\n    api = TestCases._create_api()\n\n    api.buckets_insert('foo')\n    self.validate(mock_http_request, 'https://www.googleapis.com/storage/v1/b/',\n                  expected_args={'project': 'test'}, expected_data={'name': 'foo'})\n\n    api.buckets_insert('foo', 'bar')\n    self.validate(mock_http_request, 'https://www.googleapis.com/storage/v1/b/',\n                  expected_args={'project': 'bar'}, expected_data={'name': 'foo'})\n\n  @mock.patch('google.datalab.utils.Http.request')\n  def test_buckets_delete(self, mock_http_request):\n    api = TestCases._create_api()\n    api.buckets_delete('foo')\n    self.validate(mock_http_request, 'https://www.googleapis.com/storage/v1/b/foo',\n                  expected_method='DELETE')\n\n  @mock.patch('google.datalab.utils.Http.request')\n  def test_buckets_get(self, mock_http_request):\n    api = TestCases._create_api()\n    api.buckets_get('foo')\n    self.validate(mock_http_request, 'https://www.googleapis.com/storage/v1/b/foo',\n                  expected_args={'projection': 'noAcl'})\n    api.buckets_get('foo', 'bar')\n    self.validate(mock_http_request, 'https://www.googleapis.com/storage/v1/b/foo',\n                  expected_args={'projection': 'bar'})\n\n  @mock.patch('google.datalab.utils.Http.request')\n  def test_buckets_list(self, mock_http_request):\n    api = TestCases._create_api()\n    api.buckets_list()\n    self.validate(mock_http_request, 'https://www.googleapis.com/storage/v1/b/',\n                  expected_args={'project': 'test', 'projection': 'noAcl', 'maxResults': 100})\n\n    api.buckets_list(projection='foo', max_results=99, page_token='xyz', project_id='bar')\n    self.validate(mock_http_request, 'https://www.googleapis.com/storage/v1/b/',\n                  expected_args={'project': 'bar', 'maxResults': 99,\n                                 'projection': 'foo', 'pageToken': 'xyz'})\n\n  @mock.patch('google.datalab.utils.Http.request')\n  def test_object_download(self, mock_http_request):\n    api = TestCases._create_api()\n    api.object_download('foo', 'bar')\n    self.validate(mock_http_request, 'https://www.googleapis.com/download/storage/v1/b/foo/o/bar',\n                  expected_args={'alt': 'media'})\n\n  @mock.patch('google.datalab.utils.Http.request')\n  def test_object_upload(self, mock_http_request):\n    api = TestCases._create_api()\n    api.object_upload('b', 'k', 'c', 't')\n    self.validate(mock_http_request, 'https://www.googleapis.com/upload/storage/v1/b/b/o/',\n                  expected_args={'uploadType': 'media', 'name': 'k'},\n                  expected_data='c', expected_headers={'Content-Type': 't'})\n\n  @mock.patch('google.datalab.utils.Http.request')\n  def test_objects_copy(self, mock_http_request):\n    api = TestCases._create_api()\n    api.objects_copy('sb', 'sk', 'tb', 'tk')\n    self.validate(mock_http_request,\n                  'https://www.googleapis.com/storage/v1/b/sb/o/sk/copyTo/b/tb/o/tk',\n                  expected_method='POST')\n\n  @mock.patch('google.datalab.utils.Http.request')\n  def test_objects_delete(self, mock_http_request):\n    api = TestCases._create_api()\n    api.objects_delete('b', 'k')\n    self.validate(mock_http_request, 'https://www.googleapis.com/storage/v1/b/b/o/k',\n                  expected_method='DELETE')\n\n  @mock.patch('google.datalab.utils.Http.request')\n  def test_objects_get(self, mock_http_request):\n    api = TestCases._create_api()\n    api.objects_get('b', 'k')\n    self.validate(mock_http_request, 'https://www.googleapis.com/storage/v1/b/b/o/k',\n                  expected_args={'projection': 'noAcl'})\n\n    api.objects_get('b', 'k', 'p')\n    self.validate(mock_http_request, 'https://www.googleapis.com/storage/v1/b/b/o/k',\n                  expected_args={'projection': 'p'})\n\n  @mock.patch('google.datalab.utils.Http.request')\n  def test_objects_list(self, mock_http_request):\n    api = TestCases._create_api()\n    api.objects_list('b')\n    self.validate(mock_http_request, 'https://www.googleapis.com/storage/v1/b/b/o/',\n                  expected_args={'projection': 'noAcl', 'maxResults': 100})\n\n    api.objects_list('b', 'p', 'd', 'pr', True, 99, 'foo')\n    self.validate(mock_http_request, 'https://www.googleapis.com/storage/v1/b/b/o/',\n                  expected_args={'projection': 'pr', 'maxResults': 99,\n                                 'prefix': 'p', 'delimiter': 'd', 'versions': 'true',\n                                 'pageToken': 'foo'})\n\n  @mock.patch('google.datalab.utils.Http.request')\n  def test_objects_patch(self, mock_http_request):\n    api = TestCases._create_api()\n    api.objects_patch('b', 'k', 'i')\n    self.validate(mock_http_request, 'https://www.googleapis.com/storage/v1/b/b/o/k',\n                  expected_method='PATCH', expected_data='i')\n\n  @staticmethod\n  def _create_api():\n    context = TestCases._create_context()\n    return Api(context)\n\n  @staticmethod\n  def _create_context():\n    project_id = 'test'\n    creds = mock.Mock(spec=google.auth.credentials.Credentials)\n    return google.datalab.Context(project_id, creds)\n"
  },
  {
    "path": "tests/storage/bucket_tests.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nimport mock\nimport unittest\n\nimport google.auth\nimport google.datalab\nimport google.datalab.storage\nimport google.datalab.utils\n\n\nclass TestCases(unittest.TestCase):\n\n  @mock.patch('google.datalab.storage._api.Api.buckets_get')\n  def test_bucket_existence(self, mock_api_buckets):\n    mock_api_buckets.return_value = TestCases._create_buckets_get_result()\n\n    buckets = google.datalab.storage.Buckets(context=TestCases._create_context())\n    self.assertTrue(buckets.contains('test_bucket'))\n\n    mock_api_buckets.side_effect = google.datalab.utils.RequestException(404, 'failed')\n    self.assertFalse(buckets.contains('test_bucket_2'))\n\n  @mock.patch('google.datalab.storage._api.Api.buckets_get')\n  def test_bucket_metadata(self, mock_api_buckets):\n    mock_api_buckets.return_value = TestCases._create_buckets_get_result()\n\n    b = TestCases._create_bucket()\n    m = b.metadata\n\n    self.assertEqual(m.name, 'test_bucket')\n\n  @staticmethod\n  def _create_bucket(name='test_bucket'):\n    return google.datalab.storage.Bucket(name, context=TestCases._create_context())\n\n  @staticmethod\n  def _create_context():\n    project_id = 'test'\n    creds = mock.Mock(spec=google.auth.credentials.Credentials)\n    return google.datalab.Context(project_id, creds)\n\n  @staticmethod\n  def _create_buckets_get_result():\n    return {'name': 'test_bucket'}\n"
  },
  {
    "path": "tests/storage/object_tests.py",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n# in compliance with the License. You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under the License\n# is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n# or implied. See the License for the specific language governing permissions and limitations under\n# the License.\n\nfrom __future__ import absolute_import\nfrom __future__ import unicode_literals\nimport mock\nimport unittest\n\nimport google.auth\nimport google.datalab\nimport google.datalab.storage\nimport google.datalab.utils\n\n\nclass TestCases(unittest.TestCase):\n\n  @mock.patch('google.datalab.storage._api.Api.objects_list')\n  @mock.patch('google.datalab.storage._api.Api.objects_get')\n  def test_object_existence(self, mock_api_objects_get, mock_api_objects_list):\n    mock_api_objects_list.return_value = TestCases._create_enumeration_single_result()\n    mock_api_objects_get.return_value = TestCases._create_objects_get_result()\n\n    b = TestCases._create_bucket()\n    self.assertTrue(b.objects().contains('test_object1'))\n\n    mock_api_objects_get.side_effect = google.datalab.utils.RequestException(404, 'failed')\n    self.assertFalse('test_object2' in list(b.objects()))\n\n  @mock.patch('google.datalab.storage._api.Api.objects_get')\n  def test_object_metadata(self, mock_api_objects):\n    mock_api_objects.return_value = TestCases._create_objects_get_result()\n\n    b = TestCases._create_bucket()\n    i = b.object('test_object1')\n    m = i.metadata\n\n    self.assertEqual(m.name, 'test_object1')\n    self.assertEqual(m.content_type, 'text/plain')\n\n  @mock.patch('google.datalab.storage._api.Api.objects_list')\n  def test_enumerate_objects_empty(self, mock_api_objects):\n    mock_api_objects.return_value = TestCases._create_enumeration_empty_result()\n\n    b = self._create_bucket()\n    objects = list(b.objects())\n\n    self.assertEqual(len(objects), 0)\n\n  @mock.patch('google.datalab.storage._api.Api.objects_list')\n  def test_enumerate_objects_single(self, mock_api_objects):\n    mock_api_objects.return_value = TestCases._create_enumeration_single_result()\n\n    b = TestCases._create_bucket()\n    objects = list(b.objects())\n\n    self.assertEqual(len(objects), 1)\n    self.assertEqual(objects[0].key, 'test_object1')\n\n  @mock.patch('google.datalab.storage._api.Api.objects_list')\n  def test_enumerate_objects_multi_page(self, mock_api_objects):\n    mock_api_objects.side_effect = [\n      TestCases._create_enumeration_multipage_result1(),\n      TestCases._create_enumeration_multipage_result2()\n    ]\n\n    b = TestCases._create_bucket()\n    objects = list(b.objects())\n\n    self.assertEqual(len(objects), 2)\n    self.assertEqual(objects[0].key, 'test_object1')\n    self.assertEqual(objects[1].key, 'test_object2')\n\n  @mock.patch('google.datalab.storage._api.Api.objects_list')\n  def test_object_delete_with_wait(self, mock_objects_list):\n    stable_object_name = 'testobject'\n    object_to_delete = 'temporaryobject'\n    mock_objects_list.side_effect = [\n        {'items': [{'name': stable_object_name}], 'nextPageToken': 'yes'},\n        {'items': [{'name': object_to_delete}]},\n        {'items': [{'name': stable_object_name}]},\n    ]\n\n    b = TestCases._create_bucket()\n    o = b.object(object_to_delete)\n    o._info = {'name': object_to_delete}\n\n    with mock.patch.object(google.datalab.storage._api.Api, 'objects_delete',\n                           autospec=True) as mock_objects_delete:\n      o.delete(wait_for_deletion=False)\n    self.assertEqual(1, mock_objects_delete.call_count)\n    # storage.objects.list shouldn't have been called with\n    # wait_for_deletion=False.\n    self.assertEqual(0, mock_objects_list.call_count)\n\n    with mock.patch.object(google.datalab.storage._api.Api, 'objects_delete',\n                           autospec=True) as mock_objects_delete:\n      o.delete()\n    self.assertEqual(1, mock_objects_delete.call_count)\n    # storage.objects.list should have been called three times with\n    # wait_for_deletion=True:\n    #  * twice on the first run, paging through all results, with the object\n    #    still present in the bucket, and\n    #  * once on a second run, now with no object present in the list.\n    self.assertEqual(3, mock_objects_list.call_count)\n\n  @staticmethod\n  def _create_bucket(name='test_bucket'):\n    return google.datalab.storage.Bucket(name, context=TestCases._create_context())\n\n  @staticmethod\n  def _create_context():\n    project_id = 'test'\n    creds = mock.Mock(spec=google.auth.credentials.Credentials)\n    return google.datalab.Context(project_id, creds)\n\n  @staticmethod\n  def _create_objects_get_result():\n    return {'name': 'test_object1', 'contentType': 'text/plain'}\n\n  @staticmethod\n  def _create_enumeration_empty_result():\n    return {}\n\n  @staticmethod\n  def _create_enumeration_single_result():\n    return {\n      'items': [\n        {'name': 'test_object1'}\n      ]\n    }\n\n  @staticmethod\n  def _create_enumeration_multipage_result1():\n    return {\n      'items': [\n        {'name': 'test_object1'}\n      ],\n      'nextPageToken': 'test_token'\n    }\n\n  @staticmethod\n  def _create_enumeration_multipage_result2():\n    return {\n      'items': [\n        {'name': 'test_object2'}\n      ]\n    }\n"
  },
  {
    "path": "tox.ini",
    "content": "[tox]\n# By default, we want to run tests for Python 2.7, Python 3.5, Python 3.7,\n# and run our flake8 checks.\nenvlist = py27,py35,py37,flake8,coveralls\n# If an interpreter is missing locally, skip it.\nskip_missing_interpreters = true\n\n[testenv]\n# pydatalab doesn't require users to have these dependencies installed, but we\n# need them to run our tests suite.\n#\n# tox always installs the current package, so there's no need to list it here.\ndeps = apache-airflow==1.9.0\n       dill==0.2.6\n       tensorflow==1.8.0\n       lime==0.1.1.23\n       xgboost==0.6a2\n       # Dropping this seems to cause problems with conda in some cases.\n       scipy\n       solutionbox/structured_data/\n       solutionbox/image_classification/\ncommands =\n  python ./tests/main.py {posargs}\n  python ./legacy_tests/main.py {posargs}\n\n[testenv:py27]\n# apache-beam only supports python2.7, so we add that here.\ndeps = {[testenv]deps}\n       apache-beam==2.5.0\n\n[testenv:flake8]\ncommands = flake8 --exclude=.tox,.git,./*.egg,build,.cache,env,__pycache__,docs\ndeps = flake8==3.4.1\n\n[testenv:coveralls]\npassenv = TRAVIS TRAVIS_JOB_ID TRAVIS_BRANCH\ndeps = {[testenv]deps}\n       google-cloud-dataflow==2.5.0\n       coveralls \ncommands =\n  coverage run tests/main.py {posargs}\n  - coveralls --rcfile=.coveragerc\n"
  }
]